diff --git a/CMakeLists.txt b/CMakeLists.txt
index 14b4af5259..c392ed1def 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -36,8 +36,8 @@ if (DISABLE_NETWORK)
add_definitions(-DDISABLE_NETWORK)
endif (DISABLE_NETWORK)
-set(ORCTLIBS_INCLUDE /usr/local/cross-tools/orctlibs/include)
-set(JANSSON_INCLUDE /usr/local/cross-tools/orctlibs/include/jansson)
+set(ORCTLIBS_INCLUDE /usr/local/cross-tools/orctlibs/include)
+set(JANSSON_INCLUDE /usr/local/cross-tools/orctlibs/include/jansson)
set(ORCTLIBS_LIB_DIR /usr/local/cross-tools/orctlibs/lib)
set(ORCTLIBS_LIB jansson curl ssl crypto)
@@ -50,8 +50,8 @@ file(GLOB_RECURSE ORCT2_SOURCES "src/*.c" "src/*.cpp" "lib/*.c")
if (UNIX)
# force 32bit build for now and set necessary flags to compile code as is
- set(CMAKE_C_FLAGS "-m32 -masm=intel -std=gnu99")
- set(CMAKE_CXX_FLAGS "-m32 -std=gnu++11 -masm=intel")
+ set(CMAKE_C_FLAGS "-m32 -masm=intel -fvar-tracking-assignments -std=gnu99")
+ set(CMAKE_CXX_FLAGS "-m32 -std=gnu++11 -fvar-tracking-assignments -masm=intel")
set(LIB32 /usr/lib32)
set(CMAKE_SHARED_LINKER_FLAGS "-m32 -Wl,-melf_i386 -L${LIB32} -lSDL2_ttf")
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS})
@@ -63,10 +63,14 @@ if (UNIX)
endif (UNIX)
INCLUDE_DIRECTORIES(${ORCTLIBS_INCLUDE} ${JANSSON_INCLUDE})
-LINK_DIRECTORIES(${SDL2_LIBRARY_DIRS} ${ORCTLIBS_LIB_DIR})
+LINK_DIRECTORIES(${LINK_DIRECTORIES} ${LIB32} ${SDL2_LIBRARY_DIRS} ${ORCTLIBS_LIB_DIR})
-# build as library for now, replace with add_executable
-add_library(${PROJECT} SHARED ${ORCT2_SOURCES})
+if (WIN32)
+ # build as library for now, replace with add_executable
+ add_library(${PROJECT} SHARED ${ORCT2_SOURCES})
+else (WIN32)
+ add_executable(${PROJECT} ${ORCT2_SOURCES})
+endif (WIN32)
# install into ${CMAKE_INSTALL_PREFIX}/bin/
#install (TARGETS ${PROJECT} DESTINATION bin)
@@ -79,4 +83,3 @@ TARGET_LINK_LIBRARIES(${PROJECT} ${SDL2_LIBRARIES} ${ORCTLIBS_LIB})
if (WIN32)
target_link_libraries(${PROJECT} winmm.lib -limm32 -lversion -ldsound ws2_32)
endif (WIN32)
-
diff --git a/install.sh b/install.sh
index 06fdc181b3..1400804253 100755
--- a/install.sh
+++ b/install.sh
@@ -87,7 +87,7 @@ elif [[ `uname` == "Linux" ]]; then
apt-cache search libsdl2
apt-cache policy libsdl2-dev:i386
apt-cache policy libsdl2-dev
- sudo apt-get install -y --force-yes binutils-mingw-w64-i686 gcc-mingw-w64-i686 g++-mingw-w64-i686 cmake libsdl2-dev:i386 libsdl2-ttf-dev:i386 gcc-4.8 pkg-config:i386 g++-4.8-multilib gcc-4.8-multilib libjansson-dev:i386 libspeex-dev:i386 libspeexdsp-dev:i386
+ sudo apt-get install -y --force-yes binutils-mingw-w64-i686 gcc-mingw-w64-i686 g++-mingw-w64-i686 cmake libsdl2-dev:i386 libsdl2-ttf-dev:i386 gcc-4.8 pkg-config:i386 g++-4.8-multilib gcc-4.8-multilib libjansson-dev:i386 libspeex-dev:i386 libspeexdsp-dev:i386 libcurl4-openssl-dev:i386 libcrypto++-dev:i386
export CC=gcc-4.8
export CXX=g++-4.8
fi
diff --git a/src/audio/audio.c b/src/audio/audio.c
index 07c940768b..a919d9b241 100644
--- a/src/audio/audio.c
+++ b/src/audio/audio.c
@@ -8,12 +8,12 @@
* 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.
-
+
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*****************************************************************************/
@@ -556,7 +556,8 @@ int sound_channel_load_file2(int channel, const char* filename, int offset)
if (sound_channel_is_playing(channel)) {
sound_channel_stop(channel);
}
- if (SUCCEEDED(sound_channel_load_file(channel, filename, offset))) {
+ int load_result = sound_channel_load_file(channel, filename, offset);
+ if (load_result >= 0) {
RCT2_ADDRESS(RCT2_ADDRESS_SOUND_CHANNEL_LIST, rct_sound_channel)[channel].var_4 = 0;
return 1;
}
@@ -961,7 +962,7 @@ int sound_play(rct_sound* sound, int looping, int volume, int pan, int frequency
} else {
playflags = 0;
}
- if (SUCCEEDED(sound->dsbuffer->lpVtbl->Play(sound->dsbuffer, 0, 0, playflags)))
+ if (SUCCEEDED(sound->dsbuffer->lpVtbl->Play(sound->dsbuffer, 0, 0, playflags)))
return 1;
}
@@ -1497,7 +1498,7 @@ int dsound_create_primary_buffer(int a, int device, int channels, int samples, i
if (FAILED(DirectSoundCreate(&dsdevice->guid, &RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND), 0))) {
return 0;
}
- if (FAILED(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->SetCooperativeLevel(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND), windows_get_window_handle(), DSSCL_NORMAL)) ||
+ if (FAILED(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->SetCooperativeLevel(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND), windows_get_window_handle(), DSSCL_NORMAL)) ||
FAILED(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->CreateSoundBuffer(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND), &bufferdesc, &RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER), 0))) {
RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->Release(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND));
RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND) = 0;
diff --git a/src/diagnostic.c b/src/diagnostic.c
index d2d06d5f7d..4d756348a8 100644
--- a/src/diagnostic.c
+++ b/src/diagnostic.c
@@ -79,4 +79,4 @@ void diagnostic_log_with_location(int diagnosticLevel, const char *file, const c
// Line terminator
fprintf(stream, "\n");
-}
\ No newline at end of file
+}
diff --git a/src/diagnostic.h b/src/diagnostic.h
index 21029db312..556ff98324 100644
--- a/src/diagnostic.h
+++ b/src/diagnostic.h
@@ -57,4 +57,4 @@ void diagnostic_log_with_location(int diagnosticLevel, const char *file, const c
#endif
-#endif
\ No newline at end of file
+#endif
diff --git a/src/drawing/string.c b/src/drawing/string.c
index fcca4343e2..3a11a1cdef 100644
--- a/src/drawing/string.c
+++ b/src/drawing/string.c
@@ -8,12 +8,12 @@
* 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.
-
+
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*****************************************************************************/
@@ -22,6 +22,7 @@
#include "../localisation/localisation.h"
#include "../sprites.h"
#include "../world/map.h"
+#include "../platform/platform.h"
#include "drawing.h"
static int ttf_get_string_width(const utf8 *text);
@@ -353,7 +354,7 @@ void gfx_draw_string_centred(rct_drawpixelinfo *dpi, int format, int x, int y, i
}
/**
- *
+ *
* rct2: 0x006C1E53
* dpi (edi)
* args (esi)
@@ -407,7 +408,7 @@ int gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, int x, i
}
/**
- *
+ *
* rct2: 0x006C2105
* dpi (edi)
* args (esi)
@@ -441,7 +442,7 @@ int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, int x, int
gfx_draw_string(dpi, buffer, 0xFE, x, lineY);
buffer = get_string_end(buffer) + 1;
lineY += lineHeight;
- }
+ }
return lineY - y;
}
@@ -492,7 +493,7 @@ void colour_char(uint8 colour, uint16* current_font_flags, uint8* palette_pointe
if (!(*current_font_flags & 2)) {
eax = eax & 0x0FF0000FF;
}
- // Adjust text palette. Store current colour?
+ // Adjust text palette. Store current colour?
palette_pointer[1] = eax & 0xFF;
palette_pointer[2] = (eax >> 8) & 0xFF;
palette_pointer[3] = (eax >> 16) & 0xFF;
@@ -512,7 +513,7 @@ void colour_char_window(uint8 colour, uint16* current_font_flags,uint8* palette_
if (*current_font_flags & 2) {
eax |= 0x0A0A00;
}
- //Adjust text palette. Store current colour?
+ //Adjust text palette. Store current colour?
palette_pointer[1] = eax & 0xFF;
palette_pointer[2] = (eax >> 8) & 0xFF;
palette_pointer[3] = (eax >> 16) & 0xFF;
@@ -521,7 +522,7 @@ void colour_char_window(uint8 colour, uint16* current_font_flags,uint8* palette_
}
/**
- *
+ *
* rct2: 0x00682702
* dpi (edi)
* buffer (esi)
@@ -712,7 +713,7 @@ void gfx_draw_string_centred_wrapped_partial(rct_drawpixelinfo *dpi, int x, int
lineY = y - ((numLines * lineHeight) / 2);
for (int line = 0; line <= numLines; line++) {
int halfWidth = gfx_get_string_width(buffer) / 2;
-
+
utf8 *ch = buffer;
utf8 *nextCh;
int codepoint;
@@ -735,7 +736,7 @@ void gfx_draw_string_centred_wrapped_partial(rct_drawpixelinfo *dpi, int x, int
buffer = get_string_end(buffer) + 1;
lineY += lineHeight;
- }
+ }
}
static uint32 _ttf_surface_cache_hash(TTF_Font *font, const utf8 *text)
@@ -884,7 +885,7 @@ bool ttf_initialise()
for (int i = 0; i < 4; i++) {
TTFFontDescriptor *fontDesc = &(gCurrentTTFFontSet->size[i]);
-
+
utf8 fontPath[MAX_PATH] = "C:\\Windows\\Fonts\\";
strcat(fontPath, fontDesc->filename);
@@ -1000,7 +1001,7 @@ static void ttf_draw_string_raw_ttf(rct_drawpixelinfo *dpi, const utf8 *text, te
return;
}
}
-
+
int fontSize = font_get_size_from_sprite_base(info->font_sprite_base);
int drawX = info->x + fontDesc->offset_x;
int drawY = info->y + fontDesc->offset_y;
diff --git a/src/localisation/localisation.c b/src/localisation/localisation.c
index bf532f5639..e39c58a3d9 100644
--- a/src/localisation/localisation.c
+++ b/src/localisation/localisation.c
@@ -856,7 +856,12 @@ int win1252_to_utf8(utf8string dst, const char *src, int maxBufferLength)
int result = WideCharToMultiByte(CP_UTF8, 0, intermediateBuffer, -1, dst, maxBufferLength, NULL, NULL);
#else
STUB();
- int result = 0;
+ // we cannot walk past maxBufferLength, but in case we have still space left
+ // we need one byte for null terminator
+ int result = strnlen(src, maxBufferLength) + 1;
+ result = min(result, maxBufferLength);
+ strncpy(dst, src, maxBufferLength);
+ dst[maxBufferLength - 1] = '\0';
#endif // _WIN32
if (heapBuffer != NULL) {
diff --git a/src/object.c b/src/object.c
index 4295cbb146..3bf78c483d 100644
--- a/src/object.c
+++ b/src/object.c
@@ -56,7 +56,7 @@ int object_load_file(int groupIndex, const rct_object_entry *entry, int* chunkSi
{
uint8 objectType;
rct_object_entry openedEntry;
- char path[260];
+ char path[MAX_PATH];
SDL_RWops* rw;
subsitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), (char*)installedObject + 16);
@@ -259,7 +259,7 @@ int object_load_packed(SDL_RWops* rw)
}
if (entryGroupIndex == object_entry_group_counts[type]){
- // This should never occur. Objects are not loaded before installing a
+ // This should never occur. Objects are not loaded before installing a
// packed object. So there is only one object loaded at this point.
log_error("Too many objects of the same type loaded.");
rct2_free(chunk);
@@ -285,7 +285,7 @@ int object_load_packed(SDL_RWops* rw)
}
// Convert the entry name to a upper case path name
- char path[260];
+ char path[MAX_PATH];
char objectPath[9] = { 0 };
for (int i = 0; i < 8; ++i){
if (entry.name[i] != ' ')
@@ -400,7 +400,7 @@ int object_calculate_checksum(const rct_object_entry *entry, const char *data, i
int object_chunk_load_image_directory(uint8_t** chunk)
{
int image_start_no = RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32_t);
-
+
// First dword of chunk is no_images
int no_images = *((uint32_t*)(*chunk));
*chunk += 4;
@@ -754,7 +754,7 @@ int paint_ride_entry(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo* dp
return flags;
}
else
- {
+ {
rct_window* w = (rct_window*)esi;
int width = w->x + w->width - x - 4;
@@ -1415,7 +1415,7 @@ int paint_water_entry(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo* d
return 0;
}
else if ((flags & 0xFF) == 3){
- if (!((flags >> 8) & 0xFF))
+ if (!((flags >> 8) & 0xFF))
gfx_draw_string_centred(dpi, 3326, ecx, edx, 0, (void*)esi);
}
return flags;
@@ -1467,7 +1467,7 @@ int object_paint(int type, int eax, int ebx, int ecx, int edx, int esi, int edi,
switch (type)
{
case OBJECT_TYPE_RIDE:
- return paint_ride_entry(eax, ebx, ecx, edx, (rct_drawpixelinfo*)edi, esi, ebp);
+ return paint_ride_entry(eax, ebx, ecx, edx, (rct_drawpixelinfo*)edi, esi, ebp);
case OBJECT_TYPE_SMALL_SCENERY:
return paint_small_scenery(eax, ebx, ecx, edx, (rct_drawpixelinfo*)edi, esi, ebp);
case OBJECT_TYPE_LARGE_SCENERY:
@@ -1477,7 +1477,7 @@ int object_paint(int type, int eax, int ebx, int ecx, int edx, int esi, int edi,
case OBJECT_TYPE_BANNERS:
return paint_banner(eax, ebx, ecx, edx, (rct_drawpixelinfo*)edi, esi, ebp);
case OBJECT_TYPE_PATHS:
- return paint_path_entry(eax, ebx, ecx, edx, (rct_drawpixelinfo*)edi, esi, ebp);
+ return paint_path_entry(eax, ebx, ecx, edx, (rct_drawpixelinfo*)edi, esi, ebp);
case OBJECT_TYPE_PATH_BITS:
return paint_path_bit(eax, ebx, ecx, edx, (rct_drawpixelinfo*)edi, esi, ebp);
case OBJECT_TYPE_SCENERY_SETS:
@@ -1503,14 +1503,14 @@ int object_get_scenario_text(rct_object_entry *entry)
rct_object_entry *installedObject = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*);
installedObject = object_list_find(entry);
-
+
if (installedObject == NULL){
log_error("Object not found: %.8s", entry->name);
RCT2_GLOBAL(0x00F42BD9, uint8) = 0;
return 0;
}
- char path[260];
+ char path[MAX_PATH];
char *objectPath = (char*)installedObject + 16;
subsitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), objectPath);
@@ -1571,7 +1571,7 @@ int object_get_scenario_text(rct_object_entry *entry)
memcpy(gTempObjectLoadName, openedEntry.name, 8);
// Not used??
RCT2_GLOBAL(0x009ADAFD, uint8) = 1;
- object_paint(openedEntry.flags & 0x0F, 0, 0, 0, 0, (int)chunk, 0, 0);
+ object_paint(openedEntry.flags & 0x0F, 0, 0, 0, 0, (int)chunk, 0, 0);
// Tell text to be loaded into normal address
RCT2_GLOBAL(0x009ADAFC, uint8) = 0;
// Not used??
@@ -1630,7 +1630,7 @@ rct_object_entry *object_get_next(rct_object_entry *entry)
// Skip theme objects
pos += *pos * 16 + 1;
- // Skip
+ // Skip
pos += 4;
return (rct_object_entry*)pos;
diff --git a/src/object.h b/src/object.h
index 18c11087d9..50ebf7cc86 100644
--- a/src/object.h
+++ b/src/object.h
@@ -8,12 +8,12 @@
* 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.
-
+
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*****************************************************************************/
@@ -75,7 +75,7 @@ extern int object_entry_group_counts[];
extern int object_entry_group_encoding[];
typedef struct {
- uint8 **chunks;
+ uint8 **chunks;
rct_object_entry_extended *entries;
} rct_object_entry_group;
@@ -122,4 +122,4 @@ char *object_get_name(rct_object_entry *entry);
rct_object_filters *get_object_filter(int index);
-#endif
\ No newline at end of file
+#endif
diff --git a/src/object_list.c b/src/object_list.c
index 7fd147949c..cccd9b3592 100644
--- a/src/object_list.c
+++ b/src/object_list.c
@@ -8,12 +8,12 @@
* 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.
-
+
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*****************************************************************************/
@@ -115,7 +115,7 @@ static void object_list_sort()
objectBuffer = &RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*);
numObjects = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, sint32);
copied = calloc(numObjects, sizeof(uint8));
-
+
// Get buffer size
entry = *objectBuffer;
for (i = 0; i < numObjects; i++)
@@ -166,7 +166,7 @@ static void object_list_sort()
}
/**
- *
+ *
* rct2: 0x006A93CD
*/
static void object_list_examine()
@@ -237,7 +237,7 @@ static int object_list_query_directory(int *outTotalFiles, uint64 *outTotalFileS
}
/**
- *
+ *
* rct2: 0x006A8B40
*/
void object_list_load()
@@ -291,17 +291,17 @@ void object_list_load()
free(_installedObjectFilters);
_installedObjectFilters = NULL;
}
-
+
enumFileHandle = platform_enumerate_files_begin(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char));
if (enumFileHandle != INVALID_HANDLE) {
uint32 installed_buffer_size = 0x1000;
-
+
while (platform_enumerate_files_next(enumFileHandle, &enumFileInfo)) {
fileCount++;
if ((installed_buffer_size - current_item_offset) <= 2842){
installed_buffer_size += 0x1000;
- RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*) = rct2_realloc(RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*), installed_buffer_size);
+ RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*) = rct2_realloc(RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*), installed_buffer_size);
if (RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, int) == -1){
log_error("Failed to allocate memory for object list");
rct2_exit_reason(835, 3162);
@@ -355,6 +355,11 @@ static int object_list_cache_load(int totalFiles, uint64 totalFileSize, int file
rct_plugin_header pluginHeader;
uint32 filterVersion = 0;
+#ifndef _WIN32
+ // TODO: remove me!
+ log_error("this is to be removed after testing/implementation is done");
+ return 0;
+#endif
log_verbose("loading object list cache (plugin.dat)");
get_plugin_path(path);
@@ -391,7 +396,7 @@ static int object_list_cache_load(int totalFiles, uint64 totalFileSize, int file
free(_installedObjectFilters);
_installedObjectFilters = malloc(sizeof(rct_object_filters) * pluginHeader.object_list_no_items);
if (SDL_RWread(file, _installedObjectFilters, sizeof(rct_object_filters) * pluginHeader.object_list_no_items, 1) == 1) {
-
+
SDL_RWclose(file);
reset_loaded_objects();
object_list_examine();
@@ -431,7 +436,7 @@ static int object_list_cache_save(int fileCount, uint64 totalFileSize, int fileD
SDL_RWops *file;
rct_plugin_header pluginHeader;
uint32 filterVersion = FILTER_VERSION;
-
+
log_verbose("saving object list cache (plugin.dat)");
pluginHeader.total_files = fileCount | 0x01000000;
@@ -519,7 +524,7 @@ void set_load_objects_fail_reason(){
}
/**
- *
+ *
* rct2: 0x006AA0C6
*/
int object_read_and_load_entries(SDL_RWops* rw)
@@ -557,7 +562,7 @@ int object_read_and_load_entries(SDL_RWops* rw)
}
}
- free(entries);
+ free(entries);
if (load_fail){
object_unload_all();
RCT2_GLOBAL(0x14241BC, uint32) = 0;
@@ -571,7 +576,7 @@ int object_read_and_load_entries(SDL_RWops* rw)
/**
- *
+ *
* rct2: 0x006A9CE8
*/
void object_unload_all()
@@ -631,7 +636,7 @@ void object_list_create_hash_table()
// Set hash table slot
_installedObjectHashTable[index] = installedObject;
-
+
// Next installed object
installedObject = object_get_next(installedObject);
}
@@ -645,8 +650,8 @@ int find_object_in_entry_group(rct_object_entry* entry, uint8* entry_type, uint8
*entry_type = entry->flags & 0xF;
rct_object_entry_group entry_group = object_entry_groups[*entry_type];
- for (*entry_index = 0;
- *entry_index < object_entry_group_counts[*entry_type];
+ for (*entry_index = 0;
+ *entry_index < object_entry_group_counts[*entry_type];
++(*entry_index),
entry_group.chunks++,
entry_group.entries++){
diff --git a/src/openrct2.c b/src/openrct2.c
index d2df37bac4..c6d7a80570 100644
--- a/src/openrct2.c
+++ b/src/openrct2.c
@@ -135,8 +135,19 @@ static void openrct2_set_exe_path()
if (bytesRead == -1) {
log_fatal("failed to read /proc/self/exe");
}
- exePath[MAX_PATH - 1] = '\0';
- strncpy(gExePath, exePath, MAX_PATH);
+ exePath[bytesRead] = '\0';
+ log_verbose("######################################## Setting exe path to %s", exePath);
+ char *exeDelimiter = strrchr(exePath, platform_get_path_separator());
+ if (exeDelimiter == NULL)
+ {
+ log_error("should never happen here");
+ gExePath[0] = '\0';
+ return;
+ }
+ int exeDelimiterIndex = (int)(exeDelimiter - exePath);
+
+ strncpy(gExePath, exePath, exeDelimiterIndex + 1);
+ gExePath[exeDelimiterIndex] = '\0';
#endif // _WIN32
}
diff --git a/src/platform/linux.c b/src/platform/linux.c
new file mode 100644
index 0000000000..24d68ca60e
--- /dev/null
+++ b/src/platform/linux.c
@@ -0,0 +1,759 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Ted John
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of 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.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
+#ifdef __linux
+
+#include
+#include
+#include
+#include
+#include
+#include "../addresses.h"
+#include "../cmdline.h"
+#include "../openrct2.h"
+#include "../localisation/language.h"
+#include "../localisation/currency.h"
+#include "../config.h"
+#include "platform.h"
+#include
+
+// The name of the mutex used to prevent multiple instances of the game from running
+#define SINGLE_INSTANCE_MUTEX_NAME "RollerCoaster Tycoon 2_GSKMUTEX"
+
+/**
+ * The function that is called directly from the host application (rct2.exe)'s WinMain. This will be removed when OpenRCT2 can
+ * be built as a stand alone application.
+ */
+int main(int argc, const char **argv)
+{
+ //RCT2_GLOBAL(RCT2_ADDRESS_HINSTANCE, HINSTANCE) = hInstance;
+ //RCT2_GLOBAL(RCT2_ADDRESS_CMDLINE, LPSTR) = lpCmdLine;
+
+ STUB();
+ int run_game = cmdline_run(argv, argc);
+ if (run_game == 1)
+ {
+ openrct2_launch();
+ }
+
+ exit(gExitCode);
+ return gExitCode;
+}
+
+char platform_get_path_separator()
+{
+ return '/';
+}
+
+bool platform_file_exists(const utf8 *path)
+{
+ wchar_t *wPath = utf8_to_widechar(path);
+ int len = min(MAX_PATH, utf8_length(path));
+ char buffer[MAX_PATH];
+ wcstombs(buffer, wPath, len);
+ buffer[len] = '\0';
+ free(wPath);
+ int exists = access(buffer, F_OK) != -1;
+ log_warning("file '%s' exists = %i", buffer, exists);
+ return exists;
+}
+
+bool platform_directory_exists(const utf8 *path)
+{
+ wchar_t *wPath = utf8_to_widechar(path);
+ int len = min(MAX_PATH, utf8_length(path));
+ char buffer[MAX_PATH];
+ wcstombs(buffer, wPath, len);
+ buffer[len] = '\0';
+ free(wPath);
+ struct stat dirinfo;
+ int result = stat(buffer, &dirinfo);
+ 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 1;
+}
+
+bool platform_original_game_data_exists(const utf8 *path)
+{
+ wchar_t *wPath = utf8_to_widechar(path);
+ int len = min(MAX_PATH, utf8_length(path));
+ char buffer[MAX_PATH];
+ wcstombs(buffer, wPath, len);
+ buffer[len] = '\0';
+ free(wPath);
+ char checkPath[MAX_PATH];
+ sprintf(checkPath, "%s%c%s%c%s", buffer, platform_get_path_separator(), "data", platform_get_path_separator(), "g1.dat");
+ return platform_file_exists(checkPath);
+}
+
+mode_t getumask()
+{
+ mode_t mask = umask(0);
+ umask(mask);
+ return 0777 & ~mask; // Keep in mind 0777 is octal
+}
+
+bool platform_ensure_directory_exists(const utf8 *path)
+{
+ mode_t mask = getumask();
+
+ wchar_t *wPath = utf8_to_widechar(path);
+ int len = min(MAX_PATH, utf8_length(path));
+ char buffer[MAX_PATH];
+ wcstombs(buffer, wPath, len);
+ buffer[len - 1] = '\0';
+ free(wPath);
+ log_verbose("%s", buffer);
+ const int result = mkdir(buffer, mask);
+ if (result == 0 || (result == -1 && errno == EEXIST))
+ return true;
+ return false;
+}
+
+bool platform_directory_delete(const utf8 *path)
+{
+ STUB();
+ return 1;
+}
+
+bool platform_lock_single_instance()
+{
+ STUB();
+ return 1;
+}
+
+typedef struct {
+ char active;
+ char pattern[MAX_PATH];
+ struct dirent **fileListTemp;
+ char **paths;
+ int cnt;
+ int handle;
+ void* data;
+} enumerate_file_info;
+static enumerate_file_info _enumerateFileInfoList[8] = { 0 };
+
+char *g_file_pattern;
+
+static int winfilter(const struct dirent *d)
+{
+ int entry_length = strnlen(d->d_name, MAX_PATH);
+ char *name_upper = malloc(entry_length + 1);
+ if (name_upper == NULL)
+ {
+ log_error("out of memory");
+ return 0;
+ }
+ for (int i = 0; i < entry_length; i++)
+ {
+ name_upper[i] = (char)toupper(d->d_name[i]);
+ }
+ name_upper[entry_length] = '\0';
+ bool match = strstr(name_upper, g_file_pattern) != NULL;
+ //log_warning("trying matching filename %s, result = %d", name_upper, match);
+ free(name_upper);
+ return match;
+}
+
+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);
+ char *npattern = malloc(length);
+ int converted;
+ converted = wcstombs(npattern, wpattern, length);
+ npattern[length - 1] = '\0';
+ if (converted == MAX_PATH) {
+ log_warning("truncated string %s", npattern);
+ }
+ log_warning("begin file search, pattern: %s", npattern);
+
+ char *file_name = strrchr(npattern, platform_get_path_separator());
+ char *dir_name;
+ if (file_name != NULL)
+ {
+ dir_name = strndup(npattern, file_name - npattern);
+ file_name = &file_name[1];
+ } else {
+ file_name = npattern;
+ dir_name = strdup(".");
+ }
+
+ char *smatch = strchr(file_name, '*');
+ if ((smatch != file_name) && (smatch != NULL))
+ {
+ log_error("Sorry, can only match '*' at start of filename.");
+ return -1;
+ } else {
+ // '*' found
+ if (smatch != NULL)
+ {
+ // some boundary checking needed
+ // skip the '*'
+ smatch = &smatch[1];
+ char *match2 = strchr(&smatch[1], '*');
+ if (match2 != NULL)
+ {
+ log_error("Sorry, can only match one '*' wildcard.");
+ return -1;
+ }
+ } else {
+ // '*' not found
+ smatch = file_name;
+ }
+ }
+ char *qmatch = strchr(file_name, '?');
+ if ((qmatch != &npattern[length - 1]) && (qmatch != NULL))
+ {
+ log_error("Sorry, can only match '?' at end of filename.");
+ return -1;
+ } else {
+ qmatch = &npattern[length];
+ }
+ int pattern_length = qmatch - smatch;
+ g_file_pattern = strndup(smatch, pattern_length);
+ for (int j = 0; j < pattern_length; j++)
+ {
+ g_file_pattern[j] = (char)toupper(g_file_pattern[j]);
+ }
+ log_warning("looking for file matching %s", g_file_pattern);
+ int cnt;
+ for (i = 0; i < countof(_enumerateFileInfoList); i++) {
+ enumFileInfo = &_enumerateFileInfoList[i];
+ if (!enumFileInfo->active) {
+ strncpy(enumFileInfo->pattern, npattern, length);
+ cnt = scandir(dir_name, &enumFileInfo->fileListTemp, winfilter, alphasort);
+ if (cnt < 0)
+ {
+ break;
+ }
+ log_warning("found %d files matching in dir '%s'", cnt, dir_name);
+ enumFileInfo->cnt = cnt;
+ enumFileInfo->paths = malloc(cnt * sizeof(char *));
+ char **paths = enumFileInfo->paths;
+ // 256 is size of dirent.d_name
+ const int buf_len = min(MAX_PATH, 256);
+ const int dir_name_len = strnlen(dir_name, MAX_PATH);
+ char separator[] = {platform_get_path_separator(), 0};
+ for (int idx = 0; idx < cnt; idx++)
+ {
+ struct dirent *d = enumFileInfo->fileListTemp[idx];
+ const int entry_len = strnlen(d->d_name, MAX_PATH);
+ // 1 for separator, 1 for trailing null
+ paths[idx] = malloc(sizeof(char) * min(MAX_PATH, entry_len + dir_name_len + 2));
+ paths[idx][0] = '\0';
+ log_verbose("dir_name: %s", dir_name);
+ strncat(paths[idx], dir_name, MAX_PATH);
+ strncat(paths[idx], separator, MAX_PATH);
+ strncat(paths[idx], d->d_name, MAX_PATH);
+ log_verbose("paths[%d] = %s", idx, paths[idx]);
+ }
+ enumFileInfo->handle = 0;
+ enumFileInfo->active = 1;
+ free(dir_name);
+ free(g_file_pattern);
+ g_file_pattern = NULL;
+ free(wpattern);
+ free(npattern);
+ return i;
+ }
+ }
+
+ free(dir_name);
+ free(g_file_pattern);
+ g_file_pattern = NULL;
+ free(wpattern);
+ free(npattern);
+ return -1;
+}
+
+bool platform_enumerate_files_next(int handle, file_info *outFileInfo)
+{
+ bool result;
+ enumerate_file_info *enumFileInfo;
+
+ enumFileInfo = &_enumerateFileInfoList[handle];
+
+ log_verbose("handle = %d", handle);
+ if (enumFileInfo->handle < enumFileInfo->cnt) {
+ result = true;
+ } else {
+ result = false;
+ }
+
+ 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;
+ }
+ outFileInfo->path = basename(fileName);
+ outFileInfo->size = fileInfo.st_size;
+ outFileInfo->last_modified = fileInfo.st_mtime;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+void platform_enumerate_files_end(int handle)
+{
+ int i;
+ enumerate_file_info *enumFileInfo;
+
+ enumFileInfo = &_enumerateFileInfoList[handle];
+ int cnt = enumFileInfo->cnt;
+ for (i = 0; i < cnt; i++) {
+ free(enumFileInfo->fileListTemp[i]);
+ free(enumFileInfo->paths[i]);
+ }
+ free(enumFileInfo->fileListTemp);
+ free(enumFileInfo->paths);
+ // FIXME: this here could have a bug
+ enumFileInfo->fileListTemp = NULL;
+ enumFileInfo->handle = 0;
+ enumFileInfo->active = 0;
+}
+
+static int dirfilter(const struct dirent *d)
+{
+#ifdef _DIRENT_HAVE_D_TYPE
+ if (d->d_type != DT_DIR)
+ {
+ return 1;
+ } else {
+ return 0;
+ }
+#else
+#error implement dirfilter!
+#endif // _DIRENT_HAVE_D_TYPE
+}
+
+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);
+ char *npattern = malloc(length);
+ int converted;
+ converted = wcstombs(npattern, wpattern, length);
+ npattern[length - 1] = '\0';
+ if (converted == MAX_PATH) {
+ log_warning("truncated string %s", npattern);
+ }
+ log_warning("begin directory listing, path: %s", npattern);
+
+ // TODO: add some checking for stringness and directoryness
+
+ int cnt;
+ for (i = 0; i < countof(_enumerateFileInfoList); i++) {
+ enumFileInfo = &_enumerateFileInfoList[i];
+ if (!enumFileInfo->active) {
+ strncpy(enumFileInfo->pattern, npattern, length);
+ cnt = scandir(npattern, &enumFileInfo->fileListTemp, dirfilter, alphasort);
+ if (cnt < 0)
+ {
+ break;
+ }
+ log_warning("found %d files in dir '%s'", cnt, npattern);
+ enumFileInfo->cnt = cnt;
+ enumFileInfo->paths = malloc(cnt * sizeof(char *));
+ char **paths = enumFileInfo->paths;
+ // 256 is size of dirent.d_name
+ const int buf_len = min(MAX_PATH, 256);
+ const int dir_name_len = strnlen(npattern, MAX_PATH);
+ char separator[] = {platform_get_path_separator(), 0};
+ for (int idx = 0; idx < cnt; idx++)
+ {
+ struct dirent *d = enumFileInfo->fileListTemp[idx];
+ const int entry_len = strnlen(d->d_name, MAX_PATH);
+ // 1 for separator, 1 for trailing null
+ paths[idx] = malloc(sizeof(char) * min(MAX_PATH, entry_len + dir_name_len + 2));
+ paths[idx][0] = '\0';
+ log_verbose("dir_name: %s", npattern);
+ strncat(paths[idx], npattern, MAX_PATH);
+ strncat(paths[idx], separator, MAX_PATH);
+ strncat(paths[idx], d->d_name, MAX_PATH);
+ log_verbose("paths[%d] = %s", idx, paths[idx]);
+ }
+ enumFileInfo->handle = 0;
+ enumFileInfo->active = 1;
+ free(wpattern);
+ free(npattern);
+ return i;
+ }
+ }
+
+ free(wpattern);
+ free(npattern);
+ return -1;
+}
+
+bool platform_enumerate_directories_next(int handle, utf8 *path)
+{
+ bool result;
+ enumerate_file_info *enumFileInfo;
+
+ enumFileInfo = &_enumerateFileInfoList[handle];
+
+ log_verbose("handle = %d", handle);
+ if (enumFileInfo->handle < enumFileInfo->cnt) {
+ result = true;
+ } else {
+ result = false;
+ }
+
+ 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;
+ }
+ // so very, very wrong…
+ strncpy(path, basename(fileName), MAX_PATH);
+ strncat(path, "/", MAX_PATH);
+ path[MAX_PATH - 1] = '\0';
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+void platform_enumerate_directories_end(int handle)
+{
+ int i;
+ enumerate_file_info *enumFileInfo;
+
+ enumFileInfo = &_enumerateFileInfoList[handle];
+ int cnt = enumFileInfo->cnt;
+ for (i = 0; i < cnt; i++) {
+ free(enumFileInfo->fileListTemp[i]);
+ free(enumFileInfo->paths[i]);
+ }
+ free(enumFileInfo->fileListTemp);
+ free(enumFileInfo->paths);
+ // FIXME: this here could have a bug
+ enumFileInfo->fileListTemp = NULL;
+ enumFileInfo->handle = 0;
+ enumFileInfo->active = 0;
+}
+
+int platform_get_drives(){
+ /*
+ return GetLogicalDrives();
+ */
+ STUB();
+ return 0xff;
+}
+
+bool platform_file_copy(const utf8 *srcPath, const utf8 *dstPath, bool overwrite)
+{
+ STUB();
+ return 0;
+}
+
+bool platform_file_move(const utf8 *srcPath, const utf8 *dstPath)
+{
+ STUB();
+ return 0;
+}
+
+bool platform_file_delete(const utf8 *path)
+{
+ STUB();
+ return 0;
+}
+
+void platform_hide_cursor()
+{
+ STUB();
+}
+
+void platform_show_cursor()
+{
+ STUB();
+}
+
+void platform_get_cursor_position(int *x, int *y)
+{
+
+ STUB();
+}
+
+void platform_set_cursor_position(int x, int y)
+{
+ STUB();
+}
+
+unsigned int platform_get_ticks()
+{
+ STUB();
+ return 100;
+}
+
+wchar_t *regular_to_wchar(const char* src)
+{
+ int len = strnlen(src, MAX_PATH);
+ wchar_t *w_buffer = malloc((len + 1) * sizeof(wchar_t));
+ mbtowc (NULL, NULL, 0); /* reset mbtowc */
+
+ int max = len;
+ int i = 0;
+ while (max > 0)
+ {
+ int length;
+ length = mbtowc(&w_buffer[i], &src[i], max);
+ if (length < 1)
+ {
+ w_buffer[i + 1] = '\0';
+ break;
+ }
+ i += length;
+ max -= length;
+ }
+ return w_buffer;
+}
+
+void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory)
+{
+ char buffer[MAX_PATH];
+ buffer[0] = '\0';
+ log_verbose("buffer = '%s'", buffer);
+ const char *homedir = getenv("XDG_CONFIG_HOME");
+ log_verbose("homedir = '%s'", homedir);
+ if (homedir == NULL)
+ {
+ homedir = getpwuid(getuid())->pw_dir;
+ log_verbose("homedir was null, used getuid, now is = '%s'", homedir);
+ if (homedir == NULL)
+ {
+ log_error("Couldn't find user home directory");
+ return;
+ }
+ }
+ char separator[2] = { platform_get_path_separator(), 0 };
+ strncat(buffer, homedir, MAX_PATH);
+ strncat(buffer, separator, MAX_PATH);
+ strncat(buffer, "OpenRCT2", MAX_PATH);
+ strncat(buffer, separator, MAX_PATH);
+ log_verbose("outPath + OpenRCT2 = '%s'", buffer);
+ if (subDirectory != NULL && subDirectory[0] != 0) {
+ log_verbose("adding subDirectory '%s'", subDirectory);
+ strcat(buffer, subDirectory);
+ strcat(buffer, separator);
+ }
+ int len = strnlen(buffer, MAX_PATH);
+ wchar_t *w_buffer = regular_to_wchar(buffer);
+ w_buffer[len] = '\0';
+ utf8 *path = widechar_to_utf8(w_buffer);
+ free(w_buffer);
+ strcpy(outPath, path);
+ free(path);
+ log_verbose("outPath + subDirectory = '%s'", buffer);
+}
+
+void platform_show_messagebox(char *message)
+{
+ STUB();
+ log_warning(message);
+}
+
+/**
+ *
+ * rct2: 0x004080EA
+ */
+int platform_open_common_file_dialog(int type, utf8 *title, utf8 *filename, utf8 *filterPattern, utf8 *filterName)
+{
+ STUB();
+ return 0;
+}
+
+utf8 *platform_open_directory_browser(utf8 *title)
+{
+ STUB();
+ return NULL;
+}
+
+uint16 platform_get_locale_language(){
+ /*
+ CHAR langCode[4];
+
+ if (GetLocaleInfo(LOCALE_USER_DEFAULT,
+ LOCALE_SABBREVLANGNAME,
+ (LPSTR)&langCode,
+ sizeof(langCode)) == 0){
+ return LANGUAGE_UNDEFINED;
+ }
+
+ if (strcmp(langCode, "ENG") == 0){
+ return LANGUAGE_ENGLISH_UK;
+ }
+ else if (strcmp(langCode, "ENU") == 0){
+ return LANGUAGE_ENGLISH_US;
+ }
+ else if (strcmp(langCode, "DEU") == 0){
+ return LANGUAGE_GERMAN;
+ }
+ else if (strcmp(langCode, "NLD") == 0){
+ return LANGUAGE_DUTCH;
+ }
+ else if (strcmp(langCode, "FRA") == 0){
+ return LANGUAGE_FRENCH;
+ }
+ else if (strcmp(langCode, "HUN") == 0){
+ return LANGUAGE_HUNGARIAN;
+ }
+ else if (strcmp(langCode, "PLK") == 0){
+ return LANGUAGE_POLISH;
+ }
+ else if (strcmp(langCode, "ESP") == 0){
+ return LANGUAGE_SPANISH;
+ }
+ else if (strcmp(langCode, "SVE") == 0){
+ return LANGUAGE_SWEDISH;
+ }
+ else if (strcmp(langCode, "ITA") == 0){
+ return LANGUAGE_ITALIAN;
+ }
+ else if (strcmp(langCode, "POR") == 0){
+ return LANGUAGE_PORTUGUESE_BR;
+ }
+ */
+ STUB();
+ return LANGUAGE_ENGLISH_UK;
+}
+
+time_t platform_file_get_modified_time(const utf8* path){
+ /*
+ WIN32_FILE_ATTRIBUTE_DATA data;
+ if (!GetFileAttributesEx(path, GetFileExInfoStandard, &data))
+ return 0;
+ ULARGE_INTEGER ull;
+ ull.LowPart = data.ftLastWriteTime.dwLowDateTime;
+ ull.HighPart = data.ftLastWriteTime.dwHighDateTime;
+ return ull.QuadPart / 10000000ULL - 11644473600ULL;
+ */
+ STUB();
+ return 100;
+}
+
+uint8 platform_get_locale_currency(){
+ /*
+ CHAR currCode[4];
+
+ if (GetLocaleInfo(LOCALE_USER_DEFAULT,
+ LOCALE_SINTLSYMBOL,
+ (LPSTR)&currCode,
+ sizeof(currCode)) == 0){
+ return CURRENCY_POUNDS;
+ }
+ if (strcmp(currCode, "GBP") == 0){
+ return CURRENCY_POUNDS;
+ }
+ else if (strcmp(currCode, "USD") == 0){
+ return CURRENCY_DOLLARS;
+ }
+ else if (strcmp(currCode, "EUR") == 0){
+ return CURRENCY_EUROS;
+ }
+ else if (strcmp(currCode, "SEK") == 0){
+ return CURRENCY_KRONA;
+ }
+ else if (strcmp(currCode, "DEM") == 0){
+ return CURRENCY_DEUTSCHMARK;
+ }
+ else if (strcmp(currCode, "ITL") == 0){
+ return CURRENCY_LIRA;
+ }
+ else if (strcmp(currCode, "JPY") == 0){
+ return CURRENCY_YEN;
+ }
+ else if (strcmp(currCode, "ESP") == 0){
+ return CURRENCY_PESETA;
+ }
+ else if (strcmp(currCode, "FRF") == 0){
+ return CURRENCY_FRANC;
+ }
+ else if (strcmp(currCode, "NLG") == 0){
+ return CURRENCY_GUILDERS;
+ }
+ */
+ STUB();
+ return CURRENCY_POUNDS;
+}
+
+uint8 platform_get_locale_measurement_format(){
+ /*
+ UINT measurement_system;
+ if (GetLocaleInfo(LOCALE_USER_DEFAULT,
+ LOCALE_IMEASURE | LOCALE_RETURN_NUMBER,
+ (LPSTR)&measurement_system,
+ sizeof(measurement_system)) == 0){
+ return MEASUREMENT_FORMAT_IMPERIAL;
+ }
+ switch (measurement_system){
+ case 0:
+ return MEASUREMENT_FORMAT_METRIC;
+ case 1:
+ default:
+ return MEASUREMENT_FORMAT_IMPERIAL;
+ }*/
+ STUB();
+ return MEASUREMENT_FORMAT_METRIC;
+}
+
+uint8 platform_get_locale_temperature_format(){
+ /*
+ // There does not seem to be a function to obtain this, just check the countries
+ UINT country;
+ if (GetLocaleInfo(LOCALE_USER_DEFAULT,
+ LOCALE_IMEASURE | LOCALE_RETURN_NUMBER,
+ (LPSTR)&country,
+ sizeof(country)) == 0){
+ return TEMPERATURE_FORMAT_C;
+ }
+ switch (country){
+ case CTRY_UNITED_STATES:
+ case CTRY_BELIZE:
+ return TEMPERATURE_FORMAT_F;
+ default:
+ return TEMPERATURE_FORMAT_C;
+ }
+ */
+ STUB();
+ return TEMPERATURE_FORMAT_C;
+}
+#endif // __linux
diff --git a/src/platform/platform.h b/src/platform/platform.h
index 23934c5661..a894264f77 100644
--- a/src/platform/platform.h
+++ b/src/platform/platform.h
@@ -147,6 +147,7 @@ uint8 platform_get_locale_temperature_format();
#define _strcmpi _stricmp
#define _stricmp(x, y) strcasecmp((x), (y))
#define _strnicmp(x, y, n) strncasecmp((x), (y), (n))
+#define _strdup(x) strdup((x))
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define RCT2_ENDIANESS __ORDER_LITTLE_ENDIAN__
diff --git a/src/platform/unix.c b/src/platform/unix.c
index e5151df42d..602709bb63 100644
--- a/src/platform/unix.c
+++ b/src/platform/unix.c
@@ -1,9 +1,9 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
- *
+ *
* This file is part of 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
@@ -31,14 +31,16 @@
// {
// if (cmdline_run(argv, argc))
// openrct2_launch();
-//
+//
// return gExitCode;
// }
+/*
char platform_get_path_separator()
{
return '/';
}
+*/
#endif
-#endif
\ No newline at end of file
+#endif
diff --git a/src/rct2.h b/src/rct2.h
index 5749e3a133..74cf311b7e 100644
--- a/src/rct2.h
+++ b/src/rct2.h
@@ -1,9 +1,9 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
- *
+ *
* This file is part of 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
@@ -17,7 +17,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*****************************************************************************/
-
+
#ifndef _RCT2_H_
#define _RCT2_H_
@@ -206,7 +206,11 @@ enum {
// rct2 @ 0x0097F67C
static const char * const file_paths[] =
{
- "Data\\G1.DAT",
+#ifdef _WIN32
+ "data\\g1.dat",
+#else
+ "data/g1.dat",
+#endif // _WIN32
"Data\\PLUGIN.DAT",
"Data\\CSS1.DAT",
"Data\\CSS2.DAT",