More win dep files

This commit is contained in:
Eric Froemling 2021-06-03 14:32:24 -05:00
parent 17d8b1f62d
commit cbb8c134ce
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
5 changed files with 1095 additions and 36 deletions

View File

@ -3933,41 +3933,41 @@
"assets/build/windows/Win32/vc_redist.x86.exe": "https://files.ballistica.net/cache/ba1/1c/e1/4a1a2eddda2f4aebd5f8b64ab08e",
"assets/build/windows/Win32/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/50/8d/bc2600ac9491f1b14d659709451f",
"ballisticacore-windows/Generic/BallisticaCore.ico": "https://files.ballistica.net/cache/ba1/89/c0/e32c7d2a35dc9aef57cc73b0911a",
"ballisticacore-windows/build/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/45/76/12988204e32839b08a160d08bd84",
"build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/2e/f7/b12845cae61171552b89749ecd57",
"ballisticacore-windows/build/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/bb/ef/cbbb2871d6951c4178c51b9168ee",
"build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/e8/15/872df30172235c867eda63d89589",
"build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/74/1d/fc9e33e565475daaac80da5252f0",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/16/0d/63822a96173bf2920c12ab7630c6",
"build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/7c/5c/aecdc845e170b39d2a04d1a9f20d",
"build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/2c/6a/3b1b7d66bac496f6a3b019a13758",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/78/4f/3c6279192f18688bd84bb6a4411b",
"build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/72/09/88243a2824d7367ad0828fba84b6",
"build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/62/f6/aa4a3dc1fca82b269d86b481bcb1",
"build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/9c/7b/ac1a200be0f37078af0991faca3b",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/65/a2/ab7a878985c162e4e98eb62c55e0",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/45/3a/654c7b2e849abdaf42afbafaf175",
"build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/f4/ed/0374312c647056a816b7ce8b6db2",
"build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/f7/f0/4c58353a613a96694b5bbff2991e",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/38/31/dda9f6548c1e69a34fb6863a26c6",
"build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/9e/b9/e7629c8f74f949de760475541530",
"build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/5a/f3/7ed03d9ca862fec1a0ad9aa6ba61",
"build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/9b/c1/39884c20fc3c4f1f0a94f8e7fed3",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/65/e0/f9524f6731668303cca3628df795",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/7e/05/7d254ca951f0241406283397cea7",
"build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/84/e9/db6266a9efe6728de54364735682",
"build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/c3/28/a9cce46c8b9ebde12d9b09556d84",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/66/67/14d56e4e90f25734712dbcedd94a",
"build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/78/66/a36de2580256b478e3cbdb11fb7f",
"build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/0f/fc/cd29b733f94c767231f5d3e3b49b",
"build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b2/bb/dd0a84740970e62169e8690c0906",
"build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/72/a8/bdf8597296d539357b344f75082d",
"build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f6/12/cbf8807fe66907ea9cc2a2da6a48",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/38/42/d14e16182290fffc53ffc5a94701",
"build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/26/5c/a5fdf76838573eb8e77559c1dd78",
"build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e7/b0/f52d213949d05db13145a5247285",
"build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b6/6b/37174b3a0d72a05f1bb3d904b78b",
"build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/08/e6/e9d05637c06202cbad634fcd8ed2",
"build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e4/b8/904a617bc2cfc3a4cdd6abf9aa32",
"build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ab/61/5ad24a335dc5479969238859d896",
"build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/98/b2/d69dbe14a7b78d7b1ca492e83347",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/bb/2e/87dd65f6b0a439ed6e24f270d7e2",
"build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e0/ca/b9852c43e154dc583e0ab34c743f",
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b4/4b/cc95a9c2fab610fdf18757e3138f",
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c4/d7/07816afe2317bb49da690d26b34e"
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/4b/64/b2ddd98e877794b3a47942a0dde5",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/bf/3d/ddca25182c6a76cf299b3e93eb3c",
"build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/36/a9/42c6f0eb660705953fcd43bb1649",
"build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/63/14/4abc652d741e1185a8c35b8bbb9b",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/73/30/c7eaf5ad343369861bf6a9eb013d",
"build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f8/b4/8a2165fad347af56ba3ec1bf7245",
"build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ac/e1/79171cce5c1e0fce879b9c88cf3b",
"build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d2/9f/8ec15bb92912109fec9f11c63541",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/d9/8d/d65fcf33eb6d33cf5201bd832c11",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/99/3c/8be98acc89f793f458aa61e050c2",
"build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/8d/78/97b2a524fdd3e8ba26a88673b756",
"build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/e7/86/6107002818b7fb303ea1f19b91e3",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/94/56/0eba692d01434be62ea65cc38437",
"build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/80/53/079a30edb50a069cfe828ddbc869",
"build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f0/d3/e88910c0724d5d5828598a55b3ac",
"build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/72/71/edc3f08a87cc22c1bf069f9b40a2",
"build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a3/a8/c243af3492cfd3dd85a8c48e539b",
"build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/54/bb/8a57fcf38a843b2d74a8d98eef1b",
"build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e1/80/49cdd00bede642db781d468e8b8a",
"build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/65/53/361464e556f691be8123a6981df0",
"build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2c/66/b5a14d9f0d7a86019145b227ddac",
"build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8c/55/91087a4da808d294172d55b57a80",
"build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2b/b8/428e18a3b1f7d4d353c0e5d96d23",
"build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/61/9f/c9d4c272812db7f1afe914152f5a",
"build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ed/da/8ba534efe375faee13faee6f92cb",
"build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/44/40/6b9b4be17d23e5ff78a0f0242699",
"build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/fc/09/e9e374f8ff007abd68731bd3ddb9",
"build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/21/3f/116ca7d820d2e9722ac2505471f4",
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/86/9f/c6610a0006b255768a74d73ce77b",
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a1/6e/c4b8e6499dd2404c010eb25fc55e"
}

