1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-17 03:53:07 +01:00

Reinstate support for title sequence folders

This commit is contained in:
Ted John
2016-11-13 13:15:01 +00:00
parent bf34920a0b
commit 52ffd5b521
8 changed files with 151 additions and 34 deletions

View File

@@ -124,6 +124,12 @@ public:
return _currentPath;
}
const utf8 * GetPathRelative() const override
{
// +1 to remove the path separator
return _currentPath + String::SizeOf(_rootPath) + 1;
}
void Reset() override
{
_started = false;
@@ -155,6 +161,7 @@ public:
utf8 childPath[MAX_PATH];
String::Set(childPath, sizeof(childPath), state->Path.c_str());
Path::Append(childPath, sizeof(childPath), child->Name.c_str());
PushState(childPath);
}
else if (PatternMatch(child->Name.c_str()))

View File

@@ -31,6 +31,7 @@ interface IFileScanner
virtual const FileInfo * GetFileInfo() const abstract;
virtual const utf8 * GetPath() const abstract;
virtual const utf8 * GetPathRelative() const abstract;
virtual void Reset() abstract;
virtual bool Next() abstract;

View File

@@ -34,6 +34,16 @@ namespace Path
return safe_strcat_path(buffer, src, bufferSize);
}
utf8 * GetDirectory(const utf8 * path)
{
size_t maxSize = String::SizeOf(path) + 1;
utf8 * result = Memory::Allocate<utf8>(maxSize);
GetDirectory(result, maxSize, path);
size_t reducedSize = String::SizeOf(path) + 1;
result = Memory::Reallocate(result, reducedSize);
return result;
}
utf8 * GetDirectory(utf8 * buffer, size_t bufferSize, const utf8 * path)
{
size_t lastPathSepIndex = String::LastIndexOf(path, *PATH_SEPARATOR);

View File

@@ -24,6 +24,7 @@ extern "C"
namespace Path
{
utf8 * Append(utf8 * buffer, size_t bufferSize, const utf8 * src);
utf8 * GetDirectory(const utf8 * path);
utf8 * GetDirectory(utf8 * buffer, size_t bufferSize, const utf8 * path);
const utf8 * GetFileName(const utf8 * path);
utf8 * GetFileNameWithoutExtension(const utf8 * path);

View File

@@ -20,6 +20,8 @@
#include <vector>
#include "../core/Collections.hpp"
#include "../core/Console.hpp"
#include "../core/FileScanner.h"
#include "../core/FileStream.hpp"
#include "../core/Guard.hpp"
#include "../core/Math.hpp"
#include "../core/Memory.hpp"
@@ -27,34 +29,61 @@
#include "../core/String.hpp"
#include "TitleSequence.h"
static std::vector<utf8 *> GetSaves(const utf8 * path);
static std::vector<utf8 *> GetSaves(zip_t * zip);
static std::vector<TitleCommand> LegacyScriptRead(utf8 * script, size_t scriptLength, std::vector<utf8 *> saves);
static void LegacyScriptGetLine(SDL_RWops * file, char * parts);
static void * ReadScriptFile(const utf8 * path, size_t * outSize);
static void * GetZipFileData(zip_t * zip, const char * name, size_t * outSize);
extern "C"
{
TitleSequence * LoadTitleSequence(const utf8 * path)
{
int error;
zip_t * zip = zip_open(path, ZIP_RDONLY, &error);
if (zip == nullptr)
{
Console::Error::WriteLine("Unable to open '%s'", path);
return nullptr;
}
size_t scriptLength;
char * script = (char *)GetZipFileData(zip, "script.txt", &scriptLength);
if (script == nullptr)
{
Console::Error::WriteLine("Unable to open script.txt in '%s'", path);
char * script;
std::vector<utf8 *> saves;
bool isZip;
zip_close(zip);
return nullptr;
const utf8 * ext = Path::GetExtension(path);
if (String::Equals(ext, TITLE_SEQUENCE_EXTENSION))
{
int error;
zip_t * zip = zip_open(path, ZIP_RDONLY, &error);
if (zip == nullptr)
{
Console::Error::WriteLine("Unable to open '%s'", path);
return nullptr;
}
script = (char *)GetZipFileData(zip, "script.txt", &scriptLength);
if (script == nullptr)
{
Console::Error::WriteLine("Unable to open script.txt in '%s'", path);
zip_close(zip);
return nullptr;
}
saves = GetSaves(zip);
isZip = true;
}
else
{
utf8 scriptPath[260];
String::Set(scriptPath, sizeof(scriptPath), path);
Path::Append(scriptPath, sizeof(scriptPath), "script.txt");
script = (char *)ReadScriptFile(scriptPath, &scriptLength);
if (script == nullptr)
{
Console::Error::WriteLine("Unable to open '%s'", scriptPath);
return nullptr;
}
saves = GetSaves(path);
isZip = false;
}
std::vector<utf8 *> saves = GetSaves(zip);
std::vector<TitleCommand> commands = LegacyScriptRead(script, scriptLength, saves);
TitleSequence * seq = Memory::Allocate<TitleSequence>();
@@ -64,6 +93,7 @@ extern "C"
seq->Saves = Collections::ToArray(saves);
seq->NumCommands = commands.size();
seq->Commands = Collections::ToArray(commands);
seq->IsZip = isZip;
return seq;
}
@@ -85,18 +115,30 @@ extern "C"
TitleSequenceParkHandle * TitleSequenceGetParkHandle(TitleSequence * seq, size_t index)
{
TitleSequenceParkHandle * handle = nullptr;
int error;
zip_t * zip = zip_open(seq->Path, ZIP_RDONLY, &error);
if (zip != nullptr)
if (index <= seq->NumSaves)
{
if (index <= seq->NumSaves)
const utf8 * filename = seq->Saves[index];
if (seq->IsZip)
{
utf8 * filename = seq->Saves[index];
int error;
zip_t * zip = zip_open(seq->Path, ZIP_RDONLY, &error);
if (zip != nullptr)
{
handle = Memory::Allocate<TitleSequenceParkHandle>();
handle->Data = GetZipFileData(zip, filename, &handle->DataSize);
handle->RWOps = SDL_RWFromMem(handle->Data, (int)handle->DataSize);
handle->IsScenario = String::Equals(Path::GetExtension(filename), ".sc6", true);
}
}
else
{
utf8 absolutePath[260];
String::Set(absolutePath, sizeof(absolutePath), seq->Path);
Path::Append(absolutePath, sizeof(absolutePath), filename);
handle = Memory::Allocate<TitleSequenceParkHandle>();
handle->Data = GetZipFileData(zip, filename, &handle->DataSize);
handle->RWOps = SDL_RWFromMem(handle->Data, (int)handle->DataSize);
handle->Data = nullptr;
handle->RWOps = SDL_RWFromFile(absolutePath, "rb");
handle->IsScenario = String::Equals(Path::GetExtension(filename), ".sc6", true);
}
}
@@ -105,12 +147,32 @@ extern "C"
void TitleSequenceCloseParkHandle(TitleSequenceParkHandle * handle)
{
SDL_RWclose(handle->RWOps);
Memory::Free(handle->Data);
Memory::Free(handle);
if (handle != nullptr)
{
SDL_RWclose(handle->RWOps);
Memory::Free(handle->Data);
Memory::Free(handle);
}
}
}
static std::vector<utf8 *> GetSaves(const utf8 * directory)
{
std::vector<utf8 *> saves;
utf8 pattern[260];
String::Set(pattern, sizeof(pattern), directory);
Path::Append(pattern, sizeof(pattern), "*.sc6;*.sv6");
IFileScanner * scanner = Path::ScanDirectory(pattern, true);
while (scanner->Next())
{
const utf8 * path = scanner->GetPathRelative();
saves.push_back(String::Duplicate(path));
}
return saves;
}
static std::vector<utf8 *> GetSaves(zip_t * zip)
{
std::vector<utf8 *> saves;
@@ -270,6 +332,28 @@ static void LegacyScriptGetLine(SDL_RWops * file, char * parts)
}
}
static void * ReadScriptFile(const utf8 * path, size_t * outSize)
{
void * buffer = nullptr;
size_t size = 0;
try
{
auto fs = FileStream(path, FILE_MODE_OPEN);
size = (size_t)fs.GetLength();
buffer = Memory::Allocate<void>(size);
fs.Read(buffer, size);
}
catch (Exception)
{
Memory::Free(buffer);
buffer = nullptr;
size = 0;
}
*outSize = size;
return buffer;
}
static void * GetZipFileData(zip_t * zip, const char * name, size_t * outSize)
{
void * data = nullptr;

View File

@@ -47,6 +47,8 @@ typedef struct TitleSequence
size_t NumSaves;
utf8 * * Saves;
bool IsZip;
} TitleSequence;
typedef struct TitleSequenceParkHandle
@@ -74,6 +76,10 @@ enum TITLE_SCRIPT
TITLE_SCRIPT_LOADRCT1,
};
#ifdef __cplusplus
constexpr const utf8 * TITLE_SEQUENCE_EXTENSION = ".parkseq";
#endif
#ifdef __cplusplus
extern "C"
{

View File

@@ -50,7 +50,7 @@ namespace TitleSequenceManager
std::vector<TitleSequenceManagerItem> _items;
static void Scan(const utf8 * directory);
static std::string GetNameFromSequencePath(const utf8 * path);
static std::string GetNameFromSequencePath(const std::string &path);
static void GetDataSequencesPath(utf8 * buffer, size_t bufferSize);
static void GetUserSequencesPath(utf8 * buffer, size_t bufferSize);
@@ -64,9 +64,9 @@ namespace TitleSequenceManager
return &_items[i];
}
static const uint16 GetPredefinedIndex(const utf8 * path)
static const uint16 GetPredefinedIndex(const std::string &path)
{
const utf8 * filename = Path::GetFileName(path);
const utf8 * filename = Path::GetFileName(path.c_str());
for (uint16 i = 0; i < Util::CountOf(PredefinedSequences); i++)
{
if (String::Equals(filename, PredefinedSequences[i].Filename, true))
@@ -111,16 +111,22 @@ namespace TitleSequenceManager
{
utf8 pattern[MAX_PATH];
String::Set(pattern, sizeof(pattern), directory);
Path::Append(pattern, sizeof(pattern), "*.parkseq");
Path::Append(pattern, sizeof(pattern), "script.txt;*.parkseq");
IFileScanner * fileScanner = Path::ScanDirectory(pattern, true);
while (fileScanner->Next())
{
const utf8 * path = fileScanner->GetPath();
std::string path = std::string(fileScanner->GetPath());
bool isZip = true;
if (String::Equals(Path::GetExtension(path.c_str()), ".txt", true))
{
path = std::string(Path::GetDirectory(path.c_str()));
isZip = false;
}
TitleSequenceManagerItem item;
item.PredefinedIndex = GetPredefinedIndex(path);
item.Path = std::string(path);
item.Path = path;
if (item.PredefinedIndex != PREDEFINED_INDEX_CUSTOM)
{
rct_string_id stringId = PredefinedSequences[item.PredefinedIndex].StringId;
@@ -130,14 +136,15 @@ namespace TitleSequenceManager
{
item.Name = GetNameFromSequencePath(path);
}
item.IsZip = isZip;
_items.push_back(item);
}
delete fileScanner;
}
static std::string GetNameFromSequencePath(const utf8 * path)
static std::string GetNameFromSequencePath(const std::string &path)
{
utf8 * name = Path::GetFileNameWithoutExtension(path);
utf8 * name = Path::GetFileNameWithoutExtension(path.c_str());
std::string result = std::string(name);
Memory::Free(name);
return result;

View File

@@ -27,6 +27,7 @@ struct TitleSequenceManagerItem
std::string Name;
std::string Path;
uint16 PredefinedIndex;
bool IsZip;
};
namespace TitleSequenceManager