Update to 12.0-beta1
This commit is contained in:
@@ -57,7 +57,7 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
|
||||
}
|
||||
|
||||
if (os_err == noErr) {
|
||||
DEBUG(freetype, 3, "Font path for %s: %s", font_name, file_path);
|
||||
Debug(freetype, 3, "Font path for {}: {}", font_name, file_path);
|
||||
err = FT_New_Face(_library, (const char *)file_path, 0, face);
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i
|
||||
/* Save result. */
|
||||
callback->SetFontNames(settings, name);
|
||||
if (!callback->FindMissingGlyphs()) {
|
||||
DEBUG(freetype, 2, "CT-Font for %s: %s", language_isocode, name);
|
||||
Debug(freetype, 2, "CT-Font for {}: {}", language_isocode, name);
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
@@ -221,7 +221,7 @@ void CoreTextFontCache::SetFontSize(int pixels)
|
||||
CFStringGetCString(font_name.get(), name, lengthof(name), kCFStringEncodingUTF8);
|
||||
this->font_name = name;
|
||||
|
||||
DEBUG(freetype, 2, "Loaded font '%s' with size %d", this->font_name.c_str(), pixels);
|
||||
Debug(freetype, 2, "Loaded font '{}' with size {}", this->font_name, pixels);
|
||||
}
|
||||
|
||||
GlyphID CoreTextFontCache::MapCharToGlyph(WChar key)
|
||||
@@ -359,7 +359,7 @@ void LoadCoreTextFont(FontSize fs)
|
||||
case FS_MONO: settings = &_freetype.mono; break;
|
||||
}
|
||||
|
||||
if (StrEmpty(settings->font)) return;
|
||||
if (settings->font.empty()) return;
|
||||
|
||||
CFAutoRelease<CTFontDescriptorRef> font_ref;
|
||||
|
||||
@@ -375,10 +375,10 @@ void LoadCoreTextFont(FontSize fs)
|
||||
|
||||
/* See if this is an absolute path. */
|
||||
if (FileExists(settings->font)) {
|
||||
path.reset(CFStringCreateWithCString(kCFAllocatorDefault, settings->font, kCFStringEncodingUTF8));
|
||||
path.reset(CFStringCreateWithCString(kCFAllocatorDefault, settings->font.c_str(), kCFStringEncodingUTF8));
|
||||
} else {
|
||||
/* Scan the search-paths to see if it can be found. */
|
||||
std::string full_font = FioFindFullPath(BASE_DIR, settings->font);
|
||||
std::string full_font = FioFindFullPath(BASE_DIR, settings->font.c_str());
|
||||
if (!full_font.empty()) {
|
||||
path.reset(CFStringCreateWithCString(kCFAllocatorDefault, full_font.c_str(), kCFStringEncodingUTF8));
|
||||
}
|
||||
@@ -393,13 +393,13 @@ void LoadCoreTextFont(FontSize fs)
|
||||
font_ref.reset((CTFontDescriptorRef)CFArrayGetValueAtIndex(descs.get(), 0));
|
||||
CFRetain(font_ref.get());
|
||||
} else {
|
||||
ShowInfoF("Unable to load file '%s' for %s font, using default OS font selection instead", settings->font, SIZE_TO_NAME[fs]);
|
||||
ShowInfoF("Unable to load file '%s' for %s font, using default OS font selection instead", settings->font.c_str(), SIZE_TO_NAME[fs]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!font_ref) {
|
||||
CFAutoRelease<CFStringRef> name(CFStringCreateWithCString(kCFAllocatorDefault, settings->font, kCFStringEncodingUTF8));
|
||||
CFAutoRelease<CFStringRef> name(CFStringCreateWithCString(kCFAllocatorDefault, settings->font.c_str(), kCFStringEncodingUTF8));
|
||||
|
||||
/* Simply creating the font using CTFontCreateWithNameAndSize will *always* return
|
||||
* something, no matter the name. As such, we can't use it to check for existence.
|
||||
@@ -417,7 +417,7 @@ void LoadCoreTextFont(FontSize fs)
|
||||
}
|
||||
|
||||
if (!font_ref) {
|
||||
ShowInfoF("Unable to use '%s' for %s font, using sprite font instead", settings->font, SIZE_TO_NAME[fs]);
|
||||
ShowInfoF("Unable to use '%s' for %s font, using sprite font instead", settings->font.c_str(), SIZE_TO_NAME[fs]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -191,13 +191,13 @@ const char *GetCurrentLocale(const char *)
|
||||
bool GetClipboardContents(char *buffer, const char *last)
|
||||
{
|
||||
NSPasteboard *pb = [ NSPasteboard generalPasteboard ];
|
||||
NSArray *types = [ NSArray arrayWithObject:NSStringPboardType ];
|
||||
NSArray *types = [ NSArray arrayWithObject:NSPasteboardTypeString ];
|
||||
NSString *bestType = [ pb availableTypeFromArray:types ];
|
||||
|
||||
/* Clipboard has no text data available. */
|
||||
if (bestType == nil) return false;
|
||||
|
||||
NSString *string = [ pb stringForType:NSStringPboardType ];
|
||||
NSString *string = [ pb stringForType:NSPasteboardTypeString ];
|
||||
if (string == nil || [ string length ] == 0) return false;
|
||||
|
||||
strecpy(buffer, [ string UTF8String ], last);
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
#define HAVE_OSX_1011_SDK
|
||||
#endif
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_10_12
|
||||
#define HAVE_OSX_1012_SDK
|
||||
#endif
|
||||
|
||||
/* It would seem that to ensure backward compatibility we have to ensure that we have defined MAC_OS_X_VERSION_10_x everywhere */
|
||||
#ifndef MAC_OS_X_VERSION_10_3
|
||||
#define MAC_OS_X_VERSION_10_3 1030
|
||||
@@ -73,8 +77,8 @@
|
||||
#endif
|
||||
|
||||
/* Check for mismatching 'architectures' */
|
||||
#if !defined(STRGEN) && !defined(SETTINGSGEN) && ((defined(__LP64__) && !defined(_SQ64)) || (!defined(__LP64__) && defined(_SQ64)))
|
||||
# error "Compiling 64 bits without _SQ64 set! (or vice versa)"
|
||||
#if !defined(STRGEN) && !defined(SETTINGSGEN) && ((defined(__LP64__) && !defined(POINTER_IS_64BIT)) || (!defined(__LP64__) && defined(POINTER_IS_64BIT)))
|
||||
# error "Compiling 64 bits without POINTER_IS_64BIT set! (or vice versa)"
|
||||
#endif
|
||||
|
||||
/* Name conflict */
|
||||
|
||||
+2
-5
@@ -174,7 +174,7 @@ int CDECL main(int argc, char *argv[])
|
||||
SetRandomSeed(time(nullptr));
|
||||
|
||||
/* Make sure our arguments contain only valid UTF-8 characters. */
|
||||
for (int i = 0; i < argc; i++) ValidateString(argv[i]);
|
||||
for (int i = 0; i < argc; i++) StrMakeValidInPlace(argv[i]);
|
||||
|
||||
return openttd_main(argc, argv);
|
||||
}
|
||||
@@ -203,13 +203,10 @@ bool GetClipboardContents(char *buffer, const char *last)
|
||||
}
|
||||
|
||||
|
||||
const char *FS2OTTD(const char *name) {return name;}
|
||||
const char *OTTD2FS(const char *name) {return name;}
|
||||
|
||||
void OSOpenBrowser(const char *url)
|
||||
{
|
||||
// stub only
|
||||
DEBUG(misc, 0, "Failed to open url: %s", url);
|
||||
Debug(misc, 0, "Failed to open url: {}", url);
|
||||
}
|
||||
|
||||
void SetCurrentThreadName(const char *)
|
||||
|
||||
@@ -51,10 +51,10 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
|
||||
/* Resolve the name and populate the information structure */
|
||||
pat = FcNameParse((FcChar8 *)font_family);
|
||||
if (font_style != nullptr) FcPatternAddString(pat, FC_STYLE, (FcChar8 *)font_style);
|
||||
FcConfigSubstitute(0, pat, FcMatchPattern);
|
||||
FcConfigSubstitute(nullptr, pat, FcMatchPattern);
|
||||
FcDefaultSubstitute(pat);
|
||||
fs = FcFontSetCreate();
|
||||
match = FcFontMatch(0, pat, &result);
|
||||
match = FcFontMatch(nullptr, pat, &result);
|
||||
|
||||
if (fs != nullptr && match != nullptr) {
|
||||
int i;
|
||||
@@ -148,7 +148,7 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i
|
||||
callback->SetFontNames(settings, (const char *)file);
|
||||
|
||||
bool missing = callback->FindMissingGlyphs();
|
||||
DEBUG(freetype, 1, "Font \"%s\" misses%s glyphs", file, missing ? "" : " no");
|
||||
Debug(freetype, 1, "Font \"{}\" misses{} glyphs", file, missing ? "" : " no");
|
||||
|
||||
if (!missing) {
|
||||
best_weight = value;
|
||||
|
||||
+15
-18
@@ -146,9 +146,8 @@ static const char *GetLocalCode()
|
||||
* Convert between locales, which from and which to is set in the calling
|
||||
* functions OTTD2FS() and FS2OTTD().
|
||||
*/
|
||||
static const char *convert_tofrom_fs(iconv_t convd, const char *name)
|
||||
static const char *convert_tofrom_fs(iconv_t convd, const char *name, char *outbuf, size_t outlen)
|
||||
{
|
||||
static char buf[1024];
|
||||
/* There are different implementations of iconv. The older ones,
|
||||
* e.g. SUSv2, pass a const pointer, whereas the newer ones, e.g.
|
||||
* IEEE 1003.1 (2004), pass a non-const pointer. */
|
||||
@@ -158,15 +157,14 @@ static const char *convert_tofrom_fs(iconv_t convd, const char *name)
|
||||
const char *inbuf = name;
|
||||
#endif
|
||||
|
||||
char *outbuf = buf;
|
||||
size_t outlen = sizeof(buf) - 1;
|
||||
size_t inlen = strlen(name);
|
||||
char *buf = outbuf;
|
||||
|
||||
strecpy(outbuf, name, outbuf + outlen);
|
||||
|
||||
iconv(convd, nullptr, nullptr, nullptr, nullptr);
|
||||
if (iconv(convd, &inbuf, &inlen, &outbuf, &outlen) == (size_t)(-1)) {
|
||||
DEBUG(misc, 0, "[iconv] error converting '%s'. Errno %d", name, errno);
|
||||
Debug(misc, 0, "[iconv] error converting '{}'. Errno {}", name, errno);
|
||||
}
|
||||
|
||||
*outbuf = '\0';
|
||||
@@ -179,46 +177,45 @@ static const char *convert_tofrom_fs(iconv_t convd, const char *name)
|
||||
* @param name pointer to a valid string that will be converted
|
||||
* @return pointer to a new stringbuffer that contains the converted string
|
||||
*/
|
||||
const char *OTTD2FS(const char *name)
|
||||
std::string OTTD2FS(const std::string &name)
|
||||
{
|
||||
static iconv_t convd = (iconv_t)(-1);
|
||||
char buf[1024] = {};
|
||||
|
||||
if (convd == (iconv_t)(-1)) {
|
||||
const char *env = GetLocalCode();
|
||||
convd = iconv_open(env, INTERNALCODE);
|
||||
if (convd == (iconv_t)(-1)) {
|
||||
DEBUG(misc, 0, "[iconv] conversion from codeset '%s' to '%s' unsupported", INTERNALCODE, env);
|
||||
Debug(misc, 0, "[iconv] conversion from codeset '{}' to '{}' unsupported", INTERNALCODE, env);
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
return convert_tofrom_fs(convd, name);
|
||||
return convert_tofrom_fs(convd, name.c_str(), buf, lengthof(buf));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to OpenTTD's encoding from that of the local environment
|
||||
* @param name pointer to a valid string that will be converted
|
||||
* @param name valid string that will be converted
|
||||
* @return pointer to a new stringbuffer that contains the converted string
|
||||
*/
|
||||
const char *FS2OTTD(const char *name)
|
||||
std::string FS2OTTD(const std::string &name)
|
||||
{
|
||||
static iconv_t convd = (iconv_t)(-1);
|
||||
char buf[1024] = {};
|
||||
|
||||
if (convd == (iconv_t)(-1)) {
|
||||
const char *env = GetLocalCode();
|
||||
convd = iconv_open(INTERNALCODE, env);
|
||||
if (convd == (iconv_t)(-1)) {
|
||||
DEBUG(misc, 0, "[iconv] conversion from codeset '%s' to '%s' unsupported", env, INTERNALCODE);
|
||||
Debug(misc, 0, "[iconv] conversion from codeset '{}' to '{}' unsupported", env, INTERNALCODE);
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
return convert_tofrom_fs(convd, name);
|
||||
return convert_tofrom_fs(convd, name.c_str(), buf, lengthof(buf));
|
||||
}
|
||||
|
||||
#else
|
||||
const char *FS2OTTD(const char *name) {return name;}
|
||||
const char *OTTD2FS(const char *name) {return name;}
|
||||
#endif /* WITH_ICONV */
|
||||
|
||||
void ShowInfo(const char *str)
|
||||
@@ -246,7 +243,7 @@ void CocoaReleaseAutoreleasePool();
|
||||
int CDECL main(int argc, char *argv[])
|
||||
{
|
||||
/* Make sure our arguments contain only valid UTF-8 characters. */
|
||||
for (int i = 0; i < argc; i++) ValidateString(argv[i]);
|
||||
for (int i = 0; i < argc; i++) StrMakeValidInPlace(argv[i]);
|
||||
|
||||
#ifdef WITH_COCOA
|
||||
CocoaSetupAutoreleasePool();
|
||||
@@ -280,7 +277,7 @@ bool GetClipboardContents(char *buffer, const char *last)
|
||||
}
|
||||
|
||||
char *clip = SDL_GetClipboardText();
|
||||
if (clip != NULL) {
|
||||
if (clip != nullptr) {
|
||||
strecpy(buffer, clip, last);
|
||||
SDL_free(clip);
|
||||
return true;
|
||||
@@ -309,7 +306,7 @@ void OSOpenBrowser(const char *url)
|
||||
args[1] = url;
|
||||
args[2] = nullptr;
|
||||
execvp(args[0], const_cast<char * const *>(args));
|
||||
DEBUG(misc, 0, "Failed to open url: %s", url);
|
||||
Debug(misc, 0, "Failed to open url: {}", url);
|
||||
exit(0);
|
||||
}
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#include <signal.h>
|
||||
#include <psapi.h>
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
@@ -189,7 +190,7 @@ static char *PrintModuleInfo(char *output, const char *last, HMODULE mod)
|
||||
GetModuleFileName(mod, buffer, MAX_PATH);
|
||||
GetFileInfo(&dfi, buffer);
|
||||
output += seprintf(output, last, " %-20s handle: %p size: %d crc: %.8X date: %d-%.2d-%.2d %.2d:%.2d:%.2d\n",
|
||||
FS2OTTD(buffer),
|
||||
FS2OTTD(buffer).c_str(),
|
||||
mod,
|
||||
dfi.size,
|
||||
dfi.crc32,
|
||||
@@ -206,25 +207,19 @@ static char *PrintModuleInfo(char *output, const char *last, HMODULE mod)
|
||||
/* virtual */ char *CrashLogWindows::LogModules(char *output, const char *last) const
|
||||
{
|
||||
MakeCRCTable(AllocaM(uint32, 256));
|
||||
BOOL (WINAPI *EnumProcessModules)(HANDLE, HMODULE*, DWORD, LPDWORD);
|
||||
|
||||
output += seprintf(output, last, "Module information:\n");
|
||||
|
||||
if (LoadLibraryList((Function*)&EnumProcessModules, "psapi.dll\0EnumProcessModules\0\0")) {
|
||||
HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
|
||||
if (proc != nullptr) {
|
||||
HMODULE modules[100];
|
||||
DWORD needed;
|
||||
BOOL res;
|
||||
BOOL res = EnumProcessModules(proc, modules, sizeof(modules), &needed);
|
||||
CloseHandle(proc);
|
||||
if (res) {
|
||||
size_t count = std::min<DWORD>(needed / sizeof(HMODULE), lengthof(modules));
|
||||
|
||||
HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
|
||||
if (proc != nullptr) {
|
||||
res = EnumProcessModules(proc, modules, sizeof(modules), &needed);
|
||||
CloseHandle(proc);
|
||||
if (res) {
|
||||
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");
|
||||
}
|
||||
for (size_t i = 0; i != count; i++) output = PrintModuleInfo(output, last, modules[i]);
|
||||
return output + seprintf(output, last, "\n");
|
||||
}
|
||||
}
|
||||
output = PrintModuleInfo(output, last, nullptr);
|
||||
@@ -373,22 +368,7 @@ static const uint MAX_FRAMES = 64;
|
||||
|
||||
char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) const
|
||||
{
|
||||
#define M(x) x "\0"
|
||||
static const char dbg_import[] =
|
||||
M("dbghelp.dll")
|
||||
M("SymInitialize")
|
||||
M("SymSetOptions")
|
||||
M("SymCleanup")
|
||||
M("StackWalk64")
|
||||
M("SymFunctionTableAccess64")
|
||||
M("SymGetModuleBase64")
|
||||
M("SymGetModuleInfo64")
|
||||
M("SymGetSymFromAddr64")
|
||||
M("SymGetLineFromAddr64")
|
||||
M("")
|
||||
;
|
||||
#undef M
|
||||
|
||||
DllLoader dbghelp(L"dbghelp.dll");
|
||||
struct ProcPtrs {
|
||||
BOOL (WINAPI * pSymInitialize)(HANDLE, PCSTR, BOOL);
|
||||
BOOL (WINAPI * pSymSetOptions)(DWORD);
|
||||
@@ -399,12 +379,22 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c
|
||||
BOOL (WINAPI * pSymGetModuleInfo64)(HANDLE, DWORD64, PIMAGEHLP_MODULE64);
|
||||
BOOL (WINAPI * pSymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
|
||||
BOOL (WINAPI * pSymGetLineFromAddr64)(HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64);
|
||||
} proc;
|
||||
} proc = {
|
||||
dbghelp.GetProcAddress("SymInitialize"),
|
||||
dbghelp.GetProcAddress("SymSetOptions"),
|
||||
dbghelp.GetProcAddress("SymCleanup"),
|
||||
dbghelp.GetProcAddress("StackWalk64"),
|
||||
dbghelp.GetProcAddress("SymFunctionTableAccess64"),
|
||||
dbghelp.GetProcAddress("SymGetModuleBase64"),
|
||||
dbghelp.GetProcAddress("SymGetModuleInfo64"),
|
||||
dbghelp.GetProcAddress("SymGetSymFromAddr64"),
|
||||
dbghelp.GetProcAddress("SymGetLineFromAddr64"),
|
||||
};
|
||||
|
||||
buffer += seprintf(buffer, last, "\nDecoded stack trace:\n");
|
||||
|
||||
/* Try to load the functions from the DLL, if that fails because of a too old dbghelp.dll, just skip it. */
|
||||
if (LoadLibraryList((Function*)&proc, dbg_import)) {
|
||||
if (dbghelp.Success()) {
|
||||
/* Initialize symbol handler. */
|
||||
HANDLE hCur = GetCurrentProcess();
|
||||
proc.pSymInitialize(hCur, nullptr, TRUE);
|
||||
@@ -491,17 +481,17 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c
|
||||
/* virtual */ int CrashLogWindows::WriteCrashDump(char *filename, const char *filename_last) const
|
||||
{
|
||||
int ret = 0;
|
||||
HMODULE dbghelp = LoadLibrary(L"dbghelp.dll");
|
||||
if (dbghelp != nullptr) {
|
||||
DllLoader dbghelp(L"dbghelp.dll");
|
||||
if (dbghelp.Success()) {
|
||||
typedef BOOL (WINAPI *MiniDumpWriteDump_t)(HANDLE, DWORD, HANDLE,
|
||||
MINIDUMP_TYPE,
|
||||
CONST PMINIDUMP_EXCEPTION_INFORMATION,
|
||||
CONST PMINIDUMP_USER_STREAM_INFORMATION,
|
||||
CONST PMINIDUMP_CALLBACK_INFORMATION);
|
||||
MiniDumpWriteDump_t funcMiniDumpWriteDump = (MiniDumpWriteDump_t)GetProcAddress(dbghelp, "MiniDumpWriteDump");
|
||||
MiniDumpWriteDump_t funcMiniDumpWriteDump = dbghelp.GetProcAddress("MiniDumpWriteDump");
|
||||
if (funcMiniDumpWriteDump != nullptr) {
|
||||
seprintf(filename, filename_last, "%scrash.dmp", _personal_dir.c_str());
|
||||
HANDLE file = CreateFile(OTTD2FS(filename), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, 0);
|
||||
HANDLE file = CreateFile(OTTD2FS(filename).c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, 0);
|
||||
HANDLE proc = GetCurrentProcess();
|
||||
DWORD procid = GetCurrentProcessId();
|
||||
MINIDUMP_EXCEPTION_INFORMATION mdei;
|
||||
@@ -524,7 +514,6 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
FreeLibrary(dbghelp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -638,7 +627,7 @@ static void CDECL CustomAbort(int signal)
|
||||
mov safe_esp, esp
|
||||
}
|
||||
# else
|
||||
asm("movl %esp, _safe_esp");
|
||||
asm("movl %%esp, %0" : "=rm" (safe_esp));
|
||||
# endif
|
||||
_safe_esp = safe_esp;
|
||||
#endif
|
||||
@@ -689,7 +678,8 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA
|
||||
switch (msg) {
|
||||
case WM_INITDIALOG: {
|
||||
/* We need to put the crash-log in a separate buffer because the default
|
||||
* buffer in OTTD2FS is not large enough (512 chars) */
|
||||
* buffer in MB_TO_WIDE is not large enough (512 chars) */
|
||||
wchar_t filenamebuf[MAX_PATH * 2];
|
||||
wchar_t crash_msgW[lengthof(CrashLogWindows::current->crashlog)];
|
||||
/* Convert unix -> dos newlines because the edit box only supports that properly :( */
|
||||
const char *unix_nl = CrashLogWindows::current->crashlog;
|
||||
@@ -704,19 +694,23 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA
|
||||
|
||||
/* Add path to crash.log and crash.dmp (if any) to the crash window text */
|
||||
size_t len = wcslen(_crash_desc) + 2;
|
||||
len += wcslen(OTTD2FS(CrashLogWindows::current->crashlog_filename)) + 2;
|
||||
len += wcslen(OTTD2FS(CrashLogWindows::current->crashdump_filename)) + 2;
|
||||
len += wcslen(OTTD2FS(CrashLogWindows::current->screenshot_filename)) + 1;
|
||||
len += wcslen(convert_to_fs(CrashLogWindows::current->crashlog_filename, filenamebuf, lengthof(filenamebuf))) + 2;
|
||||
len += wcslen(convert_to_fs(CrashLogWindows::current->crashdump_filename, filenamebuf, lengthof(filenamebuf))) + 2;
|
||||
len += wcslen(convert_to_fs(CrashLogWindows::current->screenshot_filename, filenamebuf, lengthof(filenamebuf))) + 1;
|
||||
|
||||
wchar_t *text = AllocaM(wchar_t, len);
|
||||
_snwprintf(text, len, _crash_desc, OTTD2FS(CrashLogWindows::current->crashlog_filename));
|
||||
if (OTTD2FS(CrashLogWindows::current->crashdump_filename)[0] != L'\0') {
|
||||
wcscat(text, L"\n");
|
||||
wcscat(text, OTTD2FS(CrashLogWindows::current->crashdump_filename));
|
||||
int printed = _snwprintf(text, len, _crash_desc, convert_to_fs(CrashLogWindows::current->crashlog_filename, filenamebuf, lengthof(filenamebuf)));
|
||||
if (printed < 0 || (size_t)printed > len) {
|
||||
MessageBox(wnd, L"Catastrophic failure trying to display crash message. Could not perform text formatting.", L"OpenTTD", MB_ICONERROR);
|
||||
return FALSE;
|
||||
}
|
||||
if (OTTD2FS(CrashLogWindows::current->screenshot_filename)[0] != L'\0') {
|
||||
if (convert_to_fs(CrashLogWindows::current->crashdump_filename, filenamebuf, lengthof(filenamebuf))[0] != L'\0') {
|
||||
wcscat(text, L"\n");
|
||||
wcscat(text, OTTD2FS(CrashLogWindows::current->screenshot_filename));
|
||||
wcscat(text, filenamebuf);
|
||||
}
|
||||
if (convert_to_fs(CrashLogWindows::current->screenshot_filename, filenamebuf, lengthof(filenamebuf))[0] != L'\0') {
|
||||
wcscat(text, L"\n");
|
||||
wcscat(text, filenamebuf);
|
||||
}
|
||||
|
||||
SetDlgItemText(wnd, 10, text);
|
||||
@@ -730,18 +724,20 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA
|
||||
CrashLog::AfterCrashLogCleanup();
|
||||
ExitProcess(2);
|
||||
case 13: // Emergency save
|
||||
wchar_t filenamebuf[MAX_PATH * 2];
|
||||
char filename[MAX_PATH];
|
||||
if (CrashLogWindows::current->WriteSavegame(filename, lastof(filename))) {
|
||||
size_t len = wcslen(_save_succeeded) + wcslen(OTTD2FS(filename)) + 1;
|
||||
convert_to_fs(filename, filenamebuf, lengthof(filenamebuf));
|
||||
size_t len = lengthof(_save_succeeded) + wcslen(filenamebuf) + 1;
|
||||
wchar_t *text = AllocaM(wchar_t, len);
|
||||
_snwprintf(text, len, _save_succeeded, OTTD2FS(filename));
|
||||
_snwprintf(text, len, _save_succeeded, filenamebuf);
|
||||
MessageBox(wnd, text, L"Save successful", MB_ICONINFORMATION);
|
||||
} else {
|
||||
MessageBox(wnd, L"Save failed", L"Save failed", MB_ICONINFORMATION);
|
||||
}
|
||||
break;
|
||||
case 15: // Expand window to show crash-message
|
||||
_expanded ^= 1;
|
||||
_expanded = !_expanded;
|
||||
SetWndSize(wnd, _expanded);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -78,12 +78,12 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
|
||||
ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, FONT_DIR_NT, 0, KEY_READ, &hKey);
|
||||
|
||||
if (ret != ERROR_SUCCESS) {
|
||||
DEBUG(freetype, 0, "Cannot open registry key HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts");
|
||||
Debug(freetype, 0, "Cannot open registry key HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Convert font name to file system encoding. */
|
||||
wchar_t *font_namep = wcsdup(OTTD2FS(font_name));
|
||||
wchar_t *font_namep = wcsdup(OTTD2FS(font_name).c_str());
|
||||
|
||||
for (index = 0;; index++) {
|
||||
wchar_t *s;
|
||||
@@ -113,7 +113,7 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
|
||||
}
|
||||
|
||||
if (!SUCCEEDED(SHGetFolderPath(nullptr, CSIDL_FONTS, nullptr, SHGFP_TYPE_CURRENT, vbuffer))) {
|
||||
DEBUG(freetype, 0, "SHGetFolderPath cannot return fonts directory");
|
||||
Debug(freetype, 0, "SHGetFolderPath cannot return fonts directory");
|
||||
goto folder_error;
|
||||
}
|
||||
|
||||
@@ -334,17 +334,17 @@ static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXT
|
||||
|
||||
info->callback->SetFontNames(info->settings, font_name, &logfont->elfLogFont);
|
||||
if (info->callback->FindMissingGlyphs()) return 1;
|
||||
DEBUG(freetype, 1, "Fallback font: %s (%s)", font_name, english_name);
|
||||
Debug(freetype, 1, "Fallback font: {} ({})", font_name, english_name);
|
||||
return 0; // stop enumerating
|
||||
}
|
||||
|
||||
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback)
|
||||
{
|
||||
DEBUG(freetype, 1, "Trying fallback fonts");
|
||||
Debug(freetype, 1, "Trying fallback fonts");
|
||||
EFCParam langInfo;
|
||||
if (GetLocaleInfo(MAKELCID(winlangid, SORT_DEFAULT), LOCALE_FONTSIGNATURE, (LPTSTR)&langInfo.locale, sizeof(langInfo.locale) / sizeof(wchar_t)) == 0) {
|
||||
/* Invalid langid or some other mysterious error, can't determine fallback font. */
|
||||
DEBUG(freetype, 1, "Can't get locale info for fallback font (langid=0x%x)", winlangid);
|
||||
Debug(freetype, 1, "Can't get locale info for fallback font (langid=0x{:x})", winlangid);
|
||||
return false;
|
||||
}
|
||||
langInfo.settings = settings;
|
||||
@@ -377,6 +377,7 @@ Win32FontCache::Win32FontCache(FontSize fs, const LOGFONT &logfont, int pixels)
|
||||
{
|
||||
this->dc = CreateCompatibleDC(nullptr);
|
||||
this->SetFontSize(fs, pixels);
|
||||
this->fontname = FS2OTTD(this->logfont.lfFaceName);
|
||||
}
|
||||
|
||||
Win32FontCache::~Win32FontCache()
|
||||
@@ -438,7 +439,7 @@ void Win32FontCache::SetFontSize(FontSize fs, int pixels)
|
||||
this->glyph_size.cx = otm->otmTextMetrics.tmMaxCharWidth;
|
||||
this->glyph_size.cy = otm->otmTextMetrics.tmHeight;
|
||||
|
||||
DEBUG(freetype, 2, "Loaded font '%s' with size %d", FS2OTTD((LPTSTR)((BYTE *)otm + (ptrdiff_t)otm->otmpFullName)), pixels);
|
||||
Debug(freetype, 2, "Loaded font '{}' with size {}", FS2OTTD((LPWSTR)((BYTE *)otm + (ptrdiff_t)otm->otmpFullName)), pixels);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -541,10 +542,10 @@ void Win32FontCache::ClearFontCache()
|
||||
/* Convert characters outside of the BMP into surrogate pairs. */
|
||||
WCHAR chars[2];
|
||||
if (key >= 0x010000U) {
|
||||
chars[0] = (WCHAR)(((key - 0x010000U) >> 10) + 0xD800);
|
||||
chars[1] = (WCHAR)(((key - 0x010000U) & 0x3FF) + 0xDC00);
|
||||
chars[0] = (wchar_t)(((key - 0x010000U) >> 10) + 0xD800);
|
||||
chars[1] = (wchar_t)(((key - 0x010000U) & 0x3FF) + 0xDC00);
|
||||
} else {
|
||||
chars[0] = (WCHAR)(key & 0xFFFF);
|
||||
chars[0] = (wchar_t)(key & 0xFFFF);
|
||||
}
|
||||
|
||||
WORD glyphs[2] = { 0, 0 };
|
||||
@@ -587,8 +588,9 @@ void LoadWin32Font(FontSize fs)
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
|
||||
if (StrEmpty(settings->font)) return;
|
||||
if (settings->font.empty()) return;
|
||||
|
||||
const char *font_name = settings->font.c_str();
|
||||
LOGFONT logfont;
|
||||
MemSetT(&logfont, 0);
|
||||
logfont.lfPitchAndFamily = fs == FS_MONO ? FIXED_PITCH : VARIABLE_PITCH;
|
||||
@@ -598,19 +600,19 @@ void LoadWin32Font(FontSize fs)
|
||||
|
||||
if (settings->os_handle != nullptr) {
|
||||
logfont = *(const LOGFONT *)settings->os_handle;
|
||||
} else if (strchr(settings->font, '.') != nullptr) {
|
||||
} else if (strchr(font_name, '.') != nullptr) {
|
||||
/* Might be a font file name, try load it. */
|
||||
|
||||
wchar_t fontPath[MAX_PATH] = {};
|
||||
|
||||
/* See if this is an absolute path. */
|
||||
if (FileExists(settings->font)) {
|
||||
convert_to_fs(settings->font, fontPath, lengthof(fontPath), false);
|
||||
convert_to_fs(font_name, fontPath, lengthof(fontPath));
|
||||
} else {
|
||||
/* Scan the search-paths to see if it can be found. */
|
||||
std::string full_font = FioFindFullPath(BASE_DIR, settings->font);
|
||||
std::string full_font = FioFindFullPath(BASE_DIR, font_name);
|
||||
if (!full_font.empty()) {
|
||||
convert_to_fs(full_font.c_str(), fontPath, lengthof(fontPath), false);
|
||||
convert_to_fs(font_name, fontPath, lengthof(fontPath));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -618,8 +620,9 @@ void LoadWin32Font(FontSize fs)
|
||||
if (AddFontResourceEx(fontPath, FR_PRIVATE, 0) != 0) {
|
||||
/* Try a nice little undocumented function first for getting the internal font name.
|
||||
* Some documentation is found at: http://www.undocprint.org/winspool/getfontresourceinfo */
|
||||
static DllLoader _gdi32(L"gdi32.dll");
|
||||
typedef BOOL(WINAPI *PFNGETFONTRESOURCEINFO)(LPCTSTR, LPDWORD, LPVOID, DWORD);
|
||||
static PFNGETFONTRESOURCEINFO GetFontResourceInfo = (PFNGETFONTRESOURCEINFO)GetProcAddress(GetModuleHandle(L"Gdi32"), "GetFontResourceInfoW");
|
||||
static PFNGETFONTRESOURCEINFO GetFontResourceInfo = _gdi32.GetProcAddress("GetFontResourceInfoW");
|
||||
|
||||
if (GetFontResourceInfo != nullptr) {
|
||||
/* Try to query an array of LOGFONTs that describe the file. */
|
||||
@@ -638,22 +641,22 @@ void LoadWin32Font(FontSize fs)
|
||||
_wsplitpath(fontPath, nullptr, nullptr, fname, nullptr);
|
||||
|
||||
wcsncpy_s(logfont.lfFaceName, lengthof(logfont.lfFaceName), fname, _TRUNCATE);
|
||||
logfont.lfWeight = strcasestr(settings->font, " bold") != nullptr || strcasestr(settings->font, "-bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts.
|
||||
logfont.lfWeight = strcasestr(font_name, " bold") != nullptr || strcasestr(font_name, "-bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts.
|
||||
}
|
||||
} else {
|
||||
ShowInfoF("Unable to load file '%s' for %s font, using default windows font selection instead", settings->font, SIZE_TO_NAME[fs]);
|
||||
ShowInfoF("Unable to load file '%s' for %s font, using default windows font selection instead", font_name, SIZE_TO_NAME[fs]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (logfont.lfFaceName[0] == 0) {
|
||||
logfont.lfWeight = strcasestr(settings->font, " bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts.
|
||||
convert_to_fs(settings->font, logfont.lfFaceName, lengthof(logfont.lfFaceName), false);
|
||||
logfont.lfWeight = strcasestr(font_name, " bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts.
|
||||
convert_to_fs(font_name, logfont.lfFaceName, lengthof(logfont.lfFaceName));
|
||||
}
|
||||
|
||||
HFONT font = CreateFontIndirect(&logfont);
|
||||
if (font == nullptr) {
|
||||
ShowInfoF("Unable to use '%s' for %s font, Win32 reported error 0x%lX, using sprite font instead", settings->font, SIZE_TO_NAME[fs], GetLastError());
|
||||
ShowInfoF("Unable to use '%s' for %s font, Win32 reported error 0x%lX, using sprite font instead", font_name, SIZE_TO_NAME[fs], GetLastError());
|
||||
return;
|
||||
}
|
||||
DeleteObject(font);
|
||||
|
||||
@@ -21,6 +21,7 @@ private:
|
||||
HDC dc = nullptr; ///< Cached GDI device context.
|
||||
HGDIOBJ old_font; ///< Old font selected into the GDI context.
|
||||
SIZE glyph_size; ///< Maximum size of regular glyphs.
|
||||
std::string fontname; ///< Cached copy of this->logfont.lfFaceName
|
||||
|
||||
void SetFontSize(FontSize fs, int pixels);
|
||||
|
||||
@@ -33,7 +34,7 @@ public:
|
||||
~Win32FontCache();
|
||||
void ClearFontCache() override;
|
||||
GlyphID MapCharToGlyph(WChar key) override;
|
||||
const char *GetFontName() override { return FS2OTTD(this->logfont.lfFaceName); }
|
||||
const char *GetFontName() override { return this->fontname.c_str(); }
|
||||
const void *GetOSHandle() override { return &this->logfont; }
|
||||
};
|
||||
|
||||
|
||||
@@ -77,8 +77,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION ${REV_MAJOR},${REV_MINOR},${REV_BUILD},${REV_ISODATE}
|
||||
PRODUCTVERSION ${REV_MAJOR},${REV_MINOR},${REV_BUILD},${REV_ISODATE}
|
||||
FILEVERSION ${REV_MAJOR},${REV_MINOR},0,${REV_ISODATE}
|
||||
PRODUCTVERSION ${REV_MAJOR},${REV_MINOR},0,${REV_ISODATE}
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
||||
@@ -144,7 +144,7 @@ void UniscribeResetScriptCache(FontSize size)
|
||||
/** Load the matching native Windows font. */
|
||||
static HFONT HFontFromFont(Font *font)
|
||||
{
|
||||
if (font->fc->GetOSHandle() != nullptr) return CreateFontIndirect((const PLOGFONT)font->fc->GetOSHandle());
|
||||
if (font->fc->GetOSHandle() != nullptr) return CreateFontIndirect(reinterpret_cast<PLOGFONT>(const_cast<void *>(font->fc->GetOSHandle())));
|
||||
|
||||
LOGFONT logfont;
|
||||
ZeroMemory(&logfont, sizeof(LOGFONT));
|
||||
|
||||
+42
-90
@@ -50,39 +50,15 @@ bool MyShowCursor(bool show, bool toggle)
|
||||
return !show;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function needed by dynamically loading libraries
|
||||
*/
|
||||
bool LoadLibraryList(Function proc[], const char *dll)
|
||||
{
|
||||
while (*dll != '\0') {
|
||||
HMODULE lib;
|
||||
lib = LoadLibrary(OTTD2FS(dll));
|
||||
|
||||
if (lib == nullptr) return false;
|
||||
for (;;) {
|
||||
FARPROC p;
|
||||
|
||||
while (*dll++ != '\0') { /* Nothing */ }
|
||||
if (*dll == '\0') break;
|
||||
p = GetProcAddress(lib, dll);
|
||||
if (p == nullptr) return false;
|
||||
*proc++ = (Function)p;
|
||||
}
|
||||
dll++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ShowOSErrorBox(const char *buf, bool system)
|
||||
{
|
||||
MyShowCursor(true);
|
||||
MessageBox(GetActiveWindow(), OTTD2FS(buf), L"Error!", MB_ICONSTOP | MB_TASKMODAL);
|
||||
MessageBox(GetActiveWindow(), OTTD2FS(buf).c_str(), L"Error!", MB_ICONSTOP | MB_TASKMODAL);
|
||||
}
|
||||
|
||||
void OSOpenBrowser(const char *url)
|
||||
{
|
||||
ShellExecute(GetActiveWindow(), L"open", OTTD2FS(url), nullptr, nullptr, SW_SHOWNORMAL);
|
||||
ShellExecute(GetActiveWindow(), L"open", OTTD2FS(url).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
|
||||
}
|
||||
|
||||
/* Code below for windows version of opendir/readdir/closedir copied and
|
||||
@@ -141,14 +117,14 @@ DIR *opendir(const wchar_t *path)
|
||||
if ((fa != INVALID_FILE_ATTRIBUTES) && (fa & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
d = dir_calloc();
|
||||
if (d != nullptr) {
|
||||
wchar_t search_path[MAX_PATH];
|
||||
std::wstring search_path = path;
|
||||
bool slash = path[wcslen(path) - 1] == '\\';
|
||||
|
||||
/* build search path for FindFirstFile, try not to append additional slashes
|
||||
* as it throws Win9x off its groove for root directories */
|
||||
_snwprintf(search_path, lengthof(search_path), L"%s%s*", path, slash ? L"" : L"\\");
|
||||
*lastof(search_path) = '\0';
|
||||
d->hFind = FindFirstFile(search_path, &d->fd);
|
||||
if (!slash) search_path += L"\\";
|
||||
search_path += L"*";
|
||||
d->hFind = FindFirstFile(search_path.c_str(), &d->fd);
|
||||
|
||||
if (d->hFind != INVALID_HANDLE_VALUE ||
|
||||
GetLastError() == ERROR_NO_MORE_FILES) { // the directory is empty
|
||||
@@ -209,7 +185,7 @@ void FiosGetDrives(FileList &file_list)
|
||||
|
||||
GetLogicalDriveStrings(lengthof(drives), drives);
|
||||
for (s = drives; *s != '\0';) {
|
||||
FiosItem *fios = file_list.Append();
|
||||
FiosItem *fios = &file_list.emplace_back();
|
||||
fios->type = FIOS_TYPE_DRIVE;
|
||||
fios->mtime = 0;
|
||||
seprintf(fios->name, lastof(fios->name), "%c:", s[0] & 0xFF);
|
||||
@@ -246,7 +222,7 @@ bool FiosGetDiskFreeSpace(const char *path, uint64 *tot)
|
||||
UINT sem = SetErrorMode(SEM_FAILCRITICALERRORS); // disable 'no-disk' message box
|
||||
|
||||
ULARGE_INTEGER bytes_free;
|
||||
bool retval = GetDiskFreeSpaceEx(OTTD2FS(path), &bytes_free, nullptr, nullptr);
|
||||
bool retval = GetDiskFreeSpaceEx(OTTD2FS(path).c_str(), &bytes_free, nullptr, nullptr);
|
||||
if (retval && tot != nullptr) *tot = bytes_free.QuadPart;
|
||||
|
||||
SetErrorMode(sem); // reset previous setting
|
||||
@@ -415,7 +391,10 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
|
||||
/* Convert the command line to UTF-8. We need a dedicated buffer
|
||||
* for this because argv[] points into this buffer and this needs to
|
||||
* be available between subsequent calls to FS2OTTD(). */
|
||||
char *cmdline = stredup(FS2OTTD(GetCommandLine()));
|
||||
char *cmdline = stredup(FS2OTTD(GetCommandLine()).c_str());
|
||||
|
||||
/* Set the console codepage to UTF-8. */
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
|
||||
#if defined(_DEBUG)
|
||||
CreateConsole();
|
||||
@@ -429,7 +408,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
|
||||
argc = ParseCommandLine(cmdline, argv, lengthof(argv));
|
||||
|
||||
/* Make sure our arguments contain only valid UTF-8 characters. */
|
||||
for (int i = 0; i < argc; i++) ValidateString(argv[i]);
|
||||
for (int i = 0; i < argc; i++) StrMakeValidInPlace(argv[i]);
|
||||
|
||||
openttd_main(argc, argv);
|
||||
|
||||
@@ -495,7 +474,7 @@ void DetermineBasePaths(const char *exe)
|
||||
wchar_t config_dir[MAX_PATH];
|
||||
wcsncpy(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());
|
||||
Debug(misc, 0, "GetFullPathName failed ({})", GetLastError());
|
||||
_searchpaths[SP_WORKING_DIR].clear();
|
||||
} else {
|
||||
std::string tmp(FS2OTTD(config_dir));
|
||||
@@ -507,13 +486,13 @@ void DetermineBasePaths(const char *exe)
|
||||
}
|
||||
|
||||
if (!GetModuleFileName(nullptr, path, lengthof(path))) {
|
||||
DEBUG(misc, 0, "GetModuleFileName failed (%lu)\n", GetLastError());
|
||||
Debug(misc, 0, "GetModuleFileName failed ({})", GetLastError());
|
||||
_searchpaths[SP_BINARY_DIR].clear();
|
||||
} else {
|
||||
wchar_t exec_dir[MAX_PATH];
|
||||
wcsncpy(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());
|
||||
Debug(misc, 0, "GetFullPathName failed ({})", GetLastError());
|
||||
_searchpaths[SP_BINARY_DIR].clear();
|
||||
} else {
|
||||
std::string tmp(FS2OTTD(exec_dir));
|
||||
@@ -553,34 +532,40 @@ bool GetClipboardContents(char *buffer, const char *last)
|
||||
|
||||
|
||||
/**
|
||||
* Convert to OpenTTD's encoding from wide characters.
|
||||
* Convert to OpenTTD's encoding from a wide string.
|
||||
* OpenTTD internal encoding is UTF8.
|
||||
* The returned value's contents can only be guaranteed until the next call to
|
||||
* this function. So if the value is needed for anything else, use convert_from_fs
|
||||
* @param name pointer to a valid string that will be converted (local, or wide)
|
||||
* @return pointer to the converted string; if failed string is of zero-length
|
||||
* @param name valid string that will be converted (local, or wide)
|
||||
* @return converted string; if failed string is of zero-length
|
||||
* @see the current code-page comes from video\win32_v.cpp, event-notification
|
||||
* WM_INPUTLANGCHANGE
|
||||
*/
|
||||
const char *FS2OTTD(const wchar_t *name)
|
||||
std::string FS2OTTD(const std::wstring &name)
|
||||
{
|
||||
static char utf8_buf[512];
|
||||
return convert_from_fs(name, utf8_buf, lengthof(utf8_buf));
|
||||
int name_len = (name.length() >= INT_MAX) ? INT_MAX : (int)name.length();
|
||||
int len = WideCharToMultiByte(CP_UTF8, 0, name.c_str(), name_len, nullptr, 0, nullptr, nullptr);
|
||||
if (len <= 0) return std::string();
|
||||
char *utf8_buf = AllocaM(char, len + 1);
|
||||
utf8_buf[len] = '\0';
|
||||
WideCharToMultiByte(CP_UTF8, 0, name.c_str(), name_len, utf8_buf, len, nullptr, nullptr);
|
||||
return std::string(utf8_buf, static_cast<size_t>(len));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from OpenTTD's encoding to wide characters.
|
||||
* Convert from OpenTTD's encoding to a wide string.
|
||||
* OpenTTD internal encoding is UTF8.
|
||||
* The returned value's contents can only be guaranteed until the next call to
|
||||
* this function. So if the value is needed for anything else, use convert_from_fs
|
||||
* @param name pointer to a valid string that will be converted (UTF8)
|
||||
* @param name valid string that will be converted (UTF8)
|
||||
* @param console_cp convert to the console encoding instead of the normal system encoding.
|
||||
* @return pointer to the converted string; if failed string is of zero-length
|
||||
* @return converted string; if failed string is of zero-length
|
||||
*/
|
||||
const wchar_t *OTTD2FS(const char *name, bool console_cp)
|
||||
std::wstring OTTD2FS(const std::string &name)
|
||||
{
|
||||
static wchar_t system_buf[512];
|
||||
return convert_to_fs(name, system_buf, lengthof(system_buf), console_cp);
|
||||
int name_len = (name.length() >= INT_MAX) ? INT_MAX : (int)name.length();
|
||||
int len = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), name_len, nullptr, 0);
|
||||
if (len <= 0) return std::wstring();
|
||||
wchar_t *system_buf = AllocaM(wchar_t, len + 1);
|
||||
system_buf[len] = L'\0';
|
||||
MultiByteToWideChar(CP_UTF8, 0, name.c_str(), name_len, system_buf, len);
|
||||
return std::wstring(system_buf, static_cast<size_t>(len));
|
||||
}
|
||||
|
||||
|
||||
@@ -594,10 +579,8 @@ const wchar_t *OTTD2FS(const char *name, bool console_cp)
|
||||
*/
|
||||
char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen)
|
||||
{
|
||||
const wchar_t *wide_buf = name;
|
||||
|
||||
/* Convert UTF-16 string to UTF-8. */
|
||||
int len = WideCharToMultiByte(CP_UTF8, 0, wide_buf, -1, utf8_buf, (int)buflen, nullptr, nullptr);
|
||||
int len = WideCharToMultiByte(CP_UTF8, 0, name, -1, utf8_buf, (int)buflen, nullptr, nullptr);
|
||||
if (len == 0) utf8_buf[0] = '\0';
|
||||
|
||||
return utf8_buf;
|
||||
@@ -614,7 +597,7 @@ char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen)
|
||||
* @param console_cp convert to the console encoding instead of the normal system encoding.
|
||||
* @return pointer to system_buf. If conversion fails the string is of zero-length
|
||||
*/
|
||||
wchar_t *convert_to_fs(const char *name, wchar_t *system_buf, size_t buflen, bool console_cp)
|
||||
wchar_t *convert_to_fs(const char *name, wchar_t *system_buf, size_t buflen)
|
||||
{
|
||||
int len = MultiByteToWideChar(CP_UTF8, 0, name, -1, system_buf, (int)buflen);
|
||||
if (len == 0) system_buf[0] = '\0';
|
||||
@@ -675,7 +658,8 @@ int OTTDStringCompare(const char *s1, const char *s2)
|
||||
#endif
|
||||
|
||||
if (first_time) {
|
||||
_CompareStringEx = (PFNCOMPARESTRINGEX)GetProcAddress(GetModuleHandle(L"Kernel32"), "CompareStringEx");
|
||||
static DllLoader _kernel32(L"Kernel32.dll");
|
||||
_CompareStringEx = _kernel32.GetProcAddress("CompareStringEx");
|
||||
first_time = false;
|
||||
}
|
||||
|
||||
@@ -703,38 +687,6 @@ int OTTDStringCompare(const char *s1, const char *s2)
|
||||
return CompareString(MAKELCID(_current_language->winlangid, SORT_DEFAULT), NORM_IGNORECASE, s1_buf, -1, s2_buf, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the current Windows version Vista or later?
|
||||
* @return True if the current Windows is Vista or later.
|
||||
*/
|
||||
bool IsWindowsVistaOrGreater()
|
||||
{
|
||||
typedef BOOL (WINAPI * LPVERIFYVERSIONINFO)(LPOSVERSIONINFOEX, DWORD, DWORDLONG);
|
||||
typedef ULONGLONG (NTAPI * LPVERSETCONDITIONMASK)(ULONGLONG, DWORD, BYTE);
|
||||
#ifdef UNICODE
|
||||
static LPVERIFYVERSIONINFO _VerifyVersionInfo = (LPVERIFYVERSIONINFO)GetProcAddress(GetModuleHandle(_T("Kernel32")), "VerifyVersionInfoW");
|
||||
#else
|
||||
static LPVERIFYVERSIONINFO _VerifyVersionInfo = (LPVERIFYVERSIONINFO)GetProcAddress(GetModuleHandle(_T("Kernel32")), "VerifyVersionInfoA");
|
||||
#endif
|
||||
static LPVERSETCONDITIONMASK _VerSetConditionMask = (LPVERSETCONDITIONMASK)GetProcAddress(GetModuleHandle(_T("Kernel32")), "VerSetConditionMask");
|
||||
|
||||
if (_VerifyVersionInfo != nullptr && _VerSetConditionMask != nullptr) {
|
||||
OSVERSIONINFOEX osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 };
|
||||
DWORDLONG dwlConditionMask = 0;
|
||||
dwlConditionMask = _VerSetConditionMask(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
dwlConditionMask = _VerSetConditionMask(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
dwlConditionMask = _VerSetConditionMask(dwlConditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
|
||||
osvi.dwMajorVersion = 6;
|
||||
osvi.dwMinorVersion = 0;
|
||||
osvi.wServicePackMajor = 0;
|
||||
|
||||
return _VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
|
||||
} else {
|
||||
return LOBYTE(GetVersion()) >= 6;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* Based on code from MSDN: https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx */
|
||||
const DWORD MS_VC_EXCEPTION = 0x406D1388;
|
||||
|
||||
+42
-8
@@ -13,18 +13,52 @@
|
||||
#include <windows.h>
|
||||
bool MyShowCursor(bool show, bool toggle = false);
|
||||
|
||||
typedef void (*Function)(int);
|
||||
bool LoadLibraryList(Function proc[], const char *dll);
|
||||
class DllLoader {
|
||||
public:
|
||||
explicit DllLoader(LPCTSTR filename)
|
||||
{
|
||||
this->hmodule = ::LoadLibrary(filename);
|
||||
if (this->hmodule == nullptr) this->success = false;
|
||||
}
|
||||
|
||||
|
||||
~DllLoader()
|
||||
{
|
||||
::FreeLibrary(this->hmodule);
|
||||
}
|
||||
|
||||
bool Success() { return this->success; }
|
||||
|
||||
class ProcAddress {
|
||||
public:
|
||||
explicit ProcAddress(void *p) : p(p) {}
|
||||
|
||||
template <typename T, typename = std::enable_if_t<std::is_function_v<T>>>
|
||||
operator T *() const
|
||||
{
|
||||
return reinterpret_cast<T *>(this->p);
|
||||
}
|
||||
|
||||
private:
|
||||
void *p;
|
||||
};
|
||||
|
||||
ProcAddress GetProcAddress(const char *proc_name)
|
||||
{
|
||||
void *p = reinterpret_cast<void *>(::GetProcAddress(this->hmodule, proc_name));
|
||||
if (p == nullptr) this->success = false;
|
||||
return ProcAddress(p);
|
||||
}
|
||||
|
||||
private:
|
||||
HMODULE hmodule = nullptr;
|
||||
bool success = true;
|
||||
};
|
||||
|
||||
char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen);
|
||||
wchar_t *convert_to_fs(const char *name, wchar_t *utf16_buf, size_t buflen, bool console_cp = false);
|
||||
|
||||
#if defined(__MINGW32__) && !defined(__MINGW64__)
|
||||
#define SHGFP_TYPE_CURRENT 0
|
||||
#endif /* __MINGW32__ */
|
||||
wchar_t *convert_to_fs(const char *name, wchar_t *utf16_buf, size_t buflen);
|
||||
|
||||
void Win32SetCurrentLocaleName(const char *iso_code);
|
||||
int OTTDStringCompare(const char *s1, const char *s2);
|
||||
bool IsWindowsVistaOrGreater();
|
||||
|
||||
#endif /* WIN32_H */
|
||||
|
||||
Reference in New Issue
Block a user