clang-format platform

This commit is contained in:
clang-format 2018-06-22 23:04:38 +02:00 committed by Hielke Morsink
parent bb3561f70b
commit 0b3edc70f2
15 changed files with 599 additions and 493 deletions

View File

@ -9,36 +9,41 @@
#ifdef __ANDROID__
#include "platform.h"
#include "../config/Config.h"
#include "../localisation/Language.h"
#include "../util/Util.h"
#include <wchar.h>
#include <jni.h>
#include "platform.h"
#include <SDL.h>
#include <jni.h>
#include <wchar.h>
#ifndef NO_TTF
bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer, size_t size)
bool platform_get_font_path(TTFFontDescriptor* font, utf8* buffer, size_t size)
{
STUB();
return false;
}
#endif
uint16_t platform_get_locale_language() {
uint16_t platform_get_locale_language()
{
return LANGUAGE_ENGLISH_UK;
}
uint8_t platform_get_locale_currency() {
uint8_t platform_get_locale_currency()
{
return platform_get_currency_value(NULL);
}
uint8_t platform_get_locale_measurement_format() {
uint8_t platform_get_locale_measurement_format()
{
return MEASUREMENT_FORMAT_METRIC;
}
float platform_get_default_scale() {
JNIEnv *env = static_cast<JNIEnv *>(SDL_AndroidGetJNIEnv());
float platform_get_default_scale()
{
JNIEnv* env = static_cast<JNIEnv*>(SDL_AndroidGetJNIEnv());
jobject activity = static_cast<jobject>(SDL_AndroidGetActivity());
jclass activityClass = env->GetObjectClass(activity);
@ -52,7 +57,7 @@ float platform_get_default_scale() {
return displayScale;
}
bool platform_get_steam_path(utf8 * outPath, size_t outSize)
bool platform_get_steam_path(utf8* outPath, size_t outSize)
{
return false;
}

View File

@ -14,41 +14,44 @@
#include <stdio.h>
#if defined(_WIN32)
#include <breakpad/client/windows/handler/exception_handler.h>
#include <string>
#include <ShlObj.h>
#include <ShlObj.h>
#include <breakpad/client/windows/handler/exception_handler.h>
#include <string>
#else
#error Breakpad support not implemented yet for this platform
#error Breakpad support not implemented yet for this platform
#endif
#include "../Version.h"
#include "../core/Console.hpp"
#include "../localisation/Language.h"
#include "../rct2/S6Exporter.h"
#include "../scenario/Scenario.h"
#include "../Version.h"
#include "platform.h"
#define WSZ(x) L"" x
#ifdef OPENRCT2_COMMIT_SHA1_SHORT
const wchar_t *_wszCommitSha1Short = WSZ(OPENRCT2_COMMIT_SHA1_SHORT);
const wchar_t* _wszCommitSha1Short = WSZ(OPENRCT2_COMMIT_SHA1_SHORT);
#else
const wchar_t *_wszCommitSha1Short = WSZ("");
const wchar_t* _wszCommitSha1Short = WSZ("");
#endif
// OPENRCT2_ARCHITECTURE is required to be defined in version.h
const wchar_t *_wszArchitecture = WSZ(OPENRCT2_ARCHITECTURE);
const wchar_t* _wszArchitecture = WSZ(OPENRCT2_ARCHITECTURE);
static bool OnCrash(const wchar_t * dumpPath,
const wchar_t * miniDumpId,
void * context,
EXCEPTION_POINTERS * exinfo,
MDRawAssertionInfo * assertion,
bool succeeded)
static bool OnCrash(
const wchar_t* dumpPath,
const wchar_t* miniDumpId,
void* context,
EXCEPTION_POINTERS* exinfo,
MDRawAssertionInfo* assertion,
bool succeeded)
{
if (!succeeded)
{
constexpr const char * DumpFailedMessage = "Failed to create the dump. Please file an issue with OpenRCT2 on GitHub and provide latest save, and provide information about what you did before the crash occurred.";
constexpr const char* DumpFailedMessage
= "Failed to create the dump. Please file an issue with OpenRCT2 on GitHub and provide latest save, and provide "
"information about what you did before the crash occurred.";
printf("%s\n", DumpFailedMessage);
if (!gOpenRCT2SilentBreakpad)
{
@ -65,7 +68,14 @@ static bool OnCrash(const wchar_t * dumpPath,
// Try to rename the files
wchar_t dumpFilePathNew[MAX_PATH];
swprintf_s(dumpFilePathNew, sizeof(dumpFilePathNew), L"%s%s(%s_%s).dmp", dumpPath, miniDumpId, _wszCommitSha1Short, _wszArchitecture);
swprintf_s(
dumpFilePathNew,
sizeof(dumpFilePathNew),
L"%s%s(%s_%s).dmp",
dumpPath,
miniDumpId,
_wszCommitSha1Short,
_wszArchitecture);
if (_wrename(dumpFilePath, dumpFilePathNew) == 0)
{
std::wcscpy(dumpFilePath, dumpFilePathNew);
@ -79,7 +89,7 @@ static bool OnCrash(const wchar_t * dumpPath,
wprintf(L"Commit: %s\n", _wszCommitSha1Short);
bool savedGameDumped = false;
utf8 * saveFilePathUTF8 = widechar_to_utf8(saveFilePath);
utf8* saveFilePathUTF8 = widechar_to_utf8(saveFilePath);
try
{
auto exporter = std::make_unique<S6Exporter>();
@ -87,7 +97,7 @@ static bool OnCrash(const wchar_t * dumpPath,
exporter->SaveGame(saveFilePathUTF8);
savedGameDumped = true;
}
catch (const std::exception &)
catch (const std::exception&)
{
}
free(saveFilePathUTF8);
@ -97,13 +107,11 @@ static bool OnCrash(const wchar_t * dumpPath,
return succeeded;
}
constexpr const wchar_t * MessageFormat = L"A crash has occurred and a dump was created at\n%s.\n\nPlease file an issue with OpenRCT2 on GitHub, and provide the dump and saved game there.\n\nVersion: %s\nCommit: %s";
constexpr const wchar_t* MessageFormat
= L"A crash has occurred and a dump was created at\n%s.\n\nPlease file an issue with OpenRCT2 on GitHub, and provide "
L"the dump and saved game there.\n\nVersion: %s\nCommit: %s";
wchar_t message[MAX_PATH * 2];
swprintf_s(message,
MessageFormat,
dumpFilePath,
WSZ(OPENRCT2_VERSION),
_wszCommitSha1Short);
swprintf_s(message, MessageFormat, dumpFilePath, WSZ(OPENRCT2_VERSION), _wszCommitSha1Short);
// Cannot use platform_show_messagebox here, it tries to set parent window already dead.
MessageBoxW(nullptr, message, WSZ(OPENRCT2_NAME), MB_OK | MB_ICONERROR);
@ -119,8 +127,9 @@ static bool OnCrash(const wchar_t * dumpPath,
{
files[numFiles++] = ILCreateFromPathW(saveFilePath);
}
if (pidl != nullptr) {
SHOpenFolderAndSelectItems(pidl, numFiles, (LPCITEMIDLIST *)files, 0);
if (pidl != nullptr)
{
SHOpenFolderAndSelectItems(pidl, numFiles, (LPCITEMIDLIST*)files, 0);
ILFree(pidl);
for (uint32_t i = 0; i < numFiles; i++)
{
@ -139,7 +148,7 @@ static std::wstring GetDumpDirectory()
char userDirectory[MAX_PATH];
platform_get_user_directory(userDirectory, nullptr, sizeof(userDirectory));
wchar_t * userDirectoryW = utf8_to_widechar(userDirectory);
wchar_t* userDirectoryW = utf8_to_widechar(userDirectory);
auto result = std::wstring(userDirectoryW);
free(userDirectoryW);
@ -147,7 +156,7 @@ static std::wstring GetDumpDirectory()
}
// Using non-null pipe name here lets breakpad try setting OOP crash handling
constexpr const wchar_t * PipeName = L"openrct2-bpad";
constexpr const wchar_t* PipeName = L"openrct2-bpad";
#endif // USE_BREAKPAD
@ -156,16 +165,9 @@ CExceptionHandler crash_init()
#ifdef USE_BREAKPAD
// Path must exist and be RW!
auto exHandler = new google_breakpad::ExceptionHandler(
GetDumpDirectory(),
0,
OnCrash,
0,
google_breakpad::ExceptionHandler::HANDLER_ALL,
MiniDumpWithDataSegs,
PipeName,
0);
GetDumpDirectory(), 0, OnCrash, 0, google_breakpad::ExceptionHandler::HANDLER_ALL, MiniDumpWithDataSegs, PipeName, 0);
return reinterpret_cast<CExceptionHandler>(exHandler);
#else // USE_BREAKPAD
#else // USE_BREAKPAD
return nullptr;
#endif // USE_BREAKPAD
}

View File

@ -10,9 +10,9 @@
#ifndef _OPENRCT2_CRASH_
#define _OPENRCT2_CRASH_
using CExceptionHandler = void *;
using CExceptionHandler = void*;
extern bool gOpenRCT2SilentBreakpad;
CExceptionHandler crash_init();
#endif /* _OPENRCT2_CRASH_ */
#endif /* _OPENRCT2_CRASH_ */

View File

@ -26,68 +26,81 @@
#ifndef NO_TTF
#include <fontconfig/fontconfig.h>
#endif // NO_TTF
#include <fnmatch.h>
#include <locale.h>
#include <pwd.h>
#include "../config/Config.h"
#include "../localisation/Language.h"
#include "../localisation/StringIds.h"
#include "../util/Util.h"
#include "platform.h"
uint16_t platform_get_locale_language(){
const char *langString = setlocale(LC_MESSAGES, "");
if(langString != nullptr){
#include <fnmatch.h>
#include <locale.h>
#include <pwd.h>
uint16_t platform_get_locale_language()
{
const char* langString = setlocale(LC_MESSAGES, "");
if (langString != nullptr)
{
// The locale has the following form:
// language[_territory[.codeset]][@modifier]
// (see https://www.gnu.org/software/libc/manual/html_node/Locale-Names.html)
// longest on my system is 29 with codeset and modifier, so 32 for the pattern should be more than enough
char pattern[32];
//strip the codeset and modifier part
// strip the codeset and modifier part
int32_t length = strlen(langString);
{
for(int32_t i = 0; i < length; ++i){
if(langString[i] == '.' || langString[i] == '@'){
for (int32_t i = 0; i < length; ++i)
{
if (langString[i] == '.' || langString[i] == '@')
{
length = i;
break;
}
}
} //end strip
memcpy(pattern, langString, length); //copy all until first '.' or '@'
} // end strip
memcpy(pattern, langString, length); // copy all until first '.' or '@'
pattern[length] = '\0';
//find _ if present
const char *strip = strchr(pattern, '_');
if(strip != nullptr){
// find _ if present
const char* strip = strchr(pattern, '_');
if (strip != nullptr)
{
// could also use '-', but '?' is more flexible. Maybe LanguagesDescriptors will change.
// pattern is now "language?territory"
pattern[strip - pattern] = '?';
}
// Iterate through all available languages
for(int32_t i = 1; i < LANGUAGE_COUNT; ++i){
if(!fnmatch(pattern, LanguagesDescriptors[i].locale, 0)){
for (int32_t i = 1; i < LANGUAGE_COUNT; ++i)
{
if (!fnmatch(pattern, LanguagesDescriptors[i].locale, 0))
{
return i;
}
}
//special cases :(
if(!fnmatch(pattern, "en_CA", 0)){
// special cases :(
if (!fnmatch(pattern, "en_CA", 0))
{
return LANGUAGE_ENGLISH_US;
}
else if (!fnmatch(pattern, "zh_CN", 0)){
else if (!fnmatch(pattern, "zh_CN", 0))
{
return LANGUAGE_CHINESE_SIMPLIFIED;
}
else if (!fnmatch(pattern, "zh_TW", 0)){
else if (!fnmatch(pattern, "zh_TW", 0))
{
return LANGUAGE_CHINESE_TRADITIONAL;
}
//no exact match found trying only language part
if(strip != nullptr){
// no exact match found trying only language part
if (strip != nullptr)
{
pattern[strip - pattern] = '*';
pattern[strip - pattern +1] = '\0'; // pattern is now "language*"
for(int32_t i = 1; i < LANGUAGE_COUNT; ++i){
if(!fnmatch(pattern, LanguagesDescriptors[i].locale, 0)){
pattern[strip - pattern + 1] = '\0'; // pattern is now "language*"
for (int32_t i = 1; i < LANGUAGE_COUNT; ++i)
{
if (!fnmatch(pattern, LanguagesDescriptors[i].locale, 0))
{
return i;
}
}
@ -96,38 +109,43 @@ uint16_t platform_get_locale_language(){
return LANGUAGE_ENGLISH_UK;
}
uint8_t platform_get_locale_currency(){
char *langstring = setlocale(LC_MONETARY, "");
uint8_t platform_get_locale_currency()
{
char* langstring = setlocale(LC_MONETARY, "");
if (langstring == nullptr) {
if (langstring == nullptr)
{
return platform_get_currency_value(NULL);
}
struct lconv *lc = localeconv();
struct lconv* lc = localeconv();
return platform_get_currency_value(lc->int_curr_symbol);
}
uint8_t platform_get_locale_measurement_format(){
// LC_MEASUREMENT is GNU specific.
#ifdef LC_MEASUREMENT
const char *langstring = setlocale(LC_MEASUREMENT, "");
#else
const char *langstring = setlocale(LC_ALL, "");
#endif
uint8_t platform_get_locale_measurement_format()
{
// LC_MEASUREMENT is GNU specific.
#ifdef LC_MEASUREMENT
const char* langstring = setlocale(LC_MEASUREMENT, "");
#else
const char* langstring = setlocale(LC_ALL, "");
#endif
if(langstring != nullptr){
//using https://en.wikipedia.org/wiki/Metrication#Chronology_and_status_of_conversion_by_country as reference
if(!fnmatch("*_US*", langstring, 0) || !fnmatch("*_MM*", langstring, 0) || !fnmatch("*_LR*", langstring, 0)){
if (langstring != nullptr)
{
// using https://en.wikipedia.org/wiki/Metrication#Chronology_and_status_of_conversion_by_country as reference
if (!fnmatch("*_US*", langstring, 0) || !fnmatch("*_MM*", langstring, 0) || !fnmatch("*_LR*", langstring, 0))
{
return MEASUREMENT_FORMAT_IMPERIAL;
}
}
return MEASUREMENT_FORMAT_METRIC;
}
bool platform_get_steam_path(utf8 * outPath, size_t outSize)
bool platform_get_steam_path(utf8* outPath, size_t outSize)
{
const char * steamRoot = getenv("STEAMROOT");
const char* steamRoot = getenv("STEAMROOT");
if (steamRoot != nullptr)
{
safe_strcpy(outPath, steamRoot, outSize);
@ -136,7 +154,7 @@ bool platform_get_steam_path(utf8 * outPath, size_t outSize)
}
char steamPath[1024] = { 0 };
const char * localSharePath = getenv("XDG_DATA_HOME");
const char* localSharePath = getenv("XDG_DATA_HOME");
if (localSharePath != nullptr)
{
safe_strcpy(steamPath, localSharePath, sizeof(steamPath));
@ -148,7 +166,7 @@ bool platform_get_steam_path(utf8 * outPath, size_t outSize)
}
}
const char * homeDir = getpwuid(getuid())->pw_dir;
const char* homeDir = getpwuid(getuid())->pw_dir;
if (homeDir != nullptr)
{
safe_strcpy(steamPath, homeDir, sizeof(steamPath));
@ -172,7 +190,7 @@ bool platform_get_steam_path(utf8 * outPath, size_t outSize)
}
#ifndef NO_TTF
bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer, size_t size)
bool platform_get_font_path(TTFFontDescriptor* font, utf8* buffer, size_t size)
{
assert(buffer != nullptr);
assert(font != nullptr);
@ -186,7 +204,7 @@ bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer, size_t size)
return false;
}
FcPattern* pat = FcNameParse((const FcChar8*) font->font_name);
FcPattern* pat = FcNameParse((const FcChar8*)font->font_name);
FcConfigSubstitute(config, pat, FcMatchPattern);
FcDefaultSubstitute(pat);
@ -205,8 +223,8 @@ bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer, size_t size)
// Western (sans-)serif font. We therefore ignore substitutions FontConfig provides,
// and instead rely on exact matches on the fonts predefined for each font family.
FcChar8* matched_font_face = nullptr;
if (FcPatternGetString(match, FC_FULLNAME, 0, &matched_font_face) == FcResultMatch &&
strcmp(font->font_name, (const char *) matched_font_face) != 0)
if (FcPatternGetString(match, FC_FULLNAME, 0, &matched_font_face) == FcResultMatch
&& strcmp(font->font_name, (const char*)matched_font_face) != 0)
{
log_verbose("FontConfig provided substitute font %s -- disregarding.", matched_font_face);
is_substitute = true;
@ -216,7 +234,7 @@ bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer, size_t size)
if (!is_substitute && FcPatternGetString(match, FC_FILE, 0, &filename) == FcResultMatch)
{
found = true;
safe_strcpy(buffer, (utf8*) filename, size);
safe_strcpy(buffer, (utf8*)filename, size);
log_verbose("FontConfig provided font %s", filename);
}

View File

@ -19,13 +19,13 @@ namespace Platform
// Android builds currently only read from /sdcard/openrct2*
switch (folder)
{
case SPECIAL_FOLDER::USER_CACHE:
case SPECIAL_FOLDER::USER_CONFIG:
case SPECIAL_FOLDER::USER_DATA:
case SPECIAL_FOLDER::USER_HOME:
return "/sdcard";
default:
return std::string();
case SPECIAL_FOLDER::USER_CACHE:
case SPECIAL_FOLDER::USER_CONFIG:
case SPECIAL_FOLDER::USER_DATA:
case SPECIAL_FOLDER::USER_HOME:
return "/sdcard";
default:
return std::string();
}
}
@ -44,6 +44,6 @@ namespace Platform
Guard::Assert(false, "GetCurrentExecutablePath() not implemented for Android.");
return std::string();
}
}
} // namespace Platform
#endif

View File

@ -13,18 +13,18 @@
#include <pwd.h>
#if defined(__FreeBSD__)
#include <stddef.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#endif // __FreeBSD__
#if defined(__linux__)
// for PATH_MAX
#include <linux/limits.h>
#endif // __linux__
#include "../OpenRCT2.h"
#include "../core/Path.hpp"
#include "../core/Util.hpp"
#include "../OpenRCT2.h"
#include "platform.h"
#include "Platform2.h"
#include "platform.h"
namespace Platform
{
@ -32,9 +32,9 @@ namespace Platform
{
switch (folder)
{
case SPECIAL_FOLDER::USER_CACHE:
case SPECIAL_FOLDER::USER_CONFIG:
case SPECIAL_FOLDER::USER_DATA:
case SPECIAL_FOLDER::USER_CACHE:
case SPECIAL_FOLDER::USER_CONFIG:
case SPECIAL_FOLDER::USER_DATA:
{
auto path = GetEnvironmentPath("XDG_CONFIG_HOME");
if (path.empty())
@ -44,17 +44,16 @@ namespace Platform
}
return path;
}
case SPECIAL_FOLDER::USER_HOME:
return GetHomePath();
default:
return std::string();
case SPECIAL_FOLDER::USER_HOME:
return GetHomePath();
default:
return std::string();
}
}
std::string GetDocsPath()
{
static const utf8 * searchLocations[] =
{
static const utf8* searchLocations[] = {
"./doc",
"/usr/share/doc/openrct2",
};
@ -71,8 +70,7 @@ namespace Platform
static std::string FindInstallPath()
{
static const char * SearchLocations[] =
{
static const char* SearchLocations[] = {
"../share/openrct2",
#ifdef ORCT2_RESOURCE_DIR
// defined in CMakeLists.txt
@ -160,10 +158,10 @@ namespace Platform
// If you are not using the port or package, you may have to change this line!
strlcpy(exePath, "/usr/local/bin/", sizeof(exePath));
#else
#error "Platform does not support full path exe retrieval"
#error "Platform does not support full path exe retrieval"
#endif
return exePath;
}
}
} // namespace Platform
#endif

View File

@ -9,14 +9,15 @@
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__)
#include <cstring>
#include <pwd.h>
#include <cstdlib>
#include <ctime>
#include "../core/String.hpp"
#include "Platform2.h"
#include "platform.h"
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <pwd.h>
namespace Platform
{
uint32_t GetTicks()
@ -24,12 +25,12 @@ namespace Platform
return platform_get_ticks();
}
std::string GetEnvironmentVariable(const std::string &name)
std::string GetEnvironmentVariable(const std::string& name)
{
return String::ToStd(getenv(name.c_str()));
}
std::string GetEnvironmentPath(const char * name)
std::string GetEnvironmentPath(const char* name)
{
auto value = getenv(name);
if (value == nullptr)
@ -90,14 +91,11 @@ namespace Platform
if (!hasChecked)
{
auto term = GetEnvironmentVariable("TERM");
isSupported =
term != "cons25" &&
term != "dumb" &&
term != "emacs";
isSupported = term != "cons25" && term != "dumb" && term != "emacs";
hasChecked = true;
}
return isSupported;
}
}
} // namespace Platform
#endif

View File

@ -13,22 +13,22 @@
#include <windows.h>
// Then the rest
#include <memory>
#include <datetimeapi.h>
#include <memory>
#include <shlobj.h>
#undef GetEnvironmentVariable
#if !defined(__MINGW32__) && ((NTDDI_VERSION >= NTDDI_VISTA) && !defined(_USING_V110_SDK71_) && !defined(_ATL_XP_TARGETING))
#define __USE_SHGETKNOWNFOLDERPATH__
#define __USE_GETDATEFORMATEX__
#define __USE_SHGETKNOWNFOLDERPATH__
#define __USE_GETDATEFORMATEX__
#else
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif
#include "../OpenRCT2.h"
#include "../core/Path.hpp"
#include "../core/String.hpp"
#include "../core/Util.hpp"
#include "../OpenRCT2.h"
#include "Platform2.h"
#include "platform.h"
@ -46,7 +46,7 @@ namespace Platform
return platform_get_ticks();
}
std::string GetEnvironmentVariable(const std::string &name)
std::string GetEnvironmentVariable(const std::string& name)
{
std::wstring result;
auto wname = String::ToUtf16(name);
@ -82,10 +82,10 @@ namespace Platform
{
switch (folder)
{
// We currently store everything under Documents/OpenRCT2
case SPECIAL_FOLDER::USER_CACHE:
case SPECIAL_FOLDER::USER_CONFIG:
case SPECIAL_FOLDER::USER_DATA:
// We currently store everything under Documents/OpenRCT2
case SPECIAL_FOLDER::USER_CACHE:
case SPECIAL_FOLDER::USER_CONFIG:
case SPECIAL_FOLDER::USER_DATA:
{
#ifdef __USE_SHGETKNOWNFOLDERPATH__
auto path = WIN32_GetKnownFolderPath(FOLDERID_Documents);
@ -98,7 +98,7 @@ namespace Platform
}
return path;
}
case SPECIAL_FOLDER::USER_HOME:
case SPECIAL_FOLDER::USER_HOME:
{
#ifdef __USE_SHGETKNOWNFOLDERPATH__
auto path = WIN32_GetKnownFolderPath(FOLDERID_Profile);
@ -115,8 +115,8 @@ namespace Platform
}
return path;
}
default:
return std::string();
default:
return std::string();
}
}
@ -151,7 +151,7 @@ namespace Platform
LONGLONG ll = Int32x32To64(timestamp, 10000000) + 116444736000000000;
FILETIME ft;
ft.dwLowDateTime = (DWORD) ll;
ft.dwLowDateTime = (DWORD)ll;
ft.dwHighDateTime = ll >> 32;
SYSTEMTIME st;
@ -199,7 +199,7 @@ namespace Platform
auto hModule = GetModuleHandleA("ntdll.dll");
if (hModule != nullptr)
{
using RtlGetVersionPtr = NTSTATUS(WINAPI *)(PRTL_OSVERSIONINFOW);
using RtlGetVersionPtr = NTSTATUS(WINAPI*)(PRTL_OSVERSIONINFOW);
auto fn = (RtlGetVersionPtr)GetProcAddress(hModule, "RtlGetVersion");
if (fn != nullptr)
{
@ -207,11 +207,9 @@ namespace Platform
rovi.dwOSVersionInfoSize = sizeof(rovi);
if (fn(&rovi) == 0)
{
if (rovi.dwMajorVersion > major ||
(rovi.dwMajorVersion == major &&
(rovi.dwMinorVersion > minor ||
(rovi.dwMinorVersion == minor &&
rovi.dwBuildNumber >= build))))
if (rovi.dwMajorVersion > major
|| (rovi.dwMajorVersion == major
&& (rovi.dwMinorVersion > minor || (rovi.dwMinorVersion == minor && rovi.dwBuildNumber >= build))))
{
result = true;
}
@ -265,11 +263,11 @@ namespace Platform
return isSupported;
}
#ifdef __USE_SHGETKNOWNFOLDERPATH__
#ifdef __USE_SHGETKNOWNFOLDERPATH__
static std::string WIN32_GetKnownFolderPath(REFKNOWNFOLDERID rfid)
{
std::string path;
wchar_t * wpath = nullptr;
wchar_t* wpath = nullptr;
if (SUCCEEDED(SHGetKnownFolderPath(rfid, KF_FLAG_CREATE, nullptr, &wpath)))
{
path = String::ToUtf8(std::wstring(wpath));
@ -300,8 +298,7 @@ namespace Platform
wExePathCapacity *= 2;
wExePath = std::make_unique<wchar_t[]>(wExePathCapacity);
size = GetModuleFileNameW(hModule, wExePath.get(), wExePathCapacity);
}
while (size >= wExePathCapacity);
} while (size >= wExePathCapacity);
return String::ToUtf8(wExePath.get());
}
} // namespace Platform

View File

@ -9,8 +9,8 @@
#if defined(__APPLE__) && defined(__MACH__)
#include "../core/Path.hpp"
#include "../OpenRCT2.h"
#include "../core/Path.hpp"
#include "Platform2.h"
// undefine `interface` and `abstract`, because it's causing conflicts with Objective-C's keywords
@ -27,17 +27,17 @@ namespace Platform
// macOS stores everything in ~/Library/Application Support/OpenRCT2
switch (folder)
{
case SPECIAL_FOLDER::USER_CACHE:
case SPECIAL_FOLDER::USER_CONFIG:
case SPECIAL_FOLDER::USER_DATA:
case SPECIAL_FOLDER::USER_CACHE:
case SPECIAL_FOLDER::USER_CONFIG:
case SPECIAL_FOLDER::USER_DATA:
{
auto home = GetFolderPath(SPECIAL_FOLDER::USER_HOME);
return Path::Combine(home, "Library/Application Support");
}
case SPECIAL_FOLDER::USER_HOME:
return GetHomePath();
default:
return std::string();
case SPECIAL_FOLDER::USER_HOME:
return GetHomePath();
default:
return std::string();
}
}
@ -48,9 +48,8 @@ namespace Platform
static std::string GetBundlePath()
{
@autoreleasepool
{
NSBundle * bundle = [NSBundle mainBundle];
@autoreleasepool {
NSBundle* bundle = [NSBundle mainBundle];
if (bundle)
{
auto resources = bundle.resourcePath.UTF8String;
@ -75,7 +74,7 @@ namespace Platform
auto exePath = GetCurrentExecutablePath();
auto exeDirectory = Path::GetDirectory(exePath);
path = Path::Combine(exeDirectory, "data");
NSString * nsPath = [NSString stringWithUTF8String:path.c_str()];
NSString* nsPath = [NSString stringWithUTF8String:path.c_str()];
if (![[NSFileManager defaultManager] fileExistsAtPath:nsPath])
{
path = GetBundlePath();

View File

@ -9,9 +9,10 @@
#pragma once
#include "../common.h"
#include <ctime>
#include <string>
#include "../common.h"
enum class SPECIAL_FOLDER
{
@ -24,14 +25,14 @@ enum class SPECIAL_FOLDER
namespace Platform
{
uint32_t GetTicks();
std::string GetEnvironmentVariable(const std::string &name);
std::string GetEnvironmentVariable(const std::string& name);
std::string GetFolderPath(SPECIAL_FOLDER folder);
std::string GetInstallPath();
std::string GetDocsPath();
std::string GetCurrentExecutablePath();
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__)
std::string GetEnvironmentPath(const char * name);
std::string GetEnvironmentPath(const char* name);
std::string GetHomePath();
#endif

View File

@ -16,8 +16,15 @@
#include <fcntl.h>
#include <fnmatch.h>
#ifndef __EMSCRIPTEN__
#include <fts.h>
#include <fts.h>
#endif
#include "../OpenRCT2.h"
#include "../config/Config.h"
#include "../localisation/Date.h"
#include "../localisation/Language.h"
#include "../util/Util.h"
#include "platform.h"
#include <libgen.h>
#include <locale.h>
#include <pwd.h>
@ -27,12 +34,6 @@
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include "../config/Config.h"
#include "../localisation/Date.h"
#include "../localisation/Language.h"
#include "../OpenRCT2.h"
#include "../util/Util.h"
#include "platform.h"
// The name of the mutex used to prevent multiple instances of the game from running
#define SINGLE_INSTANCE_MUTEX_NAME "openrct2.lock"
@ -40,11 +41,11 @@
static utf8 _userDataDirectoryPath[MAX_PATH] = { 0 };
void platform_get_date_utc(rct2_date *out_date)
void platform_get_date_utc(rct2_date* out_date)
{
assert(out_date != nullptr);
time_t rawtime;
struct tm * timeinfo;
struct tm* timeinfo;
time(&rawtime);
timeinfo = gmtime(&rawtime);
out_date->day = timeinfo->tm_mday;
@ -53,11 +54,11 @@ void platform_get_date_utc(rct2_date *out_date)
out_date->day_of_week = timeinfo->tm_wday;
}
void platform_get_time_utc(rct2_time *out_time)
void platform_get_time_utc(rct2_time* out_time)
{
assert(out_time != nullptr);
time_t rawtime;
struct tm * timeinfo;
struct tm* timeinfo;
time(&rawtime);
timeinfo = gmtime(&rawtime);
out_time->second = timeinfo->tm_sec;
@ -65,11 +66,11 @@ void platform_get_time_utc(rct2_time *out_time)
out_time->hour = timeinfo->tm_hour;
}
void platform_get_date_local(rct2_date *out_date)
void platform_get_date_local(rct2_date* out_date)
{
assert(out_date != nullptr);
time_t rawtime;
struct tm * timeinfo;
struct tm* timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
out_date->day = timeinfo->tm_mday;
@ -78,11 +79,11 @@ void platform_get_date_local(rct2_date *out_date)
out_date->day_of_week = timeinfo->tm_wday;
}
void platform_get_time_local(rct2_time *out_time)
void platform_get_time_local(rct2_time* out_time)
{
assert(out_time != nullptr);
time_t rawtime;
struct tm * timeinfo;
struct tm* timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
out_time->second = timeinfo->tm_sec;
@ -90,13 +91,14 @@ void platform_get_time_local(rct2_time *out_time)
out_time->hour = timeinfo->tm_hour;
}
static size_t platform_utf8_to_multibyte(const utf8 *path, char *buffer, size_t buffer_size)
static size_t platform_utf8_to_multibyte(const utf8* path, char* buffer, size_t buffer_size)
{
wchar_t *wpath = utf8_to_widechar(path);
wchar_t* wpath = utf8_to_widechar(path);
setlocale(LC_CTYPE, "UTF-8");
size_t len = wcstombs(NULL, wpath, 0);
bool truncated = false;
if (len > buffer_size - 1) {
if (len > buffer_size - 1)
{
truncated = true;
len = buffer_size - 1;
}
@ -108,7 +110,7 @@ static size_t platform_utf8_to_multibyte(const utf8 *path, char *buffer, size_t
return len;
}
bool platform_file_exists(const utf8 *path)
bool platform_file_exists(const utf8* path)
{
char buffer[MAX_PATH];
platform_utf8_to_multibyte(path, buffer, MAX_PATH);
@ -117,7 +119,7 @@ bool platform_file_exists(const utf8 *path)
return exists;
}
bool platform_directory_exists(const utf8 *path)
bool platform_directory_exists(const utf8* path)
{
char buffer[MAX_PATH];
platform_utf8_to_multibyte(path, buffer, MAX_PATH);
@ -131,7 +133,7 @@ bool platform_directory_exists(const utf8 *path)
return true;
}
bool platform_original_game_data_exists(const utf8 *path)
bool platform_original_game_data_exists(const utf8* path)
{
char buffer[MAX_PATH];
platform_utf8_to_multibyte(path, buffer, MAX_PATH);
@ -151,21 +153,25 @@ static mode_t openrct2_getumask()
return 0777 & ~mask; // Keep in mind 0777 is octal
}
bool platform_ensure_directory_exists(const utf8 *path)
bool platform_ensure_directory_exists(const utf8* path)
{
mode_t mask = openrct2_getumask();
char buffer[MAX_PATH];
platform_utf8_to_multibyte(path, buffer, MAX_PATH);
log_verbose("Create directory: %s", buffer);
for (char *p = buffer + 1; *p != '\0'; p++) {
if (*p == '/') {
for (char* p = buffer + 1; *p != '\0'; p++)
{
if (*p == '/')
{
// Temporarily truncate
*p = '\0';
log_verbose("mkdir(%s)", buffer);
if (mkdir(buffer, mask) != 0) {
if (errno != EEXIST) {
if (mkdir(buffer, mask) != 0)
{
if (errno != EEXIST)
{
return false;
}
}
@ -176,8 +182,10 @@ bool platform_ensure_directory_exists(const utf8 *path)
}
log_verbose("mkdir(%s)", buffer);
if (mkdir(buffer, mask) != 0) {
if (errno != EEXIST) {
if (mkdir(buffer, mask) != 0)
{
if (errno != EEXIST)
{
return false;
}
}
@ -185,26 +193,28 @@ bool platform_ensure_directory_exists(const utf8 *path)
return true;
}
bool platform_directory_delete(const utf8 *path)
bool platform_directory_delete(const utf8* path)
{
#ifdef _FTS_H
log_verbose("Recursively deleting directory %s", path);
FTS *ftsp;
FTS* ftsp;
FTSENT *p, *chp;
// fts_open only accepts non const paths, so we have to take a copy
char* ourPath = _strdup(path);
utf8* const patharray[2] = {ourPath, NULL};
if ((ftsp = fts_open(patharray, FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR, NULL)) == nullptr) {
utf8* const patharray[2] = { ourPath, NULL };
if ((ftsp = fts_open(patharray, FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR, NULL)) == nullptr)
{
log_error("fts_open returned NULL");
free(ourPath);
return false;
}
chp = fts_children(ftsp, 0);
if (chp == nullptr) {
if (chp == nullptr)
{
log_verbose("No files to traverse, deleting directory %s", path);
if (remove(path) != 0)
{
@ -214,13 +224,16 @@ bool platform_directory_delete(const utf8 *path)
return true; // No files to traverse
}
while ((p = fts_read(ftsp)) != nullptr) {
switch (p->fts_info) {
while ((p = fts_read(ftsp)) != nullptr)
{
switch (p->fts_info)
{
case FTS_DP: // Directory postorder, which means
// the directory is empty
case FTS_F: // File
if(remove(p->fts_path)) {
case FTS_F: // File
if (remove(p->fts_path))
{
log_error("Could not remove %s", p->fts_path);
fts_close(ftsp);
free(ourPath);
@ -244,7 +257,7 @@ bool platform_directory_delete(const utf8 *path)
return true;
}
utf8 * platform_get_absolute_path(const utf8 * relative_path, const utf8 * base_path)
utf8* platform_get_absolute_path(const utf8* relative_path, const utf8* base_path)
{
utf8 path[MAX_PATH];
@ -256,10 +269,9 @@ utf8 * platform_get_absolute_path(const utf8 * relative_path, const utf8 * base_
{
safe_strcpy(path, base_path, MAX_PATH);
}
return realpath(path,NULL);
return realpath(path, NULL);
}
bool platform_lock_single_instance()
{
char pidFilePath[MAX_PATH];
@ -273,11 +285,12 @@ bool platform_lock_single_instance()
// This is intentional.
int32_t pidFile = open(pidFilePath, O_CREAT | O_RDWR, 0666);
if (pidFile == -1) {
if (pidFile == -1)
{
log_warning("Cannot open lock file for writing.");
return false;
}
struct flock lock;
lock.l_start = 0;
@ -285,9 +298,10 @@ bool platform_lock_single_instance()
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
if (fcntl(pidFile, F_SETLK, &lock) == -1)
if (fcntl(pidFile, F_SETLK, &lock) == -1)
{
if (errno == EWOULDBLOCK) {
if (errno == EWOULDBLOCK)
{
log_warning("Another OpenRCT2 session has been found running.");
return false;
}
@ -297,26 +311,32 @@ bool platform_lock_single_instance()
return true;
}
int32_t platform_get_drives() {
int32_t platform_get_drives()
{
// POSIX systems do not know drives. Return 0.
return 0;
}
bool platform_file_copy(const utf8 *srcPath, const utf8 *dstPath, bool overwrite)
bool platform_file_copy(const utf8* srcPath, const utf8* dstPath, bool overwrite)
{
log_verbose("Copying %s to %s", srcPath, dstPath);
FILE *dstFile;
FILE* dstFile;
if (overwrite) {
if (overwrite)
{
dstFile = fopen(dstPath, "wb");
} else {
}
else
{
// Portability note: check your libc's support for "wbx"
dstFile = fopen(dstPath, "wbx");
}
if (dstFile == nullptr) {
if (errno == EEXIST) {
if (dstFile == nullptr)
{
if (errno == EEXIST)
{
log_warning("platform_file_copy: Not overwriting %s, because overwrite flag == false", dstPath);
return false;
}
@ -326,8 +346,9 @@ bool platform_file_copy(const utf8 *srcPath, const utf8 *dstPath, bool overwrite
}
// Open both files and check whether they are opened correctly
FILE *srcFile = fopen(srcPath, "rb");
if (srcFile == nullptr) {
FILE* srcFile = fopen(srcPath, "rb");
if (srcFile == nullptr)
{
fclose(dstFile);
log_error("Could not open source file %s for copying", srcPath);
return false;
@ -337,8 +358,9 @@ bool platform_file_copy(const utf8 *srcPath, const utf8 *dstPath, bool overwrite
size_t file_offset = 0;
// Copy file in FILE_BUFFER_SIZE-d chunks
char* buffer = (char*) malloc(FILE_BUFFER_SIZE);
while ((amount_read = fread(buffer, FILE_BUFFER_SIZE, 1, srcFile))) {
char* buffer = (char*)malloc(FILE_BUFFER_SIZE);
while ((amount_read = fread(buffer, FILE_BUFFER_SIZE, 1, srcFile)))
{
fwrite(buffer, amount_read, 1, dstFile);
file_offset += amount_read;
}
@ -356,38 +378,40 @@ bool platform_file_copy(const utf8 *srcPath, const utf8 *dstPath, bool overwrite
return true;
}
bool platform_file_move(const utf8 *srcPath, const utf8 *dstPath)
bool platform_file_move(const utf8* srcPath, const utf8* dstPath)
{
return rename(srcPath, dstPath) == 0;
}
bool platform_file_delete(const utf8 *path)
bool platform_file_delete(const utf8* path)
{
int32_t ret = unlink(path);
return ret == 0;
}
time_t platform_file_get_modified_time(const utf8* path){
time_t platform_file_get_modified_time(const utf8* path)
{
struct stat buf;
if (stat(path, &buf) == 0) {
if (stat(path, &buf) == 0)
{
return buf.st_mtime;
}
return 100;
}
uint8_t platform_get_locale_temperature_format(){
uint8_t platform_get_locale_temperature_format()
{
// LC_MEASUREMENT is GNU specific.
#ifdef LC_MEASUREMENT
const char *langstring = setlocale(LC_MEASUREMENT, "");
const char* langstring = setlocale(LC_MEASUREMENT, "");
#else
const char *langstring = setlocale(LC_ALL, "");
const char* langstring = setlocale(LC_ALL, "");
#endif
if(langstring != nullptr){
if (!fnmatch("*_US*", langstring, 0) ||
!fnmatch("*_BS*", langstring, 0) ||
!fnmatch("*_BZ*", langstring, 0) ||
!fnmatch("*_PW*", langstring, 0))
if (langstring != nullptr)
{
if (!fnmatch("*_US*", langstring, 0) || !fnmatch("*_BS*", langstring, 0) || !fnmatch("*_BZ*", langstring, 0)
|| !fnmatch("*_PW*", langstring, 0))
{
return TEMPERATURE_FORMAT_F;
}
@ -414,12 +438,16 @@ datetime64 platform_get_datetime_now_utc()
return utcNow;
}
utf8* platform_get_username() {
utf8* platform_get_username()
{
struct passwd* pw = getpwuid(getuid());
if (pw) {
if (pw)
{
return pw->pw_name;
} else {
}
else
{
return nullptr;
}
}
@ -427,9 +455,9 @@ utf8* platform_get_username() {
bool platform_process_is_elevated()
{
#ifndef __EMSCRIPTEN__
return (geteuid() == 0);
return (geteuid() == 0);
#else
return false;
return false;
#endif // __EMSCRIPTEN__
}

View File

@ -10,65 +10,69 @@
#include "../common.h"
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <unistd.h>
#include <unistd.h>
#endif
#include <stdlib.h>
#include <time.h>
#include "../Context.h"
#include "../Game.h"
#include "../OpenRCT2.h"
#include "../config/Config.h"
#include "../drawing/Drawing.h"
#include "../drawing/LightFX.h"
#include "../Game.h"
#include "../localisation/Currency.h"
#include "../localisation/Localisation.h"
#include "../util/Util.h"
#include "../world/Climate.h"
#include "platform.h"
#include <stdlib.h>
#include <time.h>
#ifdef __APPLE__
#include <mach/mach_time.h>
#include <AvailabilityMacros.h>
#ifndef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
#error Missing __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ define
#endif
#include <AvailabilityMacros.h>
#include <mach/mach_time.h>
#ifndef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
#error Missing __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ define
#endif
#endif
#if defined(__APPLE__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200)
static mach_timebase_info_data_t _mach_base_info = {};
static mach_timebase_info_data_t _mach_base_info = {};
#endif
#if !((defined (_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700) || (defined(__APPLE__) && defined(__MACH__)))
char * strndup(const char * src, size_t size)
#if !( \
(defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700) \
|| (defined(__APPLE__) && defined(__MACH__)))
char* strndup(const char* src, size_t size)
{
size_t len = strnlen(src, size);
char * dst = (char *)malloc(len + 1);
char* dst = (char*)malloc(len + 1);
if (dst == nullptr)
{
return nullptr;
}
dst = (char *)memcpy(dst, src, len);
dst = (char*)memcpy(dst, src, len);
dst[len] = '\0';
return dst;
}
#endif // !((defined (_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700) || (defined(__APPLE__) && defined(__MACH__)))
#endif // !((defined (_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700) ||
// (defined(__APPLE__) && defined(__MACH__)))
#ifdef _WIN32
static uint32_t _frequency = 0;
static uint32_t _frequency = 0;
static LARGE_INTEGER _entryTimestamp;
#endif
using update_palette_func = void (*)(const uint8_t *, int32_t, int32_t);
using update_palette_func = void (*)(const uint8_t*, int32_t, int32_t);
rct_palette_entry gPalette[256];
void platform_update_palette(const uint8_t * colours, int32_t start_index, int32_t num_colours)
void platform_update_palette(const uint8_t* colours, int32_t start_index, int32_t num_colours)
{
colours += start_index * 4;
@ -95,18 +99,18 @@ void platform_update_palette(const uint8_t * colours, int32_t start_index, int32
}
}
gPalette[i].red = r;
gPalette[i].red = r;
gPalette[i].green = g;
gPalette[i].blue = b;
gPalette[i].blue = b;
gPalette[i].alpha = 0;
colours += 4;
}
// Fix #1749 and #6535: rainbow path, donut shop and pause button contain black spots that should be white.
gPalette[255].alpha = 0;
gPalette[255].red = 255;
gPalette[255].red = 255;
gPalette[255].green = 255;
gPalette[255].blue = 255;
gPalette[255].blue = 255;
if (!gOpenRCT2Headless)
{
@ -181,7 +185,7 @@ void platform_sleep(uint32_t ms)
#endif
}
uint8_t platform_get_currency_value(const char * currCode)
uint8_t platform_get_currency_value(const char* currCode)
{
if (currCode == nullptr || strlen(currCode) < 3)
{

View File

@ -19,26 +19,28 @@
#include <windows.h>
// Then the rest
#include "../OpenRCT2.h"
#include "../Version.h"
#include "../config/Config.h"
#include "../core/Util.hpp"
#include "../localisation/Date.h"
#include "../localisation/Language.h"
#include "../rct2/RCT2.h"
#include "../util/Util.h"
#include "platform.h"
#include <lmcons.h>
#include <psapi.h>
#include <shlobj.h>
#include <sys/stat.h>
#include "../config/Config.h"
#include "../core/Util.hpp"
#include "../localisation/Date.h"
#include "../localisation/Language.h"
#include "../OpenRCT2.h"
#include "../rct2/RCT2.h"
#include "../util/Util.h"
#include "../Version.h"
#include "platform.h"
// Native resource IDs
#include "../../../resources/resource.h"
// Enable visual styles
#pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#pragma comment( \
linker, \
"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
// The name of the mutex used to prevent multiple instances of the game from running
#define SINGLE_INSTANCE_MUTEX_NAME "RollerCoaster Tycoon 2_GSKMUTEX"
@ -49,13 +51,14 @@ static HMODULE _dllModule = nullptr;
static HMODULE plaform_get_dll_module()
{
if (_dllModule == nullptr) {
if (_dllModule == nullptr)
{
_dllModule = GetModuleHandle(NULL);
}
return _dllModule;
}
void platform_get_date_local(rct2_date *out_date)
void platform_get_date_local(rct2_date* out_date)
{
assert(out_date != nullptr);
SYSTEMTIME systime;
@ -67,7 +70,7 @@ void platform_get_date_local(rct2_date *out_date)
out_date->day_of_week = systime.wDayOfWeek;
}
void platform_get_time_local(rct2_time *out_time)
void platform_get_time_local(rct2_time* out_time)
{
assert(out_time != nullptr);
SYSTEMTIME systime;
@ -77,24 +80,24 @@ void platform_get_time_local(rct2_time *out_time)
out_time->second = systime.wSecond;
}
bool platform_file_exists(const utf8 *path)
bool platform_file_exists(const utf8* path)
{
wchar_t *wPath = utf8_to_widechar(path);
wchar_t* wPath = utf8_to_widechar(path);
DWORD result = GetFileAttributesW(wPath);
DWORD error = GetLastError();
free(wPath);
return !(result == INVALID_FILE_ATTRIBUTES && (error == ERROR_FILE_NOT_FOUND || error == ERROR_PATH_NOT_FOUND));
}
bool platform_directory_exists(const utf8 *path)
bool platform_directory_exists(const utf8* path)
{
wchar_t *wPath = utf8_to_widechar(path);
wchar_t* wPath = utf8_to_widechar(path);
DWORD dwAttrib = GetFileAttributesW(wPath);
free(wPath);
return dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}
bool platform_original_game_data_exists(const utf8 *path)
bool platform_original_game_data_exists(const utf8* path)
{
utf8 checkPath[MAX_PATH];
safe_strcpy(checkPath, path, MAX_PATH);
@ -103,22 +106,22 @@ bool platform_original_game_data_exists(const utf8 *path)
return platform_file_exists(checkPath);
}
bool platform_ensure_directory_exists(const utf8 *path)
bool platform_ensure_directory_exists(const utf8* path)
{
if (platform_directory_exists(path))
return 1;
wchar_t *wPath = utf8_to_widechar(path);
wchar_t* wPath = utf8_to_widechar(path);
BOOL success = CreateDirectoryW(wPath, NULL);
free(wPath);
return success == TRUE;
}
bool platform_directory_delete(const utf8 *path)
bool platform_directory_delete(const utf8* path)
{
wchar_t pszFrom[MAX_PATH];
wchar_t *wPath = utf8_to_widechar(path);
wchar_t* wPath = utf8_to_widechar(path);
wcsncpy(pszFrom, wPath, MAX_PATH);
// Needs to be double-null terminated for some weird reason
@ -126,15 +129,15 @@ bool platform_directory_delete(const utf8 *path)
free(wPath);
SHFILEOPSTRUCTW fileop;
fileop.hwnd = nullptr; // no status display
fileop.wFunc = FO_DELETE; // delete operation
fileop.pFrom = pszFrom; // source file name as double null terminated string
fileop.pTo = nullptr; // no destination needed
fileop.fFlags = FOF_NOCONFIRMATION | FOF_SILENT; // do not prompt the user
fileop.hwnd = nullptr; // no status display
fileop.wFunc = FO_DELETE; // delete operation
fileop.pFrom = pszFrom; // source file name as double null terminated string
fileop.pTo = nullptr; // no destination needed
fileop.fFlags = FOF_NOCONFIRMATION | FOF_SILENT; // do not prompt the user
fileop.fAnyOperationsAborted = FALSE;
fileop.lpszProgressTitle = nullptr;
fileop.hNameMappings = nullptr;
fileop.lpszProgressTitle = nullptr;
fileop.hNameMappings = nullptr;
int32_t ret = SHFileOperationW(&fileop);
return (ret == 0);
@ -146,14 +149,17 @@ bool platform_lock_single_instance()
// Check if operating system mutex exists
mutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, SINGLE_INSTANCE_MUTEX_NAME);
if (mutex == nullptr) {
if (mutex == nullptr)
{
// Create new mutex
status = CreateMutex(NULL, FALSE, SINGLE_INSTANCE_MUTEX_NAME);
if (status == nullptr)
log_error("unable to create mutex\n");
return true;
} else {
}
else
{
// Already running
CloseHandle(mutex);
return false;
@ -165,37 +171,37 @@ int32_t platform_get_drives()
return GetLogicalDrives();
}
bool platform_file_copy(const utf8 *srcPath, const utf8 *dstPath, bool overwrite)
bool platform_file_copy(const utf8* srcPath, const utf8* dstPath, bool overwrite)
{
wchar_t *wSrcPath = utf8_to_widechar(srcPath);
wchar_t *wDstPath = utf8_to_widechar(dstPath);
wchar_t* wSrcPath = utf8_to_widechar(srcPath);
wchar_t* wDstPath = utf8_to_widechar(dstPath);
BOOL success = CopyFileW(wSrcPath, wDstPath, overwrite ? FALSE : TRUE);
free(wSrcPath);
free(wDstPath);
return success == TRUE;
}
bool platform_file_move(const utf8 *srcPath, const utf8 *dstPath)
bool platform_file_move(const utf8* srcPath, const utf8* dstPath)
{
wchar_t *wSrcPath = utf8_to_widechar(srcPath);
wchar_t *wDstPath = utf8_to_widechar(dstPath);
wchar_t* wSrcPath = utf8_to_widechar(srcPath);
wchar_t* wDstPath = utf8_to_widechar(dstPath);
BOOL success = MoveFileW(wSrcPath, wDstPath);
free(wSrcPath);
free(wDstPath);
return success == TRUE;
}
bool platform_file_delete(const utf8 *path)
bool platform_file_delete(const utf8* path)
{
wchar_t *wPath = utf8_to_widechar(path);
wchar_t* wPath = utf8_to_widechar(path);
BOOL success = DeleteFileW(wPath);
free(wPath);
return success == TRUE;
}
bool platform_get_steam_path(utf8 * outPath, size_t outSize)
bool platform_get_steam_path(utf8* outPath, size_t outSize)
{
wchar_t * wSteamPath;
wchar_t* wSteamPath;
HKEY hKey;
DWORD type, size;
LRESULT result;
@ -214,7 +220,7 @@ bool platform_get_steam_path(utf8 * outPath, size_t outSize)
result = RegQueryValueExW(hKey, L"SteamPath", 0, &type, (LPBYTE)wSteamPath, &size);
if (result == ERROR_SUCCESS)
{
utf8 * utf8SteamPath = widechar_to_utf8(wSteamPath);
utf8* utf8SteamPath = widechar_to_utf8(wSteamPath);
safe_strcpy(outPath, utf8SteamPath, outSize);
safe_strcat_path(outPath, "steamapps\\common", outSize);
free(utf8SteamPath);
@ -233,50 +239,61 @@ uint16_t platform_get_locale_language()
{
CHAR langCode[4];
if (GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_SABBREVLANGNAME,
(LPSTR)&langCode,
sizeof(langCode)) == 0){
if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SABBREVLANGNAME, (LPSTR)&langCode, sizeof(langCode)) == 0)
{
return LANGUAGE_UNDEFINED;
}
if (strcmp(langCode, "ENG") == 0){
if (strcmp(langCode, "ENG") == 0)
{
return LANGUAGE_ENGLISH_UK;
}
else if (strcmp(langCode, "ENU") == 0){
else if (strcmp(langCode, "ENU") == 0)
{
return LANGUAGE_ENGLISH_US;
}
else if (strcmp(langCode, "DEU") == 0){
else if (strcmp(langCode, "DEU") == 0)
{
return LANGUAGE_GERMAN;
}
else if (strcmp(langCode, "NLD") == 0){
else if (strcmp(langCode, "NLD") == 0)
{
return LANGUAGE_DUTCH;
}
else if (strcmp(langCode, "FRA") == 0){
else if (strcmp(langCode, "FRA") == 0)
{
return LANGUAGE_FRENCH;
}
else if (strcmp(langCode, "HUN") == 0){
else if (strcmp(langCode, "HUN") == 0)
{
return LANGUAGE_HUNGARIAN;
}
else if (strcmp(langCode, "PLK") == 0){
else if (strcmp(langCode, "PLK") == 0)
{
return LANGUAGE_POLISH;
}
else if (strcmp(langCode, "ESP") == 0){
else if (strcmp(langCode, "ESP") == 0)
{
return LANGUAGE_SPANISH;
}
else if (strcmp(langCode, "SVE") == 0){
else if (strcmp(langCode, "SVE") == 0)
{
return LANGUAGE_SWEDISH;
}
else if (strcmp(langCode, "ITA") == 0){
else if (strcmp(langCode, "ITA") == 0)
{
return LANGUAGE_ITALIAN;
}
else if (strcmp(langCode, "POR") == 0){
else if (strcmp(langCode, "POR") == 0)
{
return LANGUAGE_PORTUGUESE_BR;
}
else if (strcmp(langCode, "FIN") == 0){
else if (strcmp(langCode, "FIN") == 0)
{
return LANGUAGE_FINNISH;
}
else if (strcmp(langCode, "NOR") == 0){
else if (strcmp(langCode, "NOR") == 0)
{
return LANGUAGE_NORWEGIAN;
}
else if (strcmp(langCode, "DAN") == 0)
@ -290,16 +307,19 @@ time_t platform_file_get_modified_time(const utf8* path)
{
WIN32_FILE_ATTRIBUTE_DATA data;
wchar_t *wPath = utf8_to_widechar(path);
wchar_t* wPath = utf8_to_widechar(path);
BOOL result = GetFileAttributesExW(wPath, GetFileExInfoStandard, &data);
free(wPath);
if (result) {
if (result)
{
ULARGE_INTEGER ull;
ull.LowPart = data.ftLastWriteTime.dwLowDateTime;
ull.HighPart = data.ftLastWriteTime.dwHighDateTime;
return ull.QuadPart / 10000000ULL - 11644473600ULL;
} else {
}
else
{
return 0;
}
}
@ -307,11 +327,8 @@ time_t platform_file_get_modified_time(const utf8* path)
uint8_t platform_get_locale_currency()
{
CHAR currCode[4];
if (GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_SINTLSYMBOL,
(LPSTR)&currCode,
sizeof(currCode)) == 0
) {
if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SINTLSYMBOL, (LPSTR)&currCode, sizeof(currCode)) == 0)
{
return platform_get_currency_value(NULL);
}
@ -321,20 +338,20 @@ uint8_t platform_get_locale_currency()
uint8_t 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
) {
if (GetLocaleInfo(
LOCALE_USER_DEFAULT, LOCALE_IMEASURE | LOCALE_RETURN_NUMBER, (LPSTR)&measurement_system, sizeof(measurement_system))
== 0)
{
return MEASUREMENT_FORMAT_METRIC;
}
switch (measurement_system) {
case 1:
return MEASUREMENT_FORMAT_IMPERIAL;
case 0:
default:
return MEASUREMENT_FORMAT_METRIC;
switch (measurement_system)
{
case 1:
return MEASUREMENT_FORMAT_IMPERIAL;
case 0:
default:
return MEASUREMENT_FORMAT_METRIC;
}
}
@ -344,16 +361,13 @@ uint8_t platform_get_locale_temperature_format()
// GetLocaleInfo will set fahrenheit to 1 if the locale on this computer
// uses the United States measurement system or 0 otherwise.
if (GetLocaleInfo(LOCALE_USER_DEFAULT,
LOCALE_IMEASURE | LOCALE_RETURN_NUMBER,
(LPSTR)&fahrenheit,
sizeof(fahrenheit)) == 0
) {
if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IMEASURE | LOCALE_RETURN_NUMBER, (LPSTR)&fahrenheit, sizeof(fahrenheit)) == 0)
{
// Assume celsius by default if function call fails
return TEMPERATURE_FORMAT_C;
}
if(fahrenheit)
if (fahrenheit)
return TEMPERATURE_FORMAT_F;
else
return TEMPERATURE_FORMAT_C;
@ -376,7 +390,15 @@ uint8_t platform_get_locale_date_format()
//
wchar_t first[sizeof(dateFormat)];
wchar_t second[sizeof(dateFormat)];
if (swscanf_s(dateFormat, L"%l[dyM]%*l[^dyM]%l[dyM]%*l[^dyM]%*l[dyM]", first, (uint32_t)Util::CountOf(first), second, (uint32_t)Util::CountOf(second)) != 2) {
if (swscanf_s(
dateFormat,
L"%l[dyM]%*l[^dyM]%l[dyM]%*l[^dyM]%*l[dyM]",
first,
(uint32_t)Util::CountOf(first),
second,
(uint32_t)Util::CountOf(second))
!= 2)
{
return DATE_FORMAT_DAY_MONTH_YEAR;
}
@ -390,10 +412,12 @@ uint8_t platform_get_locale_date_format()
}
else if (wcsncmp(L"y", first, 1) == 0)
{
if (wcsncmp(L"d", second, 1) == 0) {
if (wcsncmp(L"d", second, 1) == 0)
{
return DATE_FORMAT_YEAR_DAY_MONTH;
}
else {
else
{
// Closest possible option
return DATE_FORMAT_YEAR_MONTH_DAY;
}
@ -404,14 +428,14 @@ uint8_t platform_get_locale_date_format()
}
#ifndef NO_TTF
bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer, size_t size)
bool platform_get_font_path(TTFFontDescriptor* font, utf8* buffer, size_t size)
{
#if !defined(__MINGW32__) && ((NTDDI_VERSION >= NTDDI_VISTA) && !defined(_USING_V110_SDK71_) && !defined(_ATL_XP_TARGETING))
wchar_t *fontFolder;
wchar_t* fontFolder;
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Fonts, 0, NULL, &fontFolder)))
{
// Convert wchar to utf8, then copy the font folder path to the buffer.
utf8 *outPathTemp = widechar_to_utf8(fontFolder);
utf8* outPathTemp = widechar_to_utf8(fontFolder);
safe_strcpy(buffer, outPathTemp, size);
free(outPathTemp);
@ -434,13 +458,13 @@ bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer, size_t size)
}
#endif // NO_TTF
utf8 * platform_get_absolute_path(const utf8 * relativePath, const utf8 * basePath)
utf8* platform_get_absolute_path(const utf8* relativePath, const utf8* basePath)
{
utf8 path[MAX_PATH];
safe_strcpy(path, basePath, sizeof(path));
safe_strcat_path(path, relativePath, sizeof(path));
wchar_t * pathW = utf8_to_widechar(path);
wchar_t* pathW = utf8_to_widechar(path);
wchar_t fullPathW[MAX_PATH];
DWORD fullPathLen = GetFullPathNameW(pathW, (DWORD)Util::CountOf(fullPathW), fullPathW, NULL);
@ -472,7 +496,8 @@ utf8* platform_get_username()
static char username[UNLEN + 1];
DWORD usernameLength = UNLEN + 1;
if (!GetUserName(username, &usernameLength)) {
if (!GetUserName(username, &usernameLength))
{
return nullptr;
}
@ -483,14 +508,17 @@ bool platform_process_is_elevated()
{
BOOL isElevated = FALSE;
HANDLE hToken = nullptr;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
TOKEN_ELEVATION Elevation;
DWORD tokenSize = sizeof(TOKEN_ELEVATION);
if (GetTokenInformation(hToken, TokenElevation, &Elevation, sizeof(Elevation), &tokenSize)) {
if (GetTokenInformation(hToken, TokenElevation, &Elevation, sizeof(Elevation), &tokenSize))
{
isElevated = Elevation.TokenIsElevated;
}
}
if (hToken) {
if (hToken)
{
CloseHandle(hToken);
}
return isElevated;
@ -500,27 +528,23 @@ bool platform_process_is_elevated()
// File association setup
///////////////////////////////////////////////////////////////////////////////
#define SOFTWARE_CLASSES L"Software\\Classes"
#define MUI_CACHE L"Local Settings\\Software\\Microsoft\\Windows\\Shell\\MuiCache"
#define SOFTWARE_CLASSES L"Software\\Classes"
#define MUI_CACHE L"Local Settings\\Software\\Microsoft\\Windows\\Shell\\MuiCache"
static void get_progIdName(wchar_t *dst, const utf8 *extension)
static void get_progIdName(wchar_t* dst, const utf8* extension)
{
utf8 progIdName[128];
safe_strcpy(progIdName, OPENRCT2_NAME, sizeof(progIdName));
safe_strcat(progIdName, extension, sizeof(progIdName));
wchar_t *progIdNameW = utf8_to_widechar(progIdName);
wchar_t* progIdNameW = utf8_to_widechar(progIdName);
lstrcpyW(dst, progIdNameW);
free(progIdNameW);
}
static bool windows_setup_file_association(
const utf8 * extension,
const utf8 * fileTypeText,
const utf8 * commandText,
const utf8 * commandArgs,
const uint32_t iconIndex
) {
const utf8* extension, const utf8* fileTypeText, const utf8* commandText, const utf8* commandArgs, const uint32_t iconIndex)
{
wchar_t exePathW[MAX_PATH];
wchar_t dllPathW[MAX_PATH];
@ -529,10 +553,10 @@ static bool windows_setup_file_association(
GetModuleFileNameW(NULL, exePathW, sizeof(exePathW));
GetModuleFileNameW(plaform_get_dll_module(), dllPathW, sizeof(dllPathW));
wchar_t *extensionW = utf8_to_widechar(extension);
wchar_t *fileTypeTextW = utf8_to_widechar(fileTypeText);
wchar_t *commandTextW = utf8_to_widechar(commandText);
wchar_t *commandArgsW = utf8_to_widechar(commandArgs);
wchar_t* extensionW = utf8_to_widechar(extension);
wchar_t* fileTypeTextW = utf8_to_widechar(fileTypeText);
wchar_t* commandTextW = utf8_to_widechar(commandText);
wchar_t* commandArgsW = utf8_to_widechar(commandArgs);
wchar_t progIdNameW[128];
get_progIdName(progIdNameW, extension);
@ -542,38 +566,45 @@ static bool windows_setup_file_association(
HKEY hRootKey = nullptr;
// [HKEY_CURRENT_USER\Software\Classes]
if (RegOpenKeyW(HKEY_CURRENT_USER, SOFTWARE_CLASSES, &hRootKey) != ERROR_SUCCESS) {
if (RegOpenKeyW(HKEY_CURRENT_USER, SOFTWARE_CLASSES, &hRootKey) != ERROR_SUCCESS)
{
goto fail;
}
// [hRootKey\.ext]
if (RegSetValueW(hRootKey, extensionW, REG_SZ, progIdNameW, 0) != ERROR_SUCCESS) {
if (RegSetValueW(hRootKey, extensionW, REG_SZ, progIdNameW, 0) != ERROR_SUCCESS)
{
goto fail;
}
if (RegCreateKeyW(hRootKey, progIdNameW, &hKey) != ERROR_SUCCESS) {
if (RegCreateKeyW(hRootKey, progIdNameW, &hKey) != ERROR_SUCCESS)
{
goto fail;
}
// [hRootKey\OpenRCT2.ext]
if (RegSetValueW(hKey, NULL, REG_SZ, fileTypeTextW, 0) != ERROR_SUCCESS) {
if (RegSetValueW(hKey, NULL, REG_SZ, fileTypeTextW, 0) != ERROR_SUCCESS)
{
goto fail;
}
// [hRootKey\OpenRCT2.ext\DefaultIcon]
wchar_t szIconW[MAX_PATH];
printResult = swprintf_s(szIconW, MAX_PATH, L"\"%s\",%d", dllPathW, iconIndex);
assert(printResult >= 0);
if (RegSetValueW(hKey, L"DefaultIcon", REG_SZ, szIconW, 0) != ERROR_SUCCESS) {
if (RegSetValueW(hKey, L"DefaultIcon", REG_SZ, szIconW, 0) != ERROR_SUCCESS)
{
goto fail;
}
// [hRootKey\OpenRCT2.sv6\shell]
if (RegSetValueW(hKey, L"shell", REG_SZ, L"open", 0) != ERROR_SUCCESS) {
if (RegSetValueW(hKey, L"shell", REG_SZ, L"open", 0) != ERROR_SUCCESS)
{
goto fail;
}
// [hRootKey\OpenRCT2.sv6\shell\open]
if (RegSetValueW(hKey, L"shell\\open", REG_SZ, commandTextW, 0) != ERROR_SUCCESS) {
if (RegSetValueW(hKey, L"shell\\open", REG_SZ, commandTextW, 0) != ERROR_SUCCESS)
{
goto fail;
}
@ -581,7 +612,8 @@ static bool windows_setup_file_association(
wchar_t szCommandW[MAX_PATH];
printResult = swprintf_s(szCommandW, MAX_PATH, L"\"%s\" %s", exePathW, commandArgsW);
assert(printResult >= 0);
if (RegSetValueW(hKey, L"shell\\open\\command", REG_SZ, szCommandW, 0) != ERROR_SUCCESS) {
if (RegSetValueW(hKey, L"shell\\open\\command", REG_SZ, szCommandW, 0) != ERROR_SUCCESS)
{
goto fail;
}
@ -596,11 +628,12 @@ fail:
return result;
}
static void windows_remove_file_association(const utf8 * extension)
static void windows_remove_file_association(const utf8* extension)
{
// [HKEY_CURRENT_USER\Software\Classes]
HKEY hRootKey;
if (RegOpenKeyW(HKEY_CURRENT_USER, SOFTWARE_CLASSES, &hRootKey) == ERROR_SUCCESS) {
if (RegOpenKeyW(HKEY_CURRENT_USER, SOFTWARE_CLASSES, &hRootKey) == ERROR_SUCCESS)
{
// [hRootKey\.ext]
RegDeleteTreeA(hRootKey, extension);
@ -616,10 +649,10 @@ static void windows_remove_file_association(const utf8 * extension)
void platform_setup_file_associations()
{
// Setup file extensions
windows_setup_file_association(".sc4", "RCT1 Scenario (.sc4)", "Play", "\"%1\"", 0);
windows_setup_file_association(".sc6", "RCT2 Scenario (.sc6)", "Play", "\"%1\"", 0);
windows_setup_file_association(".sv4", "RCT1 Saved Game (.sc4)", "Play", "\"%1\"", 0);
windows_setup_file_association(".sv6", "RCT2 Saved Game (.sv6)", "Play", "\"%1\"", 0);
windows_setup_file_association(".sc4", "RCT1 Scenario (.sc4)", "Play", "\"%1\"", 0);
windows_setup_file_association(".sc6", "RCT2 Scenario (.sc6)", "Play", "\"%1\"", 0);
windows_setup_file_association(".sv4", "RCT1 Saved Game (.sc4)", "Play", "\"%1\"", 0);
windows_setup_file_association(".sv6", "RCT2 Saved Game (.sv6)", "Play", "\"%1\"", 0);
windows_setup_file_association(".td4", "RCT1 Track Design (.td4)", "Install", "\"%1\"", 0);
windows_setup_file_association(".td6", "RCT2 Track Design (.td6)", "Install", "\"%1\"", 0);
@ -653,23 +686,29 @@ bool platform_setup_uri_protocol()
// [HKEY_CURRENT_USER\Software\Classes]
HKEY hRootKey;
if (RegOpenKeyW(HKEY_CURRENT_USER, SOFTWARE_CLASSES, &hRootKey) == ERROR_SUCCESS) {
if (RegOpenKeyW(HKEY_CURRENT_USER, SOFTWARE_CLASSES, &hRootKey) == ERROR_SUCCESS)
{
// [hRootKey\openrct2]
HKEY hClassKey;
if (RegCreateKeyA(hRootKey, "openrct2", &hClassKey) == ERROR_SUCCESS) {
if (RegSetValueA(hClassKey, NULL, REG_SZ, "URL:openrct2", 0) == ERROR_SUCCESS) {
if (RegSetKeyValueA(hClassKey, NULL, "URL Protocol", REG_SZ, "", 0) == ERROR_SUCCESS) {
if (RegCreateKeyA(hRootKey, "openrct2", &hClassKey) == ERROR_SUCCESS)
{
if (RegSetValueA(hClassKey, NULL, REG_SZ, "URL:openrct2", 0) == ERROR_SUCCESS)
{
if (RegSetKeyValueA(hClassKey, NULL, "URL Protocol", REG_SZ, "", 0) == ERROR_SUCCESS)
{
// [hRootKey\openrct2\shell\open\command]
wchar_t exePath[MAX_PATH];
GetModuleFileNameW(NULL, exePath, MAX_PATH);
wchar_t buffer[512];
swprintf_s(buffer, sizeof(buffer), L"\"%s\" handle-uri \"%%1\"", exePath);
if (RegSetValueW(hClassKey, L"shell\\open\\command", REG_SZ, buffer, 0) == ERROR_SUCCESS) {
if (RegSetValueW(hClassKey, L"shell\\open\\command", REG_SZ, buffer, 0) == ERROR_SUCCESS)
{
// Not compulsory, but gives the application a nicer name
// [HKEY_CURRENT_USER\SOFTWARE\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache]
HKEY hMuiCacheKey;
if (RegCreateKeyW(hRootKey, MUI_CACHE, &hMuiCacheKey) == ERROR_SUCCESS) {
if (RegCreateKeyW(hRootKey, MUI_CACHE, &hMuiCacheKey) == ERROR_SUCCESS)
{
swprintf_s(buffer, sizeof(buffer), L"%s.FriendlyAppName", exePath);
// mingw-w64 used to define RegSetKeyValueW's signature incorrectly
// You need at least mingw-w64 5.0 including this commit:

View File

@ -26,76 +26,86 @@
void macos_disallow_automatic_window_tabbing()
{
@autoreleasepool {
if ([NSWindow respondsToSelector:@selector(setAllowsAutomaticWindowTabbing:)]) {
if ([NSWindow respondsToSelector:@selector(setAllowsAutomaticWindowTabbing:)])
{
[NSWindow setAllowsAutomaticWindowTabbing:NO];
}
}
}
utf8* macos_str_decomp_to_precomp(utf8 *input)
utf8* macos_str_decomp_to_precomp(utf8* input)
{
@autoreleasepool
{
if (input == NULL) {
@autoreleasepool {
if (input == NULL)
{
return NULL;
}
NSString *inputDecomp = [NSString stringWithUTF8String:input];
NSString* inputDecomp = [NSString stringWithUTF8String:input];
return strdup([inputDecomp.precomposedStringWithCanonicalMapping cStringUsingEncoding:NSUTF8StringEncoding]);
}
}
#ifndef NO_TTF
bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer, size_t size)
bool platform_get_font_path(TTFFontDescriptor* font, utf8* buffer, size_t size)
{
@autoreleasepool
{
CTFontDescriptorRef fontRef = CTFontDescriptorCreateWithNameAndSize((CFStringRef)[NSString stringWithUTF8String:font->font_name], 0.0);
@autoreleasepool {
CTFontDescriptorRef fontRef
= CTFontDescriptorCreateWithNameAndSize((CFStringRef)[NSString stringWithUTF8String:font->font_name], 0.0);
CFURLRef url = (CFURLRef)CTFontDescriptorCopyAttribute(fontRef, kCTFontURLAttribute);
if (url) {
NSString *fontPath = [NSString stringWithString:[(NSURL *)CFBridgingRelease(url) path]];
if (url)
{
NSString* fontPath = [NSString stringWithString:[(NSURL*)CFBridgingRelease(url) path]];
safe_strcpy(buffer, fontPath.UTF8String, size);
return true;
} else {
}
else
{
return false;
}
}
}
#endif // NO_TTF
bool platform_has_matching_language(NSString *preferredLocale, uint16_t* languageIdentifier)
bool platform_has_matching_language(NSString* preferredLocale, uint16_t* languageIdentifier)
{
@autoreleasepool
{
if ([preferredLocale isEqualToString:@"en"] || [preferredLocale isEqualToString:@"en-CA"]) {
@autoreleasepool {
if ([preferredLocale isEqualToString:@"en"] || [preferredLocale isEqualToString:@"en-CA"])
{
*languageIdentifier = LANGUAGE_ENGLISH_US;
return YES;
}
if ([preferredLocale isEqualToString:@"zh-CN"]) {
if ([preferredLocale isEqualToString:@"zh-CN"])
{
*languageIdentifier = LANGUAGE_CHINESE_SIMPLIFIED;
return YES;
}
if ([preferredLocale isEqualToString:@"zh-TW"]) {
if ([preferredLocale isEqualToString:@"zh-TW"])
{
*languageIdentifier = LANGUAGE_CHINESE_TRADITIONAL;
return YES;
}
// Find an exact match (language and region)
for (int i = 1; i < LANGUAGE_COUNT; i++) {
if([preferredLocale isEqualToString:[NSString stringWithUTF8String:LanguagesDescriptors[i].locale]]) {
for (int i = 1; i < LANGUAGE_COUNT; i++)
{
if ([preferredLocale isEqualToString:[NSString stringWithUTF8String:LanguagesDescriptors[i].locale]])
{
*languageIdentifier = i;
return YES;
}
}
// Only check for a matching language
NSString *languageCode = [[preferredLocale componentsSeparatedByString:@"-"] firstObject];
for (int i = 1; i < LANGUAGE_COUNT; i++) {
NSString *optionLanguageCode = [[[NSString stringWithUTF8String:LanguagesDescriptors[i].locale] componentsSeparatedByString:@"-"] firstObject];
if([languageCode isEqualToString:optionLanguageCode]) {
NSString* languageCode = [[preferredLocale componentsSeparatedByString:@"-"] firstObject];
for (int i = 1; i < LANGUAGE_COUNT; i++)
{
NSString* optionLanguageCode =
[[[NSString stringWithUTF8String:LanguagesDescriptors[i].locale] componentsSeparatedByString:@"-"] firstObject];
if ([languageCode isEqualToString:optionLanguageCode])
{
*languageIdentifier = i;
return YES;
}
@ -107,12 +117,13 @@ bool platform_has_matching_language(NSString *preferredLocale, uint16_t* languag
uint16_t platform_get_locale_language()
{
@autoreleasepool
{
NSArray<NSString*> *preferredLanguages = [NSLocale preferredLanguages];
for (NSString *preferredLanguage in preferredLanguages) {
@autoreleasepool {
NSArray<NSString*>* preferredLanguages = [NSLocale preferredLanguages];
for (NSString* preferredLanguage in preferredLanguages)
{
uint16_t languageIdentifier;
if (platform_has_matching_language(preferredLanguage, &languageIdentifier)) {
if (platform_has_matching_language(preferredLanguage, &languageIdentifier))
{
return languageIdentifier;
}
}
@ -124,20 +135,19 @@ uint16_t platform_get_locale_language()
uint8_t platform_get_locale_currency()
{
@autoreleasepool
{
NSString *currencyCode = [[NSLocale currentLocale] objectForKey:NSLocaleCurrencyCode];
@autoreleasepool {
NSString* currencyCode = [[NSLocale currentLocale] objectForKey:NSLocaleCurrencyCode];
return platform_get_currency_value(currencyCode.UTF8String);
}
}
uint8_t platform_get_locale_measurement_format()
{
@autoreleasepool
{
NSNumber *metricSystem = [[NSLocale currentLocale] objectForKey:NSLocaleUsesMetricSystem];
@autoreleasepool {
NSNumber* metricSystem = [[NSLocale currentLocale] objectForKey:NSLocaleUsesMetricSystem];
if (metricSystem.boolValue) {
if (metricSystem.boolValue)
{
return MEASUREMENT_FORMAT_METRIC;
}
@ -145,16 +155,16 @@ uint8_t platform_get_locale_measurement_format()
}
}
void platform_get_changelog_path(utf8 *outPath, size_t outSize)
void platform_get_changelog_path(utf8* outPath, size_t outSize)
{
platform_get_openrct_data_path(outPath, outSize);
safe_strcat_path(outPath, "changelog.txt", outSize);
}
bool platform_get_steam_path(utf8 * outPath, size_t outSize)
bool platform_get_steam_path(utf8* outPath, size_t outSize)
{
char steamPath[1024] = { 0 };
const char * homeDir = getpwuid(getuid())->pw_dir;
const char* homeDir = getpwuid(getuid())->pw_dir;
if (homeDir != NULL)
{
safe_strcpy(steamPath, homeDir, sizeof(steamPath));

View File

@ -10,9 +10,10 @@
#ifndef _PLATFORM_H_
#define _PLATFORM_H_
#include "../common.h"
#include <string>
#include <time.h>
#include "../common.h"
struct TTFFontDescriptor;
struct rct2_install_info;
@ -31,24 +32,28 @@ struct rct2_install_info;
#define PLATFORM_NEWLINE "\n"
#endif
struct resolution_t {
struct resolution_t
{
int32_t width, height;
};
struct file_info {
const char *path;
struct file_info
{
const char* path;
uint64_t size;
uint64_t last_modified;
};
struct rct2_date {
struct rct2_date
{
uint8_t day;
uint8_t month;
int16_t year;
uint8_t day_of_week;
};
struct rct2_time {
struct rct2_time
{
uint8_t hour;
uint8_t minute;
uint8_t second;
@ -60,62 +65,64 @@ enum FILEDIALOG_TYPE
FD_SAVE
};
struct file_dialog_desc {
struct file_dialog_desc
{
uint8_t type;
const utf8 *title;
const utf8 *initial_directory;
const utf8 *default_filename;
struct {
const utf8 *name; // E.g. "Image Files"
const utf8 *pattern; // E.g. "*.png;*.jpg;*.gif"
const utf8* title;
const utf8* initial_directory;
const utf8* default_filename;
struct
{
const utf8* name; // E.g. "Image Files"
const utf8* pattern; // E.g. "*.png;*.jpg;*.gif"
} filters[8];
};
// Platform shared definitions
void platform_update_palette(const uint8_t *colours, int32_t start_index, int32_t num_colours);
void platform_update_palette(const uint8_t* colours, int32_t start_index, int32_t num_colours);
void platform_toggle_windowed_mode();
void platform_refresh_video(bool recreate_window);
void platform_get_date_utc(rct2_date *out_date);
void platform_get_time_utc(rct2_time *out_time);
void platform_get_date_local(rct2_date *out_date);
void platform_get_time_local(rct2_time *out_time);
void platform_get_date_utc(rct2_date* out_date);
void platform_get_time_utc(rct2_time* out_time);
void platform_get_date_local(rct2_date* out_date);
void platform_get_time_local(rct2_time* out_time);
// Platform specific definitions
bool platform_file_exists(const utf8 *path);
bool platform_directory_exists(const utf8 *path);
bool platform_original_game_data_exists(const utf8 *path);
bool platform_file_exists(const utf8* path);
bool platform_directory_exists(const utf8* path);
bool platform_original_game_data_exists(const utf8* path);
time_t platform_file_get_modified_time(const utf8* path);
bool platform_ensure_directory_exists(const utf8 *path);
bool platform_directory_delete(const utf8 *path);
utf8 * platform_get_absolute_path(const utf8 * relative_path, const utf8 * base_path);
bool platform_ensure_directory_exists(const utf8* path);
bool platform_directory_delete(const utf8* path);
utf8* platform_get_absolute_path(const utf8* relative_path, const utf8* base_path);
bool platform_lock_single_instance();
bool platform_place_string_on_clipboard(utf8* target);
// Returns the bitmask of the GetLogicalDrives function for windows, 0 for other systems
int32_t platform_get_drives();
bool platform_file_copy(const utf8 *srcPath, const utf8 *dstPath, bool overwrite);
bool platform_file_move(const utf8 *srcPath, const utf8 *dstPath);
bool platform_file_delete(const utf8 *path);
bool platform_file_copy(const utf8* srcPath, const utf8* dstPath, bool overwrite);
bool platform_file_move(const utf8* srcPath, const utf8* dstPath);
bool platform_file_delete(const utf8* path);
uint32_t platform_get_ticks();
void platform_sleep(uint32_t ms);
void platform_get_openrct_data_path(utf8 *outPath, size_t outSize);
void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory, size_t outSize);
void platform_get_openrct_data_path(utf8* outPath, size_t outSize);
void platform_get_user_directory(utf8* outPath, const utf8* subDirectory, size_t outSize);
utf8* platform_get_username();
bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc, size_t outSize);
utf8 *platform_open_directory_browser(const utf8 *title);
bool platform_open_common_file_dialog(utf8* outFilename, file_dialog_desc* desc, size_t outSize);
utf8* platform_open_directory_browser(const utf8* title);
uint8_t platform_get_locale_currency();
uint8_t platform_get_currency_value(const char *currencyCode);
uint8_t platform_get_currency_value(const char* currencyCode);
uint16_t platform_get_locale_language();
uint8_t platform_get_locale_measurement_format();
uint8_t platform_get_locale_temperature_format();
uint8_t platform_get_locale_date_format();
bool platform_process_is_elevated();
bool platform_get_steam_path(utf8 * outPath, size_t outSize);
bool platform_get_steam_path(utf8* outPath, size_t outSize);
std::string platform_get_rct2_steam_dir();
#ifndef NO_TTF
bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer, size_t size);
bool platform_get_font_path(TTFFontDescriptor* font, utf8* buffer, size_t size);
#endif // NO_TTF
datetime64 platform_get_datetime_now_utc();
@ -127,28 +134,28 @@ void core_init();
// Windows specific definitions
#ifdef _WIN32
#ifndef NOMINMAX
#define NOMINMAX
#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#undef CreateDirectory
#undef CreateWindow
#undef GetMessage
#ifndef NOMINMAX
#define NOMINMAX
#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#undef CreateDirectory
#undef CreateWindow
#undef GetMessage
void platform_setup_file_associations();
void platform_remove_file_associations();
bool platform_setup_uri_protocol();
// This function cannot be marked as 'static', even though it may seem to be,
// as it requires external linkage, which 'static' prevents
__declspec(dllexport) int32_t StartOpenRCT(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int32_t nCmdShow);
void platform_setup_file_associations();
void platform_remove_file_associations();
bool platform_setup_uri_protocol();
// This function cannot be marked as 'static', even though it may seem to be,
// as it requires external linkage, which 'static' prevents
__declspec(dllexport) int32_t StartOpenRCT(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int32_t nCmdShow);
#endif // _WIN32
#if defined(__APPLE__) && defined(__MACH__)
void macos_disallow_automatic_window_tabbing();
utf8* macos_str_decomp_to_precomp(utf8 *input);
void macos_disallow_automatic_window_tabbing();
utf8* macos_str_decomp_to_precomp(utf8* input);
#endif
#endif