diff --git a/src/config.h b/src/config.h index 07af8f7555..c031310b6d 100644 --- a/src/config.h +++ b/src/config.h @@ -327,6 +327,5 @@ bool config_find_or_browse_install_directory(); void title_sequences_set_default(); void title_sequences_load_presets(); -void title_sequence_save_preset_script(int preset); #endif diff --git a/src/core/Zip.cpp b/src/core/Zip.cpp index d6ddec99ed..b2c48ca8c1 100644 --- a/src/core/Zip.cpp +++ b/src/core/Zip.cpp @@ -21,17 +21,26 @@ class ZipArchive : public IZipArchive { private: - zip_t * _zip; + zip_t * _zip; + ZIP_ACCESS _access; public: - ZipArchive(const utf8 * path) + ZipArchive(const utf8 * path, ZIP_ACCESS access) { + int zipOpenMode = ZIP_RDONLY; + if (access == ZIP_ACCESS_WRITE) + { + zipOpenMode = ZIP_CREATE; + } + int error; - _zip = zip_open(path, ZIP_RDONLY, &error); + _zip = zip_open(path, zipOpenMode, &error); if (_zip == nullptr) { throw IOException("Unable to open zip file."); } + + _access = access; } ~ZipArchive() override @@ -89,21 +98,36 @@ public: if (outSize != nullptr) *outSize = dataSize; return data; } + + void SetFileData(const utf8 * path, void * data, size_t dataSize) override + { + zip_source_t * source = zip_source_buffer(_zip, data, dataSize, 0); + sint64 index = zip_name_locate(_zip, path, 0); + if (index == -1) + { + zip_add(_zip, path, source); + } + else + { + zip_replace(_zip, index, source); + } + zip_source_free(source); + } }; namespace Zip { - IZipArchive * Open(const utf8 * path) + IZipArchive * Open(const utf8 * path, ZIP_ACCESS access) { - return new ZipArchive(path); + return new ZipArchive(path, access); } - IZipArchive * TryOpen(const utf8 * path) + IZipArchive * TryOpen(const utf8 * path, ZIP_ACCESS access) { IZipArchive * result = nullptr; try { - result = new ZipArchive(path); + result = new ZipArchive(path, access); } catch (Exception) { diff --git a/src/core/Zip.h b/src/core/Zip.h index 3bec4f6f88..db89785215 100644 --- a/src/core/Zip.h +++ b/src/core/Zip.h @@ -29,10 +29,18 @@ interface IZipArchive virtual const utf8 * GetFileName(size_t index) const abstract; virtual const uint64 GetFileSize(size_t index) const abstract; virtual void * GetFileData(const utf8 * path, size_t * outSize) const abstract; + + virtual void SetFileData(const utf8 * path, void * data, size_t dataSize) abstract; +}; + +enum ZIP_ACCESS +{ + ZIP_ACCESS_READ, + ZIP_ACCESS_WRITE, }; namespace Zip { - IZipArchive * Open(const utf8 * path); - IZipArchive * TryOpen(const utf8 * path); + IZipArchive * Open(const utf8 * path, ZIP_ACCESS zipAccess); + IZipArchive * TryOpen(const utf8 * path, ZIP_ACCESS zipAccess); } diff --git a/src/title/TitleSequence.cpp b/src/title/TitleSequence.cpp index 00c4c4b7c3..e569496136 100644 --- a/src/title/TitleSequence.cpp +++ b/src/title/TitleSequence.cpp @@ -26,6 +26,7 @@ #include "../core/Memory.hpp" #include "../core/Path.hpp" #include "../core/String.hpp" +#include "../core/StringBuilder.hpp" #include "../core/Zip.h" #include "TitleSequence.h" @@ -34,6 +35,7 @@ static std::vector GetSaves(IZipArchive * zip); static std::vector LegacyScriptRead(utf8 * script, size_t scriptLength, std::vector saves); static void LegacyScriptGetLine(SDL_RWops * file, char * parts); static void * ReadScriptFile(const utf8 * path, size_t * outSize); +static utf8 * LegacyScriptWrite(TitleSequence * seq); extern "C" { @@ -47,7 +49,7 @@ extern "C" const utf8 * ext = Path::GetExtension(path); if (String::Equals(ext, TITLE_SEQUENCE_EXTENSION)) { - IZipArchive * zip = Zip::TryOpen(path); + IZipArchive * zip = Zip::TryOpen(path, ZIP_ACCESS_READ); if (zip == nullptr) { Console::Error::WriteLine("Unable to open '%s'", path); @@ -119,7 +121,7 @@ extern "C" const utf8 * filename = seq->Saves[index]; if (seq->IsZip) { - IZipArchive * zip = Zip::TryOpen(seq->Path); + IZipArchive * zip = Zip::TryOpen(seq->Path, ZIP_ACCESS_READ); if (zip != nullptr) { handle = Memory::Allocate(); @@ -153,6 +155,38 @@ extern "C" Memory::Free(handle); } } + + bool TileSequenceSave(TitleSequence * seq) + { + bool success = false; + utf8 * script = LegacyScriptWrite(seq); + if (seq->IsZip) + { + IZipArchive * zip = Zip::TryOpen(seq->Path, ZIP_ACCESS_WRITE); + zip->SetFileData("script.txt", script, String::SizeOf(script)); + delete zip; + success = true; + } + else + { + utf8 scriptPath[260]; + String::Set(scriptPath, sizeof(scriptPath), seq->Path); + Path::Append(scriptPath, sizeof(scriptPath), "script.txt"); + + try + { + auto fs = FileStream(scriptPath, FILE_MODE_WRITE); + fs.Write(script, String::SizeOf(script)); + success = true; + } + catch (Exception) + { + } + } + + Memory::Free(script); + return success; + } } static std::vector GetSaves(const utf8 * directory) @@ -353,59 +387,53 @@ static void * ReadScriptFile(const utf8 * path, size_t * outSize) return buffer; } -/* -void title_sequence_save_preset_script(int preset) +static utf8 * LegacyScriptWrite(TitleSequence * seq) { - utf8 path[MAX_PATH]; - SDL_RWops *file; - int i; + utf8 buffer[128]; + auto sb = StringBuilder(128); - - platform_get_user_directory(path, "title sequences", sizeof(path)); - safe_strcat_path(path, gConfigTitleSequences.presets[preset].name, MAX_PATH); - safe_strcat_path(path, "script.txt", MAX_PATH); - - file = SDL_RWFromFile(path, "wb"); - if (file == NULL) { - log_error("Unable to write to script file."); - return; - } - - for (i = 0; i < gConfigTitleSequences.presets[preset].num_commands; i++) { - title_command *command = &gConfigTitleSequences.presets[preset].commands[i]; - switch (command->command) { + for (size_t i = 0; i < seq->NumCommands; i++) + { + const TitleCommand * command = &seq->Commands[i]; + switch (command->Type) { case TITLE_SCRIPT_LOAD: - if (command->saveIndex == 0xFF) - rwopsprintf(file, "LOAD "); - else - rwopsprintf(file, "LOAD %s", gConfigTitleSequences.presets[preset].saves[command->saveIndex]); + if (command->SaveIndex == 0xFF) + { + sb.Append("LOAD "); + } else + { + sb.Append("LOAD "); + sb.Append(seq->Saves[command->SaveIndex]); + } break; case TITLE_SCRIPT_LOCATION: - rwopsprintf(file, "LOCATION %i %i", command->x, command->y); + String::Format(buffer, sizeof(buffer), "LOCATION %u %u", command->X, command->Y); + sb.Append(buffer); break; case TITLE_SCRIPT_ROTATE: - rwopsprintf(file, "ROTATE %i", command->rotations); + String::Format(buffer, sizeof(buffer), "ROTATE %u", command->Rotations); + sb.Append(buffer); break; case TITLE_SCRIPT_ZOOM: - rwopsprintf(file, "ZOOM %i", command->zoom); + String::Format(buffer, sizeof(buffer), "ZOOM %u", command->Zoom); + sb.Append(buffer); break; case TITLE_SCRIPT_SPEED: - rwopsprintf(file, "SPEED %i", command->speed); + String::Format(buffer, sizeof(buffer), "SPEED %u", command->Speed); + sb.Append(buffer); break; case TITLE_SCRIPT_WAIT: - rwopsprintf(file, "WAIT %i", command->seconds); - rwopswritenewline(file); - break; + String::Format(buffer, sizeof(buffer), "WAIT %u", command->Seconds); + sb.Append(buffer); case TITLE_SCRIPT_RESTART: - rwopsprintf(file, "RESTART"); + sb.Append("RESTART"); break; case TITLE_SCRIPT_END: - rwopsprintf(file, "END"); - break; + sb.Append("END"); } - rwopswritenewline(file); + sb.Append("\n"); } - SDL_RWclose(file); + utf8 * result = sb.StealString(); + return result; } -*/ diff --git a/src/title/TitleSequence.h b/src/title/TitleSequence.h index b2843ba278..72f017b981 100644 --- a/src/title/TitleSequence.h +++ b/src/title/TitleSequence.h @@ -89,6 +89,7 @@ extern "C" TitleSequenceParkHandle * TitleSequenceGetParkHandle(TitleSequence * seq, size_t index); void TitleSequenceCloseParkHandle(TitleSequenceParkHandle * handle); + bool TileSequenceSave(TitleSequence * seq); #ifdef __cplusplus } #endif