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

git subrepo pull --force tools/ZAPD (#1049)

subrepo:
  subdir:   "tools/ZAPD"
  merged:   "a3363333d"
upstream:
  origin:   "https://github.com/zeldaret/ZAPD.git"
  branch:   "master"
  commit:   "a3363333d"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo.git"
  commit:   "2f68596"
This commit is contained in:
fig02 2021-12-03 15:57:05 -05:00 committed by GitHub
parent 5e9d24fca4
commit 68899c2e33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
72 changed files with 1311 additions and 569 deletions

View file

@ -92,20 +92,20 @@ std::string Declaration::GetNormalDeclarationStr() const
if (isArray)
{
if (arrayItemCntStr != "")
if (arrayItemCntStr != "" && (IsStatic() || forceArrayCnt))
{
output += StringHelper::Sprintf("%s %s[%s];\n", varType.c_str(), varName.c_str(),
arrayItemCntStr.c_str());
}
else if (arrayItemCnt == 0)
{
output += StringHelper::Sprintf("%s %s[] = {\n", varType.c_str(), varName.c_str());
}
else
else if (arrayItemCnt != 0 && (IsStatic() || forceArrayCnt))
{
output += StringHelper::Sprintf("%s %s[%i] = {\n", varType.c_str(), varName.c_str(),
arrayItemCnt);
}
else
{
output += StringHelper::Sprintf("%s %s[] = {\n", varType.c_str(), varName.c_str());
}
output += text + "\n";
}
@ -145,16 +145,16 @@ std::string Declaration::GetExternalDeclarationStr() const
output += "static ";
}
if (arrayItemCntStr != "")
if (arrayItemCntStr != "" && (IsStatic() || forceArrayCnt))
output += StringHelper::Sprintf("%s %s[%s] = ", varType.c_str(), varName.c_str(),
arrayItemCntStr.c_str());
else if (arrayItemCnt != 0 && (IsStatic() || forceArrayCnt))
output +=
StringHelper::Sprintf("%s %s[%s] = {\n#include \"%s\"\n};", varType.c_str(),
varName.c_str(), arrayItemCntStr.c_str(), includePath.c_str());
else if (arrayItemCnt != 0)
output += StringHelper::Sprintf("%s %s[%i] = {\n#include \"%s\"\n};", varType.c_str(),
varName.c_str(), arrayItemCnt, includePath.c_str());
StringHelper::Sprintf("%s %s[%i] = ", varType.c_str(), varName.c_str(), arrayItemCnt);
else
output += StringHelper::Sprintf("%s %s[] = {\n#include \"%s\"\n};", varType.c_str(),
varName.c_str(), includePath.c_str());
output += StringHelper::Sprintf("%s %s[] = ", varType.c_str(), varName.c_str());
output += StringHelper::Sprintf("{\n#include \"%s\"\n};", includePath.c_str());
if (rightText != "")
output += " " + rightText + "";
@ -178,14 +178,16 @@ std::string Declaration::GetExternStr() const
if (isArray)
{
if (arrayItemCntStr != "")
if (arrayItemCntStr != "" && (IsStatic() || forceArrayCnt))
{
return StringHelper::Sprintf("extern %s %s[%s];\n", varType.c_str(), varName.c_str(),
arrayItemCntStr.c_str());
}
else if (arrayItemCnt != 0)
else if (arrayItemCnt != 0 && (IsStatic() || forceArrayCnt))
{
return StringHelper::Sprintf("extern %s %s[%i];\n", varType.c_str(), varName.c_str(),
arrayItemCnt);
}
else
return StringHelper::Sprintf("extern %s %s[];\n", varType.c_str(), varName.c_str());
}

View file

@ -38,10 +38,12 @@ public:
std::string varType;
std::string varName;
std::string includePath;
bool isExternal = false;
bool isArray = false;
bool forceArrayCnt = false;
size_t arrayItemCnt = 0;
std::string arrayItemCntStr;
std::string arrayItemCntStr = "";
std::vector<segptr_t> references;
bool isUnaccounted = false;
bool isPlaceholder = false;

View file

@ -25,7 +25,7 @@ GameConfig::~GameConfig()
void GameConfig::ReadTexturePool(const fs::path& texturePoolXmlPath)
{
tinyxml2::XMLDocument doc;
tinyxml2::XMLError eResult = doc.LoadFile(texturePoolXmlPath.c_str());
tinyxml2::XMLError eResult = doc.LoadFile(texturePoolXmlPath.string().c_str());
if (eResult != tinyxml2::XML_SUCCESS)
{
@ -155,7 +155,7 @@ void GameConfig::ReadConfigFile(const fs::path& argConfigFilePath)
{"ExternalFile", &GameConfig::ConfigFunc_ExternalFile},
};
configFilePath = argConfigFilePath;
configFilePath = argConfigFilePath.string();
tinyxml2::XMLDocument doc;
tinyxml2::XMLError eResult = doc.LoadFile(configFilePath.c_str());

View file

@ -3,8 +3,9 @@
#include <algorithm>
#include <string_view>
#include <Utils/File.h>
#include <Utils/Path.h>
#include "Utils/File.h"
#include "Utils/Path.h"
#include "WarningHandler.h"
#include "tinyxml2.h"
Globals* Globals::Instance;

View file

@ -20,6 +20,7 @@ typedef bool (*ExporterSetFuncBool)(ZFileMode fileMode);
typedef void (*ExporterSetFuncVoid)(int argc, char* argv[], int& i);
typedef void (*ExporterSetFuncVoid2)(const std::string& buildMode, ZFileMode& fileMode);
typedef void (*ExporterSetFuncVoid3)();
typedef void (*ExporterSetResSave)(ZResource* res, BinaryWriter& writer);
class ExporterSet
{
@ -34,6 +35,7 @@ public:
ExporterSetFunc endFileFunc = nullptr;
ExporterSetFuncVoid3 beginXMLFunc = nullptr;
ExporterSetFuncVoid3 endXMLFunc = nullptr;
ExporterSetResSave resSaveFunc = nullptr;
};
class Globals
@ -53,9 +55,6 @@ public:
TextureType texType;
ZGame game;
GameConfig cfg;
bool warnUnaccounted = false;
bool warnNoOffset = false;
bool errorNoOffset = false;
bool verboseUnaccounted = false;
bool gccCompat = false;
bool forceStatic = false;

View file

@ -6,6 +6,7 @@
#include <stdexcept>
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
/* ImageBackend */
@ -20,19 +21,28 @@ void ImageBackend::ReadPng(const char* filename)
FILE* fp = fopen(filename, "rb");
if (fp == nullptr)
throw std::runtime_error(StringHelper::Sprintf(
"ImageBackend::ReadPng: Error.\n\t Couldn't open file '%s'.", filename));
{
std::string errorHeader = StringHelper::Sprintf("could not open file '%s'", filename);
HANDLE_ERROR(WarningType::InvalidPNG, errorHeader, "");
}
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
if (!png)
throw std::runtime_error("ImageBackend::ReadPng: Error.\n\t Couldn't create png struct.");
if (png == nullptr)
{
HANDLE_ERROR(WarningType::InvalidPNG, "could not create png struct", "");
}
png_infop info = png_create_info_struct(png);
if (!info)
throw std::runtime_error("ImageBackend::ReadPng: Error.\n\t Couldn't create png info.");
if (info == nullptr)
{
HANDLE_ERROR(WarningType::InvalidPNG, "could not create png info", "");
}
if (setjmp(png_jmpbuf(png)))
throw std::runtime_error("ImageBackend::ReadPng: Error.\n\t setjmp(png_jmpbuf(png)).");
{
// TODO: better warning explanation
HANDLE_ERROR(WarningType::InvalidPNG, "setjmp(png_jmpbuf(png))", "");
}
png_init_io(png, fp);
@ -145,20 +155,30 @@ void ImageBackend::WritePng(const char* filename)
assert(hasImageData);
FILE* fp = fopen(filename, "wb");
if (!fp)
throw std::runtime_error(StringHelper::Sprintf(
"ImageBackend::WritePng: Error.\n\t Couldn't open file '%s' in write mode.", filename));
if (fp == nullptr)
{
std::string errorHeader =
StringHelper::Sprintf("could not open file '%s' in write mode", filename);
HANDLE_ERROR(WarningType::InvalidPNG, errorHeader, "");
}
png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
if (!png)
throw std::runtime_error("ImageBackend::WritePng: Error.\n\t Couldn't create png struct.");
if (png == nullptr)
{
HANDLE_ERROR(WarningType::InvalidPNG, "could not create png struct", "");
}
png_infop info = png_create_info_struct(png);
if (!info)
throw std::runtime_error("ImageBackend::WritePng: Error.\n\t Couldn't create png info.");
if (info == nullptr)
{
HANDLE_ERROR(WarningType::InvalidPNG, "could not create png info", "");
}
if (setjmp(png_jmpbuf(png)))
throw std::runtime_error("ImageBackend::WritePng: Error.\n\t setjmp(png_jmpbuf(png)).");
{
// TODO: better warning description
HANDLE_ERROR(WarningType::InvalidPNG, "setjmp(png_jmpbuf(png))", "");
}
png_init_io(png, fp);
@ -441,7 +461,7 @@ double ImageBackend::GetBytesPerPixel() const
return 1 * bitDepth / 8;
default:
throw std::invalid_argument("ImageBackend::GetBytesPerPixel():\n\t Invalid color type.");
HANDLE_ERROR(WarningType::InvalidPNG, "invalid color type", "");
}
}

View file

@ -1,8 +1,9 @@
#include <Utils/Directory.h>
#include <Utils/File.h>
#include <Utils/Path.h>
#include "Globals.h"
#include "Overlays/ZOverlay.h"
#include "Utils/Directory.h"
#include "Utils/File.h"
#include "Utils/Path.h"
#include "WarningHandler.h"
#include "ZAnimation.h"
#include "ZBackground.h"
#include "ZBlob.h"
@ -12,10 +13,10 @@
#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 <time.h>
#include <unistd.h>
#endif
@ -47,6 +48,7 @@ void ErrorHandler(int sig)
const char* crashEasterEgg[] = {
"\tYou've met with a terrible fate, haven't you?",
"\tSEA BEARS FOAM. SLEEP BEARS DREAMS. \n\tBOTH END IN THE SAME WAY: CRASSSH!",
"ZAPD has fallen and cannot get up."
};
srand(time(nullptr));
@ -97,6 +99,9 @@ int main(int argc, char* argv[])
return 1;
}
Globals* g = new Globals();
WarningHandler::Init(argc, argv);
for (int i = 1; i < argc; i++)
{
if (!strcmp(argv[i], "--version"))
@ -109,12 +114,12 @@ int main(int argc, char* argv[])
printf("Congratulations!\n");
printf("You just found the (unimplemented and undocumented) ZAPD's help message.\n");
printf("Feel free to implement it if you want :D\n");
WarningHandler::PrintHelp();
return 0;
}
}
Globals* g = new Globals;
// Parse other "commands"
for (int32_t i = 2; i < argc; i++)
{
@ -186,26 +191,15 @@ int main(int argc, char* argv[])
signal(SIGSEGV, ErrorHandler);
signal(SIGABRT, ErrorHandler);
#else
fprintf(stderr,
"Warning: Tried to set error handler, but this build lacks support for one.\n");
HANDLE_WARNING(WarningType::Always,
"tried to set error handler, but this ZAPD build lacks support for one",
"");
#endif
}
else if (arg == "-v") // Verbose
{
Globals::Instance->verbosity = static_cast<VerbosityLevel>(strtol(argv[++i], NULL, 16));
}
else if (arg == "-wu" || arg == "--warn-unaccounted") // Warn unaccounted
{
Globals::Instance->warnUnaccounted = true;
}
else if (arg == "-wno" || arg == "--warn-no-offset")
{
Globals::Instance->warnNoOffset = true;
}
else if (arg == "-eno" || arg == "--error-no-offset")
{
Globals::Instance->errorNoOffset = true;
}
else if (arg == "-vu" || arg == "--verbose-unaccounted") // Verbose unaccounted
{
Globals::Instance->verboseUnaccounted = true;
@ -262,6 +256,11 @@ int main(int argc, char* argv[])
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO)
printf("ZAPD: Zelda Asset Processor For Decomp: %s\n", gBuildHash);
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG)
{
WarningHandler::PrintWarningsDebugInfo();
}
// TODO: switch
if (fileMode == ZFileMode::Extract || fileMode == ZFileMode::BuildSourceFile)
{
@ -334,7 +333,9 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path
if (eResult != tinyxml2::XML_SUCCESS)
{
fprintf(stderr, "Invalid xml file: '%s'\n", xmlFilePath.c_str());
// TODO: use XMLDocument::ErrorIDToName to get more specific error messages here
HANDLE_ERROR(WarningType::InvalidXML,
StringHelper::Sprintf("invalid XML file: '%s'", xmlFilePath.c_str()), "");
return false;
}
@ -342,7 +343,9 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path
if (root == nullptr)
{
fprintf(stderr, "Missing Root tag in xml file: '%s'\n", xmlFilePath.c_str());
HANDLE_WARNING(
WarningType::InvalidXML,
StringHelper::Sprintf("missing Root tag in xml file: '%s'", xmlFilePath.c_str()), "");
return false;
}
@ -392,10 +395,11 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path
}
else
{
throw std::runtime_error(StringHelper::Sprintf(
"Parse: Fatal error in '%s'.\n\t A resource was found outside of "
"a File element: '%s'\n",
xmlFilePath.c_str(), child->Name()));
std::string errorHeader =
StringHelper::Sprintf("when parsing file '%s'", xmlFilePath.c_str());
std::string errorBody = StringHelper::Sprintf(
"Found a resource outside a File element: '%s'", child->Name());
HANDLE_ERROR(WarningType::InvalidXML, errorHeader, errorBody);
}
}

