Remove RCT2 interop

This commit is contained in:
Ted John 2017-12-03 19:50:44 +00:00
parent caab169968
commit 99d7aaa2d6
49 changed files with 19 additions and 1837 deletions

View File

@ -45,7 +45,7 @@ matrix:
services:
- docker
env:
- OPENRCT2_CMAKE_OPTS="-G Ninja -DFORCE32=ON -DDISABLE_RCT2=OFF -DBUILD_SHARED_LIBS=off -DCMAKE_INSTALL_PREFIX=OpenRCT2 -DDISABLE_RCT2_TESTS=on" TARGET=ubuntu_i686
- OPENRCT2_CMAKE_OPTS="-G Ninja -DFORCE32=ON -DBUILD_SHARED_LIBS=off -DCMAKE_INSTALL_PREFIX=OpenRCT2 -DDISABLE_RCT2_TESTS=on" TARGET=ubuntu_i686
- secure: "S3u2VCE2Vy8KNXoeh+DhnzjCmgTX0r95uEZrXDU+IKANOOCKn7Dg4OFDZE3LY/i1y2/EUDpnR5yLC38Ks795EUP/sv/OoMl4tjQ20yERjqWh+gcIRrgx7SdVabuAh3t4aBdaLD4Pfnj5avxeCt6rL7yGnj0wdbrbJSBZPsgSnuQ="
after_success:
# Android jobs are triggered from cron and overwrite `after_sucess` part

View File

@ -132,9 +132,6 @@ add_custom_target(g2 DEPENDS ${PROJECT} g2.dat)
# Include tests
if (WITH_TESTS)
enable_testing()
if (UNIX AND (NOT USE_MMAP) AND (NOT DISABLE_RCT2) AND (FORCE32))
include("${ROOT_DIR}/test/testpaint/CMakeLists.txt" NO_POLICY_SCOPE)
endif ()
include("${ROOT_DIR}/test/tests/CMakeLists.txt" NO_POLICY_SCOPE)
endif ()

View File

@ -3823,7 +3823,6 @@
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
NO_RCT2,
__ENABLE_LIGHTFX__,
);
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
@ -3860,7 +3859,6 @@
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
NO_RCT2,
__ENABLE_LIGHTFX__,
);
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
@ -3900,7 +3898,6 @@
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
NO_RCT2,
__ENABLE_LIGHTFX__,
);
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
@ -3939,7 +3936,6 @@
GCC_PREPROCESSOR_DEFINITIONS = (
OPENGL_NO_LINK,
"OPENRCT2_BUILD_INFO_HEADER=\"\\\"$(DERIVED_FILE_DIR)/gitversion.h\\\"\"",
NO_RCT2,
__ENABLE_LIGHTFX__,
);
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
@ -3976,7 +3972,6 @@
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
NO_RCT2,
__ENABLE_LIGHTFX__,
);
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
@ -4009,7 +4004,6 @@
GCC_PREPROCESSOR_DEFINITIONS = (
OPENGL_NO_LINK,
"OPENRCT2_BUILD_INFO_HEADER=\"\\\"$(DERIVED_FILE_DIR)/gitversion.h\\\"\"",
NO_RCT2,
__ENABLE_LIGHTFX__,
);
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;

View File

@ -51,7 +51,7 @@
C4549: 'operator': operator before comma has no effect; did you intend 'operator'?
C4555: expression has no effect; expected expression with side-effect
-->
<PreprocessorDefinitions>NO_RCT2;OPENGL_NO_LINK;_CRT_SECURE_NO_WARNINGS;_USE_MATH_DEFINES;CURL_STATICLIB;SDL_MAIN_HANDLED;_WINSOCK_DEPRECATED_NO_WARNINGS;ZIP_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>OPENGL_NO_LINK;_CRT_SECURE_NO_WARNINGS;_USE_MATH_DEFINES;CURL_STATICLIB;SDL_MAIN_HANDLED;_WINSOCK_DEPRECATED_NO_WARNINGS;ZIP_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<TreatWarningAsError>true</TreatWarningAsError>

View File

@ -85,7 +85,7 @@ include_directories("${CMAKE_BINARY_DIR}/libs/include/SDL2")
# now build app's shared lib
include_directories(./ndk_helper
${ANDROID_NDK}/sources/android/cpufeatures)
add_definitions(-DDISABLE_HTTP -DDISABLE_TWITCH -DDISABLE_NETWORK -DDISABLE_OPENGL -DGL_GLEXT_PROTOTYPES -D__STDC_LIMIT_MACROS -DNO_RCT2 -DNO_TTF -DSDL_MAIN_HANDLED)
add_definitions(-DDISABLE_HTTP -DDISABLE_TWITCH -DDISABLE_NETWORK -DDISABLE_OPENGL -DGL_GLEXT_PROTOTYPES -D__STDC_LIMIT_MACROS -DNO_TTF -DSDL_MAIN_HANDLED)
# Fix SpeexDSP compilation
add_definitions(-DHAVE_STDINT_H)

View File

