mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-27 00:34:46 +01:00
`typedef struct/union/enum name { ... } name_again;` is not needed whe compiling C++, moving the name at the back to be in front of the object and removing `typedef` makes it usable the very same way.
This also replaces typedefs with the using keyword. They have better readability, especially for function pointer types, and would allow more flexibility when used with templates.
321 lines
9.2 KiB
C++
321 lines
9.2 KiB
C++
#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers
|
|
/*****************************************************************************
|
|
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
|
*
|
|
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
|
|
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
|
|
*
|
|
* OpenRCT2 is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* A full copy of the GNU General Public License can be found in licence.txt
|
|
*****************************************************************************/
|
|
#pragma endregion
|
|
|
|
#ifndef _COMMON_H_
|
|
#define _COMMON_H_
|
|
|
|
#ifndef _USE_MATH_DEFINES
|
|
#define _USE_MATH_DEFINES
|
|
#endif
|
|
#undef M_PI
|
|
|
|
#ifdef _MSC_VER
|
|
#include <time.h>
|
|
#endif
|
|
|
|
#include <assert.h>
|
|
#include <math.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdbool.h>
|
|
|
|
using sint8 = int8_t;
|
|
using sint16 = int16_t;
|
|
using sint32 = int32_t;
|
|
using sint64 = int64_t;
|
|
using uint8 = uint8_t;
|
|
using uint16 = uint16_t;
|
|
using uint32 = uint32_t;
|
|
using uint64 = uint64_t;
|
|
|
|
#include "Diagnostic.h"
|
|
|
|
using utf8 = char;
|
|
using utf8string = utf8 *;
|
|
using const_utf8string = const utf8 *;
|
|
#ifdef _WIN32
|
|
using utf16 = wchar_t;
|
|
using utf16string = utf16*;
|
|
#endif
|
|
|
|
// Define MAX_PATH for various headers that don't want to include system headers
|
|
// just for MAX_PATH
|
|
#ifndef MAX_PATH
|
|
#define MAX_PATH 260
|
|
#endif
|
|
|
|
using codepoint_t = uint32;
|
|
using colour_t = uint8;
|
|
|
|
#define rol8(x, shift) (((uint8)(x) << (shift)) | ((uint8)(x) >> (8 - (shift))))
|
|
#define ror8(x, shift) (((uint8)(x) >> (shift)) | ((uint8)(x) << (8 - (shift))))
|
|
#define rol16(x, shift) (((uint16)(x) << (shift)) | ((uint16)(x) >> (16 - (shift))))
|
|
#define ror16(x, shift) (((uint16)(x) >> (shift)) | ((uint16)(x) << (16 - (shift))))
|
|
#define rol32(x, shift) (((uint32)(x) << (shift)) | ((uint32)(x) >> (32 - (shift))))
|
|
#define ror32(x, shift) (((uint32)(x) >> (shift)) | ((uint32)(x) << (32 - (shift))))
|
|
#define rol64(x, shift) (((uint64)(x) << (shift)) | ((uint32)(x) >> (64 - (shift))))
|
|
#define ror64(x, shift) (((uint64)(x) >> (shift)) | ((uint32)(x) << (64 - (shift))))
|
|
|
|
#ifndef __cplusplus
|
|
// in C++ you should be using Math::Min and Math::Max
|
|
#ifndef min
|
|
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
|
#endif
|
|
#ifndef max
|
|
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
|
#endif
|
|
|
|
#define sgn(x) ((x > 0) ? 1 : ((x < 0) ? -1 : 0))
|
|
#define clamp(l, x, h) (min(h, max(l, x)))
|
|
|
|
#endif // __cplusplus
|
|
|
|
// Rounds an integer down to the given power of 2. y must be a power of 2.
|
|
#define floor2(x, y) ((x) & (~((y) - 1)))
|
|
|
|
// Rounds an integer up to the given power of 2. y must be a power of 2.
|
|
#define ceil2(x, y) (((x) + (y) - 1) & (~((y) - 1)))
|
|
|
|
|
|
#ifndef __cplusplus
|
|
// in C++ you should be using Util::CountOf
|
|
#ifdef __GNUC__
|
|
/**
|
|
* Force a compilation error if condition is true, but also produce a
|
|
* result (of value 0 and type size_t), so the expression can be used
|
|
* e.g. in a structure initializer (or where-ever else comma expressions
|
|
* aren't permitted).
|
|
*/
|
|
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { sint32:-!!(e); }))
|
|
|
|
/* &a[0] degrades to a pointer: a different type from an array */
|
|
#define __must_be_array(a) \
|
|
BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0])))
|
|
|
|
// based on http://lxr.free-electrons.com/source/include/linux/kernel.h#L54
|
|
#define countof(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
|
|
#elif defined (_MSC_VER)
|
|
#define countof(arr) _countof(arr)
|
|
#else
|
|
#define countof(arr) (sizeof(arr) / sizeof((arr)[0]))
|
|
#endif // __GNUC__
|
|
#endif // __cplusplus
|
|
|
|
// Gets the name of a symbol as a C string
|
|
#define nameof(symbol) #symbol
|
|
|
|
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
|
#include <unistd.h>
|
|
#define STUB() log_warning("Function %s at %s:%d is a stub.\n", __PRETTY_FUNCTION__, __FILE__, __LINE__)
|
|
#define _strcmpi _stricmp
|
|
#define _stricmp(x, y) strcasecmp((x), (y))
|
|
#define _strnicmp(x, y, n) strncasecmp((x), (y), (n))
|
|
#define _strdup(x) strdup((x))
|
|
|
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
#define RCT2_ENDIANESS __ORDER_LITTLE_ENDIAN__
|
|
#define LOBYTE(w) ((uint8)(w))
|
|
#define HIBYTE(w) ((uint8)(((uint16)(w)>>8)&0xFF))
|
|
#endif // __BYTE_ORDER__
|
|
|
|
#ifndef RCT2_ENDIANESS
|
|
#error Unknown endianess!
|
|
#endif // RCT2_ENDIANESS
|
|
|
|
#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
|
|
|
#if !((defined (_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700))
|
|
char *strndup(const char *src, size_t size);
|
|
#endif // !(POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)
|
|
|
|
// BSD and macOS have MAP_ANON instead of MAP_ANONYMOUS
|
|
#ifndef MAP_ANONYMOUS
|
|
#define MAP_ANONYMOUS MAP_ANON
|
|
#endif
|
|
|
|
#define OPENRCT2_MASTER_SERVER_URL "https://servers.openrct2.io"
|
|
|
|
// Time (represented as number of 100-nanosecond intervals since 0001-01-01T00:00:00Z)
|
|
using datetime64 = uint64;
|
|
|
|
#define DATETIME64_MIN ((datetime64)0)
|
|
|
|
// Represent fixed point numbers. dp = decimal point
|
|
using fixed8_1dp = uint8;
|
|
using fixed8_2dp = uint8;
|
|
using fixed16_1dp = sint16;
|
|
using fixed16_2dp = sint16;
|
|
using fixed32_1dp = sint32;
|
|
using fixed32_2dp = sint32;
|
|
using fixed64_1dp = sint64;
|
|
|
|
// Money is stored as a multiple of 0.10.
|
|
using money8 = fixed8_1dp;
|
|
using money16 = fixed16_1dp;
|
|
using money32 = fixed32_1dp;
|
|
using money64 = fixed64_1dp;
|
|
|
|
// Construct a fixed point number. For example, to create the value 3.65 you
|
|
// would write FIXED_2DP(3,65)
|
|
#define FIXED_XDP(x, whole, fraction) ((whole) * (10 * x) + (fraction))
|
|
#define FIXED_1DP(whole, fraction) FIXED_XDP(1, whole, fraction)
|
|
#define FIXED_2DP(whole, fraction) FIXED_XDP(10, whole, fraction)
|
|
|
|
// Construct a money value in the format MONEY(10,70) to represent 10.70. Fractional part must be two digits.
|
|
#define MONEY(whole, fraction) ((whole) * 10 + ((fraction) / 10))
|
|
|
|
#define MONEY_FREE MONEY(0,00)
|
|
#define MONEY16_UNDEFINED (money16)(uint16)0xFFFF
|
|
#define MONEY32_UNDEFINED ((money32)0x80000000)
|
|
|
|
using EMPTY_ARGS_VOID_POINTER = void();
|
|
using rct_string_id = uint16;
|
|
|
|
#define SafeFree(x) do { free(x); (x) = nullptr; } while (false)
|
|
|
|
#define SafeDelete(x) do { delete (x); (x) = nullptr; } while (false)
|
|
#define SafeDeleteArray(x) do { delete[] (x); (x) = nullptr; } while (false)
|
|
|
|
#ifndef interface
|
|
#define interface struct
|
|
#endif
|
|
#define abstract = 0
|
|
|
|
#if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
|
|
#define OPENRCT2_X86
|
|
#elif defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_X64) || defined(_M_IX86)) // VS2008
|
|
#define OPENRCT2_X86
|
|
#endif
|
|
|
|
#if defined(__i386__) || defined(_M_IX86)
|
|
#define PLATFORM_X86
|
|
#endif
|
|
|
|
#if defined(__LP64__) || defined(_WIN64)
|
|
#define PLATFORM_64BIT
|
|
#else
|
|
#define PLATFORM_32BIT
|
|
#endif
|
|
|
|
// C99's restrict keywords guarantees the pointer in question, for the whole of its lifetime,
|
|
// will be the only way to access a given memory region. In other words: there is no other pointer
|
|
// aliasing the same memory area. Using it lets compiler generate better code. If your compiler
|
|
// does not support it, feel free to drop it, at some performance hit.
|
|
#ifdef __cplusplus
|
|
#ifdef _MSC_VER
|
|
#define RESTRICT __restrict
|
|
#else
|
|
#define RESTRICT __restrict__
|
|
#endif
|
|
#else
|
|
#ifdef _MSC_VER
|
|
#define RESTRICT __restrict
|
|
#else
|
|
#define RESTRICT restrict
|
|
#endif
|
|
#endif
|
|
#ifndef RESTRICT
|
|
#define RESTRICT
|
|
#endif
|
|
|
|
#define assert_struct_size(x, y) static_assert(sizeof(x) == (y), "Improper struct size")
|
|
|
|
#ifdef PLATFORM_X86
|
|
#ifndef FASTCALL
|
|
#ifdef __GNUC__
|
|
#define FASTCALL __attribute__((fastcall))
|
|
#elif defined(_MSC_VER)
|
|
#define FASTCALL __fastcall
|
|
#else
|
|
#pragma message "Not using fastcall calling convention, please check your compiler support"
|
|
#define FASTCALL
|
|
#endif
|
|
#endif // FASTCALL
|
|
#else // PLATFORM_X86
|
|
#define FASTCALL
|
|
#endif // PLATFORM_X86
|
|
|
|
// C++17 or later
|
|
#if defined(__cplusplus) && __cplusplus > 201402L
|
|
#define UNUSED_ATTR [[maybe_unused]]
|
|
#else
|
|
#ifdef __GNUC__
|
|
#define UNUSED_ATTR [[gnu::unused]]
|
|
#else
|
|
#define UNUSED_ATTR
|
|
#endif
|
|
#endif
|
|
|
|
/**
|
|
* x86 register structure, only used for easy interop to RCT2 code.
|
|
*/
|
|
#pragma pack(push, 1)
|
|
struct registers {
|
|
union {
|
|
sint32 eax;
|
|
sint16 ax;
|
|
struct {
|
|
char al;
|
|
char ah;
|
|
};
|
|
};
|
|
union {
|
|
sint32 ebx;
|
|
sint16 bx;
|
|
struct {
|
|
char bl;
|
|
char bh;
|
|
};
|
|
};
|
|
union {
|
|
sint32 ecx;
|
|
sint16 cx;
|
|
struct {
|
|
char cl;
|
|
char ch;
|
|
};
|
|
};
|
|
union {
|
|
sint32 edx;
|
|
sint16 dx;
|
|
struct {
|
|
char dl;
|
|
char dh;
|
|
};
|
|
};
|
|
union {
|
|
sint32 esi;
|
|
sint16 si;
|
|
};
|
|
union {
|
|
sint32 edi;
|
|
sint16 di;
|
|
};
|
|
union {
|
|
sint32 ebp;
|
|
sint16 bp;
|
|
};
|
|
};
|
|
assert_struct_size(registers, 7 * 4);
|
|
#pragma pack(pop)
|
|
|
|
#define UNUSED(x) ((void)(x))
|
|
|
|
#endif
|