View file

View file

@ -1,13 +1,13 @@
#include "ZOverlay.h"
#include <assert.h>
#include <cassert>
#include <unordered_set>
#include <Utils/Directory.h>
#include <Utils/File.h>
#include <Utils/Path.h>
#include <Utils/StringHelper.h>
#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;
@ -90,7 +90,7 @@ ZOverlay* ZOverlay::FromBuild(fs::path buildPath, fs::path cfgFolderPath)
std::vector<elfio*> readers;
for (size_t i = 1; i < cfgLines.size(); i++)
{
std::string elfPath = buildPath / (cfgLines[i].substr(0, cfgLines[i].size() - 2) + ".o");
std::string elfPath = (buildPath / (cfgLines[i].substr(0, cfgLines[i].size() - 2) + ".o")).string();
elfio* reader = new elfio();
if (!reader->load(elfPath))
@ -128,7 +128,9 @@ ZOverlay* ZOverlay::FromBuild(fs::path buildPath, fs::path cfgFolderPath)
SectionType sectionType = GetSectionTypeFromStr(pSec->get_name());
if (sectionType == SectionType::ERROR)
fprintf(stderr, "WARNING: One of the section types returned ERROR\n");
{
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++)

View file

@ -0,0 +1,443 @@
/**
* ZAPD Warning- and Error-handling system
* =======================================
*
* This provides a common standard way to write ZAPD warnings/errors, which should be used for all
* such. It will pretty-print them in a uniform way, with styles defined in the header.
*
* Warnings/errors should be constructed using the macros given in the header; there are now plenty
* of examples in the codebase of how to do this. Their purposes are noted above each category in
* the header. Each warning has a type, one of the ones in warningStringToInitMap, or
* WarningType::Always, which is used for warnings that cannot be disabled and do not display a
* type.
*
* Currently there are three levels of alert a warning can have:
* - Off (does not display anything)
* - Warn (print a warning but continue processing)
* - Err (behave like an error, i.e. print and throw an exception to crash ZAPD when occurs)
*
* Flag use:
* - -Wfoo enables warnings of type foo
* - -Wno-foo disables warnings of type foo
* - -Werror=foo escalates foo to behave like an error
* - -Weverything enables all warnings
* - -Werror escalates all enabled warnings to errors
*
* Errors do not have types, and will always throw an exception; they cannot be disabled.
*
* Format
* ===
* Each printed warning/error contains the same three sections:
* - Preamble: automatically generated; the content varies depending on category. It will print the
* file and function that the warning is from, and information about the files being processed
* or extracted.
* - Header: begins with 'warning: ' or 'error:', should contain essential information about the
* warning/error, ends with the warning type if applicable. Printed with emphasis to make it
* stand out. Does not start with a capital letter or end with a '.'
* - Body (optional): indented, should contain further diagnostic information useful for identifying
* and fixing the warning/error. Can be a sentence with captialisation and '.' on the end.
*
* Please think of what the end user will find most useful when writing the header and body, and try
* to keep it brief without sacrificing important information! Also remember that if the user is
* only looking at stderr, they will normally have no other context.
*
* Warning vs error
* ===
* The principle that we have operated on so far is
* - issue a warning if ZAPD will still be able to produce a valid, compilable C file that will
* match
* - if this cannot happen, use an error.
* but at the end of the day, it is up to the programmer's discretion what it should be possible to
* disable.
*
* Documentation
* ===
* Remember that all warnings also need to be documented in the README.md. The help is generated
* automatically.
*/
#include "WarningHandler.h"
#include <cassert>
#include "Globals.h"
#include "Utils/StringHelper.h"
typedef struct
{
WarningType type;
WarningLevel defaultLevel;
std::string description;
} WarningInfoInit;
typedef struct
{
WarningLevel level;
std::string name;
std::string description;
} WarningInfo;
/**
* Master list of all default warning types and features
*
* To add a warning type, fill in a new row of this map. Think carefully about what its default
* level should be, and try and make the description both brief and informative: it is used in the
* help message, so again, think about what the end user needs to know.
*/
// clang-format off
static const std::unordered_map<std::string, WarningInfoInit> warningStringToInitMap = {
{"deprecated", {WarningType::Deprecated,
#ifdef DEPRECATION_ON
WarningLevel::Warn,
#else
WarningLevel::Off,
#endif
"Deprecated features"}},
{"unaccounted", {WarningType::Unaccounted, WarningLevel::Off, "Large blocks of unaccounted"}},
{"missing-offsets", {WarningType::MissingOffsets, WarningLevel::Warn, "Offset attribute missing in XML tag"}},
{"intersection", {WarningType::Intersection, WarningLevel::Warn, "Two assets intersect"}},
{"missing-attribute", {WarningType::MissingAttribute, WarningLevel::Warn, "Required attribute missing in XML tag"}},
{"invalid-attribute-value", {WarningType::InvalidAttributeValue, WarningLevel::Err, "Attribute declared in XML is wrong"}},
{"unknown-attribute", {WarningType::UnknownAttribute, WarningLevel::Warn, "Unknown attribute in XML entry tag"}},
{"invalid-xml", {WarningType::InvalidXML, WarningLevel::Err, "XML has syntax errors"}},
{"invalid-jpeg", {WarningType::InvalidJPEG, WarningLevel::Err, "JPEG file does not conform to the game's format requirements"}},
{"invalid-png", {WarningType::InvalidPNG, WarningLevel::Err, "Issues arising when processing PNG data"}},
{"invalid-extracted-data", {WarningType::InvalidExtractedData, WarningLevel::Err, "Extracted data does not have correct form"}},
{"missing-segment", {WarningType::MissingSegment, WarningLevel::Warn, "Segment not given in File tag in XML"}},
{"hardcoded-pointer", {WarningType::HardcodedPointer, WarningLevel::Warn, "ZAPD lacks the info to make a symbol, so must output a hardcoded pointer"}},
{"not-implemented", {WarningType::NotImplemented, WarningLevel::Warn, "ZAPD does not currently support this feature"}},
};
/**
* Map constructed at runtime to contain the warning features as set by the user using -W flags.
*/
static std::unordered_map<WarningType, WarningInfo> warningTypeToInfoMap;
void WarningHandler::ConstructTypeToInfoMap() {
for (auto& entry : warningStringToInitMap) {
warningTypeToInfoMap[entry.second.type] = {entry.second.defaultLevel, entry.first, entry.second.description};
}
warningTypeToInfoMap[WarningType::Always] = {WarningLevel::Warn, "always", "you shouldn't be reading this"};
assert(warningTypeToInfoMap.size() == static_cast<size_t>(WarningType::Max));
}
/**
* Initialises the main warning type map and reads flags passed to set each warning type's level.
*/
void WarningHandler::Init(int argc, char* argv[]) {
ConstructTypeToInfoMap();
bool werror = false;
for (int i = 1; i < argc; i++) {
// If it doesn't start with "-W" skip it.
if (argv[i][0] != '-' || argv[i][1] != 'W' || argv[i][2] == '\0') {
continue;
}
WarningLevel warningTypeOn = WarningLevel::Warn;
size_t startingIndex = 2;
// "-Wno-"
if (argv[i][2] == 'n' && argv[i][3] == 'o' && argv[i][4] == '-' && argv[i][5] != '\0') {
warningTypeOn = WarningLevel::Off;
startingIndex = 5;
}
// Read starting after the "-W" or "-Wno-"
std::string_view currentArgv = &argv[i][startingIndex];
if (currentArgv == "error") {
werror = warningTypeOn != WarningLevel::Off;
} else if (currentArgv == "everything") {
for (auto& it: warningTypeToInfoMap) {
if (it.second.level <= WarningLevel::Warn) {
it.second.level = warningTypeOn;
}
}
} else {
// "-Werror=" / "-Wno-error=" parser
if (currentArgv.rfind("error=", 0) == 0) {
// Read starting after the "error=" part
currentArgv = &argv[i][startingIndex + 6];
warningTypeOn = warningTypeOn != WarningLevel::Off ? WarningLevel::Err : WarningLevel::Warn;
}
auto it = warningStringToInitMap.find(std::string(currentArgv));
if (it != warningStringToInitMap.end()) {
warningTypeToInfoMap[it->second.type].level = warningTypeOn;
}
else {
HANDLE_WARNING(WarningType::Always, StringHelper::Sprintf("unknown warning flag '%s'", argv[i]), "");
}
}
}
if (werror) {
for (auto& it: warningTypeToInfoMap) {
if (it.second.level >= WarningLevel::Warn) {
it.second.level = WarningLevel::Err;
}
}
}
}
bool WarningHandler::IsWarningEnabled(WarningType warnType) {
assert(static_cast<size_t>(warnType) >= 0 && warnType < WarningType::Max);
return warningTypeToInfoMap.at(warnType).level != WarningLevel::Off;
}
bool WarningHandler::WasElevatedToError(WarningType warnType) {
assert(static_cast<size_t>(warnType) >= 0 && warnType < WarningType::Max);
if (!IsWarningEnabled(warnType)) {
return false;
}
return warningTypeToInfoMap.at(warnType).level >= WarningLevel::Err;
}
/**
* Print file/line/function info for debugging
*/
void WarningHandler::FunctionPreamble(const char* filename, int32_t line, const char* function) {
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG) {
fprintf(stderr, "%s:%i: in function %s:\n", filename, line, function);
}
}
/**
* Print the information about the file(s) being processed (XML for extraction, png etc. for building)
*/
void WarningHandler::ProcessedFilePreamble() {
if (Globals::Instance->inputPath != "") {
fprintf(stderr, "When processing file %s: ", Globals::Instance->inputPath.c_str());
}
}
/**
* Print information about the binary file being extracted
*/
void WarningHandler::ExtractedFilePreamble(const ZFile *parent, const ZResource* res, const uint32_t offset) {
fprintf(stderr, "in input binary file %s, ", parent->GetName().c_str());
if (res != nullptr) {
fprintf(stderr, "resource '%s' at ", res->GetName().c_str());
}
fprintf(stderr, "offset 0x%06X: \n\t", offset);
}
/**
* Construct the rest of the message, after warning:/error. The message is filled in one character at a time, with indents added after newlines
*/
std::string WarningHandler::ConstructMessage(std::string message, const std::string& header, const std::string& body) {
message.reserve(message.size() + header.size() + body.size() + 10 * (sizeof(HANG_INDT) - 1));
message += StringHelper::Sprintf(HILITE("%s"), header.c_str());
message += "\n";
if (body == "") {
return message;
}
message += HANG_INDT;
for (const char* ptr = body.c_str(); *ptr != '\0'; ptr++) {
message += *ptr;
if (*ptr == '\n') {
message += HANG_INDT;
}
}
message += "\n";
return message;
}
/* Error module functions */
void WarningHandler::PrintErrorAndThrow(const std::string& header, const std::string& body) {
std::string errorMsg = ERR_FMT("error: ");
throw std::runtime_error(ConstructMessage(errorMsg, header, body));
}
/* Error types, to be used via the macros */
void WarningHandler::ErrorType(WarningType warnType, const std::string& header, const std::string& body) {
std::string headerMsg = header;
for (const auto& iter: warningStringToInitMap) {
if (iter.second.type == warnType) {
headerMsg += StringHelper::Sprintf(" [%s]", iter.first.c_str());
}
}
PrintErrorAndThrow(headerMsg, body);
}
void WarningHandler::Error_Plain(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) {
FunctionPreamble(filename, line, function);
ErrorType(warnType, header, body);
}
void WarningHandler::Error_Process(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) {
FunctionPreamble(filename, line, function);
ProcessedFilePreamble();
ErrorType(warnType, header, body);
}
void WarningHandler::Error_Resource(const char* filename, int32_t line, const char* function, WarningType warnType, const ZFile *parent, const ZResource* res, const uint32_t offset, const std::string& header, const std::string& body) {
assert(parent != nullptr);
FunctionPreamble(filename, line, function);
ProcessedFilePreamble();
ExtractedFilePreamble(parent, res, offset);
ErrorType(warnType, header, body);
}
/* Warning module functions */
void WarningHandler::PrintWarningBody(const std::string& header, const std::string& body) {
std::string errorMsg = WARN_FMT("warning: ");
fprintf(stderr, "%s", ConstructMessage(errorMsg, header, body).c_str());
}
void WarningHandler::WarningTypeAndChooseEscalate(WarningType warnType, const std::string& header, const std::string& body) {
std::string headerMsg = header;
for (const auto& iter: warningStringToInitMap) {
if (iter.second.type == warnType) {
headerMsg += StringHelper::Sprintf(" [-W%s]", iter.first.c_str());
}
}
if (WasElevatedToError(warnType)) {
PrintErrorAndThrow(headerMsg, body);
} else {
PrintWarningBody(headerMsg, body);
}
}
/* Warning types, to be used via the macros */
void WarningHandler::Warning_Plain(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) {
if (!IsWarningEnabled(warnType)) {
return;
}
FunctionPreamble(filename, line, function);
WarningTypeAndChooseEscalate(warnType, header, body);
}
void WarningHandler::Warning_Process(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) {
if (!IsWarningEnabled(warnType)) {
return;
}
FunctionPreamble(filename, line, function);
ProcessedFilePreamble();
WarningTypeAndChooseEscalate(warnType, header, body);
}
void WarningHandler::Warning_Resource(const char* filename, int32_t line, const char* function, WarningType warnType, const ZFile *parent, const ZResource* res, const uint32_t offset, const std::string& header, const std::string& body) {
assert(parent != nullptr);
if (!IsWarningEnabled(warnType)) {
return;
}
FunctionPreamble(filename, line, function);
ProcessedFilePreamble();
ExtractedFilePreamble(parent, res, offset);
WarningTypeAndChooseEscalate(warnType, header, body);
}
/* Help-related functions */
#include <set>
/**
* Print each warning name, default status, and description using the init map
*/
void WarningHandler::PrintHelp() {
std::set<std::string> sortedKeys;
WarningInfoInit warningInfo;
uint32_t columnWidth = 25;
std::string dt;
// Sort keys through the magic of `set`, to print in alphabetical order
for (auto& it : warningStringToInitMap) {
sortedKeys.insert(it.first);
}
printf("\nWarning types ( * means enabled by default)\n");
for (auto& key : sortedKeys) {
warningInfo = warningStringToInitMap.at(key);
if (warningInfo.defaultLevel <= WarningLevel::Warn) {
dt = "-W";
dt += key;
if (warningInfo.defaultLevel == WarningLevel::Warn) {
dt += " *";
}
printf(HELP_DT_INDT "%-*s", columnWidth, dt.c_str());
if (dt.length() + 2 > columnWidth) {
printf("\n" HELP_DT_INDT "%-*s", columnWidth, "");
}
printf("%s\n", warningInfo.description.c_str());
}
}
printf("\nDefault errors\n");
for (auto& key : sortedKeys) {
if (warningInfo.defaultLevel > WarningLevel::Warn) {
dt = "-W";
dt += key;
printf(HELP_DT_INDT "%-*s", columnWidth, dt.c_str());
if (dt.length() + 2 > columnWidth) {
printf("\n" HELP_DT_INDT "%*s", columnWidth, "");
}
printf("%s\n", warningInfo.description.c_str());
}
}
printf("\n");
printf("Other\n" HELP_DT_INDT "-Weverything will enable all existing warnings.\n" HELP_DT_INDT "-Werror will promote all warnings to errors.\n");
printf("\n");
printf("Warnings can be disabled using -Wno-... instead of -W...; -Weverything will override any -Wno-... flags passed before it.\n");
}
/**
* Print which warnings are currently enabled
*/
void WarningHandler::PrintWarningsDebugInfo()
{
std::string dt;
printf("Warnings status:\n");
for (auto& it: warningTypeToInfoMap) {
dt = it.second.name;
dt += ": ";
printf(HELP_DT_INDT "%-25s", dt.c_str());
switch (it.second.level)
{
case WarningLevel::Off:
printf(VT_FGCOL(LIGHTGRAY) "Off" VT_RST);
break;
case WarningLevel::Warn:
printf(VT_FGCOL(YELLOW) "Warn" VT_RST);
break;
case WarningLevel::Err:
printf(VT_FGCOL(RED) "Err" VT_RST);
break;
}
printf("\n");
}
printf("\n");
}

