clang-format ui/util/windows

This commit is contained in:
clang-format 2018-06-22 23:16:39 +02:00 committed by Hielke Morsink
parent abb097124c
commit adb69a2fe8
11 changed files with 906 additions and 587 deletions

View File

@ -24,40 +24,114 @@ namespace OpenRCT2::Ui
IWindowManager* const _windowManager = CreateDummyWindowManager(); IWindowManager* const _windowManager = CreateDummyWindowManager();
public: public:
void Update() override { } void Update() override
void Draw(rct_drawpixelinfo * /*dpi*/) override { } {
}
void Draw(rct_drawpixelinfo* /*dpi*/) override
{
}
void CreateWindow() override { } void CreateWindow() override
void CloseWindow() override { } {
void RecreateWindow() override { } }
void * GetWindow() override { return nullptr; } void CloseWindow() override
int32_t GetWidth() override { return 0; } {
int32_t GetHeight() override { return 0; } }
int32_t GetScaleQuality() override { return 0; } void RecreateWindow() override
void SetFullscreenMode(FULLSCREEN_MODE /*mode*/) override { } {
std::vector<Resolution> GetFullscreenResolutions() override { return std::vector<Resolution>(); } }
bool HasFocus() override { return false; } void* GetWindow() override
bool IsMinimised() override { return false; } {
bool IsSteamOverlayActive() override { return false; } return nullptr;
void ProcessMessages() override { } }
void TriggerResize() override { } int32_t GetWidth() override
{
return 0;
}
int32_t GetHeight() override
{
return 0;
}
int32_t GetScaleQuality() override
{
return 0;
}
void SetFullscreenMode(FULLSCREEN_MODE /*mode*/) override
{
}
std::vector<Resolution> GetFullscreenResolutions() override
{
return std::vector<Resolution>();
}
bool HasFocus() override
{
return false;
}
bool IsMinimised() override
{
return false;
}
bool IsSteamOverlayActive() override
{
return false;
}
void ProcessMessages() override
{
}
void TriggerResize() override
{
}
void ShowMessageBox(const std::string &/*message*/) override { } void ShowMessageBox(const std::string& /*message*/) override
std::string ShowFileDialog(const FileDialogDesc &/*desc*/) override { return std::string(); } {
std::string ShowDirectoryDialog(const std::string &/*title*/) override { return std::string(); } }
std::string ShowFileDialog(const FileDialogDesc& /*desc*/) override
{
return std::string();
}
std::string ShowDirectoryDialog(const std::string& /*title*/) override
{
return std::string();
}
// Input // Input
const CursorState * GetCursorState() override { return nullptr; } const CursorState* GetCursorState() override
CURSOR_ID GetCursor() override { return CURSOR_ARROW; } {
void SetCursor(CURSOR_ID /*cursor*/) override { } return nullptr;
void SetCursorScale(uint8_t /*scale*/) override { } }
void SetCursorVisible(bool /*value*/) override { } CURSOR_ID GetCursor() override
void GetCursorPosition(int32_t * /*x*/, int32_t * /*y*/) override { } {
void SetCursorPosition(int32_t /*x*/, int32_t /*y*/) override { } return CURSOR_ARROW;
void SetCursorTrap(bool /*value*/) override { } }
const uint8_t * GetKeysState() override { return nullptr; } void SetCursor(CURSOR_ID /*cursor*/) override
const uint8_t * GetKeysPressed() override { return nullptr; } {
void SetKeysPressed(uint32_t /*keysym*/, uint8_t /*scancode*/) override { } }
void SetCursorScale(uint8_t /*scale*/) override
{
}
void SetCursorVisible(bool /*value*/) override
{
}
void GetCursorPosition(int32_t* /*x*/, int32_t* /*y*/) override
{
}
void SetCursorPosition(int32_t /*x*/, int32_t /*y*/) override
{
}
void SetCursorTrap(bool /*value*/) override
{
}
const uint8_t* GetKeysState() override
{
return nullptr;
}
const uint8_t* GetKeysPressed() override
{
return nullptr;
}
void SetKeysPressed(uint32_t /*keysym*/, uint8_t /*scancode*/) override
{
}
class X8DrawingEngineFactory final : public IDrawingEngineFactory class X8DrawingEngineFactory final : public IDrawingEngineFactory
{ {
@ -73,10 +147,15 @@ namespace OpenRCT2::Ui
{ {
return std::make_shared<X8DrawingEngineFactory>(); return std::make_shared<X8DrawingEngineFactory>();
} }
void DrawRainAnimation(IRainDrawer* rainDrawer, rct_drawpixelinfo* dpi, DrawRainFunc drawFunc) override { } void DrawRainAnimation(IRainDrawer* rainDrawer, rct_drawpixelinfo* dpi, DrawRainFunc drawFunc) override
{
}
// Text input // Text input
bool IsTextInputActive() override { return false; } bool IsTextInputActive() override
{
return false;
}
TextInputSession* StartTextInput([[maybe_unused]] utf8* buffer, [[maybe_unused]] size_t bufferSize) override TextInputSession* StartTextInput([[maybe_unused]] utf8* buffer, [[maybe_unused]] size_t bufferSize) override
{ {
return nullptr; return nullptr;
@ -98,9 +177,15 @@ namespace OpenRCT2::Ui
return false; return false;
} }
ITitleSequencePlayer * GetTitleSequencePlayer() override { return nullptr; } ITitleSequencePlayer* GetTitleSequencePlayer() override
{
return nullptr;
}
~DummyUiContext() { delete _windowManager; } ~DummyUiContext()
{
delete _windowManager;
}
}; };
std::shared_ptr<IUiContext> CreateDummyUiContext() std::shared_ptr<IUiContext> CreateDummyUiContext()

View File

@ -14,20 +14,55 @@ namespace OpenRCT2::Ui
class DummyWindowManager final : public IWindowManager class DummyWindowManager final : public IWindowManager
{ {
void Init() override{}; void Init() override{};
rct_window * OpenWindow(rct_windowclass /*wc*/) override { return nullptr; } rct_window* OpenWindow(rct_windowclass /*wc*/) override
rct_window * OpenView(uint8_t /*view*/) override { return nullptr; } {
rct_window * OpenDetails(uint8_t /*type*/, int32_t /*id*/) override { return nullptr; } return nullptr;
rct_window * ShowError(rct_string_id /*title*/, rct_string_id /*message*/) override { return nullptr; } }
rct_window * OpenIntent(Intent * /*intent*/) override { return nullptr; }; rct_window* OpenView(uint8_t /*view*/) override
void BroadcastIntent(const Intent &/*intent*/) override { } {
void ForceClose(rct_windowclass /*windowClass*/) override { } return nullptr;
void UpdateMapTooltip() override { } }
void HandleInput() override { } rct_window* OpenDetails(uint8_t /*type*/, int32_t /*id*/) override
void HandleKeyboard(bool /*isTitle*/) override { } {
std::string GetKeyboardShortcutString(int32_t /*shortcut*/) override { return std::string(); } return nullptr;
void SetMainView(int32_t x, int32_t y, int32_t zoom, int32_t rotation) override { } }
void UpdateMouseWheel() override { } rct_window* ShowError(rct_string_id /*title*/, rct_string_id /*message*/) override
rct_window* GetOwner(const rct_viewport* viewport) override { return nullptr; } {
return nullptr;
}
rct_window* OpenIntent(Intent* /*intent*/) override
{
return nullptr;
};
void BroadcastIntent(const Intent& /*intent*/) override
{
}
void ForceClose(rct_windowclass /*windowClass*/) override
{
}
void UpdateMapTooltip() override
{
}
void HandleInput() override
{
}
void HandleKeyboard(bool /*isTitle*/) override
{
}
std::string GetKeyboardShortcutString(int32_t /*shortcut*/) override
{
return std::string();
}
void SetMainView(int32_t x, int32_t y, int32_t zoom, int32_t rotation) override
{
}
void UpdateMouseWheel() override
{
}
rct_window* GetOwner(const rct_viewport* viewport) override
{
return nullptr;
}
}; };
IWindowManager* CreateDummyWindowManager() IWindowManager* CreateDummyWindowManager()

View File

