mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #4244 from janisozaur/osx-test-64
64 bit support for OS X, Windows
This commit is contained in:
commit
53ec220bf9
|
@ -63,6 +63,10 @@ add_definitions(-DOPENRCT2_COMMIT_SHA1_SHORT="${OPENRCT2_COMMIT_SHA1_SHORT}")
|
|||
|
||||
INCLUDE(FindPkgConfig)
|
||||
|
||||
if (APPLE)
|
||||
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/opt/openssl/lib/pkgconfig")
|
||||
endif (APPLE)
|
||||
|
||||
# Options
|
||||
|
||||
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(DISABLE_OPENGL "Disable OpenGL support.")
|
||||
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)
|
||||
set(TARGET_M "-m64")
|
||||
set(OBJ_FORMAT "elf64-x86-64")
|
||||
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")
|
||||
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 ()
|
||||
set(TARGET_M "-m32")
|
||||
set(OBJ_FORMAT "elf32-i386")
|
||||
|
@ -94,6 +103,10 @@ else (DISABLE_OPENGL)
|
|||
add_definitions(-DOPENGL_NO_LINK)
|
||||
endif (DISABLE_OPENGL)
|
||||
|
||||
if (USE_MMAP)
|
||||
add_definitions(-DUSE_MMAP)
|
||||
endif (USE_MMAP)
|
||||
|
||||
if (DISABLE_NETWORK)
|
||||
add_definitions(-DDISABLE_NETWORK)
|
||||
else (DISABLE_NETWORK)
|
||||
|
@ -142,35 +155,40 @@ if (UNIX)
|
|||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/openrct2.exe
|
||||
)
|
||||
add_custom_target(segfiles DEPENDS openrct2_text openrct2_data)
|
||||
if (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")
|
||||
else (APPLE)
|
||||
# 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(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-T,\"${CMAKE_CURRENT_SOURCE_DIR}/distribution/linux/${LINKER_SCRIPT}\"")
|
||||
endif (APPLE)
|
||||
if (NOT USE_MMAP)
|
||||
if (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")
|
||||
else (APPLE)
|
||||
# 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(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)
|
||||
set(DEBUG_LEVEL 0 CACHE STRING "Select debug level for compilation. Use value in range 0–3.")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEBUG=${DEBUG_LEVEL}")
|
||||
|
@ -226,6 +244,10 @@ if (NOT DISABLE_OPENGL)
|
|||
if (WIN32)
|
||||
# Curl depends on openssl and ws2 in mingw builds, but is not wired up in pkg-config
|
||||
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)
|
||||
PKG_CHECK_MODULES(GL REQUIRED gl)
|
||||
set(GLLIBS ${GL_LIBRARIES})
|
||||
|
@ -252,7 +274,7 @@ if (UNIX)
|
|||
set(DLLIB dl)
|
||||
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})
|
||||
|
||||
|
@ -264,7 +286,11 @@ endif (NOT DISABLE_RCT2)
|
|||
|
||||
if (WIN32)
|
||||
# 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)
|
||||
add_executable(${PROJECT} ${ORCT2_SOURCES} ${ORCT2_MM_SOURCES} ${RCT2_SECTIONS})
|
||||
add_dependencies(${PROJECT} segfiles)
|
||||
|
|
|
@ -650,7 +650,7 @@
|
|||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<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>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<ObjectFileName>$(IntDir)\%(RelativeDir)</ObjectFileName>
|
||||
|
@ -677,7 +677,7 @@
|
|||
<TreatSpecificWarningsAsErrors>4013</TreatSpecificWarningsAsErrors>
|
||||
<OmitFramePointers />
|
||||
<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>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
|
|
|
@ -23,8 +23,14 @@
|
|||
#pragma warning(disable : 4731)
|
||||
#endif
|
||||
|
||||
#define RCT2_ADDRESS(address, type) ((type*)(address))
|
||||
#define RCT2_GLOBAL(address, type) (*((type*)(address)))
|
||||
#ifdef USE_MMAP
|
||||
#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
|
||||
|
||||
|
|
|
@ -40,16 +40,18 @@
|
|||
#include "version.h"
|
||||
#include "world/mapgen.h"
|
||||
|
||||
#if defined(__unix__)
|
||||
#if defined(__unix__) || defined(__MACOSX__)
|
||||
#include <sys/mman.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#endif // defined(__unix__)
|
||||
#endif // defined(__unix__) || defined(__MACOSX__)
|
||||
|
||||
int gExitCode;
|
||||
int fdData;
|
||||
char *segments = (void *)(GOOD_PLACE_FOR_DATA_SEGMENT);
|
||||
|
||||
int gOpenRCT2StartupAction = STARTUP_ACTION_TITLE;
|
||||
utf8 gOpenRCT2StartupActionPath[512] = { 0 };
|
||||
|
@ -350,6 +352,10 @@ void openrct2_dispose()
|
|||
#ifndef DISABLE_NETWORK
|
||||
EVP_MD_CTX_destroy(gHashCTX);
|
||||
#endif // DISABLE_NETWORK
|
||||
#if defined(USE_MMAP) && (defined(__unix__) || defined(__MACOSX__))
|
||||
munmap(segments, 12079104);
|
||||
close(fdData);
|
||||
#endif
|
||||
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
|
||||
// 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 DATASEG_OFFSET 0x005E2000
|
||||
|
||||
|
@ -532,11 +540,27 @@ bool openrct2_setup_rct2_segment()
|
|||
// TODO: UGLY, UGLY HACK!
|
||||
//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 numPages = (len + pageSize - 1) / pageSize;
|
||||
unsigned char *dummy = malloc(numPages);
|
||||
int err = mincore((void *)0x8a4000, len, dummy);
|
||||
|
||||
err = mincore((void *)0x8a4000, len, dummy);
|
||||
bool pagesMissing = false;
|
||||
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.");
|
||||
}
|
||||
#if !defined(USE_MMAP)
|
||||
// section: text
|
||||
err = mprotect((void *)0x401000, 0x8a4000 - 0x401000, PROT_READ | PROT_EXEC);
|
||||
if (err != 0)
|
||||
{
|
||||
perror("mprotect");
|
||||
}
|
||||
#endif // !defined(USE_MMAP)
|
||||
// section: rw data
|
||||
err = mprotect((void *)0x8a4000, 0x01429000 - 0x8a4000, PROT_READ | PROT_WRITE);
|
||||
if (err != 0)
|
||||
|
@ -583,12 +609,30 @@ bool openrct2_setup_rct2_segment()
|
|||
}
|
||||
#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.
|
||||
// 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((void *)0x009A6000, 0x009E0000 - 0x009A6000);
|
||||
const uint32 c2 = sawyercoding_calculate_checksum((void *)0x01428000, 0x014282BC - 0x01428000);
|
||||
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) {
|
||||
|
@ -596,7 +640,6 @@ bool openrct2_setup_rct2_segment()
|
|||
log_warning("c2 = %u, expected %u, match %d", c2, exp_c2, c2 == exp_c2);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ static HMODULE _dllModule = NULL;
|
|||
/**
|
||||
* 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);
|
||||
_dllModule = hInstance;
|
||||
|
|
|
@ -1297,6 +1297,7 @@ void track_paint(uint8 direction, int height, rct_map_element *mapElement)
|
|||
}
|
||||
}
|
||||
else {
|
||||
#ifndef NO_RCT2
|
||||
TRACK_PAINT_FUNCTION **trackTypeList = (TRACK_PAINT_FUNCTION**)RideTypeTrackPaintFunctionsOld[rideType];
|
||||
uint32 *trackDirectionList = (uint32*)trackTypeList[trackType];
|
||||
|
||||
|
@ -1311,6 +1312,7 @@ void track_paint(uint8 direction, int height, rct_map_element *mapElement)
|
|||
rideIndex * sizeof(rct_ride),
|
||||
trackSequence
|
||||
);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue