Merge pull request #4244 from janisozaur/osx-test-64

64 bit support for OS X, Windows
This commit is contained in:
Ted John 2016-08-08 11:51:30 +01:00 committed by GitHub
commit 53ec220bf9
6 changed files with 122 additions and 45 deletions

View File

@ -63,6 +63,10 @@ add_definitions(-DOPENRCT2_COMMIT_SHA1_SHORT="${OPENRCT2_COMMIT_SHA1_SHORT}")
INCLUDE(FindPkgConfig) INCLUDE(FindPkgConfig)
if (APPLE)
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/opt/openssl/lib/pkgconfig")
endif (APPLE)
# Options # Options
option(DISABLE_HTTP_TWITCH "Disable HTTP and Twitch support.") option(DISABLE_HTTP_TWITCH "Disable HTTP and Twitch support.")
@ -75,12 +79,17 @@ option(STATIC "Create a static build.")
option(FORCE64 "Force native (x86-64) build. Do not use, for experimental purposes only.") option(FORCE64 "Force native (x86-64) build. Do not use, for experimental purposes only.")
option(DISABLE_OPENGL "Disable OpenGL support.") option(DISABLE_OPENGL "Disable OpenGL support.")
option(DISABLE_RCT2 "WIP: Try building without using code and data segments from vanilla.") option(DISABLE_RCT2 "WIP: Try building without using code and data segments from vanilla.")
option(USE_MMAP "Use mmap to try loading rct2's data segment into memory.")
if (FORCE64) if (FORCE64)
set(TARGET_M "-m64") set(TARGET_M "-m64")
set(OBJ_FORMAT "elf64-x86-64") set(OBJ_FORMAT "elf64-x86-64")
set(LINKER_SCRIPT "ld_script_x86_64.xc") set(LINKER_SCRIPT "ld_script_x86_64.xc")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=pointer-to-int-cast -Wno-error=int-to-pointer-cast")
if ((APPLE OR WIN32) AND NOT USE_MMAP)
message(WARNING "Building such configuration won't work. Enabling USE_MMAP.")
set(USE_MMAP ON)
endif()
else () else ()
set(TARGET_M "-m32") set(TARGET_M "-m32")
set(OBJ_FORMAT "elf32-i386") set(OBJ_FORMAT "elf32-i386")
@ -94,6 +103,10 @@ else (DISABLE_OPENGL)
add_definitions(-DOPENGL_NO_LINK) add_definitions(-DOPENGL_NO_LINK)
endif (DISABLE_OPENGL) endif (DISABLE_OPENGL)
if (USE_MMAP)
add_definitions(-DUSE_MMAP)
endif (USE_MMAP)
if (DISABLE_NETWORK) if (DISABLE_NETWORK)
add_definitions(-DDISABLE_NETWORK) add_definitions(-DDISABLE_NETWORK)
else (DISABLE_NETWORK) else (DISABLE_NETWORK)
@ -142,35 +155,40 @@ if (UNIX)
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/openrct2.exe DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/openrct2.exe
) )
add_custom_target(segfiles DEPENDS openrct2_text openrct2_data) add_custom_target(segfiles DEPENDS openrct2_text openrct2_data)
if (APPLE) if (NOT USE_MMAP)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -sectcreate rct2_text __text ${CMAKE_CURRENT_SOURCE_DIR}/build/openrct2_text -sectcreate rct2_data __data ${CMAKE_CURRENT_SOURCE_DIR}/build/openrct2_data -segaddr rct2_data 0x8a4000 -segprot rct2_data rwx rwx -segaddr rct2_text 0x401000 -segprot rct2_text rwx rwx -segaddr __TEXT 0x2000000 -fno-pie -read_only_relocs suppress") if (APPLE)
else (APPLE) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -sectcreate rct2_text __text ${CMAKE_CURRENT_SOURCE_DIR}/build/openrct2_text -sectcreate rct2_data __data ${CMAKE_CURRENT_SOURCE_DIR}/build/openrct2_data -segaddr rct2_data 0x8a4000 -segprot rct2_data rwx rwx -segaddr rct2_text 0x401000 -segprot rct2_text rwx rwx -segaddr __TEXT 0x2000000 -fno-pie -read_only_relocs suppress")
# For Linux we have to use objcopy to wrap regular binaries into a linkable else (APPLE)
# format. We use specific section names which are then referenced in a # For Linux we have to use objcopy to wrap regular binaries into a linkable
# bespoke linker script so they can be placed at predefined VMAs. # format. We use specific section names which are then referenced in a
add_custom_command( # bespoke linker script so they can be placed at predefined VMAs.
OUTPUT openrct2_text_section.o add_custom_command(
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 OUTPUT openrct2_text_section.o
DEPENDS segfiles 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
WORKING_DIRECTORY ${CMAKE_BINARY_DIR} DEPENDS segfiles
) WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
add_custom_command( )
OUTPUT openrct2_data_section.o add_custom_command(
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 OUTPUT openrct2_data_section.o
DEPENDS segfiles 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
WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 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( add_custom_target(linkable_sections DEPENDS openrct2_text_section.o openrct2_data_section.o)
openrct2_text_section.o openrct2_data_section.o SET_SOURCE_FILES_PROPERTIES(
PROPERTIES openrct2_text_section.o openrct2_data_section.o
EXTERNAL_OBJECT true PROPERTIES
GENERATED true 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") # can't use GLOB here, as the files don't exist yet at cmake-time
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-T,\"${CMAKE_CURRENT_SOURCE_DIR}/distribution/linux/${LINKER_SCRIPT}\"") set(RCT2_SECTIONS "${CMAKE_BINARY_DIR}/openrct2_data_section.o" "${CMAKE_BINARY_DIR}/openrct2_text_section.o")
endif (APPLE) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-T,\"${CMAKE_CURRENT_SOURCE_DIR}/distribution/linux/${LINKER_SCRIPT}\"")
endif (APPLE)
endif (NOT USE_MMAP)
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 (UNIX) endif (UNIX)
set(DEBUG_LEVEL 0 CACHE STRING "Select debug level for compilation. Use value in range 03.") set(DEBUG_LEVEL 0 CACHE STRING "Select debug level for compilation. Use value in range 03.")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEBUG=${DEBUG_LEVEL}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEBUG=${DEBUG_LEVEL}")
@ -226,6 +244,10 @@ if (NOT DISABLE_OPENGL)
if (WIN32) if (WIN32)
# Curl depends on openssl and ws2 in mingw builds, but is not wired up in pkg-config # Curl depends on openssl and ws2 in mingw builds, but is not wired up in pkg-config
set(GLLIBS opengl32) set(GLLIBS opengl32)
elseif (APPLE)
# GL doesn't work nicely with macOS, while find_package doesn't work with multiarch on Ubuntu.
find_package(OpenGL REQUIRED)
set(GLLIBS ${OPENGL_LIBRARY})
else (WIN32) else (WIN32)
PKG_CHECK_MODULES(GL REQUIRED gl) PKG_CHECK_MODULES(GL REQUIRED gl)
set(GLLIBS ${GL_LIBRARIES}) set(GLLIBS ${GL_LIBRARIES})
@ -252,7 +274,7 @@ if (UNIX)
set(DLLIB dl) set(DLLIB dl)
endif (UNIX) endif (UNIX)
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${LIBCURL_INCLUDE_DIRS} ${JANSSON_INCLUDE_DIRS} ${SPEEX_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS} ${BREAKPAD_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${LIBCURL_INCLUDE_DIRS} ${JANSSON_INCLUDE_DIRS} ${SPEEX_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS} ${BREAKPAD_INCLUDE_DIR} ${SSL_INCLUDE_DIRS})
LINK_DIRECTORIES(${SDL2_LIBRARY_DIRS} ${JANSSON_LIBRARY_DIRS} ${LIBCURL_LIBRARY_DIRS} ${PNG_LIBRARY_DIRS} ${ZLIB_LIBRARY_DIRS} ${BREAKPAD_LIBRARY_DIR} ${SSL_LIBRARY_DIRS}) LINK_DIRECTORIES(${SDL2_LIBRARY_DIRS} ${JANSSON_LIBRARY_DIRS} ${LIBCURL_LIBRARY_DIRS} ${PNG_LIBRARY_DIRS} ${ZLIB_LIBRARY_DIRS} ${BREAKPAD_LIBRARY_DIR} ${SSL_LIBRARY_DIRS})
@ -264,7 +286,11 @@ endif (NOT DISABLE_RCT2)
if (WIN32) if (WIN32)
# build as library for now, replace with add_executable # build as library for now, replace with add_executable
add_library(${PROJECT} SHARED ${ORCT2_SOURCES} ${SPEEX_SOURCES}) if (USE_MMAP)
add_executable(${PROJECT} ${ORCT2_SOURCES} ${SPEEX_SOURCES})
else ()
add_library(${PROJECT} SHARED ${ORCT2_SOURCES} ${SPEEX_SOURCES})
endif ()
else (WIN32) else (WIN32)
add_executable(${PROJECT} ${ORCT2_SOURCES} ${ORCT2_MM_SOURCES} ${RCT2_SECTIONS}) add_executable(${PROJECT} ${ORCT2_SOURCES} ${ORCT2_MM_SOURCES} ${RCT2_SECTIONS})
add_dependencies(${PROJECT} segfiles) add_dependencies(${PROJECT} segfiles)

View File

@ -650,7 +650,7 @@
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>$(OpenRCT2_DEFINES);DEBUG;OPENGL_NO_LINK;_CRT_SECURE_NO_WARNINGS;_USE_MATH_DEFINES;CURL_STATICLIB;SDL_MAIN_HANDLED;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>USE_MMAP;$(OpenRCT2_DEFINES);DEBUG;OPENGL_NO_LINK;_CRT_SECURE_NO_WARNINGS;_USE_MATH_DEFINES;CURL_STATICLIB;SDL_MAIN_HANDLED;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<ObjectFileName>$(IntDir)\%(RelativeDir)</ObjectFileName> <ObjectFileName>$(IntDir)\%(RelativeDir)</ObjectFileName>
@ -677,7 +677,7 @@
<TreatSpecificWarningsAsErrors>4013</TreatSpecificWarningsAsErrors> <TreatSpecificWarningsAsErrors>4013</TreatSpecificWarningsAsErrors>
<OmitFramePointers /> <OmitFramePointers />
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
<PreprocessorDefinitions>$(OpenRCT2_DEFINES);OPENGL_NO_LINK;_CRT_SECURE_NO_WARNINGS;_USE_MATH_DEFINES;CURL_STATICLIB;SDL_MAIN_HANDLED;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>USE_MMAP;$(OpenRCT2_DEFINES);OPENGL_NO_LINK;_CRT_SECURE_NO_WARNINGS;_USE_MATH_DEFINES;CURL_STATICLIB;SDL_MAIN_HANDLED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ObjectFileName>$(IntDir)\%(RelativeDir)</ObjectFileName> <ObjectFileName>$(IntDir)\%(RelativeDir)</ObjectFileName>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>

View File

@ -23,8 +23,14 @@
#pragma warning(disable : 4731) #pragma warning(disable : 4731)
#endif #endif
#define RCT2_ADDRESS(address, type) ((type*)(address)) #ifdef USE_MMAP
#define RCT2_GLOBAL(address, type) (*((type*)(address))) #define GOOD_PLACE_FOR_DATA_SEGMENT ((uintptr_t)0x200000000)
#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 #pragma region Memory locations

View File

@ -40,16 +40,18 @@
#include "version.h" #include "version.h"
#include "world/mapgen.h" #include "world/mapgen.h"
#if defined(__unix__) #if defined(__unix__) || defined(__MACOSX__)
#include <sys/mman.h> #include <sys/mman.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#endif // defined(__unix__) #endif // defined(__unix__) || defined(__MACOSX__)
int gExitCode; int gExitCode;
int fdData;
char *segments = (void *)(GOOD_PLACE_FOR_DATA_SEGMENT);
int gOpenRCT2StartupAction = STARTUP_ACTION_TITLE; int gOpenRCT2StartupAction = STARTUP_ACTION_TITLE;
utf8 gOpenRCT2StartupActionPath[512] = { 0 }; utf8 gOpenRCT2StartupActionPath[512] = { 0 };
@ -350,6 +352,10 @@ void openrct2_dispose()
#ifndef DISABLE_NETWORK #ifndef DISABLE_NETWORK
EVP_MD_CTX_destroy(gHashCTX); EVP_MD_CTX_destroy(gHashCTX);
#endif // DISABLE_NETWORK #endif // DISABLE_NETWORK
#if defined(USE_MMAP) && (defined(__unix__) || defined(__MACOSX__))
munmap(segments, 12079104);
close(fdData);
#endif
platform_free(); platform_free();
} }
@ -499,7 +505,9 @@ bool openrct2_setup_rct2_segment()
{ {
// OpenRCT2 on Linux and macOS is wired to have the original Windows PE sections loaded // 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. // necessary. Windows does not need to do this as OpenRCT2 runs as a DLL loaded from the Windows PE.
#if defined(__unix__) int len = 0x01429000 - 0x8a4000; // 0xB85000, 12079104 bytes or around 11.5MB
int err = 0;
#if defined(USE_MMAP) && (defined(__unix__) || defined(__MACOSX__))
#define RDATA_OFFSET 0x004A4000 #define RDATA_OFFSET 0x004A4000
#define DATASEG_OFFSET 0x005E2000 #define DATASEG_OFFSET 0x005E2000
@ -532,11 +540,27 @@ bool openrct2_setup_rct2_segment()
// TODO: UGLY, UGLY HACK! // TODO: UGLY, UGLY HACK!
//off_t file_size = 6750208; //off_t file_size = 6750208;
int len = 0x01429000 - 0x8a4000; // 0xB85000, 12079104 bytes or around 11.5MB fdData = open("openrct2_data", 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(__MACOSX__))
#if defined(__unix__)
int pageSize = getpagesize(); int pageSize = getpagesize();
int numPages = (len + pageSize - 1) / pageSize; int numPages = (len + pageSize - 1) / pageSize;
unsigned char *dummy = malloc(numPages); unsigned char *dummy = malloc(numPages);
int err = mincore((void *)0x8a4000, len, dummy);
err = mincore((void *)0x8a4000, len, dummy);
bool pagesMissing = false; bool pagesMissing = false;
if (err != 0) if (err != 0)
{ {
@ -569,12 +593,14 @@ bool openrct2_setup_rct2_segment()
{ {
log_error("At least one of required pages was not found in memory. This can cause segfaults later on."); 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 // section: text
err = mprotect((void *)0x401000, 0x8a4000 - 0x401000, PROT_READ | PROT_EXEC); err = mprotect((void *)0x401000, 0x8a4000 - 0x401000, PROT_READ | PROT_EXEC);
if (err != 0) if (err != 0)
{ {
perror("mprotect"); perror("mprotect");
} }
#endif // !defined(USE_MMAP)
// section: rw data // section: rw data
err = mprotect((void *)0x8a4000, 0x01429000 - 0x8a4000, PROT_READ | PROT_WRITE); err = mprotect((void *)0x8a4000, 0x01429000 - 0x8a4000, PROT_READ | PROT_WRITE);
if (err != 0) if (err != 0)
@ -583,12 +609,30 @@ bool openrct2_setup_rct2_segment()
} }
#endif // defined(__unix__) #endif // defined(__unix__)
#if !defined(NO_RCT2) || !defined(__WINDOWS__) #if defined(USE_MMAP) && defined(__WINDOWS__)
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;
}
SDL_RWops * rw = SDL_RWFromFile("openrct2_data", "rb");
if (rw == NULL)
{
log_error("failed to load file");
return false;
}
if (SDL_RWread(rw, segments, len, 1) != 1) {
log_error("Unable to read chunk header!");
return false;
}
SDL_RWclose(rw);
#endif // defined(USE_MMAP) && defined(__WINDOWS__)
// Check that the expected data is at various addresses. // 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 // 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. // calls, which can be changed by windows/wine loader.
const uint32 c1 = sawyercoding_calculate_checksum((void *)0x009A6000, 0x009E0000 - 0x009A6000); const uint32 c1 = sawyercoding_calculate_checksum((const uint8*)(segments + (uintptr_t)(0x009A6000 - 0x8a4000)), 0x009E0000 - 0x009A6000);
const uint32 c2 = sawyercoding_calculate_checksum((void *)0x01428000, 0x014282BC - 0x01428000); const uint32 c2 = sawyercoding_calculate_checksum((const uint8*)(segments + (uintptr_t)(0x01428000 - 0x8a4000)), 0x014282BC - 0x01428000);
const uint32 exp_c1 = 10114815; const uint32 exp_c1 = 10114815;
const uint32 exp_c2 = 23564; const uint32 exp_c2 = 23564;
if (c1 != exp_c1 || c2 != exp_c2) { if (c1 != exp_c1 || c2 != exp_c2) {
@ -596,7 +640,6 @@ bool openrct2_setup_rct2_segment()
log_warning("c2 = %u, expected %u, match %d", c2, exp_c2, c2 == exp_c2); log_warning("c2 = %u, expected %u, match %d", c2, exp_c2, c2 == exp_c2);
return false; return false;
} }
#endif
return true; return true;
} }

View File

@ -59,7 +59,7 @@ static HMODULE _dllModule = NULL;
/** /**
* Windows entry point to OpenRCT2 with a console window using a traditional C main function. * Windows entry point to OpenRCT2 with a console window using a traditional C main function.
*/ */
int main(char *argv[], int argc) int main(int argc, char *argv[])
{ {
HINSTANCE hInstance = GetModuleHandle(NULL); HINSTANCE hInstance = GetModuleHandle(NULL);
_dllModule = hInstance; _dllModule = hInstance;

View File

@ -1297,6 +1297,7 @@ void track_paint(uint8 direction, int height, rct_map_element *mapElement)
} }
} }
else { else {
#ifndef NO_RCT2
TRACK_PAINT_FUNCTION **trackTypeList = (TRACK_PAINT_FUNCTION**)RideTypeTrackPaintFunctionsOld[rideType]; TRACK_PAINT_FUNCTION **trackTypeList = (TRACK_PAINT_FUNCTION**)RideTypeTrackPaintFunctionsOld[rideType];
uint32 *trackDirectionList = (uint32*)trackTypeList[trackType]; uint32 *trackDirectionList = (uint32*)trackTypeList[trackType];
@ -1311,6 +1312,7 @@ void track_paint(uint8 direction, int height, rct_map_element *mapElement)
rideIndex * sizeof(rct_ride), rideIndex * sizeof(rct_ride),
trackSequence trackSequence
); );
#endif
} }
} }