From dfbf8f15256d929d354b034a9a0db481078b5642 Mon Sep 17 00:00:00 2001 From: KiritoDv Date: Sat, 7 Oct 2023 21:07:04 -0600 Subject: [PATCH] Added a command to pack an mpq from a directory --- src/Companion.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ src/Companion.h | 2 ++ src/main.cpp | 27 +++++++++++++++++++++++---- src/storm/SWrapper.cpp | 2 +- src/storm/SWrapper.h | 4 ++-- 5 files changed, 69 insertions(+), 7 deletions(-) diff --git a/src/Companion.cpp b/src/Companion.cpp index 88f8542..1b98d2d 100644 --- a/src/Companion.cpp +++ b/src/Companion.cpp @@ -166,3 +166,44 @@ RawFactory *Companion::GetFactory(const std::string &extension) { return this->gFactories[extension]; } + +void Companion::Pack(const std::string& folder, const std::string& output) { + + spdlog::set_level(spdlog::level::debug); + spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] %v"); + + SPDLOG_INFO("------------------------------------------------"); + + SPDLOG_INFO("Starting CubeOS..."); + SPDLOG_INFO("Scanning {}", folder); + + auto start = duration_cast(system_clock::now().time_since_epoch()); + std::unordered_map> files; + + for (const auto & entry : fs::recursive_directory_iterator(folder)){ + if(entry.is_directory()) continue; + std::ifstream input( entry.path(), std::ios::binary ); + auto data = std::vector( std::istreambuf_iterator( input ), {} ); + input.close(); + files[entry.path().string()] = data; + } + + auto wrapper = SWrapper(output); + + for(auto& [path, data] : files){ + std::string normalized = path; + std::replace(normalized.begin(), normalized.end(), '\\', '/'); + // Remove parent folder + normalized = normalized.substr(folder.length() + 1); + wrapper.CreateFile(normalized, data); + SPDLOG_INFO("> Added {}", normalized); + } + + auto end = duration_cast(system_clock::now().time_since_epoch()); + SPDLOG_INFO("Done! Took {}ms", end.count() - start.count()); + SPDLOG_INFO("Exported to {}", output); + spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] %v"); + SPDLOG_INFO("------------------------------------------------"); + + wrapper.Close(); +} \ No newline at end of file diff --git a/src/Companion.h b/src/Companion.h index c46c21c..8d131fb 100644 --- a/src/Companion.h +++ b/src/Companion.h @@ -15,6 +15,8 @@ public: void Init(); void Process(); N64::Cartridge* GetCartridge() { return this->cartridge; } + + static void Pack(const std::string& folder, const std::string& output); private: std::filesystem::path gRomPath; std::vector gRomData; diff --git a/src/main.cpp b/src/main.cpp index 3149b66..9001fcb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,11 +5,32 @@ #ifdef STANDALONE Companion* Companion::Instance; +void BindOTRMode(CLI::App& app){ + auto otr = app.add_subcommand("otr", "Extracts the rom to a folder"); + std::string filename; + otr->add_option("rom", filename, "sm64 us rom")->required()->check(CLI::ExistingFile); + otr->parse_complete_callback([&]() { + auto instance = Companion::Instance = new Companion(filename); + instance->Init(); + }); +} + +void BindPackMode(CLI::App& app){ + auto pack = app.add_subcommand("pack", "Packs the rom from a folder"); + std::string folder; + pack->add_option("folder", folder, "Folder")->required()->check(CLI::ExistingDirectory); + std::string output; + pack->add_option("output", output, "MPQ Output")->required(); + pack->parse_complete_callback([&]() { + Companion::Pack(folder, output); + }); +} + int main(int argc, char *argv[]) { CLI::App app{"CubeOS - Rom extractor"}; - std::string filename; - app.add_option("path", filename, "sm64 us rom")->required()->check(CLI::ExistingFile); + BindOTRMode(app); + BindPackMode(app); try { app.parse(argc, argv); @@ -17,8 +38,6 @@ int main(int argc, char *argv[]) { return app.exit(e); } - Companion::Instance = new Companion(filename); - Companion::Instance->Init(); return 0; } #endif \ No newline at end of file diff --git a/src/storm/SWrapper.cpp b/src/storm/SWrapper.cpp index 2e3b109..d17042f 100644 --- a/src/storm/SWrapper.cpp +++ b/src/storm/SWrapper.cpp @@ -16,7 +16,7 @@ SWrapper::SWrapper(const std::string& path) { } } -bool SWrapper::CreateFile(std::string path, std::vector data) { +bool SWrapper::CreateFile(const std::string& path, std::vector data) { HANDLE hFile; #ifdef _WIN32 SYSTEMTIME sysTime; diff --git a/src/storm/SWrapper.h b/src/storm/SWrapper.h index b7e50ec..e713c92 100644 --- a/src/storm/SWrapper.h +++ b/src/storm/SWrapper.h @@ -9,8 +9,8 @@ public: SWrapper(const std::string& path); std::vector ReadFile(std::string path); - bool CreateFile(std::string path, std::vector data); + bool CreateFile(const std::string& path, std::vector data); void Close(); private: - HANDLE hMpq; + HANDLE hMpq{}; }; \ No newline at end of file