View file

@ -0,0 +1,145 @@
#pragma once
#include <array>
#include <string>
#include <string_view>
#include <unordered_map>
#include "Utils/vt.h"
#include "ZFile.h"
#ifdef _MSC_VER
#define __PRETTY_FUNCTION__ __FUNCSIG__
#elif not defined(__GNUC__)
#define __PRETTY_FUNCTION__ __func__
#endif
// =======================================
/* Formatting macros */
// TODO: move this somewhere else so it can be used by other help
#define HELP_DT_INDT " "
/* Macros for formatting warnings/errors */
#define VT_HILITE VT_BOLD_FGCOL(WHITE)
#define VT_WARN VT_BOLD_FGCOL(PURPLE)
#define VT_ERR VT_BOLD_FGCOL(RED)
#define HILITE(string) (VT_HILITE string VT_RST)
#define WARN_FMT(string) (VT_WARN string VT_RST)
#define ERR_FMT(string) (VT_ERR string VT_RST)
// Maybe make WARN_LF instead
// Currently 8 spaces
#define WARN_INDT " "
// Currently 16 spaces
#define HANG_INDT " "
// =======================================
/* Warning and error macros */
// TODO: better names
// General-purpose, plain style (only prints function,file,line in the preamble)
#define HANDLE_ERROR(warningType, header, body) \
WarningHandler::Error_Plain(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, body)
#define HANDLE_WARNING(warningType, header, body) \
WarningHandler::Warning_Plain(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, \
body)
// For processing XMLs or textures/blobs (preamble contains function,file,line; processed file)
#define HANDLE_ERROR_PROCESS(warningType, header, body) \
WarningHandler::Error_Process(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, \
body)
#define HANDLE_WARNING_PROCESS(warningType, header, body) \
WarningHandler::Warning_Process(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, \
body)
// For ZResource-related stuff (preamble contains function,file,line; processed file; extracted file
// and offset)
#define HANDLE_ERROR_RESOURCE(warningType, parent, resource, offset, header, body) \
WarningHandler::Error_Resource(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, parent, \
resource, offset, header, body)
#define HANDLE_WARNING_RESOURCE(warningType, parent, resource, offset, header, body) \
WarningHandler::Warning_Resource(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, parent, \
resource, offset, header, body)
// =======================================
enum class WarningType
{
Always, // Warnings of this type are always printed, cannot be disabled.
Deprecated,
Unaccounted,
MissingOffsets,
Intersection,
MissingAttribute,
InvalidAttributeValue,
UnknownAttribute,
InvalidXML,
InvalidJPEG,
InvalidPNG,
InvalidExtractedData,
MissingSegment,
HardcodedPointer,
NotImplemented,
Max,
};
enum class WarningLevel
{
Off,
Warn,
Err,
};
class WarningHandler
{
public:
static void ConstructTypeToInfoMap();
static void Init(int argc, char* argv[]);
static bool IsWarningEnabled(WarningType warnType);
static bool WasElevatedToError(WarningType warnType);
static void FunctionPreamble(const char* filename, int32_t line, const char* function);
static void ProcessedFilePreamble();
static void ExtractedFilePreamble(const ZFile* parent, const ZResource* res,
const uint32_t offset);
static std::string ConstructMessage(std::string message, const std::string& header,
const std::string& body);
[[noreturn]] static void PrintErrorAndThrow(const std::string& header, const std::string& body);
static void PrintWarningBody(const std::string& header, const std::string& body);
[[noreturn]] static void ErrorType(WarningType warnType, const std::string& header,
const std::string& body);
[[noreturn]] static void Error_Plain(const char* filename, int32_t line, const char* function,
WarningType warnType, const std::string& header,
const std::string& body);
[[noreturn]] static void Error_Process(const char* filename, int32_t line, const char* function,
WarningType warnType, const std::string& header,
const std::string& body);
[[noreturn]] static void Error_Resource(const char* filename, int32_t line,
const char* function, WarningType warnType,
const ZFile* parent, const ZResource* res,
const uint32_t offset, const std::string& header,
const std::string& body);
static void WarningTypeAndChooseEscalate(WarningType warnType, const std::string& header,
const std::string& body);
static void Warning_Plain(const char* filename, int32_t line, const char* function,
WarningType warnType, const std::string& header,
const std::string& body);
static void Warning_Process(const char* filename, int32_t line, const char* function,
WarningType warnType, const std::string& header,
const std::string& body);
static void Warning_Resource(const char* filename, int32_t line, const char* function,
WarningType warnType, const ZFile* parent, const ZResource* res,
const uint32_t offset, const std::string& header,
const std::string& body);
static void PrintHelp();
static void PrintWarningsDebugInfo();
};

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.props" Condition="Exists('..\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@ -71,8 +72,8 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LibraryPath>$(SolutionDir)lib\libgfxd;$(SolutionDir)x64\Debug;$(SolutionDir)packages\libpng.1.6.28.1\build\native\lib\x64\v140\dynamic\Debug;$(LibraryPath)</LibraryPath>
<IncludePath>$(SolutionDir)ZAPDUtils;$(SolutionDir)lib\tinyxml2;$(SolutionDir)lib\libgfxd;$(SolutionDir)lib\elfio;$(SolutionDir)lib\stb;$(ProjectDir);$(IncludePath)</IncludePath>
<LibraryPath>$(OutDir);$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\packages\libpng-v142.1.6.37.2\build\native\lib\x64\v142\Debug\;$(LibraryPath)</LibraryPath>
<IncludePath>$(ProjectDir)..\ZAPDUtils;$(ProjectDir)..\lib\tinyxml2;$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\lib\elfio;$(ProjectDir)..\lib\stb;$(ProjectDir);$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>$(IncludePath)</IncludePath>
@ -105,13 +106,16 @@
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<LanguageStandard_C>stdc11</LanguageStandard_C>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<Profile>true</Profile>
<AdditionalDependencies>libpng16.lib;ZAPDUtils.lib;/WHOLEARCHIVE:ExporterExample.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ZAPDUtils.lib;/WHOLEARCHIVE:ExporterExample.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
</Link>
<PreBuildEvent>
<Command>cd ..
mkdir build\ZAPD
python3 ZAPD/genbuildinfo.py</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
@ -146,6 +150,7 @@ python3 ZAPD/genbuildinfo.py</Command>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\build\ZAPD\BuildInfo.cpp" />
<ClCompile Include="..\lib\libgfxd\gfxd.c" />
<ClCompile Include="..\lib\libgfxd\uc.c" />
<ClCompile Include="..\lib\libgfxd\uc_f3d.c" />
@ -153,19 +158,22 @@ python3 ZAPD/genbuildinfo.py</Command>
<ClCompile Include="..\lib\libgfxd\uc_f3dex.c" />
<ClCompile Include="..\lib\libgfxd\uc_f3dex2.c" />
<ClCompile Include="..\lib\libgfxd\uc_f3dexb.c" />
<ClCompile Include="..\lib\tinyxml2\tinyxml2.cpp" />
<ClCompile Include="Declaration.cpp" />
<ClCompile Include="GameConfig.cpp" />
<ClCompile Include="Globals.cpp" />
<ClCompile Include="ImageBackend.cpp" />
<ClCompile Include="Main.cpp" />
<ClCompile Include="OtherStructs\SkinLimbStructs.cpp" />
<ClCompile Include="OutputFormatter.cpp" />
<ClCompile Include="Overlays\ZOverlay.cpp" />
<ClCompile Include="WarningHandler.cpp" />
<ClCompile Include="ZArray.cpp" />
<ClCompile Include="ZBackground.cpp" />
<ClCompile Include="ZCutsceneMM.cpp" />
<ClCompile Include="ZLimb.cpp" />
<ClCompile Include="ZMtx.cpp" />
<ClCompile Include="ZPath.cpp" />
<ClCompile Include="ZPlayerAnimationData.cpp" />
<ClCompile Include="ZRoom\Commands\SetActorCutsceneList.cpp" />
<ClCompile Include="ZRoom\Commands\SetAnimatedMaterialList.cpp" />
<ClCompile Include="ZRoom\Commands\SetCsCamera.cpp" />
@ -213,6 +221,7 @@ python3 ZAPD/genbuildinfo.py</Command>
<ClCompile Include="ZString.cpp" />
<ClCompile Include="ZSymbol.cpp" />
<ClCompile Include="ZTexture.cpp" />
<ClCompile Include="ZTextureAnimation.cpp" />
<ClCompile Include="ZVector.cpp" />
<ClCompile Include="ZVtx.cpp" />
</ItemGroup>
@ -237,10 +246,13 @@ python3 ZAPD/genbuildinfo.py</Command>
<ClInclude Include="..\lib\stb\tinyxml2.h" />
<ClInclude Include="CRC32.h" />
<ClInclude Include="Declaration.h" />
<ClInclude Include="GameConfig.h" />
<ClInclude Include="Globals.h" />
<ClInclude Include="ImageBackend.h" />
<ClInclude Include="OtherStructs\SkinLimbStructs.h" />
<ClInclude Include="OutputFormatter.h" />
<ClInclude Include="Overlays\ZOverlay.h" />
<ClInclude Include="WarningHandler.h" />
<ClInclude Include="ZAnimation.h" />
<ClInclude Include="ZArray.h" />
<ClInclude Include="ZBackground.h" />
@ -253,6 +265,7 @@ python3 ZAPD/genbuildinfo.py</Command>
<ClInclude Include="ZLimb.h" />
<ClInclude Include="ZMtx.h" />
<ClInclude Include="ZPath.h" />
<ClInclude Include="ZPlayerAnimationData.h" />
<ClInclude Include="ZRoom\Commands\SetActorCutsceneList.h" />
<ClInclude Include="ZRoom\Commands\SetAnimatedMaterialList.h" />
<ClInclude Include="ZRoom\Commands\SetCsCamera.h" />
@ -294,6 +307,7 @@ python3 ZAPD/genbuildinfo.py</Command>
<ClInclude Include="ZString.h" />
<ClInclude Include="ZSymbol.h" />
<ClInclude Include="ZTexture.h" />
<ClInclude Include="ZTextureAnimation.h" />
<ClInclude Include="ZVector.h" />
<ClInclude Include="ZVtx.h" />
</ItemGroup>
@ -301,24 +315,29 @@ python3 ZAPD/genbuildinfo.py</Command>
<Text Include="..\SymbolMap_OoTMqDbg.txt">
<DeploymentContent>true</DeploymentContent>
</Text>
<Text Include="any\any\zlib.static.txt" />
<Text Include="NuGet\libpng.static.txt" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\libpng.redist.1.6.28.1\build\native\libpng.redist.targets" Condition="Exists('..\packages\libpng.redist.1.6.28.1\build\native\libpng.redist.targets')" />
<Import Project="..\packages\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" />
<Import Project="..\packages\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" />
<Import Project="..\packages\libpng.1.6.28.1\build\native\libpng.targets" Condition="Exists('..\packages\libpng.1.6.28.1\build\native\libpng.targets')" />
<Import Project="..\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.targets" Condition="Exists('..\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.targets')" />
<Import Project="..\packages\zlib.static.1.2.5\build\native\zlib.static.targets" Condition="Exists('..\packages\zlib.static.1.2.5\build\native\zlib.static.targets')" />
<Import Project="..\packages\libpng.static.1.6.37\build\native\libpng.static.targets" Condition="Exists('..\packages\libpng.static.1.6.37\build\native\libpng.static.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\libpng.redist.1.6.28.1\build\native\libpng.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\libpng.redist.1.6.28.1\build\native\libpng.redist.targets'))" />
<Error Condition="!Exists('..\packages\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
<Error Condition="!Exists('..\packages\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
<Error Condition="!Exists('..\packages\libpng.1.6.28.1\build\native\libpng.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\libpng.1.6.28.1\build\native\libpng.targets'))" />
<Error Condition="!Exists('..\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.props'))" />
<Error Condition="!Exists('..\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.targets'))" />
<Error Condition="!Exists('..\packages\zlib.static.1.2.5\build\native\zlib.static.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\zlib.static.1.2.5\build\native\zlib.static.targets'))" />
<Error Condition="!Exists('..\packages\libpng.static.1.6.37\build\native\libpng.static.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\libpng.static.1.6.37\build\native\libpng.static.targets'))" />
</Target>
</Project>

View file

@ -49,6 +49,15 @@
<Filter Include="Header Files\Libraries\libgfxd">
<UniqueIdentifier>{85600275-99fe-491d-8189-bcc3dc1a8903}</UniqueIdentifier>
</Filter>
<Filter Include="any">
<UniqueIdentifier>{ba9990b0-1082-48bb-874c-6108534b5455}</UniqueIdentifier>
</Filter>
<Filter Include="any\any">
<UniqueIdentifier>{ce9d91b0-ba20-4296-bc2d-8630965bb392}</UniqueIdentifier>
</Filter>
<Filter Include="NuGet">
<UniqueIdentifier>{730beb67-6d59-4849-9d9b-702c4a565fc0}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Main.cpp">
@ -135,9 +144,6 @@
<ClCompile Include="ZRoom\Commands\SetCutscenes.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="..\lib\tinyxml2\tinyxml2.cpp">
<Filter>Source Files\Libraries</Filter>
</ClCompile>
<ClCompile Include="ZAnimation.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
@ -258,6 +264,24 @@
<ClCompile Include="ZString.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="GameConfig.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZTextureAnimation.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="OtherStructs\SkinLimbStructs.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="..\build\ZAPD\BuildInfo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZPlayerAnimationData.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="WarningHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ZRoom\ZRoom.h">
@ -497,11 +521,32 @@
<ClInclude Include="ZString.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="GameConfig.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ZTextureAnimation.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="OtherStructs\SkinLimbStructs.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZPlayerAnimationData.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="WarningHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="..\SymbolMap_OoTMqDbg.txt">
<Filter>Resource Files</Filter>
</Text>
<Text Include="any\any\zlib.static.txt">
<Filter>any\any</Filter>
</Text>
<Text Include="NuGet\libpng.static.txt">
<Filter>NuGet</Filter>
</Text>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View file

@ -6,6 +6,7 @@
#include "Utils/BitConverter.h"
#include "Utils/File.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZFile.h"
REGISTER_ZFILENODE(Animation, ZNormalAnimation);
@ -218,11 +219,9 @@ void ZCurveAnimation::ParseXML(tinyxml2::XMLElement* reader)
std::string skelOffsetXml = registeredAttributes.at("SkelOffset").value;
if (skelOffsetXml == "")
{
throw std::runtime_error(
StringHelper::Sprintf("ZCurveAnimation::ParseXML: Fatal error in '%s'.\n"
"\t Missing 'SkelOffset' attribute in ZCurveAnimation.\n"
"\t You need to provide the offset of the curve skeleton.",
name.c_str()));
HANDLE_ERROR_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex,
"missing 'SkelOffset' attribute in <ZCurveAnimation>",
"You need to provide the offset of the curve skeleton.");
}
skelOffset = StringHelper::StrToL(skelOffsetXml, 0);
}