@ -1094,11 +1094,7 @@ static void window_new_ride_list_vehicles_for(const uint8 rideType, const rct_ri
continue;
}
#ifdef NO_RCT2
const char * vehicleName = language_get_string(currentRideEntry->vehicleName);
#else
const char * vehicleName = language_get_string(currentRideEntry->naming.name);
#endif
if (numItems > 0)
{

View File

@ -2732,11 +2732,7 @@ static void window_ride_vehicle_mousedown(rct_window *w, rct_widgetindex widgetI
selectedIndex = numItems;
gDropdownItemsFormat[numItems] = STR_DROPDOWN_MENU_LABEL;
#ifdef NO_RCT2
gDropdownItemsArgs[numItems] = (rideEntryIndex << 16) | currentRideEntry->vehicleName;
#else
gDropdownItemsArgs[numItems] = (rideEntryIndex << 16) | currentRideEntry->naming.name;
#endif
numItems++;
}
@ -2832,11 +2828,7 @@ static void window_ride_vehicle_invalidate(rct_window *w)
carsPerTrain = ride->num_cars_per_train - rideEntry->zero_cars;
// Vehicle type
#ifdef NO_RCT2
window_ride_vehicle_widgets[WIDX_VEHICLE_TYPE].text = rideEntry->vehicleName;
#else
window_ride_vehicle_widgets[WIDX_VEHICLE_TYPE].text = rideEntry->naming.name;
#endif
// Always show a dropdown button when changing subtypes is allowed
if ((rideEntry->flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE) && !(gConfigInterface.select_by_track_type || gCheatsShowVehiclesFromOtherTrackTypes)) {
window_ride_vehicle_widgets[WIDX_VEHICLE_TYPE].type = WWT_14;
@ -2932,9 +2924,7 @@ static void window_ride_vehicle_paint(rct_window *w, rct_drawpixelinfo *dpi)
y += 5;
// Capacity
#ifdef NO_RCT2
gfx_draw_string_left(dpi, STR_CAPACITY, &rideEntry->capacity, COLOUR_BLACK, x, y);
#endif
y += 5;
if (!(rideEntry->flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE) || rideTypeShouldLoseSeparateFlag(rideEntry))

View File

@ -7,22 +7,12 @@ endif ()
# Options
option(STATIC "Create a static build.")
option(USE_MMAP "Use mmap to try loading rct2's data segment into memory.")
option(DISABLE_RCT2 "Build a standalone version, without using code and data segments from vanilla. On by default." ON)
option(DISABLE_HTTP_TWITCH "Disable HTTP and Twitch support.")
option(DISABLE_NETWORK "Disable multiplayer functionality. Mainly for testing.")
option(DISABLE_TTF "Disable support for TTF provided by freetype2.")
option(ENABLE_LIGHTFX "Enable lighting effects." ON)
if (NOT DISABLE_RCT2)
if (WIN32)
message(FATAL_ERROR "DISABLE_RCT2 not supported for Windows")
endif ()
if (NOT FORCE32)
message(FATAL_ERROR "DISABLE_RCT2 requires FORCE32")
endif ()
endif ()
# Needed for linking with non-broken OpenSSL on Apple platforms
if (APPLE)
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/opt/openssl/lib/pkgconfig")
@ -69,62 +59,6 @@ if (APPLE)
set_source_files_properties(${OPENRCT2_CORE_MM_SOURCES} PROPERTIES COMPILE_FLAGS "-x objective-c -fmodules")
endif ()
# Handle creating the rct2 text and data files on macOS and Linux
# See details in src/openrct2/rct2/interop.c:rct2_interop_setup_segment for how the values
# were derived.
if (NOT DISABLE_RCT2 AND UNIX)
set(OPENRCT2_EXE "${ROOT_DIR}/openrct2.exe")
add_custom_command(
OUTPUT openrct2_text
COMMAND dd if="${OPENRCT2_EXE}" of="${CMAKE_BINARY_DIR}/openrct2_text" bs=4096 skip=1 count=1187
DEPENDS ${OPENRCT2_EXE}
)
add_custom_command(
OUTPUT openrct2_data
COMMAND dd if="${OPENRCT2_EXE}" of="${CMAKE_BINARY_DIR}/openrct2_data" bs=4096 skip=1188 count=318
COMMAND dd if=/dev/zero of="${CMAKE_BINARY_DIR}/openrct2_data" bs=4096 seek=318 count=2630 conv=notrunc
COMMAND dd if="${OPENRCT2_EXE}" of="${CMAKE_BINARY_DIR}/openrct2_data" bs=4096 skip=1506 seek=2948 count=1 conv=notrunc
DEPENDS ${OPENRCT2_EXE}
)
add_custom_target(segfiles DEPENDS openrct2_text openrct2_data)
if (NOT USE_MMAP)
set(OBJ_FORMAT "elf32-i386")
set(LINKER_SCRIPT "ld_script_i386.xc")
if (APPLE)
set(RCT2_SEGMENT_LINKER_FLAGS "-sectcreate rct2_text __text ${CMAKE_BINARY_DIR}/openrct2_text -sectcreate rct2_data __data ${CMAKE_BINARY_DIR}/openrct2_data -segaddr rct2_data 0x8a4000 -segprot rct2_data rwx rwx -segaddr rct2_text 0x401000 -segprot rct2_text rwx rwx -segaddr __TEXT 0x2000000 -read_only_relocs suppress")
else ()
# For Linux we have to use objcopy to wrap regular binaries into a linkable
# format. We use specific section names which are then referenced in a
# bespoke linker script so they can be placed at predefined VMAs.
add_custom_command(
OUTPUT openrct2_text_section.o
COMMAND objcopy --input binary --output ${OBJ_FORMAT} --binary-architecture i386 openrct2_text openrct2_text_section.o --rename-section .data=.rct2_text,contents,alloc,load,readonly,code
DEPENDS segfiles
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
add_custom_command(
OUTPUT openrct2_data_section.o
COMMAND objcopy --input binary --output ${OBJ_FORMAT} --binary-architecture i386 openrct2_data openrct2_data_section.o --rename-section .data=.rct2_data,contents,alloc,load,readonly,data
DEPENDS segfiles
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
add_custom_target(linkable_sections DEPENDS openrct2_text_section.o openrct2_data_section.o)
set_source_files_properties(
openrct2_text_section.o openrct2_data_section.o
PROPERTIES
EXTERNAL_OBJECT true
GENERATED true
)
# can't use GLOB here, as the files don't exist yet at cmake-time
set(RCT2_SECTIONS "${CMAKE_BINARY_DIR}/openrct2_data_section.o" "${CMAKE_BINARY_DIR}/openrct2_text_section.o")
set(RCT2_SEGMENT_LINKER_FLAGS "-Wl,-T,\"${ROOT_DIR}/distribution/linux/${LINKER_SCRIPT}\"")
endif ()
endif ()
elseif (USE_MMAP)
# No dd here, can't extract data segment
message(WARNING "Sorry, your platform is not supported, you have to extract data segment manually")
endif ()
# Outputs
set(PROJECT libopenrct2)
project(${PROJECT})
@ -132,16 +66,6 @@ add_library(${PROJECT} ${OPENRCT2_CORE_SOURCES} ${OPENRCT2_CORE_MM_SOURCES} ${RC
set_target_properties(${PROJECT} PROPERTIES PREFIX "")
set_target_properties(${PROJECT} PROPERTIES COMPILE_FLAGS "-Wundef")
if (NOT DISABLE_RCT2)
add_dependencies(${PROJECT} segfiles)
if (NOT USE_MMAP)
if (NOT APPLE)
add_dependencies(${PROJECT} linkable_sections)
endif ()
set_target_properties(${PROJECT} PROPERTIES LINK_FLAGS ${RCT2_SEGMENT_LINKER_FLAGS})
endif ()
endif ()
# Libraries
if (STATIC)
target_link_libraries(${PROJECT} ${JANSSON_STATIC_LIBRARIES}
@ -261,15 +185,6 @@ endif ()
if (ENABLE_LIGHTFX)
add_definitions(-D__ENABLE_LIGHTFX__)
endif ()
if (DISABLE_RCT2)
add_definitions(-DNO_RCT2)
endif ()
if (NOT DISABLE_RCT2)
# Disable optimizations for addresses.c for all compilers, to allow optimized
# builds without need for -fno-omit-frame-pointer
set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/rct2/addresses.c PROPERTIES COMPILE_FLAGS -O0)
endif ()
if (CXX_WARN_SUGGEST_FINAL_TYPES)
# Disable -Wsuggest-final-types via pragmas where due.

View File

@ -66,7 +66,6 @@
#include "object_list.h"
#include "platform/platform.h"
#include "rct1.h"
#include "rct2/interop.h"
#include "util/util.h"
using namespace OpenRCT2;
@ -133,7 +132,6 @@ namespace OpenRCT2
#ifndef DISABLE_NETWORK
EVP_MD_CTX_destroy(gHashCTX);
#endif // DISABLE_NETWORK
rct2_interop_dispose();
delete _titleScreen;
@ -276,12 +274,6 @@ namespace OpenRCT2
crash_init();
if (!rct2_interop_setup_segment())
{
log_fatal("Unable to load RCT2 data sector");
return false;
}
if (gConfigGeneral.last_run_version != nullptr && String::Equals(gConfigGeneral.last_run_version, OPENRCT2_VERSION))
{
gOpenRCT2ShowChangelog = false;
@ -368,8 +360,6 @@ namespace OpenRCT2
theme_manager_initialise();
CopyOriginalUserFilesOver();
rct2_interop_setup_hooks();
if (!gOpenRCT2NoGraphics)
{
LoadBaseGraphics();

View File

@ -443,9 +443,6 @@ static void PrintVersion()
openrct2_write_full_version_info(buffer, sizeof(buffer));
Console::WriteLine(buffer);
Console::WriteFormat("%s (%s)", OPENRCT2_PLATFORM, OPENRCT2_ARCHITECTURE);
#ifdef NO_RCT2
Console::Write(" (NO_RCT2)");
#endif
Console::WriteLine();
}

View File

@ -199,8 +199,6 @@ typedef uint16 rct_string_id;
#if defined(__i386__) || defined(_M_IX86)
#define PLATFORM_X86
#else
#define NO_RCT2 1
#endif
#if defined(__LP64__) || defined(_WIN64)

View File

@ -27,7 +27,6 @@
#include "../ui/UiContext.h"
#include "../platform/platform.h"
#include "../rct2/addresses.h"
#include "../util/util.h"
#include "drawing.h"
@ -162,11 +161,7 @@ extern "C"
static bool _csgLoaded = false;
static size_t _g1ElementsCount = 0;
#ifdef NO_RCT2
static rct_g1_element * _g1Elements = nullptr;
#else
static rct_g1_element * _g1Elements = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element);
#endif
static rct_g1_element * _g1Elements = nullptr;
static rct_g1_element _g1Temp = { 0 };
bool gTinyFontAntiAliased = false;
@ -192,9 +187,7 @@ extern "C"
// Read element headers
_g1ElementsCount = 324206;
#ifdef NO_RCT2
_g1Elements = Memory::AllocateArray<rct_g1_element>(_g1ElementsCount);
#endif
bool is_rctc = header.num_entries == SPR_RCTC_G1_END;
read_and_convert_gxdat(&fs, header.num_entries, is_rctc, _g1Elements);
gTinyFontAntiAliased = is_rctc;
@ -224,9 +217,7 @@ extern "C"
void gfx_unload_g1()
{
SafeFree(_g1Buffer);
#ifdef NO_RCT2
SafeFree(_g1Elements);
#endif
}
void gfx_unload_g2()

View File

@ -39,9 +39,7 @@ uint32 gPickupPeepImage;
sint32 gPickupPeepX;
sint32 gPickupPeepY;
#ifdef NO_RCT2
rct_drawpixelinfo *unk_140E9A8;
#endif
/**
* 12 elements from 0xF3 are the peep top colour, 12 elements from 0xCA are peep trouser colour

View File

@ -21,11 +21,6 @@
#include "../interface/colour.h"
#include "font.h"
// For g1 only enable packing when still relying on vanilla
#ifndef NO_RCT2
#pragma pack(push, 1)
#endif
// Size: 0x10
typedef struct rct_g1_element {
uint8* offset; // 0x00
sint16 width; // 0x04
@ -35,16 +30,7 @@ typedef struct rct_g1_element {
uint16 flags; // 0x0C
uint16 zoomed_offset; // 0x0E
} rct_g1_element;
#ifndef NO_RCT2
#ifdef PLATFORM_32BIT
assert_struct_size(rct_g1_element, 0x10);
#endif
#pragma pack(pop)
#endif
// Enable packing for remaining elements
#pragma pack(push, 1)
// Size: 0x10
typedef struct rct_drawpixelinfo {
uint8* bits; // 0x00
sint16 x; // 0x04
@ -54,11 +40,7 @@ typedef struct rct_drawpixelinfo {
sint16 pitch; // 0x0C note: this is actually (pitch - width)
uint16 zoom_level; // 0x0E
} rct_drawpixelinfo;
#ifdef PLATFORM_32BIT
assert_struct_size(rct_drawpixelinfo, 0x10);
#endif
// Size: 0x10
typedef struct rct_g1_element_32bit {
uint32 offset; // 0x00 note: uint32 always!
sint16 width; // 0x04
@ -209,6 +191,8 @@ typedef struct translucent_window_palette {
FILTER_PALETTE_ID shadow;
} translucent_window_palette;
#pragma pack(push, 1)
typedef struct rct_g1_header {
uint32 num_entries;
uint32 total_size;
@ -285,11 +269,7 @@ extern bool gTinyFontAntiAliased;
extern rct_drawpixelinfo gScreenDPI;
extern rct_drawpixelinfo gWindowDPI;
#ifdef NO_RCT2
extern rct_drawpixelinfo *unk_140E9A8;
#else
#define unk_140E9A8 RCT2_GLOBAL(0x0140E9A8, rct_drawpixelinfo*)
#endif
//
bool clip_drawpixelinfo(rct_drawpixelinfo *dst, rct_drawpixelinfo *src, sint32 x, sint32 y, sint32 width, sint32 height);

View File

@ -15,7 +15,6 @@
#pragma endregion
#include "../core/Guard.hpp"
#include "../rct2/addresses.h"
#include "../localisation/localisation.h"
#include "../sprites.h"
#include "drawing.h"
@ -24,11 +23,7 @@
static const sint32 SpriteFontLineHeight[] = { 6, 10, 10, 18 };
#ifdef NO_RCT2
static uint8 _spriteFontCharacterWidths[896];
#else
static uint8 *_spriteFontCharacterWidths = RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8);
#endif
#ifndef NO_TTF
TTFFontSetDescriptor *gCurrentTTFFontSet;
@ -130,13 +125,11 @@ sint32 font_sprite_get_codepoint_width(uint16 fontSpriteBase, sint32 codepoint)
}
sint32 spriteFontIdx = fontSpriteBase + font_sprite_get_codepoint_offset(codepoint);
#ifdef NO_RCT2
if (spriteFontIdx < 0 || spriteFontIdx >= countof(_spriteFontCharacterWidths))
{
log_warning("Invalid font index %u", spriteFontIdx);
spriteFontIdx = 0;
}
#endif
return _spriteFontCharacterWidths[spriteFontIdx];
}

View File

@ -14,7 +14,6 @@
*****************************************************************************/
#pragma endregion
#include "../rct2/addresses.h"
#include "../config/Config.h"
#include "../interface/colour.h"
#include "../localisation/localisation.h"

View File

@ -79,9 +79,7 @@ bool gLoadKeepWindowsOpen = false;
uint8 gUnk13CA740;
uint8 gUnk141F568;
#ifdef NO_RCT2
uint32 gCurrentTicks;
#endif
GAME_COMMAND_CALLBACK_POINTER* game_command_callback = 0;
static GAME_COMMAND_CALLBACK_POINTER* const game_command_callback_table[] = {

View File

@ -17,7 +17,6 @@
#ifndef _GAME_H_
#define _GAME_H_
#include "rct2/addresses.h"
#include "common.h"
#include "scenario/scenario.h"
@ -140,11 +139,7 @@ extern rct_string_id gErrorStringId;
extern GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT];
#ifndef NO_RCT2
#define gCurrentTicks RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32)
#else
extern uint32 gCurrentTicks;
#endif
extern uint16 gTicksSinceLastUpdate;
extern uint8 gGamePaused;

View File

@ -52,11 +52,9 @@ sint16 gSavedViewY;
uint8 gSavedViewZoom;
uint8 gSavedViewRotation;
#ifdef NO_RCT2
paint_entry *gNextFreePaintStruct;
uint8 gCurrentRotation;
uint32 gCurrentViewportFlags = 0;
#endif
static uint32 _currentImageType;

View File

@ -110,15 +110,9 @@ extern sint16 gSavedViewY;
extern uint8 gSavedViewZoom;
extern uint8 gSavedViewRotation;
#ifdef NO_RCT2
extern paint_entry *gNextFreePaintStruct;
extern uint8 gCurrentRotation;
extern uint32 gCurrentViewportFlags;
#else
#define gNextFreePaintStruct RCT2_GLOBAL(0x00EE7888, paint_entry*)
#define gCurrentRotation RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8)
#define gCurrentViewportFlags RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_VIEWPORT_FLAGS, uint32)
#endif
void viewport_init_all();
void centre_2d_coordinates(sint32 x, sint32 y, sint32 z, sint32 * out_x, sint32 * out_y, rct_viewport * viewport);

View File

@ -292,11 +292,7 @@ void research_finish_item(uint32 entryIndex)
rct_ride_name baseRideNaming = get_ride_naming(base_ride_type, rideEntry);
set_format_arg(0, rct_string_id, baseRideNaming.name);
#ifdef NO_RCT2
set_format_arg(2, rct_string_id, rideEntry->vehicleName);
#else
set_format_arg(2, rct_string_id, rideEntry->naming.name);
#endif
}
}

View File

@ -127,10 +127,8 @@ void RideObject::Load()
GetStringTable()->Sort();
_legacyType.naming.name = language_allocate_object_string(GetName());
_legacyType.naming.description = language_allocate_object_string(GetDescription());
#if defined(NO_RCT2)
_legacyType.capacity = language_allocate_object_string(GetCapacity());
_legacyType.vehicleName = language_allocate_object_string(GetVehicleName());
#endif
_legacyType.images_offset = gfx_object_allocate_images(GetImageTable()->GetImages(), GetImageTable()->GetCount());
_legacyType.vehicle_preset_list = &_presetColours;
@ -295,9 +293,7 @@ void RideObject::Load()
}
}
vehicleEntry->peep_loading_positions = _peepLoadingPositions[i];
#ifdef NO_RCT2
vehicleEntry->peep_loading_positions_count = _peepLoadingPositionsCount[i];
#endif
}
}
}
@ -306,18 +302,14 @@ void RideObject::Unload()
{
language_free_object_string(_legacyType.naming.name);
language_free_object_string(_legacyType.naming.description);
#ifdef NO_RCT2
language_free_object_string(_legacyType.capacity);
language_free_object_string(_legacyType.vehicleName);
#endif
gfx_object_free_images(_legacyType.images_offset, GetImageTable()->GetCount());
_legacyType.naming.name = 0;
_legacyType.naming.description = 0;
#ifdef NO_RCT2
_legacyType.capacity = 0;
_legacyType.vehicleName = 0;
#endif
_legacyType.images_offset = 0;
}

View File

