Fix add park to sequence

This commit is contained in:
Ted John 2016-12-05 03:30:25 +00:00
parent 55fc9c8a4a
commit 5443ff61cc
9 changed files with 219 additions and 1 deletions

View File

@ -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" />

44
src/core/File.cpp Normal file
View File

@ -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;
}
}

24
src/core/File.h Normal file
View File

@ -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);
}

View File

@ -116,4 +116,5 @@ class IOException : public Exception
{
public:
IOException(const char * message) : Exception(message) { }
IOException(const std::string &message) : Exception(message) { }
};

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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()