View file

@ -1,6 +1,6 @@
#pragma once
#include <stdint.h>
#include <cstdint>
#include <string>
#include <vector>
#include "Vec3s.h"

View file

@ -4,6 +4,7 @@
#include "Globals.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZFile.h"
REGISTER_ZFILENODE(Array, ZArray);
@ -25,13 +26,18 @@ void ZArray::ParseXML(tinyxml2::XMLElement* reader)
ZResource::ParseXML(reader);
arrayCnt = reader->IntAttribute("Count", 0);
// TODO: do a better check.
assert(arrayCnt > 0);
if (arrayCnt <= 0)
{
HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
"invalid value found for 'Count' attribute", "");
}
tinyxml2::XMLElement* child = reader->FirstChildElement();
if (child == nullptr)
throw std::runtime_error(
StringHelper::Sprintf("Error! Array needs at least one sub-element.\n"));
{
HANDLE_ERROR_RESOURCE(WarningType::InvalidXML, parent, this, rawDataIndex,
"<Array> needs one sub-element", "");
}
childName = child->Name();
@ -42,9 +48,10 @@ void ZArray::ParseXML(tinyxml2::XMLElement* reader)
ZResource* res = nodeMap->at(childName)(parent);
if (!res->DoesSupportArray())
{
throw std::runtime_error(StringHelper::Sprintf(
"Error! Resource %s does not support being wrapped in an array!\n",
childName.c_str()));
std::string errorHeader = StringHelper::Sprintf(
"resource <%s> does not support being wrapped in an <Array>", childName.c_str());
HANDLE_ERROR_RESOURCE(WarningType::InvalidXML, parent, this, rawDataIndex, errorHeader,
"");
}
res->parent = parent;
res->SetInnerNode(true);
@ -87,7 +94,7 @@ Declaration* ZArray::DeclareVar(const std::string& prefix, const std::string& bo
std::string ZArray::GetBodySourceCode() const
{
std::string output;
std::string output = "";
for (size_t i = 0; i < arrayCnt; i++)
{

View file

@ -1,6 +1,6 @@
#pragma once
#include <stdint.h>
#include <cstdint>
#include <string>
#include <vector>
#include "ZResource.h"

View file

@ -5,6 +5,7 @@
#include "Utils/File.h"
#include "Utils/Path.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZFile.h"
REGISTER_ZFILENODE(Background, ZBackground);
@ -63,52 +64,46 @@ void ZBackground::CheckValidJpeg(const std::string& filepath)
uint32_t jpegMarker = BitConverter::ToUInt32BE(data, 0);
if (jpegMarker != JPEG_MARKER)
{
fprintf(stderr,
"ZBackground::CheckValidJpeg: Warning.\n"
"\t Missing jpeg marker at the beginning of file: '%s'.\n"
"\t The game will skip this jpeg.\n",
filename.c_str());
HANDLE_WARNING_PROCESS(
WarningType::InvalidJPEG,
StringHelper::Sprintf("missing jpeg marker at beginning of file: '%s'",
filename.c_str()),
"The game will skip this jpeg.");
}
if (data.at(6) != 'J' || data.at(7) != 'F' || data.at(8) != 'I' || data.at(9) != 'F' ||
data.at(10) != '\0')
{
std::string jfifIdentifier(data.begin() + 6, data.begin() + 6 + 5);
fprintf(stderr,
"ZBackground::CheckValidJpeg: Warning.\n"
"\t Missing 'JFIF' identifier. File: '%s'.\n"
"\t This image may be corrupted or not be a jpeg iamge.\n"
"\t The identifier found was '%s'.\n",
filename.c_str(), jfifIdentifier.c_str());
HANDLE_WARNING_PROCESS(
WarningType::InvalidJPEG, "missing 'JFIF' identifier",
StringHelper::Sprintf(
"This image may be corrupted, or not a jpeg. The identifier found was: '%s'",
jfifIdentifier.c_str()));
}
uint8_t majorVersion = data.at(11);
uint8_t minorVersion = data.at(12);
if (majorVersion != 0x01 || minorVersion != 0x01)
{
fprintf(stderr,
"ZBackground::CheckValidJpeg: Warning.\n"
"\t Wrong JFIF version '%i.%02i'. File: '%s'.\n"
"\t The expected version is '1.01'. The game may not be able to decode this image "
"properly.\n",
majorVersion, minorVersion, filename.c_str());
HANDLE_WARNING_PROCESS(
WarningType::InvalidJPEG,
StringHelper::Sprintf("wrong JFIF version '%i.%02i'", majorVersion, minorVersion),
"The expected version is '1.01'. The game may be unable to decode this image "
"correctly.");
}
if (BitConverter::ToUInt16BE(data, 20) != MARKER_DQT)
{
// This may happen when creating a custom image with Exif, XMP, thumbnail, progressive, etc.
// enabled.
fprintf(stderr,
"ZBackground::CheckValidJpeg: Warning.\n"
"\t There seems to be extra data before the image data in file: '%s'.\n"
"\t The game may not be able to decode this image properly.\n",
filename.c_str());
HANDLE_WARNING_PROCESS(WarningType::InvalidJPEG,
"there seems to be extra data before the image data in this file",
"The game may not be able to decode this image correctly.");
}
if (data.size() > GetRawDataSize())
{
fprintf(stderr,
"ZBackground::CheckValidJpeg: Warning.\n"
"\t The image is bigger than the screen buffer. File: '%s'.\n"
"\t Image size: %zu bytes.\n"
"\t Screen buffer size: %zu bytes.\n",
filename.c_str(), data.size(), GetRawDataSize());
HANDLE_WARNING_PROCESS(
WarningType::InvalidJPEG, "the image is bigger than the screen buffer",
StringHelper::Sprintf("Image size: %zu bytes\nScreen buffer size: %zu bytes",
data.size(), GetRawDataSize()));
}
}
@ -138,6 +133,7 @@ Declaration* ZBackground::DeclareVar(const std::string& prefix,
Declaration* decl = parent->AddDeclarationIncludeArray(rawDataIndex, incStr, GetRawDataSize(),
GetSourceTypeName(), auxName, 0);
decl->arrayItemCntStr = "SCREEN_WIDTH * SCREEN_HEIGHT / 4";
decl->forceArrayCnt = true;
decl->staticConf = staticConf;
return decl;
}

View file

@ -83,11 +83,6 @@ std::string ZBlob::GetBodySourceCode() const
return sourceOutput;
}
std::string ZBlob::GetSourceOutputHeader([[maybe_unused]] const std::string& prefix)
{
return StringHelper::Sprintf("extern u8 %s[];\n", name.c_str());
}
void ZBlob::Save(const fs::path& outFolder)
{
File::WriteAllBytes((outFolder / (name + ".bin")).string(), blobData);

View file

@ -16,7 +16,6 @@ public:
Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override;
std::string GetBodySourceCode() const override;
std::string GetSourceOutputHeader(const std::string& prefix) override;
void Save(const fs::path& outFolder) override;
bool IsExternalResource() const override;

View file

@ -88,7 +88,7 @@ void ZCollisionHeader::ParseRawData()
void ZCollisionHeader::DeclareReferences(const std::string& prefix)
{
std::string declaration;
std::string declaration = "";
std::string auxName = name;
if (name == "")
@ -174,7 +174,7 @@ void ZCollisionHeader::DeclareReferences(const std::string& prefix)
std::string ZCollisionHeader::GetBodySourceCode() const
{
std::string declaration;
std::string declaration = "";
declaration += "\n";

View file

@ -2,6 +2,7 @@
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZResource.h"
REGISTER_ZFILENODE(Cutscene, ZCutscene);
@ -87,7 +88,7 @@ CutsceneCommandSceneTransFX::~CutsceneCommandSceneTransFX()
std::string ZCutscene::GetBodySourceCode() const
{
std::string output;
std::string output = "";
uint32_t curPtr = 0;
output += StringHelper::Sprintf(" CS_BEGIN_CUTSCENE(%i, %i),\n", commands.size(), endFrame);
@ -225,8 +226,9 @@ void ZCutscene::ParseRawData()
cmd = new CutsceneCommandEnd(rawData, currentPtr);
break;
case CutsceneCommands::Error:
fprintf(stderr, "Cutscene command error %d %s %d\n", (int32_t)cmdID, __FILE__,
__LINE__);
HANDLE_WARNING_RESOURCE(WarningType::NotImplemented, parent, this, rawDataIndex,
StringHelper::Sprintf("cutscene command error %d", cmdID),
"");
break;
}
@ -404,7 +406,9 @@ CutsceneCommands ZCutscene::GetCommandFromID(int32_t id)
return CutsceneCommands::Unknown;
}
fprintf(stderr, "WARNING: Could not identify cutscene command ID 0x%04X\n", id);
HANDLE_WARNING_RESOURCE(
WarningType::NotImplemented, parent, this, rawDataIndex,
StringHelper::Sprintf("could not identify cutscene command. ID 0x%04X", id), "");
return CutsceneCommands::Error;
}

View file

@ -1,6 +1,6 @@
#pragma once
#include <stdint.h>
#include <cstdint>
#include <string>
#include <vector>
#include "ZFile.h"

View file

@ -1,6 +1,6 @@
#pragma once
#include <stdint.h>
#include <cstdint>
#include <string>
#include <vector>
#include "ZCutscene.h"

View file

@ -11,6 +11,7 @@
#include "Utils/File.h"
#include "Utils/Path.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "gfxd.h"
REGISTER_ZFILENODE(DList, ZDisplayList);
@ -445,11 +446,12 @@ int32_t ZDisplayList::GetDListLength(const std::vector<uint8_t>& rawData, uint32
{
if (ptr >= rawDataSize)
{
throw std::runtime_error(StringHelper::Sprintf(
"%s: Fatal error.\n"
"\t End of file found when trying to find the end of the "
"DisplayList at offset: '0x%X'.\n",
"Raw data size: 0x%zX.\n", __PRETTY_FUNCTION__, rawDataIndex, rawDataSize));
std::string errorHeader =
StringHelper::Sprintf("reached end of file when trying to find the end of the "
"DisplayList starting at offset 0x%X",
rawDataIndex);
std::string errorBody = StringHelper::Sprintf("Raw data size: 0x%zX.", rawDataSize);
HANDLE_ERROR_PROCESS(WarningType::Always, errorHeader, errorBody);
}
uint8_t opcode = rawData.at(ptr);
@ -1522,11 +1524,6 @@ void ZDisplayList::Opcode_G_ENDDL([[maybe_unused]] const std::string& prefix, ch
TextureGenCheck();
}
std::string ZDisplayList::GetSourceOutputHeader([[maybe_unused]] const std::string& prefix)
{
return "";
}
static int32_t GfxdCallback_FormatSingleEntry()
{
ZDisplayList* self = static_cast<ZDisplayList*>(gfxd_udata_get());
@ -1737,7 +1734,7 @@ static int32_t GfxdCallback_Matrix(uint32_t seg)
return 1;
}
std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix)
void ZDisplayList::DeclareReferences(const std::string& prefix)
{
std::string sourceOutput;
@ -1750,7 +1747,7 @@ std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix)
if (vertices.size() > 0)
{
std::vector<std::pair<uint32_t, std::vector<ZVtx>>> verticesSorted(vertices.begin(),
vertices.end());
vertices.end());
for (size_t i = 0; i < verticesSorted.size() - 1; i++)
{
@ -1775,15 +1772,13 @@ std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix)
// Generate Vertex Declarations
for (auto& item : vertices)
{
std::string declaration;
std::string declaration = "";
offset_t curAddr = item.first;
auto& firstVtx = item.second.at(0);
for (auto vtx : item.second)
{
declaration += StringHelper::Sprintf("\t%s,\n", vtx.GetBodySourceCode().c_str());
}
Declaration* decl = parent->AddDeclarationArray(
curAddr, firstVtx.GetDeclarationAlignment(),
@ -1800,7 +1795,7 @@ std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix)
if (vertices.size() > 0)
{
std::vector<std::pair<uint32_t, std::vector<ZVtx>>> verticesSorted(vertices.begin(),
vertices.end());
vertices.end());
for (size_t i = 0; i < verticesSorted.size() - 1; i++)
{
@ -1863,11 +1858,6 @@ std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix)
}
}
}
if (parent != nullptr)
return "";
return sourceOutput;
}
std::string ZDisplayList::ProcessLegacy(const std::string& prefix)

