ZAPD is now multi-threaded.

This commit is contained in:
Jack Walker 2022-03-31 02:47:44 -04:00
commit e4855fba0b
48 changed files with 680 additions and 192 deletions

View file

@ -209,7 +209,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
break; break;
case G_MTX: case G_MTX:
{ {
if ((!Globals::Instance->HasSegment(GETSEGNUM(data))) || ((data & 0xFFFFFFFF) == 0x07000000)) // En_Zf and En_Ny place a DL in segment 7 if ((!Globals::Instance->HasSegment(GETSEGNUM(data), res->parent->workerID)) || ((data & 0xFFFFFFFF) == 0x07000000)) // En_Zf and En_Ny place a DL in segment 7
{ {
uint32_t pp = (data & 0x000000FF00000000) >> 32; uint32_t pp = (data & 0x000000FF00000000) >> 32;
uint32_t mm = (data & 0x00000000FFFFFFFF); uint32_t mm = (data & 0x00000000FFFFFFFF);
@ -404,7 +404,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
//case G_BRANCH_Z: //case G_BRANCH_Z:
case G_DL: case G_DL:
{ {
if ((!Globals::Instance->HasSegment(GETSEGNUM(data)) && (int)opF3D != G_BRANCH_Z) if ((!Globals::Instance->HasSegment(GETSEGNUM(data), res->parent->workerID) && (int)opF3D != G_BRANCH_Z)
|| ((data & 0xFFFFFFFF) == 0x07000000)) // En_Zf and En_Ny place a DL in segment 7 || ((data & 0xFFFFFFFF) == 0x07000000)) // En_Zf and En_Ny place a DL in segment 7
{ {
int32_t pp = (data & 0x00FF000000000000) >> 56; int32_t pp = (data & 0x00FF000000000000) >> 56;
@ -681,7 +681,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
uint32_t seg = data & 0xFFFFFFFF; uint32_t seg = data & 0xFFFFFFFF;
int32_t texAddress = Seg2Filespace(data, dList->parent->baseAddress); int32_t texAddress = Seg2Filespace(data, dList->parent->baseAddress);
if (!Globals::Instance->HasSegment(GETSEGNUM(seg))) if (!Globals::Instance->HasSegment(GETSEGNUM(seg), res->parent->workerID))
{ {
int32_t __ = (data & 0x00FF000000000000) >> 48; int32_t __ = (data & 0x00FF000000000000) >> 48;
int32_t www = (data & 0x00000FFF00000000) >> 32; int32_t www = (data & 0x00000FFF00000000) >> 32;
@ -699,7 +699,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
else else
{ {
std::string texName = ""; std::string texName = "";
bool foundDecl = Globals::Instance->GetSegmentedPtrName(seg, dList->parent, "", texName); bool foundDecl = Globals::Instance->GetSegmentedPtrName(seg, dList->parent, "", texName, res->parent->workerID);
int32_t __ = (data & 0x00FF000000000000) >> 48; int32_t __ = (data & 0x00FF000000000000) >> 48;
int32_t www = (data & 0x00000FFF00000000) >> 32; int32_t www = (data & 0x00000FFF00000000) >> 32;
@ -718,7 +718,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
if (foundDecl) if (foundDecl)
{ {
ZFile* assocFile = Globals::Instance->GetSegment(GETSEGNUM(seg)); ZFile* assocFile = Globals::Instance->GetSegment(GETSEGNUM(seg), res->parent->workerID);
std::string assocFileName = assocFile->GetName(); std::string assocFileName = assocFile->GetName();
std::string fName = ""; std::string fName = "";
@ -765,8 +765,6 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
auto segOffset = GETSEGOFFSET(addr); auto segOffset = GETSEGOFFSET(addr);
Declaration* vtxDecl = dList->parent->GetDeclarationRanged(segOffset); Declaration* vtxDecl = dList->parent->GetDeclarationRanged(segOffset);
//std::string vtxName = "";
//bool foundDecl = Globals::Instance->GetSegmentedPtrName(seg, dList->parent, "", vtxName);
int32_t aa = (data & 0x000000FF00000000ULL) >> 32; int32_t aa = (data & 0x000000FF00000000ULL) >> 32;
int32_t nn = (data & 0x000FF00000000000ULL) >> 44; int32_t nn = (data & 0x000FF00000000000ULL) >> 44;

View file

@ -407,7 +407,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
{ {
uint32_t seg = cmdHeaders->headers[i] & 0xFFFFFFFF; uint32_t seg = cmdHeaders->headers[i] & 0xFFFFFFFF;
std::string headerName = ""; std::string headerName = "";
bool foundDecl = Globals::Instance->GetSegmentedPtrName(seg, room->parent, "", headerName); bool foundDecl = Globals::Instance->GetSegmentedPtrName(seg, room->parent, "", headerName, res->parent->workerID);
if (headerName == "NULL") if (headerName == "NULL")
writer->Write(""); writer->Write("");
else else
@ -443,7 +443,7 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
SetCutscenes* cmdSetCutscenes = (SetCutscenes*)cmd; SetCutscenes* cmdSetCutscenes = (SetCutscenes*)cmd;
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdSetCutscenes->cmdArg2, room->parent, "CutsceneData", listName); Globals::Instance->GetSegmentedPtrName(cmdSetCutscenes->cmdArg2, room->parent, "CutsceneData", listName, res->parent->workerID);
std::string fName = OTRExporter_DisplayList::GetPathToRes(room, listName); std::string fName = OTRExporter_DisplayList::GetPathToRes(room, listName);
//std::string fName = StringHelper::Sprintf("%s\\%s", OTRExporter_DisplayList::GetParentFolderName(room).c_str(), listName.c_str()); //std::string fName = StringHelper::Sprintf("%s\\%s", OTRExporter_DisplayList::GetParentFolderName(room).c_str(), listName.c_str());
writer->Write(fName); writer->Write(fName);

View file

@ -23,7 +23,7 @@ void OTRExporter_Skeleton::Save(ZResource* res, const fs::path& outPath, BinaryW
Declaration* skelDecl = skel->parent->GetDeclarationRanged(GETSEGOFFSET(skel->limbsTable.limbsAddresses[i])); Declaration* skelDecl = skel->parent->GetDeclarationRanged(GETSEGOFFSET(skel->limbsTable.limbsAddresses[i]));
std::string name; std::string name;
bool foundDecl = Globals::Instance->GetSegmentedPtrName(skel->limbsTable.limbsAddresses[i], skel->parent, "", name); bool foundDecl = Globals::Instance->GetSegmentedPtrName(skel->limbsTable.limbsAddresses[i], skel->parent, "", name, res->parent->workerID);
if (foundDecl) if (foundDecl)
{ {
if (name.at(0) == '&') if (name.at(0) == '&')

View file

@ -86,7 +86,7 @@ void OTRExporter_SkeletonLimb::Save(ZResource* res, const fs::path& outPath, Bin
if (limb->childPtr != 0) if (limb->childPtr != 0)
{ {
std::string name; std::string name;
bool foundDecl = Globals::Instance->GetSegmentedPtrName(limb->childPtr, limb->parent, "", name); bool foundDecl = Globals::Instance->GetSegmentedPtrName(limb->childPtr, limb->parent, "", name, res->parent->workerID);
if (foundDecl) if (foundDecl)
{ {
if (name.at(0) == '&') if (name.at(0) == '&')
@ -107,7 +107,7 @@ void OTRExporter_SkeletonLimb::Save(ZResource* res, const fs::path& outPath, Bin
if (limb->siblingPtr != 0) if (limb->siblingPtr != 0)
{ {
std::string name; std::string name;
bool foundDecl = Globals::Instance->GetSegmentedPtrName(limb->siblingPtr, limb->parent, "", name); bool foundDecl = Globals::Instance->GetSegmentedPtrName(limb->siblingPtr, limb->parent, "", name, res->parent->workerID);
if (foundDecl) if (foundDecl)
{ {
if (name.at(0) == '&') if (name.at(0) == '&')
@ -128,7 +128,7 @@ void OTRExporter_SkeletonLimb::Save(ZResource* res, const fs::path& outPath, Bin
if (limb->dListPtr != 0) if (limb->dListPtr != 0)
{ {
std::string name; std::string name;
bool foundDecl = Globals::Instance->GetSegmentedPtrName(limb->dListPtr, limb->parent, "", name); bool foundDecl = Globals::Instance->GetSegmentedPtrName(limb->dListPtr, limb->parent, "", name, res->parent->workerID);
if (foundDecl) if (foundDecl)
{ {
if (name.at(0) == '&') if (name.at(0) == '&')
@ -149,7 +149,7 @@ void OTRExporter_SkeletonLimb::Save(ZResource* res, const fs::path& outPath, Bin
if (limb->dList2Ptr != 0) if (limb->dList2Ptr != 0)
{ {
std::string name; std::string name;
bool foundDecl = Globals::Instance->GetSegmentedPtrName(limb->dList2Ptr, limb->parent, "", name); bool foundDecl = Globals::Instance->GetSegmentedPtrName(limb->dList2Ptr, limb->parent, "", name, res->parent->workerID);
if (foundDecl) if (foundDecl)
{ {
if (name.at(0) == '&') if (name.at(0) == '&')

View file

@ -72,8 +72,15 @@ void OTRGame::init(){
} }
} }
void ExtractRom() { void ExtractRom()
const WriteResult result = ExtractBaserom(patched_rom); {
WriteResult result;
if (oldExtractMode)
ExtractBaserom(patched_rom);
else
result.error = NULLSTR;
if (result.error == NULLSTR) { if (result.error == NULLSTR) {
if (MoonUtils::exists("oot.otr")) MoonUtils::rm("oot.otr"); if (MoonUtils::exists("oot.otr")) MoonUtils::rm("oot.otr");
if (MoonUtils::exists("Extract")) MoonUtils::rm("Extract"); if (MoonUtils::exists("Extract")) MoonUtils::rm("Extract");

View file

@ -112,7 +112,7 @@ void startWorker(RomVersion version) {
else else
{ {
std::string execStr = Util::format("assets/extractor/%s", isWindows() ? "ZAPD.exe" : "ZAPD.out"); std::string execStr = Util::format("assets/extractor/%s", isWindows() ? "ZAPD.exe" : "ZAPD.out");
std::string args = Util::format(" ed -eh -i %s -b tmp/baserom/ -o %s -osf %s -gsf 1 -rconf assets/extractor/Config_%s.xml -se OTR %s", path.c_str(), path + "../", path + "../", GetXMLVersion(version).c_str(), ""); std::string args = Util::format(" ed -eh -i %s -b tmp/rom.z64 -fl assets/extractor/filelists -o %s -osf %s -gsf 1 -rconf assets/extractor/Config_%s.xml -se OTR %s", path.c_str(), path + "../", path + "../", GetXMLVersion(version).c_str(), "");
ProcessResult result = NativeFS->LaunchProcess(execStr + args); ProcessResult result = NativeFS->LaunchProcess(execStr + args);
if (result.exitCode != 0) { if (result.exitCode != 0) {

View file

15
ZAPDTR/ZAPD/FileWorker.h Normal file
View file

@ -0,0 +1,15 @@
#pragma once
#include <map>
#include <string>
#include <vector>
#include "ZFile.h"
class FileWorker
{
public:
std::vector<ZFile*> files;
std::vector<ZFile*> externalFiles;
std::vector<int32_t> segments;
std::map<int32_t, std::vector<ZFile*>> segmentRefFiles;
};

View file

@ -34,30 +34,88 @@ Globals::~Globals()
} }
} }
void Globals::AddSegment(int32_t segment, ZFile* file) void Globals::AddSegment(int32_t segment, ZFile* file, int workerID)
{ {
if (!Globals::Instance->singleThreaded)
{
auto worker = workerData[workerID];
if (std::find(worker->segments.begin(), worker->segments.end(), segment) ==
worker->segments.end())
worker->segments.push_back(segment);
if (worker->segmentRefFiles.find(segment) == worker->segmentRefFiles.end())
worker->segmentRefFiles[segment] = std::vector<ZFile*>();
worker->segmentRefFiles[segment].push_back(file);
}
else
{
if (std::find(segments.begin(), segments.end(), segment) == segments.end()) if (std::find(segments.begin(), segments.end(), segment) == segments.end())
segments.push_back(segment); segments.push_back(segment);
if (cfg.segmentRefFiles.find(segment) == cfg.segmentRefFiles.end()) if (cfg.segmentRefFiles.find(segment) == cfg.segmentRefFiles.end())
cfg.segmentRefFiles[segment] = std::vector<ZFile*>(); cfg.segmentRefFiles[segment] = std::vector<ZFile*>();
cfg.segmentRefFiles[segment].push_back(file); cfg.segmentRefFiles[segment].push_back(file);
}
} }
bool Globals::HasSegment(int32_t segment) bool Globals::HasSegment(int32_t segment, int workerID)
{ {
if (!Globals::Instance->singleThreaded)
return std::find(workerData[workerID]->segments.begin(),
workerData[workerID]->segments.end(), segment) != workerData[workerID]->segments.end();
else
return std::find(segments.begin(), segments.end(), segment) != segments.end(); return std::find(segments.begin(), segments.end(), segment) != segments.end();
} }
ZFile* Globals::GetSegment(int32_t segment) ZFile* Globals::GetSegment(int32_t segment, int workerID)
{ {
if (HasSegment(segment)) if (!Globals::Instance->singleThreaded)
{
if (HasSegment(segment, workerID))
{
int idx = std::find(workerData[workerID]->segments.begin(),
workerData[workerID]->segments.end(), segment) -
workerData[workerID]->segments.begin();
return workerData[workerID]->files[idx];
}
else
return nullptr;
}
else
{
if (HasSegment(segment, workerID))
{ {
int idx = std::find(segments.begin(), segments.end(), segment) - segments.begin(); int idx = std::find(segments.begin(), segments.end(), segment) - segments.begin();
return files[idx]; return files[idx];
} }
else else
return nullptr; return nullptr;
}
}
std::map<int32_t, std::vector<ZFile*>> Globals::GetSegmentRefFiles(int workerID)
{
if (!Globals::Instance->singleThreaded)
return workerData[workerID]->segmentRefFiles;
else
return cfg.segmentRefFiles;
}
void Globals::AddFile(ZFile* file, int workerID)
{
if (singleThreaded)
files.push_back(file);
else
workerData[workerID]->files.push_back(file);
}
void Globals::AddExternalFile(ZFile* file, int workerID)
{
if (singleThreaded)
externalFiles.push_back(file);
else
workerData[workerID]->externalFiles.push_back(file);
} }
std::map<std::string, ExporterSet*>& Globals::GetExporterMap() std::map<std::string, ExporterSet*>& Globals::GetExporterMap()
@ -96,13 +154,19 @@ ExporterSet* Globals::GetExporterSet()
std::vector<uint8_t> Globals::GetBaseromFile(std::string fileName) std::vector<uint8_t> Globals::GetBaseromFile(std::string fileName)
{ {
if (fileMode == ZFileMode::ExtractDirectory) if (fileMode == ZFileMode::ExtractDirectory)
return rom->GetFile(StringHelper::Split(fileName, "baserom/")[1]); {
if (StringHelper::Contains(fileName, "baserom/"))
fileName = StringHelper::Split(fileName, "baserom/")[1];
return rom->GetFile(fileName);
}
else else
return File::ReadAllBytes(fileName); return File::ReadAllBytes(fileName);
} }
bool Globals::GetSegmentedPtrName(segptr_t segAddress, ZFile* currentFile, bool Globals::GetSegmentedPtrName(segptr_t segAddress, ZFile* currentFile,
const std::string& expectedType, std::string& declName) const std::string& expectedType, std::string& declName, int workerID)
{ {
if (segAddress == 0) if (segAddress == 0)
{ {
@ -138,9 +202,11 @@ bool Globals::GetSegmentedPtrName(segptr_t segAddress, ZFile* currentFile,
if (currentFile->GetDeclarationPtrName(segAddress, expectedType, declName)) if (currentFile->GetDeclarationPtrName(segAddress, expectedType, declName))
return true; return true;
} }
else if (HasSegment(segment)) else if (HasSegment(segment, workerID))
{ {
for (auto file : cfg.segmentRefFiles[segment]) // OTRTODO: Multithreading
auto segs = GetSegmentRefFiles(workerID);
for (auto file : segs[segment])
{ {
offset = Seg2Filespace(segAddress, file->baseAddress); offset = Seg2Filespace(segAddress, file->baseAddress);
@ -184,7 +250,7 @@ bool Globals::GetSegmentedPtrName(segptr_t segAddress, ZFile* currentFile,
bool Globals::GetSegmentedArrayIndexedName(segptr_t segAddress, size_t elementSize, bool Globals::GetSegmentedArrayIndexedName(segptr_t segAddress, size_t elementSize,
ZFile* currentFile, const std::string& expectedType, ZFile* currentFile, const std::string& expectedType,
std::string& declName) std::string& declName, int workerID)
{ {
if (segAddress == 0) if (segAddress == 0)
{ {
@ -201,9 +267,11 @@ bool Globals::GetSegmentedArrayIndexedName(segptr_t segAddress, size_t elementSi
if (addressFound) if (addressFound)
return true; return true;
} }
else if (HasSegment(segment)) else if (HasSegment(segment, workerID))
{ {
for (auto file : cfg.segmentRefFiles[segment]) // OTRTODO: Multithreading
auto segs = GetSegmentRefFiles(workerID);
for (auto file : segs[segment])
{ {
if (file->IsSegmentedInFilespaceRange(segAddress)) if (file->IsSegmentedInFilespaceRange(segAddress))
{ {

View file

@ -6,6 +6,7 @@
#include "GameConfig.h" #include "GameConfig.h"
#include "ZFile.h" #include "ZFile.h"
#include <ZRom.h> #include <ZRom.h>
#include <FileWorker.h>
class ZRoom; class ZRoom;
@ -51,9 +52,10 @@ public:
bool outputCrc = false; bool outputCrc = false;
bool profile; // Measure performance of certain operations bool profile; // Measure performance of certain operations
bool useLegacyZDList; bool useLegacyZDList;
bool singleThreaded;
VerbosityLevel verbosity; // ZAPD outputs additional information VerbosityLevel verbosity; // ZAPD outputs additional information
ZFileMode fileMode; ZFileMode fileMode;
fs::path baseRomPath, inputPath, outputPath, sourceOutputPath, cfgPath; fs::path baseRomPath, inputPath, outputPath, sourceOutputPath, cfgPath, fileListPath;
TextureType texType; TextureType texType;
ZGame game; ZGame game;
GameConfig cfg; GameConfig cfg;
@ -68,6 +70,8 @@ public:
std::vector<ZFile*> externalFiles; std::vector<ZFile*> externalFiles;
std::vector<int32_t> segments; std::vector<int32_t> segments;
std::map<int, FileWorker*> workerData;
std::string currentExporter; 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); static void AddExporter(std::string exporterName, ExporterSet* exporterSet);
@ -75,9 +79,12 @@ public:
Globals(); Globals();
~Globals(); ~Globals();
void AddSegment(int32_t segment, ZFile* file); void AddSegment(int32_t segment, ZFile* file, int workerID);
bool HasSegment(int32_t segment); bool HasSegment(int32_t segment, int workerID);
ZFile* GetSegment(int32_t segment); ZFile* GetSegment(int32_t segment, int workerID);
std::map<int32_t, std::vector<ZFile*>> GetSegmentRefFiles(int workerID);
void AddFile(ZFile* file, int workerID);
void AddExternalFile(ZFile* file, int workerID);
ZResourceExporter* GetExporter(ZResourceType resType); ZResourceExporter* GetExporter(ZResourceType resType);
ExporterSet* GetExporterSet(); ExporterSet* GetExporterSet();
@ -93,8 +100,8 @@ public:
* in which case `declName` will be set to the address formatted as a pointer. * in which case `declName` will be set to the address formatted as a pointer.
*/ */
bool GetSegmentedPtrName(segptr_t segAddress, ZFile* currentFile, bool GetSegmentedPtrName(segptr_t segAddress, ZFile* currentFile,
const std::string& expectedType, std::string& declName); const std::string& expectedType, std::string& declName, int workerID);
bool GetSegmentedArrayIndexedName(segptr_t segAddress, size_t elementSize, ZFile* currentFile, bool GetSegmentedArrayIndexedName(segptr_t segAddress, size_t elementSize, ZFile* currentFile,
const std::string& expectedType, std::string& declName); const std::string& expectedType, std::string& declName, int workerID);
}; };

View file

@ -23,16 +23,20 @@
#include <string> #include <string>
#include <string_view> #include <string_view>
#include "tinyxml2.h" #include "tinyxml2.h"
#include <ctpl_stl.h>
//extern const char gBuildHash[]; //extern const char gBuildHash[];
const char gBuildHash[] = ""; const char gBuildHash[] = "";
bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath, bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath,
ZFileMode fileMode); ZFileMode fileMode, int workerID);
void BuildAssetTexture(const fs::path& pngFilePath, TextureType texType, const fs::path& outPath); void BuildAssetTexture(const fs::path& pngFilePath, TextureType texType, const fs::path& outPath);
void BuildAssetBackground(const fs::path& imageFilePath, const fs::path& outPath); void BuildAssetBackground(const fs::path& imageFilePath, const fs::path& outPath);
void BuildAssetBlob(const fs::path& blobFilePath, const fs::path& outPath); void BuildAssetBlob(const fs::path& blobFilePath, const fs::path& outPath);
int ExtractFunc(int workerID, int fileListSize, std::string fileListItem, ZFileMode fileMode);
volatile int numWorkersLeft = 0;
#if !defined(_MSC_VER) && !defined(__CYGWIN__) #if !defined(_MSC_VER) && !defined(__CYGWIN__)
#define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0])) #define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0]))
@ -182,6 +186,10 @@ int main(int argc, char* argv[])
{ {
Globals::Instance->cfgPath = argv[++i]; Globals::Instance->cfgPath = argv[++i];
} }
else if (arg == "-fl") // Set baserom filelist path
{
Globals::Instance->fileListPath = argv[++i];
}
else if (arg == "-rconf") // Read Config File else if (arg == "-rconf") // Read Config File
{ {
Globals::Instance->cfg.ReadConfigFile(argv[++i]); Globals::Instance->cfg.ReadConfigFile(argv[++i]);
@ -254,7 +262,7 @@ int main(int argc, char* argv[])
Globals::Instance->fileMode = fileMode; Globals::Instance->fileMode = fileMode;
if (fileMode == ZFileMode::ExtractDirectory) if (fileMode == ZFileMode::ExtractDirectory)
Globals::Instance->rom = new ZRom("baserom.z64"); Globals::Instance->rom = new ZRom(Globals::Instance->baseRomPath.string());
// We've parsed through our commands once. If an exporter exists, it's been set by now. // We've parsed through our commands once. If an exporter exists, it's been set by now.
// Now we'll parse through them again but pass them on to our exporter if one is available. // Now we'll parse through them again but pass them on to our exporter if one is available.
@ -281,7 +289,6 @@ int main(int argc, char* argv[])
if (exporterSet != nullptr && exporterSet->processFileModeFunc != nullptr) if (exporterSet != nullptr && exporterSet->processFileModeFunc != nullptr)
procFileModeSuccess = exporterSet->processFileModeFunc(fileMode); procFileModeSuccess = exporterSet->processFileModeFunc(fileMode);
if (!procFileModeSuccess) if (!procFileModeSuccess)
{ {
if (fileMode == ZFileMode::ExtractDirectory) if (fileMode == ZFileMode::ExtractDirectory)
@ -289,49 +296,44 @@ int main(int argc, char* argv[])
std::vector<std::string> fileList = std::vector<std::string> fileList =
Directory::ListFiles(Globals::Instance->inputPath.string()); Directory::ListFiles(Globals::Instance->inputPath.string());
const int num_threads = std::thread::hardware_concurrency();
ctpl::thread_pool pool(num_threads / 2);
bool parseSuccessful; bool parseSuccessful;
auto start = std::chrono::steady_clock::now(); auto start = std::chrono::steady_clock::now();
int fileListSize = fileList.size();
Globals::Instance->singleThreaded = false;
for (int i = 0; i < fileList.size(); i++) for (int i = 0; i < fileListSize; i++)
{ Globals::Instance->workerData[i] = new FileWorker();
printf("(%i / %i): %s\n", (i+1), fileList.size(), fileList[i].c_str());
for (auto& extFile : Globals::Instance->cfg.externalFiles) numWorkersLeft = fileListSize;
{
fs::path externalXmlFilePath =
Globals::Instance->cfg.externalXmlFolder / extFile.xmlPath;
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) for (int i = 0; i < fileListSize; i++)
{ {
printf("Parsing external file from config: '%s'\n", if (Globals::Instance->singleThreaded)
externalXmlFilePath.c_str()); {
ExtractFunc(i, fileList.size(), fileList[i], fileMode);
}
else
{
std::string fileListItem = fileList[i];
pool.push([i, fileListSize, fileListItem, fileMode](int) {
ExtractFunc(i, fileListSize, fileListItem, fileMode);
});
}
} }
parseSuccessful = Parse(externalXmlFilePath, Globals::Instance->baseRomPath, if (!Globals::Instance->singleThreaded)
extFile.outPath, ZFileMode::ExternalFile);
if (!parseSuccessful)
return 1;
}
parseSuccessful = Parse(fileList[i], Globals::Instance->baseRomPath,
Globals::Instance->outputPath, fileMode);
if (!parseSuccessful)
return 1;
for (int i = 0; i < Globals::Instance->files.size(); i++)
{ {
delete Globals::Instance->files[i]; while (true)
Globals::Instance->files.erase(Globals::Instance->files.begin() + i); {
i--; if (numWorkersLeft <= 0)
} break;
Globals::Instance->externalFiles.clear(); std::this_thread::sleep_for(std::chrono::milliseconds(250));
Globals::Instance->segments.clear(); }
Globals::Instance->cfg.segmentRefFiles.clear();
} }
auto end = std::chrono::steady_clock::now(); auto end = std::chrono::steady_clock::now();
@ -356,7 +358,7 @@ int main(int argc, char* argv[])
} }
parseSuccessful = Parse(externalXmlFilePath, Globals::Instance->baseRomPath, parseSuccessful = Parse(externalXmlFilePath, Globals::Instance->baseRomPath,
extFile.outPath, ZFileMode::ExternalFile); extFile.outPath, ZFileMode::ExternalFile, 0);
if (!parseSuccessful) if (!parseSuccessful)
return 1; return 1;
@ -364,7 +366,7 @@ int main(int argc, char* argv[])
parseSuccessful = parseSuccessful =
Parse(Globals::Instance->inputPath, Globals::Instance->baseRomPath, Parse(Globals::Instance->inputPath, Globals::Instance->baseRomPath,
Globals::Instance->outputPath, fileMode); Globals::Instance->outputPath, fileMode, 0);
if (!parseSuccessful) if (!parseSuccessful)
return 1; return 1;
} }
@ -403,8 +405,68 @@ int main(int argc, char* argv[])
return 0; return 0;
} }
int ExtractFunc(int workerID, int fileListSize, std::string fileListItem, ZFileMode fileMode)
{
bool parseSuccessful;
printf("(%i / %i): %s\n", (workerID + 1), fileListSize, fileListItem.c_str());
for (auto& extFile : Globals::Instance->cfg.externalFiles)
{
fs::path externalXmlFilePath = Globals::Instance->cfg.externalXmlFolder / extFile.xmlPath;
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO)
{
printf("Parsing external file from config: '%s'\n", externalXmlFilePath.c_str());
}
parseSuccessful = Parse(externalXmlFilePath, Globals::Instance->baseRomPath,
extFile.outPath, ZFileMode::ExternalFile, workerID);
if (!parseSuccessful)
return 1;
}
parseSuccessful = Parse(fileListItem, Globals::Instance->baseRomPath,
Globals::Instance->outputPath, fileMode, workerID);
if (!parseSuccessful)
return 1;
if (Globals::Instance->singleThreaded)
{
for (int i = 0; i < Globals::Instance->files.size(); i++)
{
delete Globals::Instance->files[i];
Globals::Instance->files.erase(Globals::Instance->files.begin() + i);
i--;
}
Globals::Instance->externalFiles.clear();
Globals::Instance->segments.clear();
Globals::Instance->cfg.segmentRefFiles.clear();
}
else
{
for (int i = 0; i < Globals::Instance->workerData[workerID]->files.size(); i++)
{
delete Globals::Instance->workerData[workerID]->files[i];
Globals::Instance->workerData[workerID]->files.erase(
Globals::Instance->workerData[workerID]->files.begin() +
i);
i--;
}
Globals::Instance->workerData[workerID]->externalFiles.clear();
Globals::Instance->workerData[workerID]->segments.clear();
Globals::Instance->workerData[workerID]->segmentRefFiles.clear();
numWorkersLeft--;
}
}
bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath, bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath,
ZFileMode fileMode) ZFileMode fileMode, int workerID)
{ {
tinyxml2::XMLDocument doc; tinyxml2::XMLDocument doc;
tinyxml2::XMLError eResult = doc.LoadFile(xmlFilePath.string().c_str()); tinyxml2::XMLError eResult = doc.LoadFile(xmlFilePath.string().c_str());
@ -432,11 +494,11 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path
{ {
if (std::string_view(child->Name()) == "File") if (std::string_view(child->Name()) == "File")
{ {
ZFile* file = new ZFile(fileMode, child, basePath, outPath, "", xmlFilePath); ZFile* file = new ZFile(fileMode, child, basePath, outPath, "", xmlFilePath, workerID);
Globals::Instance->files.push_back(file); Globals::Instance->AddFile(file, workerID);
if (fileMode == ZFileMode::ExternalFile) if (fileMode == ZFileMode::ExternalFile)
{ {
Globals::Instance->externalFiles.push_back(file); Globals::Instance->AddExternalFile(file, workerID);
file->isExternalFile = true; file->isExternalFile = true;
} }
} }
@ -469,7 +531,7 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path
} }
// Recursion. What can go wrong? // Recursion. What can go wrong?
Parse(externalXmlFilePath, basePath, externalOutFilePath, ZFileMode::ExternalFile); Parse(externalXmlFilePath, basePath, externalOutFilePath, ZFileMode::ExternalFile, workerID);
} }
else else
{ {
@ -488,7 +550,14 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path
if (exporterSet != nullptr && exporterSet->beginXMLFunc != nullptr) if (exporterSet != nullptr && exporterSet->beginXMLFunc != nullptr)
exporterSet->beginXMLFunc(); exporterSet->beginXMLFunc();
for (ZFile* file : Globals::Instance->files) std::vector<ZFile*> files;
if (Globals::Instance->singleThreaded)
files = Globals::Instance->files;
else
files = Globals::Instance->workerData[workerID]->files;
for (ZFile* file : files)
{ {
if (fileMode == ZFileMode::BuildSourceFile) if (fileMode == ZFileMode::BuildSourceFile)
file->BuildSourceFile(); file->BuildSourceFile();

View file

@ -199,8 +199,10 @@ std::string Struct_800A598C::GetBodySourceCode() const
{ {
std::string unk_8_Str; std::string unk_8_Str;
std::string unk_C_Str; std::string unk_C_Str;
Globals::Instance->GetSegmentedPtrName(unk_8, parent, "Struct_800A57C0", unk_8_Str); Globals::Instance->GetSegmentedPtrName(unk_8, parent, "Struct_800A57C0", unk_8_Str,
Globals::Instance->GetSegmentedPtrName(unk_C, parent, "Struct_800A598C_2", unk_C_Str); parent->workerID);
Globals::Instance->GetSegmentedPtrName(unk_C, parent, "Struct_800A598C_2", unk_C_Str,
parent->workerID);
std::string entryStr = StringHelper::Sprintf("\n\t\tARRAY_COUNTU(%s), ARRAY_COUNTU(%s),\n", std::string entryStr = StringHelper::Sprintf("\n\t\tARRAY_COUNTU(%s), ARRAY_COUNTU(%s),\n",
unk_8_Str.c_str(), unk_C_Str.c_str()); unk_8_Str.c_str(), unk_C_Str.c_str());
@ -316,8 +318,9 @@ std::string Struct_800A5E28::GetBodySourceCode() const
{ {
std::string unk_4_Str; std::string unk_4_Str;
std::string unk_8_Str; std::string unk_8_Str;
Globals::Instance->GetSegmentedPtrName(unk_4, parent, "Struct_800A598C", unk_4_Str); Globals::Instance->GetSegmentedPtrName(unk_4, parent, "Struct_800A598C", unk_4_Str,
Globals::Instance->GetSegmentedPtrName(unk_8, parent, "Gfx", unk_8_Str); parent->workerID);
Globals::Instance->GetSegmentedPtrName(unk_8, parent, "Gfx", unk_8_Str, parent->workerID);
std::string entryStr = "\n"; std::string entryStr = "\n";
entryStr += StringHelper::Sprintf("\t%i, ARRAY_COUNTU(%s),\n", unk_0, unk_4_Str.c_str()); entryStr += StringHelper::Sprintf("\t%i, ARRAY_COUNTU(%s),\n", unk_0, unk_4_Str.c_str());

View file

@ -3,7 +3,7 @@
void OutputFormatter::Flush() void OutputFormatter::Flush()
{ {
//if (!Globals::Instance->otrMode) //if (!Globals::Instance->otrMode) // OTRTODO: MULTITHREADING
{ {
if (col > lineLimit && !Globals::Instance->otrMode) if (col > lineLimit && !Globals::Instance->otrMode)
{ {
@ -31,6 +31,10 @@ void OutputFormatter::Flush()
int OutputFormatter::Write(const char* buf, int count) int OutputFormatter::Write(const char* buf, int count)
{ {
// OTRTODO
//if (!Globals::Instance->singleThreaded)
//return 0;
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
char c = buf[i]; char c = buf[i];
@ -92,7 +96,7 @@ int OutputFormatter::Write(const std::string& buf)
return Write(buf.data(), buf.size()); return Write(buf.data(), buf.size());
} }
OutputFormatter* OutputFormatter::Instance; __declspec(thread) OutputFormatter* OutputFormatter::Instance;
int OutputFormatter::WriteStatic(const char* buf, int count) int OutputFormatter::WriteStatic(const char* buf, int count)
{ {

View file

@ -25,7 +25,7 @@ private:
void Flush(); void Flush();
static OutputFormatter* Instance; static __declspec(thread) OutputFormatter* Instance;
static int WriteStatic(const char* buf, int count); static int WriteStatic(const char* buf, int count);
public: public:

View file

@ -184,6 +184,7 @@
<ClCompile Include="..\lib\libgfxd\uc_f3dex2.c" /> <ClCompile Include="..\lib\libgfxd\uc_f3dex2.c" />
<ClCompile Include="..\lib\libgfxd\uc_f3dexb.c" /> <ClCompile Include="..\lib\libgfxd\uc_f3dexb.c" />
<ClCompile Include="Declaration.cpp" /> <ClCompile Include="Declaration.cpp" />
<ClCompile Include="FileWorker.cpp" />
<ClCompile Include="GameConfig.cpp" /> <ClCompile Include="GameConfig.cpp" />
<ClCompile Include="Globals.cpp" /> <ClCompile Include="Globals.cpp" />
<ClCompile Include="ImageBackend.cpp" /> <ClCompile Include="ImageBackend.cpp" />
@ -273,7 +274,9 @@
<ClInclude Include="..\lib\stb\stb_image_write.h" /> <ClInclude Include="..\lib\stb\stb_image_write.h" />
<ClInclude Include="..\lib\stb\tinyxml2.h" /> <ClInclude Include="..\lib\stb\tinyxml2.h" />
<ClInclude Include="CRC32.h" /> <ClInclude Include="CRC32.h" />
<ClInclude Include="ctpl_stl.h" />
<ClInclude Include="Declaration.h" /> <ClInclude Include="Declaration.h" />
<ClInclude Include="FileWorker.h" />
<ClInclude Include="GameConfig.h" /> <ClInclude Include="GameConfig.h" />
<ClInclude Include="Globals.h" /> <ClInclude Include="Globals.h" />
<ClInclude Include="ImageBackend.h" /> <ClInclude Include="ImageBackend.h" />

View file

@ -294,6 +294,9 @@
<ClCompile Include="yaz0\yaz0.cpp"> <ClCompile Include="yaz0\yaz0.cpp">
<Filter>Source Files\Yaz0</Filter> <Filter>Source Files\Yaz0</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="FileWorker.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="ZRoom\ZRoom.h"> <ClInclude Include="ZRoom\ZRoom.h">
@ -560,6 +563,12 @@
<ClInclude Include="yaz0\yaz0.h"> <ClInclude Include="yaz0\yaz0.h">
<Filter>Header Files\Yaz0</Filter> <Filter>Header Files\Yaz0</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="FileWorker.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ctpl_stl.h">
<Filter>Header Files\Libraries</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Text Include="..\SymbolMap_OoTMqDbg.txt"> <Text Include="..\SymbolMap_OoTMqDbg.txt">

View file

@ -150,10 +150,11 @@ void ZNormalAnimation::DeclareReferences(const std::string& prefix)
std::string ZNormalAnimation::GetBodySourceCode() const std::string ZNormalAnimation::GetBodySourceCode() const
{ {
std::string frameDataName; std::string frameDataName;
Globals::Instance->GetSegmentedPtrName(rotationValuesSeg, parent, "s16", frameDataName); Globals::Instance->GetSegmentedPtrName(rotationValuesSeg, parent, "s16", frameDataName,
parent->workerID);
std::string jointIndicesName; std::string jointIndicesName;
Globals::Instance->GetSegmentedPtrName(rotationIndicesSeg, parent, "JointIndex", Globals::Instance->GetSegmentedPtrName(rotationIndicesSeg, parent, "JointIndex",
jointIndicesName); jointIndicesName, parent->workerID);
std::string headerStr = std::string headerStr =
StringHelper::Sprintf("\n\t{ %i }, %s,\n", frameCount, frameDataName.c_str()); StringHelper::Sprintf("\n\t{ %i }, %s,\n", frameCount, frameDataName.c_str());
@ -190,7 +191,7 @@ void ZLinkAnimation::ParseRawData()
std::string ZLinkAnimation::GetBodySourceCode() const std::string ZLinkAnimation::GetBodySourceCode() const
{ {
std::string segSymbol; std::string segSymbol;
Globals::Instance->GetSegmentedPtrName(segmentAddress, parent, "", segSymbol); Globals::Instance->GetSegmentedPtrName(segmentAddress, parent, "", segSymbol, parent->workerID);
return StringHelper::Sprintf("\n\t{ %i }, %s\n", frameCount, segSymbol.c_str()); return StringHelper::Sprintf("\n\t{ %i }, %s\n", frameCount, segSymbol.c_str());
} }
@ -390,12 +391,13 @@ void ZCurveAnimation::DeclareReferences(const std::string& prefix)
std::string ZCurveAnimation::GetBodySourceCode() const std::string ZCurveAnimation::GetBodySourceCode() const
{ {
std::string refIndexStr; std::string refIndexStr;
Globals::Instance->GetSegmentedPtrName(refIndex, parent, "u8", refIndexStr); Globals::Instance->GetSegmentedPtrName(refIndex, parent, "u8", refIndexStr, parent->workerID);
std::string transformDataStr; std::string transformDataStr;
Globals::Instance->GetSegmentedPtrName(transformData, parent, "TransformData", Globals::Instance->GetSegmentedPtrName(transformData, parent, "TransformData",
transformDataStr); transformDataStr, parent->workerID);
std::string copyValuesStr; std::string copyValuesStr;
Globals::Instance->GetSegmentedPtrName(copyValues, parent, "s16", copyValuesStr); Globals::Instance->GetSegmentedPtrName(copyValues, parent, "s16", copyValuesStr,
parent->workerID);
return StringHelper::Sprintf("\n\t%s,\n\t%s,\n\t%s,\n\t%i, %i\n", refIndexStr.c_str(), return StringHelper::Sprintf("\n\t%s,\n\t%s,\n\t%s,\n\t%i, %i\n", refIndexStr.c_str(),
transformDataStr.c_str(), copyValuesStr.c_str(), unk_0C, unk_10); transformDataStr.c_str(), copyValuesStr.c_str(), unk_0C, unk_10);
@ -517,8 +519,10 @@ std::string ZLegacyAnimation::GetBodySourceCode() const
std::string frameDataName; std::string frameDataName;
std::string jointKeyName; std::string jointKeyName;
Globals::Instance->GetSegmentedPtrName(frameData, parent, "s16", frameDataName); Globals::Instance->GetSegmentedPtrName(frameData, parent, "s16", frameDataName,
Globals::Instance->GetSegmentedPtrName(jointKey, parent, "JointKey", jointKeyName); parent->workerID);
Globals::Instance->GetSegmentedPtrName(jointKey, parent, "JointKey", jointKeyName,
parent->workerID);
body += StringHelper::Sprintf("\t%i, %i,\n", frameCount, limbCount); body += StringHelper::Sprintf("\t%i, %i,\n", frameCount, limbCount);
body += StringHelper::Sprintf("\t%s,\n", frameDataName.c_str()); body += StringHelper::Sprintf("\t%s,\n", frameDataName.c_str());

View file

@ -198,23 +198,27 @@ std::string ZCollisionHeader::GetBodySourceCode() const
declaration += StringHelper::Sprintf("\t{ %i, %i, %i },\n", absMaxX, absMaxY, absMaxZ); declaration += StringHelper::Sprintf("\t{ %i, %i, %i },\n", absMaxX, absMaxY, absMaxZ);
std::string vtxName; std::string vtxName;
Globals::Instance->GetSegmentedPtrName(vtxAddress, parent, "Vec3s", vtxName); Globals::Instance->GetSegmentedPtrName(vtxAddress, parent, "Vec3s", vtxName, parent->workerID);
declaration += StringHelper::Sprintf("\t%i,\n\t%s,\n", numVerts, vtxName.c_str()); declaration += StringHelper::Sprintf("\t%i,\n\t%s,\n", numVerts, vtxName.c_str());
std::string polyName; std::string polyName;
Globals::Instance->GetSegmentedPtrName(polyAddress, parent, "CollisionPoly", polyName); Globals::Instance->GetSegmentedPtrName(polyAddress, parent, "CollisionPoly", polyName,
parent->workerID);
declaration += StringHelper::Sprintf("\t%i,\n\t%s,\n", numPolygons, polyName.c_str()); declaration += StringHelper::Sprintf("\t%i,\n\t%s,\n", numPolygons, polyName.c_str());
std::string surfaceName; std::string surfaceName;
Globals::Instance->GetSegmentedPtrName(polyTypeDefAddress, parent, "SurfaceType", surfaceName); Globals::Instance->GetSegmentedPtrName(polyTypeDefAddress, parent, "SurfaceType", surfaceName,
parent->workerID);
declaration += StringHelper::Sprintf("\t%s,\n", surfaceName.c_str()); declaration += StringHelper::Sprintf("\t%s,\n", surfaceName.c_str());
std::string camName; std::string camName;
Globals::Instance->GetSegmentedPtrName(camDataAddress, parent, "CamData", camName); Globals::Instance->GetSegmentedPtrName(camDataAddress, parent, "CamData", camName,
parent->workerID);
declaration += StringHelper::Sprintf("\t%s,\n", camName.c_str()); declaration += StringHelper::Sprintf("\t%s,\n", camName.c_str());
std::string waterBoxName; std::string waterBoxName;
Globals::Instance->GetSegmentedPtrName(waterBoxAddress, parent, "WaterBox", waterBoxName); Globals::Instance->GetSegmentedPtrName(waterBoxAddress, parent, "WaterBox", waterBoxName,
parent->workerID);
declaration += StringHelper::Sprintf("\t%i,\n\t%s\n", numWaterBoxes, waterBoxName.c_str()); declaration += StringHelper::Sprintf("\t%i,\n\t%s\n", numWaterBoxes, waterBoxName.c_str());
return declaration; return declaration;

View file

@ -553,7 +553,8 @@ int32_t ZDisplayList::OptimizationCheck_LoadTextureBlock(int32_t startIndex, std
lastTexSeg = segmentNumber; lastTexSeg = segmentNumber;
Globals::Instance->GetSegmentedPtrName(data & 0xFFFFFFFF, parent, "", texStr); Globals::Instance->GetSegmentedPtrName(data & 0xFFFFFFFF, parent, "", texStr,
parent->workerID);
} }
// gsDPSetTile // gsDPSetTile
@ -705,7 +706,7 @@ void ZDisplayList::Opcode_G_DL(uint64_t data, const std::string& prefix, char* l
if (pp != 0) if (pp != 0)
{ {
if (!Globals::Instance->HasSegment(segNum)) if (!Globals::Instance->HasSegment(segNum, parent->workerID))
sprintf(line, "gsSPBranchList(0x%08" PRIX64 "),", data & 0xFFFFFFFF); sprintf(line, "gsSPBranchList(0x%08" PRIX64 "),", data & 0xFFFFFFFF);
else if (dListDecl != nullptr) else if (dListDecl != nullptr)
sprintf(line, "gsSPBranchList(%s),", dListDecl->varName.c_str()); sprintf(line, "gsSPBranchList(%s),", dListDecl->varName.c_str());
@ -715,7 +716,7 @@ void ZDisplayList::Opcode_G_DL(uint64_t data, const std::string& prefix, char* l
} }
else else
{ {
if (!Globals::Instance->HasSegment(segNum)) if (!Globals::Instance->HasSegment(segNum, parent->workerID))
sprintf(line, "gsSPDisplayList(0x%08" PRIX64 "),", data & 0xFFFFFFFF); sprintf(line, "gsSPDisplayList(0x%08" PRIX64 "),", data & 0xFFFFFFFF);
else if (dListDecl != nullptr) else if (dListDecl != nullptr)
sprintf(line, "gsSPDisplayList(%s),", dListDecl->varName.c_str()); sprintf(line, "gsSPDisplayList(%s),", dListDecl->varName.c_str());
@ -726,7 +727,7 @@ void ZDisplayList::Opcode_G_DL(uint64_t data, const std::string& prefix, char* l
// if (segNum == 8 || segNum == 9 || segNum == 10 || segNum == 11 || segNum == 12 || segNum == // if (segNum == 8 || segNum == 9 || segNum == 10 || segNum == 11 || segNum == 12 || segNum ==
// 13) // Used for runtime-generated display lists // 13) // Used for runtime-generated display lists
if (!Globals::Instance->HasSegment(segNum)) if (!Globals::Instance->HasSegment(segNum, parent->workerID))
{ {
if (pp != 0) if (pp != 0)
sprintf(line, "gsSPBranchList(0x%08" PRIX64 "),", data & 0xFFFFFFFF); sprintf(line, "gsSPBranchList(0x%08" PRIX64 "),", data & 0xFFFFFFFF);
@ -847,7 +848,7 @@ void ZDisplayList::Opcode_G_VTX(uint64_t data, char* line)
} }
// Hack: Don't extract vertices from a unknown segment. // Hack: Don't extract vertices from a unknown segment.
if (!Globals::Instance->HasSegment(GETSEGNUM(data))) if (!Globals::Instance->HasSegment(GETSEGNUM(data), parent->workerID))
{ {
segptr_t segmented = data & 0xFFFFFFFF; segptr_t segmented = data & 0xFFFFFFFF;
references.push_back(segmented); references.push_back(segmented);
@ -951,7 +952,7 @@ void ZDisplayList::Opcode_G_SETTIMG(uint64_t data, const std::string& prefix, ch
if (parent != nullptr) if (parent != nullptr)
{ {
if (Globals::Instance->HasSegment(segmentNumber)) if (Globals::Instance->HasSegment(segmentNumber, parent->workerID))
texDecl = parent->GetDeclaration(texAddress); texDecl = parent->GetDeclaration(texAddress);
else else
texDecl = parent->GetDeclaration(data); texDecl = parent->GetDeclaration(data);
@ -959,7 +960,7 @@ void ZDisplayList::Opcode_G_SETTIMG(uint64_t data, const std::string& prefix, ch
if (texDecl != nullptr) if (texDecl != nullptr)
sprintf(texStr, "%s", texDecl->varName.c_str()); sprintf(texStr, "%s", texDecl->varName.c_str());
else if (data != 0 && Globals::Instance->HasSegment(segmentNumber)) else if (data != 0 && Globals::Instance->HasSegment(segmentNumber, parent->workerID))
sprintf(texStr, "%sTex_%06X", prefix.c_str(), texAddress); sprintf(texStr, "%sTex_%06X", prefix.c_str(), texAddress);
else else
{ {
@ -972,7 +973,7 @@ void ZDisplayList::Opcode_G_SETTIMG(uint64_t data, const std::string& prefix, ch
else else
{ {
std::string texName; std::string texName;
Globals::Instance->GetSegmentedPtrName(data, parent, "", texName); Globals::Instance->GetSegmentedPtrName(data, parent, "", texName, parent->workerID);
sprintf(line, "gsDPSetTextureImage(%s, %s, %i, %s),", fmtTbl[fmt], sizTbl[siz], www + 1, sprintf(line, "gsDPSetTextureImage(%s, %s, %i, %s),", fmtTbl[fmt], sizTbl[siz], www + 1,
texName.c_str()); texName.c_str());
} }
@ -1672,7 +1673,7 @@ static int32_t GfxdCallback_Texture(segptr_t seg, int32_t fmt, int32_t siz, int3
self->TextureGenCheck(); self->TextureGenCheck();
std::string texName; std::string texName;
Globals::Instance->GetSegmentedPtrName(seg, self->parent, "", texName); Globals::Instance->GetSegmentedPtrName(seg, self->parent, "", texName, self->parent->workerID);
gfxd_puts(texName.c_str()); gfxd_puts(texName.c_str());
@ -1696,7 +1697,7 @@ static int32_t GfxdCallback_Palette(uint32_t seg, [[maybe_unused]] int32_t idx,
self->TextureGenCheck(); self->TextureGenCheck();
std::string palName; std::string palName;
Globals::Instance->GetSegmentedPtrName(seg, self->parent, "", palName); Globals::Instance->GetSegmentedPtrName(seg, self->parent, "", palName, self->parent->workerID);
gfxd_puts(palName.c_str()); gfxd_puts(palName.c_str());
@ -1710,7 +1711,8 @@ static int32_t GfxdCallback_DisplayList(uint32_t seg)
uint32_t dListSegNum = GETSEGNUM(seg); uint32_t dListSegNum = GETSEGNUM(seg);
std::string dListName = ""; std::string dListName = "";
bool addressFound = Globals::Instance->GetSegmentedPtrName(seg, self->parent, "Gfx", dListName); bool addressFound = Globals::Instance->GetSegmentedPtrName(seg, self->parent, "Gfx", dListName,
self->parent->workerID);
if (!addressFound && self->parent->segment == dListSegNum) if (!addressFound && self->parent->segment == dListSegNum)
{ {
@ -1733,7 +1735,8 @@ static int32_t GfxdCallback_Matrix(uint32_t seg)
std::string mtxName; std::string mtxName;
ZDisplayList* self = static_cast<ZDisplayList*>(gfxd_udata_get()); ZDisplayList* self = static_cast<ZDisplayList*>(gfxd_udata_get());
bool addressFound = Globals::Instance->GetSegmentedPtrName(seg, self->parent, "Mtx", mtxName); bool addressFound = Globals::Instance->GetSegmentedPtrName(seg, self->parent, "Mtx", mtxName,
self->parent->workerID);
if (!addressFound && GETSEGNUM(seg) == self->parent->segment) if (!addressFound && GETSEGNUM(seg) == self->parent->segment)
{ {
Declaration* decl = Declaration* decl =
@ -2004,7 +2007,7 @@ bool ZDisplayList::TextureGenCheck(int32_t texWidth, int32_t texHeight, uint32_t
texWidth, texHeight, texIsPalette, texAddr); texWidth, texHeight, texIsPalette, texAddr);
if ((texSeg != 0 || texAddr != 0) && texWidth > 0 && texHeight > 0 && texLoaded && if ((texSeg != 0 || texAddr != 0) && texWidth > 0 && texHeight > 0 && texLoaded &&
Globals::Instance->HasSegment(segmentNumber)) Globals::Instance->HasSegment(segmentNumber, self->parent->workerID))
{ {
ZFile* auxParent = nullptr; ZFile* auxParent = nullptr;
if (segmentNumber == self->parent->segment) if (segmentNumber == self->parent->segment)
@ -2015,7 +2018,8 @@ bool ZDisplayList::TextureGenCheck(int32_t texWidth, int32_t texHeight, uint32_t
{ {
// Try to find a non-external file (i.e., 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. // which has the same segment number we are looking for.
for (auto& otherFile : Globals::Instance->cfg.segmentRefFiles[segmentNumber]) auto segs = Globals::Instance->GetSegmentRefFiles(self->parent->workerID);
for (auto& otherFile : segs[segmentNumber])
{ {
if (!otherFile->isExternalFile) if (!otherFile->isExternalFile)
{ {

View file

@ -41,6 +41,7 @@ ZFile::ZFile()
baseAddress = 0; baseAddress = 0;
rangeStart = 0x000000000; rangeStart = 0x000000000;
rangeEnd = 0xFFFFFFFF; rangeEnd = 0xFFFFFFFF;
workerID = 0;
} }
ZFile::ZFile(const fs::path& nOutPath, const std::string& nName) : ZFile() ZFile::ZFile(const fs::path& nOutPath, const std::string& nName) : ZFile()
@ -51,7 +52,7 @@ ZFile::ZFile(const fs::path& nOutPath, const std::string& nName) : ZFile()
} }
ZFile::ZFile(ZFileMode nMode, tinyxml2::XMLElement* reader, const fs::path& nBasePath, ZFile::ZFile(ZFileMode nMode, tinyxml2::XMLElement* reader, const fs::path& nBasePath,
const fs::path& nOutPath, const std::string& filename, const fs::path& nXmlFilePath) const fs::path& nOutPath, const std::string& filename, const fs::path& nXmlFilePath, int nWorkerID)
: ZFile() : ZFile()
{ {
xmlFilePath = nXmlFilePath; xmlFilePath = nXmlFilePath;
@ -66,6 +67,7 @@ ZFile::ZFile(ZFileMode nMode, tinyxml2::XMLElement* reader, const fs::path& nBas
outputPath = nOutPath; outputPath = nOutPath;
mode = nMode; mode = nMode;
workerID = nWorkerID;
ParseXML(reader, filename); ParseXML(reader, filename);
if (mode != ZFileMode::ExternalFile) if (mode != ZFileMode::ExternalFile)
@ -167,7 +169,7 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
} }
} }
} }
Globals::Instance->AddSegment(segment, this); Globals::Instance->AddSegment(segment, this, workerID);
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO)
{ {
@ -182,6 +184,8 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
} }
if (mode == ZFileMode::Extract || mode == ZFileMode::ExternalFile || mode == ZFileMode::ExtractDirectory) if (mode == ZFileMode::Extract || mode == ZFileMode::ExternalFile || mode == ZFileMode::ExtractDirectory)
{
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
{ {
if (!File::Exists((basePath / name).string())) if (!File::Exists((basePath / name).string()))
{ {
@ -189,8 +193,11 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
(basePath / name).c_str()); (basePath / name).c_str());
HANDLE_ERROR_PROCESS(WarningType::Always, errorHeader, ""); HANDLE_ERROR_PROCESS(WarningType::Always, errorHeader, "");
} }
}
//rawData = File::ReadAllBytes((basePath / name).string()); if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory)
rawData = Globals::Instance->GetBaseromFile(name);
else
rawData = Globals::Instance->GetBaseromFile((basePath / name).string()); rawData = Globals::Instance->GetBaseromFile((basePath / name).string());
if (reader->Attribute("RangeEnd") == nullptr) if (reader->Attribute("RangeEnd") == nullptr)
@ -1093,7 +1100,7 @@ void ZFile::ProcessDeclarationText(Declaration* decl)
{ {
std::string vtxName; std::string vtxName;
Globals::Instance->GetSegmentedArrayIndexedName(decl->references[refIndex], 0x10, this, Globals::Instance->GetSegmentedArrayIndexedName(decl->references[refIndex], 0x10, this,
"Vtx", vtxName); "Vtx", vtxName, workerID);
decl->text.replace(i, 2, vtxName); decl->text.replace(i, 2, vtxName);
refIndex++; refIndex++;

View file

@ -35,6 +35,8 @@ public:
std::string defines; std::string defines;
std::vector<ZResource*> resources; std::vector<ZResource*> resources;
int workerID;
// Default to using virtual addresses // Default to using virtual addresses
uint32_t segment = 0x80; uint32_t segment = 0x80;
uint32_t baseAddress, rangeStart, rangeEnd; uint32_t baseAddress, rangeStart, rangeEnd;
@ -42,7 +44,7 @@ public:
ZFile(const fs::path& nOutPath, const std::string& nName); ZFile(const fs::path& nOutPath, const std::string& nName);
ZFile(ZFileMode nMode, tinyxml2::XMLElement* reader, const fs::path& nBasePath, ZFile(ZFileMode nMode, tinyxml2::XMLElement* reader, const fs::path& nBasePath,
const fs::path& nOutPath, const std::string& filename, const fs::path& nXmlFilePath); const fs::path& nOutPath, const std::string& filename, const fs::path& nXmlFilePath, int nWorkerID);
~ZFile(); ~ZFile();
std::string GetName() const; std::string GetName() const;

View file

@ -223,16 +223,20 @@ std::string ZLimb::GetBodySourceCode() const
std::string dListStr; std::string dListStr;
std::string dListStr2; std::string dListStr2;
Globals::Instance->GetSegmentedArrayIndexedName(dListPtr, 8, parent, "Gfx", dListStr); Globals::Instance->GetSegmentedArrayIndexedName(dListPtr, 8, parent, "Gfx", dListStr,
Globals::Instance->GetSegmentedArrayIndexedName(dList2Ptr, 8, parent, "Gfx", dListStr2); parent->workerID);
Globals::Instance->GetSegmentedArrayIndexedName(dList2Ptr, 8, parent, "Gfx", dListStr2,
parent->workerID);
std::string entryStr = "\n\t"; std::string entryStr = "\n\t";
if (type == ZLimbType::Legacy) if (type == ZLimbType::Legacy)
{ {
std::string childName; std::string childName;
std::string siblingName; std::string siblingName;
Globals::Instance->GetSegmentedPtrName(childPtr, parent, "LegacyLimb", childName); Globals::Instance->GetSegmentedPtrName(childPtr, parent, "LegacyLimb", childName,
Globals::Instance->GetSegmentedPtrName(siblingPtr, parent, "LegacyLimb", siblingName); parent->workerID);
Globals::Instance->GetSegmentedPtrName(siblingPtr, parent, "LegacyLimb", siblingName,
parent->workerID);
entryStr += StringHelper::Sprintf("%s,\n", dListStr.c_str()); entryStr += StringHelper::Sprintf("%s,\n", dListStr.c_str());
entryStr += entryStr +=
@ -264,7 +268,8 @@ std::string ZLimb::GetBodySourceCode() const
case ZLimbType::Skin: case ZLimbType::Skin:
{ {
std::string skinSegmentStr; std::string skinSegmentStr;
Globals::Instance->GetSegmentedPtrName(skinSegment, parent, "", skinSegmentStr); Globals::Instance->GetSegmentedPtrName(skinSegment, parent, "", skinSegmentStr,
parent->workerID);
entryStr += entryStr +=
StringHelper::Sprintf("\t0x%02X, %s\n", skinSegmentType, skinSegmentStr.c_str()); StringHelper::Sprintf("\t0x%02X, %s\n", skinSegmentType, skinSegmentStr.c_str());
} }
@ -370,7 +375,7 @@ void ZLimb::DeclareDList(segptr_t dListSegmentedPtr, const std::string& prefix,
std::string dlistName; std::string dlistName;
bool declFound = Globals::Instance->GetSegmentedArrayIndexedName(dListSegmentedPtr, 8, parent, bool declFound = Globals::Instance->GetSegmentedArrayIndexedName(dListSegmentedPtr, 8, parent,
"Gfx", dlistName); "Gfx", dlistName, parent->workerID);
if (declFound) if (declFound)
return; return;

View file

@ -142,8 +142,8 @@ void PathwayEntry::DeclareReferences(const std::string& prefix)
return; return;
std::string pointsName; std::string pointsName;
bool addressFound = bool addressFound = Globals::Instance->GetSegmentedPtrName(listSegmentAddress, parent, "Vec3s",
Globals::Instance->GetSegmentedPtrName(listSegmentAddress, parent, "Vec3s", pointsName); pointsName, parent->workerID);
if (addressFound) if (addressFound)
return; return;
@ -177,7 +177,8 @@ std::string PathwayEntry::GetBodySourceCode() const
{ {
std::string declaration; std::string declaration;
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(listSegmentAddress, parent, "Vec3s", listName); Globals::Instance->GetSegmentedPtrName(listSegmentAddress, parent, "Vec3s", listName,
parent->workerID);
if (Globals::Instance->game == ZGame::MM_RETAIL) if (Globals::Instance->game == ZGame::MM_RETAIL)
declaration += declaration +=

View file

@ -7,6 +7,7 @@
#ifndef _MSC_VER #ifndef _MSC_VER
#include <byteswap.h> #include <byteswap.h>
#endif #endif
#include <Globals.h>
namespace fs = std::filesystem; namespace fs = std::filesystem;
@ -157,7 +158,7 @@ ZRom::ZRom(std::string romPath)
break; break;
} }
auto path = StringHelper::Sprintf("CFG/filelists/%s", version.listPath.c_str()); auto path = StringHelper::Sprintf("%s/%s", Globals::Instance->fileListPath.string().c_str(), version.listPath.c_str());
auto txt = File::ReadAllText(path); auto txt = File::ReadAllText(path);
std::vector<std::string> lines = StringHelper::Split(txt, "\n"); std::vector<std::string> lines = StringHelper::Split(txt, "\n");

View file

@ -54,7 +54,8 @@ void SetActorCutsceneList::DeclareReferences(const std::string& prefix)
std::string SetActorCutsceneList::GetBodySourceCode() const std::string SetActorCutsceneList::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "ActorCutscene", listName); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "ActorCutscene", listName,
parent->workerID);
return StringHelper::Sprintf("SCENE_CMD_ACTOR_CUTSCENE_LIST(%i, %s)", cutscenes.size(), return StringHelper::Sprintf("SCENE_CMD_ACTOR_CUTSCENE_LIST(%i, %s)", cutscenes.size(),
listName.c_str()); listName.c_str());
} }

View file

@ -81,7 +81,8 @@ void SetActorList::DeclareReferencesLate(const std::string& prefix)
std::string SetActorList::GetBodySourceCode() const std::string SetActorList::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "ActorEntry", listName); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "ActorEntry", listName,
parent->workerID);
if (numActors != actors.size()) if (numActors != actors.size())
{ {
printf("%s: numActors(%i) ~ actors(%li)\n", parent->GetName().c_str(), numActors, printf("%s: numActors(%i) ~ actors(%li)\n", parent->GetName().c_str(), numActors,

View file

@ -48,7 +48,8 @@ void SetAlternateHeaders::DeclareReferencesLate(const std::string& prefix)
for (size_t i = 0; i < headers.size(); i++) for (size_t i = 0; i < headers.size(); i++)
{ {
std::string altHeaderName; std::string altHeaderName;
Globals::Instance->GetSegmentedPtrName(headers.at(i), parent, "", altHeaderName); Globals::Instance->GetSegmentedPtrName(headers.at(i), parent, "", altHeaderName,
parent->workerID);
declaration += StringHelper::Sprintf("\t%s,", altHeaderName.c_str()); declaration += StringHelper::Sprintf("\t%s,", altHeaderName.c_str());
@ -66,7 +67,8 @@ void SetAlternateHeaders::DeclareReferencesLate(const std::string& prefix)
std::string SetAlternateHeaders::GetBodySourceCode() const std::string SetAlternateHeaders::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "SceneCmd*", listName); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "SceneCmd*", listName,
parent->workerID);
return StringHelper::Sprintf("SCENE_CMD_ALTERNATE_HEADER_LIST(%s)", listName.c_str()); return StringHelper::Sprintf("SCENE_CMD_ALTERNATE_HEADER_LIST(%s)", listName.c_str());
} }

View file

@ -33,7 +33,8 @@ void SetAnimatedMaterialList::DeclareReferences(const std::string& prefix)
std::string SetAnimatedMaterialList::GetBodySourceCode() const std::string SetAnimatedMaterialList::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "AnimatedMaterial", listName); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "AnimatedMaterial", listName,
parent->workerID);
return StringHelper::Sprintf("SCENE_CMD_ANIMATED_MATERIAL_LIST(%s)", listName.c_str()); return StringHelper::Sprintf("SCENE_CMD_ANIMATED_MATERIAL_LIST(%s)", listName.c_str());
} }

View file

@ -29,7 +29,8 @@ void SetCollisionHeader::DeclareReferences(const std::string& prefix)
std::string SetCollisionHeader::GetBodySourceCode() const std::string SetCollisionHeader::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "CollisionHeader", listName); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "CollisionHeader", listName,
parent->workerID);
return StringHelper::Sprintf("SCENE_CMD_COL_HEADER(%s)", listName.c_str()); return StringHelper::Sprintf("SCENE_CMD_COL_HEADER(%s)", listName.c_str());
} }

View file

@ -71,7 +71,7 @@ void SetCsCamera::DeclareReferences(const std::string& prefix)
{ {
std::string camPointsName; std::string camPointsName;
Globals::Instance->GetSegmentedPtrName(cameras.at(0).GetCamAddress(), parent, "Vec3s", Globals::Instance->GetSegmentedPtrName(cameras.at(0).GetCamAddress(), parent, "Vec3s",
camPointsName); camPointsName, parent->workerID);
std::string declaration; std::string declaration;
size_t index = 0; size_t index = 0;
@ -103,7 +103,8 @@ void SetCsCamera::DeclareReferences(const std::string& prefix)
std::string SetCsCamera::GetBodySourceCode() const std::string SetCsCamera::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "CsCameraEntry", listName); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "CsCameraEntry", listName,
parent->workerID);
return StringHelper::Sprintf("SCENE_CMD_ACTOR_CUTSCENE_CAM_LIST(%i, %s)", cameras.size(), return StringHelper::Sprintf("SCENE_CMD_ACTOR_CUTSCENE_CAM_LIST(%i, %s)", cameras.size(),
listName.c_str()); listName.c_str());
} }

View file

@ -86,7 +86,8 @@ void SetCutscenes::ParseRawData()
std::string SetCutscenes::GetBodySourceCode() const std::string SetCutscenes::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "CutsceneData", listName); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "CutsceneData", listName,
parent->workerID);
if (Globals::Instance->game == ZGame::MM_RETAIL) if (Globals::Instance->game == ZGame::MM_RETAIL)
return StringHelper::Sprintf("SCENE_CMD_CUTSCENE_LIST(%i, %s)", numCutscenes, return StringHelper::Sprintf("SCENE_CMD_CUTSCENE_LIST(%i, %s)", numCutscenes,

View file

@ -63,7 +63,8 @@ void SetEntranceList::DeclareReferencesLate([[maybe_unused]] const std::string&
std::string SetEntranceList::GetBodySourceCode() const std::string SetEntranceList::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "EntranceEntry", listName); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "EntranceEntry", listName,
parent->workerID);
return StringHelper::Sprintf("SCENE_CMD_ENTRANCE_LIST(%s)", listName.c_str()); return StringHelper::Sprintf("SCENE_CMD_ENTRANCE_LIST(%s)", listName.c_str());
} }

View file

@ -58,7 +58,7 @@ void SetExitList::DeclareReferencesLate([[maybe_unused]] const std::string& pref
std::string SetExitList::GetBodySourceCode() const std::string SetExitList::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "u16", listName); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "u16", listName, parent->workerID);
return StringHelper::Sprintf("SCENE_CMD_EXIT_LIST(%s)", listName.c_str()); return StringHelper::Sprintf("SCENE_CMD_EXIT_LIST(%s)", listName.c_str());
} }

View file

@ -52,7 +52,8 @@ void SetLightList::DeclareReferences(const std::string& prefix)
std::string SetLightList::GetBodySourceCode() const std::string SetLightList::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "LightInfo", listName); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "LightInfo", listName,
parent->workerID);
return StringHelper::Sprintf("SCENE_CMD_LIGHT_LIST(%i, %s)", numLights, listName.c_str()); return StringHelper::Sprintf("SCENE_CMD_LIGHT_LIST(%i, %s)", numLights, listName.c_str());
} }

View file

@ -44,7 +44,8 @@ void SetLightingSettings::DeclareReferences(const std::string& prefix)
std::string SetLightingSettings::GetBodySourceCode() const std::string SetLightingSettings::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "LightSettings", listName); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "LightSettings", listName,
parent->workerID);
return StringHelper::Sprintf("SCENE_CMD_ENV_LIGHT_SETTINGS(%i, %s)", settings.size(), return StringHelper::Sprintf("SCENE_CMD_ENV_LIGHT_SETTINGS(%i, %s)", settings.size(),
listName.c_str()); listName.c_str());
} }

View file

@ -78,7 +78,7 @@ std::string SetMesh::GenDListExterns(ZDisplayList* dList)
std::string SetMesh::GetBodySourceCode() const std::string SetMesh::GetBodySourceCode() const
{ {
std::string list; std::string list;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "", list); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "", list, parent->workerID);
return StringHelper::Sprintf("SCENE_CMD_MESH(%s)", list.c_str()); return StringHelper::Sprintf("SCENE_CMD_MESH(%s)", list.c_str());
} }
@ -129,8 +129,8 @@ std::string PolygonDlist::GetBodySourceCode() const
std::string bodyStr; std::string bodyStr;
std::string opaStr; std::string opaStr;
std::string xluStr; std::string xluStr;
Globals::Instance->GetSegmentedPtrName(opa, parent, "Gfx", opaStr); Globals::Instance->GetSegmentedPtrName(opa, parent, "Gfx", opaStr, parent->workerID);
Globals::Instance->GetSegmentedPtrName(xlu, parent, "Gfx", xluStr); Globals::Instance->GetSegmentedPtrName(xlu, parent, "Gfx", xluStr, parent->workerID);
if (polyType == 2) if (polyType == 2)
{ {
@ -294,7 +294,7 @@ std::string BgImage::GetBodySourceCode() const
} }
std::string backgroundName; std::string backgroundName;
Globals::Instance->GetSegmentedPtrName(source, parent, "", backgroundName); Globals::Instance->GetSegmentedPtrName(source, parent, "", backgroundName, parent->workerID);
bodyStr += StringHelper::Sprintf("%s, ", backgroundName.c_str()); bodyStr += StringHelper::Sprintf("%s, ", backgroundName.c_str());
bodyStr += "\n "; bodyStr += "\n ";
if (!isSubStruct) if (!isSubStruct)
@ -493,7 +493,7 @@ std::string PolygonType1::GetBodySourceCode() const
bodyStr += StringHelper::Sprintf("%i, %i, ", type, format); bodyStr += StringHelper::Sprintf("%i, %i, ", type, format);
std::string dlistStr; std::string dlistStr;
Globals::Instance->GetSegmentedPtrName(dlist, parent, "", dlistStr); Globals::Instance->GetSegmentedPtrName(dlist, parent, "", dlistStr, parent->workerID);
bodyStr += StringHelper::Sprintf("%s, ", dlistStr.c_str()); bodyStr += StringHelper::Sprintf("%s, ", dlistStr.c_str());
bodyStr += "}, \n"; bodyStr += "}, \n";
@ -505,7 +505,7 @@ std::string PolygonType1::GetBodySourceCode() const
bodyStr += single.GetBodySourceCode(); bodyStr += single.GetBodySourceCode();
break; break;
case 2: case 2:
Globals::Instance->GetSegmentedPtrName(list, parent, "BgImage", listStr); Globals::Instance->GetSegmentedPtrName(list, parent, "BgImage", listStr, parent->workerID);
bodyStr += StringHelper::Sprintf(" %i, %s, \n", count, listStr.c_str()); bodyStr += StringHelper::Sprintf(" %i, %s, \n", count, listStr.c_str());
break; break;
@ -592,7 +592,7 @@ void PolygonType2::DeclareReferences(const std::string& prefix)
std::string PolygonType2::GetBodySourceCode() const std::string PolygonType2::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(start, parent, "", listName); Globals::Instance->GetSegmentedPtrName(start, parent, "", listName, parent->workerID);
std::string body = StringHelper::Sprintf("\n %i, %i,\n", type, polyDLists.size()); std::string body = StringHelper::Sprintf("\n %i, %i,\n", type, polyDLists.size());
body += StringHelper::Sprintf(" %s,\n", listName.c_str()); body += StringHelper::Sprintf(" %s,\n", listName.c_str());

View file

@ -50,7 +50,8 @@ void SetMinimapChests::DeclareReferences(const std::string& prefix)
std::string SetMinimapChests::GetBodySourceCode() const std::string SetMinimapChests::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "MinimapChest", listName); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "MinimapChest", listName,
parent->workerID);
return StringHelper::Sprintf("SCENE_CMD_MINIMAP_COMPASS_ICON_INFO(0x%02X, %s)", chests.size(), return StringHelper::Sprintf("SCENE_CMD_MINIMAP_COMPASS_ICON_INFO(0x%02X, %s)", chests.size(),
listName.c_str()); listName.c_str());
} }

View file

@ -52,7 +52,8 @@ void SetMinimapList::DeclareReferences(const std::string& prefix)
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(listSegmentAddr, parent, "MinimapEntry", listName); Globals::Instance->GetSegmentedPtrName(listSegmentAddr, parent, "MinimapEntry", listName,
parent->workerID);
std::string declaration = StringHelper::Sprintf("\n\t%s, 0x%08X\n", listName.c_str(), unk4); std::string declaration = StringHelper::Sprintf("\n\t%s, 0x%08X\n", listName.c_str(), unk4);
parent->AddDeclaration( parent->AddDeclaration(
@ -65,7 +66,8 @@ void SetMinimapList::DeclareReferences(const std::string& prefix)
std::string SetMinimapList::GetBodySourceCode() const std::string SetMinimapList::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "MinimapList", listName); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "MinimapList", listName,
parent->workerID);
return StringHelper::Sprintf("SCENE_CMD_MINIMAP_INFO(%s)", listName.c_str()); return StringHelper::Sprintf("SCENE_CMD_MINIMAP_INFO(%s)", listName.c_str());
} }

View file

@ -51,7 +51,7 @@ void SetObjectList::DeclareReferences(const std::string& prefix)
std::string SetObjectList::GetBodySourceCode() const std::string SetObjectList::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "s16", listName); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "s16", listName, parent->workerID);
return StringHelper::Sprintf("SCENE_CMD_OBJECT_LIST(%i, %s)", objects.size(), listName.c_str()); return StringHelper::Sprintf("SCENE_CMD_OBJECT_LIST(%i, %s)", objects.size(), listName.c_str());
} }

View file

@ -50,7 +50,7 @@ void SetPathways::DeclareReferencesLate(const std::string& prefix)
std::string SetPathways::GetBodySourceCode() const std::string SetPathways::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "Path", listName); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "Path", listName, parent->workerID);
return StringHelper::Sprintf("SCENE_CMD_PATH_LIST(%s)", listName.c_str()); return StringHelper::Sprintf("SCENE_CMD_PATH_LIST(%s)", listName.c_str());
} }

View file

@ -34,7 +34,7 @@ void SetRoomList::DeclareReferences(const std::string& prefix)
std::string SetRoomList::GetBodySourceCode() const std::string SetRoomList::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "RomFile", listName); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "RomFile", listName, parent->workerID);
return StringHelper::Sprintf("SCENE_CMD_ROOM_LIST(%i, %s)", romfile->rooms.size(), return StringHelper::Sprintf("SCENE_CMD_ROOM_LIST(%i, %s)", romfile->rooms.size(),
listName.c_str()); listName.c_str());
} }

View file

@ -51,7 +51,8 @@ void SetStartPositionList::DeclareReferences(const std::string& prefix)
std::string SetStartPositionList::GetBodySourceCode() const std::string SetStartPositionList::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "ActorEntry", listName); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "ActorEntry", listName,
parent->workerID);
return StringHelper::Sprintf("SCENE_CMD_SPAWN_LIST(%i, %s)", actors.size(), listName.c_str()); return StringHelper::Sprintf("SCENE_CMD_SPAWN_LIST(%i, %s)", actors.size(), listName.c_str());
} }

View file

@ -52,7 +52,8 @@ void SetTransitionActorList::DeclareReferences(const std::string& prefix)
std::string SetTransitionActorList::GetBodySourceCode() const std::string SetTransitionActorList::GetBodySourceCode() const
{ {
std::string listName; std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "TransitionActorEntry", listName); Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "TransitionActorEntry", listName,
parent->workerID);
return StringHelper::Sprintf("SCENE_CMD_TRANSITION_ACTOR_LIST(%i, %s)", transitionActors.size(), return StringHelper::Sprintf("SCENE_CMD_TRANSITION_ACTOR_LIST(%i, %s)", transitionActors.size(),
listName.c_str()); listName.c_str());
} }

View file

@ -89,7 +89,8 @@ void ZSkeleton::DeclareReferences(const std::string& prefix)
std::string ZSkeleton::GetBodySourceCode() const std::string ZSkeleton::GetBodySourceCode() const
{ {
std::string limbArrayName; std::string limbArrayName;
Globals::Instance->GetSegmentedPtrName(limbsArrayAddress, parent, "", limbArrayName); Globals::Instance->GetSegmentedPtrName(limbsArrayAddress, parent, "", limbArrayName,
parent->workerID);
switch (type) switch (type)
{ {
@ -245,7 +246,8 @@ std::string ZLimbTable::GetBodySourceCode() const
for (size_t i = 0; i < count; i++) for (size_t i = 0; i < count; i++)
{ {
std::string limbName; std::string limbName;
Globals::Instance->GetSegmentedPtrName(limbsAddresses[i], parent, "", limbName); Globals::Instance->GetSegmentedPtrName(limbsAddresses[i], parent, "", limbName,
parent->workerID);
body += StringHelper::Sprintf("\t%s,", limbName.c_str()); body += StringHelper::Sprintf("\t%s,", limbName.c_str());
if (i + 1 < count) if (i + 1 < count)

View file

@ -21,12 +21,12 @@ void ZText::ParseRawData()
const auto& rawData = parent->GetRawData(); const auto& rawData = parent->GetRawData();
uint32_t currentPtr = StringHelper::StrToL(registeredAttributes.at("CodeOffset").value, 16); uint32_t currentPtr = StringHelper::StrToL(registeredAttributes.at("CodeOffset").value, 16);
std::vector<uint8_t> codeData = Globals::Instance->GetBaseromFile(Globals::Instance->baseRomPath.string() + "code"); std::vector<uint8_t> codeData;
//std::vector<uint8_t> codeData = File::ReadAllBytes(Globals::Instance->baseRomPath.string() + "\\code");
// In some cases with the multi-process extractor it seems that it fails to read the code file if something else is reading from it at the same time. if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory)
//while (codeData.size() == 0) codeData = Globals::Instance->GetBaseromFile("code");
//codeData = File::ReadAllBytes(Globals::Instance->baseRomPath.string() + "\\code"); else
codeData = Globals::Instance->GetBaseromFile(Globals::Instance->baseRomPath.string() + "code");
while (true) while (true)
{ {

View file

@ -349,9 +349,12 @@ std::string TextureColorChangingParams::GetBodySourceCode() const
std::string envColorListName; std::string envColorListName;
std::string frameDataListName; std::string frameDataListName;
Globals::Instance->GetSegmentedPtrName(primColorListAddress, parent, "", primColorListName); Globals::Instance->GetSegmentedPtrName(primColorListAddress, parent, "", primColorListName,
Globals::Instance->GetSegmentedPtrName(envColorListAddress, parent, "", envColorListName); parent->workerID);
Globals::Instance->GetSegmentedPtrName(frameDataListAddress, parent, "", frameDataListName); Globals::Instance->GetSegmentedPtrName(envColorListAddress, parent, "", envColorListName,
parent->workerID);
Globals::Instance->GetSegmentedPtrName(frameDataListAddress, parent, "", frameDataListName,
parent->workerID);
std::string bodyStr = StringHelper::Sprintf( std::string bodyStr = StringHelper::Sprintf(
"\n %d, %d, %s, %s, %s,\n", animLength, colorListCount, primColorListName.c_str(), "\n %d, %d, %s, %s, %s,\n", animLength, colorListCount, primColorListName.c_str(),
@ -423,7 +426,8 @@ void TextureCyclingParams::DeclareReferences([[maybe_unused]] const std::string&
for (const auto& tex : textureList) for (const auto& tex : textureList)
{ {
bool texFound = Globals::Instance->GetSegmentedPtrName(tex, parent, "", texName); bool texFound =
Globals::Instance->GetSegmentedPtrName(tex, parent, "", texName, parent->workerID);
// texName is a raw segmented pointer. This occurs if the texture is not declared // texName is a raw segmented pointer. This occurs if the texture is not declared
// separately since we cannot read the format. In theory we could scan DLists for the // separately since we cannot read the format. In theory we could scan DLists for the
@ -477,9 +481,10 @@ std::string TextureCyclingParams::GetBodySourceCode() const
std::string textureListName; std::string textureListName;
std::string textureIndexListName; std::string textureIndexListName;
Globals::Instance->GetSegmentedPtrName(textureListAddress, parent, "", textureListName); Globals::Instance->GetSegmentedPtrName(textureListAddress, parent, "", textureListName,
parent->workerID);
Globals::Instance->GetSegmentedPtrName(textureIndexListAddress, parent, "", Globals::Instance->GetSegmentedPtrName(textureIndexListAddress, parent, "",
textureIndexListName); textureIndexListName, parent->workerID);
std::string bodyStr = StringHelper::Sprintf( std::string bodyStr = StringHelper::Sprintf(
"\n %d, %s, %s,\n", cycleLength, textureListName.c_str(), textureIndexListName.c_str()); "\n %d, %s, %s,\n", cycleLength, textureListName.c_str(), textureIndexListName.c_str());
@ -652,7 +657,8 @@ std::string ZTextureAnimation::GetBodySourceCode() const
for (const auto& entry : entries) for (const auto& entry : entries)
{ {
std::string paramName; std::string paramName;
Globals::Instance->GetSegmentedPtrName(entry.paramsPtr, parent, "", paramName); Globals::Instance->GetSegmentedPtrName(entry.paramsPtr, parent, "", paramName,
parent->workerID);
bodyStr += StringHelper::Sprintf("\t{ %d, %d, %s },\n", entry.segment, entry.type, bodyStr += StringHelper::Sprintf("\t{ %d, %d, %s },\n", entry.segment, entry.type,
paramName.c_str()); paramName.c_str());

251
ZAPDTR/ZAPD/ctpl_stl.h Normal file
View file

@ -0,0 +1,251 @@
/*********************************************************
*
* Copyright (C) 2014 by Vitaliy Vitsentiy
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*********************************************************/
#ifndef __ctpl_stl_thread_pool_H__
#define __ctpl_stl_thread_pool_H__
#include <functional>
#include <thread>
#include <atomic>
#include <vector>
#include <memory>
#include <exception>
#include <future>
#include <mutex>
#include <queue>
// thread pool to run user's functors with signature
// ret func(int id, other_params)
// where id is the index of the thread that runs the functor
// ret is some return type
namespace ctpl {
namespace detail {
template <typename T>
class Queue {
public:
bool push(T const & value) {
std::unique_lock<std::mutex> lock(this->mutex);
this->q.push(value);
return true;
}
// deletes the retrieved element, do not use for non integral types
bool pop(T & v) {
std::unique_lock<std::mutex> lock(this->mutex);
if (this->q.empty())
return false;
v = this->q.front();
this->q.pop();
return true;
}
bool empty() {
std::unique_lock<std::mutex> lock(this->mutex);
return this->q.empty();
}
private:
std::queue<T> q;
std::mutex mutex;
};
}
class thread_pool {
public:
thread_pool() { this->init(); }
thread_pool(int nThreads) { this->init(); this->resize(nThreads); }
// the destructor waits for all the functions in the queue to be finished
~thread_pool() {
this->stop(true);
}
// get the number of running threads in the pool
int size() { return static_cast<int>(this->threads.size()); }
// number of idle threads
int n_idle() { return this->nWaiting; }
std::thread & get_thread(int i) { return *this->threads[i]; }
// change the number of threads in the pool
// should be called from one thread, otherwise be careful to not interleave, also with this->stop()
// nThreads must be >= 0
void resize(int nThreads) {
if (!this->isStop && !this->isDone) {
int oldNThreads = static_cast<int>(this->threads.size());
if (oldNThreads <= nThreads) { // if the number of threads is increased
this->threads.resize(nThreads);
this->flags.resize(nThreads);
for (int i = oldNThreads; i < nThreads; ++i) {
this->flags[i] = std::make_shared<std::atomic<bool>>(false);
this->set_thread(i);
}
}
else { // the number of threads is decreased
for (int i = oldNThreads - 1; i >= nThreads; --i) {
*this->flags[i] = true; // this thread will finish
this->threads[i]->detach();
}
{
// stop the detached threads that were waiting
std::unique_lock<std::mutex> lock(this->mutex);
this->cv.notify_all();
}
this->threads.resize(nThreads); // safe to delete because the threads are detached
this->flags.resize(nThreads); // safe to delete because the threads have copies of shared_ptr of the flags, not originals
}
}
}
// empty the queue
void clear_queue() {
std::function<void(int id)> * _f;
while (this->q.pop(_f))
delete _f; // empty the queue
}
// pops a functional wrapper to the original function
std::function<void(int)> pop() {
std::function<void(int id)> * _f = nullptr;
this->q.pop(_f);
std::unique_ptr<std::function<void(int id)>> func(_f); // at return, delete the function even if an exception occurred
std::function<void(int)> f;
if (_f)
f = *_f;
return f;
}
// wait for all computing threads to finish and stop all threads
// may be called asynchronously to not pause the calling thread while waiting
// if isWait == true, all the functions in the queue are run, otherwise the queue is cleared without running the functions
void stop(bool isWait = false) {
if (!isWait) {
if (this->isStop)
return;
this->isStop = true;
for (int i = 0, n = this->size(); i < n; ++i) {
*this->flags[i] = true; // command the threads to stop
}
this->clear_queue(); // empty the queue
}
else {
if (this->isDone || this->isStop)
return;
this->isDone = true; // give the waiting threads a command to finish
}
{
std::unique_lock<std::mutex> lock(this->mutex);
this->cv.notify_all(); // stop all waiting threads
}
for (int i = 0; i < static_cast<int>(this->threads.size()); ++i) { // wait for the computing threads to finish
if (this->threads[i]->joinable())
this->threads[i]->join();
}
// if there were no threads in the pool but some functors in the queue, the functors are not deleted by the threads
// therefore delete them here
this->clear_queue();
this->threads.clear();
this->flags.clear();
}
template<typename F, typename... Rest>
auto push(F && f, Rest&&... rest) ->std::future<decltype(f(0, rest...))> {
auto pck = std::make_shared<std::packaged_task<decltype(f(0, rest...))(int)>>(
std::bind(std::forward<F>(f), std::placeholders::_1, std::forward<Rest>(rest)...)
);
auto _f = new std::function<void(int id)>([pck](int id) {
(*pck)(id);
});
this->q.push(_f);
std::unique_lock<std::mutex> lock(this->mutex);
this->cv.notify_one();
return pck->get_future();
}
// run the user's function that excepts argument int - id of the running thread. returned value is templatized
// operator returns std::future, where the user can get the result and rethrow the catched exceptins
template<typename F>
auto push(F && f) ->std::future<decltype(f(0))> {
auto pck = std::make_shared<std::packaged_task<decltype(f(0))(int)>>(std::forward<F>(f));
auto _f = new std::function<void(int id)>([pck](int id) {
(*pck)(id);
});
this->q.push(_f);
std::unique_lock<std::mutex> lock(this->mutex);
this->cv.notify_one();
return pck->get_future();
}
private:
// deleted
thread_pool(const thread_pool &);// = delete;
thread_pool(thread_pool &&);// = delete;
thread_pool & operator=(const thread_pool &);// = delete;
thread_pool & operator=(thread_pool &&);// = delete;
void set_thread(int i) {
std::shared_ptr<std::atomic<bool>> flag(this->flags[i]); // a copy of the shared ptr to the flag
auto f = [this, i, flag/* a copy of the shared ptr to the flag */]() {
std::atomic<bool> & _flag = *flag;
std::function<void(int id)> * _f;
bool isPop = this->q.pop(_f);
while (true) {
while (isPop) { // if there is anything in the queue
std::unique_ptr<std::function<void(int id)>> func(_f); // at return, delete the function even if an exception occurred
(*_f)(i);
if (_flag)
return; // the thread is wanted to stop, return even if the queue is not empty yet
else
isPop = this->q.pop(_f);
}
// the queue is empty here, wait for the next command
std::unique_lock<std::mutex> lock(this->mutex);
++this->nWaiting;
this->cv.wait(lock, [this, &_f, &isPop, &_flag](){ isPop = this->q.pop(_f); return isPop || this->isDone || _flag; });
--this->nWaiting;
if (!isPop)
return; // if the queue is empty and this->isDone == true or *flag then return
}
};
this->threads[i].reset(new std::thread(f)); // compiler may not support std::make_unique()
}
void init() { this->nWaiting = 0; this->isStop = false; this->isDone = false; }
std::vector<std::unique_ptr<std::thread>> threads;
std::vector<std::shared_ptr<std::atomic<bool>>> flags;
detail::Queue<std::function<void(int id)> *> q;
std::atomic<bool> isDone;
std::atomic<bool> isStop;
std::atomic<int> nWaiting; // how many threads are waiting
std::mutex mutex;
std::condition_variable cv;
};
}
#endif // __ctpl_stl_thread_pool_H__

View file

@ -2,6 +2,8 @@
#define GFXD_PRIV_H #define GFXD_PRIV_H
#include "gfxd.h" #include "gfxd.h"
#define CONFIG_MT
#ifdef CONFIG_MT #ifdef CONFIG_MT
# ifdef _MSC_VER # ifdef _MSC_VER
# define TLOCAL __declspec(thread) # define TLOCAL __declspec(thread)
@ -9,7 +11,7 @@
# define TLOCAL _Thread_local # define TLOCAL _Thread_local
# endif # endif
#else #else
# define TLOCAL #define TLOCAL
#endif #endif
#define UCFUNC static inline #define UCFUNC static inline