View File

@ -503,6 +503,8 @@ add_executable(ballisticacore
${BA_SRC_ROOT}/ballistica/platform/platform.h
${BA_SRC_ROOT}/ballistica/platform/sdl/sdl_app.cc
${BA_SRC_ROOT}/ballistica/platform/sdl/sdl_app.h
${BA_SRC_ROOT}/ballistica/platform/windows/platform_windows.cc
${BA_SRC_ROOT}/ballistica/platform/windows/platform_windows.h
${BA_SRC_ROOT}/ballistica/python/class/python_class.cc
${BA_SRC_ROOT}/ballistica/python/class/python_class.h
${BA_SRC_ROOT}/ballistica/python/class/python_class_activity_data.cc

View File

@ -21,7 +21,7 @@
namespace ballistica {
// These are set automatically via script; don't modify them here.
const int kAppBuildNumber = 20373;
const int kAppBuildNumber = 20374;
const char* kAppVersion = "1.6.4";
// Our standalone globals.

View File

@ -0,0 +1,999 @@
// Released under the MIT License. See LICENSE for details.
#if BA_OSTYPE_WINDOWS
#include "ballistica/platform/windows/platform_windows.h"
#include <direct.h>
#include <fcntl.h>
#include <io.h>
#include <rpc.h>
#include <shellapi.h>
#include <shlobj_core.h>
#include <stdio.h>
#include <sysinfoapi.h>
#include <filesystem>
#pragma comment(lib, "Rpcrt4.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "iphlpapi.lib")
#if BA_DEBUG_BUILD
#pragma comment(lib, "python38_d.lib")
#else
#pragma comment(lib, "python38.lib")
#endif
#if !BA_HEADLESS_BUILD
#pragma comment(lib, "libogg.lib")
#pragma comment(lib, "libvorbis.lib")
#pragma comment(lib, "libvorbisfile.lib")
#pragma comment(lib, "OpenAL32.lib")
#pragma comment(lib, "SDL2.lib")
#pragma comment(lib, "SDL2main.lib")
#endif
#include "ballistica/game/game.h"
#include "ballistica/networking/networking_sys.h"
#include "ballistica/platform/min_sdl.h"
#if !defined(UNICODE) || !defined(_UNICODE)
#error Unicode not defined.
#endif
namespace ballistica {
// Convert a wide Unicode string to an UTF8 string.
static std::string utf8_encode(const std::wstring& wstr) {
if (wstr.empty()) return std::string();
int size_needed = WideCharToMultiByte(
CP_UTF8, 0, &wstr[0], static_cast<int>(wstr.size()), NULL, 0, NULL, NULL);
std::string str(size_needed, 0);
WideCharToMultiByte(CP_UTF8, 0, &wstr[0], static_cast<int>(wstr.size()),
&str[0], size_needed, NULL, NULL);
return str;
}
// Convert an UTF8 string to a wide Unicode String.
static std::wstring utf8_decode(const std::string& str) {
if (str.empty()) return std::wstring();
int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0],
static_cast<int>(str.size()), NULL, 0);
std::wstring wstr(size_needed, 0);
MultiByteToWideChar(CP_UTF8, 0, &str[0], static_cast<int>(str.size()),
&wstr[0], size_needed);
return wstr;
}
PlatformWindows::PlatformWindows() {
// We should be built in unicode mode.
assert(sizeof(TCHAR) == 2);
// Need to init winsock immediately since we use it for
// threading/logging/etc.
{
WSADATA a_wsa_data;
WORD a_version_requested = MAKEWORD(2, 2);
int err = WSAStartup(a_version_requested, &a_wsa_data);
BA_PRECONDITION(err == 0);
}
// If we're built as a console app, just assume we've got stdin and stdout.
if (g_buildconfig.windows_console_build()) {
have_stdin_stdout_ = true;
} else {
// In GUI mode, attempt to attach to a parent console only if one exists.
// Note: The behavior here is not currently optimal, which is why we
// stick with just using the console subsystem mostly.
// Specifically:
// - Can only seem to get stdinput from the parent console if launched
// via start /wait BallisticaCoreXXX...
// - Am seeing garbled stdout lines in some builds when run from
// WSL (namely Release builds for whatever reason).
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
have_stdin_stdout_ = true;
} else {
have_stdin_stdout_ = false;
}
}
// This seems to allow us to print unicode stuff to the console...
if (have_stdin_stdout_) {
SetConsoleOutputCP(CP_UTF8);
}
}
BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) {
switch (fdwCtrlType) {
case CTRL_C_EVENT:
if (g_game) {
g_game->PushInterruptSignalCall();
} else {
Log("SigInt handler called before g_game exists.");
}
return TRUE;
default:
return FALSE;
}
}
void PlatformWindows::SetupInterruptHandling() {
// Set up Ctrl-C handling.
if (!SetConsoleCtrlHandler(CtrlHandler, TRUE)) {
Log("Error on SetConsoleCtrlHandler()");
}
}
std::string PlatformWindows::GenerateUUID() {
std::string val;
UUID uuid;
ZeroMemory(&uuid, sizeof(UUID));
UuidCreate(&uuid);
RPC_CSTR str_a;
UuidToStringA(&uuid, &str_a);
if (str_a != nullptr) {
val = reinterpret_cast<char*>(str_a);
RpcStringFreeA(&str_a);
} else {
// As a fallback, get processor cycles since boot.
val = std::to_string(__rdtsc());
}
return val;
}
std::string PlatformWindows::GetDefaultConfigDir() {
std::string config_dir;
wchar_t* path;
auto result = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &path);
if (result != S_OK) {
throw Exception("Unable to get user local-app-data dir.");
}
std::string configdir = utf8_encode(std::wstring(path)) + "\\BallisticaCore";
return configdir;
}
std::string PlatformWindows::GetErrnoString() {
switch (errno) {
case EPERM:
return "operation not permitted";
break;
case ENOENT:
return "no such file or directory";
break;
case ENOTDIR:
return "not a directory";
break;
case EISDIR:
return "is a directory";
break;
case EROFS:
return "read only file system";
break;
case EACCES:
return "permission denied";
break;
case EEXIST:
return "file exists";
break;
case ENOSPC:
return "no space left on device";
break;
default:
return "error " + std::to_string(errno);
break;
}
}
std::string PlatformWindows::GetSocketErrorString() {
// on windows, socket errors are returned via WSAGetLastError,
// (while they're just errno elsewhere..)
return std::to_string(WSAGetLastError());
}
// auto PlatformWindows::FilePathExists(const std::string& name) -> bool {
// return std::filesystem::exists(utf8_decode(name));
// }
int PlatformWindows::GetSocketError() {
int val = WSAGetLastError();
switch (val) {
case WSAEINTR:
return EINTR;
case WSAEWOULDBLOCK:
return EWOULDBLOCK;
default:
return val;
}
}
auto PlatformWindows::Remove(const char* path) -> int {
return _wremove(utf8_decode(path).c_str());
}
auto PlatformWindows::Stat(const char* path, struct BA_STAT* buffer) -> int {
return _wstat(utf8_decode(path).c_str(), buffer);
}
auto PlatformWindows::Rename(const char* oldname, const char* newname) -> int {
// Unlike other platforms, windows will error if the target file already
// exists instead of simply overwriting it. So let's attempt to blow away
// anything there first.
auto new_name_utf8 = utf8_decode(newname);
_wremove(new_name_utf8.c_str());
return _wrename(utf8_decode(oldname).c_str(), new_name_utf8.c_str());
}
auto PlatformWindows::DoAbsPath(const std::string& path, std::string* outpath)
-> bool {
wchar_t abspath[MAX_PATH + 1];
auto path_utf8 = utf8_decode(path);
uint32_t pathlen =
GetFullPathNameW(path_utf8.c_str(), MAX_PATH, abspath, nullptr);
if (pathlen >= MAX_PATH) {
// Buffer not big enough. Should handle this case.
return false;
}
*outpath = utf8_encode(std::wstring(abspath));
return true;
}
auto PlatformWindows::FOpen(const char* path, const char* mode) -> FILE* {
return _wfopen(utf8_decode(path).c_str(), utf8_decode(mode).c_str());
}
void PlatformWindows::DoMakeDir(const std::string& dir, bool quiet) {
std::wstring stemp = utf8_decode(dir);
int result = CreateDirectory(stemp.c_str(), 0);
if (result == 0) {
DWORD err = GetLastError();
if (err != ERROR_ALREADY_EXISTS) {
throw Exception("Unable to create directory: '" + dir + "'");
}
}
}
std::string PlatformWindows::GetLocale() {
// Get the windows locale.
// (see http://msdn.microsoft.com/en-us/goglobal/bb895996.aspx)
// theres a func to convert this to a string but its not available on xp
// the standard is lang_COUNTRY I think..
// languages: http://www.loc.gov/standards/iso639-2/php/code_list.php
// country codes: http://www.iso.org/iso/prods-services/iso3166ma
// /02iso-3166-code-lists/country_names_and_code_elements
// microsoft locale IDs: http://www.microsoft.com/globaldev
// /reference/lcid-all.mspx
// found page with some extras.. if something is missing here, try these..
// http://www.codeproject.com/Articles/586099
// /NET-Framework-Cultures-with-Formats-SQL-Mapping
LCID lcid = GetUserDefaultLCID();
switch (lcid) {
case 1078:
return "af";
break; // Afrikaans
case 1039:
return "is";
break; // Icelandic
case 1052:
return "sq";
break; // Albanian
case 1057:
return "id";
break; // Indonesian
case 14337:
return "ar_AE";
break; // Arabic – United Arab Emirates
case 1040:
return "it_IT";
break; // Italian - Italy
case 15361:
return "ar_BH";
break; // Arabic - Bahrain
case 2064:
return "it_CH";
break; // Italian - Switzerland
case 5121:
return "ar_DZ";
break; // Arabic - Algeria
case 1041:
return "ja_JP";
break; // Japanese
case 3073:
return "ar_EG";
break; // Arabic - Egypt
case 1042:
return "ko_KR";
break; // Korean
case 2049:
return "ar_IQ";
break; // Arabic - Iraq
case 1062:
return "lv";
break; // Latvian
case 11265:
return "ar_JO";
break; // Arabic - Jordan
case 1063:
return "lt";
break; // Lithuanian
case 13313:
return "ar_KW";
break; // Arabic - Kuwait
case 1071:
return "mk";
break; // FYRO Macedonian
case 12289:
return "ar_LB";
break; // Arabic - Lebanon
case 1086:
return "ms_MY";
break; // Malay - Malaysia
case 4097:
return "ar_LY";
break; // Arabic - Libya
case 2110:
return "ms_BN";
break; // Malay – Brunei
case 6145:
return "ar_MA";
break; // Arabic - Morocco
case 1082:
return "mt";
break; // Maltese
case 8193:
return "ar_OM";
break; // Arabic - Oman
case 1102:
return "mr";
break; // Marathi
case 16385:
return "ar_QA";
break; // Arabic - Qatar
case 1044:
return "no_NO";
break; // Norwegian - Bokmål
case 1025:
return "ar_SA";
break; // Arabic - Saudi Arabia
case 2068:
return "no_NO";
break; // Norwegian – Nynorsk
case 10241:
return "ar_SY";
break; // Arabic - Syria
case 1045:
return "pl_PL";
break; // Polish
case 7169:
return "ar_TN";
break; // Arabic - Tunisia
case 2070:
return "pt_PT";
break; // Portuguese - Portugal
case 9217:
return "ar_YE";
break; // Arabic - Yemen
case 1046:
return "pt_BR";
break; // Portuguese - Brazil
case 1067:
return "hy";
break; // Armenian
case 1047:
return "rm";
break; // Raeto-Romance
case 1068:
return "az_AZ";
break; // Azeri – Latin
case 1048:
return "ro";
break; // Romanian - Romania
case 2092:
return "az_AZ";
break; // Azeri – Cyrillic
case 2072:
return "ro_MO";
break; // Romanian - Moldova
case 1069:
return "eu";
break; // Basque
case 1049:
return "ru_RU";
break; // Russian
case 1059:
return "be";
break; // Belarusian
case 2073:
return "ru_MO";
break; // Russian - Moldova
case 1026:
return "bg";
break; // Bulgarian
case 1103:
return "sa";
break; // Sanskrit
case 1027:
return "ca";
break; // Catalan
case 3098:
return "sr_SP";
break; // Serbian - Cyrillic
case 10266:
return "sr_SP";
break; // Serbian - Cyrillic .. are we sure?..
case 2052:
return "zh_CN";
break; // Chinese - China
case 2074:
return "sr_SP";
break; // Serbian – Latin
case 3076:
return "zh_HK";
break; // Chinese - Hong Kong S.A.R.
case 1074:
return "tn";
break; // Setsuana
case 5124:
return "zh_MO";
break; // Chinese – Macau S.A.R
case 1060:
return "sl_SL";
break; // Slovenian
case 4100:
return "zh_SG";
break; // Chinese - Singapore
case 1051:
return "sk";
break; // Slovak
case 1028:
return "zh_TW";
break; // Chinese - Taiwan
case 1070:
return "sb";
break; // Sorbian
case 1050:
return "hr";
break; // Croatian
case 1034:
return "es_ES";
break; // Spanish - Spain
case 1029:
return "cs_CZ";
break; // Czech
case 11274:
return "es_AR";
break; // Spanish - Argentina
case 1030:
return "da_DK";
break; // Danish
case 16394:
return "es_BO";
break; // Spanish - Bolivia
case 1043:
return "nl_NL";
break; // Dutch – The Netherlands
case 13322:
return "es_CL";
break; // Spanish - Chile
case 2067:
return "nl_BE";
break; // Dutch - Belgium
case 9226:
return "es_CO";
break; // Spanish - Colombia
case 3081:
return "en_AU";
break; // English - Australia
case 5130:
return "es_CR";
break; // Spanish - Costa Rica
case 10249:
return "en_BZ";
break; // English - Belize
case 7178:
return "es_DO";
break; // Spanish - Dominican Republic
case 4105:
return "en_CA";
break; // English - Canada
case 12298:
return "es_EC";
break; // Spanish - Ecuador
case 9225:
return "en_CB";
break; // English – Carribbean
case 4106:
return "es_GT";
break; // Spanish - Guatemala
case 6153:
return "en_IE";
break; // English - Ireland
case 18442:
return "es_HN";
break; // Spanish - Honduras
case 8201:
return "en_JM";
break; // English - Jamaica
case 2058:
return "es_MX";
break; // Spanish - Mexico
case 5129:
return "en_NZ";
break; // English - New Zealand
case 19466:
return "es_NI";
break; // Spanish - Nicaragua
case 13321:
return "en_PH";
break; // English – Phillippines
case 6154:
return "es_PA";
break; // Spanish - Panama
case 7177:
return "en_ZA";
break; // English - South Africa
case 10250:
return "es_PE";
break; // Spanish - Peru
case 11273:
return "en_TT";
break; // English - Trinidad
case 20490:
return "es_PR";
break; // Spanish - Puerto Rico
case 2057:
return "en_GB";
break; // English - United Kingdom
case 15370:
return "es_PY";
break; // Spanish - Paraguay
case 1033:
return "en_US";
break; // English - United States
case 17418:
return "es_SV";
break; // Spanish - El Salvador
case 1061:
return "et";
break; // Estonian
case 14346:
return "es_UY";
break; // Spanish - Uruguay
case 1065:
return "fa";
break; // Farsi
case 8202:
return "es_VE";
break; // Spanish - Venezuela
case 1035:
return "fi_FI";
break; // Finnish
case 1072:
return "sx";
break; // Sutu
case 1080:
return "fo";
break; // Faroese
case 1089:
return "sw";
break; // Swahili
case 1036:
return "fr_FR";
break; // French - France
case 1053:
return "sv_SE";
break; // Swedish - Sweden
case 2060:
return "fr_BE";
break; // French - Belgium
case 2077:
return "sv_FI";
break; // Swedish - Finland
case 3084:
return "fr_CA";
break; // French - Canada
case 1097:
return "ta";
break; // Tamil
case 5132:
return "fr_LU";
break; // French - Luxembourg
case 1092:
return "tt";
break; // Tatar
case 4108:
return "fr_CH";
break; // French - Switzerland
case 1054:
return "th";
break; // Thai
case 2108:
return "gd_IE";
break; // Gaelic – Ireland
case 1055:
return "tr_TR";
break; // Turkish
case 1084:
return "gd";
break; // Gaelic - Scotland
case 1073:
return "ts";
break; // Tsonga
case 1031:
return "de_DE";
break; // German - Germany
case 1058:
return "uk";
break; // Ukrainian
case 3079:
return "de_AT";
break; // German - Austria
case 1056:
return "ur";
break; // Urdu
case 5127:
return "de_LI";
break; // German - Liechtenstein
case 2115:
return "uz_UZ";
break; // Uzbek – Cyrillic
case 4103:
return "de_LU";
break; // German - Luxembourg
case 1091:
return "uz_UZ";
break; // Uzbek – Latin
case 2055:
return "de_CH";
break; // German - Switzerland
case 1066:
return "vi";
break; // Vietnamese
case 1032:
return "el";
break; // Greek
case 1076:
return "xh";
break; // Xhosa
case 1037:
return "he";
break; // Hebrew
case 1085:
return "yi";
break; // Yiddish
case 1081:
return "hi";
break; // Hindi
case 1077:
return "zu";
break; // Zulu
case 1038:
return "hu_HU";
break; // Hungarian
default:
return "lcid_" + std::to_string(lcid);
}
}
std::string PlatformWindows::DoGetDeviceName() {
std::string device_name;
wchar_t computer_name[256];
DWORD computer_name_size = 256;
int result = GetComputerName(computer_name, &computer_name_size);
if (result == 0) {
device_name = "BallisticaCore Game";
} else {
device_name = utf8_encode(std::wstring(computer_name));
if (device_name.size() == 0) {
device_name = "BallisticaCore Game";
}
}
return device_name;
}
bool PlatformWindows::DoHasTouchScreen() { return false; }
void PlatformWindows::HandleLog(const std::string& msg) {
// if (have_stdin_stdout_) {
// // On headless builds we use default handler (simple stdout).
// return Platform::HandleLog(msg);
// }
// Also spit this out as a debug-string for when running from msvc.
OutputDebugString(utf8_decode(msg).c_str());
}
// (The default SDL handler now covers us)
// bool PlatformWindows::BlockingFatalErrorDialog(const std::string& message) {
// if (HeadlessMode()) {
// return Platform::BlockingFatalErrorDialog(message);
// }
// MessageBoxA(nullptr, (message.c_str()), "BallisticaCore",
// MB_ICONERROR | MB_OK);
// // Our message-box call is blocking so we can return false here
// // and let the app self-terminate at this point.
// return false;
// }
void PlatformWindows::SetupDataDirectory() {
// We always want to launch with the working directory where our executable
// is, but for some reason that's not the default when visual studio
// debugging. (and overriding it is a per-user setting; ew). ...so
// let's force the issue: grab the path to our executable, lop it off
// at the last \, and chdir to that.
{
wchar_t sz_file_name[MAX_PATH + 1];
GetModuleFileName(nullptr, sz_file_name, MAX_PATH + 1);
wchar_t* last_slash = nullptr;
for (wchar_t* s = sz_file_name; *s != 0; ++s) {
if (*s == '\\') {
last_slash = s;
}
}
if (last_slash != nullptr) {
*last_slash = 0;
int result = _wchdir(sz_file_name);
if (result != 0) {
throw Exception("Unable to chdir to application directory.");
}
}
}
// Simply complain if ba_data isn't here.
if (!std::filesystem::is_directory("ba_data")) {
throw Exception("ba_data directory not found.");
}
}
void PlatformWindows::SetEnv(const std::string& name,
const std::string& value) {
auto result = SetEnvironmentVariableW(utf8_decode(name).c_str(),
utf8_decode(value).c_str());
if (result == 0) {
throw Exception("SetEnvironmentVariable failed for '" + name
+ "'; error=" + std::to_string(GetLastError()));
}
}
bool PlatformWindows::IsStdinATerminal() { return _isatty(_fileno(stdin)); }
std::string PlatformWindows::GetOSVersionString() {
DWORD dw_version = 0;
DWORD dw_major_version = 0;
DWORD dw_minor_version = 0;
DWORD dw_build = 0;
// This is deprecated, but too lazy to find replacement right now.
// Just hiding the warning.
#pragma warning(disable : 4996)
dw_version = GetVersion();
#pragma warning(disable : 4996)
dw_major_version = (DWORD)(LOBYTE(LOWORD(dw_version)));
dw_minor_version = (DWORD)(HIBYTE(LOWORD(dw_version)));
if (dw_version < 0x80000000) {
dw_build = (DWORD)(HIWORD(dw_version));
}
std::string version = std::to_string(dw_major_version) + "."
+ std::to_string(dw_minor_version) + " "
+ std::to_string(dw_build);
return version;
}
std::string PlatformWindows::GetCWD() {
wchar_t buffer[MAX_PATH];
wchar_t* result = _wgetcwd(buffer, MAX_PATH);
if (result == nullptr) {
throw Exception("Error getting CWD; errno=" + std::to_string(errno));
}
return utf8_encode(std::wstring(buffer));
}
void PlatformWindows::DoOpenURL(const std::string& url) {
auto r = reinterpret_cast<intptr_t>(
ShellExecute(nullptr, _T("open"), utf8_decode(url).c_str(), nullptr,
nullptr, SW_SHOWNORMAL));
// This should return > 32 on success.
if (r <= 32) {
Log("Error " + std::to_string(r) + " opening URL '" + url + "'");
}
}
void PlatformWindows::OpenFileExternally(const std::string& path) {
auto r = reinterpret_cast<intptr_t>(
ShellExecute(nullptr, _T("open"), _T("notepad.exe"),
utf8_decode(path).c_str(), nullptr, SW_SHOWNORMAL));
if (r <= 32) {
Log("Error " + std::to_string(r) + " on open_file_externally for '" + path
+ "'");
}
}
void PlatformWindows::OpenDirExternally(const std::string& path) {
auto r = reinterpret_cast<intptr_t>(
ShellExecute(nullptr, _T("open"), _T("explorer.exe"),
utf8_decode(path).c_str(), nullptr, SW_SHOWNORMAL));
if (r <= 32) {
Log("Error " + std::to_string(r) + " on open_dir_externally for '" + path
+ "'");
}
}
void PlatformWindows::Unlink(const char* path) { _unlink(path); }
void PlatformWindows::CloseSocket(int socket) { closesocket(socket); }
int PlatformWindows::SocketPair(int domain, int type, int protocol,
int socks_out[2]) {
assert(type == SOCK_STREAM);
int make_overlapped = false;
union {
struct sockaddr_in inaddr;
struct sockaddr addr;
} a;
SOCKET listener;
int e;
socklen_t addrlen = sizeof(a.inaddr);
DWORD flags = 0;
int reuse = 1;
int nodelay = 1;
listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listener < 0) {
return SOCKET_ERROR;
}
memset(&a, 0, sizeof(a));
a.inaddr.sin_family = AF_INET;
a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
a.inaddr.sin_port = 0;
SOCKET socks[2];
socks[0] = socks[1] = INVALID_SOCKET;
do {
if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR,
reinterpret_cast<char*>(&reuse), (socklen_t)sizeof(reuse))
== -1) {
break;
}
if (bind(listener, &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR) {
break;
}
if (getsockname(listener, &a.addr, &addrlen) == SOCKET_ERROR) {
break;
}
if (listen(listener, 1) == SOCKET_ERROR) {
break;
}
socks[0] = socket(AF_INET, SOCK_STREAM, 0);
if (socks[0] < 0) {
break;
}
if (connect(socks[0], &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR) {
break;
}
socks[1] = accept(listener, nullptr, nullptr);
// not sure if this helps but what the hey...
if (setsockopt(socks[0], IPPROTO_TCP, TCP_NODELAY,
reinterpret_cast<char*>(&nodelay),
(socklen_t)sizeof(nodelay))
== -1)
break;
if (setsockopt(socks[1], IPPROTO_TCP, TCP_NODELAY,
reinterpret_cast<char*>(&nodelay),
(socklen_t)sizeof(nodelay))
== -1) {
break;
}
if (socks[1] < 0) break;
closesocket(listener);
socks_out[0] = static_cast_check_fit<int>(socks[0]);
socks_out[1] = static_cast_check_fit<int>(socks[1]);
return 0;
} while (0);
e = WSAGetLastError();
closesocket(listener);
closesocket(socks[0]);
closesocket(socks[1]);
WSASetLastError(e);
return SOCKET_ERROR;
}
std::vector<uint32_t> PlatformWindows::GetBroadcastAddrs() {
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
std::vector<uint32_t> addrs;
// Variables used by GetIpAddrTable
PMIB_IPADDRTABLE pIPAddrTable;
DWORD dwSize = 0;
DWORD dwRetVal = 0;
bool err = false;
// Before calling AddIPAddress we use GetIpAddrTable to get an adapter to
// which we can add the IP.
pIPAddrTable = static_cast<MIB_IPADDRTABLE*>(MALLOC(sizeof(MIB_IPADDRTABLE)));
if (pIPAddrTable) {
// Make an initial call to GetIpAddrTable to get the necessary size into
// the dwSize variable
if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
FREE(pIPAddrTable);
pIPAddrTable = static_cast<MIB_IPADDRTABLE*>(MALLOC(dwSize));
}
if (pIPAddrTable == nullptr) {
Log("Error: Memory allocation failed for GetIpAddrTable\n");
err = true;
}
if (!err) {
// Make a second call to GetIpAddrTable to get the actual data we want
if ((dwRetVal = GetIpAddrTable(pIPAddrTable, &dwSize, 0)) != NO_ERROR) {
Log("Error: GetIpAddrTable failed with error "
+ std::to_string(dwRetVal));
err = true;
}
}
if (!err) {
for (int i = 0; i < static_cast<int>(pIPAddrTable->dwNumEntries); i++) {
uint32_t addr = ntohl(pIPAddrTable->table[i].dwAddr);
uint32_t subnet = ntohl(pIPAddrTable->table[i].dwMask);
uint32_t broadcast = addr | (~subnet);
addrs.push_back(broadcast);
// cout << "ADDR IS " << ((addr>>24)&0xFF) << "." << ((addr>>16)&0xFF)
// << "." << ((addr>>8)&0xFF) << "." << ((addr>>0)&0xFF) << endl; cout
// << "NETMASK IS " << ((subnet>>24)&0xFF) << "." <<
// ((subnet>>16)&0xFF)
// << "." << ((subnet>>8)&0xFF) << "." << ((subnet>>0)&0xFF) << endl;
// cout << "BROADCAST IS " << ((broadcast>>24)&0xFF) << "." <<
// ((broadcast>>16)&0xFF) << "." << ((broadcast>>8)&0xFF) << "." <<
// ((broadcast>>0)&0xFF) << endl;
}
}
if (pIPAddrTable) {
FREE(pIPAddrTable);
pIPAddrTable = nullptr;
}
}
return addrs;
#undef MALLOC
#undef FREE
}
bool PlatformWindows::SetSocketNonBlocking(int sd) {
unsigned long dataval = 1; // NOLINT (func signature wants long)
int result = ioctlsocket(sd, FIONBIO, &dataval);
if (result != 0) {
Log("Error setting non-blocking socket: "
+ g_platform->GetSocketErrorString());
return false;
}
return true;
}
std::string PlatformWindows::GetPlatformName() { return "windows"; }
std::string PlatformWindows::GetSubplatformName() {
#if BA_TEST_BUILD
return "test";
#else
return "";
#endif
}
bool PlatformWindows::ContainsPythonDist() { return true; }
} // namespace ballistica
#endif // BA_OSTYPE_WINDOWS

