1/***************************************************************************** 2 * Copyright (c) 2014-2020 OpenRCT2 developers 3 * 4 * For a complete list of all authors, please refer to contributors.md 5 * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 6 * 7 * OpenRCT2 is licensed under the GNU General Public License version 3. 8 *****************************************************************************/ 9 10#if defined(__APPLE__) && defined(__MACH__) 11 12# include "../config/Config.h" 13# include "../localisation/Language.h" 14# include "../util/Util.h" 15# include "platform.h" 16 17// undefine `interface` and `abstract`, because it's causing conflicts with Objective-C's keywords 18# undef interface 19# undef abstract 20 21# import <AppKit/AppKit.h> 22# import <Foundation/Foundation.h> 23# include <mach-o/dyld.h> 24# include <pwd.h> 25 26# ifndef NO_TTF 27bool platform_get_font_path(TTFFontDescriptor* font, utf8* buffer, size_t size) 28{ 29 @autoreleasepool 30 { 31 CTFontDescriptorRef fontRef = CTFontDescriptorCreateWithNameAndSize( 32 static_cast<CFStringRef>([NSString stringWithUTF8String:font->font_name]), 0.0); 33 CFURLRef url = static_cast<CFURLRef>(CTFontDescriptorCopyAttribute(fontRef, kCTFontURLAttribute)); 34 if (url) 35 { 36 NSString* fontPath = [NSString stringWithString:[static_cast<NSURL*>(CFBridgingRelease(url)) path]]; 37 safe_strcpy(buffer, fontPath.UTF8String, size); 38 return true; 39 } 40 else 41 { 42 return false; 43 } 44 } 45} 46# endif // NO_TTF 47 48bool platform_has_matching_language(NSString* preferredLocale, uint16_t* languageIdentifier) 49{ 50 @autoreleasepool 51 { 52 if ([preferredLocale isEqualToString:@"en"] || [preferredLocale isEqualToString:@"en-CA"]) 53 { 54 *languageIdentifier = LANGUAGE_ENGLISH_US; 55 return YES; 56 } 57 58 if ([preferredLocale isEqualToString:@"zh-CN"]) 59 { 60 *languageIdentifier = LANGUAGE_CHINESE_SIMPLIFIED; 61 return YES; 62 } 63 64 if ([preferredLocale isEqualToString:@"zh-TW"]) 65 { 66 *languageIdentifier = LANGUAGE_CHINESE_TRADITIONAL; 67 return YES; 68 } 69 70 // Find an exact match (language and region) 71 for (int i = 1; i < LANGUAGE_COUNT; i++) 72 { 73 if ([preferredLocale isEqualToString:[NSString stringWithUTF8String:LanguagesDescriptors[i].locale]]) 74 { 75 *languageIdentifier = i; 76 return YES; 77 } 78 } 79 80 // Only check for a matching language 81 NSString* languageCode = [[preferredLocale componentsSeparatedByString:@"-"] firstObject]; 82 for (int i = 1; i < LANGUAGE_COUNT; i++) 83 { 84 NSString* optionLanguageCode = [[[NSString stringWithUTF8String:LanguagesDescriptors[i].locale] 85 componentsSeparatedByString:@"-"] firstObject]; 86 if ([languageCode isEqualToString:optionLanguageCode]) 87 { 88 *languageIdentifier = i; 89 return YES; 90 } 91 } 92 93 return NO; 94 } 95} 96 97uint16_t platform_get_locale_language() 98{ 99 @autoreleasepool 100 { 101 NSArray<NSString*>* preferredLanguages = [NSLocale preferredLanguages]; 102 for (NSString* preferredLanguage in preferredLanguages) 103 { 104 uint16_t languageIdentifier; 105 if (platform_has_matching_language(preferredLanguage, &languageIdentifier)) 106 { 107 return languageIdentifier; 108 } 109 } 110 111 // Fallback 112 return LANGUAGE_ENGLISH_UK; 113 } 114} 115 116CurrencyType platform_get_locale_currency() 117{ 118 @autoreleasepool 119 { 120 NSString* currencyCode = [[NSLocale currentLocale] objectForKey:NSLocaleCurrencyCode]; 121 return platform_get_currency_value(currencyCode.UTF8String); 122 } 123} 124 125MeasurementFormat platform_get_locale_measurement_format() 126{ 127 @autoreleasepool 128 { 129 NSNumber* metricSystem = [[NSLocale currentLocale] objectForKey:NSLocaleUsesMetricSystem]; 130 131 if (metricSystem.boolValue) 132 { 133 return MeasurementFormat::Metric; 134 } 135 136 return MeasurementFormat::Imperial; 137 } 138} 139 140void platform_get_changelog_path(utf8* outPath, size_t outSize) 141{ 142 platform_get_openrct2_data_path(outPath, outSize); 143 safe_strcat_path(outPath, "changelog.txt", outSize); 144} 145 146bool platform_get_steam_path(utf8* outPath, size_t outSize) 147{ 148 char steamPath[1024] = { 0 }; 149 const char* homeDir = getpwuid(getuid())->pw_dir; 150 if (homeDir != NULL) 151 { 152 safe_strcpy(steamPath, homeDir, sizeof(steamPath)); 153 safe_strcat_path( 154 steamPath, "Library/Application Support/Steam/Steam.AppBundle/Steam/Contents/MacOS/steamapps", sizeof(steamPath)); 155 if (platform_directory_exists(steamPath)) 156 { 157 safe_strcpy(outPath, steamPath, outSize); 158 return true; 159 } 160 } 161 return false; 162} 163 164#endif 165