Update MinimapList struct + ZAPD (#1165)

* Update MinimapList struct

* git subrepo pull --force tools/ZAPD

subrepo:
  subdir:   "tools/ZAPD"
  merged:   "5786abbdd"
upstream:
  origin:   "https://github.com/zeldaret/ZAPD.git"
  branch:   "master"
  commit:   "5786abbdd"
git-subrepo:
  version:  "0.4.5"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "dbb99be"
This commit is contained in:
Derek Hensley
2023-01-01 14:04:19 -03:00
committed by GitHub
parent c52414ff79
commit e4e0aed7cb
76 changed files with 931 additions and 5729 deletions
+1 -1
View File
@@ -477,7 +477,7 @@ typedef struct {
typedef struct {
/* 0x0 */ MinimapEntry* entry;
/* 0x4 */ UNK_TYPE unk4;
/* 0x4 */ s16 unk4;
} MinimapList; // size = 0x8
typedef struct {
+3 -3
View File
@@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/zeldaret/ZAPD.git
branch = master
commit = 87cb648b4311d20673452111edaf4d38a5290c28
parent = 06412c070f0240eacfaa860eee99b9c723245b7f
commit = 5786abbdd2d0fd14907e03575a0bd972c1fe9b28
parent = e451a103ba5d14af3dd14acfa54a6b4999fd951f
method = merge
cmdver = 0.4.3
cmdver = 0.4.5
@@ -58,9 +58,11 @@ void ExporterExample_Collision::Save(ZResource* res, [[maybe_unused]] fs::path o
writer->Seek(col->polyTypeDefSegmentOffset, SeekOffsetType::Start);
for (uint16_t i = 0; i < col->polygonTypes.size(); i++)
writer->Write(col->polygonTypes[i]);
for (const auto& poly : col->polygonTypes)
{
writer->Write(poly.data[0]);
writer->Write(poly.data[1]);
}
writer->Seek(col->camDataSegmentOffset, SeekOffsetType::Start);
for (auto entry : col->camData->entries)
+2 -2
View File
@@ -30,7 +30,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -43,7 +43,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+1 -1
View File
@@ -334,7 +334,7 @@ void ExporterExample_Room::Save(ZResource* res, fs::path outPath, BinaryWriter*
writer->Write(entry.rotX);
writer->Write(entry.rotY);
writer->Write(entry.rotZ);
writer->Write(entry.initVar);
writer->Write(entry.params);
}
writer->Seek(oldOffset, SeekOffsetType::Start);
+10 -1
View File
@@ -68,6 +68,15 @@ pipeline {
}
}
// INSTALL PYTHON DEPENDENCIES, currently MM only
stage('Install Python dependencies') {
steps {
dir('mm') {
sh 'python3 -m pip install -r requirements.txt'
}
}
}
// BUILD THE REPOS
stage('Build repos') {
parallel {
@@ -82,7 +91,7 @@ pipeline {
steps {
dir('mm') {
sh 'make -j disasm'
sh 'make -j all'
sh 'make -j'
}
}
}
+1 -1
View File
@@ -15,7 +15,7 @@ else
CXX := g++
endif
INC := -I ZAPD -I lib/elfio -I lib/libgfxd -I lib/tinyxml2 -I ZAPDUtils
INC := -I ZAPD -I lib/libgfxd -I lib/tinyxml2 -I ZAPDUtils
CXXFLAGS := -fpic -std=c++17 -Wall -Wextra -fno-omit-frame-pointer
OPTFLAGS :=
-5
View File
@@ -71,9 +71,6 @@ ZAPD needs a _File parsing mode_ to be passed as first parameter. The options ar
- `blb`: "Build blob" mode.
- In this mode, ZAPD expects a BIN file as input and a filename as ouput.
- ZAPD will try to convert the given BIN into the contents of a `uint8_t` C array.
- `bovl`: "Build overlay" mode.
- In this mode, ZAPD expects an overlay C file as input, a filename as ouput and an overlay configuration path (`-cfg`).
- ZAPD will generate a reloc `.s` file.
ZAPD also accepts the following list of extra parameters:
@@ -102,8 +99,6 @@ ZAPD also accepts the following list of extra parameters:
- `ia16`
- `ci4`
- `ci8`
- `-cfg PATH`: Set cfg path (for overlays).
- Can be used only in `bovl` mode.
- `-rconf PATH` Read Config File.
- `-eh`: Enable error handler.
- Only available in non-Windows environments.
+205
View File
@@ -0,0 +1,205 @@
#include "CrashHandler.h"
#include "Utils/StringHelper.h"
#if __has_include(<unistd.h>)
#define HAS_POSIX 1
#else
#define HAS_POSIX 0
#endif
#include <array>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#if HAS_POSIX == 1
#include <csignal>
#include <cxxabi.h> // for __cxa_demangle
#include <dlfcn.h> // for dladdr
#include <execinfo.h>
#include <unistd.h>
#elif defined(_MSC_VER)
#include <Windows.h>
#include <DbgHelp.h>
#include <inttypes.h>
#pragma comment(lib, "Dbghelp.lib")
#endif
// Feel free to add more crash messages.
static std::array<const char* const, 14> crashEasterEgg = {
"\tYou've met with a terrible fate, haven't you?",
"\tSEA BEARS FOAM. SLEEP BEARS DREAMS. \n\tBOTH END IN THE SAME WAY: CRASSSH!",
"\tZAPD has fallen and cannot get up.",
"\tIT'S A SECRET TO EVERYBODY. \n\tBut it shouldn't be, you'd better ask about it!",
"\tI AM ERROR.",
"\tGRUMBLE,GRUMBLE...",
"\tDODONGO DISLIKES SMOKE \n\tAnd ZAPD dislikes whatever you fed it.",
"\tMay the way of the Hero lead \n\tto the debugger.",
"\tTHE WIND FISH SLUMBERS LONG... \n\tTHE HERO'S LIFE GONE... ",
"\tSEA BEARS FOAM, SLEEP BEARS DREAMS. \n\tBOTH END IN THE SAME WAY CRASSSH!",
"\tYou've met with a terrible fate, haven't you?",
"\tMaster, I calculate a 100% probability that ZAPD has crashed. \n\tAdditionally, the "
"batteries in your Wii Remote are nearly depleted.",
"\t CONGRATURATIONS! \n"
"\tAll Pages are displayed.\n"
"\t THANK YOU! \n"
"\t You are great debugger!",
"\tRCP is HUNG UP!!\n"
"\tOh! MY GOD!!",
};
#if HAS_POSIX == 1
void ErrorHandler(int sig)
{
std::array<void*, 4096> arr;
constexpr size_t nMaxFrames = arr.size();
size_t size = backtrace(arr.data(), nMaxFrames);
char** symbols = backtrace_symbols(arr.data(), nMaxFrames);
fprintf(stderr, "\nZAPD crashed. (Signal: %i)\n", sig);
srand(time(nullptr));
auto easterIndex = rand() % crashEasterEgg.size();
fprintf(stderr, "\n%s\n\n", crashEasterEgg[easterIndex]);
fprintf(stderr, "Traceback:\n");
for (size_t i = 1; i < size; i++)
{
Dl_info info;
uint32_t gotAddress = dladdr(arr[i], &info);
std::string functionName(symbols[i]);
if (gotAddress != 0 && info.dli_sname != nullptr)
{
int32_t status;
char* demangled = abi::__cxa_demangle(info.dli_sname, nullptr, nullptr, &status);
const char* nameFound = info.dli_sname;
if (status == 0)
{
nameFound = demangled;
}
functionName = StringHelper::Sprintf("%s (+0x%X)", nameFound,
(char*)arr[i] - (char*)info.dli_saddr);
free(demangled);
}
fprintf(stderr, "%-3zd %s\n", i, functionName.c_str());
}
fprintf(stderr, "\n");
free(symbols);
exit(1);
}
#elif defined(_MSC_VER)
void printStack(CONTEXT* ctx)
{
BOOL result;
HANDLE process;
HANDLE thread;
HMODULE hModule;
ULONG frame;
DWORD64 displacement;
DWORD disp;
srand(time(nullptr));
auto easterIndex = rand() % crashEasterEgg.size();
fprintf(stderr, "\n%s\n\n", crashEasterEgg[easterIndex]);
#if defined(_M_AMD64)
STACKFRAME64 stack;
memset(&stack, 0, sizeof(STACKFRAME64));
#else
STACKFRAME stack;
memset(&stack, 0, sizeof(STACKFRAME));
#endif
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME + sizeof(TCHAR)];
char module[512];
PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
CONTEXT ctx2;
memcpy(&ctx2, ctx, sizeof(CONTEXT));
process = GetCurrentProcess();
thread = GetCurrentThread();
SymInitialize(process, nullptr, TRUE);
constexpr DWORD machineType =
#if defined(_M_AMD64)
IMAGE_FILE_MACHINE_AMD64;
#else
IMAGE_FILE_MACHINE_I386;
#endif
displacement = 0;
for (frame = 0;; frame++)
{
result = StackWalk(machineType, process, thread, &stack, &ctx2, nullptr,
SymFunctionTableAccess, SymGetModuleBase, nullptr);
if (!result)
{
break;
}
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
symbol->MaxNameLen = MAX_SYM_NAME;
SymFromAddr(process, (ULONG64)stack.AddrPC.Offset, &displacement, symbol);
#if defined(_M_AMD64)
IMAGEHLP_LINE64 line;
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
#else
IMAGEHLP_LINE line;
line.SizeOfStruct = sizeof(IMAGEHLP_LINE);
#endif
if (SymGetLineFromAddr(process, stack.AddrPC.Offset, &disp, &line))
{
fprintf(stderr, "%u\t %s in %s: line: %lu: \n", frame, symbol->Name, line.FileName,
line.LineNumber);
}
else
{
fprintf(stderr, "%u\tat % s\n", frame, symbol->Name);
hModule = nullptr;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
(LPCTSTR)(stack.AddrPC.Offset), &hModule);
if (hModule != nullptr)
{
GetModuleFileNameA(hModule, module, 512 - 1);
}
fprintf(stderr, "%u\tIn %s\n", frame, module);
}
}
}
LONG seh_filter(_EXCEPTION_POINTERS* ex)
{
fprintf(stderr, "EXCEPTION 0x%x occured\n", ex->ExceptionRecord->ExceptionCode);
printStack(ex->ContextRecord);
return EXCEPTION_EXECUTE_HANDLER;
}
#endif
void CrashHandler_Init()
{
#if HAS_POSIX == 1
signal(SIGSEGV, ErrorHandler);
signal(SIGABRT, ErrorHandler);
#elif defined(_MSC_VER)
SetUnhandledExceptionFilter(seh_filter);
#else
HANDLE_WARNING(WarningType::Always,
"tried to set error handler, but this ZAPD build lacks support for one", "");
#endif
}
+6
View File
@@ -0,0 +1,6 @@
#ifndef CRASH_HANDLER_H
#define CRASH_HANDLER_H
void CrashHandler_Init();
#endif
+23 -1
View File
@@ -94,6 +94,26 @@ void GameConfig::ConfigFunc_ObjectList(const tinyxml2::XMLElement& element)
objectList.emplace_back(std::move(line));
}
void GameConfig::ConfigFunc_EntranceList(const tinyxml2::XMLElement& element)
{
std::string fileName = element.Attribute("File");
std::vector<std::string> lines =
File::ReadAllLines(Path::GetDirectoryName(configFilePath) / fileName);
for (auto& line : lines)
entranceList.emplace_back(std::move(line));
}
void GameConfig::ConfigFunc_specialEntranceList(const tinyxml2::XMLElement& element)
{
std::string fileName = element.Attribute("File");
std::vector<std::string> lines =
File::ReadAllLines(Path::GetDirectoryName(configFilePath) / fileName);
for (auto& line : lines)
specialEntranceList.emplace_back(std::move(line));
}
void GameConfig::ConfigFunc_TexturePool(const tinyxml2::XMLElement& element)
{
std::string fileName = element.Attribute("File");
@@ -145,10 +165,12 @@ void GameConfig::ConfigFunc_ExternalFile(const tinyxml2::XMLElement& element)
void GameConfig::ReadConfigFile(const fs::path& argConfigFilePath)
{
static const std::map<std::string, ConfigFunc> ConfigFuncDictionary = {
static const std::unordered_map<std::string, ConfigFunc> ConfigFuncDictionary = {
{"SymbolMap", &GameConfig::ConfigFunc_SymbolMap},
{"ActorList", &GameConfig::ConfigFunc_ActorList},
{"ObjectList", &GameConfig::ConfigFunc_ObjectList},
{"EntranceList", &GameConfig::ConfigFunc_EntranceList},
{"SpecialEntranceList", &GameConfig::ConfigFunc_specialEntranceList},
{"TexturePool", &GameConfig::ConfigFunc_TexturePool},
{"BGConfig", &GameConfig::ConfigFunc_BGConfig},
{"ExternalXMLFolder", &GameConfig::ConfigFunc_ExternalXMLFolder},
+4
View File
@@ -31,6 +31,8 @@ public:
std::map<uint32_t, std::string> symbolMap;
std::vector<std::string> actorList;
std::vector<std::string> objectList;
std::vector<std::string> entranceList;
std::vector<std::string> specialEntranceList;
std::map<uint32_t, TexturePoolEntry> texturePool; // Key = CRC
// ZBackground
@@ -49,6 +51,8 @@ public:
void ConfigFunc_SymbolMap(const tinyxml2::XMLElement& element);
void ConfigFunc_ActorList(const tinyxml2::XMLElement& element);
void ConfigFunc_ObjectList(const tinyxml2::XMLElement& element);
void ConfigFunc_EntranceList(const tinyxml2::XMLElement& element);
void ConfigFunc_specialEntranceList(const tinyxml2::XMLElement& element);
void ConfigFunc_TexturePool(const tinyxml2::XMLElement& element);
void ConfigFunc_BGConfig(const tinyxml2::XMLElement& element);
void ConfigFunc_ExternalXMLFolder(const tinyxml2::XMLElement& element);
+2 -2
View File
@@ -398,7 +398,7 @@ void ImageBackend::SetPaletteIndex(size_t index, uint8_t nR, uint8_t nG, uint8_t
alphaPalette[index] = nA;
}
void ImageBackend::SetPalette(const ImageBackend& pal)
void ImageBackend::SetPalette(const ImageBackend& pal, uint32_t offset)
{
assert(isColorIndexed);
size_t bytePerPixel = pal.GetBytesPerPixel();
@@ -422,7 +422,7 @@ void ImageBackend::SetPalette(const ImageBackend& pal)
uint8_t g = pal.pixelMatrix[y][x * bytePerPixel + 1];
uint8_t b = pal.pixelMatrix[y][x * bytePerPixel + 2];
uint8_t a = pal.pixelMatrix[y][x * bytePerPixel + 3];
SetPaletteIndex(index, r, g, b, a);
SetPaletteIndex(index + offset, r, g, b, a);
}
}
}
+2 -1
View File
@@ -42,8 +42,9 @@ public:
void SetGrayscalePixel(size_t y, size_t x, uint8_t grayscale, uint8_t alpha = 0);
void SetIndexedPixel(size_t y, size_t x, uint8_t index, uint8_t grayscale);
void SetIndexedPixel(size_t y, size_t x, uint8_t index, RGBAPixel pixel);
void SetPaletteIndex(size_t index, uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA);
void SetPalette(const ImageBackend& pal);
void SetPalette(const ImageBackend& pal, uint32_t offset = 0);
uint32_t GetWidth() const;
uint32_t GetHeight() const;
+3 -93
View File
@@ -1,5 +1,4 @@
#include "Globals.h"
#include "Overlays/ZOverlay.h"
#include "Utils/Directory.h"
#include "Utils/File.h"
#include "Utils/Path.h"
@@ -10,22 +9,12 @@
#include "ZFile.h"
#include "ZTexture.h"
#if !defined(_MSC_VER) && !defined(__CYGWIN__)
#include <csignal>
#include <cstdlib>
#include <ctime>
#include <cxxabi.h> // for __cxa_demangle
#include <dlfcn.h> // for dladdr
#include <execinfo.h>
#include <unistd.h>
#endif
#include "CrashHandler.h"
#include <string>
#include <string_view>
#include "tinyxml2.h"
extern const char gBuildHash[];
bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath,
ZFileMode fileMode);
@@ -33,61 +22,7 @@ void BuildAssetTexture(const fs::path& pngFilePath, TextureType texType, const f
void BuildAssetBackground(const fs::path& imageFilePath, const fs::path& outPath);
void BuildAssetBlob(const fs::path& blobFilePath, const fs::path& outPath);
#if !defined(_MSC_VER) && !defined(__CYGWIN__)
#define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0]))
void ErrorHandler(int sig)
{
void* array[4096];
const size_t nMaxFrames = sizeof(array) / sizeof(array[0]);
size_t size = backtrace(array, nMaxFrames);
char** symbols = backtrace_symbols(array, nMaxFrames);
fprintf(stderr, "\nZAPD crashed. (Signal: %i)\n", sig);
// Feel free to add more crash messages.
const char* crashEasterEgg[] = {
"\tYou've met with a terrible fate, haven't you?",
"\tSEA BEARS FOAM. SLEEP BEARS DREAMS. \n\tBOTH END IN THE SAME WAY: CRASSSH!",
"\tZAPD has fallen and cannot get up.",
};
srand(time(nullptr));
auto easterIndex = rand() % ARRAY_COUNT(crashEasterEgg);
fprintf(stderr, "\n%s\n\n", crashEasterEgg[easterIndex]);
fprintf(stderr, "Traceback:\n");
for (size_t i = 1; i < size; i++)
{
Dl_info info;
uint32_t gotAddress = dladdr(array[i], &info);
std::string functionName(symbols[i]);
if (gotAddress != 0 && info.dli_sname != nullptr)
{
int32_t status;
char* demangled = abi::__cxa_demangle(info.dli_sname, nullptr, nullptr, &status);
const char* nameFound = info.dli_sname;
if (status == 0)
{
nameFound = demangled;
}
functionName = StringHelper::Sprintf("%s (+0x%X)", nameFound,
(char*)array[i] - (char*)info.dli_saddr);
free(demangled);
}
fprintf(stderr, "%-3zd %s\n", i, functionName.c_str());
}
fprintf(stderr, "\n");
free(symbols);
exit(1);
}
#endif
extern const char gBuildHash[];
int main(int argc, char* argv[])
{
@@ -175,26 +110,13 @@ int main(int argc, char* argv[])
{
Globals::Instance->texType = ZTexture::GetTextureTypeFromString(argv[++i]);
}
else if (arg == "-cfg") // Set cfg path (for overlays)
// TODO: Change the name of this to something else so it doesn't
// get confused with XML config files.
{
Globals::Instance->cfgPath = argv[++i];
}
else if (arg == "-rconf") // Read Config File
{
Globals::Instance->cfg.ReadConfigFile(argv[++i]);
}
else if (arg == "-eh") // Enable Error Handler
{
#if !defined(_MSC_VER) && !defined(__CYGWIN__)
signal(SIGSEGV, ErrorHandler);
signal(SIGABRT, ErrorHandler);
#else
HANDLE_WARNING(WarningType::Always,
"tried to set error handler, but this ZAPD build lacks support for one",
"");
#endif
CrashHandler_Init();
}
else if (arg == "-v") // Verbose
{
@@ -231,8 +153,6 @@ int main(int argc, char* argv[])
fileMode = ZFileMode::BuildTexture;
else if (buildMode == "bren")
fileMode = ZFileMode::BuildBackground;
else if (buildMode == "bovl")
fileMode = ZFileMode::BuildOverlay;
else if (buildMode == "bsf")
fileMode = ZFileMode::BuildSourceFile;
else if (buildMode == "bblb")
@@ -314,16 +234,6 @@ int main(int argc, char* argv[])
{
BuildAssetBlob(Globals::Instance->inputPath, Globals::Instance->outputPath);
}
else if (fileMode == ZFileMode::BuildOverlay)
{
ZOverlay* overlay =
ZOverlay::FromBuild(Path::GetDirectoryName(Globals::Instance->inputPath),
Path::GetDirectoryName(Globals::Instance->cfgPath));
if (overlay != nullptr)
File::WriteAllText(Globals::Instance->outputPath.string(),
overlay->GetSourceOutputCode(""));
}
delete g;
return 0;
@@ -54,6 +54,7 @@ CutsceneMMCommand_GenericCmd::CutsceneMMCommand_GenericCmd(const std::vector<uin
commandID = static_cast<uint32_t>(cmdId);
entries.reserve(numEntries);
for (size_t i = 0; i < numEntries; i++)
{
auto* entry = new CutsceneSubCommandEntry_GenericMMCmd(rawData, rawDataIndex, cmdId);
@@ -96,6 +97,7 @@ CutsceneMMCommand_Camera::CutsceneMMCommand_Camera(const std::vector<uint8_t>& r
{
rawDataIndex += 4;
entries.reserve(numEntries);
for (size_t i = 0; i < numEntries / 4; i++)
{
auto* entry = new CutsceneSubCommandEntry_Camera(rawData, rawDataIndex);
@@ -138,6 +140,7 @@ CutsceneMMCommand_FadeScreen::CutsceneMMCommand_FadeScreen(const std::vector<uin
{
rawDataIndex += 4;
entries.reserve(numEntries);
for (size_t i = 0; i < numEntries; i++)
{
auto* entry = new CutsceneSubCommandEntry_FadeScreen(rawData, rawDataIndex);
@@ -174,6 +177,7 @@ CutsceneMMCommand_FadeSeq::CutsceneMMCommand_FadeSeq(const std::vector<uint8_t>&
{
rawDataIndex += 4;
entries.reserve(numEntries);
for (size_t i = 0; i < numEntries; i++)
{
auto* entry = new CutsceneSubCommandEntry_FadeSeq(rawData, rawDataIndex);
@@ -199,6 +203,7 @@ CutsceneMMCommand_NonImplemented::CutsceneMMCommand_NonImplemented(
{
rawDataIndex += 4;
entries.reserve(numEntries);
for (size_t i = 0; i < numEntries; i++)
{
auto* entry = new CutsceneSubCommandEntry_NonImplemented(rawData, rawDataIndex);
@@ -154,6 +154,7 @@ CutsceneCommand_GenericCmd::CutsceneCommand_GenericCmd(const std::vector<uint8_t
rawDataIndex += 4;
commandID = static_cast<uint32_t>(cmdId);
entries.reserve(numEntries);
for (size_t i = 0; i < numEntries; i++)
{
@@ -320,6 +321,7 @@ CutsceneCommand_Rumble::CutsceneCommand_Rumble(const std::vector<uint8_t>& rawDa
{
rawDataIndex += 4;
entries.reserve(numEntries);
for (size_t i = 0; i < numEntries; i++)
{
auto* entry = new CutsceneSubCommandEntry_Rumble(rawData, rawDataIndex);
@@ -363,6 +365,7 @@ CutsceneCommand_SetTime::CutsceneCommand_SetTime(const std::vector<uint8_t>& raw
{
rawDataIndex += 4;
entries.reserve(numEntries);
for (size_t i = 0; i < numEntries; i++)
{
auto* entry = new CutsceneSubCommandEntry_SetTime(rawData, rawDataIndex);
@@ -438,6 +441,7 @@ CutsceneCommand_TextBox::CutsceneCommand_TextBox(const std::vector<uint8_t>& raw
{
rawDataIndex += 4;
entries.reserve(numEntries);
for (size_t i = 0; i < numEntries; i++)
{
auto* entry = new CutsceneSubCommandEntry_TextBox(rawData, rawDataIndex);
@@ -516,6 +520,7 @@ CutsceneCommand_ActorAction::CutsceneCommand_ActorAction(const std::vector<uint8
{
rawDataIndex += 4;
entries.reserve(numEntries);
for (size_t i = 0; i < numEntries; i++)
{
auto* entry = new CutsceneSubCommandEntry_ActorAction(rawData, rawDataIndex);
@@ -104,6 +104,8 @@ void Struct_800A598C::ParseRawData()
if (unk_8 != 0 && GETSEGNUM(unk_8) == parent->segment)
{
uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress);
unk_8_arr.reserve(unk_0);
for (size_t i = 0; i < unk_0; i++)
{
Struct_800A57C0 unk8_data(parent);
@@ -117,6 +119,8 @@ void Struct_800A598C::ParseRawData()
if (unk_C != 0 && GETSEGNUM(unk_8) == parent->segment)
{
uint32_t unk_C_Offset = Seg2Filespace(unk_C, parent->baseAddress);
unk_C_arr.reserve(unk_2);
for (size_t i = 0; i < unk_2; i++)
{
Struct_800A598C_2 unkC_data(parent);
@@ -244,6 +248,8 @@ void Struct_800A5E28::ParseRawData()
if (unk_4 != 0 && GETSEGNUM(unk_4) == parent->segment)
{
uint32_t unk_4_Offset = Seg2Filespace(unk_4, parent->baseAddress);
unk_4_arr.reserve(unk_2);
for (size_t i = 0; i < unk_2; i++)
{
Struct_800A598C unk_4_data(parent);
-352
View File
@@ -1,352 +0,0 @@
#include "ZOverlay.h"
#include <cassert>
#include <unordered_set>
#include "Globals.h"
#include "Utils/Directory.h"
#include "Utils/File.h"
#include "Utils/Path.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
using namespace ELFIO;
const char* RelocationEntry::GetSectionName() const
{
switch (sectionType)
{
case SectionType::Text:
return ".text";
case SectionType::Data:
return ".data";
case SectionType::RoData:
return ".rodata";
case SectionType::Bss:
return ".bss";
case SectionType::ERROR:
return ".ERROR";
}
assert(!"Oh no :c");
}
const char* RelocationEntry::GetRelocTypeName() const
{
switch (relocationType)
{
case RelocationType::R_MIPS_32:
return "R_MIPS_32";
case RelocationType::R_MIPS_26:
return "R_MIPS_26";
case RelocationType::R_MIPS_HI16:
return "R_MIPS_HI16";
case RelocationType::R_MIPS_LO16:
return "R_MIPS_LO16";
}
assert(!"Oh no :c");
}
ZOverlay::ZOverlay()
{
name = "";
entries = std::vector<RelocationEntry*>();
}
ZOverlay::ZOverlay(const std::string& nName) : ZOverlay()
{
name = nName;
}
ZOverlay::~ZOverlay()
{
for (auto entry : entries)
if (entry)
delete entry;
entries.clear();
}
static const std::unordered_set<std::string> sRelSections = {
".rel.text",
".rel.data",
".rel.rodata",
};
static const std::unordered_set<std::string> sSections = {
".text", ".data", ".symtab", ".rodata", ".rodata.str1.4", ".rodata.cst4", ".rodata.cst8",
};
ZOverlay* ZOverlay::FromBuild(fs::path buildPath, fs::path cfgFolderPath)
{
std::string cfgText = File::ReadAllText(cfgFolderPath / "overlay.cfg");
std::vector<std::string> cfgLines = StringHelper::Split(cfgText, "\n");
ZOverlay* ovl = new ZOverlay(StringHelper::Strip(cfgLines[0], "\r"));
ovl->cfgLines = cfgLines;
int32_t sectionOffs[5] = {0};
std::vector<RelocationEntry*> textRelocs;
std::vector<RelocationEntry*> dataRelocs;
std::vector<RelocationEntry*> rodataRelocs;
// get the elf files
std::vector<elfio*> readers;
for (size_t i = 1; i < cfgLines.size(); i++)
{
std::string elfPath =
(buildPath / (cfgLines[i].substr(0, cfgLines[i].size() - 2) + ".o")).string();
elfio* reader = new elfio();
if (!reader->load(elfPath))
{
// not all files were compiled
for (auto r : readers)
delete r;
readers.clear();
delete ovl;
return nullptr;
}
readers.push_back(reader);
}
for (size_t curReaderId = 0; curReaderId < readers.size(); curReaderId++)
{
auto& curReader = readers[curReaderId];
Elf_Half sec_num = curReader->sections.size();
for (int32_t i = 0; i < sec_num; i++)
{
section* pSec = curReader->sections[i];
if (pSec->get_type() != SHT_REL ||
sRelSections.find(pSec->get_name()) == sRelSections.end())
{
continue;
}
symbol_section_accessor currentSymbols(*curReader,
curReader->sections[(Elf_Half)pSec->get_link()]);
SectionType sectionType = GetSectionTypeFromStr(pSec->get_name());
if (sectionType == SectionType::ERROR)
{
HANDLE_WARNING(WarningType::Always, "one of the section types returned ERROR", "");
}
relocation_section_accessor relocs(*curReader, pSec);
for (Elf_Xword j = 0; j < relocs.get_entries_num(); j++)
{
Elf64_Addr offset = 0;
Elf_Word symbol = 0;
Elf_Word type = 0;
{
Elf_Sxword addend = 0;
relocs.get_entry(j, offset, symbol, type, addend);
}
std::string curSymName;
Elf_Half curSymShndx = SHN_UNDEF;
{
Elf64_Addr value;
Elf_Xword size;
unsigned char bind;
unsigned char type;
unsigned char other;
currentSymbols.get_symbol(symbol, curSymName, value, size, bind, type,
curSymShndx, other);
}
// check symbols outside the elf but within the overlay
if (curSymShndx == SHN_UNDEF)
{
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG)
{
printf("Symbol '%s' doesn't exist in current .o file (%s). Searching...\n",
curSymName.c_str(), cfgLines[curReaderId + 1].c_str());
}
for (size_t readerId = 0; readerId < readers.size(); readerId++)
{
auto& reader = readers[readerId];
if (curSymShndx != SHN_UNDEF)
break;
if (reader == curReader)
continue;
auto sectionData = reader->sections[(Elf_Half)pSec->get_link()];
curSymShndx =
ovl->FindSymbolInSection(curSymName, sectionData, *reader, readerId);
if (curSymShndx != SHN_UNDEF)
break;
if (Globals::Instance->gccCompat)
{
// Symbol wasn't found, try checking every section
Elf_Half sec_num = reader->sections.size();
for (int32_t otherSectionIdx = 0; otherSectionIdx < sec_num;
otherSectionIdx++)
{
if (curSymShndx != SHN_UNDEF)
{
break;
}
auto sectionDataIter = reader->sections[otherSectionIdx];
curSymShndx = ovl->FindSymbolInSection(curSymName, sectionDataIter,
*reader, readerId);
}
}
}
}
if (curSymShndx != SHN_UNDEF)
{
RelocationType typeConverted = (RelocationType)type;
offset += sectionOffs[static_cast<size_t>(sectionType)];
RelocationEntry* reloc =
new RelocationEntry(sectionType, typeConverted, offset);
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG)
{
printf(".word 0x%08X # %s %s 0x%04X\n", reloc->CalcRelocationWord(),
reloc->GetSectionName(), reloc->GetRelocTypeName(), reloc->offset);
}
// this is to keep the correct reloc entry order
if (sectionType == SectionType::Text)
textRelocs.push_back(reloc);
if (sectionType == SectionType::Data)
dataRelocs.push_back(reloc);
if (sectionType == SectionType::RoData)
rodataRelocs.push_back(reloc);
}
}
}
// increase section offsets
for (int32_t i = 0; i < sec_num; i++)
{
section* pSec = curReader->sections[i];
if (pSec->get_type() == SHT_PROGBITS &&
sSections.find(pSec->get_name()) != sSections.end())
{
SectionType sectionType = GetSectionTypeFromStr(pSec->get_name());
sectionOffs[static_cast<size_t>(sectionType)] += pSec->get_size();
}
}
}
ovl->entries.reserve(textRelocs.size() + dataRelocs.size() + rodataRelocs.size());
ovl->entries.insert(ovl->entries.end(), textRelocs.begin(), textRelocs.end());
ovl->entries.insert(ovl->entries.end(), dataRelocs.begin(), dataRelocs.end());
ovl->entries.insert(ovl->entries.end(), rodataRelocs.begin(), rodataRelocs.end());
for (auto r : readers)
delete r;
readers.clear();
return ovl;
}
std::string ZOverlay::GetSourceOutputCode([[maybe_unused]] const std::string& prefix)
{
std::string output;
output += ".section .ovl\n";
output += StringHelper::Sprintf("# %sOverlayInfo\n", name.c_str());
output += StringHelper::Sprintf(".word _%sSegmentTextSize\n", name.c_str());
output += StringHelper::Sprintf(".word _%sSegmentDataSize\n", name.c_str());
output += StringHelper::Sprintf(".word _%sSegmentRoDataSize\n", name.c_str());
output += StringHelper::Sprintf(".word _%sSegmentBssSize\n", name.c_str());
output += "\n";
output += StringHelper::Sprintf(".word %i # reloc_count\n", entries.size());
for (size_t i = 0; i < entries.size(); i++)
{
RelocationEntry* reloc = entries[i];
output += StringHelper::Sprintf(".word 0x%08X # %s %s 0x%04X\n",
reloc->CalcRelocationWord(), reloc->GetSectionName(),
reloc->GetRelocTypeName(), reloc->offset);
}
size_t offset = (entries.size() * 4) + 20;
while (offset % 16 != 12)
{
output += ".word 0\n";
offset += 4;
}
output += "\n";
output +=
StringHelper::Sprintf(".word 0x%08X # %sOverlayInfoOffset\n", offset + 4, name.c_str());
return output;
}
SectionType ZOverlay::GetSectionTypeFromStr(const std::string& sectionName)
{
if (sectionName == ".rel.text" || sectionName == ".text")
return SectionType::Text;
else if (sectionName == ".rel.data" || sectionName == ".data")
return SectionType::Data;
else if (sectionName == ".rel.rodata" || sectionName == ".rodata" ||
sectionName == ".rodata.str1.4" || sectionName == ".rodata.cst4")
return SectionType::RoData;
else if (sectionName == ".rel.bss" || sectionName == ".bss")
return SectionType::Bss;
return SectionType::ERROR;
}
ELFIO::Elf_Half ZOverlay::FindSymbolInSection(const std::string& curSymName,
ELFIO::section* sectionData, ELFIO::elfio& reader,
size_t readerId)
{
if (sectionData == nullptr)
return SHN_UNDEF;
auto sectionDataName = sectionData->get_name();
if (sSections.find(sectionDataName) == sSections.end())
return SHN_UNDEF;
#ifdef DEVELOPMENT
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG)
{
printf("\t File '%s' section: %s \n", cfgLines[readerId + 1].c_str(),
sectionDataName.c_str());
}
#endif
symbol_section_accessor symbols(reader, sectionData);
Elf_Xword symbolNum = symbols.get_symbols_num();
for (Elf_Xword symIdx = 0; symIdx < symbolNum; symIdx++)
{
Elf_Half shndx = SHN_UNDEF;
Elf64_Addr value;
std::string name;
Elf_Xword size;
unsigned char bind;
unsigned char type;
unsigned char other;
symbols.get_symbol(symIdx, name, value, size, bind, type, shndx, other);
if (name == curSymName)
{
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG)
{
printf("\t Symbol '%s' found in '%s' '%s' \n", curSymName.c_str(),
cfgLines[readerId + 1].c_str(), sectionDataName.c_str());
}
return shndx;
}
}
return SHN_UNDEF;
}
-75
View File
@@ -1,75 +0,0 @@
#pragma once
#include "Utils/Directory.h"
#include "ZResource.h"
#include "elfio/elfio.hpp"
#include "tinyxml2.h"
enum class SectionType
{
Text = 1,
Data = 2,
RoData = 3,
Bss = 4,
ERROR = 255
};
enum class RelocationType
{
R_MIPS_32 = 2,
R_MIPS_26 = 4,
R_MIPS_HI16 = 5,
R_MIPS_LO16 = 6,
};
class RelocationEntry
{
public:
SectionType sectionType;
RelocationType relocationType;
int32_t offset;
RelocationEntry(SectionType nSecType, RelocationType nRelType, int32_t nOffset)
{
sectionType = nSecType;
relocationType = nRelType;
offset = nOffset;
}
uint32_t CalcRelocationWord()
{
uint32_t relocationWord = 0;
relocationWord |= static_cast<uint32_t>(sectionType) << 30;
relocationWord |= static_cast<uint32_t>(relocationType) << 24;
relocationWord |= offset;
return relocationWord;
}
const char* GetSectionName() const;
const char* GetRelocTypeName() const;
};
class ZOverlay
{
public:
std::string name;
ZOverlay(const std::string& nName);
~ZOverlay();
static ZOverlay* FromBuild(fs::path buildPath, fs::path cfgFolderPath);
std::string GetSourceOutputCode(const std::string& prefix);
private:
std::vector<RelocationEntry*> entries;
std::vector<std::string> cfgLines;
ZOverlay();
static SectionType GetSectionTypeFromStr(const std::string& sectionName);
// static std::string GetOverlayNameFromElf(ELFIO::elfio& reader);
ELFIO::Elf_Half FindSymbolInSection(const std::string& curSymName, ELFIO::section* sectionData,
ELFIO::elfio& reader, size_t readerId);
};

Some files were not shown because too many files have changed in this diff Show More