tools: Introduce new "eutex" tool

This is effectively currently the same as "texdump", but will allow provisions for expanding to creating new textures/such. A good thing.
This commit is contained in:
Lily Tsuru 2025-01-17 18:36:58 -05:00
parent 8d5a8d4adc
commit 3968cde61e
6 changed files with 214 additions and 2 deletions

View file

@ -6,7 +6,11 @@
# SPDX-License-Identifier: MIT # SPDX-License-Identifier: MIT
# #
# Toollib
add_subdirectory(toollib)
add_subdirectory(eupak) add_subdirectory(eupak)
add_subdirectory(eutex)
add_executable(texdump texdump.cpp) add_executable(texdump texdump.cpp)
target_link_libraries(texdump PUBLIC target_link_libraries(texdump PUBLIC
@ -22,8 +26,6 @@ target_link_libraries(jsfscramble PUBLIC
) )
europa_target(jsfscramble) europa_target(jsfscramble)
# Toollib
add_subdirectory(toollib)
# Temporary test target. # Temporary test target.
add_executable(toollib_test add_executable(toollib_test

View file

@ -0,0 +1,29 @@
#
# EuropaTools
#
# (C) 2021-2025 modeco80 <lily.modeco80@protonmail.ch>
#
# SPDX-License-Identifier: MIT
#
add_executable(eutex
main.cpp
# commands
DumpCommand.cpp
)
target_link_libraries(eutex PUBLIC
europa
toollib
lodepng
)
configure_file(EutexConfig.hpp.in
${CMAKE_CURRENT_BINARY_DIR}/EutexConfig.hpp
)
target_include_directories(eutex PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(eutex PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
europa_target(eutex)

View file

@ -0,0 +1,29 @@
//
// EuropaTools
//
// (C) 2021-2025 modeco80 <lily.modeco80@protonmail.ch>
//
// SPDX-License-Identifier: MIT
//
#pragma once
#include <filesystem>
namespace europa {
namespace io {}
namespace util {}
namespace structs {}
} // namespace europa
namespace eutex {
namespace fs = std::filesystem;
// Shorthands for libeuropa components
// that we might want to reference
namespace eio = europa::io;
namespace eutil = europa::util;
namespace estructs = europa::structs;
} // namespace eutex

View file

@ -0,0 +1,108 @@
//
// EuropaTools
//
// (C) 2021-2025 modeco80 <lily.modeco80@protonmail.ch>
//
// SPDX-License-Identifier: MIT
//
#include <lodepng.h>
#include <argparse/argparse.hpp>
#include <CommonDefs.hpp>
#include <europa/io/yatf/Reader.hpp>
#include <europa/util/ImageSurface.hpp>
#include <filesystem>
#include <fstream>
#include <toollib/ToolCommand.hpp>
namespace eutex {
namespace yatf = eio::yatf;
struct DumpCommand : tool::IToolCommand {
DumpCommand()
: parser("dump", "", argparse::default_arguments::help) {
// clang-format off
parser
.add_description("Dumps a .tex (YATF) texture file to PNG");
parser
.add_argument("-o", "--output-file")
.default_value("")
.metavar("OUTPUT")
.help("Directory to extract to.");
parser
.add_argument("input")
.help("Input .tex file")
.metavar("TEX_FILE");
// clang-format on
}
void Init(argparse::ArgumentParser& parentParser) override {
parentParser.add_subparser(parser);
}
bool ShouldRun(argparse::ArgumentParser& parentParser) const override {
return parentParser.is_subcommand_used("dump");
}
int Parse() override {
inputTexPath = fs::path(parser.get("input"));
if(parser.is_used("--output-file")) {
outputPngPath = fs::path(parser.get("--output-file"));
} else {
// To maintain workflow compatibility with the older `texdump` utility,
// if an output file is not specified, we just replace extension
outputPngPath = fs::path(parser.get("input")).replace_extension("png");
}
return 0;
}
int Run() override {
if(!fs::is_regular_file(inputTexPath)) {
std::cout << "Invalid file " << inputTexPath << "\n";
return 1;
}
std::ifstream ifs(inputTexPath.string(), std::ifstream::binary);
yatf::Reader reader(ifs);
europa::structs::YatfHeader yatfHeader;
eutil::ImageSurface surface;
std::cout << "Opening \"" << inputTexPath << "\"\n";
if(!reader.ReadImage(yatfHeader, surface)) {
std::cout << "Invalid YATF file \"" << inputTexPath << "\"\n";
return 1;
}
auto size = surface.GetSize();
if(auto res = lodepng::encode(outputPngPath.string(), reinterpret_cast<std::uint8_t*>(surface.GetBuffer()), size.width, size.height, LCT_RGBA, 8); res == 0) {
std::cout << "Wrote image to " << outputPngPath << '\n';
return 0;
} else {
std::cout << "Error encoding PNG: " << lodepng_error_text(res) << "\n";
return 1;
}
return 0;
}
private:
argparse::ArgumentParser parser;
fs::path inputTexPath;
fs::path outputPngPath;
};
TOOLLIB_REGISTER_TOOLCOMMAND("eutex_dump", DumpCommand);
} // namespace eutex

View file

@ -0,0 +1,13 @@
//
// EuropaTools
//
// (C) 2021-2025 modeco80 <lily.modeco80@protonmail.ch>
//
// SPDX-License-Identifier: MIT
//
#define EUTEX_VERSION_STR "@PROJECT_VERSION@"
#define EUTEX_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
#define EUTEX_VERSION_MINOR @PROJECT_VERSION_MINOR@
#define EUTEX_VERSION_PATCH @PROJECT_VERSION_PATCH@

31
src/tools/eutex/main.cpp Normal file
View file

@ -0,0 +1,31 @@
//
// EuropaTools
//
// (C) 2021-2025 modeco80 <lily.modeco80@protonmail.ch>
//
// SPDX-License-Identifier: MIT
//
#include <EutexConfig.hpp>
#include <toollib/ToolCommand.hpp>
#include <toollib/ToolMain.hpp>
int main(int argc, char** argv) {
const tool::ToolInfo info {
.name = "eutex",
.version = EUTEX_VERSION_STR,
.description = "Europa Tex (YATF) Tool v" EUTEX_VERSION_STR
};
auto toolCommands = std::vector {
tool::ToolCommandFactory::CreateNamed("eutex_dump")
};
// clang-format off
return tool::ToolMain(info, {
.toolCommands = toolCommands,
.argc = argc,
.argv = argv
});
// clang-format on
}