1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-08-12 09:50:50 +00:00

Building on Macs (#1086)

* git subrepo pull (merge) tools/ZAPD

subrepo:
  subdir:   "tools/ZAPD"
  merged:   "945e6ca1a"
upstream:
  origin:   "https://github.com/zeldaret/ZAPD.git"
  branch:   "master"
  commit:   "50242eca9"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo.git"
  commit:   "2f68596"

* Fix extract_assets.py multithreading

* Update binutils doc a bit

* Remove * import, add multiprocessing option
and way to pass arguments to ZAPD

* Update format.sh to be more platform-independent

* git subrepo pull --force tools/ZAPD

subrepo:
  subdir:   "tools/ZAPD"
  merged:   "fd5a7f434"
upstream:
  origin:   "https://github.com/zeldaret/ZAPD.git"
  branch:   "master"
  commit:   "fd5a7f434"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo.git"
  commit:   "2f68596"

* Remove ;

* Update formatting script to not just use 11

* Add Python requirements,
move the Mac stuff in the README into its own doc

* Fix readme link

* Minor format thing

* .

* Move ZAPDArgs into its own function

* Update readme and remove requirements.txt

* Dragorn-inspired rewrite of processZAPDArgs

* git subrepo pull --force tools/ZAPD

subrepo:
  subdir:   "tools/ZAPD"
  merged:   "a0d3f7b68"
upstream:
  origin:   "https://github.com/zeldaret/ZAPD.git"
  branch:   "master"
  commit:   "a0d3f7b68"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo.git"
  commit:   "2f68596"

* Fix function definition

* Building docs overhaul

* Add Python packages to Mac and Cygwin

* Heading number

* format format.sh (!)

* Replace "currently"

* Remove Debian

* git subrepo pull (merge) --force tools/ZAPD

subrepo:
  subdir:   "tools/ZAPD"
  merged:   "0ba781304"
upstream:
  origin:   "https://github.com/zeldaret/ZAPD.git"
  branch:   "master"
  commit:   "0ba781304"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo.git"
  commit:   "2f68596"
This commit is contained in:
EllipticEllipsis 2022-01-17 00:43:07 +00:00 committed by GitHub
parent 9450272503
commit 9b67778a00
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 640 additions and 325 deletions

View file

@ -171,7 +171,7 @@ std::string Declaration::GetExternalDeclarationStr() const
std::string Declaration::GetExternStr() const
{
if (IsStatic() || varType == "")
if (IsStatic() || varType == "" || isUnaccounted)
{
return "";
}

View file

@ -12,8 +12,7 @@ typedef uint32_t offset_t;
enum class DeclarationAlignment
{
Align4,
Align8,
Align16
Align8
};
enum class StaticConfig

View file

@ -152,8 +152,8 @@ bool Globals::GetSegmentedPtrName(segptr_t segAddress, ZFile* currentFile,
}
}
const auto& symbolFromMap = Globals::Instance->symbolMap.find(segAddress);
if (symbolFromMap != Globals::Instance->symbolMap.end())
const auto& symbolFromMap = Globals::Instance->cfg.symbolMap.find(segAddress);
if (symbolFromMap != Globals::Instance->cfg.symbolMap.end())
{
declName = "&" + symbolFromMap->second;
return true;

View file

@ -58,11 +58,11 @@ public:
bool verboseUnaccounted = false;
bool gccCompat = false;
bool forceStatic = false;
bool forceUnaccountedStatic = false;
std::vector<ZFile*> files;
std::vector<ZFile*> externalFiles;
std::vector<int32_t> segments;
std::map<uint32_t, std::string> symbolMap;
std::string currentExporter;
static std::map<std::string, ExporterSet*>& GetExporterMap();

View file

@ -48,7 +48,7 @@ void ErrorHandler(int sig)
const char* crashEasterEgg[] = {
"\tYou've met with a terrible fate, haven't you?",
"\tSEA BEARS FOAM. SLEEP BEARS DREAMS. \n\tBOTH END IN THE SAME WAY: CRASSSH!",
"ZAPD has fallen and cannot get up."
"\tZAPD has fallen and cannot get up.",
};
srand(time(nullptr));
@ -216,6 +216,10 @@ int main(int argc, char* argv[])
{
Globals::Instance->forceStatic = true;
}
else if (arg == "-us" || arg == "--unaccounted-static")
{
Globals::Instance->forceUnaccountedStatic = true;
}
}
// Parse File Mode
@ -430,6 +434,10 @@ void BuildAssetTexture(const fs::path& pngFilePath, TextureType texType, const f
std::string name = outPath.stem().string();
ZTexture tex(nullptr);
if (name.find("u32") != std::string::npos)
tex.dWordAligned = false;
tex.FromPNG(pngFilePath.string(), texType);
std::string cfgPath = StringHelper::Split(pngFilePath.string(), ".")[0] + ".cfg";

View file

@ -263,7 +263,7 @@ void Struct_800A5E28::DeclareReferences(const std::string& prefix)
ZResource::DeclareReferences(varPrefix);
if (unk_4 != 0 && GETSEGNUM(unk_4) == parent->segment)
if (unk_4 != SEGMENTED_NULL && GETSEGNUM(unk_4) == parent->segment)
{
const auto& res = unk_4_arr.at(0);
std::string unk_4_Str = res.GetDefaultName(varPrefix);
@ -293,7 +293,7 @@ void Struct_800A5E28::DeclareReferences(const std::string& prefix)
decl->text = entryStr;
}
if (unk_8 != 0 && GETSEGNUM(unk_8) == parent->segment)
if (unk_8 != SEGMENTED_NULL && GETSEGNUM(unk_8) == parent->segment)
{
uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress);
@ -306,6 +306,8 @@ void Struct_800A5E28::DeclareReferences(const std::string& prefix)
std::string dListStr =
StringHelper::Sprintf("%sSkinLimbDL_%06X", varPrefix.c_str(), unk_8_Offset);
unk_8_dlist->SetName(dListStr);
unk_8_dlist->DeclareVar(varPrefix, "");
unk_8_dlist->DeclareReferences(varPrefix);
parent->AddResource(unk_8_dlist);
}
}

