1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-18 20:43:04 +01:00

Merge pull request #2150 from janisozaur/develop

Fixes
This commit is contained in:
Ted John
2015-10-29 19:38:06 +00:00
4 changed files with 98 additions and 50 deletions

View File

@@ -59,7 +59,7 @@ if (UNIX)
# force 32bit build for now and set necessary flags to compile code as is
set(CMAKE_C_FLAGS "-m32 -std=gnu99")
set(CMAKE_CXX_FLAGS "-m32 -std=gnu++11")
set(CMAKE_SHARED_LINKER_FLAGS "-m32 -Wl,-melf_i386")
set(CMAKE_SHARED_LINKER_FLAGS "-m32")
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS})
endif (UNIX)

View File

@@ -543,6 +543,8 @@ static void input_scroll_continue(rct_window *w, int widgetIndex, int state, int
int scroll_part, scroll_id;
int x2, y2;
assert(w != NULL);
widget = &w->widgets[widgetIndex];
if (widgetIndex != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, uint32)){
invalidate_scroll();
@@ -662,6 +664,7 @@ static void input_scroll_part_update_hthumb(rct_window *w, int widgetIndex, int
*/
static void input_scroll_part_update_vthumb(rct_window *w, int widgetIndex, int y, int scroll_id)
{
assert(w != NULL);
rct_widget *widget = &w->widgets[widgetIndex];
int newTop;
@@ -699,6 +702,7 @@ static void input_scroll_part_update_vthumb(rct_window *w, int widgetIndex, int
*/
static void input_scroll_part_update_hleft(rct_window *w, int widgetIndex, int scroll_id)
{
assert(w != NULL);
if (window_find_by_number(w->classification, w->number)) {
w->scrolls[scroll_id].flags |= HSCROLLBAR_LEFT_PRESSED;
if (w->scrolls[scroll_id].h_left < 0)
@@ -716,6 +720,7 @@ static void input_scroll_part_update_hleft(rct_window *w, int widgetIndex, int s
*/
static void input_scroll_part_update_hright(rct_window *w, int widgetIndex, int scroll_id)
{
assert(w != NULL);
rct_widget *widget = &w->widgets[widgetIndex];
if (window_find_by_number(w->classification, w->number)) {
w->scrolls[scroll_id].flags |= HSCROLLBAR_RIGHT_PRESSED;
@@ -739,7 +744,8 @@ static void input_scroll_part_update_hright(rct_window *w, int widgetIndex, int
* rct: 0x006E9C37
*/
static void input_scroll_part_update_vtop(rct_window *w, int widgetIndex, int scroll_id)
{;
{
assert(w != NULL);
if (window_find_by_number(w->classification, w->number)) {
w->scrolls[scroll_id].flags |= VSCROLLBAR_UP_PRESSED;
if (w->scrolls[scroll_id].v_top < 0)
@@ -757,6 +763,7 @@ static void input_scroll_part_update_vtop(rct_window *w, int widgetIndex, int sc
*/
static void input_scroll_part_update_vbottom(rct_window *w, int widgetIndex, int scroll_id)
{
assert(w != NULL);
rct_widget *widget = &w->widgets[widgetIndex];
if (window_find_by_number(w->classification, w->number)) {
w->scrolls[scroll_id].flags |= VSCROLLBAR_DOWN_PRESSED;

View File

@@ -58,6 +58,12 @@ bool gOpenRCT2Headless = false;
bool gOpenRCT2ShowChangelog;
#if defined(__linux__)
void *gDataSegment;
void *gTextSegment;
int gExeFd;
#endif // defined(__linux__)
/** If set, will end the OpenRCT2 game loop. Intentially private to this module so that the flag can not be set back to 0. */
int _finished;
@@ -66,6 +72,7 @@ static struct { sint16 x, y, z; } _spritelocations1[MAX_SPRITES], _spritelocatio
static void openrct2_loop();
static bool openrct2_setup_rct2_segment();
static bool openrct2_release_rct2_segment();
static void openrct2_setup_rct2_hooks();
static void openrct2_copy_files_over(const utf8 *originalDirectory, const utf8 *newDirectory, const utf8 *extension)
@@ -308,6 +315,7 @@ void openrct2_dispose()
network_close();
http_dispose();
language_close_all();
openrct2_release_rct2_segment();
platform_free();
}
@@ -465,8 +473,8 @@ static bool openrct2_setup_rct2_segment()
#define DATA_OFFSET 0x004A4000
const char *exepath = "openrct2.exe";
int fd = open(exepath, O_RDONLY);
if (fd < 0) {
gExeFd = open(exepath, O_RDONLY);
if (gExeFd < 0) {
log_fatal("failed to open %s, errno = %d", exepath, errno);
exit(1);
}
@@ -503,23 +511,22 @@ static bool openrct2_setup_rct2_segment()
int len = 0x01429000 - 0x8a4000; // 0xB85000, 12079104 bytes or around 11.5MB
// section: rw data
void *base = mmap((void *)0x8a4000, len, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0);
log_warning("base = %x, 0x01423b40 >= base == %i, 0x01423b40 < base + len == %i", base, (void *)0x01423b40 >= base, (void *)0x01423b40 < base + len);
if (base == MAP_FAILED) {
log_warning("errno = %i", errno);
gDataSegment = mmap((void *)0x8a4000, len, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_SHARED, 0, 0);
if (gDataSegment != (void *)0x8a4000) {
log_fatal("mmap failed to get required offset for data segment! got %p, expected %p, errno = %d", gDataSegment, (void *)(0x8a4000), errno);
exit(1);
}
len = 0x004A3000;
// section: text
void *base2 = mmap((void *)(0x401000), len, PROT_EXEC | PROT_WRITE | PROT_READ, MAP_PRIVATE, fd, 0x1000);
if (base2 != (void *)(0x401000))
gTextSegment = mmap((void *)(0x401000), len, PROT_EXEC | PROT_WRITE | PROT_READ, MAP_FIXED | MAP_PRIVATE, gExeFd, 0x1000);
if (gTextSegment != (void *)(0x401000))
{
log_fatal("mmap failed to get required offset! got %p, expected %p, errno = %d", base2, (void *)(0x401000), errno);
log_fatal("mmap failed to get required offset for text segment! got %p, expected %p, errno = %d", gTextSegment, (void *)(0x401000), errno);
exit(1);
}
void *fbase = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
void *fbase = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, gExeFd, 0);
int err = errno;
log_warning("mmapped file to %p", fbase);
if (fbase == MAP_FAILED)
@@ -529,7 +536,13 @@ static bool openrct2_setup_rct2_segment()
}
// .rdata and real part of .data
// 0x9e2000 - 0x8a4000 = 0x13e000
memcpy(base, fbase + DATA_OFFSET, 0x13e000);
memcpy(gDataSegment, fbase + DATA_OFFSET, 0x13e000);
err = munmap(fbase, file_size);
if (err != 0)
{
err = errno;
log_error("Failed to unmap file! errno = %d", err);
}
#endif // __linux__
// Check that the expected data is at various addresses.
@@ -546,6 +559,41 @@ static bool openrct2_setup_rct2_segment()
return true;
}
/**
* Releases segments created with @ref openrct2_setup_rct2_segment, if any.
*/
static bool openrct2_release_rct2_segment()
{
bool result = true;
#if defined(__linux__)
int len = 0x01429000 - 0x8a4000; // 0xB85000, 12079104 bytes or around 11.5MB
int err;
err = munmap(gDataSegment, len);
if (err != 0)
{
err = errno;
log_error("Failed to unmap data segment! errno = %d", err);
result = false;
}
len = 0x004A3000;
err = munmap(gTextSegment, len);
if (err != 0)
{
err = errno;
log_error("Failed to unmap text segment! errno = %d", err);
result = false;
}
err = close(gExeFd);
if (err != 0)
{
err = errno;
log_error("Failed to close file! errno = %d", err);
result = false;
}
#endif // defined(__linux__)
return result;
}
/**
* Setup hooks to allow RCT2 to call OpenRCT2 functions instead.
*/

View File

@@ -96,7 +96,7 @@ bool platform_file_exists(const utf8 *path)
wcstombs(buffer, wPath, len);
buffer[len] = '\0';
free(wPath);
int exists = access(buffer, F_OK) != -1;
bool exists = access(buffer, F_OK) != -1;
log_warning("file '%s' exists = %i", buffer, exists);
return exists;
}
@@ -114,9 +114,9 @@ bool platform_directory_exists(const utf8 *path)
log_verbose("checking dir %s, result = %d, is_dir = %d", buffer, result, S_ISDIR(dirinfo.st_mode));
if ((result != 0) || !S_ISDIR(dirinfo.st_mode))
{
return 0;
return false;
}
return 1;
return true;
}
bool platform_original_game_data_exists(const utf8 *path)
@@ -159,13 +159,13 @@ bool platform_ensure_directory_exists(const utf8 *path)
bool platform_directory_delete(const utf8 *path)
{
STUB();
return 1;
return true;
}
bool platform_lock_single_instance()
{
STUB();
return 1;
return true;
}
typedef struct {
@@ -203,7 +203,6 @@ static int winfilter(const struct dirent *d)
int platform_enumerate_files_begin(const utf8 *pattern)
{
int i;
enumerate_file_info *enumFileInfo;
wchar_t *wpattern = utf8_to_widechar(pattern);
int length = min(utf8_length(pattern), MAX_PATH);
@@ -266,7 +265,7 @@ int platform_enumerate_files_begin(const utf8 *pattern)
}
log_warning("looking for file matching %s", g_file_pattern);
int cnt;
for (i = 0; i < countof(_enumerateFileInfoList); i++) {
for (int i = 0; i < countof(_enumerateFileInfoList); i++) {
enumFileInfo = &_enumerateFileInfoList[i];
if (!enumFileInfo->active) {
strncpy(enumFileInfo->pattern, npattern, length);
@@ -317,16 +316,15 @@ int platform_enumerate_files_begin(const utf8 *pattern)
bool platform_enumerate_files_next(int handle, file_info *outFileInfo)
{
bool result = true;
enumerate_file_info *enumFileInfo;
if (handle < 0)
{
result = false;
return false;
}
enumFileInfo = &_enumerateFileInfoList[handle];
enumerate_file_info *enumFileInfo = &_enumerateFileInfoList[handle];
bool result;
if (result && (enumFileInfo->handle < enumFileInfo->cnt)) {
if (enumFileInfo->handle < enumFileInfo->cnt) {
result = true;
} else {
result = false;
@@ -341,29 +339,26 @@ bool platform_enumerate_files_next(int handle, file_info *outFileInfo)
statRes = stat(fileName, &fileInfo);
if (statRes == -1) {
log_error("failed to stat file '%s'! errno = %i", fileName, errno);
return 0;
return false;
}
outFileInfo->path = basename(fileName);
outFileInfo->size = fileInfo.st_size;
outFileInfo->last_modified = fileInfo.st_mtime;
return 1;
return true;
} else {
return 0;
return false;
}
}
void platform_enumerate_files_end(int handle)
{
int i;
enumerate_file_info *enumFileInfo;
if (handle < 0)
{
return;
}
enumFileInfo = &_enumerateFileInfoList[handle];
enumerate_file_info *enumFileInfo = &_enumerateFileInfoList[handle];
int cnt = enumFileInfo->cnt;
for (i = 0; i < cnt; i++) {
for (int i = 0; i < cnt; i++) {
free(enumFileInfo->fileListTemp[i]);
free(enumFileInfo->paths[i]);
}
@@ -380,7 +375,7 @@ static int dirfilter(const struct dirent *d)
if (d->d_name[0] == '.') {
return 0;
}
#ifdef _DIRENT_HAVE_D_TYPE
#if defined(_DIRENT_HAVE_D_TYPE) || defined(DT_UNKNOWN)
if (d->d_type == DT_DIR)
{
return 1;
@@ -389,12 +384,11 @@ static int dirfilter(const struct dirent *d)
}
#else
#error implement dirfilter!
#endif // _DIRENT_HAVE_D_TYPE
#endif // defined(_DIRENT_HAVE_D_TYPE) || defined(DT_UNKNOWN)
}
int platform_enumerate_directories_begin(const utf8 *directory)
{
int i;
enumerate_file_info *enumFileInfo;
wchar_t *wpattern = utf8_to_widechar(directory);
int length = min(utf8_length(directory), MAX_PATH);
@@ -410,7 +404,7 @@ int platform_enumerate_directories_begin(const utf8 *directory)
// TODO: add some checking for stringness and directoryness
int cnt;
for (i = 0; i < countof(_enumerateFileInfoList); i++) {
for (int i = 0; i < countof(_enumerateFileInfoList); i++) {
enumFileInfo = &_enumerateFileInfoList[i];
if (!enumFileInfo->active) {
strncpy(enumFileInfo->pattern, npattern, length);
@@ -455,13 +449,16 @@ int platform_enumerate_directories_begin(const utf8 *directory)
bool platform_enumerate_directories_next(int handle, utf8 *path)
{
bool result;
enumerate_file_info *enumFileInfo;
if (handle < 0)
{
return false;
}
enumFileInfo = &_enumerateFileInfoList[handle];
bool result;
enumerate_file_info *enumFileInfo = &_enumerateFileInfoList[handle];
log_verbose("handle = %d", handle);
if ((handle >= 0) && (enumFileInfo->handle < enumFileInfo->cnt)) {
if (enumFileInfo->handle < enumFileInfo->cnt) {
result = true;
} else {
result = false;
@@ -470,36 +467,32 @@ bool platform_enumerate_directories_next(int handle, utf8 *path)
if (result) {
int entryIdx = enumFileInfo->handle++;
struct stat fileInfo;
log_verbose("trying handle %d", entryIdx);
char *fileName = enumFileInfo->paths[entryIdx];
int statRes;
statRes = stat(fileName, &fileInfo);
if (statRes == -1) {
log_error("failed to stat file '%s'! errno = %i", fileName, errno);
return 0;
return false;
}
// so very, very wrong…
strncpy(path, basename(fileName), MAX_PATH);
strncat(path, "/", MAX_PATH);
path[MAX_PATH - 1] = '\0';
return 1;
return true;
} else {
return 0;
return false;
}
}
void platform_enumerate_directories_end(int handle)
{
int i;
enumerate_file_info *enumFileInfo;
if (handle < 0)
{
return;
}
enumFileInfo = &_enumerateFileInfoList[handle];
enumerate_file_info *enumFileInfo = &_enumerateFileInfoList[handle];
int cnt = enumFileInfo->cnt;
for (i = 0; i < cnt; i++) {
for (int i = 0; i < cnt; i++) {
free(enumFileInfo->fileListTemp[i]);
free(enumFileInfo->paths[i]);
}