mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #7066 from IntelOrca/refactor/memory-operations
Refactor memory operations 1
This commit is contained in:
commit
8f1100c986
|
@ -14,14 +14,15 @@
|
|||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <openrct2/common.h>
|
||||
#include <SDL.h>
|
||||
#include <speex/speex_resampler.h>
|
||||
#include <list>
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/core/Guard.hpp>
|
||||
#include <openrct2/core/Math.hpp>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include <openrct2/core/Util.hpp>
|
||||
#include <openrct2/audio/audio.h>
|
||||
#include <openrct2/audio/AudioChannel.h>
|
||||
|
@ -37,38 +38,6 @@
|
|||
|
||||
namespace OpenRCT2 { namespace Audio
|
||||
{
|
||||
struct Buffer
|
||||
{
|
||||
private:
|
||||
void * _data = nullptr;
|
||||
size_t _capacity = 0;
|
||||
|
||||
public:
|
||||
void * GetData() const { return _data; }
|
||||
void * GetData() { return _data; }
|
||||
size_t GetCapacity() const { return _capacity; }
|
||||
|
||||
~Buffer()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
|
||||
void Free()
|
||||
{
|
||||
SafeFree(_data);
|
||||
_capacity = 0;
|
||||
}
|
||||
|
||||
void EnsureCapacity(size_t capacity)
|
||||
{
|
||||
if (_capacity < capacity)
|
||||
{
|
||||
_capacity = capacity;
|
||||
_data = Memory::Reallocate(_data, capacity);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class AudioMixerImpl final : public IAudioMixer
|
||||
{
|
||||
private:
|
||||
|
@ -86,9 +55,9 @@ namespace OpenRCT2 { namespace Audio
|
|||
IAudioSource * _css1Sources[SOUND_MAXID] = { nullptr };
|
||||
IAudioSource * _musicSources[PATH_ID_END] = { nullptr };
|
||||
|
||||
Buffer _channelBuffer;
|
||||
Buffer _convertBuffer;
|
||||
Buffer _effectBuffer;
|
||||
std::vector<uint8> _channelBuffer;
|
||||
std::vector<uint8> _convertBuffer;
|
||||
std::vector<uint8> _effectBuffer;
|
||||
|
||||
public:
|
||||
AudioMixerImpl()
|
||||
|
@ -159,9 +128,12 @@ namespace OpenRCT2 { namespace Audio
|
|||
}
|
||||
|
||||
// Free buffers
|
||||
_channelBuffer.Free();
|
||||
_convertBuffer.Free();
|
||||
_effectBuffer.Free();
|
||||
_channelBuffer.clear();
|
||||
_channelBuffer.shrink_to_fit();
|
||||
_convertBuffer.clear();
|
||||
_convertBuffer.shrink_to_fit();
|
||||
_effectBuffer.clear();
|
||||
_effectBuffer.shrink_to_fit();
|
||||
}
|
||||
|
||||
void Lock() override
|
||||
|
@ -252,7 +224,7 @@ namespace OpenRCT2 { namespace Audio
|
|||
UpdateAdjustedSound();
|
||||
|
||||
// Zero the output buffer
|
||||
Memory::Set(dst, 0, length);
|
||||
std::fill_n(dst, length, 0);
|
||||
|
||||
// Mix channels onto output buffer
|
||||
auto it = _channels.begin();
|
||||
|
@ -318,15 +290,15 @@ namespace OpenRCT2 { namespace Audio
|
|||
// Read raw PCM from channel
|
||||
sint32 readSamples = (sint32)(numSamples * rate);
|
||||
size_t readLength = (size_t)(readSamples / cvt.len_ratio) * byteRate;
|
||||
_channelBuffer.EnsureCapacity(readLength);
|
||||
size_t bytesRead = channel->Read(_channelBuffer.GetData(), readLength);
|
||||
_channelBuffer.resize(readLength);
|
||||
size_t bytesRead = channel->Read(_channelBuffer.data(), readLength);
|
||||
|
||||
// Convert data to required format if necessary
|
||||
void * buffer = nullptr;
|
||||
size_t bufferLen = 0;
|
||||
if (mustConvert)
|
||||
{
|
||||
if (Convert(&cvt, _channelBuffer.GetData(), bytesRead))
|
||||
if (Convert(&cvt, _channelBuffer.data(), bytesRead))
|
||||
{
|
||||
buffer = cvt.buf;
|
||||
bufferLen = cvt.len_cvt;
|
||||
|
@ -338,7 +310,7 @@ namespace OpenRCT2 { namespace Audio
|
|||
}
|
||||
else
|
||||
{
|
||||
buffer = _channelBuffer.GetData();
|
||||
buffer = _channelBuffer.data();
|
||||
bufferLen = bytesRead;
|
||||
}
|
||||
|
||||
|
@ -352,9 +324,9 @@ namespace OpenRCT2 { namespace Audio
|
|||
inRate = _format.freq;
|
||||
outRate = _format.freq * (1 / rate);
|
||||
}
|
||||
_effectBuffer.EnsureCapacity(length);
|
||||
_effectBuffer.resize(length);
|
||||
bufferLen = ApplyResample(channel, buffer, (sint32)(bufferLen / byteRate), numSamples, inRate, outRate);
|
||||
buffer = _effectBuffer.GetData();
|
||||
buffer = _effectBuffer.data();
|
||||
}
|
||||
|
||||
// Apply panning and volume
|
||||
|
@ -391,7 +363,7 @@ namespace OpenRCT2 { namespace Audio
|
|||
resampler,
|
||||
(const spx_int16_t *)srcBuffer,
|
||||
&inLen,
|
||||
(spx_int16_t *)_effectBuffer.GetData(),
|
||||
(spx_int16_t *)_effectBuffer.data(),
|
||||
&outLen);
|
||||
|
||||
return outLen * byteRate;
|
||||
|
@ -523,11 +495,11 @@ namespace OpenRCT2 { namespace Audio
|
|||
if (len != 0 && cvt->len_mult != 0)
|
||||
{
|
||||
size_t reqConvertBufferCapacity = len * cvt->len_mult;
|
||||
_convertBuffer.EnsureCapacity(reqConvertBufferCapacity);
|
||||
Memory::Copy(_convertBuffer.GetData(), src, len);
|
||||
_convertBuffer.resize(reqConvertBufferCapacity);
|
||||
std::copy_n((const uint8 *)src, len, _convertBuffer.data());
|
||||
|
||||
cvt->len = (sint32)len;
|
||||
cvt->buf = (uint8 *)_convertBuffer.GetData();
|
||||
cvt->buf = (uint8 *)_convertBuffer.data();
|
||||
if (SDL_ConvertAudio(cvt) >= 0)
|
||||
{
|
||||
result = true;
|
||||
|
|
|
@ -14,10 +14,11 @@
|
|||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <openrct2/common.h>
|
||||
#include <SDL.h>
|
||||
#include <openrct2/core/Math.hpp>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include <openrct2/audio/AudioMixer.h>
|
||||
#include <openrct2/audio/AudioSource.h>
|
||||
#include "AudioContext.h"
|
||||
|
@ -32,10 +33,15 @@ namespace OpenRCT2 { namespace Audio
|
|||
class MemoryAudioSource final : public ISDLAudioSource
|
||||
{
|
||||
private:
|
||||
AudioFormat _format = { 0 };
|
||||
uint8 * _data = nullptr;
|
||||
size_t _length = 0;
|
||||
bool _isSDLWav = false;
|
||||
AudioFormat _format = { 0 };
|
||||
std::vector<uint8> _data;
|
||||
uint8 * _dataSDL = nullptr;
|
||||
size_t _length = 0;
|
||||
|
||||
const uint8 * GetData()
|
||||
{
|
||||
return _dataSDL != nullptr ? _dataSDL : _data.data();
|
||||
}
|
||||
|
||||
public:
|
||||
~MemoryAudioSource()
|
||||
|
@ -59,7 +65,12 @@ namespace OpenRCT2 { namespace Audio
|
|||
if (offset < _length)
|
||||
{
|
||||
bytesToRead = (size_t)Math::Min<uint64>(len, _length - offset);
|
||||
Memory::Copy<void>(dst, _data + offset, bytesToRead);
|
||||
|
||||
auto src = GetData();
|
||||
if (src != nullptr)
|
||||
{
|
||||
std::copy_n(src + offset, bytesToRead, (uint8 *)dst);
|
||||
}
|
||||
}
|
||||
return bytesToRead;
|
||||
}
|
||||
|
@ -76,14 +87,13 @@ namespace OpenRCT2 { namespace Audio
|
|||
{
|
||||
SDL_AudioSpec audiospec = { 0 };
|
||||
uint32 audioLen;
|
||||
SDL_AudioSpec * spec = SDL_LoadWAV_RW(rw, false, &audiospec, &_data, &audioLen);
|
||||
SDL_AudioSpec * spec = SDL_LoadWAV_RW(rw, false, &audiospec, &_dataSDL, &audioLen);
|
||||
if (spec != nullptr)
|
||||
{
|
||||
_format.freq = spec->freq;
|
||||
_format.format = spec->format;
|
||||
_format.channels = spec->channels;
|
||||
_length = audioLen;
|
||||
_isSDLWav = true;
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
|
@ -129,13 +139,13 @@ namespace OpenRCT2 { namespace Audio
|
|||
_format.format = AUDIO_S16LSB;
|
||||
_format.channels = waveFormat.channels;
|
||||
|
||||
_data = new (std::nothrow) uint8[_length];
|
||||
if (_data != nullptr)
|
||||
try
|
||||
{
|
||||
SDL_RWread(rw, _data, _length, 1);
|
||||
_data.resize(_length);
|
||||
SDL_RWread(rw, _data.data(), _length, 1);
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
catch (const std::bad_alloc &)
|
||||
{
|
||||
log_verbose("Unable to allocate data");
|
||||
}
|
||||
|
@ -156,21 +166,21 @@ namespace OpenRCT2 { namespace Audio
|
|||
SDL_AudioCVT cvt;
|
||||
if (SDL_BuildAudioCVT(&cvt, _format.format, _format.channels, _format.freq, format->format, format->channels, format->freq) >= 0)
|
||||
{
|
||||
auto src = GetData();
|
||||
auto cvtBuffer = std::vector<uint8>(_length * cvt.len_mult);
|
||||
std::copy_n(src, _length, cvtBuffer.data());
|
||||
cvt.len = (sint32)_length;
|
||||
cvt.buf = new uint8[cvt.len * cvt.len_mult];
|
||||
Memory::Copy(cvt.buf, _data, _length);
|
||||
cvt.buf = cvtBuffer.data();
|
||||
if (SDL_ConvertAudio(&cvt) >= 0)
|
||||
{
|
||||
cvtBuffer.resize(cvt.len_cvt);
|
||||
|
||||
Unload();
|
||||
_data = cvt.buf;
|
||||
_data = std::move(cvtBuffer);
|
||||
_length = cvt.len_cvt;
|
||||
_format = *format;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete[] cvt.buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -179,19 +189,14 @@ namespace OpenRCT2 { namespace Audio
|
|||
private:
|
||||
void Unload()
|
||||
{
|
||||
if (_data != nullptr)
|
||||
{
|
||||
if (_isSDLWav)
|
||||
{
|
||||
SDL_FreeWAV(_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete[] _data;
|
||||
}
|
||||
_data = nullptr;
|
||||
}
|
||||
_isSDLWav = false;
|
||||
// Free our data
|
||||
_data.clear();
|
||||
_data.shrink_to_fit();
|
||||
|
||||
// Free SDL2's data
|
||||
SDL_FreeWAV(_dataSDL);
|
||||
_dataSDL = nullptr;
|
||||
|
||||
_length = 0;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -14,18 +14,17 @@
|
|||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include <algorithm>
|
||||
#include <openrct2/common.h>
|
||||
#include <SDL.h>
|
||||
#include <openrct2/config/Config.h>
|
||||
#include <openrct2/core/Guard.hpp>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include <openrct2/drawing/IDrawingEngine.h>
|
||||
#include <openrct2/drawing/X8DrawingEngine.h>
|
||||
#include <openrct2/Game.h>
|
||||
#include <openrct2/ui/UiContext.h>
|
||||
#include "DrawingEngines.h"
|
||||
|
||||
#include <openrct2/Game.h>
|
||||
|
||||
using namespace OpenRCT2;
|
||||
using namespace OpenRCT2::Drawing;
|
||||
using namespace OpenRCT2::Ui;
|
||||
|
@ -121,7 +120,7 @@ private:
|
|||
}
|
||||
|
||||
// Copy pixels from the virtual screen buffer to the surface
|
||||
Memory::Copy<void>(_surface->pixels, _bits, _surface->pitch * _surface->h);
|
||||
std::copy_n(_bits, _surface->pitch * _surface->h, (uint8 *)_surface->pixels);
|
||||
|
||||
// Unlock the surface
|
||||
if (SDL_MUSTLOCK(_surface))
|
||||
|
|
|
@ -16,33 +16,29 @@
|
|||
|
||||
#ifndef DISABLE_OPENGL
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <unordered_map>
|
||||
#include <SDL.h>
|
||||
|
||||
#include <openrct2/config/Config.h>
|
||||
#include <openrct2/core/Console.hpp>
|
||||
#include <openrct2/core/Math.hpp>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include <openrct2/drawing/Drawing.h>
|
||||
#include <openrct2/drawing/IDrawingContext.h>
|
||||
#include <openrct2/drawing/IDrawingEngine.h>
|
||||
#include <openrct2/drawing/LightFX.h>
|
||||
#include <openrct2/drawing/Rain.h>
|
||||
#include <openrct2/interface/Screenshot.h>
|
||||
#include <openrct2/ui/UiContext.h>
|
||||
|
||||
#include <openrct2-ui/interface/Window.h>
|
||||
#include <openrct2/Intro.h>
|
||||
#include <openrct2/drawing/Drawing.h>
|
||||
#include <openrct2/drawing/LightFX.h>
|
||||
|
||||
#include <openrct2-ui/interface/Window.h>
|
||||
#include <openrct2/ui/UiContext.h>
|
||||
#include "../DrawingEngines.h"
|
||||
#include "GLSLTypes.h"
|
||||
#include "OpenGLAPI.h"
|
||||
#include "OpenGLFramebuffer.h"
|
||||
#include "ApplyPaletteShader.h"
|
||||
#include "DrawCommands.h"
|
||||
#include "DrawLineShader.h"
|
||||
#include "DrawRectShader.h"
|
||||
#include "GLSLTypes.h"
|
||||
#include "OpenGLAPI.h"
|
||||
#include "OpenGLFramebuffer.h"
|
||||
#include "SwapFramebuffer.h"
|
||||
#include "TextureCache.h"
|
||||
#include "TransparencyDepth.h"
|
||||
|
@ -346,27 +342,27 @@ private:
|
|||
uint8 * newBits = new uint8[newBitsSize];
|
||||
if (_bits == nullptr)
|
||||
{
|
||||
Memory::Set(newBits, 0, newBitsSize);
|
||||
std::fill_n(newBits, newBitsSize, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_pitch == pitch)
|
||||
{
|
||||
Memory::Copy(newBits, _bits, Math::Min(_bitsSize, newBitsSize));
|
||||
std::copy_n(_bits, std::min(_bitsSize, newBitsSize), newBits);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8 * src = _bits;
|
||||
uint8 * dst = newBits;
|
||||
|
||||
uint32 minWidth = Math::Min(_width, width);
|
||||
uint32 minHeight = Math::Min(_height, height);
|
||||
uint32 minWidth = std::min(_width, width);
|
||||
uint32 minHeight = std::min(_height, height);
|
||||
for (uint32 y = 0; y < minHeight; y++)
|
||||
{
|
||||
Memory::Copy(dst, src, minWidth);
|
||||
std::copy_n(src, minWidth, dst);
|
||||
if (pitch - minWidth > 0)
|
||||
{
|
||||
Memory::Set(dst + minWidth, 0, pitch - minWidth);
|
||||
std::fill_n(dst + minWidth, pitch - minWidth, 0);
|
||||
}
|
||||
src += _pitch;
|
||||
dst += pitch;
|
||||
|
@ -716,8 +712,8 @@ void OpenGLDrawingContext::DrawSpriteRawMasked(sint32 x, sint32 y, uint32 maskIm
|
|||
|
||||
sint32 drawOffsetX = g1ElementMask->x_offset;
|
||||
sint32 drawOffsetY = g1ElementMask->y_offset;
|
||||
sint32 drawWidth = Math::Min(g1ElementMask->width, g1ElementColour->width);
|
||||
sint32 drawHeight = Math::Min(g1ElementMask->height, g1ElementColour->height);
|
||||
sint32 drawWidth = std::min(g1ElementMask->width, g1ElementColour->width);
|
||||
sint32 drawHeight = std::min(g1ElementMask->height, g1ElementColour->height);
|
||||
|
||||
sint32 left = x + drawOffsetX;
|
||||
sint32 top = y + drawOffsetY;
|
||||
|
|
|
@ -16,9 +16,10 @@
|
|||
|
||||
#ifndef DISABLE_OPENGL
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <openrct2/common.h>
|
||||
#include <SDL_video.h>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include "OpenGLFramebuffer.h"
|
||||
|
||||
constexpr GLuint BACKBUFFER_ID = 0;
|
||||
|
@ -94,21 +95,20 @@ void OpenGLFramebuffer::GetPixels(rct_drawpixelinfo &dpi) const
|
|||
{
|
||||
assert(dpi.width == _width && dpi.height == _height);
|
||||
|
||||
uint8 * pixels = Memory::Allocate<uint8>(_width * _height);
|
||||
auto pixels = std::make_unique<uint8[]>(_width * _height);
|
||||
glBindTexture(GL_TEXTURE_2D, _texture);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, pixels);
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, pixels.get());
|
||||
|
||||
// Flip pixels vertically on copy
|
||||
uint8 * src = pixels + ((_height - 1) * _width);
|
||||
uint8 * src = pixels.get() + ((_height - 1) * _width);
|
||||
uint8 * dst = dpi.bits;
|
||||
for (sint32 y = 0; y < _height; y++)
|
||||
{
|
||||
Memory::Copy(dst, src, _width);
|
||||
std::copy_n(src, _width, dst);
|
||||
src -= _width;
|
||||
dst += dpi.width + dpi.pitch;
|
||||
}
|
||||
Memory::Free(pixels);
|
||||
}
|
||||
|
||||
void OpenGLFramebuffer::SwapColourBuffer(OpenGLFramebuffer &other)
|
||||
|
|
|
@ -16,29 +16,28 @@
|
|||
|
||||
#ifndef DISABLE_OPENGL
|
||||
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/core/Console.hpp>
|
||||
#include <openrct2/core/FileStream.hpp>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include <openrct2/core/Path.hpp>
|
||||
#include <openrct2/core/String.hpp>
|
||||
#include <openrct2/PlatformEnvironment.h>
|
||||
#include "OpenGLShaderProgram.h"
|
||||
|
||||
#include <openrct2/platform/platform.h>
|
||||
using namespace OpenRCT2;
|
||||
|
||||
OpenGLShader::OpenGLShader(const char * name, GLenum type)
|
||||
{
|
||||
_type = type;
|
||||
|
||||
utf8 path[MAX_PATH];
|
||||
GetPath(path, sizeof(path), name);
|
||||
char * sourceCode = ReadSourceCode(path);
|
||||
auto path = GetPath(name);
|
||||
auto sourceCode = ReadSourceCode(path);
|
||||
auto sourceCodeStr = sourceCode.c_str();
|
||||
|
||||
_id = glCreateShader(type);
|
||||
glShaderSource(_id, 1, (const GLchar**)&sourceCode, nullptr);
|
||||
glShaderSource(_id, 1, (const GLchar * *)&sourceCodeStr, nullptr);
|
||||
glCompileShader(_id);
|
||||
|
||||
Memory::Free(sourceCode);
|
||||
|
||||
GLint status;
|
||||
glGetShaderiv(_id, GL_COMPILE_STATUS, &status);
|
||||
if (status != GL_TRUE)
|
||||
|
@ -47,7 +46,7 @@ OpenGLShader::OpenGLShader(const char * name, GLenum type)
|
|||
glGetShaderInfoLog(_id, sizeof(buffer), nullptr, buffer);
|
||||
glDeleteShader(_id);
|
||||
|
||||
Console::Error::WriteLine("Error compiling %s", path);
|
||||
Console::Error::WriteLine("Error compiling %s", path.c_str());
|
||||
Console::Error::WriteLine(buffer);
|
||||
|
||||
throw std::runtime_error("Error compiling shader.");
|
||||
|
@ -64,22 +63,23 @@ GLuint OpenGLShader::GetShaderId()
|
|||
return _id;
|
||||
}
|
||||
|
||||
void OpenGLShader::GetPath(char * buffer, size_t bufferSize, const char * name)
|
||||
std::string OpenGLShader::GetPath(const std::string &name)
|
||||
{
|
||||
platform_get_openrct_data_path(buffer, bufferSize);
|
||||
Path::Append(buffer, bufferSize, "shaders");
|
||||
Path::Append(buffer, bufferSize, name);
|
||||
auto env = GetContext()->GetPlatformEnvironment();
|
||||
auto shadersPath = env->GetDirectoryPath(DIRBASE::OPENRCT2, DIRID::SHADER);
|
||||
auto path = Path::Combine(shadersPath, name);
|
||||
if (_type == GL_VERTEX_SHADER)
|
||||
{
|
||||
String::Append(buffer, bufferSize, ".vert");
|
||||
path += ".vert";
|
||||
}
|
||||
else
|
||||
{
|
||||
String::Append(buffer, bufferSize, ".frag");
|
||||
path += ".frag";
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
char * OpenGLShader::ReadSourceCode(const utf8 * path)
|
||||
std::string OpenGLShader::ReadSourceCode(const std::string &path)
|
||||
{
|
||||
auto fs = FileStream(path, FILE_MODE_OPEN);
|
||||
|
||||
|
@ -89,9 +89,8 @@ char * OpenGLShader::ReadSourceCode(const utf8 * path)
|
|||
throw IOException("Shader source too large.");
|
||||
}
|
||||
|
||||
utf8 * fileData = Memory::Allocate<utf8>((size_t)fileLength + 1);
|
||||
fs.Read(fileData, fileLength);
|
||||
fileData[fileLength] = '\0';
|
||||
auto fileData = std::string((size_t)fileLength + 1, '\0');
|
||||
fs.Read((void *)fileData.data(), fileLength);
|
||||
return fileData;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <openrct2/common.h>
|
||||
#include "OpenGLAPI.h"
|
||||
|
||||
|
@ -34,8 +35,8 @@ public:
|
|||
GLuint GetShaderId();
|
||||
|
||||
private:
|
||||
void GetPath(char * buffer, size_t bufferSize, const char * name);
|
||||
static char * ReadSourceCode(const utf8 * path);
|
||||
std::string GetPath(const std::string &name);
|
||||
static std::string ReadSourceCode(const std::string &path);
|
||||
};
|
||||
|
||||
class OpenGLShaderProgram
|
||||
|
|
|
@ -16,12 +16,11 @@
|
|||
|
||||
#ifndef DISABLE_OPENGL
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include "TextureCache.h"
|
||||
|
||||
#include <vector>
|
||||
#include <openrct2/drawing/Drawing.h>
|
||||
#include "TextureCache.h"
|
||||
|
||||
constexpr uint32 UNUSED_INDEX = 0xFFFFFFFF;
|
||||
|
||||
|
@ -95,7 +94,7 @@ BasicTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32 image, uint8 * palet
|
|||
{
|
||||
GlyphId glyphId;
|
||||
glyphId.Image = image;
|
||||
Memory::Copy<void>(&glyphId.Palette, palette, sizeof(glyphId.Palette));
|
||||
std::copy_n(palette, sizeof(glyphId.Palette), (uint8 *)&glyphId.Palette);
|
||||
|
||||
auto kvp = _glyphTextureMap.find(glyphId);
|
||||
if (kvp != _glyphTextureMap.end())
|
||||
|
@ -290,8 +289,8 @@ void TextureCache::FreeTextures()
|
|||
rct_drawpixelinfo TextureCache::CreateDPI(sint32 width, sint32 height)
|
||||
{
|
||||
size_t numPixels = width * height;
|
||||
uint8 * pixels8 = Memory::Allocate<uint8>(numPixels);
|
||||
Memory::Set(pixels8, 0, numPixels);
|
||||
auto pixels8 = new uint8[numPixels];
|
||||
std::fill_n(pixels8, numPixels, 0);
|
||||
|
||||
rct_drawpixelinfo dpi;
|
||||
dpi.bits = pixels8;
|
||||
|
@ -306,7 +305,7 @@ rct_drawpixelinfo TextureCache::CreateDPI(sint32 width, sint32 height)
|
|||
|
||||
void TextureCache::DeleteDPI(rct_drawpixelinfo dpi)
|
||||
{
|
||||
Memory::Free(dpi.bits);
|
||||
delete dpi.bits;
|
||||
}
|
||||
|
||||
GLuint TextureCache::GetAtlasesTexture()
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <openrct2/core/Console.hpp>
|
||||
#include <openrct2/core/File.h>
|
||||
#include <openrct2/core/FileStream.hpp>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include <openrct2/core/Path.hpp>
|
||||
#include <openrct2/core/String.hpp>
|
||||
#include <openrct2/PlatformEnvironment.h>
|
||||
|
|
|
@ -14,16 +14,20 @@
|
|||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/OpenRCT2.h>
|
||||
#include <openrct2/core/Math.hpp>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
#include <openrct2/core/String.hpp>
|
||||
#include <openrct2/localisation/Localisation.h>
|
||||
#include <openrct2/OpenRCT2.h>
|
||||
#include <openrct2/platform/platform.h>
|
||||
#include <openrct2/PlatformEnvironment.h>
|
||||
#include <openrct2/util/Util.h>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
enum {
|
||||
WIDX_BACKGROUND,
|
||||
|
@ -89,10 +93,8 @@ static rct_window_event_list window_changelog_events = {
|
|||
static bool window_changelog_read_file();
|
||||
static void window_changelog_dispose_file();
|
||||
|
||||
static char *_changelogText = nullptr;
|
||||
static size_t _changelogTextSize = 0;
|
||||
static char **_changelogLines = nullptr;
|
||||
static sint32 _changelogNumLines = 0;
|
||||
static std::string _changelogText;
|
||||
static std::vector<const char *> _changelogLines;
|
||||
static sint32 _changelogLongestLineWidth = 0;
|
||||
|
||||
rct_window * window_changelog_open()
|
||||
|
@ -164,7 +166,7 @@ static void window_changelog_resize(rct_window *w)
|
|||
static void window_changelog_scrollgetsize(rct_window *w, sint32 scrollIndex, sint32 *width, sint32 *height)
|
||||
{
|
||||
*width = _changelogLongestLineWidth + 4;
|
||||
*height = _changelogNumLines * 11;
|
||||
*height = (sint32)(_changelogLines.size() * 11);
|
||||
}
|
||||
|
||||
static void window_changelog_invalidate(rct_window *w)
|
||||
|
@ -192,73 +194,85 @@ static void window_changelog_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi,
|
|||
|
||||
sint32 x = 3;
|
||||
sint32 y = 3;
|
||||
for (sint32 i = 0; i < _changelogNumLines; i++) {
|
||||
gfx_draw_string(dpi, _changelogLines[i], w->colours[0], x, y);
|
||||
for (auto line : _changelogLines)
|
||||
{
|
||||
gfx_draw_string(dpi, (char *)line, w->colours[0], x, y);
|
||||
y += 11;
|
||||
}
|
||||
}
|
||||
|
||||
static std::string GetChangelogPath()
|
||||
{
|
||||
auto env = GetContext()->GetPlatformEnvironment();
|
||||
return env->GetFilePath(PATHID::CHANGELOG);
|
||||
}
|
||||
|
||||
static std::string GetChangelogText()
|
||||
{
|
||||
auto path = GetChangelogPath();
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
auto pathW = String::ToUtf16(path);
|
||||
auto fs = std::ifstream(pathW, std::ios::in);
|
||||
#else
|
||||
auto fs = std::ifstream(path, std::ios::in);
|
||||
#endif
|
||||
if (!fs.is_open())
|
||||
{
|
||||
throw std::runtime_error("Unable to open " + path);
|
||||
}
|
||||
return std::string((std::istreambuf_iterator<char>(fs)), std::istreambuf_iterator<char>());
|
||||
}
|
||||
|
||||
static bool window_changelog_read_file()
|
||||
{
|
||||
window_changelog_dispose_file();
|
||||
utf8 path[MAX_PATH];
|
||||
platform_get_changelog_path(path, sizeof(path));
|
||||
if (!readentirefile(path, (void**)&_changelogText, &_changelogTextSize)) {
|
||||
try
|
||||
{
|
||||
_changelogText = GetChangelogText();
|
||||
}
|
||||
catch (const std::bad_alloc &)
|
||||
{
|
||||
log_error("Unable to allocate memory for changelog.txt");
|
||||
return false;
|
||||
}
|
||||
catch (const std::exception &)
|
||||
{
|
||||
log_error("Unable to read changelog.txt");
|
||||
return false;
|
||||
}
|
||||
void* new_memory = realloc(_changelogText, _changelogTextSize + 1);
|
||||
if (new_memory == nullptr) {
|
||||
log_error("Failed to reallocate memory for changelog text");
|
||||
return false;
|
||||
}
|
||||
_changelogText = (char*)new_memory;
|
||||
_changelogText[_changelogTextSize++] = 0;
|
||||
|
||||
char *start = _changelogText;
|
||||
if (_changelogTextSize >= 3 && utf8_is_bom(_changelogText))
|
||||
// Non-const cast required until C++17 is enabled
|
||||
auto * start = (char *)_changelogText.data();
|
||||
if (_changelogText.size() >= 3 && utf8_is_bom(start))
|
||||
{
|
||||
start += 3;
|
||||
}
|
||||
|
||||
sint32 changelogLinesCapacity = 8;
|
||||
_changelogLines = Memory::Allocate<utf8*>(changelogLinesCapacity * sizeof(char*));
|
||||
_changelogLines[0] = start;
|
||||
_changelogNumLines = 1;
|
||||
|
||||
char *ch = start;
|
||||
while (*ch != 0) {
|
||||
_changelogLines.clear();
|
||||
_changelogLines.push_back(start);
|
||||
auto ch = start;
|
||||
while (*ch != '\0')
|
||||
{
|
||||
uint8 c = *ch;
|
||||
if (c == '\n') {
|
||||
if (c == '\n')
|
||||
{
|
||||
*ch++ = 0;
|
||||
_changelogNumLines++;
|
||||
if (_changelogNumLines > changelogLinesCapacity) {
|
||||
changelogLinesCapacity *= 2;
|
||||
new_memory = realloc(_changelogLines, changelogLinesCapacity * sizeof(char*));
|
||||
if (new_memory == nullptr) {
|
||||
log_error("Failed to reallocate memory for change log lines");
|
||||
return false;
|
||||
}
|
||||
_changelogLines = (char**)new_memory;
|
||||
}
|
||||
_changelogLines[_changelogNumLines - 1] = ch;
|
||||
} else if (c < 32 || c > 122) {
|
||||
// A character that won't be drawn or change state.
|
||||
_changelogLines.push_back(ch);
|
||||
}
|
||||
else if (utf8_is_format_code(c))
|
||||
{
|
||||
*ch++ = FORMAT_OUTLINE_OFF;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ch++;
|
||||
}
|
||||
}
|
||||
|
||||
new_memory = realloc(_changelogLines, _changelogNumLines * sizeof(char*));
|
||||
if (new_memory == nullptr) {
|
||||
log_error("Failed to reallocate memory for change log lines");
|
||||
return false;
|
||||
}
|
||||
_changelogLines = (char**)new_memory;
|
||||
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;
|
||||
_changelogLongestLineWidth = 0;
|
||||
for (sint32 i = 0; i < _changelogNumLines; i++) {
|
||||
sint32 width = gfx_get_string_width(_changelogLines[i]);
|
||||
for (auto line : _changelogLines)
|
||||
{
|
||||
auto width = gfx_get_string_width(line);
|
||||
_changelogLongestLineWidth = Math::Max(width, _changelogLongestLineWidth);
|
||||
}
|
||||
return true;
|
||||
|
@ -266,8 +280,7 @@ static bool window_changelog_read_file()
|
|||
|
||||
static void window_changelog_dispose_file()
|
||||
{
|
||||
SafeFree(_changelogText);
|
||||
SafeFree(_changelogLines);
|
||||
_changelogTextSize = 0;
|
||||
_changelogNumLines = 0;
|
||||
_changelogText = std::string();
|
||||
_changelogLines.clear();
|
||||
_changelogLines.shrink_to_fit();
|
||||
}
|
||||
|
|
|
@ -14,32 +14,31 @@
|
|||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
|
||||
#include <vector>
|
||||
#include <openrct2/audio/audio.h>
|
||||
#include <openrct2/config/Config.h>
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include <openrct2/Editor.h>
|
||||
#include <openrct2/EditorObjectSelectionSession.h>
|
||||
#include <openrct2/Game.h>
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
#include <openrct2/localisation/Localisation.h>
|
||||
#include <openrct2/object/ObjectList.h>
|
||||
#include <openrct2/object/ObjectManager.h>
|
||||
#include <openrct2/object/ObjectRepository.h>
|
||||
#include <openrct2/object/RideObject.h>
|
||||
#include <openrct2/object/StexObject.h>
|
||||
#include <openrct2/object/ObjectList.h>
|
||||
#include <openrct2/OpenRCT2.h>
|
||||
#include <openrct2/platform/platform.h>
|
||||
#include <openrct2/ride/RideGroupManager.h>
|
||||
#include <openrct2/sprites.h>
|
||||
#include <openrct2/util/Util.h>
|
||||
#include <openrct2-ui/interface/Dropdown.h>
|
||||
#include <openrct2/windows/Intent.h>
|
||||
#include <openrct2-ui/interface/Dropdown.h>
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
|
||||
enum {
|
||||
FILTER_RCT2 = (1 << 0),
|
||||
|
@ -270,42 +269,34 @@ typedef struct list_item {
|
|||
|
||||
static rct_string_id get_ride_type_string_id(const ObjectRepositoryItem * item);
|
||||
|
||||
typedef sint32(*sortFunc_t)(const void *, const void *);
|
||||
typedef bool (*sortFunc_t)(const list_item &, const list_item &);
|
||||
|
||||
static sint32 _numListItems = 0;
|
||||
static list_item *_listItems = nullptr;
|
||||
static std::vector<list_item> _listItems;
|
||||
static sint32 _listSortType = RIDE_SORT_TYPE;
|
||||
static bool _listSortDescending = false;
|
||||
static void * _loadedObject = nullptr;
|
||||
|
||||
static void visible_list_dispose()
|
||||
{
|
||||
SafeFree(_listItems);
|
||||
_numListItems = 0;
|
||||
_listItems.clear();
|
||||
_listItems.shrink_to_fit();
|
||||
}
|
||||
|
||||
static sint32 visible_list_sort_ride_name(const void *rawA, const void *rawB)
|
||||
static bool visible_list_sort_ride_name(const list_item &a, const list_item &b)
|
||||
{
|
||||
list_item *a = (list_item*)rawA;
|
||||
list_item *b = (list_item*)rawB;
|
||||
|
||||
const char *nameA = a->repositoryItem->Name;
|
||||
const char *nameB = b->repositoryItem->Name;
|
||||
return strcmp(nameA, nameB);
|
||||
auto nameA = a.repositoryItem->Name;
|
||||
auto nameB = b.repositoryItem->Name;
|
||||
return strcmp(nameA, nameB) < 0;
|
||||
}
|
||||
|
||||
static sint32 visible_list_sort_ride_type(const void *rawA, const void *rawB)
|
||||
static bool visible_list_sort_ride_type(const list_item &a, const list_item &b)
|
||||
{
|
||||
list_item *a = (list_item*)rawA;
|
||||
list_item *b = (list_item*)rawB;
|
||||
|
||||
const char *rideTypeA = language_get_string(get_ride_type_string_id(a->repositoryItem));
|
||||
const char *rideTypeB = language_get_string(get_ride_type_string_id(b->repositoryItem));
|
||||
auto rideTypeA = language_get_string(get_ride_type_string_id(a.repositoryItem));
|
||||
auto rideTypeB = language_get_string(get_ride_type_string_id(b.repositoryItem));
|
||||
sint32 result = strcmp(rideTypeA, rideTypeB);
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
return visible_list_sort_ride_name(rawA, rawB);
|
||||
return result != 0 ?
|
||||
result < 0 :
|
||||
visible_list_sort_ride_name(a, b);
|
||||
}
|
||||
|
||||
static void visible_list_refresh(rct_window *w)
|
||||
|
@ -314,10 +305,7 @@ static void visible_list_refresh(rct_window *w)
|
|||
|
||||
visible_list_dispose();
|
||||
w->selected_list_item = -1;
|
||||
_listItems = Memory::AllocateArray<list_item>(numObjects);
|
||||
_numListItems = 0;
|
||||
|
||||
list_item *currentListItem = &_listItems[0];
|
||||
const ObjectRepositoryItem *items = object_repository_get_items();
|
||||
for (sint32 i = 0; i < numObjects; i++) {
|
||||
uint8 selectionFlags = _objectSelectionFlags[i];
|
||||
|
@ -333,29 +321,25 @@ static void visible_list_refresh(rct_window *w)
|
|||
filter->ride.category[0] = 0;
|
||||
filter->ride.category[1] = 0;
|
||||
filter->ride.ride_type = 0;
|
||||
currentListItem->repositoryItem = item;
|
||||
currentListItem->entry = (rct_object_entry *)&item->ObjectEntry;
|
||||
currentListItem->filter = filter;
|
||||
currentListItem->flags = &_objectSelectionFlags[i];
|
||||
currentListItem++;
|
||||
_numListItems++;
|
||||
|
||||
list_item currentListItem;
|
||||
currentListItem.repositoryItem = item;
|
||||
currentListItem.entry = (rct_object_entry *)&item->ObjectEntry;
|
||||
currentListItem.filter = filter;
|
||||
currentListItem.flags = &_objectSelectionFlags[i];
|
||||
_listItems.push_back(std::move(currentListItem));
|
||||
}
|
||||
}
|
||||
|
||||
if (_numListItems == 0)
|
||||
if (_listItems.size() == 0)
|
||||
{
|
||||
visible_list_dispose();
|
||||
window_invalidate(w);
|
||||
return;
|
||||
}
|
||||
|
||||
_listItems = Memory::ReallocateArray(_listItems, _numListItems);
|
||||
if (_listItems == nullptr) {
|
||||
_numListItems = 0;
|
||||
log_error("Unable to reallocate list items");
|
||||
} else {
|
||||
else
|
||||
{
|
||||
sortFunc_t sortFunc = nullptr;
|
||||
switch (_listSortType) {
|
||||
switch (_listSortType)
|
||||
{
|
||||
case RIDE_SORT_TYPE:
|
||||
sortFunc = visible_list_sort_ride_type;
|
||||
break;
|
||||
|
@ -364,17 +348,14 @@ static void visible_list_refresh(rct_window *w)
|
|||
break;
|
||||
default:
|
||||
log_warning("Wrong sort type %d, leaving list as-is.", _listSortType);
|
||||
window_invalidate(w);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
qsort(_listItems, _numListItems, sizeof(list_item), sortFunc);
|
||||
|
||||
if (_listSortDescending) {
|
||||
for (sint32 i = 0; i < _numListItems / 2; i++) {
|
||||
sint32 ri = _numListItems - i - 1;
|
||||
list_item temp = _listItems[i];
|
||||
_listItems[i] = _listItems[ri];
|
||||
_listItems[ri] = temp;
|
||||
if (sortFunc != nullptr)
|
||||
{
|
||||
std::sort(_listItems.begin(), _listItems.end(), sortFunc);
|
||||
if (_listSortDescending)
|
||||
{
|
||||
std::reverse(_listItems.begin(), _listItems.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -681,7 +662,7 @@ static void window_editor_object_selection_dropdown(rct_window *w, rct_widgetind
|
|||
*/
|
||||
static void window_editor_object_selection_scrollgetsize(rct_window *w, sint32 scrollIndex, sint32 *width, sint32 *height)
|
||||
{
|
||||
*height = _numListItems * 12;
|
||||
*height = (sint32)(_listItems.size() * 12);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1110,7 +1091,7 @@ static void window_editor_object_selection_paint(rct_window *w, rct_drawpixelinf
|
|||
*/
|
||||
static void window_editor_object_selection_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 scrollIndex)
|
||||
{
|
||||
sint32 x, y, i, colour, colour2;
|
||||
sint32 x, y, colour, colour2;
|
||||
|
||||
bool ridePage = (w->selected_tab == WINDOW_OBJECT_SELECTION_PAGE_RIDE_VEHICLES_ATTRACTIONS);
|
||||
|
||||
|
@ -1118,27 +1099,26 @@ static void window_editor_object_selection_scrollpaint(rct_window *w, rct_drawpi
|
|||
gfx_clear(dpi, paletteIndex);
|
||||
|
||||
y = 0;
|
||||
for (i = 0; i < _numListItems; i++) {
|
||||
list_item *listItem = &_listItems[i];
|
||||
|
||||
for (const auto &listItem : _listItems)
|
||||
{
|
||||
if (y + 12 >= dpi->y && y <= dpi->y + dpi->height) {
|
||||
// Draw checkbox
|
||||
if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) && !(*listItem->flags & 0x20))
|
||||
if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) && !(*listItem.flags & 0x20))
|
||||
gfx_fill_rect_inset(dpi, 2, y, 11, y + 10, w->colours[1], INSET_RECT_F_E0);
|
||||
|
||||
// Highlight background
|
||||
colour = COLOUR_BRIGHT_GREEN | COLOUR_FLAG_TRANSLUCENT;
|
||||
if (listItem->entry == w->object_entry && !(*listItem->flags & OBJECT_SELECTION_FLAG_6)) {
|
||||
if (listItem.entry == w->object_entry && !(*listItem.flags & OBJECT_SELECTION_FLAG_6)) {
|
||||
gfx_filter_rect(dpi, 0, y, w->width, y + 11, PALETTE_DARKEN_1);
|
||||
colour = COLOUR_BRIGHT_GREEN;
|
||||
}
|
||||
|
||||
// Draw checkmark
|
||||
if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) && (*listItem->flags & OBJECT_SELECTION_FLAG_SELECTED)) {
|
||||
if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) && (*listItem.flags & OBJECT_SELECTION_FLAG_SELECTED)) {
|
||||
x = 2;
|
||||
gCurrentFontSpriteBase = colour == COLOUR_BRIGHT_GREEN ? FONT_SPRITE_BASE_MEDIUM_EXTRA_DARK : FONT_SPRITE_BASE_MEDIUM_DARK;
|
||||
colour2 = NOT_TRANSLUCENT(w->colours[1]);
|
||||
if (*listItem->flags & (OBJECT_SELECTION_FLAG_IN_USE | OBJECT_SELECTION_FLAG_ALWAYS_REQUIRED))
|
||||
if (*listItem.flags & (OBJECT_SELECTION_FLAG_IN_USE | OBJECT_SELECTION_FLAG_ALWAYS_REQUIRED))
|
||||
colour2 |= COLOUR_FLAG_INSET;
|
||||
|
||||
gfx_draw_string(dpi, (char*)CheckBoxMarkString, colour2, x, y);
|
||||
|
@ -1148,7 +1128,7 @@ static void window_editor_object_selection_scrollpaint(rct_window *w, rct_drawpi
|
|||
|
||||
char *bufferWithColour = gCommonStringFormatBuffer;
|
||||
char *buffer = utf8_write_codepoint(bufferWithColour, colour);
|
||||
if (*listItem->flags & OBJECT_SELECTION_FLAG_6) {
|
||||
if (*listItem.flags & OBJECT_SELECTION_FLAG_6) {
|
||||
colour = w->colours[1] & 0x7F;
|
||||
gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM_DARK;
|
||||
}
|
||||
|
@ -1159,14 +1139,14 @@ static void window_editor_object_selection_scrollpaint(rct_window *w, rct_drawpi
|
|||
|
||||
if (ridePage) {
|
||||
// Draw ride type
|
||||
rct_string_id rideTypeStringId = get_ride_type_string_id(listItem->repositoryItem);
|
||||
rct_string_id rideTypeStringId = get_ride_type_string_id(listItem.repositoryItem);
|
||||
safe_strcpy(buffer, language_get_string(rideTypeStringId), 256 - (buffer - bufferWithColour));
|
||||
gfx_draw_string(dpi, bufferWithColour, colour, x, y);
|
||||
x = w->widgets[WIDX_LIST_SORT_RIDE].left - w->widgets[WIDX_LIST].left;
|
||||
}
|
||||
|
||||
// Draw text
|
||||
safe_strcpy(buffer, listItem->repositoryItem->Name, 256 - (buffer - bufferWithColour));
|
||||
safe_strcpy(buffer, listItem.repositoryItem->Name, 256 - (buffer - bufferWithColour));
|
||||
if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) {
|
||||
while (*buffer != 0 && *buffer != 9)
|
||||
buffer++;
|
||||
|
@ -1221,7 +1201,7 @@ static void window_editor_object_selection_set_pressed_tab(rct_window *w)
|
|||
static sint32 get_object_from_object_selection(uint8 object_type, sint32 y)
|
||||
{
|
||||
sint32 listItemIndex = y / 12;
|
||||
if (listItemIndex < 0 || listItemIndex >= _numListItems)
|
||||
if (listItemIndex < 0 || (size_t)listItemIndex >= _listItems.size())
|
||||
return -1;
|
||||
|
||||
return listItemIndex;
|
||||
|
|
|
@ -14,11 +14,13 @@
|
|||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/object/ObjectManager.h>
|
||||
#include <openrct2/ride/TrackDesignRepository.h>
|
||||
#include <openrct2/core/Math.hpp>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
|
||||
#include <openrct2/audio/audio.h>
|
||||
|
@ -94,10 +96,10 @@ static rct_window_event_list window_install_track_events = {
|
|||
nullptr
|
||||
};
|
||||
|
||||
static rct_track_td6 *_trackDesign;
|
||||
static utf8 *_trackPath;
|
||||
static utf8 *_trackName;
|
||||
static uint8 *_trackDesignPreviewPixels;
|
||||
static rct_track_td6 * _trackDesign;
|
||||
static std::string _trackPath;
|
||||
static std::string _trackName;
|
||||
static std::vector<uint8> _trackDesignPreviewPixels;
|
||||
|
||||
static void window_install_track_update_preview();
|
||||
static void window_install_track_design(rct_window *w);
|
||||
|
@ -142,9 +144,9 @@ rct_window * window_install_track_open(const utf8 *path)
|
|||
w->track_list.track_list_being_updated = false;
|
||||
window_push_others_right(w);
|
||||
|
||||
_trackPath = _strdup(path);
|
||||
_trackName = track_repository_get_name_from_path(path);
|
||||
_trackDesignPreviewPixels = Memory::AllocateArray<uint8>(4 * TRACK_PREVIEW_IMAGE_SIZE);
|
||||
_trackPath = path;
|
||||
_trackName = GetNameFromTrackPath(path);
|
||||
_trackDesignPreviewPixels.resize(4 * TRACK_PREVIEW_IMAGE_SIZE);
|
||||
|
||||
window_install_track_update_preview();
|
||||
window_invalidate(w);
|
||||
|
@ -158,9 +160,10 @@ rct_window * window_install_track_open(const utf8 *path)
|
|||
*/
|
||||
static void window_install_track_close(rct_window *w)
|
||||
{
|
||||
SafeFree(_trackPath);
|
||||
SafeFree(_trackName);
|
||||
SafeFree(_trackDesignPreviewPixels);
|
||||
_trackPath.clear();
|
||||
_trackName.clear();
|
||||
_trackDesignPreviewPixels.clear();
|
||||
_trackDesignPreviewPixels.shrink_to_fit();
|
||||
track_design_dispose(_trackDesign);
|
||||
_trackDesign = nullptr;
|
||||
}
|
||||
|
@ -229,7 +232,7 @@ static void window_install_track_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
gfx_fill_rect(dpi, x, y, x + 369, y + 216, colour);
|
||||
|
||||
rct_g1_element g1temp = { nullptr };
|
||||
g1temp.offset = _trackDesignPreviewPixels + (_currentTrackPieceDirection * TRACK_PREVIEW_IMAGE_SIZE);
|
||||
g1temp.offset = _trackDesignPreviewPixels.data() + (_currentTrackPieceDirection * TRACK_PREVIEW_IMAGE_SIZE);
|
||||
g1temp.width = 370;
|
||||
g1temp.height = 217;
|
||||
g1temp.flags = G1_FLAG_BMP;
|
||||
|
@ -400,15 +403,14 @@ static void window_install_track_text_input(rct_window *w, rct_widgetindex widge
|
|||
return;
|
||||
}
|
||||
|
||||
free(_trackName);
|
||||
_trackName = _strdup(text);
|
||||
_trackName = text;
|
||||
|
||||
window_event_mouse_up_call(w, WIDX_INSTALL);
|
||||
}
|
||||
|
||||
static void window_install_track_update_preview()
|
||||
{
|
||||
track_design_draw_preview(_trackDesign, _trackDesignPreviewPixels);
|
||||
track_design_draw_preview(_trackDesign, _trackDesignPreviewPixels.data());
|
||||
}
|
||||
|
||||
static void window_install_track_design(rct_window *w)
|
||||
|
@ -422,7 +424,7 @@ static void window_install_track_design(rct_window *w)
|
|||
return;
|
||||
}
|
||||
|
||||
safe_strcat_path(destPath, _trackName, sizeof(destPath));
|
||||
safe_strcat_path(destPath, _trackName.c_str(), sizeof(destPath));
|
||||
path_append_extension(destPath, ".td6", sizeof(destPath));
|
||||
|
||||
if (platform_file_exists(destPath)) {
|
||||
|
@ -433,11 +435,11 @@ static void window_install_track_design(rct_window *w)
|
|||
WIDX_INSTALL,
|
||||
STR_SELECT_NEW_NAME_FOR_TRACK_DESIGN,
|
||||
STR_AN_EXISTING_TRACK_DESIGN_ALREADY_HAS_THIS_NAME,
|
||||
_trackName,
|
||||
_trackName.c_str(),
|
||||
255
|
||||
);
|
||||
} else {
|
||||
if (track_repository_install(_trackPath)) {
|
||||
if (track_repository_install(_trackPath.c_str())) {
|
||||
window_close(w);
|
||||
} else {
|
||||
context_show_error(STR_CANT_SAVE_TRACK_DESIGN, STR_NONE);
|
||||
|
|
|
@ -14,24 +14,24 @@
|
|||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include <openrct2/OpenRCT2.h>
|
||||
#include <openrct2/core/Math.hpp>
|
||||
#include <openrct2/core/Util.hpp>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include <openrct2/Context.h>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <openrct2/audio/audio.h>
|
||||
#include <openrct2/Cheats.h>
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/core/Math.hpp>
|
||||
#include <openrct2/core/Util.hpp>
|
||||
#include <openrct2/Game.h>
|
||||
#include <openrct2/Input.h>
|
||||
#include <openrct2-ui/interface/Viewport.h>
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
#include <openrct2/localisation/Localisation.h>
|
||||
#include <openrct2/OpenRCT2.h>
|
||||
#include <openrct2/ride/Track.h>
|
||||
#include <openrct2/world/Entrance.h>
|
||||
#include <openrct2/world/Footpath.h>
|
||||
#include <openrct2/world/Scenery.h>
|
||||
|
||||
#include <openrct2-ui/interface/LandTool.h>
|
||||
#include <openrct2-ui/interface/Viewport.h>
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
|
||||
#define MAP_COLOUR_2(colourA, colourB) ((colourA << 8) | colourB)
|
||||
|
@ -175,7 +175,7 @@ static uint8 _activeTool;
|
|||
static uint32 _currentLine;
|
||||
|
||||
/** rct2: 0x00F1AD68 */
|
||||
static uint8 (*_mapImageData)[MAP_WINDOW_MAP_SIZE][MAP_WINDOW_MAP_SIZE];
|
||||
static std::vector<uint8> _mapImageData;
|
||||
|
||||
static sint32 _nextPeepSpawnIndex = 0;
|
||||
|
||||
|
@ -217,8 +217,12 @@ rct_window * window_map_open()
|
|||
return w;
|
||||
}
|
||||
|
||||
_mapImageData = Memory::Allocate<uint8[MAP_WINDOW_MAP_SIZE][MAP_WINDOW_MAP_SIZE]>();
|
||||
if (_mapImageData == nullptr) {
|
||||
try
|
||||
{
|
||||
_mapImageData.resize(MAP_WINDOW_MAP_SIZE * MAP_WINDOW_MAP_SIZE);
|
||||
}
|
||||
catch (const std::bad_alloc &)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -284,7 +288,8 @@ void window_map_reset()
|
|||
*/
|
||||
static void window_map_close(rct_window *w)
|
||||
{
|
||||
free(_mapImageData);
|
||||
_mapImageData.clear();
|
||||
_mapImageData.shrink_to_fit();
|
||||
if ((input_test_flag(INPUT_FLAG_TOOL_ACTIVE)) &&
|
||||
gCurrentToolWidget.window_classification == w->classification &&
|
||||
gCurrentToolWidget.window_number == w->number) {
|
||||
|
@ -889,7 +894,7 @@ static void window_map_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32
|
|||
gfx_clear(dpi, PALETTE_INDEX_10);
|
||||
|
||||
rct_g1_element g1temp = { nullptr };
|
||||
g1temp.offset = (uint8 *)_mapImageData;
|
||||
g1temp.offset = _mapImageData.data();
|
||||
g1temp.width = MAP_WINDOW_MAP_SIZE;
|
||||
g1temp.height = MAP_WINDOW_MAP_SIZE;
|
||||
g1temp.x_offset = -8;
|
||||
|
@ -914,7 +919,7 @@ static void window_map_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32
|
|||
*/
|
||||
static void window_map_init_map()
|
||||
{
|
||||
memset(_mapImageData, PALETTE_INDEX_10, sizeof(*_mapImageData));
|
||||
std::fill(_mapImageData.begin(), _mapImageData.end(), PALETTE_INDEX_10);
|
||||
_currentLine = 0;
|
||||
}
|
||||
|
||||
|
@ -1653,12 +1658,11 @@ static uint16 map_window_get_pixel_colour_ride(sint32 x, sint32 y)
|
|||
static void map_window_set_pixels(rct_window *w)
|
||||
{
|
||||
uint16 colour = 0;
|
||||
uint8 *destination;
|
||||
sint32 x = 0, y = 0, dx = 0, dy = 0;
|
||||
|
||||
sint32 pos = (_currentLine * (MAP_WINDOW_MAP_SIZE - 1)) + MAXIMUM_MAP_SIZE_TECHNICAL - 1;
|
||||
LocationXY16 destinationPosition = MakeXY16(pos % MAP_WINDOW_MAP_SIZE, pos / MAP_WINDOW_MAP_SIZE);
|
||||
destination = &(*_mapImageData)[destinationPosition.y][destinationPosition.x];
|
||||
auto destination = _mapImageData.data() + (destinationPosition.y * MAP_WINDOW_MAP_SIZE) + destinationPosition.x;
|
||||
switch (get_current_rotation()) {
|
||||
case 0:
|
||||
x = _currentLine * 32;
|
||||
|
@ -1709,7 +1713,7 @@ static void map_window_set_pixels(rct_window *w)
|
|||
|
||||
destinationPosition.x++;
|
||||
destinationPosition.y++;
|
||||
destination = &(*_mapImageData)[destinationPosition.y][destinationPosition.x];
|
||||
destination = _mapImageData.data() + (destinationPosition.y * MAP_WINDOW_MAP_SIZE) + destinationPosition.x;
|
||||
}
|
||||
_currentLine++;
|
||||
if (_currentLine >= MAXIMUM_MAP_SIZE_TECHNICAL)
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <openrct2/localisation/Localisation.h>
|
||||
#include <openrct2/object/ObjectManager.h>
|
||||
#include <openrct2/platform/platform.h>
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
|
||||
enum WINDOW_OBJECT_LOAD_ERROR_WIDGET_IDX {
|
||||
WIDX_BACKGROUND,
|
||||
|
@ -96,9 +96,9 @@ static rct_window_event_list window_object_load_error_events = {
|
|||
window_object_load_error_scrollpaint
|
||||
};
|
||||
|
||||
static rct_object_entry * _invalid_entries = nullptr;
|
||||
static std::vector<rct_object_entry> _invalid_entries;
|
||||
static sint32 highlighted_index = -1;
|
||||
static utf8 * file_path = nullptr;
|
||||
static std::string file_path;
|
||||
|
||||
/**
|
||||
* Returns an rct_string_id that represents an rct_object_entry's type.
|
||||
|
@ -187,9 +187,7 @@ static void copy_object_names_to_clipboard(rct_window *w)
|
|||
|
||||
rct_window * window_object_load_error_open(utf8 * path, size_t numMissingObjects, const rct_object_entry * missingObjects)
|
||||
{
|
||||
size_t missingObjectsSize = numMissingObjects * sizeof(rct_object_entry);
|
||||
_invalid_entries = Memory::AllocateArray<rct_object_entry>(numMissingObjects);
|
||||
memcpy(_invalid_entries, missingObjects, missingObjectsSize);
|
||||
_invalid_entries = std::vector<rct_object_entry>(missingObjects, missingObjects + numMissingObjects);
|
||||
|
||||
// Check if window is already open
|
||||
rct_window * window = window_bring_to_front_by_class(WC_OBJECT_LOAD_ERROR);
|
||||
|
@ -213,7 +211,7 @@ rct_window * window_object_load_error_open(utf8 * path, size_t numMissingObjects
|
|||
|
||||
// Refresh list items and path
|
||||
window->no_list_items = (uint16)numMissingObjects;
|
||||
file_path = strndup(path, strnlen(path, MAX_PATH));
|
||||
file_path = path;
|
||||
|
||||
window_invalidate(window);
|
||||
return window;
|
||||
|
@ -221,7 +219,8 @@ rct_window * window_object_load_error_open(utf8 * path, size_t numMissingObjects
|
|||
|
||||
static void window_object_load_error_close(rct_window *w)
|
||||
{
|
||||
SafeFree(_invalid_entries);
|
||||
_invalid_entries.clear();
|
||||
_invalid_entries.shrink_to_fit();
|
||||
}
|
||||
|
||||
static void window_object_load_error_update(rct_window *w)
|
||||
|
@ -303,7 +302,7 @@ static void window_object_load_error_paint(rct_window *w, rct_drawpixelinfo *dpi
|
|||
|
||||
// Draw file name
|
||||
set_format_arg(0, rct_string_id, STR_OBJECT_ERROR_WINDOW_FILE);
|
||||
set_format_arg(2, utf8*, file_path);
|
||||
set_format_arg(2, utf8*, file_path.c_str());
|
||||
gfx_draw_string_left_clipped(dpi, STR_BLACK_STRING, gCommonFormatArgs, COLOUR_BLACK, w->x + 5, w->y + 43, WW-5);
|
||||
}
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ static rct_window_event_list window_title_command_editor_events = {
|
|||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
window_title_command_editor_tool_down,
|
||||
window_title_command_editor_tool_down,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
|
|
|
@ -14,42 +14,45 @@
|
|||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include <openrct2/config/Config.h>
|
||||
#include <openrct2/scenario/ScenarioRepository.h>
|
||||
#include <openrct2/scenario/ScenarioSources.h>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
|
||||
#include <vector>
|
||||
#include <openrct2/audio/audio.h>
|
||||
#include <openrct2/config/Config.h>
|
||||
#include <openrct2/interface/themes.h>
|
||||
#include <openrct2/localisation/Date.h>
|
||||
#include <openrct2/localisation/Localisation.h>
|
||||
#include <openrct2/scenario/ScenarioRepository.h>
|
||||
#include <openrct2/scenario/ScenarioSources.h>
|
||||
#include <openrct2/sprites.h>
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
#include <openrct2/interface/themes.h>
|
||||
#include <openrct2/util/Util.h>
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
|
||||
#define INITIAL_NUM_UNLOCKED_SCENARIOS 5
|
||||
|
||||
enum {
|
||||
LIST_ITEM_TYPE_HEADING,
|
||||
LIST_ITEM_TYPE_SCENARIO,
|
||||
LIST_ITEM_TYPE_END,
|
||||
enum class LIST_ITEM_TYPE : uint8
|
||||
{
|
||||
HEADING,
|
||||
SCENARIO,
|
||||
};
|
||||
|
||||
typedef struct sc_list_item {
|
||||
uint8 type;
|
||||
union {
|
||||
struct {
|
||||
struct sc_list_item
|
||||
{
|
||||
LIST_ITEM_TYPE type;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
rct_string_id string_id;
|
||||
} heading;
|
||||
struct {
|
||||
const scenario_index_entry *scenario;
|
||||
struct
|
||||
{
|
||||
const scenario_index_entry * scenario;
|
||||
bool is_locked;
|
||||
} scenario;
|
||||
};
|
||||
} sc_list_item;
|
||||
};
|
||||
|
||||
static sc_list_item *_listItems = nullptr;
|
||||
static std::vector<sc_list_item> _listItems;
|
||||
|
||||
enum {
|
||||
WIDX_BACKGROUND,
|
||||
|
@ -250,7 +253,8 @@ static void window_scenarioselect_init_tabs(rct_window *w)
|
|||
|
||||
static void window_scenarioselect_close(rct_window *w)
|
||||
{
|
||||
SafeFree(_listItems);
|
||||
_listItems.clear();
|
||||
_listItems.shrink_to_fit();
|
||||
}
|
||||
|
||||
static void window_scenarioselect_mouseup(rct_window *w, rct_widgetindex widgetIndex)
|
||||
|
@ -277,12 +281,14 @@ static void window_scenarioselect_mousedown(rct_window *w, rct_widgetindex widge
|
|||
static void window_scenarioselect_scrollgetsize(rct_window *w, sint32 scrollIndex, sint32 *width, sint32 *height)
|
||||
{
|
||||
sint32 y = 0;
|
||||
for (sc_list_item *listItem = _listItems; listItem->type != LIST_ITEM_TYPE_END; listItem++) {
|
||||
switch (listItem->type) {
|
||||
case LIST_ITEM_TYPE_HEADING:
|
||||
for (const auto &listItem : _listItems)
|
||||
{
|
||||
switch (listItem.type)
|
||||
{
|
||||
case LIST_ITEM_TYPE::HEADING:
|
||||
y += 18;
|
||||
break;
|
||||
case LIST_ITEM_TYPE_SCENARIO:
|
||||
case LIST_ITEM_TYPE::SCENARIO:
|
||||
y += 24;
|
||||
break;
|
||||
}
|
||||
|
@ -296,17 +302,19 @@ static void window_scenarioselect_scrollgetsize(rct_window *w, sint32 scrollInde
|
|||
*/
|
||||
static void window_scenarioselect_scrollmousedown(rct_window *w, sint32 scrollIndex, sint32 x, sint32 y)
|
||||
{
|
||||
for (sc_list_item *listItem = _listItems; listItem->type != LIST_ITEM_TYPE_END; listItem++) {
|
||||
switch (listItem->type) {
|
||||
case LIST_ITEM_TYPE_HEADING:
|
||||
for (const auto &listItem : _listItems)
|
||||
{
|
||||
switch (listItem.type)
|
||||
{
|
||||
case LIST_ITEM_TYPE::HEADING:
|
||||
y -= 18;
|
||||
break;
|
||||
case LIST_ITEM_TYPE_SCENARIO:
|
||||
case LIST_ITEM_TYPE::SCENARIO:
|
||||
y -= 24;
|
||||
if (y < 0 && !listItem->scenario.is_locked) {
|
||||
if (y < 0 && !listItem.scenario.is_locked) {
|
||||
audio_play_sound(SOUND_CLICK_1, 0, w->x + (w->width / 2));
|
||||
gFirstTimeSaving = true;
|
||||
_callback(listItem->scenario.scenario->path);
|
||||
_callback(listItem.scenario.scenario->path);
|
||||
if (_titleEditor)
|
||||
{
|
||||
window_close(w);
|
||||
|
@ -329,18 +337,20 @@ static void window_scenarioselect_scrollmouseover(rct_window *w, sint32 scrollIn
|
|||
bool originalShowLockedInformation = _showLockedInformation;
|
||||
_showLockedInformation = false;
|
||||
const scenario_index_entry *selected = nullptr;
|
||||
for (sc_list_item *listItem = _listItems; listItem->type != LIST_ITEM_TYPE_END; listItem++) {
|
||||
switch (listItem->type) {
|
||||
case LIST_ITEM_TYPE_HEADING:
|
||||
for (const auto &listItem : _listItems)
|
||||
{
|
||||
switch (listItem.type)
|
||||
{
|
||||
case LIST_ITEM_TYPE::HEADING:
|
||||
y -= 18;
|
||||
break;
|
||||
case LIST_ITEM_TYPE_SCENARIO:
|
||||
case LIST_ITEM_TYPE::SCENARIO:
|
||||
y -= 24;
|
||||
if (y < 0) {
|
||||
if (listItem->scenario.is_locked) {
|
||||
if (listItem.scenario.is_locked) {
|
||||
_showLockedInformation = true;
|
||||
} else {
|
||||
selected = listItem->scenario.scenario;
|
||||
selected = listItem.scenario.scenario;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -483,30 +493,32 @@ static void window_scenarioselect_scrollpaint(rct_window *w, rct_drawpixelinfo *
|
|||
sint32 listWidth = listWidget->right - listWidget->left - 12;
|
||||
|
||||
sint32 y = 0;
|
||||
for (sc_list_item *listItem = _listItems; listItem->type != LIST_ITEM_TYPE_END; listItem++) {
|
||||
for (const auto &listItem : _listItems)
|
||||
{
|
||||
if (y > dpi->y + dpi->height) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (listItem->type) {
|
||||
case LIST_ITEM_TYPE_HEADING:
|
||||
switch (listItem.type)
|
||||
{
|
||||
case LIST_ITEM_TYPE::HEADING:
|
||||
{
|
||||
const sint32 horizontalRuleMargin = 4;
|
||||
draw_category_heading(w, dpi, horizontalRuleMargin, listWidth - horizontalRuleMargin, y + 2, listItem->heading.string_id);
|
||||
draw_category_heading(w, dpi, horizontalRuleMargin, listWidth - horizontalRuleMargin, y + 2, listItem.heading.string_id);
|
||||
y += 18;
|
||||
break;
|
||||
}
|
||||
case LIST_ITEM_TYPE_SCENARIO:
|
||||
case LIST_ITEM_TYPE::SCENARIO:
|
||||
{
|
||||
// Draw hover highlight
|
||||
const scenario_index_entry *scenario = listItem->scenario.scenario;
|
||||
const scenario_index_entry *scenario = listItem.scenario.scenario;
|
||||
bool isHighlighted = w->highlighted_scenario == scenario;
|
||||
if (isHighlighted) {
|
||||
gfx_filter_rect(dpi, 0, y, w->width, y + 23, PALETTE_DARKEN_1);
|
||||
}
|
||||
|
||||
bool isCompleted = scenario->highscore != nullptr;
|
||||
bool isDisabled = listItem->scenario.is_locked;
|
||||
bool isDisabled = listItem.scenario.is_locked;
|
||||
|
||||
// Draw scenario name
|
||||
char buffer[64];
|
||||
|
@ -574,12 +586,8 @@ static void draw_category_heading(rct_window *w, rct_drawpixelinfo *dpi, sint32
|
|||
|
||||
static void initialise_list_items(rct_window *w)
|
||||
{
|
||||
SafeFree(_listItems);
|
||||
|
||||
size_t numScenarios = scenario_repository_get_count();
|
||||
size_t capacity = numScenarios + 16;
|
||||
size_t length = 0;
|
||||
_listItems = Memory::AllocateArray<sc_list_item>(capacity);
|
||||
_listItems.clear();
|
||||
|
||||
// Mega park unlock
|
||||
const uint32 rct1RequiredCompletedScenarios = (1 << SC_MEGA_PARK) - 1;
|
||||
|
@ -596,8 +604,6 @@ static void initialise_list_items(rct_window *w)
|
|||
if (_titleEditor && scenario->source_game == SCENARIO_SOURCE_OTHER)
|
||||
continue;
|
||||
|
||||
sc_list_item *listItem;
|
||||
|
||||
// Category heading
|
||||
rct_string_id headingStringId = STR_NONE;
|
||||
if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN || _titleEditor) {
|
||||
|
@ -623,70 +629,69 @@ static void initialise_list_items(rct_window *w)
|
|||
}
|
||||
}
|
||||
|
||||
if (headingStringId != STR_NONE) {
|
||||
// Ensure list capacity
|
||||
if (length == capacity) {
|
||||
capacity += 32;
|
||||
_listItems = Memory::ReallocateArray(_listItems, capacity);
|
||||
}
|
||||
listItem = &_listItems[length++];
|
||||
|
||||
listItem->type = LIST_ITEM_TYPE_HEADING;
|
||||
listItem->heading.string_id = headingStringId;
|
||||
if (headingStringId != STR_NONE)
|
||||
{
|
||||
sc_list_item headerItem;
|
||||
headerItem.type = LIST_ITEM_TYPE::HEADING;
|
||||
headerItem.heading.string_id = headingStringId;
|
||||
_listItems.push_back(std::move(headerItem));
|
||||
}
|
||||
|
||||
// Ensure list capacity
|
||||
if (length == capacity) {
|
||||
capacity += 32;
|
||||
_listItems = Memory::ReallocateArray(_listItems, capacity);
|
||||
}
|
||||
listItem = &_listItems[length++];
|
||||
|
||||
// Scenario
|
||||
listItem->type = LIST_ITEM_TYPE_SCENARIO;
|
||||
listItem->scenario.scenario = scenario;
|
||||
if (is_locking_enabled(w)) {
|
||||
listItem->scenario.is_locked = numUnlocks <= 0;
|
||||
if (scenario->highscore == nullptr) {
|
||||
sc_list_item scenarioItem;
|
||||
scenarioItem.type = LIST_ITEM_TYPE::SCENARIO;
|
||||
scenarioItem.scenario.scenario = scenario;
|
||||
if (is_locking_enabled(w))
|
||||
{
|
||||
scenarioItem.scenario.is_locked = numUnlocks <= 0;
|
||||
if (scenario->highscore == nullptr)
|
||||
{
|
||||
numUnlocks--;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// Mark RCT1 scenario as completed
|
||||
if (scenario->sc_id < SC_MEGA_PARK) {
|
||||
if (scenario->sc_id < SC_MEGA_PARK)
|
||||
{
|
||||
rct1CompletedScenarios |= 1 << scenario->sc_id;
|
||||
}
|
||||
}
|
||||
|
||||
// If scenario is Mega Park, keep a reference to it
|
||||
if (scenario->sc_id == SC_MEGA_PARK) {
|
||||
megaParkListItemIndex = length - 1;
|
||||
if (scenario->sc_id == SC_MEGA_PARK)
|
||||
{
|
||||
megaParkListItemIndex = _listItems.size() - 1;
|
||||
}
|
||||
} else {
|
||||
listItem->scenario.is_locked = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
scenarioItem.scenario.is_locked = false;
|
||||
}
|
||||
_listItems.push_back(std::move(scenarioItem));
|
||||
}
|
||||
|
||||
length++;
|
||||
_listItems = Memory::ReallocateArray(_listItems, capacity);
|
||||
_listItems[length - 1].type = LIST_ITEM_TYPE_END;
|
||||
|
||||
// Mega park handling
|
||||
if (megaParkListItemIndex != SIZE_MAX) {
|
||||
if (megaParkListItemIndex != SIZE_MAX)
|
||||
{
|
||||
bool megaParkLocked = (rct1CompletedScenarios & rct1RequiredCompletedScenarios) != rct1RequiredCompletedScenarios;
|
||||
_listItems[megaParkListItemIndex].scenario.is_locked = megaParkLocked;
|
||||
if (megaParkLocked && gConfigGeneral.scenario_hide_mega_park) {
|
||||
if (megaParkLocked && gConfigGeneral.scenario_hide_mega_park)
|
||||
{
|
||||
// Remove mega park
|
||||
size_t remainingItems = length - megaParkListItemIndex - 1;
|
||||
memmove(&_listItems[megaParkListItemIndex], &_listItems[megaParkListItemIndex + 1], remainingItems);
|
||||
_listItems.pop_back();
|
||||
|
||||
// Remove empty headings
|
||||
sint32 i = 0;
|
||||
for (sc_list_item *listItem = _listItems; listItem->type != LIST_ITEM_TYPE_END; listItem++) {
|
||||
if (listItem->type == LIST_ITEM_TYPE_HEADING && (listItem + 1)->type != LIST_ITEM_TYPE_SCENARIO) {
|
||||
remainingItems = length - i - 1;
|
||||
memmove(&_listItems[i], &_listItems[i + 1], remainingItems);
|
||||
listItem--;
|
||||
} else {
|
||||
i++;
|
||||
for (auto it = _listItems.begin(); it != _listItems.end(); it++)
|
||||
{
|
||||
const auto &listItem = *it;
|
||||
if (listItem.type == LIST_ITEM_TYPE::HEADING)
|
||||
{
|
||||
if ((it + 1) == _listItems.end() ||
|
||||
(it + 1)->type == LIST_ITEM_TYPE::HEADING)
|
||||
{
|
||||
_listItems.erase(it);
|
||||
it--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,23 +14,23 @@
|
|||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <openrct2/audio/audio.h>
|
||||
#include <openrct2/Cheats.h>
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/core/Math.hpp>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include <openrct2/Game.h>
|
||||
#include <openrct2/Input.h>
|
||||
#include <openrct2-ui/interface/Viewport.h>
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
#include <openrct2/localisation/Localisation.h>
|
||||
#include <openrct2/ride/Track.h>
|
||||
#include <openrct2/ride/TrackData.h>
|
||||
#include <openrct2/ride/TrackDesignRepository.h>
|
||||
#include <openrct2/sprites.h>
|
||||
#include <openrct2/windows/Intent.h>
|
||||
#include <openrct2-ui/interface/Viewport.h>
|
||||
#include <openrct2-ui/interface/Widget.h>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
|
||||
#define TRACK_MINI_PREVIEW_WIDTH 168
|
||||
#define TRACK_MINI_PREVIEW_HEIGHT 78
|
||||
|
@ -104,7 +104,7 @@ static rct_window_event_list window_track_place_events = {
|
|||
nullptr
|
||||
};
|
||||
|
||||
static uint8 *_window_track_place_mini_preview;
|
||||
static std::vector<uint8> _window_track_place_mini_preview;
|
||||
static sint16 _window_track_place_last_x;
|
||||
static sint16 _window_track_place_last_y;
|
||||
|
||||
|
@ -135,7 +135,7 @@ static uint8 *draw_mini_preview_get_pixel_ptr(LocationXY16 pixel);
|
|||
*/
|
||||
static void window_track_place_clear_mini_preview()
|
||||
{
|
||||
memset(_window_track_place_mini_preview, PALETTE_INDEX_TRANSPARENT, TRACK_MINI_PREVIEW_SIZE);
|
||||
std::fill(_window_track_place_mini_preview.begin(), _window_track_place_mini_preview.end(), PALETTE_INDEX_TRANSPARENT);
|
||||
}
|
||||
|
||||
#define swap(x, y) x = x ^ y; y = x ^ y; x = x ^ y;
|
||||
|
@ -153,7 +153,7 @@ rct_window * window_track_place_open(const track_design_file_ref *tdFileRef)
|
|||
|
||||
window_close_construction_windows();
|
||||
|
||||
_window_track_place_mini_preview = Memory::Allocate<uint8>(TRACK_MINI_PREVIEW_SIZE);
|
||||
_window_track_place_mini_preview.resize(TRACK_MINI_PREVIEW_SIZE);
|
||||
|
||||
rct_window *w = window_create(
|
||||
0,
|
||||
|
@ -198,7 +198,8 @@ static void window_track_place_close(rct_window *w)
|
|||
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_CONSTRUCT;
|
||||
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_ARROW;
|
||||
hide_gridlines();
|
||||
SafeFree(_window_track_place_mini_preview);
|
||||
_window_track_place_mini_preview.clear();
|
||||
_window_track_place_mini_preview.shrink_to_fit();
|
||||
track_design_dispose(_trackDesign);
|
||||
_trackDesign = nullptr;
|
||||
}
|
||||
|
@ -468,7 +469,7 @@ static void window_track_place_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
rct_drawpixelinfo clippedDpi;
|
||||
if (clip_drawpixelinfo(&clippedDpi, dpi, w->x + 4, w->y + 18, 168, 78)) {
|
||||
rct_g1_element g1temp = { nullptr };
|
||||
g1temp.offset = _window_track_place_mini_preview;
|
||||
g1temp.offset = _window_track_place_mini_preview.data();
|
||||
g1temp.width = TRACK_MINI_PREVIEW_WIDTH;
|
||||
g1temp.height = TRACK_MINI_PREVIEW_HEIGHT;
|
||||
gfx_set_g1_element(SPR_TEMP, &g1temp);
|
||||
|
|
|
@ -14,12 +14,10 @@
|
|||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
|
||||
#include <vector>
|
||||
#include <openrct2/audio/audio.h>
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/core/Math.hpp>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include <openrct2/core/String.hpp>
|
||||
#include <openrct2/drawing/IDrawingEngine.h>
|
||||
#include <openrct2/Editor.h>
|
||||
|
@ -30,7 +28,7 @@
|
|||
#include <openrct2/ride/TrackDesignRepository.h>
|
||||
#include <openrct2/sprites.h>
|
||||
#include <openrct2/windows/Intent.h>
|
||||
#include <vector>
|
||||
#include <openrct2-ui/windows/Window.h>
|
||||
|
||||
enum {
|
||||
WIDX_BACKGROUND,
|
||||
|
@ -108,13 +106,12 @@ static rct_window_event_list window_track_list_events = {
|
|||
|
||||
ride_list_item _window_track_list_item;
|
||||
|
||||
static track_design_file_ref * _trackDesigns = nullptr;
|
||||
static size_t _trackDesignsCount = 0;
|
||||
static std::vector<track_design_file_ref> _trackDesigns;
|
||||
static utf8 _filterString[USER_STRING_MAX_LENGTH];
|
||||
static std::vector<uint16> _filteredTrackIds;
|
||||
static uint16 _loadedTrackDesignIndex;
|
||||
static rct_track_td6 * _loadedTrackDesign;
|
||||
static uint8 * _trackDesignPreviewPixels;
|
||||
static std::vector<uint8> _trackDesignPreviewPixels;
|
||||
|
||||
static void track_list_load_designs(ride_list_item item);
|
||||
static bool track_list_load_design_for_preview(utf8 *path);
|
||||
|
@ -171,7 +168,7 @@ rct_window * window_track_list_open(ride_list_item item)
|
|||
|
||||
// Start with first track highlighted
|
||||
w->selected_list_item = 0;
|
||||
if (_trackDesignsCount != 0 && !(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER)) {
|
||||
if (_trackDesigns.size() != 0 && !(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER)) {
|
||||
w->selected_list_item = 1;
|
||||
}
|
||||
|
||||
|
@ -179,7 +176,7 @@ rct_window * window_track_list_open(ride_list_item item)
|
|||
window_push_others_right(w);
|
||||
_currentTrackPieceDirection = 2;
|
||||
|
||||
_trackDesignPreviewPixels = Memory::AllocateArray<uint8>(4 * TRACK_PREVIEW_IMAGE_SIZE);
|
||||
_trackDesignPreviewPixels.resize(4 * TRACK_PREVIEW_IMAGE_SIZE);
|
||||
|
||||
_loadedTrackDesign = nullptr;
|
||||
_loadedTrackDesignIndex = TRACK_DESIGN_INDEX_UNLOADED;
|
||||
|
@ -194,7 +191,7 @@ static void window_track_list_filter_list()
|
|||
// Nothing to filter, so fill the list with all indices
|
||||
if (String::LengthOf(_filterString) == 0)
|
||||
{
|
||||
for (uint16 i = 0; i < _trackDesignsCount; i++)
|
||||
for (uint16 i = 0; i < _trackDesigns.size(); i++)
|
||||
_filteredTrackIds.push_back(i);
|
||||
|
||||
return;
|
||||
|
@ -207,7 +204,7 @@ static void window_track_list_filter_list()
|
|||
filterStringLower[i] = (utf8)tolower(filterStringLower[i]);
|
||||
|
||||
// Fill the set with indices for tracks that match the filter
|
||||
for (uint16 i = 0; i < _trackDesignsCount; i++)
|
||||
for (uint16 i = 0; i < _trackDesigns.size(); i++)
|
||||
{
|
||||
utf8 trackNameLower[USER_STRING_MAX_LENGTH];
|
||||
String::Set(trackNameLower, sizeof(trackNameLower), _trackDesigns[i].name);
|
||||
|
@ -230,15 +227,16 @@ static void window_track_list_close(rct_window *w)
|
|||
// Dispose track design and preview
|
||||
track_design_dispose(_loadedTrackDesign);
|
||||
_loadedTrackDesign = nullptr;
|
||||
SafeFree(_trackDesignPreviewPixels);
|
||||
_trackDesignPreviewPixels.clear();
|
||||
_trackDesignPreviewPixels.shrink_to_fit();
|
||||
|
||||
// Dispose track list
|
||||
for (size_t i = 0; i < _trackDesignsCount; i++) {
|
||||
free(_trackDesigns[i].name);
|
||||
free(_trackDesigns[i].path);
|
||||
for (auto &trackDesign : _trackDesigns)
|
||||
{
|
||||
free(trackDesign.name);
|
||||
free(trackDesign.path);
|
||||
}
|
||||
SafeFree(_trackDesigns);
|
||||
_trackDesignsCount = 0;
|
||||
_trackDesigns.clear();
|
||||
|
||||
// If gScreenAge is zero, we're already in the process
|
||||
// of loading the track manager, so we shouldn't try
|
||||
|
@ -501,7 +499,7 @@ static void window_track_list_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
sint32 listItemIndex = w->selected_list_item;
|
||||
if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER)
|
||||
{
|
||||
if (_trackDesignsCount == 0 || listItemIndex == -1)
|
||||
if (_trackDesigns.size() == 0 || listItemIndex == -1)
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
@ -538,7 +536,7 @@ static void window_track_list_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
}
|
||||
|
||||
rct_g1_element g1temp = { nullptr };
|
||||
g1temp.offset = _trackDesignPreviewPixels + (_currentTrackPieceDirection * TRACK_PREVIEW_IMAGE_SIZE);
|
||||
g1temp.offset = _trackDesignPreviewPixels.data() + (_currentTrackPieceDirection * TRACK_PREVIEW_IMAGE_SIZE);
|
||||
g1temp.width = 370;
|
||||
g1temp.height = 217;
|
||||
g1temp.flags = G1_FLAG_BMP;
|
||||
|
@ -684,7 +682,7 @@ static void window_track_list_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi,
|
|||
sint32 y = 0;
|
||||
size_t listIndex = 0;
|
||||
if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) {
|
||||
if (_trackDesignsCount == 0) {
|
||||
if (_trackDesigns.size() == 0) {
|
||||
// No track designs
|
||||
gfx_draw_string_left(dpi, STR_NO_TRACK_DESIGNS_OF_THIS_TYPE, nullptr, COLOUR_BLACK, x, y - 1);
|
||||
return;
|
||||
|
@ -735,6 +733,7 @@ static void window_track_list_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi,
|
|||
|
||||
static void track_list_load_designs(ride_list_item item)
|
||||
{
|
||||
auto repo = GetTrackDesignRepository();
|
||||
if (!RideGroupManager::RideTypeHasRideGroups(item.type))
|
||||
{
|
||||
char entry[9];
|
||||
|
@ -747,13 +746,14 @@ static void track_list_load_designs(ride_list_item item)
|
|||
entryPtr = entry;
|
||||
}
|
||||
}
|
||||
_trackDesignsCount = track_repository_get_items_for_ride(&_trackDesigns, item.type, entryPtr);
|
||||
|
||||
_trackDesigns = repo->GetItemsForObjectEntry(item.type, String::ToStd(entryPtr));
|
||||
}
|
||||
else
|
||||
{
|
||||
rct_ride_entry *rideEntry = get_ride_entry(item.entry_index);
|
||||
const RideGroup * rideGroup = RideGroupManager::GetRideGroup(item.type, rideEntry);
|
||||
_trackDesignsCount = track_repository_get_items_for_ride_group(&_trackDesigns, item.type, rideGroup);
|
||||
auto rideEntry = get_ride_entry(item.entry_index);
|
||||
auto rideGroup = RideGroupManager::GetRideGroup(item.type, rideEntry);
|
||||
_trackDesigns = repo->GetItemsForRideGroup(item.type, rideGroup);
|
||||
}
|
||||
|
||||
window_track_list_filter_list();
|
||||
|
@ -767,7 +767,7 @@ static bool track_list_load_design_for_preview(utf8 *path)
|
|||
|
||||
_loadedTrackDesign = track_design_open(path);
|
||||
if (_loadedTrackDesign != nullptr && drawing_engine_get_type() != DRAWING_ENGINE_OPENGL) {
|
||||
track_design_draw_preview(_loadedTrackDesign, _trackDesignPreviewPixels);
|
||||
track_design_draw_preview(_loadedTrackDesign, _trackDesignPreviewPixels.data());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -99,6 +99,8 @@ private:
|
|||
return DIRBASE::RCT1;
|
||||
case PATHID::SCORES_RCT2:
|
||||
return DIRBASE::RCT2;
|
||||
case PATHID::CHANGELOG:
|
||||
return DIRBASE::DOCUMENTATION;
|
||||
case PATHID::NETWORK_GROUPS:
|
||||
case PATHID::NETWORK_SERVERS:
|
||||
case PATHID::NETWORK_USERS:
|
||||
|
@ -134,6 +136,7 @@ IPlatformEnvironment * OpenRCT2::CreatePlatformEnvironment()
|
|||
basePaths[(size_t)DIRBASE::USER] = Path::Combine(Platform::GetFolderPath(SPECIAL_FOLDER::USER_DATA), subDirectory);
|
||||
basePaths[(size_t)DIRBASE::CONFIG] = Path::Combine(Platform::GetFolderPath(SPECIAL_FOLDER::USER_CONFIG), subDirectory);
|
||||
basePaths[(size_t)DIRBASE::CACHE] = Path::Combine(Platform::GetFolderPath(SPECIAL_FOLDER::USER_CACHE), subDirectory);
|
||||
basePaths[(size_t)DIRBASE::DOCUMENTATION] = Platform::GetDocsPath();
|
||||
|
||||
// Override paths that have been specified via the command line
|
||||
if (!String::IsNullOrEmpty(gCustomRCT2DataPath))
|
||||
|
@ -151,6 +154,11 @@ IPlatformEnvironment * OpenRCT2::CreatePlatformEnvironment()
|
|||
basePaths[(size_t)DIRBASE::CACHE] = gCustomUserDataPath;
|
||||
}
|
||||
|
||||
if (basePaths[(size_t)DIRBASE::DOCUMENTATION].empty())
|
||||
{
|
||||
basePaths[(size_t)DIRBASE::DOCUMENTATION] = basePaths[(size_t)DIRBASE::OPENRCT2];
|
||||
}
|
||||
|
||||
auto env = OpenRCT2::CreatePlatformEnvironment(basePaths);
|
||||
|
||||
// Now load the config so we can get the RCT1 and RCT2 paths
|
||||
|
@ -206,7 +214,7 @@ const char * PlatformEnvironment::DirectoryNamesOpenRCT2[] =
|
|||
"scenario", // SCENARIO
|
||||
"screenshot", // SCREENSHOT
|
||||
"sequence", // SEQUENCE
|
||||
"shader", // SHADER
|
||||
"shaders", // SHADER
|
||||
"themes", // THEME
|
||||
"track", // TRACK
|
||||
};
|
||||
|
@ -225,5 +233,6 @@ const char * PlatformEnvironment::FileNames[] =
|
|||
"highscores.dat", // SCORES
|
||||
"scores.dat", // SCORES (LEGACY)
|
||||
"Saved Games" PATH_SEPARATOR "scores.dat", // SCORES (RCT2)
|
||||
"changelog.txt" // CHANGELOG
|
||||
};
|
||||
// clang-format on
|
||||
|
|
|
@ -31,8 +31,9 @@ namespace OpenRCT2
|
|||
USER, // Base directory for OpenRCT2 user content.
|
||||
CONFIG, // Base directory for OpenRCT2 configuration.
|
||||
CACHE, // Base directory for OpenRCT2 cache files.
|
||||
DOCUMENTATION, // Base directory for OpenRCT2 doc files.
|
||||
};
|
||||
constexpr sint32 DIRBASE_COUNT = 6;
|
||||
constexpr sint32 DIRBASE_COUNT = 7;
|
||||
using DIRBASE_VALUES = std::string[DIRBASE_COUNT];
|
||||
|
||||
enum class DIRID
|
||||
|
@ -67,6 +68,7 @@ namespace OpenRCT2
|
|||
SCORES, // Scenario scores (highscores.dat).
|
||||
SCORES_LEGACY, // Scenario scores, legacy (scores.dat).
|
||||
SCORES_RCT2, // Scenario scores, rct2 (\Saved Games\scores.dat).
|
||||
CHANGELOG, // Notable changes to the game between versions, distributed with the game.
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -69,11 +69,6 @@ float platform_get_default_scale() {
|
|||
return displayScale;
|
||||
}
|
||||
|
||||
void platform_get_changelog_path(utf8 *outPath, size_t outSize)
|
||||
{
|
||||
STUB();
|
||||
}
|
||||
|
||||
bool platform_get_steam_path(utf8 * outPath, size_t outSize)
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -108,27 +108,6 @@ void platform_posix_sub_resolve_openrct_data_path(utf8 *out, size_t size) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default directory fallback is:
|
||||
* - <exePath>/doc
|
||||
* - /usr/share/doc/openrct2
|
||||
*/
|
||||
static void platform_posix_sub_resolve_openrct_doc_path(utf8 *out, size_t size) {
|
||||
static const utf8 *searchLocations[] = {
|
||||
"./doc",
|
||||
"/usr/share/doc/openrct2",
|
||||
};
|
||||
for (auto searchLocation : searchLocations)
|
||||
{
|
||||
log_verbose("Looking for OpenRCT2 doc path at %s", searchLocation);
|
||||
if (platform_directory_exists(searchLocation))
|
||||
{
|
||||
safe_strcpy(out, searchLocation, size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16 platform_get_locale_language(){
|
||||
const char *langString = setlocale(LC_MESSAGES, "");
|
||||
if(langString != NULL){
|
||||
|
@ -218,12 +197,6 @@ uint8 platform_get_locale_measurement_format(){
|
|||
return MEASUREMENT_FORMAT_METRIC;
|
||||
}
|
||||
|
||||
void platform_get_changelog_path(utf8 *outPath, size_t outSize)
|
||||
{
|
||||
platform_posix_sub_resolve_openrct_doc_path(outPath, outSize);
|
||||
safe_strcat_path(outPath, "changelog.txt", outSize);
|
||||
}
|
||||
|
||||
bool platform_get_steam_path(utf8 * outPath, size_t outSize)
|
||||
{
|
||||
const char * steamRoot = getenv("STEAMROOT");
|
||||
|
|
|
@ -34,6 +34,11 @@ namespace Platform
|
|||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetDocsPath()
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <pwd.h>
|
||||
#include "../core/Path.hpp"
|
||||
#include "platform.h"
|
||||
#include "Platform2.h"
|
||||
|
||||
namespace Platform
|
||||
|
@ -44,6 +45,24 @@ namespace Platform
|
|||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetDocsPath()
|
||||
{
|
||||
static const utf8 * searchLocations[] =
|
||||
{
|
||||
"./doc",
|
||||
"/usr/share/doc/openrct2",
|
||||
};
|
||||
for (auto searchLocation : searchLocations)
|
||||
{
|
||||
log_verbose("Looking for OpenRCT2 doc path at %s", searchLocation);
|
||||
if (platform_directory_exists(searchLocation))
|
||||
{
|
||||
return searchLocation;
|
||||
}
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -147,6 +147,11 @@ namespace Platform
|
|||
return path;
|
||||
}
|
||||
|
||||
std::string GetDocsPath()
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
static SYSTEMTIME TimeToSystemTime(std::time_t timestamp)
|
||||
{
|
||||
LONGLONG ll = Int32x32To64(timestamp, 10000000) + 116444736000000000;
|
||||
|
|
|
@ -39,6 +39,11 @@ namespace Platform
|
|||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetDocsPath()
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -36,6 +36,7 @@ namespace Platform
|
|||
std::string GetEnvironmentVariable(const std::string &name);
|
||||
std::string GetFolderPath(SPECIAL_FOLDER folder);
|
||||
std::string GetInstallPath();
|
||||
std::string GetDocsPath();
|
||||
|
||||
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__)
|
||||
std::string GetEnvironmentPath(const char * name);
|
||||
|
|
|
@ -244,12 +244,6 @@ void platform_get_openrct_data_path(utf8 *outPath, size_t outSize)
|
|||
safe_strcpy(outPath, _openrctDataDirectoryPath, outSize);
|
||||
}
|
||||
|
||||
void platform_get_changelog_path(utf8 *outPath, size_t outSize)
|
||||
{
|
||||
safe_strcpy(outPath, gExePath, outSize);
|
||||
safe_strcat_path(outPath, "changelog.txt", outSize);
|
||||
}
|
||||
|
||||
bool platform_get_steam_path(utf8 * outPath, size_t outSize)
|
||||
{
|
||||
wchar_t * wSteamPath;
|
||||
|
|
|
@ -127,7 +127,6 @@ uint8 platform_get_locale_measurement_format();
|
|||
uint8 platform_get_locale_temperature_format();
|
||||
uint8 platform_get_locale_date_format();
|
||||
bool platform_process_is_elevated();
|
||||
void platform_get_changelog_path(utf8 *outPath, size_t outSize);
|
||||
bool platform_get_steam_path(utf8 * outPath, size_t outSize);
|
||||
|
||||
#ifndef NO_TTF
|
||||
|
|
|
@ -114,7 +114,7 @@ rct_track_td6 * track_design_open(const utf8 * path)
|
|||
|
||||
if (td6 != nullptr)
|
||||
{
|
||||
td6->name = track_repository_get_name_from_path(path);
|
||||
td6->name = String::Duplicate(GetNameFromTrackPath(path).c_str());
|
||||
return td6;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ enum TRACK_REPO_ITEM_FLAGS
|
|||
TRIF_READ_ONLY = (1 << 0),
|
||||
};
|
||||
|
||||
static std::string GetNameFromTrackPath(const std::string &path)
|
||||
std::string GetNameFromTrackPath(const std::string &path)
|
||||
{
|
||||
std::string name = Path::GetFileNameWithoutExtension(path);
|
||||
//The track name should be the file name until the first instance of a dot
|
||||
|
@ -222,7 +222,7 @@ public:
|
|||
* @param entry The entry name to build a track list for. Leave empty to build track list for the non-separated types (e.g. Hyper-Twister, Car Ride)
|
||||
* @return
|
||||
*/
|
||||
size_t GetItemsForObjectEntry(track_design_file_ref * * outRefs, uint8 rideType, const std::string &entry) const override
|
||||
std::vector<track_design_file_ref> GetItemsForObjectEntry(uint8 rideType, const std::string &entry) const override
|
||||
{
|
||||
std::vector<track_design_file_ref> refs;
|
||||
const IObjectRepository * repo = GetObjectRepository();
|
||||
|
@ -252,11 +252,10 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
*outRefs = Collections::ToArray(refs);
|
||||
return refs.size();
|
||||
return refs;
|
||||
}
|
||||
|
||||
size_t GetItemsForRideGroup(track_design_file_ref **outRefs, uint8 rideType, const RideGroup * rideGroup) const override
|
||||
std::vector<track_design_file_ref> GetItemsForRideGroup(uint8 rideType, const RideGroup * rideGroup) const override
|
||||
{
|
||||
std::vector<track_design_file_ref> refs;
|
||||
const IObjectRepository * repo = GetObjectRepository();
|
||||
|
@ -281,8 +280,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
*outRefs = Collections::ToArray(refs);
|
||||
return refs.size();
|
||||
return refs;
|
||||
}
|
||||
|
||||
void Scan() override
|
||||
|
@ -418,18 +416,6 @@ extern "C"
|
|||
repo->Scan();
|
||||
}
|
||||
|
||||
size_t track_repository_get_items_for_ride(track_design_file_ref * * outRefs, uint8 rideType, const utf8 * entry)
|
||||
{
|
||||
ITrackDesignRepository * repo = GetTrackDesignRepository();
|
||||
return repo->GetItemsForObjectEntry(outRefs, rideType, String::ToStd(entry));
|
||||
}
|
||||
|
||||
size_t track_repository_get_items_for_ride_group(track_design_file_ref * * outRefs, uint8 rideType, const RideGroup * rideGroup)
|
||||
{
|
||||
ITrackDesignRepository * repo = GetTrackDesignRepository();
|
||||
return repo->GetItemsForRideGroup(outRefs, rideType, rideGroup);
|
||||
}
|
||||
|
||||
bool track_repository_delete(const utf8 * path)
|
||||
{
|
||||
ITrackDesignRepository * repo = GetTrackDesignRepository();
|
||||
|
@ -449,9 +435,4 @@ extern "C"
|
|||
std::string newPath = repo->Install(srcPath);
|
||||
return !newPath.empty();
|
||||
}
|
||||
|
||||
utf8 * track_repository_get_name_from_path(const utf8 * path)
|
||||
{
|
||||
return String::Duplicate(GetNameFromTrackPath(path));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,12 +42,10 @@ interface ITrackDesignRepository
|
|||
virtual size_t GetCount() const abstract;
|
||||
virtual size_t GetCountForObjectEntry(uint8 rideType, const std::string &entry) const abstract;
|
||||
virtual size_t GetCountForRideGroup(uint8 rideType, const RideGroup * rideGroup) const abstract;
|
||||
virtual size_t GetItemsForObjectEntry(track_design_file_ref * * outRefs,
|
||||
uint8 rideType,
|
||||
const std::string &entry) const abstract;
|
||||
virtual size_t GetItemsForRideGroup(track_design_file_ref **outRefs,
|
||||
uint8 rideType,
|
||||
const RideGroup * rideGroup) const abstract;
|
||||
virtual std::vector<track_design_file_ref> GetItemsForObjectEntry(uint8 rideType,
|
||||
const std::string &entry) const abstract;
|
||||
virtual std::vector<track_design_file_ref> GetItemsForRideGroup(uint8 rideType,
|
||||
const RideGroup * rideGroup) const abstract;
|
||||
|
||||
virtual void Scan() abstract;
|
||||
virtual bool Delete(const std::string &path) abstract;
|
||||
|
@ -57,6 +55,7 @@ interface ITrackDesignRepository
|
|||
|
||||
ITrackDesignRepository * CreateTrackDesignRepository(OpenRCT2::IPlatformEnvironment * env);
|
||||
ITrackDesignRepository * GetTrackDesignRepository();
|
||||
std::string GetNameFromTrackPath(const std::string &path);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -65,9 +64,6 @@ extern "C"
|
|||
{
|
||||
#endif
|
||||
void track_repository_scan();
|
||||
size_t track_repository_get_items_for_ride(track_design_file_ref * * outRefs, uint8 rideType, const utf8 * entry);
|
||||
size_t track_repository_get_items_for_ride_group(track_design_file_ref * * outRefs, uint8 rideType, const RideGroup * rideGroup);
|
||||
utf8 * track_repository_get_name_from_path(const utf8 *path);
|
||||
bool track_repository_delete(const utf8 *path);
|
||||
bool track_repository_rename(const utf8 *path, const utf8 *newName);
|
||||
bool track_repository_install(const utf8 *srcPath);
|
||||
|
|
Loading…
Reference in New Issue