mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
Merge branch 'dont-skip-leg-day'
This commit is contained in:
2
.github/workflows/publish-client.yml
vendored
2
.github/workflows/publish-client.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
dotnet-version: 9.0.x
|
||||
|
||||
- name: Package client
|
||||
run: Tools/package_client_build.py -p windows mac linux
|
||||
run: Tools/package_client_build.py
|
||||
|
||||
- name: Shuffle files around
|
||||
run: |
|
||||
|
||||
@@ -2,6 +2,7 @@ input-key-Escape = Escape
|
||||
input-key-Control = Control
|
||||
input-key-Shift = Shift
|
||||
input-key-Alt = Alt
|
||||
input-key-Alt-mac = ⌥
|
||||
input-key-Menu = Menu
|
||||
input-key-F1 = F1
|
||||
input-key-F2 = F2
|
||||
@@ -70,8 +71,8 @@ input-key-MouseButton9 = Mouse 9
|
||||
|
||||
input-key-LSystem-win = Left Win
|
||||
input-key-RSystem-win = Right Win
|
||||
input-key-LSystem-mac = Left Cmd
|
||||
input-key-RSystem-mac = Right Cmd
|
||||
input-key-LSystem-mac = Left ⌘
|
||||
input-key-RSystem-mac = Right ⌘
|
||||
input-key-LSystem-linux = Left Meta
|
||||
input-key-RSystem-linux = Right Meta
|
||||
|
||||
|
||||
@@ -374,6 +374,8 @@ namespace Robust.Client.Graphics.Clyde
|
||||
if (reg.IsDisposed)
|
||||
return;
|
||||
|
||||
_sawmillWin.Debug($"Destroying window {reg.Id}");
|
||||
|
||||
reg.IsDisposed = true;
|
||||
|
||||
_glContext!.WindowDestroyed(reg);
|
||||
|
||||
@@ -128,7 +128,11 @@ namespace Robust.Client.Graphics.Clyde
|
||||
// macOS cannot.
|
||||
if (OperatingSystem.IsWindows() || OperatingSystem.IsLinux())
|
||||
_cfg.OverrideDefault(CVars.DisplayThreadWindowApi, true);
|
||||
|
||||
#if MACOS
|
||||
// Trust macOS to not need threaded window blitting.
|
||||
// (threaded window blitting is a workaround to avoid having to frequently MakeCurrent() on Windows, as it is broken).
|
||||
_cfg.OverrideDefault(CVars.DisplayThreadWindowBlit, false);
|
||||
#endif
|
||||
_threadWindowBlit = _cfg.GetCVar(CVars.DisplayThreadWindowBlit);
|
||||
_threadWindowApi = _cfg.GetCVar(CVars.DisplayThreadWindowApi);
|
||||
|
||||
|
||||
@@ -102,6 +102,8 @@ namespace Robust.Client.Graphics.Clyde
|
||||
{
|
||||
var data = _windowData[reg.Id];
|
||||
data.BlitDoneEvent?.Set();
|
||||
// Set events so blit thread properly wakes up and notices it needs to shut down.
|
||||
data.BlitStartEvent?.Set();
|
||||
|
||||
_windowData.Remove(reg.Id);
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ public static partial class SDL
|
||||
|
||||
public const string SDL_PROP_FILE_DIALOG_NFILTERS_NUMBER = "SDL.filedialog.nfilters";
|
||||
public const string SDL_PROP_FILE_DIALOG_FILTERS_POINTER = "SDL.filedialog.filters";
|
||||
public const string SDL_PROP_FILE_DIALOG_WINDOW_POINTER = "SDL.filedialog.window";
|
||||
|
||||
public static int SDL_VERSIONNUM_MAJOR(int version) => version / 1000000;
|
||||
public static int SDL_VERSIONNUM_MINOR(int version) => version / 1000 % 1000;
|
||||
|
||||
@@ -81,6 +81,11 @@ internal partial class Clyde
|
||||
case EventQuit:
|
||||
ProcessEventQuit();
|
||||
break;
|
||||
#if MACOS
|
||||
case EventWindowDestroyed:
|
||||
ProcessEventWindowDestroyed();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
_sawmill.Error($"Unknown SDL3 event type: {evb.GetType().Name}");
|
||||
break;
|
||||
@@ -255,5 +260,15 @@ internal partial class Clyde
|
||||
{
|
||||
_clyde.SendInputModeChanged();
|
||||
}
|
||||
|
||||
#if MACOS
|
||||
private void ProcessEventWindowDestroyed()
|
||||
{
|
||||
// For some reason, on macOS, closing a secondary window
|
||||
// causes the GL context on the primary thread to crap itself.
|
||||
// Rebinding it seems to fix it.
|
||||
GLMakeContextCurrent(_clyde._mainWindow);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,10 @@ internal partial class Clyde
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Giving a parent window is required to avoid the file dialog being blocking on macOS.
|
||||
var mainWindow = (Sdl3WindowReg)_clyde._mainWindow!;
|
||||
SDL.SDL_SetPointerProperty(props, SDL.SDL_PROP_FILE_DIALOG_WINDOW_POINTER, mainWindow.Sdl3Window);
|
||||
|
||||
var task = ShowFileDialogWithProperties(type, props);
|
||||
|
||||
SDL.SDL_DestroyProperties(props);
|
||||
|
||||
@@ -278,5 +278,9 @@ internal partial class Clyde
|
||||
private sealed class EventKeyMapChanged : EventBase;
|
||||
|
||||
private sealed class EventQuit : EventBase;
|
||||
|
||||
#if MACOS
|
||||
private sealed class EventWindowDestroyed : EventBase;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,10 @@ using Robust.Shared.Maths;
|
||||
using SDL3;
|
||||
using TerraFX.Interop.Windows;
|
||||
using TerraFX.Interop.Xlib;
|
||||
#if WINDOWS
|
||||
using BOOL = TerraFX.Interop.Windows.BOOL;
|
||||
using Windows = TerraFX.Interop.Windows.Windows;
|
||||
#endif
|
||||
using GLAttr = SDL3.SDL.SDL_GLAttr;
|
||||
using X11Window = TerraFX.Interop.Xlib.Window;
|
||||
|
||||
@@ -142,9 +144,12 @@ internal partial class Clyde
|
||||
});
|
||||
}
|
||||
|
||||
private static void WinThreadWinDestroy(CmdWinDestroy cmd)
|
||||
private void WinThreadWinDestroy(CmdWinDestroy cmd)
|
||||
{
|
||||
SDL.SDL_DestroyWindow(cmd.Window);
|
||||
#if MACOS
|
||||
SendEvent(new EventWindowDestroyed());
|
||||
#endif
|
||||
}
|
||||
|
||||
private (nint window, nint context) CreateSdl3WindowForRenderer(
|
||||
@@ -461,6 +466,7 @@ internal partial class Clyde
|
||||
var reg = (Sdl3WindowReg)window;
|
||||
var windowPtr = WinPtr(reg);
|
||||
|
||||
#if WINDOWS
|
||||
// On Windows, SwapBuffers does not correctly sync to the DWM compositor.
|
||||
// This means OpenGL vsync is effectively broken by default on Windows.
|
||||
// We manually sync via DwmFlush(). GLFW does this automatically, SDL3 does not.
|
||||
@@ -473,7 +479,7 @@ internal partial class Clyde
|
||||
var dwmFlush = false;
|
||||
var swapInterval = 0;
|
||||
|
||||
if (OperatingSystem.IsWindows() && !reg.Fullscreen && reg.SwapInterval > 0)
|
||||
if (!reg.Fullscreen && reg.SwapInterval > 0)
|
||||
{
|
||||
BOOL compositing;
|
||||
// 6.2 is Windows 8
|
||||
@@ -492,9 +498,12 @@ internal partial class Clyde
|
||||
swapInterval = reg.SwapInterval;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//_sawmill.Debug($"Swapping: {window.Id} @ {_clyde._gameTiming.CurFrame}");
|
||||
SDL.SDL_GL_SwapWindow(windowPtr);
|
||||
|
||||
#if WINDOWS
|
||||
if (dwmFlush)
|
||||
{
|
||||
var i = swapInterval;
|
||||
@@ -505,6 +514,7 @@ internal partial class Clyde
|
||||
|
||||
SDL.SDL_GL_SetSwapInterval(swapInterval);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public uint? WindowGetX11Id(WindowReg window)
|
||||
@@ -547,17 +557,18 @@ internal partial class Clyde
|
||||
|
||||
public void TextInputSetRect(WindowReg reg, UIBox2i rect, int cursor)
|
||||
{
|
||||
var ratio = ((Sdl3WindowReg)reg).PixelRatio;
|
||||
SendCmd(new CmdTextInputSetRect
|
||||
{
|
||||
Window = WinPtr(reg),
|
||||
Rect = new SDL.SDL_Rect
|
||||
{
|
||||
x = rect.Left,
|
||||
y = rect.Top,
|
||||
w = rect.Width,
|
||||
h = rect.Height
|
||||
x = (int)(rect.Left / ratio.X),
|
||||
y = (int)(rect.Top / ratio.Y),
|
||||
w = (int)(rect.Width / ratio.X),
|
||||
h = (int)(rect.Height / ratio.Y)
|
||||
},
|
||||
Cursor = cursor
|
||||
Cursor = (int)(cursor / ratio.X)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,10 @@ internal partial class Clyde
|
||||
// https://github.com/libsdl-org/SDL/issues/11813
|
||||
SDL.SDL_SetHint(SDL.SDL_HINT_WINDOWS_GAMEINPUT, "0");
|
||||
|
||||
#if MACOS
|
||||
SDL.SDL_SetHint(SDL.SDL_HINT_MAC_OPENGL_ASYNC_DISPATCH, "1");
|
||||
#endif
|
||||
|
||||
var res = SDL.SDL_Init(SDL.SDL_InitFlags.SDL_INIT_VIDEO | SDL.SDL_InitFlags.SDL_INIT_EVENTS);
|
||||
if (!res)
|
||||
{
|
||||
|
||||
@@ -197,6 +197,13 @@ namespace Robust.Client.Input
|
||||
locId += "-linux";
|
||||
}
|
||||
|
||||
#if MACOS
|
||||
if (key == Key.Alt)
|
||||
{
|
||||
locId += "-mac";
|
||||
}
|
||||
#endif
|
||||
|
||||
if (loc.TryGetString(locId, out var name))
|
||||
return name;
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import sys
|
||||
import zipfile
|
||||
import argparse
|
||||
import glob
|
||||
from enum import StrEnum
|
||||
|
||||
from typing import List, Optional
|
||||
|
||||
@@ -28,12 +29,34 @@ except ImportError:
|
||||
|
||||
p = os.path.join
|
||||
|
||||
PLATFORM_WINDOWS = "windows"
|
||||
PLATFORM_WIN = "win"
|
||||
PLATFORM_LINUX = "linux"
|
||||
PLATFORM_LINUX_ARM64 = "linux-arm64"
|
||||
PLATFORM_MACOS = "mac"
|
||||
PLATFORM_OSX = "osx"
|
||||
PLATFORM_FREEBSD = "freebsd"
|
||||
|
||||
TARGET_OS_WINDOWS = "Windows"
|
||||
TARGET_OS_MACOS = "MacOS"
|
||||
TARGET_OS_LINUX = "Linux"
|
||||
TARGET_OS_FREEBSD = "FreeBSD"
|
||||
|
||||
class TargetOS(StrEnum):
|
||||
Windows = "Windows"
|
||||
MacOS = "MacOS"
|
||||
Linux = "Linux"
|
||||
FreeBSD = "FreeBSD"
|
||||
|
||||
RID_WIN_X64 = f"{PLATFORM_WIN}-x64"
|
||||
RID_WIN_ARM64 = f"{PLATFORM_WIN}-arm64"
|
||||
RID_LINUX_X64 = f"{PLATFORM_LINUX}-x64"
|
||||
RID_LINUX_ARM64 = f"{PLATFORM_LINUX}-arm64"
|
||||
RID_OSX_X64 = f"{PLATFORM_OSX}-x64"
|
||||
RID_OSX_ARM64 = f"{PLATFORM_OSX}-arm64"
|
||||
RID_FREEBSD_X64 = f"{PLATFORM_FREEBSD}-x64"
|
||||
RID_FREEBSD_ARM64 = f"{PLATFORM_FREEBSD}-arm64"
|
||||
|
||||
DEFAULT_RIDS = [RID_WIN_X64, RID_LINUX_X64, RID_OSX_X64, RID_FREEBSD_X64]
|
||||
ALL_RIDS = [RID_WIN_X64, RID_WIN_ARM64, RID_LINUX_X64, RID_LINUX_ARM64, RID_OSX_X64, RID_OSX_ARM64, RID_FREEBSD_X64, RID_FREEBSD_ARM64]
|
||||
|
||||
IGNORED_RESOURCES = {
|
||||
".gitignore",
|
||||
".directory",
|
||||
@@ -88,7 +111,7 @@ def main() -> None:
|
||||
parser.add_argument("--platform",
|
||||
"-p",
|
||||
action="store",
|
||||
choices=[PLATFORM_WINDOWS, PLATFORM_MACOS, PLATFORM_LINUX, PLATFORM_FREEBSD],
|
||||
choices=ALL_RIDS,
|
||||
nargs="*",
|
||||
help="Which platform to build for. If not provided, all platforms will be built")
|
||||
|
||||
@@ -97,11 +120,17 @@ def main() -> None:
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
args = parser.parse_args()
|
||||
platforms = args.platform
|
||||
skip_build = args.skip_build
|
||||
platforms: list[str] = args.platform
|
||||
skip_build: bool = args.skip_build
|
||||
|
||||
if not platforms:
|
||||
platforms = [PLATFORM_WINDOWS, PLATFORM_MACOS, PLATFORM_LINUX, PLATFORM_FREEBSD]
|
||||
platforms = DEFAULT_RIDS
|
||||
|
||||
# Validate that nobody put invalid platform names in.
|
||||
for rid in platforms:
|
||||
if rid not in ALL_RIDS:
|
||||
print(Fore.RED + f"Invalid platform specified: '{rid}'" + Style.RESET_ALL)
|
||||
exit(1)
|
||||
|
||||
if os.path.exists("release"):
|
||||
print(Fore.BLUE + Style.DIM +
|
||||
@@ -111,32 +140,25 @@ def main() -> None:
|
||||
else:
|
||||
os.mkdir("release")
|
||||
|
||||
for platform in platforms:
|
||||
build_for_platform(platform, skip_build)
|
||||
|
||||
if PLATFORM_WINDOWS in platforms:
|
||||
if not skip_build:
|
||||
wipe_bin()
|
||||
build_windows(skip_build)
|
||||
|
||||
if PLATFORM_LINUX in platforms:
|
||||
if not skip_build:
|
||||
wipe_bin()
|
||||
build_linux(skip_build, "linux", "Linux")
|
||||
def build_for_platform(rid: str, skip_build: bool):
|
||||
print(Fore.GREEN + f"Building for platform '{rid}'..." + Style.RESET_ALL)
|
||||
|
||||
if PLATFORM_LINUX_ARM64 in platforms:
|
||||
if not skip_build:
|
||||
wipe_bin()
|
||||
build_linux_arm64(skip_build)
|
||||
|
||||
if PLATFORM_MACOS in platforms:
|
||||
if not skip_build:
|
||||
wipe_bin()
|
||||
build_macos(skip_build)
|
||||
|
||||
if PLATFORM_FREEBSD in platforms:
|
||||
if not skip_build:
|
||||
wipe_bin()
|
||||
build_linux(skip_build, "freebsd", "FreeBSD")
|
||||
if not skip_build:
|
||||
wipe_bin()
|
||||
|
||||
platform = rid.split('-', maxsplit=2)[0]
|
||||
if platform == PLATFORM_WIN:
|
||||
build_windows(rid, skip_build)
|
||||
elif platform == PLATFORM_LINUX:
|
||||
build_linux_like(rid, TargetOS.Linux, skip_build)
|
||||
elif platform == PLATFORM_OSX:
|
||||
build_macos(rid, skip_build)
|
||||
elif platform == PLATFORM_FREEBSD:
|
||||
build_linux_like(rid, TargetOS.FreeBSD, skip_build)
|
||||
|
||||
def wipe_bin():
|
||||
print(Fore.BLUE + Style.DIM +
|
||||
@@ -146,53 +168,42 @@ def wipe_bin():
|
||||
shutil.rmtree("bin")
|
||||
|
||||
|
||||
def build_windows(skip_build: bool) -> None:
|
||||
# Run a full build.
|
||||
print(Fore.GREEN + "Building project for Windows x64..." + Style.RESET_ALL)
|
||||
|
||||
def build_windows(rid: str, skip_build: bool) -> None:
|
||||
if not skip_build:
|
||||
publish_client("win-x64", "Windows")
|
||||
publish_client(rid, TargetOS.Windows)
|
||||
if sys.platform != "win32":
|
||||
subprocess.run(["Tools/exe_set_subsystem.py", p("bin", "Client", "win-x64", "publish", "Robust.Client"), "2"])
|
||||
subprocess.run(["Tools/exe_set_subsystem.py", p("bin", "Client", rid, "publish", "Robust.Client"), "2"])
|
||||
|
||||
|
||||
print(Fore.GREEN + "Packaging Windows x64 client..." + Style.RESET_ALL)
|
||||
print(Fore.GREEN + f"Packaging {rid} client..." + Style.RESET_ALL)
|
||||
|
||||
client_zip = zipfile.ZipFile(
|
||||
p("release", "Robust.Client_win-x64.zip"), "w",
|
||||
p("release", f"Robust.Client_{rid}.zip"), "w",
|
||||
compression=zipfile.ZIP_DEFLATED)
|
||||
|
||||
copy_dir_into_zip(p("bin", "Client", "win-x64", "publish"), "", client_zip, IGNORED_FILES_WINDOWS)
|
||||
copy_dir_into_zip(p("bin", "Client", rid, "publish"), "", client_zip, IGNORED_FILES_WINDOWS)
|
||||
copy_resources("Resources", client_zip)
|
||||
# Cool we're done.
|
||||
client_zip.close()
|
||||
|
||||
def build_macos(skip_build: bool) -> None:
|
||||
print(Fore.GREEN + "Building project for macOS x64..." + Style.RESET_ALL)
|
||||
|
||||
def build_macos(rid: str, skip_build: bool) -> None:
|
||||
if not skip_build:
|
||||
publish_client("osx-x64", "MacOS")
|
||||
publish_client(rid, TargetOS.MacOS)
|
||||
|
||||
print(Fore.GREEN + "Packaging macOS x64 client..." + Style.RESET_ALL)
|
||||
print(Fore.GREEN + f"Packaging {rid} client..." + Style.RESET_ALL)
|
||||
# Client has to go in an app bundle.
|
||||
client_zip = zipfile.ZipFile(p("release", "Robust.Client_osx-x64.zip"), "a",
|
||||
client_zip = zipfile.ZipFile(p("release", f"Robust.Client_{rid}.zip"), "a",
|
||||
compression=zipfile.ZIP_DEFLATED)
|
||||
|
||||
contents = p("Space Station 14.app", "Contents", "Resources")
|
||||
copy_dir_into_zip(p("BuildFiles", "Mac", "Space Station 14.app"), "Space Station 14.app", client_zip)
|
||||
copy_dir_into_zip(p("bin", "Client", "osx-x64", "publish"), contents, client_zip, IGNORED_FILES_MACOS)
|
||||
copy_dir_into_zip(p("bin", "Client", rid, "publish"), contents, client_zip, IGNORED_FILES_MACOS)
|
||||
copy_resources(p(contents, "Resources"), client_zip)
|
||||
client_zip.close()
|
||||
|
||||
|
||||
def build_linux(skip_build: bool, platform, name) -> None:
|
||||
"""Build on Unix-like platforms including Linux and FreeBSD."""
|
||||
# Run a full build.
|
||||
rid = "%s-x64" % platform
|
||||
print(Fore.GREEN + "Building project for %s..." % rid + Style.RESET_ALL)
|
||||
|
||||
def build_linux_like(rid: str, target_os: TargetOS, skip_build: bool) -> None:
|
||||
if not skip_build:
|
||||
publish_client(rid, name)
|
||||
publish_client(rid, target_os)
|
||||
|
||||
print(Fore.GREEN + "Packaging %s client..." % rid + Style.RESET_ALL)
|
||||
|
||||
@@ -206,37 +217,7 @@ def build_linux(skip_build: bool, platform, name) -> None:
|
||||
client_zip.close()
|
||||
|
||||
|
||||
|
||||
def build_linux_arm64(skip_build: bool) -> None:
|
||||
# Run a full build.
|
||||
# TODO: Linux-arm64 is currently server-only.
|
||||
pass
|
||||
""" print(Fore.GREEN + "Building project for Linux ARM64 (SERVER ONLY)..." + Style.RESET_ALL)
|
||||
|
||||
if not skip_build:
|
||||
subprocess.run([
|
||||
"dotnet",
|
||||
"build",
|
||||
"SpaceStation14.sln",
|
||||
"-c", "Release",
|
||||
"--nologo",
|
||||
"/v:m",
|
||||
"/p:TargetOS=Linux",
|
||||
"/t:Rebuild",
|
||||
"/p:FullRelease=True"
|
||||
], check=True)
|
||||
|
||||
publish_client("linux-arm64", "Linux", True)
|
||||
|
||||
print(Fore.GREEN + "Packaging Linux ARM64 server..." + Style.RESET_ALL)
|
||||
server_zip = zipfile.ZipFile(p("release", "SS14.Server_Linux_ARM64.zip"), "w",
|
||||
compression=zipfile.ZIP_DEFLATED)
|
||||
copy_dir_into_zip(p("RobustToolbox", "bin", "Server", "linux-arm64", "publish"), "", server_zip)
|
||||
copy_resources(p("Resources"), server_zip, server=True)
|
||||
server_zip.close()"""
|
||||
|
||||
|
||||
def publish_client(runtime: str, target_os: str) -> None:
|
||||
def publish_client(runtime: str, target_os: TargetOS) -> None:
|
||||
base = [
|
||||
"dotnet", "publish",
|
||||
"--runtime", runtime,
|
||||
|
||||
Reference in New Issue
Block a user