Merge remote-tracking branch 'upstream/master'

This commit is contained in:
pelya
2021-01-25 00:50:42 +02:00
1076 changed files with 25433 additions and 61762 deletions
+4
View File
@@ -0,0 +1,4 @@
add_subdirectory(macosx)
add_subdirectory(os2)
add_subdirectory(unix)
add_subdirectory(windows)
+11
View File
@@ -0,0 +1,11 @@
add_files(
crashlog_osx.cpp
macos.h
macos.mm
osx_stdafx.h
splash.cpp
splash.h
string_osx.cpp
string_osx.h
CONDITION APPLE
)
+4 -2
View File
@@ -63,10 +63,12 @@ class CrashLogOSX : public CrashLog {
" Name: Mac OS X\n"
" Release: %d.%d.%d\n"
" Machine: %s\n"
" Min Ver: %d\n",
" Min Ver: %d\n"
" Max Ver: %d\n",
ver_maj, ver_min, ver_bug,
arch != nullptr ? arch->description : "unknown",
MAC_OS_X_VERSION_MIN_REQUIRED
MAC_OS_X_VERSION_MIN_REQUIRED,
MAC_OS_X_VERSION_MAX_ALLOWED
);
}
+56 -17
View File
@@ -12,7 +12,9 @@
#include "../../rev.h"
#include "macos.h"
#include "../../string_func.h"
#include "../../fileio_func.h"
#include <pthread.h>
#include <array>
#define Rect OTTDRect
#define Point OTTDPoint
@@ -40,6 +42,10 @@ typedef struct {
#define NSOperatingSystemVersion OTTDOperatingSystemVersion
#endif
#ifdef WITH_COCOA
static NSAutoreleasePool *_ottd_autorelease_pool;
#endif
/**
* Get the version of the MacOS we are running under. Code adopted
* from http://www.cocoadev.com/index.pl?DeterminingOSVersion
@@ -66,6 +72,10 @@ void GetMacOSVersion(int *return_major, int *return_minor, int *return_bugfix)
}
#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10)
#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
SInt32 systemVersion, version_major, version_minor, version_bugfix;
if (Gestalt(gestaltSystemVersion, &systemVersion) == noErr) {
if (systemVersion >= 0x1040) {
@@ -78,6 +88,9 @@ void GetMacOSVersion(int *return_major, int *return_minor, int *return_bugfix)
*return_bugfix = (int)GB(systemVersion, 0, 4);
}
}
#ifdef __clang__
# pragma clang diagnostic pop
#endif
#endif
}
@@ -161,19 +174,8 @@ const char *GetCurrentLocale(const char *)
NSString *preferredLang = [ languages objectAtIndex:0 ];
/* preferredLang is either 2 or 5 characters long ("xx" or "xx_YY"). */
/* Since Apple introduced encoding to CString in OSX 10.4 we have to make a few conditions
* to get the right code for the used version of OSX. */
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
if (MacOSVersionIsAtLeast(10, 4, 0)) {
[ preferredLang getCString:retbuf maxLength:32 encoding:NSASCIIStringEncoding ];
} else
#endif
{
#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4)
/* maxLength does not include the \0 char in contrast to the call above. */
[ preferredLang getCString:retbuf maxLength:31 ];
#endif
}
[ preferredLang getCString:retbuf maxLength:32 encoding:NSASCIIStringEncoding ];
return retbuf;
}
@@ -202,6 +204,45 @@ bool GetClipboardContents(char *buffer, const char *last)
return true;
}
/** Set the application's bundle directory.
*
* This is needed since OS X application bundles do not have a
* current directory and the data files are 'somewhere' in the bundle.
*/
void CocoaSetApplicationBundleDir()
{
extern std::array<std::string, NUM_SEARCHPATHS> _searchpaths;
char tmp[MAXPATHLEN];
CFAutoRelease<CFURLRef> url(CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()));
if (CFURLGetFileSystemRepresentation(url.get(), true, (unsigned char *)tmp, MAXPATHLEN)) {
_searchpaths[SP_APPLICATION_BUNDLE_DIR] = tmp;
AppendPathSeparator(_searchpaths[SP_APPLICATION_BUNDLE_DIR]);
} else {
_searchpaths[SP_APPLICATION_BUNDLE_DIR].clear();
}
}
/**
* Setup autorelease for the application pool.
*
* These are called from main() to prevent a _NSAutoreleaseNoPool error when
* exiting before the cocoa video driver has been loaded
*/
void CocoaSetupAutoreleasePool()
{
_ottd_autorelease_pool = [ [ NSAutoreleasePool alloc ] init ];
}
/**
* Autorelease the application pool.
*/
void CocoaReleaseAutoreleasePool()
{
[ _ottd_autorelease_pool release ];
}
#endif
/**
@@ -213,7 +254,7 @@ bool IsMonospaceFont(CFStringRef name)
{
NSFont *font = [ NSFont fontWithName:(__bridge NSString *)name size:0.0f ];
return font != NULL ? [ font isFixedPitch ] : false;
return font != nil ? [ font isFixedPitch ] : false;
}
/**
@@ -222,14 +263,12 @@ bool IsMonospaceFont(CFStringRef name)
*/
void MacOSSetThreadName(const char *name)
{
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
if (MacOSVersionIsAtLeast(10, 6, 0)) {
pthread_setname_np(name);
}
#endif
NSThread *cur = [ NSThread currentThread ];
if (cur != NULL && [ cur respondsToSelector:@selector(setName:) ]) {
if (cur != nil && [ cur respondsToSelector:@selector(setName:) ]) {
[ cur performSelector:@selector(setName:) withObject:[ NSString stringWithUTF8String:name ] ];
}
}
+4
View File
@@ -18,6 +18,10 @@
#define HAVE_OSX_107_SDK
#endif
#ifdef MAC_OS_X_VERSION_10_9
#define HAVE_OSX_109_SDK
#endif
#ifdef MAC_OS_X_VERSION_10_11
#define HAVE_OSX_1011_SDK
#endif
+40 -22
View File
@@ -18,7 +18,34 @@
#include <CoreFoundation/CoreFoundation.h>
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
/* CTRunDelegateCreate is supported since MacOS X 10.5, but was only included in the SDKs starting with the 10.9 SDK. */
#ifndef HAVE_OSX_109_SDK
extern "C" {
typedef const struct __CTRunDelegate * CTRunDelegateRef;
typedef void (*CTRunDelegateDeallocateCallback) (void* refCon);
typedef CGFloat (*CTRunDelegateGetAscentCallback) (void* refCon);
typedef CGFloat (*CTRunDelegateGetDescentCallback) (void* refCon);
typedef CGFloat (*CTRunDelegateGetWidthCallback) (void* refCon);
typedef struct {
CFIndex version;
CTRunDelegateDeallocateCallback dealloc;
CTRunDelegateGetAscentCallback getAscent;
CTRunDelegateGetDescentCallback getDescent;
CTRunDelegateGetWidthCallback getWidth;
} CTRunDelegateCallbacks;
enum {
kCTRunDelegateVersion1 = 1,
kCTRunDelegateCurrentVersion = kCTRunDelegateVersion1
};
extern const CFStringRef kCTRunDelegateAttributeName AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER;
CTRunDelegateRef CTRunDelegateCreate(const CTRunDelegateCallbacks* callbacks, void* refCon) AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER;
}
#endif /* HAVE_OSX_109_SDK */
/** Cached current locale. */
static CFAutoRelease<CFLocaleRef> _osx_locale;
/** CoreText cache for font information, cleared when OTTD changes fonts. */
@@ -233,7 +260,7 @@ int CoreTextParagraphLayout::CoreTextLine::GetLeading() const
{
int leading = 0;
for (const auto &run : *this) {
leading = max(leading, run.GetLeading());
leading = std::max(leading, run.GetLeading());
}
return leading;
@@ -262,6 +289,17 @@ void MacOSResetScriptCache(FontSize size)
_font_cache[size].reset();
}
/** Register an external font file with the CoreText system. */
void MacOSRegisterExternalFont(const char *file_path)
{
if (!MacOSVersionIsAtLeast(10, 6, 0)) return;
CFAutoRelease<CFStringRef> path(CFStringCreateWithCString(kCFAllocatorDefault, file_path, kCFStringEncodingUTF8));
CFAutoRelease<CFURLRef> url(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path.get(), kCFURLPOSIXPathStyle, false));
CTFontManagerRegisterFontsForURL(url.get(), kCTFontManagerScopeProcess, nullptr);
}
/** Store current language locale as a CoreFounation locale. */
void MacOSSetCurrentLocaleName(const char *iso_code)
{
@@ -406,23 +444,3 @@ int MacOSStringCompare(const char *s1, const char *s2)
return new OSXStringIterator();
}
#else
void MacOSResetScriptCache(FontSize size) {}
void MacOSSetCurrentLocaleName(const char *iso_code) {}
int MacOSStringCompare(const char *s1, const char *s2)
{
return 0;
}
/* static */ StringIterator *OSXStringIterator::Create()
{
return nullptr;
}
/* static */ ParagraphLayouter *CoreTextParagraphLayoutFactory::GetParagraphLayout(CharType *buff, CharType *buff_end, FontMap &fontMapping)
{
return nullptr;
}
#endif /* (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) */
+2
View File
@@ -85,4 +85,6 @@ void MacOSResetScriptCache(FontSize size);
void MacOSSetCurrentLocaleName(const char *iso_code);
int MacOSStringCompare(const char *s1, const char *s2);
void MacOSRegisterExternalFont(const char *file_path);
#endif /* STRING_OSX_H */
+4
View File
@@ -0,0 +1,4 @@
add_files(
os2.cpp
CONDITION OPTION_OS2
)
+2 -2
View File
@@ -26,7 +26,7 @@
#include <stdlib.h>
#include <time.h>
#ifndef __INNOTEK_LIBC__
#include <dos.h>
# include <dos.h>
#endif
#include "../../safeguards.h"
@@ -36,7 +36,7 @@
#include <os2.h>
#ifndef __INNOTEK_LIBC__
#include <i86.h>
# include <i86.h>
#endif
bool FiosIsRoot(const char *file)
+9
View File
@@ -0,0 +1,9 @@
add_files(
crashlog_unix.cpp
CONDITION UNIX AND NOT APPLE AND NOT OPTION_OS2
)
add_files(
unix.cpp
CONDITION UNIX AND NOT OPTION_OS2
)
+24 -7
View File
@@ -24,14 +24,18 @@
#include <time.h>
#include <signal.h>
#ifdef WITH_SDL2
#include <SDL.h>
#endif
#ifdef __APPLE__
#include <sys/mount.h>
# include <sys/mount.h>
#elif ((defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L) || defined(__GLIBC__)) && !defined(__ANDROID__)
#define HAS_STATVFS
# define HAS_STATVFS
#endif
#if defined(OPENBSD) || defined(__NetBSD__) || defined(__FreeBSD__)
#define HAS_SYSCTL
# define HAS_SYSCTL
#endif
#ifdef HAS_STATVFS
@@ -238,8 +242,8 @@ void ShowOSErrorBox(const char *buf, bool system)
#endif
#ifdef WITH_COCOA
void cocoaSetupAutoreleasePool();
void cocoaReleaseAutoreleasePool();
void CocoaSetupAutoreleasePool();
void CocoaReleaseAutoreleasePool();
#endif
#ifdef __ANDROID__
@@ -253,7 +257,7 @@ int CDECL main(int argc, char *argv[])
for (int i = 0; i < argc; i++) ValidateString(argv[i]);
#ifdef WITH_COCOA
cocoaSetupAutoreleasePool();
CocoaSetupAutoreleasePool();
/* This is passed if we are launched by double-clicking */
if (argc >= 2 && strncmp(argv[1], "-psn", 4) == 0) {
argv[1] = nullptr;
@@ -269,7 +273,7 @@ int CDECL main(int argc, char *argv[])
int ret = openttd_main(argc, argv);
#ifdef WITH_COCOA
cocoaReleaseAutoreleasePool();
CocoaReleaseAutoreleasePool();
#endif
return ret;
@@ -278,6 +282,19 @@ int CDECL main(int argc, char *argv[])
#ifndef WITH_COCOA
bool GetClipboardContents(char *buffer, const char *last)
{
#ifdef WITH_SDL2
if (SDL_HasClipboardText() == SDL_FALSE) {
return false;
}
char *clip = SDL_GetClipboardText();
if (clip != NULL) {
strecpy(buffer, clip, last);
SDL_free(clip);
return true;
}
#endif
return false;
}
#endif
+8
View File
@@ -0,0 +1,8 @@
add_files(
crashlog_win.cpp
string_uniscribe.cpp
string_uniscribe.h
win32.cpp
win32.h
CONDITION WIN32
)
+5 -2
View File
@@ -219,7 +219,7 @@ static char *PrintModuleInfo(char *output, const char *last, HMODULE mod)
res = EnumProcessModules(proc, modules, sizeof(modules), &needed);
CloseHandle(proc);
if (res) {
size_t count = min(needed / sizeof(HMODULE), lengthof(modules));
size_t count = std::min<DWORD>(needed / sizeof(HMODULE), lengthof(modules));
for (size_t i = 0; i != count; i++) output = PrintModuleInfo(output, last, modules[i]);
return output + seprintf(output, last, "\n");
@@ -499,7 +499,7 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c
CONST PMINIDUMP_CALLBACK_INFORMATION);
MiniDumpWriteDump_t funcMiniDumpWriteDump = (MiniDumpWriteDump_t)GetProcAddress(dbghelp, "MiniDumpWriteDump");
if (funcMiniDumpWriteDump != nullptr) {
seprintf(filename, filename_last, "%scrash.dmp", _personal_dir);
seprintf(filename, filename_last, "%scrash.dmp", _personal_dir.c_str());
HANDLE file = CreateFile(OTTD2FS(filename), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, 0);
HANDLE proc = GetCurrentProcess();
DWORD procid = GetCurrentProcessId();
@@ -540,6 +540,9 @@ void *_safe_esp = nullptr;
static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep)
{
/* Disable our event loop. */
SetWindowLongPtr(GetActiveWindow(), GWLP_WNDPROC, (LONG_PTR)&DefWindowProc);
if (CrashLogWindows::current != nullptr) {
CrashLog::AfterCrashLogCleanup();
ExitProcess(2);
+13 -13
View File
@@ -37,24 +37,24 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_DEFAULT
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
100 ICON DISCARDABLE "../../../media/openttd.ico"
100 ICON DISCARDABLE "${CMAKE_SOURCE_DIR}/os/windows/openttd.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
100 DIALOG DISCARDABLE 0, 0, 305, 99
100 DIALOG DISCARDABLE 0, 0, 305, 101
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Fatal Application Failure"
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "&Close",12,7,80,50,14
PUSHBUTTON "&Emergency save",13,155,80,68,14
PUSHBUTTON "",15,243,80,55,14
EDITTEXT 11,7,101,291,118,ES_MULTILINE | ES_READONLY | WS_VSCROLL |
PUSHBUTTON "&Close",12,7,82,60,14
PUSHBUTTON "&Emergency save",13,158,82,60,14
PUSHBUTTON "",15,238,82,60,14
EDITTEXT 11,7,103,291,118,ES_MULTILINE | ES_READONLY | WS_VSCROLL |
WS_HSCROLL | NOT WS_TABSTOP
LTEXT "",10,36,7,262,65
LTEXT "",10,36,5,262,72
ICON 100,IDC_STATIC,9,9,20,20
END
@@ -77,8 +77,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,10,0,!!ISODATE!!
PRODUCTVERSION 1,10,0,!!ISODATE!!
FILEVERSION 1,11,0,${REV_ISODATE}
PRODUCTVERSION 1,11,0,${REV_ISODATE}
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -96,14 +96,14 @@ BEGIN
VALUE "Comments", "This program is licensed under the GNU General Public License version 2.\0"
VALUE "CompanyName", "OpenTTD Development Team\0"
VALUE "FileDescription", "OpenTTD\0"
VALUE "FileVersion", "!!VERSION!!\0"
VALUE "FileVersion", "${REV_VERSION}\0"
VALUE "InternalName", "openttd\0"
VALUE "LegalCopyright", "Copyright \xA9 OpenTTD Developers 2002-2019. All Rights Reserved.\0"
VALUE "LegalCopyright", "Copyright \xA9 OpenTTD Developers 2002-${REV_YEAR}. All Rights Reserved.\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "openttd.exe\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "OpenTTD\0"
VALUE "ProductVersion", "!!VERSION!!\0"
VALUE "ProductVersion", "${REV_VERSION}\0"
VALUE "SpecialBuild", "-\0"
END
END
@@ -116,7 +116,7 @@ END
#endif // !_MAC
#ifdef __MINGW32__
1 24 "..\\..\\..\\projects\\dpi_aware.manifest"
1 24 "${CMAKE_SOURCE_DIR}/os/windows/openttd.manifest"
#endif
#endif // Neutral (Default) resources
+2 -6
View File
@@ -7,8 +7,6 @@
/** @file string_uniscribe.cpp Functions related to laying out text on Win32. */
#if defined(WITH_UNISCRIBE)
#include "../../stdafx.h"
#include "../../debug.h"
#include "string_uniscribe.h"
@@ -304,7 +302,7 @@ static std::vector<SCRIPT_ITEM> UniscribeItemizeString(UniscribeParagraphLayoutF
for (auto const &i : fontMapping) {
while (cur_pos < i.first && cur_item != items.end() - 1) {
/* Add a range that spans the intersection of the remaining item and font run. */
int stop_pos = min(i.first, (cur_item + 1)->iCharPos);
int stop_pos = std::min(i.first, (cur_item + 1)->iCharPos);
assert(stop_pos - cur_pos > 0);
ranges.push_back(UniscribeRun(cur_pos, stop_pos - cur_pos, i.second, cur_item->a));
@@ -454,7 +452,7 @@ int UniscribeParagraphLayout::UniscribeLine::GetLeading() const
{
int leading = 0;
for (const auto &run : *this) {
leading = max(leading, run.GetLeading());
leading = std::max(leading, run.GetLeading());
}
return leading;
@@ -620,5 +618,3 @@ const int *UniscribeParagraphLayout::UniscribeVisualRun::GetGlyphToCharMap() con
return this->utf16_to_utf8[this->cur_pos];
}
#endif /* defined(WITH_UNISCRIBE) */
-4
View File
@@ -10,8 +10,6 @@
#ifndef STRING_UNISCRIBE_H
#define STRING_UNISCRIBE_H
#if defined(WITH_UNISCRIBE)
#include "../../gfx_layout.h"
#include "../../string_base.h"
#include <vector>
@@ -85,6 +83,4 @@ public:
size_t Prev(IterType what) override;
};
#endif /* defined(WITH_UNISCRIBE) */
#endif /* STRING_UNISCRIBE_H */
+52 -27
View File
@@ -29,6 +29,7 @@
#include <sys/stat.h>
#include "../../language.h"
#include "../../thread.h"
#include <array>
#include "../../safeguards.h"
@@ -451,60 +452,84 @@ char *getcwd(char *buf, size_t size)
return buf;
}
extern std::string _config_file;
void DetermineBasePaths(const char *exe)
{
char tmp[MAX_PATH];
extern std::array<std::string, NUM_SEARCHPATHS> _searchpaths;
TCHAR path[MAX_PATH];
#ifdef WITH_PERSONAL_DIR
if (SUCCEEDED(OTTDSHGetFolderPath(nullptr, CSIDL_PERSONAL, nullptr, SHGFP_TYPE_CURRENT, path))) {
strecpy(tmp, FS2OTTD(path), lastof(tmp));
AppendPathSeparator(tmp, lastof(tmp));
strecat(tmp, PERSONAL_DIR, lastof(tmp));
AppendPathSeparator(tmp, lastof(tmp));
_searchpaths[SP_PERSONAL_DIR] = stredup(tmp);
std::string tmp(FS2OTTD(path));
AppendPathSeparator(tmp);
tmp += PERSONAL_DIR;
AppendPathSeparator(tmp);
_searchpaths[SP_PERSONAL_DIR] = tmp;
tmp += "content_download";
AppendPathSeparator(tmp);
_searchpaths[SP_AUTODOWNLOAD_PERSONAL_DIR] = tmp;
} else {
_searchpaths[SP_PERSONAL_DIR] = nullptr;
_searchpaths[SP_PERSONAL_DIR].clear();
}
if (SUCCEEDED(OTTDSHGetFolderPath(nullptr, CSIDL_COMMON_DOCUMENTS, nullptr, SHGFP_TYPE_CURRENT, path))) {
strecpy(tmp, FS2OTTD(path), lastof(tmp));
AppendPathSeparator(tmp, lastof(tmp));
strecat(tmp, PERSONAL_DIR, lastof(tmp));
AppendPathSeparator(tmp, lastof(tmp));
_searchpaths[SP_SHARED_DIR] = stredup(tmp);
std::string tmp(FS2OTTD(path));
AppendPathSeparator(tmp);
tmp += PERSONAL_DIR;
AppendPathSeparator(tmp);
_searchpaths[SP_SHARED_DIR] = tmp;
} else {
_searchpaths[SP_SHARED_DIR] = nullptr;
_searchpaths[SP_SHARED_DIR].clear();
}
#else
_searchpaths[SP_PERSONAL_DIR] = nullptr;
_searchpaths[SP_SHARED_DIR] = nullptr;
_searchpaths[SP_PERSONAL_DIR].clear();
_searchpaths[SP_SHARED_DIR].clear();
#endif
/* Get the path to working directory of OpenTTD */
getcwd(tmp, lengthof(tmp));
AppendPathSeparator(tmp, lastof(tmp));
_searchpaths[SP_WORKING_DIR] = stredup(tmp);
if (_config_file.empty()) {
char cwd[MAX_PATH];
getcwd(cwd, lengthof(cwd));
std::string cwd_s(cwd);
AppendPathSeparator(cwd_s);
_searchpaths[SP_WORKING_DIR] = cwd_s;
} else {
/* Use the folder of the config file as working directory. */
TCHAR config_dir[MAX_PATH];
_tcsncpy(path, convert_to_fs(_config_file.c_str(), path, lengthof(path)), lengthof(path));
if (!GetFullPathName(path, lengthof(config_dir), config_dir, nullptr)) {
DEBUG(misc, 0, "GetFullPathName failed (%lu)\n", GetLastError());
_searchpaths[SP_WORKING_DIR].clear();
} else {
std::string tmp(FS2OTTD(config_dir));
auto pos = tmp.find_last_of(PATHSEPCHAR);
if (pos != std::string::npos) tmp.erase(pos + 1);
_searchpaths[SP_WORKING_DIR] = tmp;
}
}
if (!GetModuleFileName(nullptr, path, lengthof(path))) {
DEBUG(misc, 0, "GetModuleFileName failed (%lu)\n", GetLastError());
_searchpaths[SP_BINARY_DIR] = nullptr;
_searchpaths[SP_BINARY_DIR].clear();
} else {
TCHAR exec_dir[MAX_PATH];
_tcsncpy(path, convert_to_fs(exe, path, lengthof(path)), lengthof(path));
if (!GetFullPathName(path, lengthof(exec_dir), exec_dir, nullptr)) {
DEBUG(misc, 0, "GetFullPathName failed (%lu)\n", GetLastError());
_searchpaths[SP_BINARY_DIR] = nullptr;
_searchpaths[SP_BINARY_DIR].clear();
} else {
strecpy(tmp, convert_from_fs(exec_dir, tmp, lengthof(tmp)), lastof(tmp));
char *s = strrchr(tmp, PATHSEPCHAR);
*(s + 1) = '\0';
_searchpaths[SP_BINARY_DIR] = stredup(tmp);
std::string tmp(FS2OTTD(exec_dir));
auto pos = tmp.find_last_of(PATHSEPCHAR);
if (pos != std::string::npos) tmp.erase(pos + 1);
_searchpaths[SP_BINARY_DIR] = tmp;
}
}
_searchpaths[SP_INSTALLATION_DIR] = nullptr;
_searchpaths[SP_APPLICATION_BUNDLE_DIR] = nullptr;
_searchpaths[SP_INSTALLATION_DIR].clear();
_searchpaths[SP_APPLICATION_BUNDLE_DIR].clear();
}