mirror of https://github.com/OpenRCT2/OpenRCT2.git
Fix add park to sequence
This commit is contained in:
parent
55fc9c8a4a
commit
5443ff61cc
|
@ -101,6 +101,7 @@
|
|||
<ClCompile Include="src\config.c" />
|
||||
<ClCompile Include="src\core\Console.cpp" />
|
||||
<ClCompile Include="src\core\Diagnostics.cpp" />
|
||||
<ClCompile Include="src\core\File.cpp" />
|
||||
<ClCompile Include="src\core\FileScanner.cpp" />
|
||||
<ClCompile Include="src\core\Guard.cpp" />
|
||||
<ClCompile Include="src\core\IStream.cpp" />
|
||||
|
@ -434,6 +435,7 @@
|
|||
<ClInclude Include="src\core\Console.hpp" />
|
||||
<ClInclude Include="src\core\Diagnostics.hpp" />
|
||||
<ClInclude Include="src\core\Exception.hpp" />
|
||||
<ClInclude Include="src\core\File.h" />
|
||||
<ClInclude Include="src\core\FileScanner.h" />
|
||||
<ClInclude Include="src\core\FileStream.hpp" />
|
||||
<ClInclude Include="src\core\Guard.hpp" />
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
|
||||
/*****************************************************************************
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
|
||||
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
|
||||
*
|
||||
* OpenRCT2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* A full copy of the GNU General Public License can be found in licence.txt
|
||||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Console.hpp"
|
||||
#include "File.h"
|
||||
#include "FileStream.hpp"
|
||||
#include "String.hpp"
|
||||
|
||||
namespace File
|
||||
{
|
||||
void * ReadAllBytes(const utf8 * path, size_t * length)
|
||||
{
|
||||
void * result = nullptr;
|
||||
|
||||
FileStream fs = FileStream(path, FILE_MODE_OPEN);
|
||||
uint64 fsize = fs.GetLength();
|
||||
if (fsize > SIZE_MAX)
|
||||
{
|
||||
std::string message = String::StdFormat("'%s' exceeds maximum length of %lld bytes.", SIZE_MAX);
|
||||
throw IOException(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = fs.ReadArray<uint8>(fsize);
|
||||
}
|
||||
*length = fsize;
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
|
||||
/*****************************************************************************
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
|
||||
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
|
||||
*
|
||||
* OpenRCT2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* A full copy of the GNU General Public License can be found in licence.txt
|
||||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../common.h"
|
||||
|
||||
namespace File
|
||||
{
|
||||
void * ReadAllBytes(const utf8 * path, size_t * length);
|
||||
}
|
|
@ -116,4 +116,5 @@ class IOException : public Exception
|
|||
{
|
||||
public:
|
||||
IOException(const char * message) : Exception(message) { }
|
||||
IOException(const std::string &message) : Exception(message) { }
|
||||
};
|
||||
|
|
|
@ -34,6 +34,15 @@ namespace String
|
|||
else return std::string(str);
|
||||
}
|
||||
|
||||
std::string StdFormat(const utf8 * format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
const utf8 * buffer = Format_VA(format, args);
|
||||
va_end(args);
|
||||
return ToStd(buffer);
|
||||
}
|
||||
|
||||
bool IsNullOrEmpty(const utf8 * str)
|
||||
{
|
||||
return str == nullptr || str[0] == '\0';
|
||||
|
@ -150,6 +159,68 @@ namespace String
|
|||
return buffer;
|
||||
}
|
||||
|
||||
utf8 * Format(const utf8 * format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
utf8 * result = Format_VA(format, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
utf8 * Format_VA(const utf8 * format, va_list args)
|
||||
{
|
||||
va_list args1, args2;
|
||||
va_copy(args1, args);
|
||||
va_copy(args2, args);
|
||||
|
||||
// Try to format to a initial buffer, enlarge if not big enough
|
||||
size_t bufferSize = 4096;
|
||||
utf8 * buffer = Memory::Allocate<utf8>(bufferSize);
|
||||
|
||||
// Start with initial buffer
|
||||
int len = vsnprintf(buffer, bufferSize, format, args);
|
||||
if (len < 0)
|
||||
{
|
||||
Memory::Free(buffer);
|
||||
va_end(args1);
|
||||
va_end(args2);
|
||||
|
||||
// An error occured...
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t requiredSize = (size_t)len + 1;
|
||||
if (requiredSize > bufferSize)
|
||||
{
|
||||
// Try again with bigger buffer
|
||||
buffer = Memory::Reallocate<utf8>(buffer, bufferSize);
|
||||
int len = vsnprintf(buffer, bufferSize, format, args);
|
||||
if (len < 0)
|
||||
{
|
||||
Memory::Free(buffer);
|
||||
va_end(args1);
|
||||
va_end(args2);
|
||||
|
||||
// An error occured...
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reduce buffer size to only what was required
|
||||
bufferSize = requiredSize;
|
||||
buffer = Memory::Reallocate<utf8>(buffer, bufferSize);
|
||||
}
|
||||
|
||||
// Ensure buffer is terminated
|
||||
buffer[bufferSize - 1] = '\0';
|
||||
|
||||
va_end(args1);
|
||||
va_end(args2);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
utf8 * AppendFormat(utf8 * buffer, size_t bufferSize, const utf8 * format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace String
|
|||
constexpr const utf8 * Empty = "";
|
||||
|
||||
std::string ToStd(const utf8 * str);
|
||||
std::string StdFormat(const utf8 * format, ...);
|
||||
|
||||
bool IsNullOrEmpty(const utf8 * str);
|
||||
bool Equals(const utf8 * a, const utf8 * b, bool ignoreCase = false);
|
||||
|
@ -44,6 +45,8 @@ namespace String
|
|||
utf8 * Set(utf8 * buffer, size_t bufferSize, const utf8 * src, size_t srcSize);
|
||||
utf8 * Append(utf8 * buffer, size_t bufferSize, const utf8 * src);
|
||||
utf8 * Format(utf8 * buffer, size_t bufferSize, const utf8 * format, ...);
|
||||
utf8 * Format(const utf8 * format, ...);
|
||||
utf8 * Format_VA(const utf8 * format, va_list args);
|
||||
utf8 * AppendFormat(utf8 * buffer, size_t bufferSize, const utf8 * format, ...);
|
||||
utf8 * Duplicate(const utf8 * src);
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "../common.h"
|
||||
#include "../core/Collections.hpp"
|
||||
#include "../core/Console.hpp"
|
||||
#include "../core/File.h"
|
||||
#include "../core/FileScanner.h"
|
||||
#include "../core/FileStream.hpp"
|
||||
#include "../core/Guard.hpp"
|
||||
|
@ -30,6 +31,11 @@
|
|||
#include "../core/Zip.h"
|
||||
#include "TitleSequence.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../platform/platform.h"
|
||||
}
|
||||
|
||||
static std::vector<utf8 *> GetSaves(const utf8 * path);
|
||||
static std::vector<utf8 *> GetSaves(IZipArchive * zip);
|
||||
static std::vector<TitleCommand> LegacyScriptRead(utf8 * script, size_t scriptLength, std::vector<utf8 *> saves);
|
||||
|
@ -194,6 +200,72 @@ extern "C"
|
|||
Memory::Free(script);
|
||||
return success;
|
||||
}
|
||||
|
||||
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++)
|
||||
{
|
||||
if (String::Equals(seq->Saves[i], path, true))
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index == SIZE_MAX)
|
||||
{
|
||||
seq->Saves = Memory::ReallocateArray(seq->Saves, seq->NumSaves + 1);
|
||||
Guard::Assert(seq->Saves != nullptr, GUARD_LINE);
|
||||
index = seq->NumSaves;
|
||||
seq->NumSaves++;
|
||||
}
|
||||
seq->Saves[index] = String::Duplicate(dstPath);
|
||||
|
||||
if (seq->IsZip)
|
||||
{
|
||||
try
|
||||
{
|
||||
size_t fsize;
|
||||
void * fdata = File::ReadAllBytes(path, &fsize);
|
||||
|
||||
IZipArchive * zip = Zip::TryOpen(seq->Path, ZIP_ACCESS_WRITE);
|
||||
if (zip == nullptr)
|
||||
{
|
||||
Console::Error::WriteLine("Unable to open '%s'", seq->Path);
|
||||
return false;
|
||||
}
|
||||
zip->SetFileData(dstPath, fdata, fsize);
|
||||
delete zip;
|
||||
Memory::Free(fdata);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console::Error::WriteLine(ex.GetMessage());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!platform_file_copy(path, dstPath, true))
|
||||
{
|
||||
Console::Error::WriteLine("Unable to copy '%s' to '%s'", path, dstPath);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static std::vector<utf8 *> GetSaves(const utf8 * directory)
|
||||
|
|
|
@ -91,6 +91,7 @@ extern "C"
|
|||
TitleSequenceParkHandle * TitleSequenceGetParkHandle(TitleSequence * seq, size_t index);
|
||||
void TitleSequenceCloseParkHandle(TitleSequenceParkHandle * handle);
|
||||
bool TileSequenceSave(TitleSequence * seq);
|
||||
bool TileSequenceAddPark(TitleSequence * seq, const utf8 * path, const utf8 * name);
|
||||
|
||||
bool TitleSequenceIsLoadCommand(const TitleCommand * command);
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -1022,7 +1022,7 @@ static void window_title_editor_add_park_callback(int result, const utf8 * path)
|
|||
return;
|
||||
}
|
||||
|
||||
// title_sequence_add_save(gCurrentTitleSequence, path, newName);
|
||||
TileSequenceAddPark(_editingTitleSequence, path, filename);
|
||||
}
|
||||
|
||||
static void window_title_editor_save_sequence()
|
||||
|
|
Loading…
Reference in New Issue