@ -51,7 +51,6 @@ sint32 object_entry_group_encoding[] = {
CHUNK_ENCODING_ROTATE
};
#ifdef NO_RCT2
rct_ride_entry *gRideEntries[MAX_RIDE_OBJECTS];
rct_small_scenery_entry *gSmallSceneryEntries[MAX_SMALL_SCENERY_OBJECTS];
rct_large_scenery_entry *gLargeSceneryEntries[MAX_LARGE_SCENERY_OBJECTS];
@ -63,9 +62,7 @@ sint32 object_entry_group_encoding[] = {
rct_entrance_type *gParkEntranceEntries[MAX_PARK_ENTRANCE_OBJECTS];
rct_water_type *gWaterEntries[MAX_WATER_OBJECTS];
rct_stex_entry *gStexEntries[MAX_SCENARIO_TEXT_OBJECTS];
#endif
#ifdef NO_RCT2
static rct_object_entry_extended _objectEntriesRides[MAX_RIDE_OBJECTS];
static rct_object_entry_extended _objectEntriesSmallScenery[MAX_SMALL_SCENERY_OBJECTS];
static rct_object_entry_extended _objectEntriesLargeScenery[MAX_LARGE_SCENERY_OBJECTS];
@ -77,19 +74,6 @@ sint32 object_entry_group_encoding[] = {
static rct_object_entry_extended _objectEntriesParkEntrances[MAX_PARK_ENTRANCE_OBJECTS];
static rct_object_entry_extended _objectEntriesWaters[MAX_WATER_OBJECTS];
static rct_object_entry_extended _objectEntriesStexs[MAX_SCENARIO_TEXT_OBJECTS];
#else
#define _objectEntriesRides RCT2_ADDRESS(0x00F3F03C ,rct_object_entry_extended)
#define _objectEntriesSmallScenery RCT2_ADDRESS(0x00F3F03C + (128 * 20),rct_object_entry_extended)
#define _objectEntriesLargeScenery RCT2_ADDRESS(0x00F3F03C + (380 * 20),rct_object_entry_extended)
#define _objectEntriesWalls RCT2_ADDRESS(0x00F3F03C + (508 * 20),rct_object_entry_extended)
#define _objectEntriesBanners RCT2_ADDRESS(0x00F3F03C + (636 * 20),rct_object_entry_extended)
#define _objectEntriesFootpaths RCT2_ADDRESS(0x00F3F03C + (668 * 20),rct_object_entry_extended)
#define _objectEntriesFootpathAdditions RCT2_ADDRESS(0x00F3F03C + (684 * 20),rct_object_entry_extended)
#define _objectEntriesSceneryGroups RCT2_ADDRESS(0x00F3F03C + (699 * 20),rct_object_entry_extended)
#define _objectEntriesParkEntrances RCT2_ADDRESS(0x00F3F03C + (718 * 20),rct_object_entry_extended)
#define _objectEntriesWaters RCT2_ADDRESS(0x00F3F03C + (719 * 20),rct_object_entry_extended)
#define _objectEntriesStexs RCT2_ADDRESS(0x00F3F03C + (720 * 20),rct_object_entry_extended)
#endif // NO_RCT2
// 0x98D97C chunk address', 0x98D980 object_entries

View File

@ -1,6 +1,5 @@
#pragma once
#include "rct2/addresses.h"
#include "ride/ride.h"
#include "world/banner.h"
#include "world/entrance.h"
@ -24,33 +23,17 @@ extern "C" {
#define MAX_WATER_OBJECTS 1
#define MAX_SCENARIO_TEXT_OBJECTS 1
#ifdef NO_RCT2
extern rct_ride_entry *gRideEntries[MAX_RIDE_OBJECTS];
extern rct_small_scenery_entry *gSmallSceneryEntries[MAX_SMALL_SCENERY_OBJECTS];
extern rct_large_scenery_entry *gLargeSceneryEntries[MAX_LARGE_SCENERY_OBJECTS];
extern rct_wall_scenery_entry *gWallSceneryEntries[MAX_WALL_SCENERY_OBJECTS];
extern rct_banner *gBannerSceneryEntries[MAX_BANNER_OBJECTS];
extern rct_footpath_entry *gFootpathEntries[MAX_PATH_OBJECTS];
extern rct_path_bit_scenery_entry *gFootpathAdditionEntries[MAX_PATH_ADDITION_OBJECTS];
extern rct_scenery_group_entry *gSceneryGroupEntries[MAX_SCENERY_GROUP_OBJECTS];
extern rct_entrance_type *gParkEntranceEntries[MAX_PARK_ENTRANCE_OBJECTS];
extern rct_water_type *gWaterEntries[MAX_WATER_OBJECTS];
extern rct_stex_entry *gStexEntries[MAX_SCENARIO_TEXT_OBJECTS];
#else
#define gRideEntries RCT2_ADDRESS(RCT2_ADDRESS_RIDE_ENTRIES, rct_ride_entry*)
#define gSmallSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_SMALL_SCENERY_ENTRIES, rct_small_scenery_entry*)
#define gLargeSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_LARGE_SCENERY_ENTRIES, rct_large_scenery_entry*)
#define gWallSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_WALL_SCENERY_ENTRIES, rct_wall_scenery_entry*)
#define gBannerSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_BANNER_SCENERY_ENTRIES, rct_banner*)
#define gFootpathEntries RCT2_ADDRESS(RCT2_ADDRESS_PATH_TYPES, rct_footpath_entry*)
#define gFootpathAdditionEntries RCT2_ADDRESS(RCT2_ADDRESS_PATH_BIT_SCENERY_ENTRIES, rct_path_bit_scenery_entry*)
#define gSceneryGroupEntries RCT2_ADDRESS(RCT2_ADDRESS_SCENERY_SET_ENTRIES, rct_scenery_group_entry*)
#define gParkEntranceEntries RCT2_ADDRESS(RCT2_ADDRESS_PARK_ENTRANCE_ENTRIES, rct_entrance_type*)
#define gWaterEntries RCT2_ADDRESS(RCT2_ADDRESS_WATER_ENTRIES, rct_water_type*)
#define gStexEntries RCT2_ADDRESS(RCT2_ADDRESS_SCENARIO_TEXT_ENTRIES, rct_stex_entry*)
#endif
extern rct_ride_entry *gRideEntries[MAX_RIDE_OBJECTS];
extern rct_small_scenery_entry *gSmallSceneryEntries[MAX_SMALL_SCENERY_OBJECTS];
extern rct_large_scenery_entry *gLargeSceneryEntries[MAX_LARGE_SCENERY_OBJECTS];
extern rct_wall_scenery_entry *gWallSceneryEntries[MAX_WALL_SCENERY_OBJECTS];
extern rct_banner *gBannerSceneryEntries[MAX_BANNER_OBJECTS];
extern rct_footpath_entry *gFootpathEntries[MAX_PATH_OBJECTS];
extern rct_path_bit_scenery_entry *gFootpathAdditionEntries[MAX_PATH_ADDITION_OBJECTS];
extern rct_scenery_group_entry *gSceneryGroupEntries[MAX_SCENERY_GROUP_OBJECTS];
extern rct_entrance_type *gParkEntranceEntries[MAX_PARK_ENTRANCE_OBJECTS];
extern rct_water_type *gWaterEntries[MAX_WATER_OBJECTS];
extern rct_stex_entry *gStexEntries[MAX_SCENARIO_TEXT_OBJECTS];
void get_type_entry_index(size_t index, uint8 * outObjectType, uint8 * outEntryIndex);
const rct_object_entry * get_loaded_object_entry(size_t index);

View File

@ -31,12 +31,6 @@ uint8 gClipHeight = 128; // Default to middle value
paint_session gPaintSession;
static bool _paintSessionInUse;
#ifndef NO_RCT2
#define _paintQuadrants (RCT2_ADDRESS(0x00F1A50C, paint_struct*))
#define _paintQuadrantBackIndex RCT2_GLOBAL(0xF1AD0C, uint32)
#define _paintQuadrantFrontIndex RCT2_GLOBAL(0xF1AD10, uint32)
#endif
static const uint8 BoundBoxDebugColours[] =
{
0, // NONE

View File

@ -17,13 +17,11 @@
#ifndef _PAINT_H
#define _PAINT_H
#include "../rct2/addresses.h"
#include "../common.h"
#include "../world/map.h"
#include "../interface/colour.h"
#include "../drawing/drawing.h"
typedef struct attached_paint_struct attached_paint_struct;
typedef struct paint_struct paint_struct;
typedef union paint_entry paint_entry;
@ -181,28 +179,6 @@ typedef struct paint_session
extern paint_session gPaintSession;
#ifndef NO_RCT2
#define gPaintStructs RCT2_ADDRESS(0x00EE788C, paint_entry)
#define g_currently_drawn_item RCT2_GLOBAL(0x009DE578, void*)
#define gEndOfPaintStructArray RCT2_GLOBAL(0x00EE7880, paint_entry *)
#define gPaintSpritePosition RCT2_GLOBAL(0x009DE568, LocationXY16)
#define gPaintInteractionType RCT2_GLOBAL(RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE, uint8)
#define gSupportSegments RCT2_ADDRESS(RCT2_ADDRESS_CURRENT_SUPPORT_SEGMENTS, support_height)
#define gSupport RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT, support_height)
#define gWoodenSupportsPrependTo RCT2_GLOBAL(0x009DEA58, paint_struct *)
#define gPaintMapPosition RCT2_GLOBAL(0x009DE574, LocationXY16)
#define gLeftTunnels RCT2_ADDRESS(0x009E3138, tunnel_entry)
#define gLeftTunnelCount RCT2_GLOBAL(0x0141F56A, uint8)
#define gRightTunnels RCT2_ADDRESS(0x009E30B6, tunnel_entry)
#define gRightTunnelCount RCT2_GLOBAL(0x0141F56B, uint8)
#define gVerticalTunnelHeight RCT2_GLOBAL(0x009E323C, uint8)
#define gSurfaceElement RCT2_GLOBAL(0x009E3250, rct_tile_element *)
#define gDidPassSurface RCT2_GLOBAL(0x009DE57C, bool)
#define g141E9DB RCT2_GLOBAL(0x0141E9DB, uint8)
#define gUnk141E9DC RCT2_GLOBAL(0x0141E9DC, uint16)
#define gTrackColours RCT2_ADDRESS(0x00F44198, uint32)
#endif
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -490,14 +490,6 @@ bool wooden_a_supports_paint_setup(paint_session * session, sint32 supportType,
*/
bool wooden_b_supports_paint_setup(paint_session * session, sint32 supportType, sint32 special, sint32 height, uint32 imageColourFlags, bool * underground)
{
#ifndef NO_RCT2
if (gUseOriginalRidePaint) {
sint32 eax = special, ebx = 0, ecx = 0, edx = height, esi = 0, _edi = supportType, ebp = imageColourFlags;
RCT2_CALLFUNC_X(0x00662D5C, &eax, &ebx, &ecx, &edx, &esi, &_edi, &ebp);
return eax & 0xFF;
}
#endif
bool _9E32B1 = false;
if (gCurrentViewportFlags & VIEWPORT_FLAG_INVISIBLE_SUPPORTS) {
@ -876,14 +868,6 @@ bool metal_a_supports_paint_setup(paint_session * session, uint8 supportType, ui
*/
bool metal_b_supports_paint_setup(paint_session * session, uint8 supportType, uint8 segment, sint32 special, sint32 height, uint32 imageColourFlags)
{
#ifndef NO_RCT2
if (gUseOriginalRidePaint) {
sint32 eax = special, ebx = segment, ecx = 0, edx = height, esi = 0, _edi = supportType, ebp = imageColourFlags;
RCT2_CALLFUNC_X(0x00663584, &eax, &ebx, &ecx, &edx, &esi, &_edi, &ebp);
return eax & 0xFF;
}
#endif
support_height * supportSegments = session->SupportSegments;
uint8 originalSegment = segment;
@ -1065,15 +1049,6 @@ bool metal_b_supports_paint_setup(paint_session * session, uint8 supportType, ui
bool path_a_supports_paint_setup(paint_session * session, sint32 supportType, sint32 special, sint32 height, uint32 imageColourFlags,
rct_footpath_entry * pathEntry, bool * underground)
{
#ifndef NO_RCT2
if (gUseOriginalRidePaint) {
RCT2_GLOBAL(0xF3EF6C, rct_footpath_entry *) = pathEntry;
sint32 eax = special, ebx = 0, ecx = 0, edx = height, esi = 0, _edi = supportType, ebp = imageColourFlags;
RCT2_CALLFUNC_X(0x006A2ECC, &eax, &ebx, &ecx, &edx, &esi, &_edi, &ebp);
return eax & 0xFF;
}
#endif
if (underground != NULL) {
*underground = false; // AND
}
@ -1245,15 +1220,6 @@ bool path_a_supports_paint_setup(paint_session * session, sint32 supportType, si
bool path_b_supports_paint_setup(paint_session * session, sint32 segment, sint32 special, sint32 height, uint32 imageColourFlags,
rct_footpath_entry * pathEntry)
{
#ifndef NO_RCT2
if (gUseOriginalRidePaint) {
RCT2_GLOBAL(0xF3EF6C, rct_footpath_entry *) = pathEntry;
sint32 eax = special, ebx = segment, ecx = 0, edx = height, esi = 0, _edi = 0, ebp = imageColourFlags;
RCT2_CALLFUNC_X(0x006A326B, &eax, &ebx, &ecx, &edx, &esi, &_edi, &ebp);
return eax & 0xFF;
}
#endif
support_height * supportSegments = session->SupportSegments;
if (gCurrentViewportFlags & VIEWPORT_FLAG_INVISIBLE_SUPPORTS) {

View File

@ -143,11 +143,6 @@ static void sub_68B3FB(paint_session * session, sint32 x, sint32 y)
session->LeftTunnels[0] = (tunnel_entry){0xFF, 0xFF};
session->RightTunnels[0] = (tunnel_entry){0xFF, 0xFF};
session->VerticalTunnelHeight = 0xFF;
#ifndef NO_RCT2
RCT2_GLOBAL(0x009DE56A, uint16) = x;
RCT2_GLOBAL(0x009DE56E, uint16) = y;
#endif
session->MapPosition.x = x;
session->MapPosition.y = y;

View File

@ -17,7 +17,6 @@
#ifndef _PAINT_TILE_ELEMENT_H
#define _PAINT_TILE_ELEMENT_H
#include "../../rct2/addresses.h"
#include "../../common.h"
#include "../../world/map.h"

View File

@ -3056,7 +3056,6 @@ static void peep_update_ride_sub_state_1(rct_peep * peep)
}
sint8 load_position = 0;
#ifdef NO_RCT2
// Safe, in case current seat > number of loading positions
uint16 numSeatPositions = vehicle_type->peep_loading_positions_count;
if (numSeatPositions != 0)
@ -3068,10 +3067,6 @@ static void peep_update_ride_sub_state_1(rct_peep * peep)
}
load_position = vehicle_type->peep_loading_positions[loadPositionIndex];
}
#else
// Unsafe as we don't know the number of loading positions
load_position = vehicle_type->peep_loading_positions[peep->current_seat];
#endif
switch (vehicle->sprite_direction / 8)
{

View File

@ -1,244 +0,0 @@
#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 NO_RCT2
#include "addresses.h"
#if defined(__GNUC__)
#ifdef __clang__
#define DISABLE_OPT __attribute__((noinline,optnone))
#else
#define DISABLE_OPT __attribute__((noinline,optimize("O0")))
#endif // __clang__
#else
#define DISABLE_OPT
#endif // defined(__GNUC__)
// This variable serves a purpose of identifying a crash if it has happened inside original code.
// When switching to original code, stack frame pointer is modified and prevents breakpad from providing stack trace.
volatile sint32 _originalAddress = 0;
sint32 DISABLE_OPT RCT2_CALLPROC_X(sint32 address, sint32 _eax, sint32 _ebx, sint32 _ecx, sint32 _edx, sint32 _esi, sint32 _edi, sint32 _ebp)
{
sint32 result = 0;
_originalAddress = address;
#if defined(PLATFORM_X86) && !defined(NO_RCT2)
#ifdef _MSC_VER
__asm {
push ebp
push address
mov eax, _eax
mov ebx, _ebx
mov ecx, _ecx
mov edx, _edx
mov esi, _esi
mov edi, _edi
mov ebp, _ebp
call [esp]
lahf
pop ebp
pop ebp
/* Load result with flags */
mov result, eax
}
#else
__asm__ volatile ( "\
\n\
push %%ebx \n\
push %%ebp \n\
push %[address] \n\
mov %[eax], %%eax \n\
mov %[ebx], %%ebx \n\
mov %[ecx], %%ecx \n\
mov %[edx], %%edx \n\
mov %[esi], %%esi \n\
mov %[edi], %%edi \n\
mov %[ebp], %%ebp \n\
call *(%%esp) \n\
lahf \n\
add $4, %%esp \n\
pop %%ebp \n\
pop %%ebx \n\
/* Load result with flags */ \n\
mov %%eax, %[result] \n\
" : [address] "+m" (address), [eax] "+m" (_eax), [ebx] "+m" (_ebx), [ecx] "+m" (_ecx), [edx] "+m" (_edx), [esi] "+m" (_esi), [edi] "+m" (_edi), [ebp] "+m" (_ebp), [result] "+m" (result)
:
: "eax","ecx","edx","esi","edi","memory"
);
#endif
#endif // PLATFORM_X86
_originalAddress = 0;
// lahf only modifies ah, zero out the rest
return result & 0xFF00;
}
sint32 DISABLE_OPT RCT2_CALLFUNC_X(sint32 address, sint32 *_eax, sint32 *_ebx, sint32 *_ecx, sint32 *_edx, sint32 *_esi, sint32 *_edi, sint32 *_ebp)
{
sint32 result = 0;
_originalAddress = address;
#if defined(PLATFORM_X86) && !defined(NO_RCT2)
#ifdef _MSC_VER
__asm {
// Store C's base pointer
push ebp
push ebx
// Store address to call
push address
// Set all registers to the input values
mov eax, [_eax]
mov eax, [eax]
mov ebx, [_ebx]
mov ebx, [ebx]
mov ecx, [_ecx]
mov ecx, [ecx]
mov edx, [_edx]
mov edx, [edx]
mov esi, [_esi]
mov esi, [esi]
mov edi, [_edi]
mov edi, [edi]
mov ebp, [_ebp]
mov ebp, [ebp]
// Call function
call [esp]
// Store output eax
push eax
push ebp
push ebx
mov ebp, [esp + 20]
mov ebx, [esp + 16]
// Get resulting ecx, edx, esi, edi registers
mov eax, [_edi]
mov [eax], edi
mov eax, [_esi]
mov [eax], esi
mov eax, [_edx]
mov [eax], edx
mov eax, [_ecx]
mov [eax], ecx
// Pop ebx reg into ecx
pop ecx
mov eax, [_ebx]
mov[eax], ecx
// Pop ebp reg into ecx
pop ecx
mov eax, [_ebp]
mov[eax], ecx
pop eax
// Get resulting eax register
mov ecx, [_eax]
mov [ecx], eax
// Save flags as return in eax
lahf
// Pop address
pop ebp
pop ebx
pop ebp
/* Load result with flags */
mov result, eax
}
#else
__asm__ volatile ( "\
\n\
/* Store C's base pointer*/ \n\
push %%ebp \n\
push %%ebx \n\
\n\
/* Store %[address] to call*/ \n\
push %[address] \n\
\n\
/* Set all registers to the input values*/ \n\
mov %[_eax], %%eax \n\
mov (%%eax), %%eax \n\
mov %[_ebx], %%ebx \n\
mov (%%ebx), %%ebx \n\
mov %[_ecx], %%ecx \n\
mov (%%ecx), %%ecx \n\
mov %[_edx], %%edx \n\
mov (%%edx), %%edx \n\
mov %[_esi], %%esi \n\
mov (%%esi), %%esi \n\
mov %[_edi], %%edi \n\
mov (%%edi), %%edi \n\
mov %[_ebp], %%ebp \n\
mov (%%ebp), %%ebp \n\
\n\
/* Call function*/ \n\
call *(%%esp) \n\
\n\
/* Store output eax */ \n\
push %%eax \n\
push %%ebp \n\
push %%ebx \n\
mov 20(%%esp), %%ebp \n\
mov 16(%%esp), %%ebx \n\
/* Get resulting ecx, edx, esi, edi registers*/ \n\
mov %[_edi], %%eax \n\
mov %%edi, (%%eax) \n\
mov %[_esi], %%eax \n\
mov %%esi, (%%eax) \n\
mov %[_edx], %%eax \n\
mov %%edx, (%%eax) \n\
mov %[_ecx], %%eax \n\
mov %%ecx, (%%eax) \n\
/* Pop ebx reg into ecx*/ \n\
pop %%ecx \n\
mov %[_ebx], %%eax \n\
mov %%ecx, (%%eax) \n\
\n\
/* Pop ebp reg into ecx */\n\
pop %%ecx \n\
mov %[_ebp], %%eax \n\
mov %%ecx, (%%eax) \n\
\n\
pop %%eax \n\
/* Get resulting eax register*/ \n\
mov %[_eax], %%ecx \n\
mov %%eax, (%%ecx) \n\
\n\
/* Save flags as return in eax*/ \n\
lahf \n\
/* Pop address*/ \n\
pop %%ebp \n\
\n\
pop %%ebx \n\
pop %%ebp \n\
/* Load result with flags */ \n\
mov %%eax, %[result] \n\
" : [address] "+m" (address), [_eax] "+m" (_eax), [_ebx] "+m" (_ebx), [_ecx] "+m" (_ecx), [_edx] "+m" (_edx), [_esi] "+m" (_esi), [_edi] "+m" (_edi), [_ebp] "+m" (_ebp), [result] "+m" (result)
:
: "eax","ecx","edx","esi","edi","memory"
);
#endif
#endif // PLATFORM_X86
_originalAddress = 0;
// lahf only modifies ah, zero out the rest
return result & 0xFF00;
}
#endif // NO_RCT2

View File

@ -1,647 +0,0 @@
#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 _ADDRESSES_H_
#define _ADDRESSES_H_
#ifndef NO_RCT2
#include "../common.h"
#ifdef _MSC_VER
#pragma warning(disable : 4731)
#endif
#ifdef USE_MMAP
#if defined(PLATFORM_64BIT)
#define GOOD_PLACE_FOR_DATA_SEGMENT ((uintptr_t)0x200000000)
#elif defined(PLATFORM_32BIT)
#define GOOD_PLACE_FOR_DATA_SEGMENT ((uintptr_t)0x09000000)
#else
#error "Unknown platform"
#endif
#else
#define GOOD_PLACE_FOR_DATA_SEGMENT ((uintptr_t)0x8a4000)
#endif
#define RCT2_ADDRESS(address, type) ((type*)(GOOD_PLACE_FOR_DATA_SEGMENT - 0x8a4000 + (address)))
#define RCT2_GLOBAL(address, type) (*((type*)(GOOD_PLACE_FOR_DATA_SEGMENT - 0x8a4000 + (address))))
#pragma region Memory locations
#define RCT2_ADDRESS_VIEWPORT_PAINT_BITS_PTR 0x009AC118
#define RCT2_ADDRESS_VIEWPORT_DPI 0x009AC128
#define RCT2_ADDRESS_RIDE_ENTRIES 0x009ACFA4
#define RCT2_ADDRESS_SMALL_SCENERY_ENTRIES 0x009AD1A4
#define RCT2_ADDRESS_LARGE_SCENERY_ENTRIES 0x009AD594
#define RCT2_ADDRESS_WALL_SCENERY_ENTRIES 0x009AD794
#define RCT2_ADDRESS_BANNER_SCENERY_ENTRIES 0x009AD994
#define RCT2_ADDRESS_PATH_TYPES 0x009ADA14
#define RCT2_ADDRESS_PATH_BIT_SCENERY_ENTRIES 0x009ADA54
#define RCT2_ADDRESS_SCENERY_SET_ENTRIES 0x009ADA90
#define RCT2_ADDRESS_PARK_ENTRANCE_ENTRIES 0x009ADADC
#define RCT2_ADDRESS_WATER_ENTRIES 0x009ADAE0
#define RCT2_ADDRESS_SCENARIO_TEXT_ENTRIES 0x009ADAE4
// Of type viewport interaction
#define RCT2_ADDRESS_PAINT_SETUP_CURRENT_TYPE 0x009DE570
#define RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_X 0x009DEA52
#define RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_Y 0x009DEA54
#define RCT2_ADDRESS_PAINT_BOUNDBOX_OFFSET_Z 0x009DEA56
#define RCT2_ADDRESS_G1_ELEMENTS 0x009EBD28
// No longer used
#define RCT2_ADDRESS_PEEP_UPDATE_FALLING_MAP 0x00F1AEC4
#define RCT2_ADDRESS_PEEP_UPDATE_FALLING_HEIGHT 0x00F1AEC8
#define RCT2_ADDRESS_SCENARIO_TICKS 0x00F663AC
#define RCT2_ADDRESS_TILE_ELEMENTS 0x00F663B8
#define RCT2_ADDRESS_TILE_ELEMENTS_END 0x010E53B8
#define RCT2_ADDRESS_CURRENT_TICKS 0x013628F4
#define RCT2_ADDRESS_RIDE_LIST 0x013628F8
#define RCT2_ADDRESS_SPRITE_LIST 0x010E63BC
#define RCT2_ADDRESS_SPRITE_LISTS_HEAD 0x013573BC
#define RCT2_ADDRESS_SPRITE_LISTS_COUNT 0x013573C8
// How many ticks the scenario has existed for
#define RCT2_ADDRESS_SAVED_VIEW_X 0x0138869A
#define RCT2_ADDRESS_SAVED_VIEW_Y 0x0138869C
#define RCT2_ADDRESS_SAVED_VIEW_ZOOM 0x0138869E
#define RCT2_ADDRESS_SAVED_VIEW_ROTATION 0x0138869F
#define RCT2_ADDRESS_TILE_TILE_ELEMENT_POINTERS 0x013CE9A4
#define RCT2_ADDRESS_CURRENT_ROTATION 0x0141E9E0
#define RCT2_ADDRESS_CURRENT_VIEWPORT_FLAGS 0x0141E9E4
#define RCT2_ADDRESS_FONT_CHAR_WIDTH 0x0141E9E8
#define RCT2_ADDRESS_CURRENT_SUPPORT_SEGMENTS 0x0141E9B4
#define RCT2_ADDRESS_CURRENT_PAINT_TILE_MAX_HEIGHT 0x0141E9D8
#pragma endregion
#pragma region Obsolete
#ifdef USE_OBSOLETE_ADDRESSES
// The following addresses relate to memory locations that no longer used by
// OpenRCT2. This may be due to the data at those locations being stored in
// the new C modules or changed behaviour of code that used them.
#define RCT2_ADDRESS_RIDE_FLAGS 0x0097CF40
#define RCT2_ADDRESS_Y_RELATED_GLOBAL_1 0x9E3D12 // uint16
#define RCT2_ADDRESS_Y_END_POINT_GLOBAL 0x9ABDAC // sint16
#define RCT2_ADDRESS_Y_START_POINT_GLOBAL 0xEDF808 // sint16
#define RCT2_ADDRESS_X_RELATED_GLOBAL_1 0x9E3D10 // uint16
#define RCT2_ADDRESS_X_END_POINT_GLOBAL 0x9ABDA8 // sint16
#define RCT2_ADDRESS_X_START_POINT_GLOBAL 0xEDF80C // sint16
#define RCT2_ADDRESS_DPI_LINE_LENGTH_GLOBAL 0x9ABDB0 // uint16 width+pitch
#define RCT2_ADDRESS_LAND_TOOL_SIZE 0x009A9800
#define RCT2_ADDRESS_SAVE_PROMPT_MODE 0x009A9802
#define RCT2_ADDRESS_MAP_TOOLTIP_ARGS 0x009A9808
#define RCT2_ADDRESS_CONFIG_FIRST_TIME_LOAD_OBJECTS 0x009AA00D
#define RCT2_ADDRESS_CONFIG_FIRST_TIME_LOAD_CONFIG 0x009AB4C6
#define RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK 0x009ADAF8
#define RCT2_ADDRESS_NAUSEA_THRESHOLDS 0x00982390 // uint16
// An array of pointers to the start of a way to
// translate between scroll positions for drawing
#define RCT2_ADDRESS_SCROLLING_MODE_POSITIONS 0x00992FB8
// The following memory locations represent memory in RCT2 that is still used
// by OpenRCT2. Only when the memory is no longer needed due to them being
// stored in a new C module or changed behaviour of code that used them.
// This generally can happen once all functions that referenced the location
// are implemented in C. Sometimes memory locations are still used even if
// they aren't directly referenced, for example when a game is saved and
// loaded, large chunks of data is read and written to.
#define RCT2_ADDRESS_SPRITE_ENTRIES 0x00982708
#define RCT2_ADDRESS_EASTEREGG_NAMES 0x00988C20
#define RCT2_ADDRESS_BTM_TOOLBAR_DIRTY_FLAGS 0x009A9804
#define RCT2_ADDRESS_APP_PATH 0x009AA214
#define RCT2_ADDRESS_CONFIG_FLAGS 0x009AAC74
#define RCT2_ADDRESS_CONFIG_METRIC 0x009AAC78
#define RCT2_ADDRESS_CONFIG_TEMPERATURE 0x009AAC79
#define RCT2_ADDRESS_CONFIG_KEYBOARD_SHORTCUTS 0x009AAC7A
#define RCT2_ADDRESS_CONFIG_EDGE_SCROLLING 0x009AACBA
#define RCT2_ADDRESS_CONFIG_CURRENCY 0x009AACBB
#define RCT2_ADDRESS_CONFIG_HEIGHT_MARKERS 0x009AACBD
#define RCT2_ADDRESS_CONFIG_CONSTRUCTION_MARKER 0x009AACBF
#define RCT2_ADDRESS_APP_PATH_SLASH 0x009AB4D9
#define RCT2_ADDRESS_SAVED_GAMES_PATH 0x009AB5DA
#define RCT2_ADDRESS_SCENARIOS_PATH 0x009AB6E9
#define RCT2_ADDRESS_LANDSCAPES_PATH 0x009AB7FB
#define RCT2_ADDRESS_OBJECT_DATA_PATH 0x009AB90E
#define RCT2_ADDRESS_TRACKS_PATH 0x009ABA1E
#define RCT2_ADDRESS_SAVED_GAMES_PATH_2 0x009ABB37
#define RCT2_ADDRESS_EXPANSION_NAMES 0x009AACC0
#define RCT2_ADDRESS_EXPANSION_FLAGS 0x009AB4C0
#define RCT2_ADDRESS_CONFIG_RESOLUTION_WIDTH 0x009AB4C2
#define RCT2_ADDRESS_CONFIG_RESOLUTION_HEIGHT 0x009AB4C4
#define RCT2_ADDRESS_SCREEN_DPI 0x009ABDC8
#define RCT2_ADDRESS_SCREEN_WIDTH 0x009ABDD8
#define RCT2_ADDRESS_SCREEN_HEIGHT 0x009ABDDA
#define RCT2_ADDRESS_DIRTY_BLOCK_WIDTH 0x009ABDE4
#define RCT2_ADDRESS_DIRTY_BLOCK_HEIGHT 0x009ABDE6
#define RCT2_ADDRESS_DIRTY_BLOCK_COLUMNS 0x009ABDE8
#define RCT2_ADDRESS_DIRTY_BLOCK_ROWS 0x009ABDEC
#define RCT2_ADDRESS_NO_RAIN_PIXELS 0x009AC00C
#define RCT2_ADDRESS_RAIN_PATTERN 0x009AC010
#define RCT2_ADDRESS_LIGHTNING_ACTIVE 0x009AC068
#define RCT2_ADDRESS_VIEWPORT_PAINT_X 0x009AC11C
#define RCT2_ADDRESS_VIEWPORT_PAINT_Y 0x009AC11E
#define RCT2_ADDRESS_VIEWPORT_PAINT_WIDTH 0x009AC120
#define RCT2_ADDRESS_VIEWPORT_PAINT_HEIGHT 0x009AC122
#define RCT2_ADDRESS_VIEWPORT_PAINT_PITCH 0x009AC124
#define RCT2_ADDRESS_VIEWPORT_ZOOM 0x009AC126
#define RCT2_ADDRESS_RUN_INTRO_TICK_PART 0x009AC319
#define RCT2_ADDRESS_ERROR_TYPE 0x009AC31B
#define RCT2_ADDRESS_ERROR_STRING_ID 0x009AC31C
#define RCT2_ADDRESS_WINDOW_MAP_FLASHING_FLAGS 0x009AC861
#define RCT2_ADDRESS_INSTALLED_OBJECT_LIST 0x009ADAE8
#define RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST 0x009ADAEC
#define RCT2_ADDRESS_TOTAL_NO_IMAGES 0x009ADAF0
#define RCT2_ADDRESS_CURRENT_SOUND_DEVICE 0x009AF280
#define RCT2_ADDRESS_VEHICLE_SOUND_LIST 0x009AF288
#define RCT2_ADDRESS_DRAW_SCROLL_LIST 0x009C3840
#define RCT2_ADDRESS_DRAW_SCROLL_NEXT_ID 0x009D7A80
#define RCT2_ADDRESS_INPUT_FLAGS 0x009DE518
#define RCT2_ADDRESS_INPUT_STATE 0x009DE51D
#define RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS 0x009DE51F
#define RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER 0x009DE520
#define RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX 0x009DE524
#define RCT2_ADDRESS_CURSOR_DRAG_LAST_X 0x009DE52A
#define RCT2_ADDRESS_CURSOR_DRAG_LAST_Y 0x009DE52C
#define RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER 0x009DE52E
#define RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS 0x009DE530
#define RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS 0x009DE533
#define RCT2_ADDRESS_TOOLTIP_WINDOW_NUMBER 0x009DE534
#define RCT2_ADDRESS_TOOLTIP_WIDGET_INDEX 0x009DE536
#define RCT2_ADDRESS_TOOLTIP_CURSOR_X 0x009DE538
#define RCT2_ADDRESS_TOOLTIP_CURSOR_Y 0x009DE53A
#define RCT2_ADDRESS_TOOLTIP_TIMEOUT 0x009DE53C
#define RCT2_ADDRESS_TOOLTIP_NOT_SHOWN_TICKS 0x009DE53E
#define RCT2_ADDRESS_CURRENT_SCROLL_AREA 0x009DE548
#define RCT2_ADDRESS_CURRENT_SCROLL_ID 0x009DE54C
#define RCT2_ADDRESS_TICKS_SINCE_DRAG_START 0x009DE540
#define RCT2_ADDRESS_CURSOR_OVER_WINDOWCLASS 0x009DE55C
#define RCT2_ADDRESS_CURSOR_OVER_WINDOWNUMBER 0x009DE55E
#define RCT2_ADDRESS_CURSOR_OVER_WIDGETINDEX 0x009DE560
#define RCT2_ADDRESS_CURENT_CURSOR 0x009DE51C
#define RCT2_ADDRESS_TOOL_WINDOWNUMBER 0x009DE542
#define RCT2_ADDRESS_TOOL_WINDOWCLASS 0x009DE544
#define RCT2_ADDRESS_CURRENT_TOOL 0x009DE545
#define RCT2_ADDRESS_TOOL_WIDGETINDEX 0x009DE546
#define RCT2_ADDRESS_PICKEDUP_PEEP_IMAGE 0x009DE550
#define RCT2_ADDRESS_PICKEDUP_PEEP_X 0x009DE554
#define RCT2_ADDRESS_PICKEDUP_PEEP_Y 0x009DE556
#define RCT2_ADDRESS_LAST_TICK_COUNT 0x009DE580
#define RCT2_ADDRESS_PALETTE_EFFECT_FRAME_NO 0x009DE584
#define RCT2_ADDRESS_TICKS_SINCE_LAST_UPDATE 0x009DE588
// Flags:
// 0x1 Enable selection
// 0x2 Enable construct selection, see CONSTRUCT_PATH_*
// 0x4 Show yellow arrow, see MAP_ARROW_*
// 0x8 ?
#define RCT2_ADDRESS_MAP_SELECTION_FLAGS 0x009DE58A
#define RCT2_ADDRESS_MAP_SELECTION_A_X 0x009DE58C
#define RCT2_ADDRESS_MAP_SELECTION_B_X 0x009DE58E
#define RCT2_ADDRESS_MAP_SELECTION_A_Y 0x009DE590
#define RCT2_ADDRESS_MAP_SELECTION_B_Y 0x009DE592
// Types:
// 0-3 Corners
// 4 Whole tile
// 5 ?
// 6-9 Quarters
// 10-13 Edges
#define RCT2_ADDRESS_MAP_SELECTION_TYPE 0x009DE594
#define RCT2_ADDRESS_MAP_ARROW_X 0x009DEA48
#define RCT2_ADDRESS_MAP_ARROW_Y 0x009DEA4A
#define RCT2_ADDRESS_MAP_ARROW_Z 0x009DEA4C
#define RCT2_ADDRESS_MAP_ARROW_DIRECTION 0x009DEA4E
#define RCT2_ADDRESS_PLACE_OBJECT_MODIFIER 0x009DEA70
#define RCT2_ADDRESS_ON_TUTORIAL 0x009DEA71
#define RCT2_ADDRESS_MOUSE_WRITE_INDEX 0x009E2DE4
#define RCT2_ADDRESS_MOUSE_READ_INDEX 0x009E2DE8
#define RCT2_ADDRESS_PROGRESSBAR_HWND 0x009E2DF8
#define RCT2_ADDRESS_COMMAND_MAP_X 0x009DEA5E
#define RCT2_ADDRESS_COMMAND_MAP_Y 0x009DEA60
#define RCT2_ADDRESS_COMMAND_MAP_Z 0x009DEA62
#define RCT2_ADDRESS_SCREEN_AGE 0x009DEA66
#define RCT2_ADDRESS_SCREEN_FLAGS 0x009DEA68
#define RCT2_ADDRESS_SCREENSHOT_COUNTDOWN 0x009DEA6D
#define RCT2_ADDRESS_GAME_PAUSED 0x009DEA6E
#define RCT2_ADDRESS_WINDOW_DPI 0x009DEA74
#define RCT2_ADDRESS_WINDOW_UPDATE_TICKS 0x009DEB7C
#define RCT2_ADDRESS_TEXTINPUT_WIDGETINDEX 0x009DEB88
#define RCT2_ADDRESS_TEXTINPUT_WINDOWNUMBER 0x009DEB8A
#define RCT2_ADDRESS_TEXTINPUT_WINDOWCLASS 0x009DEB8C
#define RCT2_ADDRESS_CMDLINE 0x009E2D98
#define RCT2_ADDRESS_HFONT 0x009E2DEC
#define RCT2_ADDRESS_LAND_RAISE_COST 0x009E2E1C
#define RCT2_ADDRESS_LAND_LOWER_COST 0x009E2E20
#define RCT2_ADDRESS_SELECTED_TERRAIN_EDGE 0x009E2E24
#define RCT2_ADDRESS_SELECTED_TERRAIN_SURFACE 0x009E2E25
#define RCT2_ADDRESS_PARK_ENTRANCE_GHOST_X 0x009E32CC
#define RCT2_ADDRESS_PARK_ENTRANCE_GHOST_Y 0x009E32CE
#define RCT2_ADDRESS_PARK_ENTRANCE_GHOST_Z 0x009E32D0
#define RCT2_ADDRESS_PARK_ENTRANCE_GHOST_DIRECTION 0x009E32D1
#define RCT2_ADDRESS_PARK_ENTRANCE_GHOST_EXISTS 0x009E32D2
#define RCT2_ADDRESS_PARK_ENTRANCE_GHOST_PRICE 0x009E32D3
// Every pixel changed by rain is stored.
// 32bit (pixel_offset 24 bit)(pixel_colour 8 bit)
// Use the rainPixels[] global in drawing.c from now on
#define RCT2_ADDRESS_RAIN_PIXEL_STORE 0x00EDF850
#define RCT2_ADDRESS_UNCOMPLETED_RESEARCH_TYPES 0x00EE787C
#define RCT2_ADDRESS_ELEMENT_LOCATION_COMPARED_TO_GROUND_AND_WATER 0x00F1AD60
#define RCT2_ADDRESS_MAP_IMAGE_DATA 0x00F1AD68
#define RCT2_ADDRESS_PEEP_PATHFINDING_GOAL_X 0x00F1AECE
#define RCT2_ADDRESS_PEEP_PATHFINDING_GOAL_Y 0x00F1AED0
#define RCT2_ADDRESS_PEEP_PATHFINDING_GOAL_Z 0x00F1AED2
#define RCT2_ADDRESS_PEEP_PATHFINDING_FEWEST_NUM_STEPS 0x00F1AED3
#define RCT2_ADDRESS_PEEP_PATHFINDING_NUM_JUNCTIONS 0x00F1AEDC
#define RCT2_ADDRESS_PEEP_PATHFINDING_SINGLE_CHOICE_SECTION 0x00F1AEDE
#define RCT2_ADDRESS_PEEP_PATHFINDING_IS_STAFF 0x00F1AEDD
#define RCT2_ADDRESS_WINDOW_GUEST_LIST_SELECTED_FILTER 0x00F1EE06
#define RCT2_ADDRESS_WINDOW_GUEST_LIST_SELECTED_TAB 0x00F1EE12
#define RCT2_ADDRESS_WINDOW_GUEST_LIST_SELECTED_VIEW 0x00F1EE13
#define RCT2_ADDRESS_PROVISIONAL_PATH_FLAGS 0x00F3EF92
#define RCT2_ADDRESS_PROVISIONAL_PATH_X 0x00F3EF94
#define RCT2_ADDRESS_PROVISIONAL_PATH_Y 0x00F3EF96
#define RCT2_ADDRESS_PROVISIONAL_PATH_Z 0x00F3EF98
#define RCT2_ADDRESS_PATH_CONSTRUCTION_MODE 0x00F3EF99
#define RCT2_ADDRESS_PATH_ERROR_OCCURED 0x00F3EF9F
#define RCT2_ADDRESS_SELECTED_PATH_ID 0x00F3EFA0
#define RCT2_ADDRESS_SELECTED_PATH_TYPE 0x00F3EFA2
#define RCT2_ADDRESS_CONSTRUCT_PATH_FROM_X 0x00F3EF8A
#define RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Y 0x00F3EF8C
#define RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Z 0x00F3EF8E
#define RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION 0x00F3EF90
#define RCT2_ADDRESS_CONSTRUCT_PATH_SLOPE 0x00F3EF91
#define RCT2_ADDRESS_CONSTRUCT_PATH_VALID_DIRECTIONS 0x00F3EF9E
#define RCT2_ADDRESS_WINDOW_RIDE_LIST_INFORMATION_TYPE 0x00F43833
#define RCT2_ADDRESS_WINDOW_RIDE_LIST_SELECTED_TAB 0x00F43824
#define RCT2_ADDRESS_WINDOW_RIDE_LIST_HIGHLIGHTED_ITEM 0x00F43825
#define RCT2_ADDRESS_STAFF_HIGHLIGHTED_INDEX 0x00F43908
#define RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB 0x00F4390A
// Each character is painted onto a drawing surface
// any coloured pixels are marked in this bitmap
// 8 x 8 in size.
#define RCT2_ADDRESS_CHARACTER_BITMAP 0x00F4393C
#define RCT2_ADDRESS_TRACK_PREVIEW_ROTATION 0x00F440AE
#define RCT2_ADDRESS_TRACK_PREVIEW_X_MIN 0x00F440F9
#define RCT2_ADDRESS_TRACK_PREVIEW_X_MAX 0x00F440FB
#define RCT2_ADDRESS_TRACK_PREVIEW_Y_MIN 0x00F440FD
#define RCT2_ADDRESS_TRACK_PREVIEW_Y_MAX 0x00F440FF
#define RCT2_ADDRESS_TRACK_PREVIEW_Z_MIN 0x00F44101
#define RCT2_ADDRESS_TRACK_PREVIEW_Z_MAX 0x00F44103
#define RCT2_ADDRESS_TRACK_DESIGN_CACHE 0x00F44105
#define RCT2_ADDRESS_TRACK_DESIGN_INDEX_CACHE 0x00F44109
#define RCT2_ADDRESS_TRACK_DESIGN_NEXT_INDEX_CACHE 0x00F44119
#define RCT2_ADDRESS_TRACK_DESIGN_COST 0x00F4411D
#define RCT2_ADDRESS_TRACK_DESIGN_SCENERY_TOGGLE 0x00F44152
#define RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS 0x00F42B6C
#define RCT2_ADDRESS_ORIGINAL_RCT2_OBJECT_COUNT 0x00F42B70
#define RCT2_ADDRESS_CURR_OBJECT_BASE_STRING_ID 0x00F42BBC
#define RCT2_ADDRESS_CURR_OBJECT_CHUNK_POINTER 0x00F42BC0
#define RCT2_ADDRESS_SCENARIO_TEXT_TEMP_OBJECT 0x00F42BC8
// 1 if custom objects installed, 0 otherwise
#define RCT2_ADDRESS_CUSTOM_OBJECTS_INSTALLED 0x00F42BDA
#define RCT2_ADDRESS_SELECTED_OBJECTS_FILE_SIZE 0x00F4340D
#define RCT2_ADDRESS_VOLUME_ADJUST_ZOOM 0x00F438AC
#define RCT2_ADDRESS_ABOVE_GROUND_FLAGS 0x00F441D4
#define RCT2_ADDRESS_TRACK_LIST 0x00F441EC
#define RCT2_ADDRESS_CURRENT_MONTH_YEAR 0x00F663A8
#define RCT2_ADDRESS_CURRENT_MONTH_TICKS 0x00F663AA
#define RCT2_ADDRESS_SCENERY_COST 0x00F64EB4
#define RCT2_ADDRESS_SCENERY_TILE_ELEMENT 0x00F64EBC
#define RCT2_ADDRESS_SCENERY_ROTATION 0x00F64EC0
#define RCT2_ADDRESS_GHOST_SCENERY_X 0x00F64EC4
#define RCT2_ADDRESS_GHOST_SCENERY_Y 0x00F64EC6
#define RCT2_ADDRESS_GHOST_SCENERY_Z 0x00F64F09
#define RCT2_ADDRESS_SCENERY_TILE_ELEMENT_TYPE 0x00F64F0C
#define RCT2_ADDRESS_GHOST_SCENERY_TYPE 0x00F64F0D
#define RCT2_ADDRESS_SCENERY_TARGET_PATH_INCLINE 0x00F64F0F
#define RCT2_ADDRESS_GHOST_SCENERY_PATH_OBJECT_TYPE 0x00F64EAC
#define RCT2_ADDRESS_CTRL_PRESS_Z_COORDINATE 0x00F64ECC
#define RCT2_ADDRESS_SHIFT_PRESS_X_COORDINATE 0x00F64ECE
#define RCT2_ADDRESS_SHIFT_PRESS_Y_COORDINATE 0x00F64ED0
#define RCT2_ADDRESS_SHIFT_PRESS_Z_VECTOR 0x00F64ED2
#define RCT2_ADDRESS_SCENERY_Z_COORDINATE 0x00F64ED4
#define RCT2_ADDRESS_SCENERY_SELECTED_OBJECT 0x00F64EDA
#define RCT2_ADDRESS_SCENERY_TARGET_PATH_TYPE 0x00F64F10
#define RCT2_ADDRESS_GHOST_SCENERY_WALL_ROTATION 0x00F64F11
#define RCT2_ADDRESS_SCENERY_TOOL_CTRL_PRESSED 0x00F64F12
#define RCT2_ADDRESS_SCENERY_TOOL_SHIFT_PRESSED 0x00F64F13
#define RCT2_ADDRESS_SCENARIO_SRAND_0 0x00F663B0
#define RCT2_ADDRESS_SCENARIO_SRAND_1 0x00F663B4
#define RCT2_ADDRESS_INITIAL_CASH 0x013573DC
#define RCT2_ADDRESS_CURRENT_LOAN 0x013573E0
#define RCT2_TOTAL_RIDE_VALUE 0x013580EE
#define RCT2_ADDRESS_MAXIMUM_LOAN 0x013580F0
#define RCT2_ADDRESS_CURRENT_EXPENDITURE 0x0135832C
#define RCT2_ADDRESS_CURRENT_PROFIT 0x01358330
#define RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED 0x013587F8
#define RCT2_ADDRESS_CURRENT_INTEREST_RATE 0x0135934A
#define RCT2_ADDRESS_WEEKLY_PROFIT_AVERAGE_DIVIDEND 0x01358334
#define RCT2_ADDRESS_WEEKLY_PROFIT_AVERAGE_DIVISOR 0x01358338
#define RCT2_ADDRESS_BALANCE_HISTORY 0x0135812C
#define RCT2_ADDRESS_WEEKLY_PROFIT_HISTORY 0x0135833C
#define RCT2_ADDRESS_PARK_VALUE_HISTORY 0x01358540
#define RCT2_ADDRESS_EXPENDITURE_TABLE 0x01357848
#define RCT2_ADDRESS_PEEP_SPAWNS 0x013573F2
#define RCT2_ADDRESS_GUEST_CHANGE_MODIFIER 0x013573FE
#define RCT2_ADDRESS_LAST_GUESTS_IN_PARK 0x01357BC8
#define RCT2_ADDRESS_NEXT_GUEST_NUMBER 0x013B0E6C
#define RCT2_ADDRESS_PARK_NAME 0x013573D4
#define RCT2_ADDRESS_PARK_NAME_ARGS 0x013573D8
#define RCT2_ADDRESS_PEEP_WARNING_THROTTLE 0x01358750
#define RCT2_ADDRESS_PARK_FLAGS 0x013573E4
#define RCT2_ADDRESS_PARK_ENTRANCE_FEE 0x013573E8
#define RCT2_ADDRESS_GUESTS_IN_PARK 0x01357844
#define RCT2_ADDRESS_GUESTS_HEADING_FOR_PARK 0x01357846
#define RCT2_ADDRESS_HANDYMAN_COLOUR 0x01357BCD
#define RCT2_ADDRESS_MECHANIC_COLOUR 0x01357BCE
#define RCT2_ADDRESS_SECURITY_COLOUR 0x01357BCF
#define RCT2_ADDRESS_CURRENT_PARK_RATING 0x01357CB0
#define RCT2_ADDRESS_PARK_RATING_HISTORY 0x01357CB2
#define RCT2_ADDRESS_GUESTS_IN_PARK_HISTORY 0x01357CD2
#define RCT2_ADDRESS_OBJECTIVE_TYPE 0x013580F8
#define RCT2_ADDRESS_OBJECTIVE_YEAR 0x013580F9
#define RCT2_ADDRESS_OBJECTIVE_CURRENCY 0x013580FC
#define RCT2_ADDRESS_OBJECTIVE_NUM_GUESTS 0x01358100
#define RCT2_ADDRESS_COMPLETED_COMPANY_VALUE 0x01358740
#define RCT2_ADDRESS_TOTAL_ADMISSIONS 0x01358744
#define RCT2_ADDRESS_INCOME_FROM_ADMISSIONS 0x01358748
#define RCT2_ADDRESS_CURRENT_COMPANY_VALUE 0x0135874C
#define RCT2_ADDRESS_COMPANY_VALUE_RECORD 0x013587C0
#define RCT2_ADDRESS_GUEST_INITIAL_CASH 0x013580F4
#define RCT2_ADDRESS_GUEST_INITIAL_HAPPINESS 0x013580E9
#define RCT2_ADDRESS_GUEST_INITIAL_HUNGER 0x013580F6
#define RCT2_ADDRESS_GUEST_INITIAL_THIRST 0x013580F7
#define RCT2_ADDRESS_MAP_SIZE_UNITS 0x01358830
#define RCT2_ADDRESS_MAP_SIZE_MINUS_2 0x01358832
#define RCT2_ADDRESS_MAP_SIZE 0x01358834
#define RCT2_ADDRESS_MAP_MAX_XY 0x01358836
#define RCT2_ADDRESS_SAME_PRICE_THROUGHOUT 0x01358838
#define RCT2_ADDRESS_SAME_PRICE_THROUGHOUT_EXTENDED 0x0135934C
#define RCT2_ADDRESS_PARK_ENTRANCE_X 0x01359350
#define RCT2_ADDRESS_PARK_ENTRANCE_Y 0x01359358
#define RCT2_ADDRESS_PARK_ENTRANCE_Z 0x01359360
#define RCT2_ADDRESS_PARK_ENTRANCE_DIRECTION 0x01359368
#define RCT2_ADDRESS_CURRENT_RESEARCH_LEVEL 0x013573FF
#define RCT2_ADDRESS_ACTIVE_RESEARCH_TYPES 0x01357CF2
#define RCT2_ADDRESS_RESEARH_PROGRESS_STAGE 0x01357CF3
#define RCT2_ADDRESS_LAST_RESEARCHED_ITEM_SUBJECT 0x01357CF4
#define RCT2_ADDRESS_NEXT_RESEARCH_ITEM 0x013580E0
#define RCT2_ADDRESS_RESEARH_PROGRESS 0x013580E4
#define RCT2_ADDRESS_NEXT_RESEARCH_CATEGORY 0x013580E6
#define RCT2_ADDRESS_NEXT_RESEARCH_EXPECTED_DAY 0x013580E7
#define RCT2_ADDRESS_NEXT_RESEARCH_EXPECTED_MONTH 0x013580E8
#define RCT2_ADDRESS_RIDE_COUNT 0x013587C8
#define RCT2_ADDRESS_LAST_ENTRANCE_STYLE 0x01358840
#define RCT2_RESEARCH_ITEMS 0x01358844
#define RCT2_ADDRESS_RESEARCHED_RIDE_TYPES 0x01357404
#define RCT2_ADDRESS_RESEARCHED_RIDE_ENTRIES 0x01357424
#define RCT2_ADDRESS_RESEARCHED_TRACK_TYPES_A 0x01357444
#define RCT2_ADDRESS_RESEARCHED_TRACK_TYPES_B 0x01357644
#define RCT2_ADDRESS_RESEARCHED_SCENERY_ITEMS 0x01357BD0
#define RCT2_ADDRESS_PARK_SIZE 0x013580EA
#define RCT2_ADDRESS_CURRENT_PARK_VALUE 0x0135853C
#define RCT2_ADDRESS_AWARD_LIST 0x01358760
#define RCT2_ADDRESS_LAND_COST 0x01358770
#define RCT2_ADDRESS_CONSTRUCTION_RIGHTS_COST 0x01358772
#define RCT2_ADDRESS_LOAN_HASH 0x013587C4
#define RCT2_ADDRESS_SCENARIO_COMPLETED_BY 0x013587D8
#define RCT2_ADDRESS_PARK_RATING_WARNING_DAYS 0x0135883E
#define RCT2_ADDRESS_SCENARIO_NAME 0x0135920A
#define RCT2_ADDRESS_SCENARIO_DETAILS 0x0135924A
#define RCT2_ADDRESS_SAVED_AGE 0x01388698
#define RCT2_ADDRESS_NUM_MAP_ANIMATIONS 0x0138B580
#define RCT2_ADDRESS_RIDE_MEASUREMENTS 0x0138B60C
#define RCT2_ADDRESS_GRASS_SCENERY_TILEPOS 0x013B0E70
#define RCT2_ADDRESS_STAFF_PATROL_AREAS 0x013B0E72
#define RCT2_ADDRESS_STAFF_MODE_ARRAY 0x013CA672
#define RCT2_ADDRESS_CLIMATE 0x013CA746
#define RCT2_ADDRESS_CURRENT_WEATHER 0x013CA74A
#define RCT2_ADDRESS_NEXT_WEATHER 0x013CA74B
#define RCT2_ADDRESS_CURRENT_TEMPERATURE 0x013CA74C
#define RCT2_ADDRESS_NEXT_TEMPERATURE 0x013CA74D
#define RCT2_ADDRESS_CLIMATE_UPDATE_TIMER 0x013CA748
#define RCT2_ADDRESS_CURRENT_WEATHER_EFFECT 0x013CA74E
#define RCT2_ADDRESS_NEXT_WEATHER_EFFECT 0x013CA74F
#define RCT2_ADDRESS_CURRENT_WEATHER_GLOOM 0x013CA750
#define RCT2_ADDRESS_NEXT_WEATHER_GLOOM 0x013CA751
#define RCT2_ADDRESS_CURRENT_RAIN_LEVEL 0x013CA752
#define RCT2_ADDRESS_NEXT_RAIN_LEVEL 0x013CA753
#define RCT2_ADDRESS_NEWS_ITEM_LIST 0x013CA754
#define RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE 0x013CE950
#define RCT2_ADDRESS_CURRENT_FONT_FLAGS 0x013CE9A2
#define RCT2_ADDRESS_COMMON_FORMAT_ARGS 0x013CE952
#define RCT2_ADDRESS_NEXT_FREE_TILE_ELEMENT 0x0140E9A4
#define RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT 0x0141E9AC
#define RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE 0x0141E9AE
#define RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER 0x0141ED68
#define RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE 0x0141F56C
#define RCT2_ADDRESS_WATER_RAISE_COST 0x0141F738
#define RCT2_ADDRESS_WATER_LOWER_COST 0x0141F73C
#define RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_1 0x0141F740
#define RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_2 0x0141F741
#define RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_3 0x0141F742
#define RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_4 0x0141F743
#define RCT2_ADDRESS_TOOLTIP_TEXT_BUFFER 0x0141FE44
#define RCT2_ADDRESS_TOOLTIP_TEXT_HEIGHT 0x01420044
#define RCT2_ADDRESS_WINDOW_LIST 0x01420078
#define RCT2_ADDRESS_NEW_WINDOW_PTR 0x014234B8
#define RCT2_ADDRESS_VIEWPORT_LIST 0x014234BC
// Null Terminated list of active viewport pointers.
// This is also the end of RCT2_ADDRESS_VIEWPORT_LIST.
#define RCT2_ADDRESS_ACTIVE_VIEWPORT_PTR_ARRAY 0x01423570
#define RCT2_ADDRESS_HINSTANCE 0x01423A08
#define RCT2_ADDRESS_PALETTE 0x01424680
#define RCT2_ADDRESS_HCURSOR_START 0x01423598
#define RCT2_ADDRESS_HCURSOR_ARROW 0x01423598
#define RCT2_ADDRESS_HCURSOR_BLANK 0x0142359C
#define RCT2_ADDRESS_HCURSOR_UP_ARROW 0x014235A0
#define RCT2_ADDRESS_HCURSOR_UP_DOWN_ARROW 0x014235A4
#define RCT2_ADDRESS_HCURSOR_HAND_POINT 0x014235A8
#define RCT2_ADDRESS_HCURSOR_ZZZ 0x014235AC
#define RCT2_ADDRESS_HCURSOR_DIAGONAL_ARROWS 0x014235B0
#define RCT2_ADDRESS_HCURSOR_PICKER 0x014235B4
#define RCT2_ADDRESS_HCURSOR_TREE_DOWN 0x014235B8
#define RCT2_ADDRESS_HCURSOR_FOUNTAIN_DOWN 0x014235BC
#define RCT2_ADDRESS_HCURSOR_STATUE_DOWN 0x014235C0
#define RCT2_ADDRESS_HCURSOR_BENCH_DOWN 0x014235C4
#define RCT2_ADDRESS_HCURSOR_CROSS_HAIR 0x014235C8
#define RCT2_ADDRESS_HCURSOR_BIN_DOWN 0x014235CC
#define RCT2_ADDRESS_HCURSOR_LAMPPOST_DOWN 0x014235D0
#define RCT2_ADDRESS_HCURSOR_FENCE_DOWN 0x014235D4
#define RCT2_ADDRESS_HCURSOR_FLOWER_DOWN 0x014235D8
#define RCT2_ADDRESS_HCURSOR_PATH_DOWN 0x014235DC
#define RCT2_ADDRESS_HCURSOR_DIG_DOWN 0x014235E0
#define RCT2_ADDRESS_HCURSOR_WATER_DOWN 0x014235E4
#define RCT2_ADDRESS_HCURSOR_HOUSE_DOWN 0x014235E8
#define RCT2_ADDRESS_HCURSOR_VOLCANO_DOWN 0x014235EC
#define RCT2_ADDRESS_HCURSOR_WALK_DOWN 0x014235F0
#define RCT2_ADDRESS_HCURSOR_PAINT_DOWN 0x014235F4
#define RCT2_ADDRESS_HCURSOR_ENTRANCE_DOWN 0x014235F8
#define RCT2_ADDRESS_HCURSOR_HAND_OPEN 0x014235FC
#define RCT2_ADDRESS_HCURSOR_HAND_CLOSED 0x01423600
#define RCT2_ADDRESS_HCURSOR_END 0x01423600
#define RCT2_ADDRESS_WINDOW_MAP_SELECTED_TAB 0x014209E4
#define RCT2_ADDRESS_GAME_VERSION_NUMBER 0x0013587BC
#define RCT2_ADDRESS_OS_TIME_MINUTE 0x01424654
#define RCT2_ADDRESS_OS_TIME_HOUR 0x01424656
#define RCT2_ADDRESS_OS_TIME_DAY 0x01424304
#define RCT2_ADDRESS_OS_TIME_MONTH 0x01423A04
#define RCT2_ADDRESS_OS_TIME_YEAR 0x01424320
#define RCT2_ADDRESS_OS_TIME_DAYOFWEEK 0x01423B20
#define RCT2_ADDRESS_OS_PLATFORM_ID 0x01423B40
#define RCT2_ADDRESS_OS_MAJOR_VERSION 0x01423B44
#define RCT2_ADDRESS_OS_MINOR_VERSION 0x01423B48
#define RCT2_ADDRESS_OS_BUILD_NUMBER 0x01423B4C
#define RCT2_ADDRESS_OS_USER_NAME 0x01423B68
#define RCT2_ADDRESS_OS_COMPUTER_NAME 0x01423BB8
#define RCT2_ADDRESS_SYS_OEM_ID 0x01423B50
#define RCT2_ADDRESS_SYS_CPU_LEVEL 0x01423B52
#define RCT2_ADDRESS_SYS_CPU_REVISION 0x01423B54
#define RCT2_ADDRESS_SYS_CPU_NUMBER 0x01423B58
#define RCT2_ADDRESS_MEM_TOTAL_PHYSICAL 0x01423B5C
#define RCT2_ADDRESS_MEM_TOTAL_PAGEFILE 0x01423B60
#define RCT2_ADDRESS_MEM_TOTAL_VIRTUAL 0x01423B64
#define RCT2_ADDRESS_SCREEN_CAP_BPP 0x01423C10
#define RCT2_ADDRESS_SCREEN_CAP_RASTER_STRETCH 0x01423C14
#define RCT2_ADDRESS_INPUT_QUEUE 0x01424340
#define RCT2_ADDRESS_AUDIO_INFO 0x01425B40
#endif
#pragma endregion
/**
* Returns the flags register
*
* Flags register is as follows:
* 0bSZ0A_0P0C_0000_0000
* S = Signed flag
* Z = Zero flag
* C = Carry flag
* A = Adjust flag
* P = Parity flag
* All other bits are undefined.
*/
sint32 RCT2_CALLPROC_X(sint32 address, sint32 _eax, sint32 _ebx, sint32 _ecx, sint32 _edx, sint32 _esi, sint32 _edi, sint32 _ebp);
/**
* Returns the flags register
*
* Flags register is as follows:
* 0bSZ0A_0P0C_0000_00000
* S = Signed flag
* Z = Zero flag
* C = Carry flag
* A = Adjust flag
* P = Parity flag
* All other bits are undefined.
*/
sint32 RCT2_CALLFUNC_X(sint32 address, sint32 *_eax, sint32 *_ebx, sint32 *_ecx, sint32 *_edx, sint32 *_esi, sint32 *_edi, sint32 *_ebp);
#endif
#endif

View File

@ -1,214 +0,0 @@
#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
#include "../common.h"
#ifndef NO_RCT2
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/mman.h>
#endif // _WIN32
#include "../platform/platform.h"
#include "hook.h"
void* _hookTableAddress = 0;
sint32 _hookTableOffset = 0;
sint32 _maxHooks = 1000;
#define HOOK_BYTE_COUNT (140)
registers gHookRegisters = {0};
// This macro writes a little-endian 4-byte long value into *data
// It is used to avoid type punning.
#define write_address_strictalias(data, addr) \
*(data + 0) = ((addr) & 0x000000ff) >> 0; \
*(data + 1) = ((addr) & 0x0000ff00) >> 8; \
*(data + 2) = ((addr) & 0x00ff0000) >> 16; \
*(data + 3) = ((addr) & 0xff000000) >> 24;
static void hookfunc(uintptr_t address, uintptr_t hookAddress, sint32 stacksize)
{
sint32 i = 0;
uint8 data[HOOK_BYTE_COUNT] = {0};
uintptr_t registerAddress = (uintptr_t) &gHookRegisters;
data[i++] = 0x89; // mov [gHookRegisters], eax
data[i++] = (0b000 << 3) | 0b101;
write_address_strictalias(&data[i], registerAddress);
i += 4;
data[i++] = 0x89; // mov [gHookRegisters + 4], ebx
data[i++] = (0b011 << 3) | 0b101;
write_address_strictalias(&data[i], registerAddress + 4);
i += 4;
data[i++] = 0x89; // mov [gHookRegisters + 8], ecx
data[i++] = (0b001 << 3) | 0b101;
write_address_strictalias(&data[i], registerAddress + 8);
i += 4;
data[i++] = 0x89; // mov [gHookRegisters + 12], edx
data[i++] = (0b010 << 3) | 0b101;
write_address_strictalias(&data[i], registerAddress + 12);
i += 4;
data[i++] = 0x89; // mov [gHookRegisters + 16], esi
data[i++] = (0b110 << 3) | 0b101;
write_address_strictalias(&data[i], registerAddress + 16);
i += 4;
data[i++] = 0x89; // mov [gHookRegisters + 20], edi
data[i++] = (0b111 << 3) | 0b101;
write_address_strictalias(&data[i], registerAddress + 20);
i += 4;
data[i++] = 0x89; // mov [gHookRegisters + 24], ebp
data[i++] = (0b101 << 3) | 0b101;
write_address_strictalias(&data[i], registerAddress + 24);
i += 4;
// work out distance to nearest 0xC
// (esp - numargs * 4) & 0xC
// move to align - 4
// save that amount
// push the registers to be on the stack to access as arguments
data[i++] = 0x68; // push gHookRegisters
write_address_strictalias(&data[i], registerAddress);
i += 4;
data[i++] = 0xE8; // call
write_address_strictalias(&data[i], hookAddress - address - i - 4);
i += 4;
data[i++] = 0x83; // add esp, 4
data[i++] = 0xC4;
data[i++] = 0x04;
data[i++] = 0x25; // and eax,0xff
data[i++] = 0xff;
data[i++] = 0x00;
data[i++] = 0x00;
data[i++] = 0x00;
data[i++] = 0xc1; // shl eax, 8
data[i++] = 0xe0;
data[i++] = 0x08;
data[i++] = 0x9e; // sahf
data[i++] = 0x9c; // pushf
data[i++] = 0x8B; // mov eax, [gHookRegisters]
data[i++] = (0b000 << 3) | 0b101;
write_address_strictalias(&data[i], registerAddress);
i += 4;
data[i++] = 0x8B; // mov ebx, [gHookRegisters + 4]
data[i++] = (0b011 << 3) | 0b101;
write_address_strictalias(&data[i], registerAddress + 4);
i += 4;
data[i++] = 0x8B; // mov ecx, [gHookRegisters + 8]
data[i++] = (0b001 << 3) | 0b101;
write_address_strictalias(&data[i], registerAddress + 8);
i += 4;
data[i++] = 0x8B; // mov edx, [gHookRegisters + 12]
data[i++] = (0b010 << 3) | 0b101;
write_address_strictalias(&data[i], registerAddress + 12);
i += 4;
data[i++] = 0x8B; // mov esi, [gHookRegisters + 16]
data[i++] = (0b110 << 3) | 0b101;
write_address_strictalias(&data[i], registerAddress + 16);
i += 4;
data[i++] = 0x8B; // mov edi, [gHookRegisters + 20]
data[i++] = (0b111 << 3) | 0b101;
write_address_strictalias(&data[i], registerAddress + 20);
i += 4;
data[i++] = 0x8B; // mov ebp, [gHookRegisters + 24]
data[i++] = (0b101 << 3) | 0b101;
write_address_strictalias(&data[i], registerAddress + 24);
i += 4;
data[i++] = 0x9d; // popf
data[i++] = 0xC3; // retn
#ifdef _WIN32
WriteProcessMemory(GetCurrentProcess(), (LPVOID)address, data, i, 0);
#else
// We own the pages with PROT_WRITE | PROT_EXEC, we can simply just memcpy the data
memcpy((void *)address, data, i);
#endif // _WIN32
}
void addhook(uintptr_t address, hook_function *function)
{
if (!_hookTableAddress) {
size_t size = _maxHooks * HOOK_BYTE_COUNT;
#ifdef _WIN32
_hookTableAddress = VirtualAllocEx(GetCurrentProcess(), NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#else
_hookTableAddress = mmap(NULL, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (_hookTableAddress == MAP_FAILED)
{
perror("mmap");
exit(1);
}
#endif // _WIN32
}
if (_hookTableOffset > _maxHooks) {
return;
}
uint32 hookaddress = (uint32)_hookTableAddress + (_hookTableOffset * HOOK_BYTE_COUNT);
uint8 data[9];
sint32 i = 0;
data[i++] = 0xE9; // jmp
write_address_strictalias(&data[i], hookaddress - address - i - 4);
i += 4;
data[i++] = 0xC3; // retn
#ifdef _WIN32
WriteProcessMemory(GetCurrentProcess(), (LPVOID)address, data, i, 0);
#else
// We own the pages with PROT_WRITE | PROT_EXEC, we can simply just memcpy the data
sint32 err = mprotect((void *)0x401000, 0x8a4000 - 0x401000, PROT_READ | PROT_WRITE);
if (err != 0)
{
perror("mprotect");
}
memcpy((void *)address, data, i);
err = mprotect((void *)0x401000, 0x8a4000 - 0x401000, PROT_READ | PROT_EXEC);
if (err != 0)
{
perror("mprotect");
}
#endif // _WIN32
hookfunc(hookaddress, (uintptr_t)function, 0);
_hookTableOffset++;
}
#endif

View File

@ -1,48 +0,0 @@
#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 _HOOK_H_
#define _HOOK_H_
#ifndef NO_RCT2
#include "../common.h"
enum {
X86_FLAG_CARRY = 1 << 0,
X86_FLAG_PARITY = 1 << 2,
X86_FLAG_ADJUST = 1 << 4,
X86_FLAG_ZERO = 1 << 6,
X86_FLAG_SIGN = 1 << 7,
};
typedef uint8 (hook_function)(registers *regs);
#ifdef __cplusplus
extern "C" {
#endif
void addhook(uintptr_t address, hook_function *function);
#ifdef __cplusplus
}
#endif
#endif
#endif

View File

@ -1,238 +0,0 @@
#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
#include "../common.h"
#include "interop.h"
#if !defined(NO_RCT2)
#include <stdio.h>
#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#if defined(__unix__) || defined(__APPLE__)
#include <sys/mman.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#endif // defined(__unix__) || defined(__APPLE__)
#include "../OpenRCT2.h"
#include "../platform/platform.h"
#include "../util/sawyercoding.h"
#include "../util/util.h"
#include "addresses.h"
#include "hook.h"
#if defined(USE_MMAP) && (defined(__unix__) || defined(__APPLE__))
static sint32 fdData = -1;
#endif
static char * segments = (char *)(GOOD_PLACE_FOR_DATA_SEGMENT);
static void rct2_interop_get_segment_data_path(char * buffer, size_t bufferSize)
{
platform_get_exe_path(buffer, bufferSize);
safe_strcat_path(buffer, "openrct2_data", bufferSize);
}
/**
* Loads RCT2's data model and remaps the addresses.
* @returns true if the data integrity check succeeded, otherwise false.
*/
bool rct2_interop_setup_segment()
{
// OpenRCT2 on Linux and macOS is wired to have the original Windows PE sections loaded
// necessary. Windows does not need to do this as OpenRCT2 runs as a DLL loaded from the Windows PE.
sint32 len = 0x01429000 - 0x8a4000; // 0xB85000, 12079104 bytes or around 11.5MB
sint32 err = 0;
// in some configurations err and len may be unused
UNUSED(err);
UNUSED(len);
UNUSED(segments);
#if defined(USE_MMAP) && (defined(__unix__) || defined(__APPLE__))
#define RDATA_OFFSET 0x004A4000
#define DATASEG_OFFSET 0x005E2000
// Using PE-bear I was able to figure out all the needed addresses to be filled.
// There are three sections to be loaded: .rdata, .data and .text, plus another
// one to be mapped: DATASEG.
// Out of the three, two can simply be mmapped into memory, while the third one,
// .data has a virtual size which is much completely different to its file size
// (even when taking page-alignment into consideration)
//
// The sections are as follows (dump from gdb)
// [0] 0x401000->0x6f7000 at 0x00001000: .text ALLOC LOAD READONLY CODE HAS_CONTENTS
// [1] 0x6f7000->0x8a325d at 0x002f7000: CODESEG ALLOC LOAD READONLY CODE HAS_CONTENTS
// [2] 0x8a4000->0x9a5894 at 0x004a4000: .rdata ALLOC LOAD DATA HAS_CONTENTS
// [3] 0x9a6000->0x9e2000 at 0x005a6000: .data ALLOC LOAD DATA HAS_CONTENTS
// [4] 0x1428000->0x14282bc at 0x005e2000: DATASEG ALLOC LOAD DATA HAS_CONTENTS
// [5] 0x1429000->0x1452000 at 0x005e3000: .cms_t ALLOC LOAD READONLY CODE HAS_CONTENTS
// [6] 0x1452000->0x14aaf3e at 0x0060c000: .cms_d ALLOC LOAD DATA HAS_CONTENTS
// [7] 0x14ab000->0x14ac58a at 0x00665000: .idata ALLOC LOAD READONLY DATA HAS_CONTENTS
// [8] 0x14ad000->0x14b512f at 0x00667000: .rsrc ALLOC LOAD DATA HAS_CONTENTS
//
// .data section, however, has virtual size of 0xA81C3C, and so
// 0x9a6000 + 0xA81C3C = 0x1427C3C, which after alignment to page size becomes
// 0x1428000, which can be seen as next section, DATASEG
//
// The data is now loaded into memory with a linker script, which proves to
// be more reliable, as mallocs that happen before we reach segment setup
// could have already taken the space we need.
// TODO: UGLY, UGLY HACK!
//off_t file_size = 6750208;
utf8 segmentDataPath[MAX_PATH];
rct2_interop_get_segment_data_path(segmentDataPath, sizeof(segmentDataPath));
fdData = open(segmentDataPath, O_RDONLY);
if (fdData < 0)
{
log_fatal("failed to load openrct2_data");
exit(1);
}
log_warning("%p", GOOD_PLACE_FOR_DATA_SEGMENT);
segments = mmap((void *)(GOOD_PLACE_FOR_DATA_SEGMENT), len, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE, fdData, 0);
log_warning("%p", segments);
if ((uintptr_t)segments != GOOD_PLACE_FOR_DATA_SEGMENT) {
perror("mmap");
return false;
}
#endif // defined(USE_MMAP) && (defined(__unix__) || defined(__APPLE__))
#if defined(__unix__)
sint32 pageSize = getpagesize();
sint32 numPages = (len + pageSize - 1) / pageSize;
uint8 *dummy = malloc(numPages);
err = mincore((void *)segments, len, dummy);
bool pagesMissing = false;
if (err != 0)
{
err = errno;
#ifdef __linux__
// On Linux ENOMEM means all requested range is unmapped
if (err != ENOMEM)
{
pagesMissing = true;
perror("mincore");
}
#else
pagesMissing = true;
perror("mincore");
#endif // __linux__
} else {
for (sint32 i = 0; i < numPages; i++)
{
if (dummy[i] != 1)
{
pagesMissing = true;
void *start = (void *)segments + i * pageSize;
void *end = (void *)segments + (i + 1) * pageSize - 1;
log_warning("required page %p - %p is not in memory!", start, end);
}
}
}
free(dummy);
if (pagesMissing)
{
log_error("At least one of required pages was not found in memory. This can cause segfaults later on.");
}
#if !defined(USE_MMAP)
// section: text
err = mprotect((void *)0x401000, 0x8a4000 - 0x401000, PROT_READ | PROT_EXEC | PROT_WRITE);
if (err != 0)
{
perror("mprotect");
}
#endif // !defined(USE_MMAP)
// section: rw data
err = mprotect((void *)segments, 0x01429000 - 0x8a4000, PROT_READ | PROT_WRITE);
if (err != 0)
{
perror("mprotect");
}
#endif // defined(__unix__)
#if defined(USE_MMAP) && defined(_WIN32)
segments = VirtualAlloc((void *)(GOOD_PLACE_FOR_DATA_SEGMENT), len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if ((uintptr_t)segments != GOOD_PLACE_FOR_DATA_SEGMENT) {
log_error("VirtualAlloc, segments = %p, GetLastError = 0x%x", segments, GetLastError());
return false;
}
utf8 segmentDataPath[MAX_PATH];
rct2_interop_get_segment_data_path(segmentDataPath, sizeof(segmentDataPath));
// Warning: for Windows this will fail if given a non-ASCII path,
// but given this code is temporary - it's not worth resolving.
FILE * file = fopen(segmentDataPath, "rb");
if (file == NULL)
{
log_error("failed to load file");
return false;
}
if (fread(segments, len, 1, file) != 1) {
log_error("Unable to read chunk header!");
return false;
}
fclose(file);
#endif // defined(USE_MMAP) && defined(_WIN32)
#if defined(USE_MMAP)
// Check that the expected data is at various addresses.
// Start at 0x9a6000, which is start of .data, to skip the region containing addresses to DLL
// calls, which can be changed by windows/wine loader.
const uint32 c1 = sawyercoding_calculate_checksum((const uint8*)(segments + (uintptr_t)(0x009A6000 - 0x8a4000)), 0x009E0000 - 0x009A6000);
const uint32 c2 = sawyercoding_calculate_checksum((const uint8*)(segments + (uintptr_t)(0x01428000 - 0x8a4000)), 0x014282BC - 0x01428000);
const uint32 exp_c1 = 10114815;
const uint32 exp_c2 = 23564;
if (c1 != exp_c1 || c2 != exp_c2) {
log_warning("c1 = %u, expected %u, match %d", c1, exp_c1, c1 == exp_c1);
log_warning("c2 = %u, expected %u, match %d", c2, exp_c2, c2 == exp_c2);
return false;
}
#endif
return true;
}
/**
* Setup hooks to allow RCT2 to call OpenRCT2 functions instead.
*/
void rct2_interop_setup_hooks()
{
// None for now
}
void rct2_interop_dispose()
{
#if defined(USE_MMAP) && (defined(__unix__) || defined(__APPLE__)) && !defined(NO_RCT2)
munmap(segments, 12079104);
close(fdData);
#endif
}
#else
bool rct2_interop_setup_segment() { return true; }
void rct2_interop_setup_hooks() {}
void rct2_interop_dispose() {}
#endif // !defined(NO_RCT2)

View File

@ -1,32 +0,0 @@
#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 _RCT2_INTEROP_H_
#define _RCT2_INTEROP_H_
#ifdef __cplusplus
extern "C" {
#endif
bool rct2_interop_setup_segment();
void rct2_interop_setup_hooks();
void rct2_interop_dispose();
#ifdef __cplusplus
}
#endif
#endif

View File

@ -28,7 +28,6 @@
#include "../management/NewsItem.h"
#include "../platform/platform.h"
#include "../rct12.h"
#include "../rct2/hook.h"
#include "../scenario/scenario.h"
#include "../util/util.h"
#include "../world/map_animation.h"

View File

@ -20,13 +20,10 @@
#include "../common.h"
#include "../world/map.h"
#pragma pack(push, 1)
/* size: 0x2 */
typedef struct rct_vehicle_colour {
uint8 body_colour;
uint8 trim_colour;
} rct_vehicle_colour;
assert_struct_size(rct_vehicle_colour, 2);
/**
* Ride type vehicle structure.
@ -76,13 +73,8 @@ typedef struct rct_ride_entry_vehicle {
uint8 draw_order;
uint8 num_vertical_frames_override; // 0x60 , 0x7A, A custom number that can be used rather than letting RCT2 determine it. Needs the VEHICLE_ENTRY_FLAG_OVERRIDE_NUM_VERTICAL_FRAMES flag to be set.
sint8* peep_loading_positions; // 0x61 , 0x7B
#ifdef NO_RCT2
uint16 peep_loading_positions_count;
#endif
} rct_ride_entry_vehicle;
#if defined(PLATFORM_32BIT) && !defined(NO_RCT2)
assert_struct_size(rct_ride_entry_vehicle, 0x65);
#endif
typedef struct rct_vehicle {
uint8 sprite_identifier; // 0x00
@ -201,8 +193,6 @@ typedef struct rct_vehicle {
uint8 seat_rotation; // 0xD8
uint8 target_seat_rotation; // 0xD9
} rct_vehicle;
assert_struct_size(rct_vehicle, 0xDA);
#pragma pack(pop)
typedef struct train_ref {
rct_vehicle *head;

View File

@ -37,7 +37,6 @@
#include "../peep/Peep.h"
#include "../peep/Staff.h"
#include "../rct1.h"
#include "../rct2/addresses.h"
#include "../scenario/scenario.h"
#include "../util/util.h"
#include "../windows/Intent.h"
@ -134,11 +133,7 @@ static const sint32 RideInspectionInterval[] = {
10, 20, 30, 45, 60, 120, 0, 0
};
#ifdef NO_RCT2
Ride gRideList[MAX_RIDES];
#else
Ride *gRideList = RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, Ride);
#endif
rct_ride_measurement gRideMeasurements[MAX_RIDE_MEASUREMENTS];

View File

@ -125,14 +125,9 @@ typedef struct rct_ride_entry {
uint8 category[RCT2_MAX_CATEGORIES_PER_RIDE]; // 0x1BE
uint8 shop_item; // 0x1C0
uint8 shop_item_secondary; // 0x1C1
#if defined(NO_RCT2)
rct_string_id capacity;
rct_string_id vehicleName;
#endif
} rct_ride_entry;
#if defined(PLATFORM_32BIT) && !defined(NO_RCT2)
assert_struct_size(rct_ride_entry, 0x1c2);
#endif
/**
* Ride structure.
@ -1014,11 +1009,7 @@ extern uint32 gSamePriceThroughoutParkB;
extern const uint8 gRideClassifications[MAX_RIDES];
#ifdef NO_RCT2
extern Ride gRideList[MAX_RIDES];
#else
extern Ride *gRideList;
#endif
extern rct_ride_measurement gRideMeasurements[MAX_RIDE_MEASUREMENTS];
extern uint16 gRideCount;

View File

@ -42,11 +42,7 @@ bool gTrackDesignSaveMode = false;
uint8 gTrackDesignSaveRideIndex = 255;
static size_t _trackSavedTileElementsCount;
#ifdef NO_RCT2
static rct_tile_element *_trackSavedTileElements[TRACK_MAX_SAVED_TILE_ELEMENTS];
#else
static rct_tile_element **_trackSavedTileElements = (rct_tile_element**)0x00F63674;
#endif
static rct_tile_element *_trackSavedTileElements[TRACK_MAX_SAVED_TILE_ELEMENTS];
static size_t _trackSavedTileElementsDescCount;
static rct_td6_scenery_element _trackSavedTileElementsDesc[TRACK_MAX_SAVED_TILE_ELEMENTS];
@ -68,12 +64,7 @@ void track_design_save_init()
_trackSavedTileElementsCount = 0;
_trackSavedTileElementsDescCount = 0;
#ifdef NO_RCT2
memset(_trackSavedTileElements, 0, sizeof(_trackSavedTileElements));
#else
memset(_trackSavedTileElements, 0, sizeof(rct_tile_element*) * TRACK_MAX_SAVED_TILE_ELEMENTS);
#endif
memset(_trackSavedTileElementsDesc, 0, sizeof(_trackSavedTileElementsDesc));
}
@ -262,11 +253,6 @@ static void track_design_save_push_tile_element(sint32 x, sint32 y, rct_tile_ele
if (_trackSavedTileElementsCount < TRACK_MAX_SAVED_TILE_ELEMENTS) {
_trackSavedTileElements[_trackSavedTileElementsCount++] = tileElement;
map_invalidate_tile_full(x, y);
#ifndef NO_RCT2
// Required as drawing still uses 0xFFFFFFFF as a list terminator
_trackSavedTileElements[_trackSavedTileElementsCount] = NULL;
#endif
}
}
@ -432,11 +418,7 @@ static void track_design_save_pop_tile_element(sint32 x, sint32 y, rct_tile_elem
);
}
_trackSavedTileElementsCount--;
#ifdef NO_RCT2
_trackSavedTileElements[_trackSavedTileElementsCount] = NULL;
#else
_trackSavedTileElements[_trackSavedTileElementsCount] = NULL;
#endif
}
}

View File

@ -1787,36 +1787,13 @@ void track_paint(paint_session * session, uint8 direction, sint32 height, rct_ti
session->TrackColours[SCHEME_3] = ghost_id;
}
bool useOriginalRidePaint = false;
#ifndef NO_RCT2
useOriginalRidePaint = gUseOriginalRidePaint;
#endif
TRACK_PAINT_FUNCTION_GETTER paintFunctionGetter = RideTypeTrackPaintFunctions[ride->type];
if (paintFunctionGetter != NULL && !useOriginalRidePaint) {
if (paintFunctionGetter != NULL) {
TRACK_PAINT_FUNCTION paintFunction = paintFunctionGetter(trackType, direction);
if (paintFunction != NULL) {
paintFunction(session, rideIndex, trackSequence, direction, height, tileElement);
}
}
else {
#ifndef NO_RCT2
uint32 *trackDirectionList = (uint32 *)RideTypeTrackPaintFunctionsOld[ride->type][trackType];
if (trackDirectionList != NULL) {
// Have to call from this point as it pushes esi and expects callee to pop it
RCT2_CALLPROC_X(
0x006C4934,
ride->type,
(sint32)trackDirectionList,
direction,
height,
(sint32)tileElement,
rideIndex * sizeof(Ride),
trackSequence
);
}
#endif
}
}
if (isEntranceStyleNone) {

View File

@ -17,7 +17,6 @@
#ifndef _TRACK_PAINT_H
#define _TRACK_PAINT_H
#include "../rct2/addresses.h"
#include "ride_data.h"
#include "../common.h"
#include "../paint/tile_element/tile_element.h"

View File

@ -71,9 +71,7 @@ bool gFirstTimeSaving = true;
uint16 gSavedAge;
uint32 gLastAutoSaveUpdate = 0;
#if defined(NO_RCT2)
uint32 gScenarioTicks;
#endif
uint32 gScenarioSrand0;
uint32 gScenarioSrand1;

View File

@ -23,7 +23,6 @@
#include "../object.h"
#include "../rct12.h"
#include "../rct2.h"
#include "../rct2/addresses.h"
#include "../ride/ride.h"
#include "../ride/ride_ratings.h"
#include "../world/banner.h"
@ -366,11 +365,7 @@ extern "C" {
extern const rct_string_id ScenarioCategoryStringIds[SCENARIO_CATEGORY_COUNT];
#if defined(NO_RCT2)
extern uint32 gScenarioTicks;
#else
#define gScenarioTicks RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, uint32)
#endif
extern uint32 gScenarioSrand0;
extern uint32 gScenarioSrand1;

View File

@ -14,7 +14,6 @@
*****************************************************************************/
#pragma endregion
#include "../rct2/addresses.h"
#include "../audio/audio.h"
#include "../cheats.h"
#include "../config/Config.h"
@ -95,13 +94,8 @@ sint16 gMapSize;
sint16 gMapSizeMaxXY;
sint16 gMapBaseZ;
#if defined(NO_RCT2)
rct_tile_element gTileElements[MAX_TILE_TILE_ELEMENT_POINTERS * 3];
rct_tile_element *gTileElementTilePointers[MAX_TILE_TILE_ELEMENT_POINTERS];
#else
rct_tile_element *gTileElements = RCT2_ADDRESS(RCT2_ADDRESS_TILE_ELEMENTS, rct_tile_element);
rct_tile_element **gTileElementTilePointers = RCT2_ADDRESS(RCT2_ADDRESS_TILE_TILE_ELEMENT_POINTERS, rct_tile_element*);
#endif
LocationXY16 gMapSelectionTiles[300];
rct2_peep_spawn gPeepSpawns[MAX_PEEP_SPAWNS];

View File

@ -388,13 +388,8 @@ extern uint8 gMapSelectArrowDirection;
extern uint8 gMapGroundFlags;
#ifdef NO_RCT2
extern rct_tile_element gTileElements[];
extern rct_tile_element *gTileElementTilePointers[];
#else
extern rct_tile_element *gTileElements;
extern rct_tile_element **gTileElementTilePointers;
#endif
extern LocationXY16 gMapSelectionTiles[300];
extern rct2_peep_spawn gPeepSpawns[MAX_PEEP_SPAWNS];

View File

@ -21,20 +21,13 @@
#include "../localisation/date.h"
#include "../localisation/localisation.h"
#include "../OpenRCT2.h"
#include "../rct2/addresses.h"
#include "../scenario/scenario.h"
#include "Fountain.h"
#include "sprite.h"
#ifdef NO_RCT2
uint16 gSpriteListHead[6];
uint16 gSpriteListCount[6];
static rct_sprite _spriteList[MAX_SPRITES];
#else
uint16 *gSpriteListHead = RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LISTS_HEAD, uint16);
uint16 *gSpriteListCount = RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LISTS_COUNT, uint16);
static rct_sprite *_spriteList = RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite);
#endif
static bool _spriteFlashingList[MAX_SPRITES];

View File

@ -392,14 +392,8 @@ extern "C" {
rct_sprite *try_get_sprite(size_t spriteIndex);
rct_sprite *get_sprite(size_t sprite_idx);
#ifdef NO_RCT2
extern uint16 gSpriteListHead[6];
extern uint16 gSpriteListCount[6];
#else
extern uint16 *gSpriteListHead;
extern uint16 *gSpriteListCount;
#endif
extern uint16 gSpriteSpatialIndex[0x10001];
rct_sprite *create_sprite(uint8 bl);