View file

@ -363,8 +363,7 @@ public:
size_t GetRawDataSize() const override;
DeclarationAlignment GetDeclarationAlignment() const override;
std::string GetSourceOutputHeader(const std::string& prefix) override;
std::string GetSourceOutputCode(const std::string& prefix) override;
void DeclareReferences(const std::string& prefix) override;
std::string ProcessLegacy(const std::string& prefix);
std::string ProcessGfxDis(const std::string& prefix);

View file

@ -13,6 +13,7 @@
#include "Utils/MemoryStream.h"
#include "Utils/Path.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZAnimation.h"
#include "ZArray.h"
#include "ZBackground.h"
@ -73,19 +74,13 @@ ZFile::ZFile(ZFileMode nMode, tinyxml2::XMLElement* reader, const fs::path& nBas
ZFile::~ZFile()
{
for (ZResource* res : resources)
{
delete res;
}
for (auto d : declarations)
{
delete d.second;
}
for (auto sym : symbolResources)
{
delete sym.second;
}
}
void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
@ -114,8 +109,11 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
else if (std::string_view(gameStr) == "OOT")
Globals::Instance->game = ZGame::OOT_RETAIL;
else
throw std::runtime_error(
StringHelper::Sprintf("Error: Game type %s not supported.", gameStr));
{
std::string errorHeader =
StringHelper::Sprintf("'Game' type '%s' is not supported.", gameStr);
HANDLE_ERROR_PROCESS(WarningType::InvalidAttributeValue, errorHeader, "");
}
}
if (reader->Attribute("BaseAddress") != nullptr)
@ -128,16 +126,22 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
rangeEnd = StringHelper::StrToL(reader->Attribute("RangeEnd"), 16);
if (rangeStart > rangeEnd)
throw std::runtime_error("Error: RangeStart must be before than RangeEnd.");
HANDLE_ERROR_PROCESS(
WarningType::Always,
StringHelper::Sprintf("'RangeStart' 0x%06X must be before 'RangeEnd' 0x%06X",
rangeStart, rangeEnd),
"");
const char* segmentXml = reader->Attribute("Segment");
if (segmentXml != nullptr)
{
if (!StringHelper::HasOnlyDigits(segmentXml))
{
throw std::runtime_error(StringHelper::Sprintf(
"error: Invalid segment value '%s': must be a decimal between 0 and 15 inclusive",
segmentXml));
HANDLE_ERROR_PROCESS(WarningType::Always,
StringHelper::Sprintf("error: Invalid segment value '%s': must be "
"a decimal between 0 and 15 inclusive",
segmentXml),
"");
}
segment = StringHelper::StrToL(segmentXml, 10);
@ -146,16 +150,19 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
if (segment == 128)
{
#ifdef DEPRECATION_ON
fprintf(stderr, "warning: segment 128 is deprecated.\n\tRemove "
"'Segment=\"128\"' from the xml to use virtual addresses\n");
HANDLE_WARNING_PROCESS(
WarningType::Always, "warning: segment 128 is deprecated.",
"Remove 'Segment=\"128\"' from the xml to use virtual addresses\n");
#endif
}
else
{
throw std::runtime_error(
HANDLE_ERROR_PROCESS(
WarningType::Always,
StringHelper::Sprintf("error: invalid segment value '%s': must be a decimal "
"number between 0 and 15 inclusive",
segmentXml));
segmentXml),
"");
}
}
}
@ -176,18 +183,16 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
if (mode == ZFileMode::Extract || mode == ZFileMode::ExternalFile)
{
if (!File::Exists((basePath / name).string()))
throw std::runtime_error(
StringHelper::Sprintf("Error! File %s does not exist.", (basePath / name).c_str()));
{
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());
/*
* TODO: In OoT repo ovl_Boss_Sst has a wrong RangeEnd (0xAD40 instead of 0xAD70),
* so uncommenting the following produces wrong behavior.
* If somebody fixes that in OoT repo, uncomment this. I'm too tired of fixing XMLs.
*/
// if (reader->Attribute("RangeEnd") == nullptr)
// rangeEnd = rawData.size();
if (reader->Attribute("RangeEnd") == nullptr)
rangeEnd = rawData.size();
}
std::unordered_set<std::string> nameSet;
@ -211,20 +216,17 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
if (offsetSet.find(offsetXml) != offsetSet.end())
{
throw std::runtime_error(StringHelper::Sprintf(
"ZFile::ParseXML: Error in '%s'.\n\t Repeated 'Offset' attribute: %s \n",
name.c_str(), offsetXml));
std::string errorHeader =
StringHelper::Sprintf("repeated 'Offset' attribute: %s", offsetXml);
HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, "");
}
offsetSet.insert(offsetXml);
}
else if (Globals::Instance->warnNoOffset)
else
{
fprintf(stderr, "Warning No offset specified for: %s", nameXml);
}
else if (Globals::Instance->errorNoOffset)
{
throw std::runtime_error(
StringHelper::Sprintf("Error no offset specified for %s", nameXml));
HANDLE_WARNING_RESOURCE(WarningType::MissingOffsets, this, nullptr, rawDataIndex,
StringHelper::Sprintf("no offset specified for %s.", nameXml),
"");
}
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO)
@ -234,9 +236,9 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
{
if (outNameSet.find(outNameXml) != outNameSet.end())
{
throw std::runtime_error(StringHelper::Sprintf(
"ZFile::ParseXML: Error in '%s'.\n\t Repeated 'OutName' attribute: %s \n",
name.c_str(), outNameXml));
std::string errorHeader =
StringHelper::Sprintf("repeated 'OutName' attribute: %s", outNameXml);
HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, "");
}
outNameSet.insert(outNameXml);
}
@ -244,9 +246,9 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
{
if (nameSet.find(nameXml) != nameSet.end())
{
throw std::runtime_error(StringHelper::Sprintf(
"ZFile::ParseXML: Error in '%s'.\n\t Repeated 'Name' attribute: %s \n",
name.c_str(), nameXml));
std::string errorHeader =
StringHelper::Sprintf("repeated 'Name' attribute: %s", nameXml);
HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, "");
}
nameSet.insert(nameXml);
}
@ -279,16 +281,14 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
}
else if (std::string_view(child->Name()) == "File")
{
throw std::runtime_error(StringHelper::Sprintf(
"ZFile::ParseXML: Error in '%s'.\n\t Can't declare a File inside a File.\n",
name.c_str()));
std::string errorHeader = "Can't declare a <File> inside a <File>";
HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, "");
}
else
{
throw std::runtime_error(
StringHelper::Sprintf("ZFile::ParseXML: Error in '%s'.\n\t Unknown element found "
"inside a File element: '%s'.\n",
name.c_str(), nodeName.c_str()));
std::string errorHeader = StringHelper::Sprintf(
"Unknown element found inside a <File> element: %s", nodeName.c_str());
HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, "");
}
}
}
@ -307,7 +307,7 @@ void ZFile::BuildSourceFile()
return;
if (!Directory::Exists(outputPath))
Directory::CreateDirectory(outputPath);
Directory::CreateDirectory(outputPath.string());
GenerateSourceFiles();
}
@ -317,6 +317,11 @@ std::string ZFile::GetName() const
return name;
}
std::string ZFile::GetOutName() const
{
return outName.string();
}
ZFileMode ZFile::GetMode() const
{
return mode;
@ -338,10 +343,10 @@ void ZFile::ExtractResources()
return;
if (!Directory::Exists(outputPath))
Directory::CreateDirectory(outputPath);
Directory::CreateDirectory(outputPath.string());
if (!Directory::Exists(GetSourceOutputFolderPath()))
Directory::CreateDirectory(GetSourceOutputFolderPath());
Directory::CreateDirectory(GetSourceOutputFolderPath().string());
for (size_t i = 0; i < resources.size(); i++)
resources[i]->ParseRawDataLate();
@ -351,8 +356,8 @@ void ZFile::ExtractResources()
if (Globals::Instance->genSourceFile)
GenerateSourceFiles();
MemoryStream* memStream = new MemoryStream();
BinaryWriter writer = BinaryWriter(memStream);
auto memStreamFile = std::shared_ptr<MemoryStream>(new MemoryStream());
BinaryWriter writerFile = BinaryWriter(memStreamFile);
ExporterSet* exporterSet = Globals::Instance->GetExporterSet();
@ -361,6 +366,9 @@ void ZFile::ExtractResources()
for (ZResource* res : resources)
{
auto memStreamRes = std::shared_ptr<MemoryStream>(new MemoryStream());
BinaryWriter writerRes = BinaryWriter(memStreamRes);
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO)
printf("Saving resource %s\n", res->GetName().c_str());
@ -369,18 +377,24 @@ void ZFile::ExtractResources()
// Check if we have an exporter "registered" for this resource type
ZResourceExporter* exporter = Globals::Instance->GetExporter(res->GetResourceType());
if (exporter != nullptr)
exporter->Save(res, Globals::Instance->outputPath.string(), &writer);
{
//exporter->Save(res, Globals::Instance->outputPath.string(), &writerFile);
exporter->Save(res, Globals::Instance->outputPath.string(), &writerRes);
}
if (exporterSet != nullptr && exporterSet->resSaveFunc != nullptr)
exporterSet->resSaveFunc(res, writerRes);
}
if (memStream->GetLength() > 0)
if (memStreamFile->GetLength() > 0)
{
File::WriteAllBytes(StringHelper::Sprintf("%s%s.bin",
Globals::Instance->outputPath.string().c_str(),
GetName().c_str()),
memStream->ToVector());
memStreamFile->ToVector());
}
writer.Close();
writerFile.Close();
if (exporterSet != nullptr && exporterSet->endFileFunc != nullptr)
exporterSet->endFileFunc(this);
@ -1070,8 +1084,6 @@ std::string ZFile::ProcessDeclarations()
}
}
output += "\n";
return output;
}
@ -1234,11 +1246,12 @@ bool ZFile::HandleUnaccountedAddress(uint32_t currentAddress, uint32_t lastAddr,
{
Declaration* currentDecl = declarations.at(currentAddress);
fprintf(stderr,
"WARNING: Intersection detected from 0x%06X:0x%06X (%s), conflicts with "
"0x%06X (%s)\n",
lastAddr, lastAddr + lastSize, lastDecl->varName.c_str(), currentAddress,
currentDecl->varName.c_str());
std::string intersectionInfo = StringHelper::Sprintf(
"Resource from 0x%06X:0x%06X (%s) conflicts with 0x%06X (%s).", lastAddr,
lastAddr + lastSize, lastDecl->varName.c_str(), currentAddress,
currentDecl->varName.c_str());
HANDLE_WARNING_RESOURCE(WarningType::Intersection, this, nullptr, currentAddress,
"intersection detected", intersectionInfo);
}
}
@ -1309,25 +1322,17 @@ bool ZFile::HandleUnaccountedAddress(uint32_t currentAddress, uint32_t lastAddr,
diff, src);
decl->isUnaccounted = true;
if (Globals::Instance->warnUnaccounted)
if (nonZeroUnaccounted)
{
if (nonZeroUnaccounted)
{
fprintf(stderr,
"Warning in file: %s (%s)\n"
"\t A non-zero unaccounted block was found at offset '0x%06X'.\n"
"\t Block size: '0x%X'.\n",
xmlFilePath.c_str(), name.c_str(), unaccountedAddress, diff);
}
else if (diff >= 16)
{
fprintf(stderr,
"Warning in file: %s (%s)\n"
"\t A big (size>=0x10) zero-only unaccounted block was found "
"at offset '0x%06X'.\n"
"\t Block size: '0x%X'.\n",
xmlFilePath.c_str(), name.c_str(), unaccountedAddress, diff);
}
HANDLE_WARNING_RESOURCE(WarningType::Unaccounted, this, nullptr, unaccountedAddress,
"a non-zero unaccounted block was found",
StringHelper::Sprintf("Block size: '0x%X'", diff));
}
else if (diff >= 16)
{
HANDLE_WARNING_RESOURCE(WarningType::Unaccounted, this, nullptr, unaccountedAddress,
"a big (size>=0x10) zero-only unaccounted block was found",
StringHelper::Sprintf("Block size: '0x%X'", diff));
}
}
}