@ -9,12 +9,13 @@
#pragma once #pragma once
#include "../Context.h"
#include "../common.h"
#include "../interface/Cursors.h"
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include "../common.h"
#include "../Context.h"
#include "../interface/Cursors.h"
struct rct_drawpixelinfo; struct rct_drawpixelinfo;
interface ITitleSequencePlayer; interface ITitleSequencePlayer;
@ -25,7 +26,8 @@ namespace OpenRCT2
{ {
interface IDrawingEngineFactory; interface IDrawingEngineFactory;
interface IRainDrawer; interface IRainDrawer;
using DrawRainFunc = void(*)(OpenRCT2::Drawing::IRainDrawer * rainDrawer, int32_t left, int32_t top, int32_t width, int32_t height); using DrawRainFunc
= void (*)(OpenRCT2::Drawing::IRainDrawer* rainDrawer, int32_t left, int32_t top, int32_t width, int32_t height);
} // namespace Drawing } // namespace Drawing
namespace Ui namespace Ui
@ -52,8 +54,7 @@ namespace OpenRCT2
inline bool operator==(const Resolution& lhs, const Resolution& rhs) inline bool operator==(const Resolution& lhs, const Resolution& rhs)
{ {
return lhs.Width == rhs.Width && return lhs.Width == rhs.Width && lhs.Height == rhs.Height;
lhs.Height == rhs.Height;
} }
inline bool operator!=(const Resolution& lhs, const Resolution& rhs) inline bool operator!=(const Resolution& lhs, const Resolution& rhs)
@ -127,7 +128,9 @@ namespace OpenRCT2
// Drawing // Drawing
virtual std::shared_ptr<Drawing::IDrawingEngineFactory> GetDrawingEngineFactory() abstract; virtual std::shared_ptr<Drawing::IDrawingEngineFactory> GetDrawingEngineFactory() abstract;
virtual void DrawRainAnimation(OpenRCT2::Drawing::IRainDrawer* rainDrawer, rct_drawpixelinfo* dpi, OpenRCT2::Drawing::DrawRainFunc drawFunc) abstract; virtual void DrawRainAnimation(
OpenRCT2::Drawing::IRainDrawer * rainDrawer, rct_drawpixelinfo * dpi, OpenRCT2::Drawing::DrawRainFunc drawFunc)
abstract;
// Text input // Text input
virtual bool IsTextInputActive() abstract; virtual bool IsTextInputActive() abstract;

View File

@ -9,11 +9,11 @@
#pragma once #pragma once
#include <string>
#include "../windows/Intent.h"
#include "../common.h" #include "../common.h"
#include "../interface/Window.h" #include "../interface/Window.h"
#include "../windows/Intent.h"
#include <string>
namespace OpenRCT2::Ui namespace OpenRCT2::Ui
{ {

View File

@ -7,14 +7,15 @@
* OpenRCT2 is licensed under the GNU General Public License version 3. * OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/ *****************************************************************************/
#include <cstring> #include "SawyerCoding.h"
#include "../core/Math.hpp" #include "../core/Math.hpp"
#include "../platform/platform.h" #include "../platform/platform.h"
#include "../scenario/Scenario.h" #include "../scenario/Scenario.h"
#include "SawyerCoding.h"
#include "Util.h" #include "Util.h"
#include <cstring>
static size_t decode_chunk_rle(const uint8_t* src_buffer, uint8_t* dst_buffer, size_t length); static size_t decode_chunk_rle(const uint8_t* src_buffer, uint8_t* dst_buffer, size_t length);
static size_t decode_chunk_rle_with_size(const uint8_t* src_buffer, uint8_t* dst_buffer, size_t length, size_t dstSize); static size_t decode_chunk_rle_with_size(const uint8_t* src_buffer, uint8_t* dst_buffer, size_t length, size_t dstSize);
@ -39,15 +40,19 @@ uint32_t sawyercoding_calculate_checksum(const uint8_t* buffer, size_t length)
* rct2: 0x006762E1 * rct2: 0x006762E1
* *
*/ */
size_t sawyercoding_write_chunk_buffer(uint8_t *dst_file, const uint8_t* buffer, sawyercoding_chunk_header chunkHeader) { size_t sawyercoding_write_chunk_buffer(uint8_t* dst_file, const uint8_t* buffer, sawyercoding_chunk_header chunkHeader)
{
uint8_t *encode_buffer, *encode_buffer2; uint8_t *encode_buffer, *encode_buffer2;
if (gUseRLE == false) { if (gUseRLE == false)
if (chunkHeader.encoding == CHUNK_ENCODING_RLE || chunkHeader.encoding == CHUNK_ENCODING_RLECOMPRESSED) { {
if (chunkHeader.encoding == CHUNK_ENCODING_RLE || chunkHeader.encoding == CHUNK_ENCODING_RLECOMPRESSED)
{
chunkHeader.encoding = CHUNK_ENCODING_NONE; chunkHeader.encoding = CHUNK_ENCODING_NONE;
} }
} }
switch (chunkHeader.encoding){ switch (chunkHeader.encoding)
{
case CHUNK_ENCODING_NONE: case CHUNK_ENCODING_NONE:
memcpy(dst_file, &chunkHeader, sizeof(sawyercoding_chunk_header)); memcpy(dst_file, &chunkHeader, sizeof(sawyercoding_chunk_header));
dst_file += sizeof(sawyercoding_chunk_header); dst_file += sizeof(sawyercoding_chunk_header);
@ -107,7 +112,8 @@ size_t sawyercoding_decode_sc4(const uint8_t *src, uint8_t *dst, size_t length,
for (size_t i = 0x60018; i <= std::min(decodedLength - 1, (size_t)0x1F8353); i++) for (size_t i = 0x60018; i <= std::min(decodedLength - 1, (size_t)0x1F8353); i++)
dst[i] = dst[i] ^ 0x9C; dst[i] = dst[i] ^ 0x9C;
for (size_t i = 0x60018; i <= std::min(decodedLength - 1, (size_t)0x1F8350); i += 4) { for (size_t i = 0x60018; i <= std::min(decodedLength - 1, (size_t)0x1F8350); i += 4)
{
dst[i + 1] = ror8(dst[i + 1], 3); dst[i + 1] = ror8(dst[i + 1], 3);
uint32_t* code = (uint32_t*)&dst[i]; uint32_t* code = (uint32_t*)&dst[i];
@ -137,11 +143,13 @@ size_t sawyercoding_decode_td6(const uint8_t *src, uint8_t *dst, size_t length)
return decode_chunk_rle(src, dst, length - 4); return decode_chunk_rle(src, dst, length - 4);
} }
size_t sawyercoding_encode_td6(const uint8_t* src, uint8_t* dst, size_t length){ size_t sawyercoding_encode_td6(const uint8_t* src, uint8_t* dst, size_t length)
{
size_t output_length = encode_chunk_rle(src, dst, length); size_t output_length = encode_chunk_rle(src, dst, length);
uint32_t checksum = 0; uint32_t checksum = 0;
for (size_t i = 0; i < output_length; i++){ for (size_t i = 0; i < output_length; i++)
{
uint8_t new_byte = ((checksum & 0xFF) + dst[i]) & 0xFF; uint8_t new_byte = ((checksum & 0xFF) + dst[i]) & 0xFF;
checksum = (checksum & 0xFFFFFF00) + new_byte; checksum = (checksum & 0xFFFFFF00) + new_byte;
checksum = rol32(checksum, 3); checksum = rol32(checksum, 3);
@ -154,11 +162,13 @@ size_t sawyercoding_encode_td6(const uint8_t* src, uint8_t* dst, size_t length){
} }
/* Based off of rct2: 0x006770C1 */ /* Based off of rct2: 0x006770C1 */
int32_t sawyercoding_validate_track_checksum(const uint8_t* src, size_t length){ int32_t sawyercoding_validate_track_checksum(const uint8_t* src, size_t length)
{
uint32_t file_checksum = *((uint32_t*)&src[length - 4]); uint32_t file_checksum = *((uint32_t*)&src[length - 4]);
uint32_t checksum = 0; uint32_t checksum = 0;
for (size_t i = 0; i < length - 4; i++){ for (size_t i = 0; i < length - 4; i++)
{
uint8_t new_byte = ((checksum & 0xFF) + src[i]) & 0xFF; uint8_t new_byte = ((checksum & 0xFF) + src[i]) & 0xFF;
checksum = (checksum & 0xFFFFFF00) + new_byte; checksum = (checksum & 0xFFFFFF00) + new_byte;
checksum = rol32(checksum, 3); checksum = rol32(checksum, 3);
@ -187,14 +197,18 @@ static size_t decode_chunk_rle(const uint8_t* src_buffer, uint8_t* dst_buffer, s
dst = dst_buffer; dst = dst_buffer;
for (size_t i = 0; i < length; i++) { for (size_t i = 0; i < length; i++)
{
rleCodeByte = src_buffer[i]; rleCodeByte = src_buffer[i];
if (rleCodeByte & 128) { if (rleCodeByte & 128)
{
i++; i++;
count = 257 - rleCodeByte; count = 257 - rleCodeByte;
memset(dst, src_buffer[i], count); memset(dst, src_buffer[i], count);
dst = (uint8_t*)((uintptr_t)dst + count); dst = (uint8_t*)((uintptr_t)dst + count);
} else { }
else
{
memcpy(dst, src_buffer + i + 1, rleCodeByte + 1); memcpy(dst, src_buffer + i + 1, rleCodeByte + 1);
dst = (uint8_t*)((uintptr_t)dst + rleCodeByte + 1); dst = (uint8_t*)((uintptr_t)dst + rleCodeByte + 1);
i += rleCodeByte + 1; i += rleCodeByte + 1;
@ -218,16 +232,20 @@ static size_t decode_chunk_rle_with_size(const uint8_t* src_buffer, uint8_t* dst
assert(length > 0); assert(length > 0);
assert(dstSize > 0); assert(dstSize > 0);
for (size_t i = 0; i < length; i++) { for (size_t i = 0; i < length; i++)
{
rleCodeByte = src_buffer[i]; rleCodeByte = src_buffer[i];
if (rleCodeByte & 128) { if (rleCodeByte & 128)
{
i++; i++;
count = 257 - rleCodeByte; count = 257 - rleCodeByte;
assert(dst + count <= dst_buffer + dstSize); assert(dst + count <= dst_buffer + dstSize);
assert(i < length); assert(i < length);
memset(dst, src_buffer[i], count); memset(dst, src_buffer[i], count);
dst = (uint8_t*)((uintptr_t)dst + count); dst = (uint8_t*)((uintptr_t)dst + count);
} else { }
else
{
assert(dst + rleCodeByte + 1 <= dst_buffer + dstSize); assert(dst + rleCodeByte + 1 <= dst_buffer + dstSize);
assert(i + 1 < length); assert(i + 1 < length);
memcpy(dst, src_buffer + i + 1, rleCodeByte + 1); memcpy(dst, src_buffer + i + 1, rleCodeByte + 1);
@ -256,18 +274,22 @@ static size_t encode_chunk_rle(const uint8_t *src_buffer, uint8_t *dst_buffer, s
uint8_t count = 0; uint8_t count = 0;
const uint8_t* src_norm_start = src; const uint8_t* src_norm_start = src;
while (src < end_src - 1){ while (src < end_src - 1)
{
if ((count && *src == src[1]) || count > 125){ if ((count && *src == src[1]) || count > 125)
{
*dst++ = count - 1; *dst++ = count - 1;
memcpy(dst, src_norm_start, count); memcpy(dst, src_norm_start, count);
dst += count; dst += count;
src_norm_start += count; src_norm_start += count;
count = 0; count = 0;
} }
if (*src == src[1]){ if (*src == src[1])
for (; (count < 125) && ((src + count) < end_src); count++){ {
if (*src != src[count]) break; for (; (count < 125) && ((src + count) < end_src); count++)
{
if (*src != src[count])
break;
} }
*dst++ = 257 - count; *dst++ = 257 - count;
*dst++ = *src; *dst++ = *src;
@ -275,13 +297,16 @@ static size_t encode_chunk_rle(const uint8_t *src_buffer, uint8_t *dst_buffer, s
src_norm_start = src; src_norm_start = src;
count = 0; count = 0;
} }
else{ else
{
count++; count++;
src++; src++;
} }
} }
if (src == end_src - 1)count++; if (src == end_src - 1)
if (count){ count++;
if (count)
{
*dst++ = count - 1; *dst++ = count - 1;
memcpy(dst, src_norm_start, count); memcpy(dst, src_norm_start, count);
dst += count; dst += count;
@ -302,26 +327,33 @@ static size_t encode_chunk_repeat(const uint8_t *src_buffer, uint8_t *dst_buffer
outLength += 2; outLength += 2;
// Iterate through remainder of the source buffer // Iterate through remainder of the source buffer
for (size_t i = 1; i < length; ) { for (size_t i = 1; i < length;)
{
size_t searchIndex = (i < 32) ? 0 : (i - 32); size_t searchIndex = (i < 32) ? 0 : (i - 32);
size_t searchEnd = i - 1; size_t searchEnd = i - 1;
size_t bestRepeatIndex = 0; size_t bestRepeatIndex = 0;
size_t bestRepeatCount = 0; size_t bestRepeatCount = 0;
for (size_t repeatIndex = searchIndex; repeatIndex <= searchEnd; repeatIndex++) { for (size_t repeatIndex = searchIndex; repeatIndex <= searchEnd; repeatIndex++)
{
size_t repeatCount = 0; size_t repeatCount = 0;
size_t maxRepeatCount = std::min(std::min((size_t)7, searchEnd - repeatIndex), length - i - 1); size_t maxRepeatCount = std::min(std::min((size_t)7, searchEnd - repeatIndex), length - i - 1);
// maxRepeatCount should not exceed length // maxRepeatCount should not exceed length
assert(repeatIndex + maxRepeatCount < length); assert(repeatIndex + maxRepeatCount < length);
assert(i + maxRepeatCount < length); assert(i + maxRepeatCount < length);
for (size_t j = 0; j <= maxRepeatCount; j++) { for (size_t j = 0; j <= maxRepeatCount; j++)
if (src_buffer[repeatIndex + j] == src_buffer[i + j]) { {
if (src_buffer[repeatIndex + j] == src_buffer[i + j])
{
repeatCount++; repeatCount++;
} else { }
else
{
break; break;
} }
} }
if (repeatCount > bestRepeatCount) { if (repeatCount > bestRepeatCount)
{
bestRepeatIndex = repeatIndex; bestRepeatIndex = repeatIndex;
bestRepeatCount = repeatCount; bestRepeatCount = repeatCount;
@ -331,12 +363,15 @@ static size_t encode_chunk_repeat(const uint8_t *src_buffer, uint8_t *dst_buffer
} }
} }
if (bestRepeatCount == 0) { if (bestRepeatCount == 0)
{
*dst_buffer++ = 255; *dst_buffer++ = 255;
*dst_buffer++ = src_buffer[i]; *dst_buffer++ = src_buffer[i];
outLength += 2; outLength += 2;
i++; i++;
} else { }
else
{
*dst_buffer++ = (uint8_t)((bestRepeatCount - 1) | ((32 - (i - bestRepeatIndex)) << 3)); *dst_buffer++ = (uint8_t)((bestRepeatCount - 1) | ((32 - (i - bestRepeatIndex)) << 3));
outLength++; outLength++;
i += bestRepeatCount; i += bestRepeatCount;
@ -350,7 +385,8 @@ static void encode_chunk_rotate(uint8_t *buffer, size_t length)
{ {
size_t i; size_t i;
uint8_t code = 1; uint8_t code = 1;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++)
{
buffer[i] = rol8(buffer[i], code); buffer[i] = rol8(buffer[i], code);
code = (code + 2) % 8; code = (code + 2) % 8;
} }
@ -366,7 +402,8 @@ int32_t sawyercoding_detect_file_type(const uint8_t *src, size_t length)
uint32_t checksum = *((uint32_t*)&src[length - 4]); uint32_t checksum = *((uint32_t*)&src[length - 4]);
uint32_t actualChecksum = 0; uint32_t actualChecksum = 0;
for (i = 0; i < length - 4; i++) { for (i = 0; i < length - 4; i++)
{
actualChecksum = (actualChecksum & 0xFFFFFF00) | (((actualChecksum & 0xFF) + (uint8_t)src[i]) & 0xFF); actualChecksum = (actualChecksum & 0xFFFFFF00) | (((actualChecksum & 0xFF) + (uint8_t)src[i]) & 0xFF);
actualChecksum = rol32(actualChecksum, 3); actualChecksum = rol32(actualChecksum, 3);
} }

View File

@ -13,22 +13,24 @@
#include "../common.h" #include "../common.h"
#pragma pack(push, 1) #pragma pack(push, 1)
struct sawyercoding_chunk_header { struct sawyercoding_chunk_header
{
uint8_t encoding; uint8_t encoding;
uint32_t length; uint32_t length;
}; };
assert_struct_size(sawyercoding_chunk_header, 5); assert_struct_size(sawyercoding_chunk_header, 5);
#pragma pack(pop) #pragma pack(pop)
enum
enum { {
CHUNK_ENCODING_NONE, CHUNK_ENCODING_NONE,
CHUNK_ENCODING_RLE, CHUNK_ENCODING_RLE,
CHUNK_ENCODING_RLECOMPRESSED, CHUNK_ENCODING_RLECOMPRESSED,
CHUNK_ENCODING_ROTATE CHUNK_ENCODING_ROTATE
}; };
enum { enum
{
FILE_VERSION_MASK = (3 << 0), FILE_VERSION_MASK = (3 << 0),
FILE_VERSION_RCT1 = (0 << 0), FILE_VERSION_RCT1 = (0 << 0),
FILE_VERSION_RCT1_AA = (1 << 0), FILE_VERSION_RCT1_AA = (1 << 0),

View File

@ -7,9 +7,8 @@
* OpenRCT2 is licensed under the GNU General Public License version 3. * OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/ *****************************************************************************/
#include <cctype> #include "Util.h"
#include <cmath>
#include <ctime>
#include "../common.h" #include "../common.h"
#include "../core/Guard.hpp" #include "../core/Guard.hpp"
#include "../core/Math.hpp" #include "../core/Math.hpp"
@ -17,9 +16,12 @@
#include "../localisation/Localisation.h" #include "../localisation/Localisation.h"
#include "../platform/platform.h" #include "../platform/platform.h"
#include "../title/TitleScreen.h" #include "../title/TitleScreen.h"
#include "Util.h"
#include "zlib.h" #include "zlib.h"
#include <cctype>
#include <cmath>
#include <ctime>
int32_t squaredmetres_to_squaredfeet(int32_t squaredMetres) int32_t squaredmetres_to_squaredfeet(int32_t squaredMetres)
{ {
// 1 metre squared = 10.7639104 feet squared // 1 metre squared = 10.7639104 feet squared
@ -49,9 +51,10 @@ int32_t mph_to_dmps(int32_t mph)
bool filename_valid_characters(const utf8* filename) bool filename_valid_characters(const utf8* filename)
{ {
for (int32_t i = 0; filename[i] != '\0'; i++) { for (int32_t i = 0; filename[i] != '\0'; i++)
if (filename[i] == '\\' || filename[i] == '/' || filename[i] == ':' || filename[i] == '?' || {
filename[i] == '*' || filename[i] == '<' || filename[i] == '>' || filename[i] == '|') if (filename[i] == '\\' || filename[i] == '/' || filename[i] == ':' || filename[i] == '?' || filename[i] == '*'
|| filename[i] == '<' || filename[i] == '>' || filename[i] == '|')
return false; return false;
} }
return true; return true;
@ -65,7 +68,8 @@ utf8 *path_get_directory(const utf8 *path)
filename = filename < filename_posix ? filename_posix : filename; filename = filename < filename_posix ? filename_posix : filename;
// If the path is invalid (e.g. just a file name), return NULL // If the path is invalid (e.g. just a file name), return NULL
if (filename == nullptr) { if (filename == nullptr)
{
return nullptr; return nullptr;
} }
@ -141,11 +145,14 @@ void path_remove_extension(utf8 *path)
log_warning("No extension found. (path = %s)", path); log_warning("No extension found. (path = %s)", path);
} }
void path_end_with_separator(utf8 *path, size_t size) { void path_end_with_separator(utf8* path, size_t size)
{
size_t length = strnlen(path, size); size_t length = strnlen(path, size);
if (length >= size - 1) return; if (length >= size - 1)
return;
if ((length == 0) || ((path[length - 1] != *PATH_SEPARATOR) && path[length - 1] != '/')) { if ((length == 0) || ((path[length - 1] != *PATH_SEPARATOR) && path[length - 1] != '/'))
{
safe_strcat(path, PATH_SEPARATOR, size); safe_strcat(path, PATH_SEPARATOR, size);
} }
} }
@ -263,17 +270,14 @@ static int32_t bitcount_popcnt(uint32_t source)
static int32_t bitcount_lut(uint32_t source) static int32_t bitcount_lut(uint32_t source)
{ {
// https://graphics.stanford.edu/~seander/bithacks.html // https://graphics.stanford.edu/~seander/bithacks.html
static constexpr const uint8_t BitsSetTable256[256] = static constexpr const uint8_t BitsSetTable256[256] = {
{
#define B2(n) n, (n) + 1, (n) + 1, (n) + 2 #define B2(n) n, (n) + 1, (n) + 1, (n) + 2
#define B4(n) B2(n), B2((n) + 1), B2((n) + 1), B2((n) + 2) #define B4(n) B2(n), B2((n) + 1), B2((n) + 1), B2((n) + 2)
#define B6(n) B4(n), B4((n) + 1), B4((n) + 1), B4((n) + 2) #define B6(n) B4(n), B4((n) + 1), B4((n) + 1), B4((n) + 2)
B6(0), B6(1), B6(1), B6(2) B6(0), B6(1), B6(1), B6(2)
}; };
return BitsSetTable256[source & 0xff] + return BitsSetTable256[source & 0xff] + BitsSetTable256[(source >> 8) & 0xff] + BitsSetTable256[(source >> 16) & 0xff]
BitsSetTable256[(source >> 8) & 0xff] + + BitsSetTable256[source >> 24];
BitsSetTable256[(source >> 16) & 0xff] +
BitsSetTable256[source >> 24];
} }
static int32_t (*bitcount_fn)(uint32_t); static int32_t (*bitcount_fn)(uint32_t);
@ -290,15 +294,14 @@ int32_t bitcount(uint32_t source)
bool strequals(const char* a, const char* b, int32_t length, bool caseInsensitive) bool strequals(const char* a, const char* b, int32_t length, bool caseInsensitive)
{ {
return caseInsensitive ? return caseInsensitive ? _strnicmp(a, b, length) == 0 : strncmp(a, b, length) == 0;
_strnicmp(a, b, length) == 0 :
strncmp(a, b, length) == 0;
} }
/* case insensitive compare */ /* case insensitive compare */
int32_t strcicmp(char const* a, char const* b) int32_t strcicmp(char const* a, char const* b)
{ {
for (;; a++, b++) { for (;; a++, b++)
{
int32_t d = tolower(*a) - tolower(*b); int32_t d = tolower(*a) - tolower(*b);
if (d != 0 || !*a) if (d != 0 || !*a)
return d; return d;
@ -312,22 +315,35 @@ int32_t strcicmp(char const *a, char const *b)
// - Guest 100 // - Guest 100
// - John v2.0 // - John v2.0
// - John v2.1 // - John v2.1
int32_t strlogicalcmp(char const *a, char const *b) { int32_t strlogicalcmp(char const* a, char const* b)
for (;; a++, b++) { {
for (;; a++, b++)
{
int32_t result = tolower(*a) - tolower(*b); int32_t result = tolower(*a) - tolower(*b);
bool both_numeric = *a >= '0' && *a <= '9' && *b >= '0' && *b <= '9'; bool both_numeric = *a >= '0' && *a <= '9' && *b >= '0' && *b <= '9';
if (result != 0 || !*a || both_numeric) { // difference found || end of string if (result != 0 || !*a || both_numeric)
if (both_numeric) { // a and b both start with a number { // difference found || end of string
if (both_numeric)
{ // a and b both start with a number
// Get the numbers in the string at current positions // Get the numbers in the string at current positions
int32_t na = 0, nb = 0; int32_t na = 0, nb = 0;
for (; *a >= '0' && *a <= '9'; a++) { na *= 10; na += *a - '0'; } for (; *a >= '0' && *a <= '9'; a++)
for (; *b >= '0' && *b <= '9'; b++) { nb *= 10; nb += *b - '0'; } {
na *= 10;
na += *a - '0';
}
for (; *b >= '0' && *b <= '9'; b++)
{
nb *= 10;
nb += *b - '0';
}
// In case the numbers are the same // In case the numbers are the same
if (na == nb) if (na == nb)
continue; continue;
return na - nb; return na - nb;
} }
else { else
{
return result; return result;
} }
} }
@ -338,16 +354,21 @@ utf8 * safe_strtrunc(utf8 * text, size_t size)
{ {
assert(text != nullptr); assert(text != nullptr);
if (size == 0) return text; if (size == 0)
return text;
const char* sourceLimit = text + size - 1; const char* sourceLimit = text + size - 1;
char* ch = text; char* ch = text;
char* last = text; char* last = text;
uint32_t codepoint; uint32_t codepoint;
while ((codepoint = utf8_get_next(ch, (const utf8 **)&ch)) != 0) { while ((codepoint = utf8_get_next(ch, (const utf8**)&ch)) != 0)
if (ch <= sourceLimit) { {
if (ch <= sourceLimit)
{
last = ch; last = ch;
} else { }
else
{
break; break;
} }
} }
@ -361,7 +382,8 @@ char *safe_strcpy(char * destination, const char * source, size_t size)
assert(destination != nullptr); assert(destination != nullptr);
assert(source != nullptr); assert(source != nullptr);
if (size == 0) return destination; if (size == 0)
return destination;
char* result = destination; char* result = destination;
@ -369,16 +391,21 @@ char *safe_strcpy(char * destination, const char * source, size_t size)
const char* sourceLimit = source + size - 1; const char* sourceLimit = source + size - 1;
const char* ch = source; const char* ch = source;
uint32_t codepoint; uint32_t codepoint;
while ((codepoint = utf8_get_next(ch, &ch)) != 0) { while ((codepoint = utf8_get_next(ch, &ch)) != 0)
if (ch <= sourceLimit) { {
if (ch <= sourceLimit)
{
destination = utf8_write_codepoint(destination, codepoint); destination = utf8_write_codepoint(destination, codepoint);
} else { }
else
{
truncated = true; truncated = true;
} }
} }
*destination = 0; *destination = 0;
if (truncated) { if (truncated)
{
log_warning("Truncating string \"%s\" to %d bytes.", result, size); log_warning("Truncating string \"%s\" to %d bytes.", result, size);
} }
return result; return result;
@ -389,33 +416,43 @@ char *safe_strcat(char *destination, const char *source, size_t size)
assert(destination != nullptr); assert(destination != nullptr);
assert(source != nullptr); assert(source != nullptr);
if (size == 0) { if (size == 0)
{
return destination; return destination;
} }
char* result = destination; char* result = destination;
size_t i; size_t i;
for (i = 0; i < size; i++) { for (i = 0; i < size; i++)
if (*destination == '\0') { {
if (*destination == '\0')
{
break; break;
} else { }
else
{
destination++; destination++;
} }
} }
bool terminated = false; bool terminated = false;
for (; i < size; i++) { for (; i < size; i++)
if (*source != '\0') { {
if (*source != '\0')
{
*destination++ = *source++; *destination++ = *source++;
} else { }
else
{
*destination = *source; *destination = *source;
terminated = true; terminated = true;
break; break;
} }
} }
if (!terminated) { if (!terminated)
{
result[size - 1] = '\0'; result[size - 1] = '\0';
log_warning("Truncating string \"%s\" to %d bytes.", result, size); log_warning("Truncating string \"%s\" to %d bytes.", result, size);
} }
@ -435,7 +472,8 @@ char *safe_strcat_path(char *destination, const char *source, size_t size)
char* safe_strtrimleft(char* destination, const char* source, size_t size) char* safe_strtrimleft(char* destination, const char* source, size_t size)
{ {
while (*source == ' ') { while (*source == ' ')
{
source++; source++;
} }
return safe_strcpy(destination, source, size); return safe_strcpy(destination, source, size);
@ -448,7 +486,8 @@ char * strcasestr(const char * haystack, const char * needle)
const char* p2 = needle; const char* p2 = needle;
const char* r = *p2 == 0 ? haystack : 0; const char* r = *p2 == 0 ? haystack : 0;
while (*p1 != 0 && *p2 != 0) { while (*p1 != 0 && *p2 != 0)
{
if (tolower((unsigned char)*p1) == tolower((unsigned char)*p2)) if (tolower((unsigned char)*p1) == tolower((unsigned char)*p2))
{ {
if (r == 0) if (r == 0)
@ -489,12 +528,14 @@ bool str_is_null_or_empty(const char *str)
return str == nullptr || str[0] == 0; return str == nullptr || str[0] == 0;
} }
void util_srand(int32_t source) { void util_srand(int32_t source)
{
srand(source); srand(source);
} }
// Caveat: rand() might only return values up to 0x7FFF, which is the minimum specified in the C standard. // Caveat: rand() might only return values up to 0x7FFF, which is the minimum specified in the C standard.
uint32_t util_rand() { uint32_t util_rand()
{
return rand(); return rand();
} }
@ -505,7 +546,8 @@ uint32_t util_rand() {
* @brief Inflates zlib-compressed data * @brief Inflates zlib-compressed data
* @param data Data to be decompressed * @param data Data to be decompressed
* @param data_in_size Size of data to be decompressed * @param data_in_size Size of data to be decompressed
* @param data_out_size Pointer to a variable where output size will be written. If not 0, it will be used to set initial output buffer size. * @param data_out_size Pointer to a variable where output size will be written. If not 0, it will be used to set initial output
* buffer size.
* @return Returns a pointer to memory holding decompressed data or NULL on failure. * @return Returns a pointer to memory holding decompressed data or NULL on failure.
* @note It is caller's responsibility to free() the returned pointer once done with it. * @note It is caller's responsibility to free() the returned pointer once done with it.
*/ */
@ -522,17 +564,22 @@ uint8_t *util_zlib_inflate(uint8_t *data, size_t data_in_size, size_t *data_out_
} }
uLongf buffer_size = out_size; uLongf buffer_size = out_size;
uint8_t* buffer = (uint8_t*)malloc(buffer_size); uint8_t* buffer = (uint8_t*)malloc(buffer_size);
do { do
{
if (ret == Z_BUF_ERROR) if (ret == Z_BUF_ERROR)
{ {
buffer_size *= 2; buffer_size *= 2;
out_size = buffer_size; out_size = buffer_size;
buffer = (uint8_t*)realloc(buffer, buffer_size); buffer = (uint8_t*)realloc(buffer, buffer_size);
} else if (ret == Z_STREAM_ERROR) { }
else if (ret == Z_STREAM_ERROR)
{
log_error("Your build is shipped with broken zlib. Please use the official build."); log_error("Your build is shipped with broken zlib. Please use the official build.");
free(buffer); free(buffer);
return nullptr; return nullptr;
} else if (ret < 0) { }
else if (ret < 0)
{
log_error("Error uncompressing data."); log_error("Error uncompressing data.");
free(buffer); free(buffer);
return nullptr; return nullptr;
@ -558,13 +605,16 @@ uint8_t *util_zlib_deflate(const uint8_t *data, size_t data_in_size, size_t *dat
uLongf out_size = (uLongf)*data_out_size; uLongf out_size = (uLongf)*data_out_size;
uLong buffer_size = compressBound((uLong)data_in_size); uLong buffer_size = compressBound((uLong)data_in_size);
uint8_t* buffer = (uint8_t*)malloc(buffer_size); uint8_t* buffer = (uint8_t*)malloc(buffer_size);
do { do
{
if (ret == Z_BUF_ERROR) if (ret == Z_BUF_ERROR)
{ {
buffer_size *= 2; buffer_size *= 2;
out_size = buffer_size; out_size = buffer_size;
buffer = (uint8_t*)realloc(buffer, buffer_size); buffer = (uint8_t*)realloc(buffer, buffer_size);
} else if (ret == Z_STREAM_ERROR) { }
else if (ret == Z_STREAM_ERROR)
{
log_error("Your build is shipped with broken zlib. Please use the official build."); log_error("Your build is shipped with broken zlib. Please use the official build.");
free(buffer); free(buffer);
return nullptr; return nullptr;
@ -578,13 +628,16 @@ uint8_t *util_zlib_deflate(const uint8_t *data, size_t data_in_size, size_t *dat
// Type-independent code left as macro to reduce duplicate code. // Type-independent code left as macro to reduce duplicate code.
#define add_clamp_body(value, value_to_add, min_cap, max_cap) \ #define add_clamp_body(value, value_to_add, min_cap, max_cap) \
if ((value_to_add > 0) && (value > (max_cap - (value_to_add)))) { \ if ((value_to_add > 0) && (value > (max_cap - (value_to_add)))) \
{ \
value = max_cap; \ value = max_cap; \
} \ } \
else if ((value_to_add < 0) && (value < (min_cap - (value_to_add)))) { \ else if ((value_to_add < 0) && (value < (min_cap - (value_to_add)))) \
{ \
value = min_cap; \ value = min_cap; \
} \ } \
else { \ else \
{ \
value += value_to_add; \ value += value_to_add; \
} }
@ -630,8 +683,10 @@ uint8_t lerp(uint8_t a, uint8_t b, float t)
float flerp(float a, float b, float t) float flerp(float a, float b, float t)
{ {
if (t <= 0) return a; if (t <= 0)
if (t >= 1) return b; return a;
if (t >= 1)
return b;
float range = b - a; float range = b - a;
float amount = range * t; float amount = range * t;
@ -660,7 +715,8 @@ uint8_t soft_light(uint8_t a, uint8_t b)
size_t strcatftime(char* buffer, size_t bufferSize, const char* format, const struct tm* tp) size_t strcatftime(char* buffer, size_t bufferSize, const char* format, const struct tm* tp)
{ {
size_t stringLen = strnlen(buffer, bufferSize); size_t stringLen = strnlen(buffer, bufferSize);
if (stringLen < bufferSize) { if (stringLen < bufferSize)
{
char* dst = buffer + stringLen; char* dst = buffer + stringLen;
size_t dstMaxSize = bufferSize - stringLen; size_t dstMaxSize = bufferSize - stringLen;
return strftime(dst, dstMaxSize, format, tp); return strftime(dst, dstMaxSize, format, tp);

View File

@ -10,9 +10,10 @@
#ifndef _UTIL_H_ #ifndef _UTIL_H_
#define _UTIL_H_ #define _UTIL_H_
#include <time.h>
#include "../common.h" #include "../common.h"
#include <time.h>
int32_t squaredmetres_to_squaredfeet(int32_t squaredMetres); int32_t squaredmetres_to_squaredfeet(int32_t squaredMetres);
int32_t metres_to_feet(int32_t metres); int32_t metres_to_feet(int32_t metres);
int32_t mph_to_kmph(int32_t mph); int32_t mph_to_kmph(int32_t mph);

View File

@ -7,10 +7,12 @@
* OpenRCT2 is licensed under the GNU General Public License version 3. * OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/ *****************************************************************************/
#include <utility>
#include "../core/Guard.hpp"
#include "Intent.h" #include "Intent.h"
#include "../core/Guard.hpp"
#include <utility>
Intent::Intent(rct_windowclass windowclass) Intent::Intent(rct_windowclass windowclass)
{ {
this->_Class = windowclass; this->_Class = windowclass;

View File

@ -9,16 +9,24 @@
#pragma once #pragma once
#include <map>
#include <string>
#include "../common.h" #include "../common.h"
#include "../interface/Window.h" #include "../interface/Window.h"
#include <map>
#include <string>
struct IntentData struct IntentData
{ {
enum DATATYPE { DT_INT, DT_STRING, DT_POINTER, DT_CLOSE_CALLBACK } type; enum DATATYPE
{
DT_INT,
DT_STRING,
DT_POINTER,
DT_CLOSE_CALLBACK
} type;
union { union
{
uint32_t unsignedInt; uint32_t unsignedInt;
int32_t signedInt; int32_t signedInt;
} intVal; } intVal;
@ -32,6 +40,7 @@ class Intent
private: private:
rct_windowclass _Class; rct_windowclass _Class;
std::map<uint32_t, IntentData> _Data; std::map<uint32_t, IntentData> _Data;
public: public:
explicit Intent(rct_windowclass windowclass); explicit Intent(rct_windowclass windowclass);
rct_windowclass GetWindowClass() const; rct_windowclass GetWindowClass() const;

View File

@ -7,12 +7,12 @@
* OpenRCT2 is licensed under the GNU General Public License version 3. * OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/ *****************************************************************************/
#include "../audio/audio.h"
#include "../Cheats.h" #include "../Cheats.h"
#include "../Context.h" #include "../Context.h"
#include "../core/Util.hpp"
#include "../Game.h" #include "../Game.h"
#include "../Input.h" #include "../Input.h"
#include "../audio/audio.h"
#include "../core/Util.hpp"
#include "../interface/Viewport.h" #include "../interface/Viewport.h"
#include "../network/network.h" #include "../network/network.h"
#include "../paint/VirtualFloor.h" #include "../paint/VirtualFloor.h"
@ -131,23 +131,23 @@ void game_command_callback_place_ride_entrance_or_exit(
[[maybe_unused]] int32_t edi, [[maybe_unused]] int32_t edi,
[[maybe_unused]] int32_t ebp) [[maybe_unused]] int32_t ebp)
{ {
audio_play_sound_at_location( audio_play_sound_at_location(SOUND_PLACE_ITEM, gCommandPosition.x, gCommandPosition.y, gCommandPosition.z);
SOUND_PLACE_ITEM,
gCommandPosition.x,
gCommandPosition.y,
gCommandPosition.z
);
Ride* ride = get_ride(gRideEntranceExitPlaceRideIndex); Ride* ride = get_ride(gRideEntranceExitPlaceRideIndex);
if (ride_are_all_possible_entrances_and_exits_built(ride)) { if (ride_are_all_possible_entrances_and_exits_built(ride))
{
tool_cancel(); tool_cancel();
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_NO_TRACK)) { if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_NO_TRACK))
{
window_close_by_class(WC_RIDE_CONSTRUCTION); window_close_by_class(WC_RIDE_CONSTRUCTION);
} }
} else { }
else
{
gRideEntranceExitPlaceType ^= 1; gRideEntranceExitPlaceType ^= 1;
gCurrentToolWidget.widget_index = (gRideEntranceExitPlaceType == ENTRANCE_TYPE_RIDE_ENTRANCE) ? gCurrentToolWidget.widget_index = (gRideEntranceExitPlaceType == ENTRANCE_TYPE_RIDE_ENTRANCE)
WC_RIDE_CONSTRUCTION__WIDX_ENTRANCE : WC_RIDE_CONSTRUCTION__WIDX_EXIT; ? WC_RIDE_CONSTRUCTION__WIDX_ENTRANCE
: WC_RIDE_CONSTRUCTION__WIDX_EXIT;
} }
} }
@ -155,7 +155,14 @@ void game_command_callback_place_ride_entrance_or_exit(
* *
* rct2: 0x006CA162 * rct2: 0x006CA162
*/ */
money32 place_provisional_track_piece(int32_t rideIndex, int32_t trackType, int32_t trackDirection, int32_t liftHillAndAlternativeState, int32_t x, int32_t y, int32_t z) money32 place_provisional_track_piece(
int32_t rideIndex,
int32_t trackType,
int32_t trackDirection,
int32_t liftHillAndAlternativeState,
int32_t x,
int32_t y,
int32_t z)
{ {
Ride* ride; Ride* ride;
money32 result; money32 result;
@ -164,7 +171,8 @@ money32 place_provisional_track_piece(int32_t rideIndex, int32_t trackType, int3
ride = get_ride(rideIndex); ride = get_ride(rideIndex);
if (ride->type == RIDE_TYPE_MAZE) if (ride->type == RIDE_TYPE_MAZE)
{ {
int32_t flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5 | GAME_COMMAND_FLAG_GHOST; // 105 int32_t flags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5
| GAME_COMMAND_FLAG_GHOST; // 105
result = maze_set_track(x, y, z, flags, true, 0, rideIndex, GC_SET_MAZE_TRACK_BUILD); result = maze_set_track(x, y, z, flags, true, 0, rideIndex, GC_SET_MAZE_TRACK_BUILD);
if (result == MONEY32_UNDEFINED) if (result == MONEY32_UNDEFINED)
return result; return result;
@ -191,7 +199,14 @@ money32 place_provisional_track_piece(int32_t rideIndex, int32_t trackType, int3
} }
else else
{ {
result = game_do_command(x, 105 | (trackDirection << 8), y, rideIndex | (trackType << 8) | (liftHillAndAlternativeState << 16), GAME_COMMAND_PLACE_TRACK, z, 0); result = game_do_command(
x,
105 | (trackDirection << 8),
y,
rideIndex | (trackType << 8) | (liftHillAndAlternativeState << 16),
GAME_COMMAND_PLACE_TRACK,
z,
0);
if (result == MONEY32_UNDEFINED) if (result == MONEY32_UNDEFINED)
return result; return result;
@ -231,7 +246,8 @@ money32 place_provisional_track_piece(int32_t rideIndex, int32_t trackType, int3
} }
} }
static std::tuple<bool, uint8_t> window_ride_construction_update_state_get_track_element() { static std::tuple<bool, uint8_t> window_ride_construction_update_state_get_track_element()
{
auto intent = Intent(INTENT_ACTION_RIDE_CONSTRUCTION_UPDATE_PIECES); auto intent = Intent(INTENT_ACTION_RIDE_CONSTRUCTION_UPDATE_PIECES);
context_broadcast_intent(&intent); context_broadcast_intent(&intent);
@ -240,7 +256,8 @@ static std::tuple<bool, uint8_t> window_ride_construction_update_state_get_track
uint8_t startBank = _previousTrackBankEnd; uint8_t startBank = _previousTrackBankEnd;
uint8_t endBank = _currentTrackBankEnd; uint8_t endBank = _currentTrackBankEnd;
if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) { if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK)
{
startSlope = _currentTrackSlopeEnd; startSlope = _currentTrackSlopeEnd;
endSlope = _previousTrackSlopeEnd; endSlope = _previousTrackSlopeEnd;
startBank = _currentTrackBankEnd; startBank = _currentTrackBankEnd;
@ -248,13 +265,16 @@ static std::tuple<bool, uint8_t> window_ride_construction_update_state_get_track
} }
uint16_t curve = _currentTrackCurve; uint16_t curve = _currentTrackCurve;
if (curve == 0xFFFF) { if (curve == 0xFFFF)
{
return std::make_tuple(false, 0); return std::make_tuple(false, 0);
} }
bool startsDiagonal = (_currentTrackPieceDirection & (1 << 2)) != 0; bool startsDiagonal = (_currentTrackPieceDirection & (1 << 2)) != 0;
if (curve == TRACK_CURVE_LEFT_LARGE || curve == TRACK_CURVE_RIGHT_LARGE) { if (curve == TRACK_CURVE_LEFT_LARGE || curve == TRACK_CURVE_RIGHT_LARGE)
if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) { {
if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK)
{
startsDiagonal = !startsDiagonal; startsDiagonal = !startsDiagonal;
} }
} }
@ -265,12 +285,18 @@ static std::tuple<bool, uint8_t> window_ride_construction_update_state_get_track
{ {
const track_descriptor* trackDescriptor = &gTrackDescriptors[i]; const track_descriptor* trackDescriptor = &gTrackDescriptors[i];
if (trackDescriptor->track_curve != curve) continue; if (trackDescriptor->track_curve != curve)
if (trackDescriptor->starts_diagonal != startsDiagonal) continue; continue;
if (trackDescriptor->slope_start != startSlope) continue; if (trackDescriptor->starts_diagonal != startsDiagonal)
if (trackDescriptor->slope_end != endSlope) continue; continue;
if (trackDescriptor->bank_start != startBank) continue; if (trackDescriptor->slope_start != startSlope)
if (trackDescriptor->bank_end != endBank) continue; continue;
if (trackDescriptor->slope_end != endSlope)
continue;
if (trackDescriptor->bank_start != startBank)
continue;
if (trackDescriptor->bank_end != endBank)
continue;
return std::make_tuple(true, trackDescriptor->track_element); return std::make_tuple(true, trackDescriptor->track_element);
} }
@ -278,15 +304,18 @@ static std::tuple<bool, uint8_t> window_ride_construction_update_state_get_track
return std::make_tuple(false, 0); return std::make_tuple(false, 0);
} }
switch (curve & 0xFF) { switch (curve & 0xFF)
{
case TRACK_ELEM_END_STATION: case TRACK_ELEM_END_STATION:
case TRACK_ELEM_S_BEND_LEFT: case TRACK_ELEM_S_BEND_LEFT:
case TRACK_ELEM_S_BEND_RIGHT: case TRACK_ELEM_S_BEND_RIGHT:
if (startSlope != TRACK_SLOPE_NONE || endSlope != TRACK_SLOPE_NONE) { if (startSlope != TRACK_SLOPE_NONE || endSlope != TRACK_SLOPE_NONE)
{
return std::make_tuple(false, 0); return std::make_tuple(false, 0);
} }
if (startBank != TRACK_BANK_NONE || endBank != TRACK_BANK_NONE) { if (startBank != TRACK_BANK_NONE || endBank != TRACK_BANK_NONE)
{
return std::make_tuple(false, 0); return std::make_tuple(false, 0);
} }
@ -294,16 +323,22 @@ static std::tuple<bool, uint8_t> window_ride_construction_update_state_get_track
case TRACK_ELEM_LEFT_VERTICAL_LOOP: case TRACK_ELEM_LEFT_VERTICAL_LOOP:
case TRACK_ELEM_RIGHT_VERTICAL_LOOP: case TRACK_ELEM_RIGHT_VERTICAL_LOOP:
if (startBank != TRACK_BANK_NONE || endBank != TRACK_BANK_NONE) { if (startBank != TRACK_BANK_NONE || endBank != TRACK_BANK_NONE)
{
return std::make_tuple(false, 0); return std::make_tuple(false, 0);
} }
if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) { if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK)
if (endSlope != TRACK_SLOPE_DOWN_25) { {
if (endSlope != TRACK_SLOPE_DOWN_25)
{
return std::make_tuple(false, 0); return std::make_tuple(false, 0);
} }
} else { }
if (startSlope != TRACK_SLOPE_UP_25) { else
{
if (startSlope != TRACK_SLOPE_UP_25)
{
return std::make_tuple(false, 0); return std::make_tuple(false, 0);
} }
} }
@ -328,30 +363,44 @@ static std::tuple<bool, uint8_t> window_ride_construction_update_state_get_track
* @param[out] _properties (edirs16) * @param[out] _properties (edirs16)
* @return (CF) * @return (CF)
*/ */
bool window_ride_construction_update_state(int32_t *_trackType, int32_t *_trackDirection, int32_t *_rideIndex, int32_t *_liftHillAndAlternativeState, int32_t *_x, int32_t *_y, int32_t *_z, int32_t *_properties) { bool window_ride_construction_update_state(
int32_t* _trackType,
int32_t* _trackDirection,
int32_t* _rideIndex,
int32_t* _liftHillAndAlternativeState,
int32_t* _x,
int32_t* _y,
int32_t* _z,
int32_t* _properties)
{
uint8_t trackType, trackDirection, rideIndex; uint8_t trackType, trackDirection, rideIndex;
uint16_t z, x, y, liftHillAndAlternativeState, properties; uint16_t z, x, y, liftHillAndAlternativeState, properties;
auto updated_element = window_ride_construction_update_state_get_track_element(); auto updated_element = window_ride_construction_update_state_get_track_element();
if (!std::get<0>(updated_element)) { if (!std::get<0>(updated_element))
{
return true; return true;
} }
trackType = std::get<1>(updated_element); trackType = std::get<1>(updated_element);
liftHillAndAlternativeState = 0; liftHillAndAlternativeState = 0;
rideIndex = _currentRideIndex; rideIndex = _currentRideIndex;
if (_currentTrackLiftHill & CONSTRUCTION_LIFT_HILL_SELECTED) { if (_currentTrackLiftHill & CONSTRUCTION_LIFT_HILL_SELECTED)
{
liftHillAndAlternativeState |= CONSTRUCTION_LIFT_HILL_SELECTED; liftHillAndAlternativeState |= CONSTRUCTION_LIFT_HILL_SELECTED;
} }
if (_currentTrackAlternative & RIDE_TYPE_ALTERNATIVE_TRACK_TYPE) { if (_currentTrackAlternative & RIDE_TYPE_ALTERNATIVE_TRACK_TYPE)
{
liftHillAndAlternativeState |= RIDE_TYPE_ALTERNATIVE_TRACK_TYPE; liftHillAndAlternativeState |= RIDE_TYPE_ALTERNATIVE_TRACK_TYPE;
} }
Ride* ride = get_ride(rideIndex); Ride* ride = get_ride(rideIndex);
if (_enabledRidePieces & (1ULL << TRACK_SLOPE_STEEP_LONG)) { if (_enabledRidePieces & (1ULL << TRACK_SLOPE_STEEP_LONG))
switch (trackType) { {
switch (trackType)
{
case TRACK_ELEM_FLAT_TO_60_DEG_UP: case TRACK_ELEM_FLAT_TO_60_DEG_UP:
trackType = TRACK_ELEM_FLAT_TO_60_DEG_UP_LONG_BASE; trackType = TRACK_ELEM_FLAT_TO_60_DEG_UP_LONG_BASE;
break; break;
@ -376,10 +425,15 @@ bool window_ride_construction_update_state(int32_t *_trackType, int32_t *_trackD
} }
} }
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_TRACK_ELEMENTS_HAVE_TWO_VARIETIES) && _currentTrackAlternative & RIDE_TYPE_ALTERNATIVE_TRACK_PIECES) { if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_TRACK_ELEMENTS_HAVE_TWO_VARIETIES)
if (ride->type != RIDE_TYPE_WATER_COASTER || trackType == TRACK_ELEM_FLAT || trackType == TRACK_ELEM_LEFT_QUARTER_TURN_5_TILES || trackType == TRACK_ELEM_RIGHT_QUARTER_TURN_5_TILES) { && _currentTrackAlternative & RIDE_TYPE_ALTERNATIVE_TRACK_PIECES)
{
if (ride->type != RIDE_TYPE_WATER_COASTER || trackType == TRACK_ELEM_FLAT
|| trackType == TRACK_ELEM_LEFT_QUARTER_TURN_5_TILES || trackType == TRACK_ELEM_RIGHT_QUARTER_TURN_5_TILES)
{
int16_t alternativeType = AlternativeTrackTypes[trackType]; int16_t alternativeType = AlternativeTrackTypes[trackType];
if (alternativeType > -1) { if (alternativeType > -1)
{
trackType = (uint8_t)alternativeType; trackType = (uint8_t)alternativeType;
} }
liftHillAndAlternativeState &= ~CONSTRUCTION_LIFT_HILL_SELECTED; liftHillAndAlternativeState &= ~CONSTRUCTION_LIFT_HILL_SELECTED;
@ -391,18 +445,21 @@ bool window_ride_construction_update_state(int32_t *_trackType, int32_t *_trackD
x = _currentTrackBeginX; x = _currentTrackBeginX;
y = _currentTrackBeginY; y = _currentTrackBeginY;
z = _currentTrackBeginZ; z = _currentTrackBeginZ;
if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) { if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK)
{
z -= trackCoordinates->z_end; z -= trackCoordinates->z_end;
trackDirection = _currentTrackPieceDirection ^ 0x02; trackDirection = _currentTrackPieceDirection ^ 0x02;
trackDirection -= trackCoordinates->rotation_end; trackDirection -= trackCoordinates->rotation_end;
trackDirection += trackCoordinates->rotation_begin; trackDirection += trackCoordinates->rotation_begin;
trackDirection &= 0x03; trackDirection &= 0x03;
if (trackCoordinates->rotation_begin & (1 << 2)) { if (trackCoordinates->rotation_begin & (1 << 2))
{
trackDirection |= 0x04; trackDirection |= 0x04;
} }
switch (trackDirection & 0x03) { switch (trackDirection & 0x03)
{
case 0: case 0:
x -= trackCoordinates->x; x -= trackCoordinates->x;
y -= trackCoordinates->y; y -= trackCoordinates->y;
@ -423,48 +480,63 @@ bool window_ride_construction_update_state(int32_t *_trackType, int32_t *_trackD
y -= trackCoordinates->x; y -= trackCoordinates->x;
break; break;
} }
} else { }
else
{
z -= trackCoordinates->z_begin; z -= trackCoordinates->z_begin;
trackDirection = _currentTrackPieceDirection; trackDirection = _currentTrackPieceDirection;
} }
bool turnOffLiftHill = false; bool turnOffLiftHill = false;
if (!(_enabledRidePieces & (1ULL << TRACK_LIFT_HILL_CURVE))) { if (!(_enabledRidePieces & (1ULL << TRACK_LIFT_HILL_CURVE)))
if (TrackFlags[trackType] & TRACK_ELEM_FLAG_CURVE_ALLOWS_LIFT) { {
if (TrackFlags[trackType] & TRACK_ELEM_FLAG_CURVE_ALLOWS_LIFT)
{
turnOffLiftHill = true; turnOffLiftHill = true;
} }
} }
if (!(TrackFlags[trackType] & TRACK_ELEM_FLAG_ALLOW_LIFT_HILL)) { if (!(TrackFlags[trackType] & TRACK_ELEM_FLAG_ALLOW_LIFT_HILL))
{
turnOffLiftHill = true; turnOffLiftHill = true;
} }
if (turnOffLiftHill && !gCheatsEnableChainLiftOnAllTrack) { if (turnOffLiftHill && !gCheatsEnableChainLiftOnAllTrack)
{
liftHillAndAlternativeState &= ~CONSTRUCTION_LIFT_HILL_SELECTED; liftHillAndAlternativeState &= ~CONSTRUCTION_LIFT_HILL_SELECTED;
_currentTrackLiftHill &= ~CONSTRUCTION_LIFT_HILL_SELECTED; _currentTrackLiftHill &= ~CONSTRUCTION_LIFT_HILL_SELECTED;
if (trackType == TRACK_ELEM_LEFT_CURVED_LIFT_HILL || trackType == TRACK_ELEM_RIGHT_CURVED_LIFT_HILL) { if (trackType == TRACK_ELEM_LEFT_CURVED_LIFT_HILL || trackType == TRACK_ELEM_RIGHT_CURVED_LIFT_HILL)
{
liftHillAndAlternativeState |= CONSTRUCTION_LIFT_HILL_SELECTED; liftHillAndAlternativeState |= CONSTRUCTION_LIFT_HILL_SELECTED;
} }
} }
if (track_element_has_speed_setting(trackType))
if (track_element_has_speed_setting(trackType)) { {
properties = _currentBrakeSpeed2; properties = _currentBrakeSpeed2;
} else { }
else
{
properties = _currentSeatRotationAngle << 12; properties = _currentSeatRotationAngle << 12;
} }
if (_trackType != NULL)
if (_trackType != NULL) *_trackType = trackType; *_trackType = trackType;
if (_trackDirection != NULL) *_trackDirection = trackDirection; if (_trackDirection != NULL)
if (_rideIndex != NULL) *_rideIndex = rideIndex; *_trackDirection = trackDirection;
if (_liftHillAndAlternativeState != NULL) *_liftHillAndAlternativeState = liftHillAndAlternativeState; if (_rideIndex != NULL)
if (_x != NULL) *_x = x; *_rideIndex = rideIndex;
if (_y != NULL) *_y = y; if (_liftHillAndAlternativeState != NULL)
if (_z != NULL) *_z = z; *_liftHillAndAlternativeState = liftHillAndAlternativeState;
if (_properties != NULL) *_properties = properties; if (_x != NULL)
*_x = x;
if (_y != NULL)
*_y = y;
if (_z != NULL)
*_z = z;
if (_properties != NULL)
*_properties = properties;
return false; return false;
} }
@ -474,16 +546,22 @@ void window_ride_construction_do_entrance_exit_check()
rct_window* w = window_find_by_class(WC_RIDE_CONSTRUCTION); rct_window* w = window_find_by_class(WC_RIDE_CONSTRUCTION);
Ride* ride = get_ride(_currentRideIndex); Ride* ride = get_ride(_currentRideIndex);
if (w == NULL || ride == NULL) { if (w == NULL || ride == NULL)
{
return; return;
} }
if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_0) { if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_0)
{
w = window_find_by_class(WC_RIDE_CONSTRUCTION); w = window_find_by_class(WC_RIDE_CONSTRUCTION);
if (w != NULL) { if (w != NULL)
if (!ride_are_all_possible_entrances_and_exits_built(ride)) { {
if (!ride_are_all_possible_entrances_and_exits_built(ride))
{
window_event_mouse_up_call(w, WC_RIDE_CONSTRUCTION__WIDX_ENTRANCE); window_event_mouse_up_call(w, WC_RIDE_CONSTRUCTION__WIDX_ENTRANCE);
} else { }
else
{
_deferClose = true; _deferClose = true;
} }
} }
@ -493,14 +571,16 @@ void window_ride_construction_do_entrance_exit_check()
void window_ride_construction_do_station_check() void window_ride_construction_do_station_check()
{ {
Ride* ride = get_ride(_currentRideIndex); Ride* ride = get_ride(_currentRideIndex);
if (ride != NULL) { if (ride != NULL)
{
_stationConstructed = ride->num_stations != 0; _stationConstructed = ride->num_stations != 0;
} }
} }
void window_ride_construction_mouseup_demolish_next_piece(int32_t x, int32_t y, int32_t z, int32_t direction, int32_t type) void window_ride_construction_mouseup_demolish_next_piece(int32_t x, int32_t y, int32_t z, int32_t direction, int32_t type)
{ {
if (gGotoStartPlacementMode) { if (gGotoStartPlacementMode)
{
z &= 0xFFF0; z &= 0xFFF0;
_currentTrackBeginZ = z; _currentTrackBeginZ = z;
_rideConstructionState = RIDE_CONSTRUCTION_STATE_FRONT; _rideConstructionState = RIDE_CONSTRUCTION_STATE_FRONT;
@ -516,10 +596,12 @@ void window_ride_construction_mouseup_demolish_next_piece(int32_t x, int32_t y,
int32_t b4 = _currentTrackLiftHill; int32_t b4 = _currentTrackLiftHill;
ride_construction_set_default_next_piece(); ride_construction_set_default_next_piece();
window_ride_construction_update_active_elements(); window_ride_construction_update_active_elements();
if (!ride_try_get_origin_element(_currentRideIndex, NULL)) { if (!ride_try_get_origin_element(_currentRideIndex, NULL))
{
ride_initialise_construction_window(_currentRideIndex); ride_initialise_construction_window(_currentRideIndex);
_currentTrackPieceDirection = direction & 3; _currentTrackPieceDirection = direction & 3;
if (!(slope & 0x100)) { if (!(slope & 0x100))
{
_currentTrackCurve = slope; _currentTrackCurve = slope;
_previousTrackSlopeEnd = slopeEnd; _previousTrackSlopeEnd = slopeEnd;
_currentTrackSlopeEnd = b2; _currentTrackSlopeEnd = b2;
@ -531,16 +613,20 @@ void window_ride_construction_mouseup_demolish_next_piece(int32_t x, int32_t y,
} }
} }
} }
else { else
if (_rideConstructionState2 == RIDE_CONSTRUCTION_STATE_SELECTED || {
_rideConstructionState2 == RIDE_CONSTRUCTION_STATE_FRONT if (_rideConstructionState2 == RIDE_CONSTRUCTION_STATE_SELECTED
) { || _rideConstructionState2 == RIDE_CONSTRUCTION_STATE_FRONT)
if (type == TRACK_ELEM_MIDDLE_STATION || type == TRACK_ELEM_BEGIN_STATION) { {
if (type == TRACK_ELEM_MIDDLE_STATION || type == TRACK_ELEM_BEGIN_STATION)
{
type = TRACK_ELEM_END_STATION; type = TRACK_ELEM_END_STATION;
} }
} }
if (_rideConstructionState2 == RIDE_CONSTRUCTION_STATE_BACK) { if (_rideConstructionState2 == RIDE_CONSTRUCTION_STATE_BACK)
if (type == TRACK_ELEM_MIDDLE_STATION) { {
if (type == TRACK_ELEM_MIDDLE_STATION)
{
type = TRACK_ELEM_BEGIN_STATION; type = TRACK_ELEM_BEGIN_STATION;
} }
} }
@ -556,10 +642,12 @@ void window_ride_construction_mouseup_demolish_next_piece(int32_t x, int32_t y,
_currentTrackPieceType = type; _currentTrackPieceType = type;
_currentTrackSelectionFlags = 0; _currentTrackSelectionFlags = 0;
_rideConstructionArrowPulseTime = 0; _rideConstructionArrowPulseTime = 0;
if (_rideConstructionState2 == RIDE_CONSTRUCTION_STATE_FRONT) { if (_rideConstructionState2 == RIDE_CONSTRUCTION_STATE_FRONT)
{
ride_select_next_section(); ride_select_next_section();
} }
else if (_rideConstructionState2 == RIDE_CONSTRUCTION_STATE_BACK) { else if (_rideConstructionState2 == RIDE_CONSTRUCTION_STATE_BACK)
{
ride_select_previous_section(); ride_select_previous_section();
} }
window_ride_construction_update_active_elements(); window_ride_construction_update_active_elements();
@ -585,7 +673,8 @@ void game_command_callback_place_banner(
int32_t edi, int32_t edi,
[[maybe_unused]] int32_t ebp) [[maybe_unused]] int32_t ebp)
{ {
if (ebx != MONEY32_UNDEFINED) { if (ebx != MONEY32_UNDEFINED)
{
int32_t bannerId = edi; int32_t bannerId = edi;
audio_play_sound_at_location(SOUND_PLACE_ITEM, gCommandPosition.x, gCommandPosition.y, gCommandPosition.z); audio_play_sound_at_location(SOUND_PLACE_ITEM, gCommandPosition.x, gCommandPosition.y, gCommandPosition.z);