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