mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-28 10:03:15 +08:00
More win dep files
This commit is contained in:
parent
17d8b1f62d
commit
cbb8c134ce
@ -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"
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
999
src/ballistica/platform/windows/platform_windows.cc
Normal file
999
src/ballistica/platform/windows/platform_windows.cc
Normal 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
|
||||
58
src/ballistica/platform/windows/platform_windows.h
Normal file
58
src/ballistica/platform/windows/platform_windows.h
Normal 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_
|
||||
Loading…
x
Reference in New Issue
Block a user