diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj
index 2d78655e37..13d1c0ff54 100644
--- a/projects/openrct2.vcxproj
+++ b/projects/openrct2.vcxproj
@@ -85,8 +85,8 @@
+
-
diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters
index 1b5b6966ab..d32f0f5439 100644
--- a/projects/openrct2.vcxproj.filters
+++ b/projects/openrct2.vcxproj.filters
@@ -300,7 +300,7 @@
Source\Platform
-
+
Source\Platform
@@ -825,4 +825,4 @@
Source\Interface
-
\ No newline at end of file
+
diff --git a/src/platform/linux.c b/src/platform/linux.c
index bce343888c..f5d062e5dd 100644
--- a/src/platform/linux.c
+++ b/src/platform/linux.c
@@ -18,756 +18,40 @@
* along with this program. If not, see .
*****************************************************************************/
-#ifdef __linux
+#if defined(__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 "../util/util.h"
-#include
-#include
-#include
+#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"
+// See http://syprog.blogspot.ru/2011/12/listing-loaded-shared-objects-in-linux.html
+struct lmap {
+ void* base_address;
+ char* path;
+ void* unused;
+ struct lmap *next, *prev;
+};
-utf8 _userDataDirectoryPath[MAX_PATH] = { 0 };
+struct dummy {
+ void* pointers[3];
+ struct dummy* ptr;
+};
-/**
- * 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;
+bool platform_check_steam_overlay_attached() {
+ void* processHandle = dlopen(NULL, RTLD_NOW);
- STUB();
- int run_game = cmdline_run(argv, argc);
- if (run_game == 1)
- {
- openrct2_launch();
+ struct dummy* p = (struct dummy*) processHandle;
+ p = p->ptr;
+
+ struct lmap* pl = (struct lmap*) p->ptr;
+
+ while (pl != NULL) {
+ if (strstr(pl->path, "gameoverlayrenderer.so") != NULL) {
+ return true;
+ }
+ pl = pl->next;
}
- exit(gExitCode);
- return gExitCode;
-}
-
-void platform_get_date(rct2_date *out_date)
-{
- assert(out_date != NULL);
- time_t rawtime;
- struct tm * timeinfo;
- time(&rawtime);
- timeinfo = gmtime(&rawtime);
- out_date->day = timeinfo->tm_mday;
- out_date->month = timeinfo->tm_mon;
- out_date->year = timeinfo->tm_year;
- out_date->day_of_week = timeinfo->tm_wday;
-}
-
-void platform_get_time(rct2_time *out_time)
-{
- assert(out_time != NULL);
- time_t rawtime;
- struct tm * timeinfo;
- time(&rawtime);
- timeinfo = gmtime(&rawtime);
- out_time->second = timeinfo->tm_sec;
- out_time->minute = timeinfo->tm_min;
- out_time->hour = timeinfo->tm_hour;
-}
-
-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);
- bool 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 false;
- }
- return true;
-}
-
-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 true;
-}
-
-bool platform_lock_single_instance()
-{
- STUB();
- return true;
-}
-
-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 = fnmatch(g_file_pattern, name_upper, FNM_PATHNAME) == 0;
- //log_warning("trying matching filename %s, result = %d", name_upper, match);
- free(name_upper);
- return match;
-}
-
-int platform_enumerate_files_begin(const utf8 *pattern)
-{
- enumerate_file_info *enumFileInfo;
- wchar_t *wpattern = utf8_to_widechar(pattern);
- int length = min(utf8_length(pattern), MAX_PATH);
- char *npattern = malloc(length+1);
- int converted;
- converted = wcstombs(npattern, wpattern, length);
- npattern[length] = '\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(".");
- }
-
-
- int pattern_length = strlen(file_name);
- g_file_pattern = strndup(file_name, 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 (int i = 0; i < countof(_enumerateFileInfoList); i++) {
- enumFileInfo = &_enumerateFileInfoList[i];
- if (!enumFileInfo->active) {
- safe_strncpy(enumFileInfo->pattern, npattern, sizeof(enumFileInfo->pattern));
- 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)
-{
-
- if (handle < 0)
- {
- return false;
- }
- enumerate_file_info *enumFileInfo = &_enumerateFileInfoList[handle];
- bool result;
-
- 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 false;
- }
- outFileInfo->path = basename(fileName);
- outFileInfo->size = fileInfo.st_size;
- outFileInfo->last_modified = fileInfo.st_mtime;
- return true;
- } else {
- return false;
- }
-}
-
-void platform_enumerate_files_end(int handle)
-{
- if (handle < 0)
- {
- return;
- }
- enumerate_file_info *enumFileInfo = &_enumerateFileInfoList[handle];
- int cnt = enumFileInfo->cnt;
- for (int 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)
-{
- if (d->d_name[0] == '.') {
- return 0;
- }
-#if defined(_DIRENT_HAVE_D_TYPE) || defined(DT_UNKNOWN)
- if (d->d_type == DT_DIR)
- {
- return 1;
- } else {
- return 0;
- }
-#else
-#error implement dirfilter!
-#endif // defined(_DIRENT_HAVE_D_TYPE) || defined(DT_UNKNOWN)
-}
-
-int platform_enumerate_directories_begin(const utf8 *directory)
-{
- enumerate_file_info *enumFileInfo;
- wchar_t *wpattern = utf8_to_widechar(directory);
- int length = min(utf8_length(directory), MAX_PATH);
- char *npattern = malloc(length+1);
- int converted;
- converted = wcstombs(npattern, wpattern, length);
- npattern[length] = '\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 (int i = 0; i < countof(_enumerateFileInfoList); i++) {
- enumFileInfo = &_enumerateFileInfoList[i];
- if (!enumFileInfo->active) {
- safe_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)
-{
- if (handle < 0)
- {
- return false;
- }
-
- bool result;
- enumerate_file_info *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;
- 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 false;
- }
- // so very, very wrong
- safe_strncpy(path, basename(fileName), MAX_PATH);
- strncat(path, "/", MAX_PATH);
- path[MAX_PATH - 1] = '\0';
- return true;
- } else {
- return false;
- }
-}
-
-void platform_enumerate_directories_end(int handle)
-{
- if (handle < 0)
- {
- return;
- }
- enumerate_file_info *enumFileInfo = &_enumerateFileInfoList[handle];
- int cnt = enumFileInfo->cnt;
- for (int 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 0;
-}
-
-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;
-}
-
-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;
-}
-
-/**
- * Default directory fallback is:
- * - (command line argument)
- * - $XDG_CONFIG_HOME/.config/OpenRCT2
- * - /home/[uid]/.config/OpenRCT2
- */
-void platform_resolve_user_data_path()
-{
- const char separator[2] = { platform_get_path_separator(), 0 };
-
- if (gCustomUserDataPath[0] != 0) {
- realpath(gCustomUserDataPath, _userDataDirectoryPath);
-
- // Ensure path ends with separator
- int len = strlen(_userDataDirectoryPath);
- if (_userDataDirectoryPath[len - 1] != separator[0]) {
- strcat(_userDataDirectoryPath, separator);
- }
- return;
- }
-
- 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_fatal("Couldn't find user data directory");
- exit(-1);
- return;
- }
-
- strncat(buffer, homedir, MAX_PATH);
- strncat(buffer, separator, MAX_PATH);
- strncat(buffer, ".config", MAX_PATH);
- }
- else
- {
- strncat(buffer, homedir, MAX_PATH);
- }
- strncat(buffer, separator, MAX_PATH);
- strncat(buffer, "OpenRCT2", MAX_PATH);
- strncat(buffer, separator, MAX_PATH);
- log_verbose("OpenRCT2 user data directory = '%s'", buffer);
- 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);
- safe_strncpy(_userDataDirectoryPath, path, MAX_PATH);
- free(path);
-}
-
-void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory)
-{
- const char separator[2] = { platform_get_path_separator(), 0 };
- char buffer[MAX_PATH];
- safe_strncpy(buffer, _userDataDirectoryPath, sizeof(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);
- safe_strncpy(outPath, path, MAX_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){
- struct stat buf;
- if (stat(path, &buf) == 0) {
- return buf.st_mtime;
- }
- 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
+#endif
diff --git a/src/platform/osx.c b/src/platform/osx.c
index 4f08d128f1..c1928d0f02 100644
--- a/src/platform/osx.c
+++ b/src/platform/osx.c
@@ -18,19 +18,13 @@
* along with this program. If not, see .
*****************************************************************************/
-#ifdef __APPLE__
+#if defined(__APPLE__) && defined(__MACH__)
-/**
- * OSX entry point to OpenRCT2.
- */
-// int main(char *argv[], int argc)
-// {
-// return 0;
-// }
+#include "platform.h"
-char platform_get_path_separator()
-{
- return '/';
+bool platform_check_steam_overlay_attached() {
+ STUB();
+ return false;
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/platform/posix.c b/src/platform/posix.c
new file mode 100644
index 0000000000..917f27ff4f
--- /dev/null
+++ b/src/platform/posix.c
@@ -0,0 +1,774 @@
+/*****************************************************************************
+ * 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 .
+ *****************************************************************************/
+
+#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
+
+#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 "../util/util.h"
+#include
+#include
+#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"
+
+utf8 _userDataDirectoryPath[MAX_PATH] = { 0 };
+
+/**
+ * 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;
+}
+
+void platform_get_date(rct2_date *out_date)
+{
+ assert(out_date != NULL);
+ time_t rawtime;
+ struct tm * timeinfo;
+ time(&rawtime);
+ timeinfo = gmtime(&rawtime);
+ out_date->day = timeinfo->tm_mday;
+ out_date->month = timeinfo->tm_mon;
+ out_date->year = timeinfo->tm_year;
+ out_date->day_of_week = timeinfo->tm_wday;
+}
+
+void platform_get_time(rct2_time *out_time)
+{
+ assert(out_time != NULL);
+ time_t rawtime;
+ struct tm * timeinfo;
+ time(&rawtime);
+ timeinfo = gmtime(&rawtime);
+ out_time->second = timeinfo->tm_sec;
+ out_time->minute = timeinfo->tm_min;
+ out_time->hour = timeinfo->tm_hour;
+}
+
+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);
+ bool 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 false;
+ }
+ return true;
+}
+
+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 true;
+}
+
+bool platform_lock_single_instance()
+{
+ STUB();
+ return true;
+}
+
+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 = fnmatch(g_file_pattern, name_upper, FNM_PATHNAME) == 0;
+ //log_warning("trying matching filename %s, result = %d", name_upper, match);
+ free(name_upper);
+ return match;
+}
+
+int platform_enumerate_files_begin(const utf8 *pattern)
+{
+ enumerate_file_info *enumFileInfo;
+ wchar_t *wpattern = utf8_to_widechar(pattern);
+ int length = min(utf8_length(pattern), MAX_PATH);
+ char *npattern = malloc(length+1);
+ int converted;
+ converted = wcstombs(npattern, wpattern, length);
+ npattern[length] = '\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(".");
+ }
+
+
+ int pattern_length = strlen(file_name);
+ g_file_pattern = strndup(file_name, 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 (int i = 0; i < countof(_enumerateFileInfoList); i++) {
+ enumFileInfo = &_enumerateFileInfoList[i];
+ if (!enumFileInfo->active) {
+ safe_strncpy(enumFileInfo->pattern, npattern, sizeof(enumFileInfo->pattern));
+ 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)
+{
+
+ if (handle < 0)
+ {
+ return false;
+ }
+ enumerate_file_info *enumFileInfo = &_enumerateFileInfoList[handle];
+ bool result;
+
+ 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 false;
+ }
+ outFileInfo->path = basename(fileName);
+ outFileInfo->size = fileInfo.st_size;
+ outFileInfo->last_modified = fileInfo.st_mtime;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void platform_enumerate_files_end(int handle)
+{
+ if (handle < 0)
+ {
+ return;
+ }
+ enumerate_file_info *enumFileInfo = &_enumerateFileInfoList[handle];
+ int cnt = enumFileInfo->cnt;
+ for (int 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)
+{
+ if (d->d_name[0] == '.') {
+ return 0;
+ }
+#if defined(_DIRENT_HAVE_D_TYPE) || defined(DT_UNKNOWN)
+ if (d->d_type == DT_DIR)
+ {
+ return 1;
+ } else {
+ return 0;
+ }
+#else
+#error implement dirfilter!
+#endif // defined(_DIRENT_HAVE_D_TYPE) || defined(DT_UNKNOWN)
+}
+
+int platform_enumerate_directories_begin(const utf8 *directory)
+{
+ enumerate_file_info *enumFileInfo;
+ wchar_t *wpattern = utf8_to_widechar(directory);
+ int length = min(utf8_length(directory), MAX_PATH);
+ char *npattern = malloc(length+1);
+ int converted;
+ converted = wcstombs(npattern, wpattern, length);
+ npattern[length] = '\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 (int i = 0; i < countof(_enumerateFileInfoList); i++) {
+ enumFileInfo = &_enumerateFileInfoList[i];
+ if (!enumFileInfo->active) {
+ safe_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)
+{
+ if (handle < 0)
+ {
+ return false;
+ }
+
+ bool result;
+ enumerate_file_info *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;
+ 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 false;
+ }
+ // so very, very wrong
+ safe_strncpy(path, basename(fileName), MAX_PATH);
+ strncat(path, "/", MAX_PATH);
+ path[MAX_PATH - 1] = '\0';
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void platform_enumerate_directories_end(int handle)
+{
+ if (handle < 0)
+ {
+ return;
+ }
+ enumerate_file_info *enumFileInfo = &_enumerateFileInfoList[handle];
+ int cnt = enumFileInfo->cnt;
+ for (int 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 0;
+}
+
+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;
+}
+
+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;
+}
+
+/**
+ * Default directory fallback is:
+ * - (command line argument)
+ * - $XDG_CONFIG_HOME/.config/OpenRCT2
+ * - /home/[uid]/.config/OpenRCT2
+ */
+void platform_resolve_user_data_path()
+{
+ const char separator[2] = { platform_get_path_separator(), 0 };
+
+ if (gCustomUserDataPath[0] != 0) {
+ realpath(gCustomUserDataPath, _userDataDirectoryPath);
+
+ // Ensure path ends with separator
+ int len = strlen(_userDataDirectoryPath);
+ if (_userDataDirectoryPath[len - 1] != separator[0]) {
+ strcat(_userDataDirectoryPath, separator);
+ }
+ return;
+ }
+
+ 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_fatal("Couldn't find user data directory");
+ exit(-1);
+ return;
+ }
+
+ strncat(buffer, homedir, MAX_PATH);
+ strncat(buffer, separator, MAX_PATH);
+ strncat(buffer, ".config", MAX_PATH);
+ }
+ else
+ {
+ strncat(buffer, homedir, MAX_PATH);
+ }
+ strncat(buffer, separator, MAX_PATH);
+ strncat(buffer, "OpenRCT2", MAX_PATH);
+ strncat(buffer, separator, MAX_PATH);
+ log_verbose("OpenRCT2 user data directory = '%s'", buffer);
+ 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);
+ safe_strncpy(_userDataDirectoryPath, path, MAX_PATH);
+ free(path);
+}
+
+void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory)
+{
+ const char separator[2] = { platform_get_path_separator(), 0 };
+ char buffer[MAX_PATH];
+ safe_strncpy(buffer, _userDataDirectoryPath, sizeof(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);
+ safe_strncpy(outPath, path, MAX_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){
+ struct stat buf;
+ if (stat(path, &buf) == 0) {
+ return buf.st_mtime;
+ }
+ 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
diff --git a/src/platform/unix.c b/src/platform/unix.c
deleted file mode 100644
index 956828364e..0000000000
--- a/src/platform/unix.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*****************************************************************************
- * 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 .
- *****************************************************************************/
-
-#ifndef _WIN32
-#ifndef __APPLE__
-
-#include "../cmdline.h"
-#include "../openrct2.h"
-#include
-
-/**
- * Unix, linux and fallback entry point to OpenRCT2.
- */
-// int main(char *argv[], int argc)
-// {
-// if (cmdline_run(argv, argc))
-// openrct2_launch();
-//
-// return gExitCode;
-// }
-
-/*
-char platform_get_path_separator()
-{
- return '/';
-}
-*/
-
-// See http://syprog.blogspot.ru/2011/12/listing-loaded-shared-objects-in-linux.html
-struct lmap {
- void* base_address;
- char* path;
- void* unused;
- struct lmap *next, *prev;
-};
-
-struct dummy {
- void* pointers[3];
- struct dummy* ptr;
-};
-
-bool platform_check_steam_overlay_attached() {
- void* processHandle = dlopen(NULL, RTLD_NOW);
-
- struct dummy* p = (struct dummy*) processHandle;
- p = p->ptr;
-
- struct lmap* pl = (struct lmap*) p->ptr;
-
- while (pl != NULL) {
- if (strstr(pl->path, "gameoverlayrenderer.so") != NULL) {
- return true;
- }
- pl = pl->next;
- }
-
- return false;
-}
-
-#endif
-#endif
diff --git a/src/rct2.h b/src/rct2.h
index 660536a691..4910528dbc 100644
--- a/src/rct2.h
+++ b/src/rct2.h
@@ -92,7 +92,7 @@ typedef utf16* utf16string;
#ifdef __linux__
#define OPENRCT2_PLATFORM "Linux"
#endif
-#ifdef __APPLE__
+#if defined(__APPLE__) && defined(__MACH__)
#define OPENRCT2_PLATFORM "OS X"
#endif
#ifndef OPENRCT2_PLATFORM