diff --git a/game/skeldal.c b/game/skeldal.c index a6cdd8e..88a67c1 100644 --- a/game/skeldal.c +++ b/game/skeldal.c @@ -911,6 +911,12 @@ void init_DDL_manager() { display_error("Can't open resource file (adv_patch): %s", ddlfile); abort(); } + const char *lang_fld = lang_get_folder(); + if (lang_fld) { + const char *gfx = build_pathname(2, lang_fld, "gfx.ddl"); + gfx = local_strdup(gfx); + add_patch_file(gfx); + } if (!add_patch_file(ddlfile)) { display_error("Can't open resource file (main): %s", ddlfile); abort(); diff --git a/tools/ddl_ar.cpp b/tools/ddl_ar.cpp index 6e01a37..4c23d3d 100644 --- a/tools/ddl_ar.cpp +++ b/tools/ddl_ar.cpp @@ -1,6 +1,10 @@ #include "ddl_ar.h" #include "ddl_ar_class.h" + +#include +#include #include +#include void show_licence_header() { @@ -20,11 +24,83 @@ void show_help() { std::puts("ddl_ar -h"); std::puts("ddl_ar -l"); std::puts("ddl_ar -x "); + std::puts("ddl_ar -n "); std::puts(""); std::puts("-h this help\n" "file.ddl input ddl file\n" "-l list of files\n" - "-x extract files\n"); + "-x extract files\n" + "-n pack directory to new file\n" + ); +} + +struct DirEntry { + std::filesystem::path path; + std::string name; + uint32_t size; + uint32_t offset; +}; + +void new_ddl(std::string ddl_file, std::string path) { + std::vector dir; + + std::filesystem::directory_iterator iter(path); + std::filesystem::directory_iterator end; + while (iter != end) { + const auto &entry = *iter; + if (entry.is_regular_file()) { + uint32_t sz = entry.file_size(); + std::string fname = entry.path().filename().string(); + if (fname.size() <= 12) { + std::transform(fname.begin(), fname.end(), fname.begin(),[](char c)->char{return std::toupper(c);}); + dir.push_back(DirEntry{entry.path(), fname, sz,0}); + } + } + ++iter; + + } + + if (dir.empty()) { + std::cerr << "No files found, nothing changed" << std::endl; + } + + std::size_t dataofs = 8 + dir.size()*(12+4); + + for (auto &x: dir) { + x.offset = dataofs; + dataofs+=4+x.size; + } + + uint32_t group = 0; + uint32_t group_offset = 8; + + std::ofstream f(ddl_file, std::ios::out|std::ios::trunc|std::ios::binary); + + f.write(reinterpret_cast(&group),4); + f.write(reinterpret_cast(&group_offset),4); + + for (const auto &x: dir) { + char n[13]; + std::strncpy(n,x.name.c_str(), 12); + n[12] = 0; + f.write(n,12); + f.write(reinterpret_cast(&x.offset),4); + } + for (const auto &x: dir) { + f.write(reinterpret_cast(&x.size),4); + std::ifstream in(x.path, std::ios::in|std::ios::binary); + char *buff = new char[x.size]; + if (!in) { + std::cerr << "Failed to open " << x.path << std::endl; + } else { + in.read(buff,x.size); + f.write(buff,x.size); + std::cout << "Added " << x.name << " from file " << x.path << std::endl; + } + delete [] buff; + } + + } int main(int argc, char **argv) { @@ -44,14 +120,23 @@ int main(int argc, char **argv) { return 1; } + std::string_view swch(argv[2]); + if (swch == "-n") { + if (argc <= 3) { + show_short_help(); + return 1; + } + new_ddl(std::string(ddl_file), argv[3]); + return 0; + } + + DDLArchive arch; if (!arch.open(ddl_file)) { std::cerr << "Failed to read ddl file: " << ddl_file; return 1; } - - std::string_view swch(argv[2]); if (swch == "-l") { for (const auto &x: arch.get_directory()) { std::puts(x.first.c_str()); diff --git a/tools/ddl_ar_class.cpp b/tools/ddl_ar_class.cpp index 9194c55..0142254 100644 --- a/tools/ddl_ar_class.cpp +++ b/tools/ddl_ar_class.cpp @@ -49,3 +49,5 @@ DDLArchive::Extracted DDLArchive::extract_file(std::ifstream &s, return {fname, true, std::move(data)}; } + + diff --git a/tools/ddl_ar_class.h b/tools/ddl_ar_class.h index 4d252f8..43a200e 100644 --- a/tools/ddl_ar_class.h +++ b/tools/ddl_ar_class.h @@ -37,6 +37,7 @@ public: } } + protected: std::filesystem::path _ar_file;