View File

@ -0,0 +1,58 @@
// Released under the MIT License. See LICENSE for details.
#ifndef BALLISTICA_PLATFORM_WINDOWS_PLATFORM_WINDOWS_H_
#define BALLISTICA_PLATFORM_WINDOWS_PLATFORM_WINDOWS_H_
#if BA_OSTYPE_WINDOWS
#include <string>
#include <vector>
#include "ballistica/platform/platform.h"
namespace ballistica {
class PlatformWindows : public Platform {
public:
PlatformWindows();
void SetupInterruptHandling() override;
auto GetDeviceUUIDPrefix() -> std::string override { return "w"; }
auto GenerateUUID() -> std::string override;
auto GetDefaultConfigDir() -> std::string override;
auto Remove(const char* path) -> int;
auto Stat(const char* path, struct BA_STAT* buffer) -> int;
auto Rename(const char* oldname, const char* newname) -> int;
auto DoAbsPath(const std::string& path, std::string* outpath)
-> bool override;
auto FOpen(const char* path, const char* mode) -> FILE* override;
auto GetErrnoString() -> std::string override;
auto GetSocketErrorString() -> std::string override;
auto GetSocketError() -> int override;
void DoMakeDir(const std::string& dir, bool quiet) override;
auto GetLocale() -> std::string override;
auto DoGetDeviceName() -> std::string override;
auto DoHasTouchScreen() -> bool override;
void HandleLog(const std::string& msg) override;
void SetupDataDirectory() override;
void SetEnv(const std::string& name, const std::string& value) override;
auto IsStdinATerminal() -> bool override;
auto GetOSVersionString() -> std::string override;
auto GetCWD() -> std::string override;
void DoOpenURL(const std::string& url) override;
void OpenFileExternally(const std::string& path) override;
void OpenDirExternally(const std::string& path) override;
void Unlink(const char* path) override;
void CloseSocket(int socket) override;
auto SocketPair(int domain, int type, int protocol, int socks[2])
-> int override;
auto GetBroadcastAddrs() -> std::vector<uint32_t> override;
auto SetSocketNonBlocking(int sd) -> bool override;
auto GetPlatformName() -> std::string override;
auto GetSubplatformName() -> std::string override;
virtual auto ContainsPythonDist() -> bool;
bool have_stdin_stdout_ = false;
};
} // namespace ballistica
#endif // BA_OSTYPE_WINDOWS
#endif // BALLISTICA_PLATFORM_WINDOWS_PLATFORM_WINDOWS_H_