View file

@ -90,7 +90,8 @@ ZOverlay* ZOverlay::FromBuild(fs::path buildPath, fs::path cfgFolderPath)
std::vector<elfio*> readers;
for (size_t i = 1; i < cfgLines.size(); i++)
{
std::string elfPath = (buildPath / (cfgLines[i].substr(0, cfgLines[i].size() - 2) + ".o")).string();
std::string elfPath =
(buildPath / (cfgLines[i].substr(0, cfgLines[i].size() - 2) + ".o")).string();
elfio* reader = new elfio();
if (!reader->load(elfPath))

View file

@ -104,7 +104,7 @@ void ZNormalAnimation::DeclareReferences(const std::string& prefix)
valuesStr += "\n ";
}
parent->AddDeclarationArray(rotationValuesOffset, DeclarationAlignment::Align16,
parent->AddDeclarationArray(rotationValuesOffset, DeclarationAlignment::Align4,
rotationValues.size() * 2, "s16",
StringHelper::Sprintf("%sFrameData", defaultPrefix.c_str()),
rotationValues.size(), valuesStr);
@ -118,7 +118,7 @@ void ZNormalAnimation::DeclareReferences(const std::string& prefix)
indicesStr += "\n";
}
parent->AddDeclarationArray(rotationIndicesOffset, DeclarationAlignment::Align16,
parent->AddDeclarationArray(rotationIndicesOffset, DeclarationAlignment::Align4,
rotationIndices.size() * 6, "JointIndex",
StringHelper::Sprintf("%sJointIndices", defaultPrefix.c_str()),
rotationIndices.size(), indicesStr);
@ -385,7 +385,7 @@ size_t ZCurveAnimation::GetRawDataSize() const
DeclarationAlignment ZCurveAnimation::GetDeclarationAlignment() const
{
return DeclarationAlignment::Align16;
return DeclarationAlignment::Align4;
}
std::string ZCurveAnimation::GetSourceTypeName() const

View file

@ -101,11 +101,18 @@ std::string ZArray::GetBodySourceCode() const
const auto& res = resList[i];
output += "\t";
if (res->GetResourceType() == ZResourceType::Scalar ||
res->GetResourceType() == ZResourceType::Vertex)
switch (res->GetResourceType())
{
case ZResourceType::Pointer:
case ZResourceType::Scalar:
case ZResourceType::Vertex:
output += resList.at(i)->GetBodySourceCode();
else
break;
default:
output += StringHelper::Sprintf("{ %s }", resList.at(i)->GetBodySourceCode().c_str());
break;
}
if (i < arrayCnt - 1 || res->IsExternalResource())
output += ",\n";

View file

@ -1,5 +1,6 @@
#include "ZCollision.h"
#include <cassert>
#include <cstdint>
#include <string>
@ -76,9 +77,42 @@ void ZCollisionHeader::ParseRawData()
polygonTypes.push_back(
BitConverter::ToUInt64BE(rawData, polyTypeDefSegmentOffset + (i * 8)));
if (camDataAddress != 0)
camData = new CameraDataList(parent, name, rawData, camDataSegmentOffset,
polyTypeDefSegmentOffset, polygonTypes.size());
if (camDataAddress != SEGMENTED_NULL)
{
// Try to guess how many elements the CamDataList array has.
// The "guessing algorithm" is basically a "best effort" one and it
// is error-prone.
// This is based mostly on observation of how CollisionHeader data is
// usually ordered. If for some reason the data was in some other funny
// order, this would probably break.
// The most common ordering is:
// - *CamData*
// - SurfaceType
// - CollisionPoly
// - Vertices
// - WaterBoxes
// - CollisionHeader
offset_t upperCameraBoundary = polyTypeDefSegmentOffset;
if (upperCameraBoundary == 0)
{
upperCameraBoundary = polySegmentOffset;
}
if (upperCameraBoundary == 0)
{
upperCameraBoundary = vtxSegmentOffset;
}
if (upperCameraBoundary == 0)
{
upperCameraBoundary = waterBoxSegmentOffset;
}
if (upperCameraBoundary == 0)
{
upperCameraBoundary = rawDataIndex;
}
camData =
new CameraDataList(parent, name, rawData, camDataSegmentOffset, upperCameraBoundary);
}
for (uint16_t i = 0; i < numWaterBoxes; i++)
waterBoxes.push_back(WaterBoxHeader(
@ -106,8 +140,7 @@ void ZCollisionHeader::DeclareReferences(const std::string& prefix)
parent->AddDeclarationArray(
waterBoxSegmentOffset, DeclarationAlignment::Align4, 16 * waterBoxes.size(), "WaterBox",
StringHelper::Sprintf("%s_waterBoxes_%06X", auxName.c_str(), waterBoxSegmentOffset),
waterBoxes.size(), declaration);
StringHelper::Sprintf("%sWaterBoxes", auxName.c_str()), waterBoxes.size(), declaration);
}
if (polygons.size() > 0)
@ -126,8 +159,7 @@ void ZCollisionHeader::DeclareReferences(const std::string& prefix)
parent->AddDeclarationArray(
polySegmentOffset, DeclarationAlignment::Align4, polygons.size() * 16, "CollisionPoly",
StringHelper::Sprintf("%s_polygons_%08X", auxName.c_str(), polySegmentOffset),
polygons.size(), declaration);
StringHelper::Sprintf("%sPolygons", auxName.c_str()), polygons.size(), declaration);
}
declaration.clear();
@ -141,11 +173,10 @@ void ZCollisionHeader::DeclareReferences(const std::string& prefix)
}
if (polyTypeDefAddress != 0)
parent->AddDeclarationArray(
polyTypeDefSegmentOffset, DeclarationAlignment::Align4, polygonTypes.size() * 8,
"SurfaceType",
StringHelper::Sprintf("%s_surfaceType_%08X", auxName.c_str(), polyTypeDefSegmentOffset),
polygonTypes.size(), declaration);
parent->AddDeclarationArray(polyTypeDefSegmentOffset, DeclarationAlignment::Align4,
polygonTypes.size() * 8, "SurfaceType",
StringHelper::Sprintf("%sSurfaceType", auxName.c_str()),
polygonTypes.size(), declaration);
declaration.clear();
@ -167,8 +198,7 @@ void ZCollisionHeader::DeclareReferences(const std::string& prefix)
parent->AddDeclarationArray(
vtxSegmentOffset, first.GetDeclarationAlignment(),
vertices.size() * first.GetRawDataSize(), first.GetSourceTypeName(),
StringHelper::Sprintf("%s_vtx_%08X", auxName.c_str(), vtxSegmentOffset),
vertices.size(), declaration);
StringHelper::Sprintf("%sVertices", auxName.c_str()), vertices.size(), declaration);
}
}
@ -183,11 +213,11 @@ std::string ZCollisionHeader::GetBodySourceCode() const
std::string vtxName;
Globals::Instance->GetSegmentedPtrName(vtxAddress, parent, "Vec3s", vtxName);
declaration += StringHelper::Sprintf("\t%i,\n\t%s,\n", numVerts, vtxName.c_str());
declaration += StringHelper::Sprintf("\t%i, %s,\n", numVerts, vtxName.c_str());
std::string polyName;
Globals::Instance->GetSegmentedPtrName(polyAddress, parent, "CollisionPoly", polyName);
declaration += StringHelper::Sprintf("\t%i,\n\t%s,\n", numPolygons, polyName.c_str());
declaration += StringHelper::Sprintf("\t%i, %s,\n", numPolygons, polyName.c_str());
std::string surfaceName;
Globals::Instance->GetSegmentedPtrName(polyTypeDefAddress, parent, "SurfaceType", surfaceName);
@ -199,7 +229,7 @@ std::string ZCollisionHeader::GetBodySourceCode() const
std::string waterBoxName;
Globals::Instance->GetSegmentedPtrName(waterBoxAddress, parent, "WaterBox", waterBoxName);
declaration += StringHelper::Sprintf("\t%i,\n\t%s\n", numWaterBoxes, waterBoxName.c_str());
declaration += StringHelper::Sprintf("\t%i, %s\n", numWaterBoxes, waterBoxName.c_str());
return declaration;
}
@ -261,16 +291,17 @@ std::string WaterBoxHeader::GetBodySourceCode() const
}
CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix,
const std::vector<uint8_t>& rawData, uint32_t rawDataIndex,
uint32_t polyTypeDefSegmentOffset,
[[maybe_unused]] uint32_t polygonTypesCnt)
const std::vector<uint8_t>& rawData, offset_t rawDataIndex,
offset_t upperCameraBoundary)
{
std::string declaration;
// Parse CameraDataEntries
int32_t numElements = (polyTypeDefSegmentOffset - rawDataIndex) / 8;
uint32_t cameraPosDataSeg = rawDataIndex;
for (int32_t i = 0; i < numElements; i++)
size_t numElements = (upperCameraBoundary - rawDataIndex) / 8;
assert(numElements < 10000);
offset_t cameraPosDataSeg = rawDataIndex;
for (size_t i = 0; i < numElements; i++)
{
CameraDataEntry* entry = new CameraDataEntry();
@ -302,8 +333,7 @@ CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix,
{
int32_t index =
((entries[i]->cameraPosDataSeg & 0x00FFFFFF) - cameraPosDataOffset) / 0x6;
sprintf(camSegLine, "&%s_camPosData_%08X[%i]", prefix.c_str(), cameraPosDataOffset,
index);
sprintf(camSegLine, "&%sCamPosData[%i]", prefix.c_str(), index);
}
else
sprintf(camSegLine, "NULL");
@ -318,7 +348,7 @@ CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix,
parent->AddDeclarationArray(
rawDataIndex, DeclarationAlignment::Align4, entries.size() * 8, "CamData",
StringHelper::Sprintf("%s_camDataList_%08X", prefix.c_str(), rawDataIndex), entries.size(),
StringHelper::Sprintf("%sCamDataList", prefix.c_str(), rawDataIndex), entries.size(),
declaration);
uint32_t numDataTotal = (rawDataIndex - cameraPosDataOffset) / 0x6;
@ -339,10 +369,9 @@ CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix,
int32_t cameraPosDataIndex = GETSEGOFFSET(cameraPosDataSeg);
uint32_t entrySize = numDataTotal * 0x6;
parent->AddDeclarationArray(
cameraPosDataIndex, DeclarationAlignment::Align4, entrySize, "Vec3s",
StringHelper::Sprintf("%s_camPosData_%08X", prefix.c_str(), cameraPosDataIndex),
numDataTotal, declaration);
parent->AddDeclarationArray(cameraPosDataIndex, DeclarationAlignment::Align4, entrySize,
"Vec3s", StringHelper::Sprintf("%sCamPosData", prefix.c_str()),
numDataTotal, declaration);
}
}