View file

@ -1,6 +1,5 @@
#pragma once
#include <Utils/Directory.h>
#include <string>
#include <vector>
@ -46,6 +45,7 @@ public:
~ZFile();
std::string GetName() const;
std::string GetOutName() const;
ZFileMode GetMode() const;
const fs::path& GetXmlFilePath() const;
const std::vector<uint8_t>& GetRawData() const;

View file

@ -4,7 +4,7 @@
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
REGISTER_ZFILENODE(Limb, ZLimb);
@ -37,17 +37,15 @@ void ZLimb::ParseXML(tinyxml2::XMLElement* reader)
if (limbType == "")
{
throw std::runtime_error(StringHelper::Sprintf("ZLimb::ParseXML: Error in '%s'.\n"
"\t Missing 'LimbType' attribute in xml.\n",
name.c_str()));
HANDLE_ERROR_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex,
"missing 'LimbType' attribute in <Limb>", "");
}
type = GetTypeByAttributeName(limbType);
if (type == ZLimbType::Invalid)
{
throw std::runtime_error(StringHelper::Sprintf("ZLimb::ParseXML: Error in '%s'.\n"
"\t Invalid 'LimbType' found: '%s'.\n",
name.c_str(), limbType.c_str()));
HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
"invalid value found for 'LimbType' attribute", "");
}
}
@ -109,8 +107,12 @@ void ZLimb::ParseRawData()
}
break;
default:
throw std::runtime_error("Invalid ZLimb type");
case ZLimbType::Curve:
case ZLimbType::Legacy:
break;
case ZLimbType::Invalid:
assert(!"whoops");
break;
}
}

View file

@ -3,6 +3,7 @@
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZFile.h"
REGISTER_ZFILENODE(Path, ZPath);
@ -20,10 +21,12 @@ void ZPath::ParseXML(tinyxml2::XMLElement* reader)
numPaths = StringHelper::StrToL(registeredAttributes.at("NumPaths").value);
if (numPaths < 1)
throw std::runtime_error(
StringHelper::Sprintf("ZPath::ParseXML: Fatal error in '%s'.\n"
"\t Invalid value for attribute 'NumPaths': '%i'\n",
name.c_str(), numPaths));
{
HANDLE_ERROR_RESOURCE(
WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
StringHelper::Sprintf("invalid value '%d' found for 'NumPaths' attribute", numPaths),
"Should be at least '1'");
}
}
void ZPath::ParseRawData()
@ -144,7 +147,7 @@ void PathwayEntry::DeclareReferences(const std::string& prefix)
if (addressFound)
return;
std::string declaration;
std::string declaration = "";
size_t index = 0;
for (const auto& point : points)

View file

@ -4,6 +4,7 @@
#include <regex>
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZFile.h"
ZResource::ZResource(ZFile* nParent)
@ -85,29 +86,33 @@ void ZResource::ParseXML(tinyxml2::XMLElement* reader)
}
if (!attrDeclared)
fprintf(stderr,
"ZResource::ParseXML: Warning while parsing '%s'.\n"
"\t Unexpected '%s' attribute in resource '%s'.\n",
parent->GetName().c_str(), attrName.c_str(), reader->Name());
{
HANDLE_WARNING_RESOURCE(
WarningType::UnknownAttribute, parent, this, rawDataIndex,
StringHelper::Sprintf("unexpected '%s' attribute in resource <%s>",
attrName.c_str(), reader->Name()),
"");
}
attrs = attrs->Next();
}
if (!canHaveInner && !reader->NoChildren())
{
throw std::runtime_error(
StringHelper::Sprintf("ZResource::ParseXML: Fatal error in '%s'.\n"
"\t Resource '%s' with inner element/child detected.\n",
name.c_str(), reader->Name()));
std::string errorHeader = StringHelper::Sprintf(
"resource '%s' with inner element/child detected", reader->Name());
HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, "");
}
for (const auto& attr : registeredAttributes)
{
if (attr.second.isRequired && attr.second.value == "")
throw std::runtime_error(StringHelper::Sprintf(
"ZResource::ParseXML: Fatal error while parsing '%s'.\n"
"\t Missing required attribute '%s' in resource '%s'.\n"
"\t Aborting...",
parent->GetName().c_str(), attr.first.c_str(), reader->Name()));
{
std::string headerMsg =
StringHelper::Sprintf("missing required attribute '%s' in resource <%s>",
attr.first.c_str(), reader->Name());
HANDLE_ERROR_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex,
headerMsg, "");
}
}
name = registeredAttributes.at("Name").value;
@ -118,10 +123,8 @@ void ZResource::ParseXML(tinyxml2::XMLElement* reader)
{
if (!std::regex_match(name, r))
{
throw std::domain_error(
StringHelper::Sprintf("ZResource::ParseXML: Fatal error in '%s'.\n"
"\t Resource with invalid 'Name' attribute.\n",
name.c_str()));
HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this,
rawDataIndex, "invalid value found for 'Name' attribute", "");
}
}
@ -146,7 +149,9 @@ void ZResource::ParseXML(tinyxml2::XMLElement* reader)
}
else
{
throw std::runtime_error("Invalid value for 'Static' attribute.");
HANDLE_ERROR_RESOURCE(
WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
StringHelper::Sprintf("invalid value '%s' for 'Static' attribute", staticConf), "");
}
declaredInXml = true;
@ -253,18 +258,21 @@ std::string ZResource::GetDefaultName(const std::string& prefix) const
rawDataIndex);
}
std::string ZResource::GetSourceOutputCode([[maybe_unused]] const std::string& prefix)
void ZResource::GetSourceOutputCode([[maybe_unused]] const std::string& prefix)
{
std::string bodyStr = GetBodySourceCode();
Declaration* decl = parent->GetDeclaration(rawDataIndex);
if (decl == nullptr || decl->isPlaceholder)
decl = DeclareVar(prefix, bodyStr);
else
decl->text = bodyStr;
decl->staticConf = staticConf;
if (bodyStr != "ERROR")
{
Declaration* decl = parent->GetDeclaration(rawDataIndex);
return "";
if (decl == nullptr || decl->isPlaceholder)
decl = DeclareVar(prefix, bodyStr);
else
decl->text = bodyStr;
decl->staticConf = staticConf;
}
}
std::string ZResource::GetSourceOutputHeader([[maybe_unused]] const std::string& prefix)
@ -312,13 +320,13 @@ offset_t Seg2Filespace(segptr_t segmentedAddress, uint32_t parentBaseAddress)
uint32_t parentBaseOffset = GETSEGOFFSET(parentBaseAddress);
if (parentBaseOffset > currentPtr)
{
throw std::runtime_error(
StringHelper::Sprintf("\nSeg2Filespace: Segmented address is smaller than "
"'BaseAddress'. Maybe your 'BaseAddress' is wrong?\n"
"\t SegmentedAddress: 0x%08X\n"
"\t BaseAddress: 0x%08X\n",
segmentedAddress, parentBaseAddress));
HANDLE_ERROR(WarningType::Always,
StringHelper::Sprintf(
"resource address 0x%08X is smaller than 'BaseAddress' 0x%08X",
segmentedAddress, parentBaseAddress),
"Maybe your 'BaseAddress' is wrong?");
}
currentPtr -= parentBaseOffset;
}

