diff --git a/src/core/Zip.cpp b/src/core/Zip.cpp index 5a9d88b3e8..7ff0103b1c 100644 --- a/src/core/Zip.cpp +++ b/src/core/Zip.cpp @@ -112,6 +112,12 @@ public: zip_replace(_zip, index, source); } } + + void DeleteFile(const utf8 * path) override + { + uint64 index = zip_name_locate(_zip, path, 0); + zip_delete(_zip, index); + } }; namespace Zip diff --git a/src/core/Zip.h b/src/core/Zip.h index af62cd4f4a..77f1cb1685 100644 --- a/src/core/Zip.h +++ b/src/core/Zip.h @@ -37,7 +37,9 @@ interface IZipArchive * the zip archive has been disposed. * @param dataSize The size of the data in bytes. */ - virtual void SetFileData(const utf8 * path, void * data, size_t dataSize) abstract; + virtual void SetFileData(const utf8 * path, void * data, size_t dataSize) abstract; + + virtual void DeleteFile(const utf8 * path) abstract; }; enum ZIP_ACCESS diff --git a/src/title/TitleSequence.cpp b/src/title/TitleSequence.cpp index a49e5179dc..7aaddf4db8 100644 --- a/src/title/TitleSequence.cpp +++ b/src/title/TitleSequence.cpp @@ -36,6 +36,9 @@ extern "C" #include "../platform/platform.h" } +// defines DeleteFile, which conflicts with IZipArchive call +#undef DeleteFile + static std::vector GetSaves(const utf8 * path); static std::vector GetSaves(IZipArchive * zip); static std::vector LegacyScriptRead(utf8 * script, size_t scriptLength, std::vector saves); @@ -84,7 +87,7 @@ extern "C" } else { - utf8 scriptPath[260]; + utf8 scriptPath[MAX_PATH]; String::Set(scriptPath, sizeof(scriptPath), path); Path::Append(scriptPath, sizeof(scriptPath), "script.txt"); script = (char *)ReadScriptFile(scriptPath, &scriptLength); @@ -146,7 +149,7 @@ extern "C" } else { - utf8 absolutePath[260]; + utf8 absolutePath[MAX_PATH]; String::Set(absolutePath, sizeof(absolutePath), seq->Path); Path::Append(absolutePath, sizeof(absolutePath), filename); @@ -182,7 +185,7 @@ extern "C" } else { - utf8 scriptPath[260]; + utf8 scriptPath[MAX_PATH]; String::Set(scriptPath, sizeof(scriptPath), seq->Path); Path::Append(scriptPath, sizeof(scriptPath), "script.txt"); @@ -203,18 +206,6 @@ extern "C" bool TileSequenceAddPark(TitleSequence * seq, const utf8 * path, const utf8 * name) { - // Determine new path (relative for zip) - utf8 dstPath[260]; - if (seq->IsZip) - { - String::Set(dstPath, sizeof(dstPath), name); - } - else - { - String::Set(dstPath, sizeof(dstPath), seq->Path); - Path::Append(dstPath, sizeof(dstPath), name); - } - // Get new save index size_t index = SIZE_MAX; for (size_t i = 0; i < seq->NumSaves; i++) @@ -232,7 +223,7 @@ extern "C" index = seq->NumSaves; seq->NumSaves++; } - seq->Saves[index] = String::Duplicate(dstPath); + seq->Saves[index] = String::Duplicate(name); if (seq->IsZip) { @@ -247,7 +238,7 @@ extern "C" Console::Error::WriteLine("Unable to open '%s'", seq->Path); return false; } - zip->SetFileData(dstPath, fdata, fsize); + zip->SetFileData(name, fdata, fsize); delete zip; Memory::Free(fdata); } @@ -258,6 +249,10 @@ extern "C" } else { + // Determine destination path + utf8 dstPath[MAX_PATH]; + String::Set(dstPath, sizeof(dstPath), seq->Path); + Path::Append(dstPath, sizeof(dstPath), name); if (!platform_file_copy(path, dstPath, true)) { Console::Error::WriteLine("Unable to copy '%s' to '%s'", path, dstPath); @@ -266,13 +261,53 @@ extern "C" } return true; } + + bool TitleSequenceRemovePark(TitleSequence * seq, size_t index) + { + Guard::Assert(seq->NumSaves > index, GUARD_LINE); + + // Delete park file + utf8 * relativePath = seq->Saves[index]; + if (seq->IsZip) + { + IZipArchive * zip = Zip::TryOpen(seq->Path, ZIP_ACCESS_WRITE); + if (zip == nullptr) + { + Console::Error::WriteLine("Unable to open '%s'", seq->Path); + return false; + } + zip->DeleteFile(relativePath); + delete zip; + } + else + { + utf8 absolutePath[MAX_PATH]; + String::Set(absolutePath, sizeof(absolutePath), seq->Path); + Path::Append(absolutePath, sizeof(absolutePath), relativePath); + if (!platform_file_delete(absolutePath)) + { + Console::Error::WriteLine("Unable to delete '%s'", absolutePath); + return false; + } + } + + // Remove from sequence + Memory::Free(relativePath); + for (size_t i = index; i < seq->NumSaves - 1; i++) + { + seq->Saves[i] = seq->Saves[i + 1]; + } + seq->NumSaves--; + + return true; + } } static std::vector GetSaves(const utf8 * directory) { std::vector saves; - utf8 pattern[260]; + utf8 pattern[MAX_PATH]; String::Set(pattern, sizeof(pattern), directory); Path::Append(pattern, sizeof(pattern), "*.sc6;*.sv6"); diff --git a/src/title/TitleSequence.h b/src/title/TitleSequence.h index a4466e4309..e92387906b 100644 --- a/src/title/TitleSequence.h +++ b/src/title/TitleSequence.h @@ -92,6 +92,7 @@ extern "C" void TitleSequenceCloseParkHandle(TitleSequenceParkHandle * handle); bool TileSequenceSave(TitleSequence * seq); bool TileSequenceAddPark(TitleSequence * seq, const utf8 * path, const utf8 * name); + bool TitleSequenceRemovePark(TitleSequence * seq, size_t index); bool TitleSequenceIsLoadCommand(const TitleCommand * command); #ifdef __cplusplus diff --git a/src/windows/title_editor.c b/src/windows/title_editor.c index 06d3a516dc..4ea4a74a40 100644 --- a/src/windows/title_editor.c +++ b/src/windows/title_editor.c @@ -342,11 +342,9 @@ static void window_title_editor_mouseup(rct_window *w, int widgetIndex) case WIDX_TITLE_EDITOR_REMOVE_SAVE: if (window_title_editor_check_can_edit()) { if (w->selected_list_item != -1) { - // title_sequence_remove_save(_selectedTitleSequence, w->selected_list_item); - if (w->selected_list_item > 0) { + TitleSequenceRemovePark(_editingTitleSequence, w->selected_list_item); + if (w->selected_list_item >= _editingTitleSequence->NumSaves) { w->selected_list_item--; - } else if (w->selected_list_item > (sint16)_editingTitleSequence->NumSaves) { - w->selected_list_item = (sint16)(_editingTitleSequence->NumSaves - 1); } } }