mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-22 14:23:44 -07:00
ZAPD is now multi-threaded.
This commit is contained in:
parent
dba4cf6c14
commit
e4855fba0b
48 changed files with 680 additions and 192 deletions
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) == '&')
|
||||||
|
|
|
@ -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) == '&')
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
0
ZAPDTR/ZAPD/FileWorker.cpp
Normal file
0
ZAPDTR/ZAPD/FileWorker.cpp
Normal file
15
ZAPDTR/ZAPD/FileWorker.h
Normal file
15
ZAPDTR/ZAPD/FileWorker.h
Normal 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;
|
||||||
|
};
|
|
@ -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 (std::find(segments.begin(), segments.end(), segment) == segments.end())
|
if (!Globals::Instance->singleThreaded)
|
||||||
segments.push_back(segment);
|
|
||||||
if (cfg.segmentRefFiles.find(segment) == cfg.segmentRefFiles.end())
|
|
||||||
cfg.segmentRefFiles[segment] = std::vector<ZFile*>();
|
|
||||||
|
|
||||||
cfg.segmentRefFiles[segment].push_back(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Globals::HasSegment(int32_t segment)
|
|
||||||
{
|
|
||||||
return std::find(segments.begin(), segments.end(), segment) != segments.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
ZFile* Globals::GetSegment(int32_t segment)
|
|
||||||
{
|
|
||||||
if (HasSegment(segment))
|
|
||||||
{
|
{
|
||||||
int idx = std::find(segments.begin(), segments.end(), segment) - segments.begin();
|
auto worker = workerData[workerID];
|
||||||
return files[idx];
|
|
||||||
|
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
|
else
|
||||||
return nullptr;
|
{
|
||||||
|
if (std::find(segments.begin(), segments.end(), segment) == segments.end())
|
||||||
|
segments.push_back(segment);
|
||||||
|
if (cfg.segmentRefFiles.find(segment) == cfg.segmentRefFiles.end())
|
||||||
|
cfg.segmentRefFiles[segment] = std::vector<ZFile*>();
|
||||||
|
|
||||||
|
cfg.segmentRefFiles[segment].push_back(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
ZFile* Globals::GetSegment(int32_t segment, int workerID)
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
return files[idx];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
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))
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
numWorkersLeft = fileListSize;
|
||||||
|
|
||||||
|
for (int i = 0; i < fileListSize; i++)
|
||||||
{
|
{
|
||||||
printf("(%i / %i): %s\n", (i+1), fileList.size(), fileList[i].c_str());
|
if (Globals::Instance->singleThreaded)
|
||||||
|
|
||||||
for (auto& extFile : Globals::Instance->cfg.externalFiles)
|
|
||||||
{
|
{
|
||||||
fs::path externalXmlFilePath =
|
ExtractFunc(i, fileList.size(), fileList[i], fileMode);
|
||||||
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);
|
|
||||||
|
|
||||||
if (!parseSuccessful)
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
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];
|
std::string fileListItem = fileList[i];
|
||||||
Globals::Instance->files.erase(Globals::Instance->files.begin() + i);
|
pool.push([i, fileListSize, fileListItem, fileMode](int) {
|
||||||
i--;
|
ExtractFunc(i, fileListSize, fileListItem, fileMode);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Globals::Instance->externalFiles.clear();
|
if (!Globals::Instance->singleThreaded)
|
||||||
Globals::Instance->segments.clear();
|
{
|
||||||
Globals::Instance->cfg.segmentRefFiles.clear();
|
while (true)
|
||||||
|
{
|
||||||
|
if (numWorkersLeft <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto end = std::chrono::steady_clock::now();
|
auto end = std::chrono::steady_clock::now();
|
||||||
|
@ -339,7 +341,7 @@ int main(int argc, char* argv[])
|
||||||
std::chrono::duration_cast<std::chrono::seconds>(end - start).count();
|
std::chrono::duration_cast<std::chrono::seconds>(end - start).count();
|
||||||
|
|
||||||
printf("Generated OTR File Data in %i seconds\n", diff);
|
printf("Generated OTR File Data in %i seconds\n", diff);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool parseSuccessful;
|
bool parseSuccessful;
|
||||||
|
@ -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();
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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" />
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -183,15 +185,20 @@ 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 (!File::Exists((basePath / name).string()))
|
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
|
||||||
{
|
{
|
||||||
std::string errorHeader = StringHelper::Sprintf("binary file '%s' does not exist.",
|
if (!File::Exists((basePath / name).string()))
|
||||||
(basePath / name).c_str());
|
{
|
||||||
HANDLE_ERROR_PROCESS(WarningType::Always, errorHeader, "");
|
std::string errorHeader = StringHelper::Sprintf("binary file '%s' does not exist.",
|
||||||
|
(basePath / name).c_str());
|
||||||
|
HANDLE_ERROR_PROCESS(WarningType::Always, errorHeader, "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//rawData = File::ReadAllBytes((basePath / name).string());
|
if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory)
|
||||||
rawData = Globals::Instance->GetBaseromFile((basePath / name).string());
|
rawData = Globals::Instance->GetBaseromFile(name);
|
||||||
|
else
|
||||||
|
rawData = Globals::Instance->GetBaseromFile((basePath / name).string());
|
||||||
|
|
||||||
if (reader->Attribute("RangeEnd") == nullptr)
|
if (reader->Attribute("RangeEnd") == nullptr)
|
||||||
rangeEnd = rawData.size();
|
rangeEnd = rawData.size();
|
||||||
|
@ -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++;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 +=
|
||||||
|
|
|
@ -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");
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
251
ZAPDTR/ZAPD/ctpl_stl.h
Normal 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__
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue