tools/eupak: rename "pmdl" in eupak create to europa-prerelease

This more accurately reflects that it was used during development; art was probably the earliest part of the game to be finished, therefore there are lots of leftovers of older formats. Henceforth why the game can parse them.
This commit is contained in:
Lily Tsuru 2025-01-16 01:41:05 -05:00
parent ecca00a708
commit 4c2bda9fbf
2 changed files with 40 additions and 42 deletions

View file

@ -83,8 +83,7 @@ namespace eupak::tasks {
};
std::optional<estructs::PakVersion> ParsePakVersion(const std::string& str) {
// FIXME: PMDL should be "starfighter-prerelease"
if(str == "pmdl") {
if(str == "europa-prerelease") {
return estructs::PakVersion::Ver3;
} else if(str == "starfighter") {
return estructs::PakVersion::Ver4;
@ -107,7 +106,7 @@ namespace eupak::tasks {
parser.add_argument("-V", "--archive-version")
.default_value("starfighter")
.help(R"(Output archive version. Either "pmdl", "starfighter" or "jedistarfighter".)")
.help(R"(Output archive version. Either "europa-prerelease", "starfighter" or "jedistarfighter".)")
.metavar("VERSION");
parser.add_argument("-s", "--sector-aligned")
@ -124,9 +123,17 @@ namespace eupak::tasks {
.default_value(false)
.implicit_value(true);
// FIXME: At some point for accurate rebuilds we should also accept a JSON manifest file
// that contains: Package version, sector alignment, package build time, order of all files (as original) and their modtime, so on.
// Then a user can just do `eupak create --manifest manifest.json` and it'll all be figured out
// FIXME: At some point for bit-accurate rebuilds we should also accept a JSON manifest file
// that contains:
// - Package version,
// - sector alignment (for v5),
// - package build time,
// - data order of all files
// - TOC order of all files
// - file TOC data (modtime, TOC index, so on)
// Then a user can just do `eupak create --manifest manifest.json` and it'll all be done for them
//
// `eupak extract` should optionally generate this manifest for the user
// (I have not dreamt up the schema for this yet and this relies on other FIXMEs being done so this will have to wait.)
// clang-format on
@ -141,11 +148,9 @@ namespace eupak::tasks {
}
int CreateTask::Parse() {
auto& args = currentArgs;
args.verbose = parser.get<bool>("--verbose");
args.inputDirectory = fs::path(parser.get("--directory"));
args.outputFile = fs::path(parser.get("output"));
currentArgs.verbose = parser.get<bool>("--verbose");
currentArgs.inputDirectory = fs::path(parser.get("--directory"));
currentArgs.outputFile = fs::path(parser.get("output"));
if(parser.is_used("--archive-version")) {
const auto& versionStr = parser.get("--archive-version");
@ -157,18 +162,18 @@ namespace eupak::tasks {
return 1;
}
} else {
args.pakVersion = estructs::PakVersion::Ver4;
currentArgs.pakVersion = estructs::PakVersion::Ver4;
}
args.sectorAligned = parser.get<bool>("--sector-aligned");
currentArgs.sectorAligned = parser.get<bool>("--sector-aligned");
if(args.sectorAligned && args.pakVersion != estructs::PakVersion::Ver5) {
if(currentArgs.sectorAligned && currentArgs.pakVersion != estructs::PakVersion::Ver5) {
std::cout << "Error: --sector-aligned is only valid for creating a package with \"-V jedistarfighter\".\n"
<< parser;
return 1;
}
if(!eupak::fs::is_directory(args.inputDirectory)) {
if(!eupak::fs::is_directory(currentArgs.inputDirectory)) {
std::cout << "Error: Provided input isn't a directory\n"
<< parser;
return 1;
@ -178,22 +183,19 @@ namespace eupak::tasks {
}
int CreateTask::Run() {
// we should not be modifying arguments past this point
const auto& args = currentArgs;
auto currFile = 0;
auto fileCount = 0;
// Count how many files we're gonna add to the archive
for(auto& ent : fs::recursive_directory_iterator(args.inputDirectory)) {
for(auto& ent : fs::recursive_directory_iterator(currentArgs.inputDirectory)) {
if(ent.is_directory())
continue;
fileCount++;
}
std::cout << "Going to write " << fileCount << " files into " << args.outputFile << '\n';
std::cout << "Going to write " << fileCount << " files into " << currentArgs.outputFile << '\n';
if(args.sectorAligned) {
if(currentArgs.sectorAligned) {
std::cout << "Writing a sector aligned package\n";
}
@ -216,11 +218,11 @@ namespace eupak::tasks {
std::vector<eio::pak::Writer::FlattenedType> files;
files.reserve(fileCount);
for(auto& ent : fs::recursive_directory_iterator(args.inputDirectory)) {
for(auto& ent : fs::recursive_directory_iterator(currentArgs.inputDirectory)) {
if(ent.is_directory())
continue;
auto relativePathName = fs::relative(ent.path(), args.inputDirectory).string();
auto relativePathName = fs::relative(ent.path(), currentArgs.inputDirectory).string();
auto lastModified = fs::last_write_time(ent.path());
// Convert to Windows path separator always (that's what the game wants, after all)
@ -233,7 +235,7 @@ namespace eupak::tasks {
eio::pak::File file;
eio::pak::FileData pakData = eio::pak::FileData::InitAsPath(ent.path());
file.InitAs(args.pakVersion, args.sectorAligned);
file.InitAs(currentArgs.pakVersion, currentArgs.sectorAligned);
// Add data
file.SetData(std::move(pakData));
@ -253,21 +255,21 @@ namespace eupak::tasks {
indicators::show_console_cursor(true);
std::ofstream ofs(args.outputFile.string(), std::ofstream::binary);
std::ofstream ofs(currentArgs.outputFile.string(), std::ofstream::binary);
if(!ofs) {
std::cout << "Error: Couldn't open " << args.outputFile << " for writing\n";
std::cout << "Error: Couldn't open " << currentArgs.outputFile << " for writing\n";
return 1;
}
CreateArchiveReportSink reportSink(fileCount);
eio::pak::Writer writer(args.pakVersion);
eio::pak::Writer writer(currentArgs.pakVersion);
using enum eio::pak::Writer::SectorAlignment;
eio::pak::Writer::SectorAlignment alignment = DoNotAlign;
if(args.sectorAligned)
if(currentArgs.sectorAligned)
alignment = Align;
writer.Write(ofs, std::move(files), reportSink, alignment);

View file

@ -44,14 +44,12 @@ namespace eupak::tasks {
}
int InfoTask::Parse() {
auto& args = currentArgs;
try {
args.verbose = parser.get<bool>("--verbose");
args.inputPath = eupak::fs::path(parser.get("input"));
currentArgs.verbose = parser.get<bool>("--verbose");
currentArgs.inputPath = eupak::fs::path(parser.get("input"));
if(fs::is_directory(args.inputPath)) {
std::cout << "Error: " << args.inputPath << " appears to be a directory, not a file.\n";
if(fs::is_directory(currentArgs.inputPath)) {
std::cout << "Error: " << currentArgs.inputPath << " appears to be a directory, not a file.\n";
return 1;
}
@ -67,12 +65,10 @@ namespace eupak::tasks {
}
int InfoTask::Run() {
const auto& args = currentArgs;
std::ifstream ifs(args.inputPath.string(), std::ifstream::binary);
std::ifstream ifs(currentArgs.inputPath.string(), std::ifstream::binary);
if(!ifs) {
std::cout << "Error: Could not open file " << args.inputPath << ".\n";
std::cout << "Error: Could not open file " << currentArgs.inputPath << ".\n";
return 1;
}
@ -81,7 +77,7 @@ namespace eupak::tasks {
reader.ReadHeaderAndTOC();
if(reader.Invalid()) {
std::cout << "Error: Invalid PAK/PMDL file " << args.inputPath << ".\n";
std::cout << "Error: Invalid PAK/PMDL file " << currentArgs.inputPath << ".\n";
return 1;
}
@ -90,13 +86,13 @@ namespace eupak::tasks {
// This is the best other than just duplicating the body for each pak version.. :(
if constexpr(std::decay_t<decltype(header)>::VERSION == estructs::PakVersion::Ver3)
version = "Version 3 (PMDL)";
version = "Version 3 (Starfighter/Europa pre-release, May-July 2000?)";
else if constexpr(std::decay_t<decltype(header)>::VERSION == estructs::PakVersion::Ver4)
version = "Version 4 (Starfighter)";
else if constexpr(std::decay_t<decltype(header)>::VERSION == estructs::PakVersion::Ver5)
version = "Version 5 (Jedi Starfighter)";
std::cout << "Archive " << args.inputPath << ":\n";
std::cout << "Archive " << currentArgs.inputPath << ":\n";
std::cout << " Created: " << FormatUnixTimestamp(header.creationUnixTime, DATE_FORMAT) << '\n';
std::cout << " Version: " << version << '\n';
std::cout << " Size: " << FormatUnit(header.tocOffset + header.tocSize) << '\n';
@ -107,7 +103,7 @@ namespace eupak::tasks {
// Print a detailed file list if verbose.
for(auto& [filename, file] : reader.GetFiles()) {
if(args.verbose) {
if(currentArgs.verbose) {
std::cout << "File \"" << filename << "\":\n";
file.VisitTocEntry([&](auto& tocEntry) {
std::cout << " Created: " << FormatUnixTimestamp(tocEntry.creationUnixTime, DATE_FORMAT) << '\n';