View file

@ -1,16 +1,15 @@
#pragma once
#include <Utils/BinaryWriter.h>
#include <cstdint>
#include <map>
#include <stdexcept>
#include <stdint.h>
#include <string>
#include <vector>
#include "Declaration.h"
#include "Utils/BinaryWriter.h"
#include "Utils/Directory.h"
#include "tinyxml2.h"
#include <Utils/Directory.h>
#define SEGMENT_SCENE 2
#define SEGMENT_ROOM 3
#define SEGMENT_KEEP 4
@ -113,7 +112,7 @@ public:
*/
[[nodiscard]] virtual std::string GetDefaultName(const std::string& prefix) const;
virtual std::string GetSourceOutputCode(const std::string& prefix);
virtual void GetSourceOutputCode(const std::string& prefix);
virtual std::string GetSourceOutputHeader(const std::string& prefix);
virtual void CalcHash();
/**

View file

@ -1,8 +1,10 @@
#include "SetMesh.h"
#include <Globals.h>
#include <Utils/Path.h>
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/Path.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZBackground.h"
#include "ZFile.h"
#include "ZRoom/ZRoom.h"
@ -34,9 +36,8 @@ void SetMesh::ParseRawData()
break;
default:
throw std::runtime_error(StringHelper::Sprintf("Error in SetMesh::ParseRawData\n"
"\t Unknown meshHeaderType: %i\n",
meshHeaderType));
HANDLE_ERROR(WarningType::InvalidExtractedData,
StringHelper::Sprintf("unknown meshHeaderType: %i", meshHeaderType), "");
}
polyType->ParseRawData();
@ -53,11 +54,9 @@ void SetMesh::DeclareReferences(const std::string& prefix)
void GenDListDeclarations(ZRoom* zRoom, ZFile* parent, ZDisplayList* dList)
{
if (dList == nullptr)
{
return;
}
std::string sourceOutput = dList->GetSourceOutputCode(zRoom->GetName());
dList->DeclareReferences(zRoom->GetName());
for (ZDisplayList* otherDList : dList->otherDLists)
GenDListDeclarations(zRoom, parent, otherDList);
@ -143,21 +142,17 @@ std::string PolygonDlist::GetBodySourceCode() const
return bodyStr;
}
std::string PolygonDlist::GetSourceOutputCode(const std::string& prefix)
void PolygonDlist::GetSourceOutputCode(const std::string& prefix)
{
std::string bodyStr = StringHelper::Sprintf("\n\t%s\n", GetBodySourceCode().c_str());
Declaration* decl = parent->GetDeclaration(rawDataIndex);
if (decl == nullptr)
{
DeclareVar(prefix, bodyStr);
}
else
{
decl->text = bodyStr;
}
return "";
if (decl == nullptr)
DeclareVar(prefix, bodyStr);
else
decl->text = bodyStr;
}
std::string PolygonDlist::GetSourceTypeName() const
@ -472,8 +467,8 @@ void PolygonType1::DeclareReferences(const std::string& prefix)
break;
default:
throw std::runtime_error(StringHelper::Sprintf(
"Error in PolygonType1::PolygonType1\n\t Unknown format: %i\n", format));
HANDLE_ERROR(WarningType::InvalidExtractedData,
StringHelper::Sprintf("unknown format: %i", format), "");
break;
}
}
@ -582,9 +577,11 @@ void PolygonType2::DeclareReferences(const std::string& prefix)
polyDListName = StringHelper::Sprintf("%s%s_%06X", prefix.c_str(), polyDlistType.c_str(),
GETSEGOFFSET(start));
parent->AddDeclarationArray(GETSEGOFFSET(start), DeclarationAlignment::Align4,
polyDLists.size() * polyDLists.at(0).GetRawDataSize(),
polyDlistType, polyDListName, polyDLists.size(), declaration);
Declaration* decl = parent->AddDeclarationArray(
GETSEGOFFSET(start), DeclarationAlignment::Align4,
polyDLists.size() * polyDLists.at(0).GetRawDataSize(), polyDlistType, polyDListName,
polyDLists.size(), declaration);
decl->forceArrayCnt = true;
}
parent->AddDeclaration(GETSEGOFFSET(end), DeclarationAlignment::Align4, 4, "s32",

View file

@ -28,7 +28,7 @@ public:
std::string GetBodySourceCode() const override;
std::string GetSourceOutputCode(const std::string& prefix) override;
void GetSourceOutputCode(const std::string& prefix) override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;

View file

@ -115,11 +115,9 @@ std::string RomFile::GetBodySourceCode() const
return declaration;
}
std::string RomFile::GetSourceOutputCode(const std::string& prefix)
void RomFile::GetSourceOutputCode(const std::string& prefix)
{
DeclareVar(prefix, GetBodySourceCode());
return "";
}
std::string RomFile::GetSourceTypeName() const

View file

@ -24,7 +24,7 @@ public:
Declaration* DeclareVar(const std::string& prefix, const std::string& body) override;
std::string GetBodySourceCode() const override;
std::string GetSourceOutputCode(const std::string& prefix) override;
void GetSourceOutputCode(const std::string& prefix) override;
std::string GetSourceTypeName() const override;
virtual ZResourceType GetResourceType() const override;

View file

@ -40,6 +40,7 @@
#include "Utils/File.h"
#include "Utils/Path.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZBlob.h"
#include "ZCutscene.h"
#include "ZFile.h"
@ -123,10 +124,12 @@ void ZRoom::ParseXML(tinyxml2::XMLElement* reader)
{
hackMode = std::string(reader->Attribute("HackMode"));
if (hackMode != "syotes_room")
throw std::runtime_error(
StringHelper::Sprintf("ZRoom::ParseXML: Fatal error in '%s'.\n"
"\t Invalid value for attribute 'HackMode': '%s'\n",
name.c_str(), hackMode.c_str()));
{
std::string headerError = StringHelper::Sprintf(
"invalid value found for 'HackMode' attribute: '%s'", hackMode.c_str());
HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
headerError, "");
}
}
}
@ -392,14 +395,10 @@ size_t ZRoom::GetCommandSizeFromNeighbor(ZRoomCommand* cmd)
return 0;
}
std::string ZRoom::GetSourceOutputCode([[maybe_unused]] const std::string& prefix)
void ZRoom::GetSourceOutputCode([[maybe_unused]] const std::string& prefix)
{
if (hackMode == "syotes_room")
return "";
DeclareVar(prefix, GetBodySourceCode());
return "";
if (hackMode != "syotes_room")
DeclareVar(prefix, GetBodySourceCode());
}
size_t ZRoom::GetRawDataSize() const

View file

@ -34,7 +34,7 @@ public:
Declaration* DeclareVar(const std::string& prefix, const std::string& body) override;
std::string GetBodySourceCode() const override;
std::string GetSourceOutputCode(const std::string& prefix) override;
void GetSourceOutputCode(const std::string& prefix) override;
std::string GetDefaultName(const std::string& prefix) const override;
size_t GetDeclarationSizeFromNeighbor(uint32_t declarationAddress);

View file

@ -4,6 +4,7 @@
#include "Utils/BitConverter.h"
#include "Utils/File.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZFile.h"
REGISTER_ZFILENODE(Scalar, ZScalar);
@ -207,8 +208,8 @@ void ZScalar::ParseRawData()
scalarData.f64 = BitConverter::ToDoubleBE(rawData, rawDataIndex);
break;
case ZScalarType::ZSCALAR_NONE:
fprintf(stderr, "Warning in ZScalar: Invalid type. %d %s %d\n", (int32_t)scalarType,
__FILE__, __LINE__);
HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
"invalid value found for 'Type' attribute", "Defaulting to ''");
break;
}
}

View file

@ -1,6 +1,6 @@
#pragma once
#include <stdint.h>
#include <cstdint>
#include <string>
#include <vector>
#include "ZResource.h"

View file

@ -5,6 +5,7 @@
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
REGISTER_ZFILENODE(Skeleton, ZSkeleton);
REGISTER_ZFILENODE(LimbTable, ZLimbTable);
@ -27,18 +28,19 @@ void ZSkeleton::ParseXML(tinyxml2::XMLElement* reader)
type = ZSkeletonType::Curve;
else if (skelTypeXml != "Normal")
{
throw std::runtime_error(StringHelper::Sprintf("ZSkeleton::ParseXML: Error in '%s'.\n"
"\t Invalid Type found: '%s'.\n",
name.c_str(), skelTypeXml.c_str()));
HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
"invalid value found for 'Type' attribute", "");
}
std::string limbTypeXml = registeredAttributes.at("LimbType").value;
limbType = ZLimb::GetTypeByAttributeName(limbTypeXml);
if (limbType == ZLimbType::Invalid)
{
throw std::runtime_error(StringHelper::Sprintf("ZSkeleton::ParseXML: Error in '%s'.\n"
"\t Invalid LimbType found: '%s'.\n",
name.c_str(), limbTypeXml.c_str()));
HANDLE_ERROR_RESOURCE(
WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
StringHelper::Sprintf("invalid value '%s' found for 'LimbType' attribute",
limbTypeXml.c_str()),
"Defaulting to 'Standard'.");
}
}
@ -170,11 +172,9 @@ void ZLimbTable::ParseXML(tinyxml2::XMLElement* reader)
limbType = ZLimb::GetTypeByAttributeName(limbTypeXml);
if (limbType == ZLimbType::Invalid)
{
fprintf(stderr,
"ZLimbTable::ParseXML: Warning in '%s'.\n"
"\t Invalid LimbType found: '%s'.\n"
"\t Defaulting to 'Standard'.\n",
name.c_str(), limbTypeXml.c_str());
HANDLE_WARNING_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
"invalid value found for 'LimbType' attribute.",
"Defaulting to 'Standard'.");
limbType = ZLimbType::Standard;
}

View file

@ -1,6 +1,7 @@
#include "ZSymbol.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZFile.h"
REGISTER_ZFILENODE(Symbol, ZSymbol);
@ -20,11 +21,8 @@ void ZSymbol::ParseXML(tinyxml2::XMLElement* reader)
if (typeXml == "")
{
fprintf(stderr,
"ZSymbol::ParseXML: Warning in '%s'.\n"
"\t Missing 'Type' attribute in xml.\n"
"\t Defaulting to 'void*'.\n",
name.c_str());
HANDLE_WARNING_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex,
"missing 'Type' attribute in <Symbol>", "Defaulting to 'void*'.");
type = "void*";
}
else
@ -35,11 +33,8 @@ void ZSymbol::ParseXML(tinyxml2::XMLElement* reader)
std::string typeSizeXml = registeredAttributes.at("TypeSize").value;
if (typeSizeXml == "")
{
fprintf(stderr,
"ZSymbol::ParseXML: Warning in '%s'.\n"
"\t Missing 'TypeSize' attribute in xml.\n"
"\t Defaulting to '4'.\n",
name.c_str());
HANDLE_WARNING_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex,
"missing 'TypeSize' attribute in <Symbol>", "Defaulting to '4'.");
typeSize = 4; // Size of a word.
}
else
@ -58,7 +53,9 @@ void ZSymbol::ParseXML(tinyxml2::XMLElement* reader)
if (registeredAttributes.at("Static").value == "On")
{
fprintf(stderr, "A <Symbol> can't be marked as static.\n\t Disabling static\n");
HANDLE_WARNING_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
"a <Symbol> cannot be marked as static",
"Disabling static for this resource.");
}
staticConf = StaticConfig::Off;
}

View file

@ -8,6 +8,7 @@
#include "Utils/Directory.h"
#include "Utils/File.h"
#include "Utils/Path.h"
#include "WarningHandler.h"
REGISTER_ZFILENODE(Texture, ZTexture);
@ -57,17 +58,17 @@ void ZTexture::ParseXML(tinyxml2::XMLElement* reader)
if (!StringHelper::HasOnlyDigits(widthXml))
{
throw std::runtime_error(
StringHelper::Sprintf("ZTexture::ParseXML: Error in %s\n"
"\t Value of 'Width' attribute has non-decimal digits: '%s'.\n",
name.c_str(), widthXml.c_str()));
std::string errorHeader = StringHelper::Sprintf(
"value of 'Width' attribute has non-decimal digits: '%s'", widthXml.c_str());
HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
errorHeader, "");
}
if (!StringHelper::HasOnlyDigits(heightXml))
{
throw std::runtime_error(
StringHelper::Sprintf("ZTexture::ParseXML: Error in %s\n"
"\t Value of 'Height' attribute has non-decimal digits: '%s'.\n",
name.c_str(), heightXml.c_str()));
std::string errorHeader = StringHelper::Sprintf(
"value of 'Height' attribute has non-decimal digits: '%s'", heightXml.c_str());
HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
errorHeader, "");
}
width = StringHelper::StrToL(widthXml);
@ -77,7 +78,10 @@ void ZTexture::ParseXML(tinyxml2::XMLElement* reader)
format = GetTextureTypeFromString(formatStr);
if (format == TextureType::Error)
throw std::runtime_error("Format " + formatStr + " is not supported!");
{
HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
"invalid value found for 'Format' attribute", "");
}
const auto& tlutOffsetAttr = registeredAttributes.at("TlutOffset");
if (tlutOffsetAttr.wasSet)
@ -90,10 +94,9 @@ void ZTexture::ParseXML(tinyxml2::XMLElement* reader)
break;
default:
throw std::runtime_error(StringHelper::Sprintf(
"ZTexture::ParseXML: Error in %s\n"
"\t 'TlutOffset' declared in non color-indexed (ci4 or ci8) texture.\n",
name.c_str()));
HANDLE_ERROR_RESOURCE(WarningType::InvalidXML, parent, this, rawDataIndex,
"'TlutOffset' declared in non color-indexed (ci4 or ci8) texture",
"");
break;
}
}
@ -102,10 +105,10 @@ void ZTexture::ParseXML(tinyxml2::XMLElement* reader)
void ZTexture::ParseRawData()
{
if (rawDataIndex % 8 != 0)
fprintf(stderr,
"ZTexture::ParseXML: Warning in '%s'.\n"
"\t This texture is not 64-bit aligned.\n",
name.c_str());
{
HANDLE_WARNING_RESOURCE(WarningType::NotImplemented, parent, this, rawDataIndex,
"this texture is not 64-bit aligned", "");
}
switch (format)
{
@ -136,8 +139,11 @@ void ZTexture::ParseRawData()
case TextureType::Palette8bpp:
PrepareBitmapPalette8();
break;
default:
throw std::runtime_error("Format is not supported!");
case TextureType::Error:
HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
StringHelper::Sprintf("Invalid texture format", format), "");
assert(!"TODO");
break;
}
}
@ -375,8 +381,9 @@ void ZTexture::PrepareRawDataFromFile(const fs::path& pngFilePath)
case TextureType::Palette8bpp:
PrepareRawDataPalette8(pngFilePath);
break;
default:
throw std::runtime_error("Format is not supported!");
case TextureType::Error:
HANDLE_ERROR_PROCESS(WarningType::InvalidPNG, "Input PNG file has invalid format type", "");
break;
}
}
@ -860,13 +867,9 @@ TextureType ZTexture::GetTextureTypeFromString(const std::string& str)
else if (str == "rgb5a1")
{
texType = TextureType::RGBA16bpp;
#ifdef DEPRECATION_ON
fprintf(stderr, "ZTexture::GetTextureTypeFromString: Deprecation warning.\n"
"\t The texture format 'rgb5a1' is currently deprecated, and will be "
"removed in a future "
"version.\n"
"\t Use the format 'rgba16' instead.\n");
#endif
HANDLE_WARNING(WarningType::Deprecated,
"the texture format 'rgb5a1' is currently deprecated",
"It will be removed in a future version. Use the format 'rgba16' instead.");
}
else if (str == "i4")
texType = TextureType::Grayscale4bpp;
@ -883,7 +886,9 @@ TextureType ZTexture::GetTextureTypeFromString(const std::string& str)
else if (str == "ci8")
texType = TextureType::Palette8bpp;
else
fprintf(stderr, "Encountered Unknown Texture format %s \n", str.c_str());
// TODO: handle this case in a more coherent way
HANDLE_WARNING(WarningType::InvalidAttributeValue,
"invalid value found for 'Type' attribute", "Defaulting to ''.");
return texType;
}

View file

@ -2,8 +2,8 @@
* File: ZTextureAnimation.cpp
* ZResources defined: ZTextureAnimation, ZTextureAnimationParams (XML declaration not supported for
* the latter)
* Purpose: extracting texture animating structures from asset files Note: data type is exclusive to
* Majora's Mask
* Purpose: extracting texture animating structures from asset files
* Note: data type is exclusive to Majora's Mask
*
* Structure of data:
* A texture animation consists of a main array of data of the form
@ -82,6 +82,7 @@
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "WarningHandler.h"
#include "ZFile.h"
#include "ZResource.h"
#include "tinyxml2.h"
@ -115,7 +116,7 @@ void ZTextureAnimationParams::ExtractFromBinary(uint32_t nRawDataIndex)
ParseRawData();
}
// Implemented by TextureScrollingParams only[
// Implemented by TextureScrollingParams only
void ZTextureAnimationParams::ExtractFromBinary([[maybe_unused]] uint32_t nRawDataIndex,
[[maybe_unused]] int count)
{
@ -217,19 +218,8 @@ void TextureColorChangingParams::ParseRawData()
((type == TextureAnimationParamsType::ColorChange) ? animLength : colorListCount);
if (listLength == 0)
throw std::runtime_error(StringHelper::Sprintf(
"When processing file %s: in input binary file %s, offset 0x%06X:"
"\n\t"
"\033[97m"
"TextureColorChangingParams::ParseRawData:"
"\033[0m"
"\033[91m"
" error: "
"\033[0m"
"\033[97m"
"color list length cannot be 0\n"
"\033[0m",
Globals::Instance->inputPath.c_str(), parent->GetName().c_str(), rawDataIndex));
HANDLE_ERROR_RESOURCE(WarningType::Always, parent, this, rawDataIndex,
"color list length cannot be 0", "");
primColorListAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex + 4);
envColorListAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8);
@ -378,20 +368,8 @@ void TextureCyclingParams::ParseRawData()
cycleLength = BitConverter::ToUInt16BE(rawData, rawDataIndex);
if (cycleLength == 0)
throw std::runtime_error(
StringHelper::Sprintf("When processing file %s: in input binary file %s, offset 0x%06X:"
"\n\t"
"\033[97m"
"TextureCyclingParams::ParseRawData:"
"\033[0m"
"\033[91m"
" error: "
"\033[0m"
"\033[97m"
"cycleLength cannot be 0\n"
"\033[0m",
Globals::Instance->inputPath.c_str(), parent->GetName().c_str(),
Seg2Filespace(rawDataIndex, 0)));
HANDLE_ERROR_RESOURCE(WarningType::Always, parent, this, rawDataIndex,
"cycle length cannot be 0", "");
textureListAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex + 4);
textureIndexListAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8);
@ -454,21 +432,12 @@ void TextureCyclingParams::DeclareReferences([[maybe_unused]] const std::string&
{
comment = " // Raw pointer, declare texture in XML to use proper symbol";
fprintf(stderr,
"When processing file %s: in input binary file %s, offset 0x%06X:"
"\n\t"
"\033[97m"
"TextureCyclingParams::DeclareReferences:"
"\033[0m"
"\033[95m"
" warning: "
"\033[0m"
"\033[97m"
"TexCycle declared here points to unknown texture at address %s. "
"Please declare the texture in the XML to use the proper symbol.\n"
"\033[0m",
Globals::Instance->inputPath.c_str(), parent->GetName().c_str(),
Seg2Filespace(textureListAddress, parent->baseAddress), texName.c_str());
auto msgHeader = StringHelper::Sprintf(
"TexCycle texture array declared here points to unknown texture at address %s",
texName.c_str());
HANDLE_WARNING_RESOURCE(
WarningType::HardcodedPointer, parent, this, rawDataIndex, msgHeader,
"Please declare the texture in the XML to use the proper symbol.");
}
texturesBodyStr += StringHelper::Sprintf("\t%s,%s\n", texName.c_str(), comment.c_str());
}
@ -546,22 +515,14 @@ void ZTextureAnimation::ParseRawData()
if ((type < 0) || (type > 6))
{
throw std::runtime_error(StringHelper::Sprintf(
"When processing file %s: in input binary file %s, offset 0x%06X:"
"\n\t"
"\033[97m"
"ZTextureAnimation::ParseRawData:"
"\033[0m"
"\033[91m"
" error: "
"\033[0m"
"\033[97m"
"unknown TextureAnimationParams type 0x%02X in TextureAnimation: entry reads\n\t{ "
"0x%02X, 0x%02X, 0x%08X }\n(type should be between "
"0x00 and 0x06)\n"
"\033[0m",
Globals::Instance->inputPath.c_str(), parent->GetName().c_str(), rawDataIndex, type,
currentEntry.segment, type, currentEntry.paramsPtr));
HANDLE_ERROR_RESOURCE(
WarningType::Always, parent, this, rawDataIndex,
StringHelper::Sprintf(
"unknown TextureAnimationParams type 0x%02X in TextureAnimation", type),
StringHelper::Sprintf(
"Entry reads { 0x%02X, 0x%02X, 0x%08X } , but type should be "
"between 0x00 and 0x06 inclusive.",
currentEntry.segment, type, currentEntry.paramsPtr));
}
if (currentEntry.segment <= 0)
@ -589,13 +550,24 @@ void ZTextureAnimation::DeclareReferences(const std::string& prefix)
if (!parent->HasDeclaration(paramsOffset))
{
ZTextureAnimationParams* params;
int count = 2;
int count;
switch (entry.type)
{
case TextureAnimationParamsType::SingleScroll:
count = 1;
[[fallthrough]];
case TextureAnimationParamsType::DualScroll:
if (true)
{
count = 1;
// The else now allows SingleScroll to fall through to params = ... without
// touching the code in the else block
}
else
{
// The contents of this block can only be run by jumping into it with the
// case label
[[fallthrough]];
case TextureAnimationParamsType::DualScroll:
count = 2;
}
params = new TextureScrollingParams(parent);
params->ExtractFromBinary(paramsOffset, count);
break;
@ -614,22 +586,12 @@ void ZTextureAnimation::DeclareReferences(const std::string& prefix)
break;
case TextureAnimationParamsType::Empty:
fprintf(stderr,
"When processing file %s: in input binary file %s: offset 0x%06X:"
"\n\t"
"\033[97m"
"ZTextureAnimation::DeclareReferences:"
"\033[0m"
"\033[95m"
" warning: "
"\033[0m"
"\033[97m"
"TextureAnimationParams entry has empty type (6), but params pointer "
"is not NULL. Params read\n\t\t"
"{ 0x%02X, 0x%02X, 0x%08X }\n"
"\033[0m",
Globals::Instance->inputPath.c_str(), parent->GetName().c_str(),
rawDataIndex, entry.segment, (int)entry.type, entry.paramsPtr);
HANDLE_WARNING_RESOURCE(
WarningType::InvalidExtractedData, parent, this, rawDataIndex,
"TextureAnimationParams entry has empty type (6), but params pointer is "
"not NULL",
StringHelper::Sprintf("Params read { 0x%02X, 0x%02X, 0x%08X } .",
entry.segment, (int)entry.type, entry.paramsPtr));
return;
default:
// Because GCC is worried this could happen

View file

@ -6,6 +6,7 @@
#include "Utils/BitConverter.h"
#include "Utils/File.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZFile.h"
REGISTER_ZFILENODE(Vector, ZVector);
@ -86,20 +87,18 @@ std::string ZVector::GetSourceTypeName() const
return "Vec3i";
else
{
std::string output = StringHelper::Sprintf(
"Encountered unsupported vector type: %d dimensions, %s type", dimensions,
std::string msgHeader = StringHelper::Sprintf(
"encountered unsupported vector type: %d dimensions, %s type", dimensions,
ZScalar::MapScalarTypeToOutputType(scalarType).c_str());
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG)
printf("%s\n", output.c_str());
throw std::runtime_error(output);
HANDLE_ERROR_RESOURCE(WarningType::NotImplemented, parent, this, rawDataIndex, msgHeader,
"");
}
}
std::string ZVector::GetBodySourceCode() const
{
std::string body;
std::string body = "";
for (size_t i = 0; i < scalars.size(); i++)
{

View file

@ -1,6 +1,6 @@
#pragma once
#include <stdint.h>
#include <cstdint>
#include <string>
#include <vector>
#include "ZResource.h"

View file

@ -1,6 +1,6 @@
#pragma once
#include <stdint.h>
#include <cstdint>
#include <string>
#include <vector>
#include "ZResource.h"

View file

View file

@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="libpng" version="1.6.28.1" targetFramework="native" />
<package id="libpng.redist" version="1.6.28.1" targetFramework="native" />
<package id="libpng.static" version="1.6.37" targetFramework="native" />
<package id="YY.NuGet.Import.Helper" version="1.0.0.4" targetFramework="native" />
<package id="zlib" version="1.2.8.8" targetFramework="native" />
<package id="zlib.static" version="1.2.5" targetFramework="native" />
<package id="zlib.v120.windesktop.msvcstl.dyn.rt-dyn" version="1.2.8.8" targetFramework="native" />
<package id="zlib.v140.windesktop.msvcstl.dyn.rt-dyn" version="1.2.8.8" targetFramework="native" />
</packages>