View file

@ -55,8 +55,7 @@ public:
std::vector<CameraPositionData*> cameraPositionData;
CameraDataList(ZFile* parent, const std::string& prefix, const std::vector<uint8_t>& rawData,
uint32_t rawDataIndex, uint32_t polyTypeDefSegmentOffset,
uint32_t polygonTypesCnt);
offset_t rawDataIndex, offset_t upperCameraBoundary);
~CameraDataList();
};

View file

@ -3,6 +3,7 @@
#include <algorithm>
#include <cassert>
#include <chrono>
#include <cinttypes>
#include <cmath>
#include "Globals.h"
@ -26,8 +27,8 @@ ZDisplayList::ZDisplayList(ZFile* nParent) : ZResource(nParent)
lastTexSizTest = F3DZEXTexSizes::G_IM_SIZ_16b;
lastTexLoaded = false;
lastTexIsPalette = false;
name = "";
dListType = Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX;
RegisterOptionalAttribute("Ucode");
}
ZDisplayList::~ZDisplayList()
@ -43,13 +44,29 @@ void ZDisplayList::ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDat
{
rawDataIndex = nRawDataIndex;
ParseXML(reader);
// TODO add error handling here
bool ucodeSet = registeredAttributes.at("Ucode").wasSet;
std::string ucodeValue = registeredAttributes.at("Ucode").value;
if ((Globals::Instance->game == ZGame::OOT_SW97) || (ucodeValue == "f3dex"))
{
dListType = DListType::F3DEX;
}
else if (!ucodeSet || ucodeValue == "f3dex2")
{
dListType = DListType::F3DZEX;
}
else
{
HANDLE_ERROR_RESOURCE(
WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
StringHelper::Sprintf("Invalid ucode type in node: %s\n", reader->Name()), "");
}
// Don't parse raw data of external files
if (parent->GetMode() != ZFileMode::ExternalFile)
{
int32_t rawDataSize = ZDisplayList::GetDListLength(
parent->GetRawData(), rawDataIndex,
Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX);
int32_t rawDataSize =
ZDisplayList::GetDListLength(parent->GetRawData(), rawDataIndex, dListType);
numInstructions = rawDataSize / 8;
ParseRawData();
}
@ -106,7 +123,7 @@ void ZDisplayList::ParseF3DZEX(F3DZEXOpcode opcode, uint64_t data, int32_t i,
switch (opcode)
{
case F3DZEXOpcode::G_NOOP:
sprintf(line, "gsDPNoOpTag(0x%08lX),", data & 0xFFFFFFFF);
sprintf(line, "gsDPNoOpTag(0x%08" PRIX64 "),", data & 0xFFFFFFFF);
break;
case F3DZEXOpcode::G_DL:
Opcode_G_DL(data, prefix, line);
@ -221,7 +238,7 @@ void ZDisplayList::ParseF3DZEX(F3DZEXOpcode opcode, uint64_t data, int32_t i,
break;
case F3DZEXOpcode::G_POPMTX:
{
sprintf(line, "gsSPPopMatrix(%li),", data);
sprintf(line, "gsSPPopMatrix(%" PRIi64 "),", data);
}
break;
case F3DZEXOpcode::G_LOADTLUT:
@ -298,7 +315,7 @@ void ZDisplayList::ParseF3DEX(F3DEXOpcode opcode, uint64_t data, const std::stri
switch (opcode)
{
case F3DEXOpcode::G_NOOP:
sprintf(line, "gsDPNoOpTag(0x%08lX),", data & 0xFFFFFFFF);
sprintf(line, "gsDPNoOpTag(0x%08" PRIX64 "),", data & 0xFFFFFFFF);
break;
case F3DEXOpcode::G_VTX:
Opcode_G_VTX(data, line);
@ -688,20 +705,22 @@ void ZDisplayList::Opcode_G_DL(uint64_t data, const std::string& prefix, char* l
if (pp != 0)
{
if (!Globals::Instance->HasSegment(segNum))
sprintf(line, "gsSPBranchList(0x%08lX),", data & 0xFFFFFFFF);
sprintf(line, "gsSPBranchList(0x%08" PRIX64 "),", data & 0xFFFFFFFF);
else if (dListDecl != nullptr)
sprintf(line, "gsSPBranchList(%s),", dListDecl->varName.c_str());
else
sprintf(line, "gsSPBranchList(%sDlist0x%06lX),", prefix.c_str(), GETSEGOFFSET(data));
sprintf(line, "gsSPBranchList(%sDlist0x%06" PRIX64 "),", prefix.c_str(),
GETSEGOFFSET(data));
}
else
{
if (!Globals::Instance->HasSegment(segNum))
sprintf(line, "gsSPDisplayList(0x%08lX),", data & 0xFFFFFFFF);
sprintf(line, "gsSPDisplayList(0x%08" PRIX64 "),", data & 0xFFFFFFFF);
else if (dListDecl != nullptr)
sprintf(line, "gsSPDisplayList(%s),", dListDecl->varName.c_str());
else
sprintf(line, "gsSPDisplayList(%sDlist0x%06lX),", prefix.c_str(), GETSEGOFFSET(data));
sprintf(line, "gsSPDisplayList(%sDlist0x%06" PRIX64 "),", prefix.c_str(),
GETSEGOFFSET(data));
}
// if (segNum == 8 || segNum == 9 || segNum == 10 || segNum == 11 || segNum == 12 || segNum ==
@ -709,9 +728,9 @@ void ZDisplayList::Opcode_G_DL(uint64_t data, const std::string& prefix, char* l
if (!Globals::Instance->HasSegment(segNum))
{
if (pp != 0)
sprintf(line, "gsSPBranchList(0x%08lX),", data & 0xFFFFFFFF);
sprintf(line, "gsSPBranchList(0x%08" PRIX64 "),", data & 0xFFFFFFFF);
else
sprintf(line, "gsSPDisplayList(0x%08lX),", data & 0xFFFFFFFF);
sprintf(line, "gsSPDisplayList(0x%08" PRIX64 "),", data & 0xFFFFFFFF);
}
else
{
@ -831,7 +850,7 @@ void ZDisplayList::Opcode_G_VTX(uint64_t data, char* line)
{
segptr_t segmented = data & 0xFFFFFFFF;
references.push_back(segmented);
parent->AddDeclaration(segmented, DeclarationAlignment::Align16, 16, "Vtx",
parent->AddDeclaration(segmented, DeclarationAlignment::Align8, 16, "Vtx",
StringHelper::Sprintf("0x%08X", segmented), "");
return;
}
@ -943,7 +962,7 @@ void ZDisplayList::Opcode_G_SETTIMG(uint64_t data, const std::string& prefix, ch
sprintf(texStr, "%sTex_%06X", prefix.c_str(), texAddress);
else
{
sprintf(texStr, "0x%08lX", data & 0xFFFFFFFF);
sprintf(texStr, "0x%08" PRIX64, data & 0xFFFFFFFF);
}
sprintf(line, "gsDPSetTextureImage(%s, %s, %i, %s),", fmtTbl[fmt], sizTbl[siz], www + 1,
@ -1747,7 +1766,7 @@ void ZDisplayList::DeclareReferences(const std::string& prefix)
if (vertices.size() > 0)
{
std::vector<std::pair<uint32_t, std::vector<ZVtx>>> verticesSorted(vertices.begin(),
vertices.end());
vertices.end());
for (size_t i = 0; i < verticesSorted.size() - 1; i++)
{
@ -1795,7 +1814,7 @@ void ZDisplayList::DeclareReferences(const std::string& prefix)
if (vertices.size() > 0)
{
std::vector<std::pair<uint32_t, std::vector<ZVtx>>> verticesSorted(vertices.begin(),
vertices.end());
vertices.end());
for (size_t i = 0; i < verticesSorted.size() - 1; i++)
{
@ -1889,10 +1908,10 @@ std::string ZDisplayList::ProcessLegacy(const std::string& prefix)
}
auto end = std::chrono::steady_clock::now();
auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
int64_t diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG && diff > 5)
printf("F3DOP: 0x%02X, TIME: %lims\n", opcode, diff);
printf("F3DOP: 0x%02X, TIME: %" PRIi64 "ms\n", opcode, diff);
sourceOutput += line;
@ -1973,7 +1992,7 @@ bool ZDisplayList::TextureGenCheck(int32_t texWidth, int32_t texHeight, uint32_t
}
else
{
// Try to find a non-external file (ie, one we are actually extracting)
// Try to find a non-external file (i.e., one we are actually extracting)
// which has the same segment number we are looking for.
for (auto& otherFile : Globals::Instance->cfg.segmentRefFiles[segmentNumber])
{

View file

@ -8,6 +8,7 @@
#include "Globals.h"
#include "OutputFormatter.h"
#include "Utils/BinaryWriter.h"
#include "Utils/BitConverter.h"
#include "Utils/Directory.h"
#include "Utils/File.h"
#include "Utils/MemoryStream.h"
@ -192,7 +193,7 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
rawData = File::ReadAllBytes((basePath / name).string());
if (reader->Attribute("RangeEnd") == nullptr)
rangeEnd = rawData.size();
rangeEnd = rawData.size();
}
std::unordered_set<std::string> nameSet;
@ -378,7 +379,7 @@ void ZFile::ExtractResources()
ZResourceExporter* exporter = Globals::Instance->GetExporter(res->GetResourceType());
if (exporter != nullptr)
{
//exporter->Save(res, Globals::Instance->outputPath.string(), &writerFile);
// exporter->Save(res, Globals::Instance->outputPath.string(), &writerFile);
exporter->Save(res, Globals::Instance->outputPath.string(), &writerRes);
}
@ -391,7 +392,7 @@ void ZFile::ExtractResources()
File::WriteAllBytes(StringHelper::Sprintf("%s%s.bin",
Globals::Instance->outputPath.string().c_str(),
GetName().c_str()),
memStreamFile->ToVector());
memStreamFile->ToVector());
}
writerFile.Close();
@ -949,9 +950,6 @@ std::string ZFile::ProcessDeclarations()
defines += ProcessTextureIntersections(name);
// Account for padding/alignment
uint32_t lastAddr = 0;
// printf("RANGE START: 0x%06X - RANGE END: 0x%06X\n", rangeStart, rangeEnd);
// Optimization: See if there are any arrays side by side that can be merged...
@ -1002,43 +1000,6 @@ std::string ZFile::ProcessDeclarations()
{
while (item.second->size % 4 != 0)
item.second->size++;
if (lastAddr != 0)
{
if (item.second->alignment == DeclarationAlignment::Align16)
{
int32_t curPtr = lastAddr + declarations[lastAddr]->size;
while (curPtr % 4 != 0)
{
declarations[lastAddr]->size++;
curPtr++;
}
}
else if (item.second->alignment == DeclarationAlignment::Align8)
{
size_t curPtr = lastAddr + declarations[lastAddr]->size;
while (curPtr % 4 != 0)
{
declarations[lastAddr]->size++;
curPtr++;
}
while (curPtr % 8 != 0)
{
char buffer[2048];
sprintf(buffer, "u32 %s_align%02zX = 0;\n", name.c_str(), curPtr);
item.second->preText = buffer + item.second->preText;
declarations[lastAddr]->size += 4;
curPtr += 4;
}
}
}
lastAddr = item.first;
}
HandleUnaccountedData();
@ -1199,14 +1160,15 @@ void ZFile::HandleUnaccountedData()
{
uint32_t lastAddr = 0;
uint32_t lastSize = 0;
std::vector<uint32_t> declsAddresses;
std::vector<offset_t> declsAddresses;
for (const auto& item : declarations)
{
declsAddresses.push_back(item.first);
}
bool breakLoop = false;
for (uint32_t currentAddress : declsAddresses)
for (offset_t currentAddress : declsAddresses)
{
if (currentAddress >= rangeEnd)
{
@ -1235,7 +1197,7 @@ void ZFile::HandleUnaccountedData()
}
}
bool ZFile::HandleUnaccountedAddress(uint32_t currentAddress, uint32_t lastAddr, uint32_t& lastSize)
bool ZFile::HandleUnaccountedAddress(offset_t currentAddress, offset_t lastAddr, uint32_t& lastSize)
{
if (currentAddress != lastAddr && declarations.find(lastAddr) != declarations.end())
{
@ -1275,6 +1237,29 @@ bool ZFile::HandleUnaccountedAddress(uint32_t currentAddress, uint32_t lastAddr,
xmlFilePath.c_str(), currentAddress, name.c_str(), rawData.size()));
}
// Handle Align8
if (currentAddress % 8 == 0 && diff % 8 != 0)
{
Declaration* currentDecl = GetDeclaration(currentAddress);
if (currentDecl != nullptr)
{
if (currentDecl->alignment == DeclarationAlignment::Align8)
{
// Check removed bytes are zeroes
if (BitConverter::ToUInt32BE(rawData, unaccountedAddress + diff - 4) == 0)
{
diff -= 4;
}
}
if (diff == 0)
{
return false;
}
}
}
for (int i = 0; i < diff; i++)
{
uint8_t val = rawData.at(unaccountedAddress + i);
@ -1320,7 +1305,10 @@ bool ZFile::HandleUnaccountedAddress(uint32_t currentAddress, uint32_t lastAddr,
StringHelper::Sprintf("%s_%s_%06X", name.c_str(), unaccountedPrefix.c_str(),
unaccountedAddress),
diff, src);
decl->isUnaccounted = true;
if (Globals::Instance->forceUnaccountedStatic)
decl->staticConf = StaticConfig::On;
if (nonZeroUnaccounted)
{

View file

@ -133,5 +133,5 @@ protected:
std::string ProcessTextureIntersections(const std::string& prefix);
void HandleUnaccountedData();
bool HandleUnaccountedAddress(uint32_t currentAddress, uint32_t lastAddr, uint32_t& lastSize);
bool HandleUnaccountedAddress(offset_t currentAddress, offset_t lastAddr, uint32_t& lastSize);
};

View file

@ -228,8 +228,8 @@ std::string ZLimb::GetBodySourceCode() const
{
std::string childName;
std::string siblingName;
Globals::Instance->GetSegmentedPtrName(childPtr, parent, "Gfx", childName);
Globals::Instance->GetSegmentedPtrName(siblingPtr, parent, "Gfx", siblingName);
Globals::Instance->GetSegmentedPtrName(childPtr, parent, "LegacyLimb", childName);
Globals::Instance->GetSegmentedPtrName(siblingPtr, parent, "LegacyLimb", siblingName);
entryStr += StringHelper::Sprintf("%s,\n", dListStr.c_str());
entryStr +=

View file

@ -0,0 +1,57 @@
#include "ZPointer.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZFile.h"
REGISTER_ZFILENODE(Pointer, ZPointer);
ZPointer::ZPointer(ZFile* nParent) : ZResource(nParent)
{
RegisterRequiredAttribute("Type");
}
void ZPointer::ParseXML(tinyxml2::XMLElement* reader)
{
ZResource::ParseXML(reader);
type = registeredAttributes.at("Type").value;
}
void ZPointer::ParseRawData()
{
auto& rawData = parent->GetRawData();
ptr = BitConverter::ToUInt32BE(rawData, rawDataIndex);
}
std::string ZPointer::GetBodySourceCode() const
{
std::string ptrName;
Globals::Instance->GetSegmentedPtrName(ptr, parent, "", ptrName);
return ptrName;
}
bool ZPointer::DoesSupportArray() const
{
return true;
}
std::string ZPointer::GetSourceTypeName() const
{
return type + "*";
}
ZResourceType ZPointer::GetResourceType() const
{
return ZResourceType::Pointer;
}
size_t ZPointer::GetRawDataSize() const
{
return 0x04;
}

View file

@ -0,0 +1,22 @@
#pragma once
#include "ZResource.h"
class ZPointer : public ZResource
{
public:
segptr_t ptr = SEGMENTED_NULL;
std::string type;
ZPointer(ZFile* nParent);
void ParseXML(tinyxml2::XMLElement* reader) override;
void ParseRawData() override;
std::string GetBodySourceCode() const override;
bool DoesSupportArray() const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
size_t GetRawDataSize() const override;
};

View file

@ -38,6 +38,7 @@ enum class ZResourceType
Mtx,
Path,
PlayerAnimationData,
Pointer,
Room,
RoomCommand,
Scalar,

View file

@ -152,7 +152,6 @@ void PolygonDlist::GetSourceOutputCode(const std::string& prefix)
DeclareVar(prefix, bodyStr);
else
decl->text = bodyStr;
}
std::string PolygonDlist::GetSourceTypeName() const

View file

@ -1,6 +1,8 @@
#include "SetSpecialObjects.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "ZRoom/ZNames.h"
SetSpecialObjects::SetSpecialObjects(ZFile* nParent) : ZRoomCommand(nParent)
{
@ -15,8 +17,10 @@ void SetSpecialObjects::ParseRawData()
std::string SetSpecialObjects::GetBodySourceCode() const
{
return StringHelper::Sprintf("SCENE_CMD_SPECIAL_FILES(0x%02X, 0x%04X)", elfMessage,
globalObject);
std::string objectName = ZNames::GetObjectName(globalObject);
return StringHelper::Sprintf("SCENE_CMD_SPECIAL_FILES(0x%02X, %s)", elfMessage,
objectName.c_str());
}
std::string SetSpecialObjects::GetCommandCName() const

View file

@ -2,7 +2,9 @@
#include <algorithm>
#include <cassert>
#include <chrono>
#include <cinttypes>
#include <string_view>
#include "Commands/EndMarker.h"
#include "Commands/SetActorCutsceneList.h"
#include "Commands/SetActorList.h"
@ -259,9 +261,10 @@ void ZRoom::ParseRawData()
if (Globals::Instance->profile)
{
auto end = std::chrono::steady_clock::now();
auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
int64_t diff =
std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
if (diff > 50)
printf("OP: %s, TIME: %lims\n", cmd->GetCommandCName().c_str(), diff);
printf("OP: %s, TIME: %" PRIi64 "ms\n", cmd->GetCommandCName().c_str(), diff);
}
cmd->cmdIndex = currentIndex;

View file

@ -139,7 +139,7 @@ ZResourceType ZSkeleton::GetResourceType() const
DeclarationAlignment ZSkeleton::GetDeclarationAlignment() const
{
return DeclarationAlignment::Align16;
return DeclarationAlignment::Align4;
}
uint8_t ZSkeleton::GetLimbCount()

View file

@ -16,6 +16,7 @@ ZTexture::ZTexture(ZFile* nParent) : ZResource(nParent)
{
width = 0;
height = 0;
dWordAligned = true;
RegisterRequiredAttribute("Width");
RegisterRequiredAttribute("Height");
@ -105,10 +106,7 @@ void ZTexture::ParseXML(tinyxml2::XMLElement* reader)
void ZTexture::ParseRawData()
{
if (rawDataIndex % 8 != 0)
{
HANDLE_WARNING_RESOURCE(WarningType::NotImplemented, parent, this, rawDataIndex,
"this texture is not 64-bit aligned", "");
}
dWordAligned = false;
switch (format)
{
@ -724,7 +722,12 @@ void ZTexture::Save(const fs::path& outFolder)
if (!Directory::Exists(outPath.string()))
Directory::CreateDirectory(outPath.string());
auto outFileName = outPath / (outName + "." + GetExternalExtension() + ".png");
fs::path outFileName;
if (!dWordAligned)
outFileName = outPath / (outName + ".u32" + "." + GetExternalExtension() + ".png");
else
outFileName = outPath / (outName + +"." + GetExternalExtension() + ".png");
#ifdef TEXTURE_DEBUG
printf("Saving PNG: %s\n", outFileName.c_str());
@ -745,7 +748,7 @@ Declaration* ZTexture::DeclareVar(const std::string& prefix,
{
std::string auxName = name;
std::string auxOutName = outName;
std::string incStr;
if (auxName == "")
auxName = GetDefaultName(prefix);
@ -754,8 +757,12 @@ Declaration* ZTexture::DeclareVar(const std::string& prefix,
auto filepath = Globals::Instance->outputPath / fs::path(auxOutName).stem();
std::string incStr =
StringHelper::Sprintf("%s.%s.inc.c", filepath.c_str(), GetExternalExtension().c_str());
if (dWordAligned)
incStr =
StringHelper::Sprintf("%s.%s.inc.c", filepath.c_str(), GetExternalExtension().c_str());
else
incStr = StringHelper::Sprintf("%s.u32.%s.inc.c", filepath.c_str(),
GetExternalExtension().c_str());
if (!Globals::Instance->cfg.texturePool.empty())
{
@ -765,13 +772,19 @@ Declaration* ZTexture::DeclareVar(const std::string& prefix,
const auto& poolEntry = Globals::Instance->cfg.texturePool.find(hash);
if (poolEntry != Globals::Instance->cfg.texturePool.end())
{
incStr = StringHelper::Sprintf("%s.%s.inc.c", poolEntry->second.path.c_str(),
GetExternalExtension().c_str());
if (dWordAligned)
incStr = StringHelper::Sprintf("%s.%s.inc.c", poolEntry->second.path.c_str(),
GetExternalExtension().c_str());
else
incStr = StringHelper::Sprintf("%s.u32.%s.inc.c", poolEntry->second.path.c_str(),
GetExternalExtension().c_str());
}
}
size_t texSizeDivisor = (dWordAligned) ? 8 : 4;
Declaration* decl = parent->AddDeclarationIncludeArray(
rawDataIndex, incStr, GetRawDataSize(), GetSourceTypeName(), auxName, GetRawDataSize() / 8);
Declaration* decl = parent->AddDeclarationIncludeArray(rawDataIndex, incStr, GetRawDataSize(),
GetSourceTypeName(), auxName,
GetRawDataSize() / texSizeDivisor);
decl->staticConf = staticConf;
return decl;
}
@ -779,15 +792,17 @@ Declaration* ZTexture::DeclareVar(const std::string& prefix,
std::string ZTexture::GetBodySourceCode() const
{
std::string sourceOutput;
for (size_t i = 0; i < textureDataRaw.size(); i += 8)
size_t texSizeInc = (dWordAligned) ? 8 : 4;
for (size_t i = 0; i < textureDataRaw.size(); i += texSizeInc)
{
if (i % 32 == 0)
sourceOutput += " ";
sourceOutput +=
StringHelper::Sprintf("0x%016llX, ", BitConverter::ToUInt64BE(textureDataRaw, i));
if (dWordAligned)
sourceOutput +=
StringHelper::Sprintf("0x%016llX, ", BitConverter::ToUInt64BE(textureDataRaw, i));
else
sourceOutput +=
StringHelper::Sprintf("0x%08llX, ", BitConverter::ToUInt32BE(textureDataRaw, i));
if (i % 32 == 24)
sourceOutput += StringHelper::Sprintf(" // 0x%06X \n", rawDataIndex + ((i / 32) * 32));
}
@ -812,7 +827,7 @@ ZResourceType ZTexture::GetResourceType() const
std::string ZTexture::GetSourceTypeName() const
{
return "u64";
return dWordAligned ? "u64" : "u32";
}
void ZTexture::CalcHash()

View file

@ -54,6 +54,7 @@ public:
ZTexture(ZFile* nParent);
bool isPalette = false;
bool dWordAligned = true;
void ExtractFromBinary(uint32_t nRawDataIndex, int32_t nWidth, int32_t nHeight,
TextureType nType, bool nIsPalette);

View file

@ -82,5 +82,5 @@ std::string ZVtx::GetExternalExtension() const
DeclarationAlignment ZVtx::GetDeclarationAlignment() const
{
return DeclarationAlignment::Align16;
return DeclarationAlignment::Align8;
}