Added display selection option to settings for fullscreen modes.
This commit is contained in:
committed by
Paul Chote
parent
de0bb9ee39
commit
98aef70e88
@@ -17,7 +17,7 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
public interface IPlatform
|
public interface IPlatform
|
||||||
{
|
{
|
||||||
IPlatformWindow CreateWindow(Size size, WindowMode windowMode, float scaleModifier, int batchSize);
|
IPlatformWindow CreateWindow(Size size, WindowMode windowMode, float scaleModifier, int batchSize, int videoDisplay);
|
||||||
ISoundEngine CreateSound(string device);
|
ISoundEngine CreateSound(string device);
|
||||||
IFont CreateFont(byte[] data);
|
IFont CreateFont(byte[] data);
|
||||||
}
|
}
|
||||||
@@ -44,6 +44,8 @@ namespace OpenRA
|
|||||||
float NativeWindowScale { get; }
|
float NativeWindowScale { get; }
|
||||||
float EffectiveWindowScale { get; }
|
float EffectiveWindowScale { get; }
|
||||||
Size SurfaceSize { get; }
|
Size SurfaceSize { get; }
|
||||||
|
int DisplayCount { get; }
|
||||||
|
int CurrentDisplay { get; }
|
||||||
|
|
||||||
event Action<float, float, float, float> OnWindowScaleChanged;
|
event Action<float, float, float, float> OnWindowScaleChanged;
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ namespace OpenRA
|
|||||||
this.platform = platform;
|
this.platform = platform;
|
||||||
var resolution = GetResolution(graphicSettings);
|
var resolution = GetResolution(graphicSettings);
|
||||||
|
|
||||||
Window = platform.CreateWindow(new Size(resolution.Width, resolution.Height), graphicSettings.Mode, graphicSettings.UIScale, graphicSettings.BatchSize);
|
Window = platform.CreateWindow(new Size(resolution.Width, resolution.Height), graphicSettings.Mode, graphicSettings.UIScale, graphicSettings.BatchSize, graphicSettings.VideoDisplay);
|
||||||
Context = Window.Context;
|
Context = Window.Context;
|
||||||
|
|
||||||
TempBufferSize = graphicSettings.BatchSize;
|
TempBufferSize = graphicSettings.BatchSize;
|
||||||
@@ -478,5 +478,15 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
return platform.CreateFont(data);
|
return platform.CreateFont(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int DisplayCount
|
||||||
|
{
|
||||||
|
get { return Window.DisplayCount; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CurrentDisplay
|
||||||
|
{
|
||||||
|
get { return Window.CurrentDisplay; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,6 +176,9 @@ namespace OpenRA
|
|||||||
[Desc("Use OpenGL ES if both ES and regular OpenGL are available.")]
|
[Desc("Use OpenGL ES if both ES and regular OpenGL are available.")]
|
||||||
public bool PreferGLES = false;
|
public bool PreferGLES = false;
|
||||||
|
|
||||||
|
[Desc("Display index to use in a multi-monitor fullscreen setup.")]
|
||||||
|
public int VideoDisplay = 0;
|
||||||
|
|
||||||
public int BatchSize = 8192;
|
public int BatchSize = 8192;
|
||||||
public int SheetSize = 2048;
|
public int SheetSize = 2048;
|
||||||
|
|
||||||
|
|||||||
@@ -121,6 +121,9 @@ namespace OpenRA.Mods.Common.LoadScreens
|
|||||||
Game.Renderer.SetUIScale(1.0f);
|
Game.Renderer.SetUIScale(1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Saved settings may have been invalidated by a hardware change
|
||||||
|
Game.Settings.Graphics.VideoDisplay = Game.Renderer.CurrentDisplay;
|
||||||
|
|
||||||
// If a ModContent section is defined then we need to make sure that the
|
// If a ModContent section is defined then we need to make sure that the
|
||||||
// required content is installed or switch to the defined content installer.
|
// required content is installed or switch to the defined content installer.
|
||||||
if (!ModData.Manifest.Contains<ModContent>())
|
if (!ModData.Manifest.Contains<ModContent>())
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
{
|
{
|
||||||
enum PanelType { Display, Audio, Input, Hotkeys, Advanced }
|
enum PanelType { Display, Audio, Input, Hotkeys, Advanced }
|
||||||
|
|
||||||
|
static readonly int OriginalVideoDisplay;
|
||||||
static readonly string OriginalSoundDevice;
|
static readonly string OriginalSoundDevice;
|
||||||
static readonly WindowMode OriginalGraphicsMode;
|
static readonly WindowMode OriginalGraphicsMode;
|
||||||
static readonly int2 OriginalGraphicsWindowedSize;
|
static readonly int2 OriginalGraphicsWindowedSize;
|
||||||
@@ -52,6 +53,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
var original = Game.Settings;
|
var original = Game.Settings;
|
||||||
OriginalSoundDevice = original.Sound.Device;
|
OriginalSoundDevice = original.Sound.Device;
|
||||||
OriginalGraphicsMode = original.Graphics.Mode;
|
OriginalGraphicsMode = original.Graphics.Mode;
|
||||||
|
OriginalVideoDisplay = original.Graphics.VideoDisplay;
|
||||||
OriginalGraphicsWindowedSize = original.Graphics.WindowedSize;
|
OriginalGraphicsWindowedSize = original.Graphics.WindowedSize;
|
||||||
OriginalGraphicsFullscreenSize = original.Graphics.FullscreenSize;
|
OriginalGraphicsFullscreenSize = original.Graphics.FullscreenSize;
|
||||||
OriginalServerDiscoverNatDevices = original.Server.DiscoverNatDevices;
|
OriginalServerDiscoverNatDevices = original.Server.DiscoverNatDevices;
|
||||||
@@ -92,6 +94,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
Action closeAndExit = () => { Ui.CloseWindow(); onExit(); };
|
Action closeAndExit = () => { Ui.CloseWindow(); onExit(); };
|
||||||
if (current.Sound.Device != OriginalSoundDevice ||
|
if (current.Sound.Device != OriginalSoundDevice ||
|
||||||
current.Graphics.Mode != OriginalGraphicsMode ||
|
current.Graphics.Mode != OriginalGraphicsMode ||
|
||||||
|
current.Graphics.VideoDisplay != OriginalVideoDisplay ||
|
||||||
current.Graphics.WindowedSize != OriginalGraphicsWindowedSize ||
|
current.Graphics.WindowedSize != OriginalGraphicsWindowedSize ||
|
||||||
current.Graphics.FullscreenSize != OriginalGraphicsFullscreenSize ||
|
current.Graphics.FullscreenSize != OriginalGraphicsFullscreenSize ||
|
||||||
current.Server.DiscoverNatDevices != OriginalServerDiscoverNatDevices)
|
current.Server.DiscoverNatDevices != OriginalServerDiscoverNatDevices)
|
||||||
@@ -250,7 +253,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
"Windowed" : ds.Mode == WindowMode.Fullscreen ? "Fullscreen (Legacy)" : "Fullscreen";
|
"Windowed" : ds.Mode == WindowMode.Fullscreen ? "Fullscreen (Legacy)" : "Fullscreen";
|
||||||
|
|
||||||
var modeChangesDesc = panel.Get("MODE_CHANGES_DESC");
|
var modeChangesDesc = panel.Get("MODE_CHANGES_DESC");
|
||||||
modeChangesDesc.IsVisible = () => ds.Mode != WindowMode.Windowed && ds.Mode != OriginalGraphicsMode;
|
modeChangesDesc.IsVisible = () => ds.Mode != WindowMode.Windowed && (ds.Mode != OriginalGraphicsMode ||
|
||||||
|
ds.VideoDisplay != OriginalVideoDisplay);
|
||||||
|
|
||||||
|
var displaySelectionDropDown = panel.Get<DropDownButtonWidget>("DISPLAY_SELECTION_DROPDOWN");
|
||||||
|
displaySelectionDropDown.OnMouseDown = _ => ShowDisplaySelectionDropdown(displaySelectionDropDown, ds);
|
||||||
|
var displaySelectionLabel = new CachedTransform<int, string>(i => "Display {0}".F(i + 1));
|
||||||
|
displaySelectionDropDown.GetText = () => displaySelectionLabel.Update(ds.VideoDisplay);
|
||||||
|
displaySelectionDropDown.IsDisabled = () => Game.Renderer.DisplayCount < 2;
|
||||||
|
|
||||||
var statusBarsDropDown = panel.Get<DropDownButtonWidget>("STATUS_BAR_DROPDOWN");
|
var statusBarsDropDown = panel.Get<DropDownButtonWidget>("STATUS_BAR_DROPDOWN");
|
||||||
statusBarsDropDown.OnMouseDown = _ => ShowStatusBarsDropdown(statusBarsDropDown, gs);
|
statusBarsDropDown.OnMouseDown = _ => ShowStatusBarsDropdown(statusBarsDropDown, gs);
|
||||||
@@ -289,6 +299,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
|
|
||||||
uiScaleDropdown.IsDisabled = () => disableUIScale;
|
uiScaleDropdown.IsDisabled = () => disableUIScale;
|
||||||
|
|
||||||
|
panel.Get("DISPLAY_SELECTION").IsVisible = () => ds.Mode != WindowMode.Windowed;
|
||||||
panel.Get("WINDOW_RESOLUTION").IsVisible = () => ds.Mode == WindowMode.Windowed;
|
panel.Get("WINDOW_RESOLUTION").IsVisible = () => ds.Mode == WindowMode.Windowed;
|
||||||
var windowWidth = panel.Get<TextFieldWidget>("WINDOW_WIDTH");
|
var windowWidth = panel.Get<TextFieldWidget>("WINDOW_WIDTH");
|
||||||
var origWidthText = windowWidth.Text = ds.WindowedSize.X.ToString();
|
var origWidthText = windowWidth.Text = ds.WindowedSize.X.ToString();
|
||||||
@@ -369,6 +380,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
ds.MaxFramerate = dds.MaxFramerate;
|
ds.MaxFramerate = dds.MaxFramerate;
|
||||||
ds.Language = dds.Language;
|
ds.Language = dds.Language;
|
||||||
ds.Mode = dds.Mode;
|
ds.Mode = dds.Mode;
|
||||||
|
ds.VideoDisplay = dds.VideoDisplay;
|
||||||
ds.WindowedSize = dds.WindowedSize;
|
ds.WindowedSize = dds.WindowedSize;
|
||||||
ds.CursorDouble = dds.CursorDouble;
|
ds.CursorDouble = dds.CursorDouble;
|
||||||
ds.ViewportDistance = dds.ViewportDistance;
|
ds.ViewportDistance = dds.ViewportDistance;
|
||||||
@@ -830,6 +842,22 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem);
|
dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ShowDisplaySelectionDropdown(DropDownButtonWidget dropdown, GraphicSettings s)
|
||||||
|
{
|
||||||
|
Func<int, ScrollItemWidget, ScrollItemWidget> setupItem = (o, itemTemplate) =>
|
||||||
|
{
|
||||||
|
var item = ScrollItemWidget.Setup(itemTemplate,
|
||||||
|
() => s.VideoDisplay == o,
|
||||||
|
() => s.VideoDisplay = o);
|
||||||
|
|
||||||
|
var label = "Display {0}".F(o + 1);
|
||||||
|
item.Get<LabelWidget>("LABEL").GetText = () => label;
|
||||||
|
return item;
|
||||||
|
};
|
||||||
|
|
||||||
|
dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, Enumerable.Range(0, Game.Renderer.DisplayCount), setupItem);
|
||||||
|
}
|
||||||
|
|
||||||
static void ShowTargetLinesDropdown(DropDownButtonWidget dropdown, GameSettings s)
|
static void ShowTargetLinesDropdown(DropDownButtonWidget dropdown, GameSettings s)
|
||||||
{
|
{
|
||||||
var options = new Dictionary<string, TargetLinesType>()
|
var options = new Dictionary<string, TargetLinesType>()
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ namespace OpenRA.Platforms.Default
|
|||||||
{
|
{
|
||||||
public class DefaultPlatform : IPlatform
|
public class DefaultPlatform : IPlatform
|
||||||
{
|
{
|
||||||
public IPlatformWindow CreateWindow(Size size, WindowMode windowMode, float scaleModifier, int batchSize)
|
public IPlatformWindow CreateWindow(Size size, WindowMode windowMode, float scaleModifier, int batchSize, int videoDisplay)
|
||||||
{
|
{
|
||||||
return new Sdl2PlatformWindow(size, windowMode, scaleModifier, batchSize);
|
return new Sdl2PlatformWindow(size, windowMode, scaleModifier, batchSize, videoDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ISoundEngine CreateSound(string device)
|
public ISoundEngine CreateSound(string device)
|
||||||
|
|||||||
@@ -87,12 +87,28 @@ namespace OpenRA.Platforms.Default
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int CurrentDisplay
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return SDL.SDL_GetWindowDisplayIndex(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int DisplayCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return SDL.SDL_GetNumVideoDisplays();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public event Action<float, float, float, float> OnWindowScaleChanged = (oldNative, oldEffective, newNative, newEffective) => { };
|
public event Action<float, float, float, float> OnWindowScaleChanged = (oldNative, oldEffective, newNative, newEffective) => { };
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
static extern bool SetProcessDPIAware();
|
static extern bool SetProcessDPIAware();
|
||||||
|
|
||||||
public Sdl2PlatformWindow(Size requestEffectiveWindowSize, WindowMode windowMode, float scaleModifier, int batchSize)
|
public Sdl2PlatformWindow(Size requestEffectiveWindowSize, WindowMode windowMode, float scaleModifier, int batchSize, int videoDisplay)
|
||||||
{
|
{
|
||||||
// Lock the Window/Surface properties until initialization is complete
|
// Lock the Window/Surface properties until initialization is complete
|
||||||
lock (syncObject)
|
lock (syncObject)
|
||||||
@@ -129,8 +145,11 @@ namespace OpenRA.Platforms.Default
|
|||||||
|
|
||||||
Console.WriteLine("Using SDL 2 with OpenGL{0} renderer", useGLES ? " ES" : "");
|
Console.WriteLine("Using SDL 2 with OpenGL{0} renderer", useGLES ? " ES" : "");
|
||||||
|
|
||||||
|
if (videoDisplay < 0 || videoDisplay >= DisplayCount)
|
||||||
|
videoDisplay = 0;
|
||||||
|
|
||||||
SDL.SDL_DisplayMode display;
|
SDL.SDL_DisplayMode display;
|
||||||
SDL.SDL_GetCurrentDisplayMode(0, out display);
|
SDL.SDL_GetCurrentDisplayMode(videoDisplay, out display);
|
||||||
|
|
||||||
// Windows and Linux define window sizes in native pixel units.
|
// Windows and Linux define window sizes in native pixel units.
|
||||||
// Query the display/dpi scale so we can convert our requested effective size to pixels.
|
// Query the display/dpi scale so we can convert our requested effective size to pixels.
|
||||||
@@ -138,7 +157,7 @@ namespace OpenRA.Platforms.Default
|
|||||||
if (Platform.CurrentPlatform == PlatformType.Windows)
|
if (Platform.CurrentPlatform == PlatformType.Windows)
|
||||||
{
|
{
|
||||||
float ddpi, hdpi, vdpi;
|
float ddpi, hdpi, vdpi;
|
||||||
if (SDL.SDL_GetDisplayDPI(0, out ddpi, out hdpi, out vdpi) == 0)
|
if (SDL.SDL_GetDisplayDPI(videoDisplay, out ddpi, out hdpi, out vdpi) == 0)
|
||||||
windowScale = ddpi / 96;
|
windowScale = ddpi / 96;
|
||||||
}
|
}
|
||||||
else if (Platform.CurrentPlatform != PlatformType.OSX)
|
else if (Platform.CurrentPlatform != PlatformType.OSX)
|
||||||
@@ -166,7 +185,7 @@ namespace OpenRA.Platforms.Default
|
|||||||
if (Platform.CurrentPlatform == PlatformType.OSX && windowMode == WindowMode.Fullscreen)
|
if (Platform.CurrentPlatform == PlatformType.OSX && windowMode == WindowMode.Fullscreen)
|
||||||
SDL.SDL_SetHint(SDL.SDL_HINT_VIDEO_HIGHDPI_DISABLED, "1");
|
SDL.SDL_SetHint(SDL.SDL_HINT_VIDEO_HIGHDPI_DISABLED, "1");
|
||||||
|
|
||||||
window = SDL.SDL_CreateWindow("OpenRA", SDL.SDL_WINDOWPOS_CENTERED, SDL.SDL_WINDOWPOS_CENTERED,
|
window = SDL.SDL_CreateWindow("OpenRA", SDL.SDL_WINDOWPOS_CENTERED_DISPLAY(videoDisplay), SDL.SDL_WINDOWPOS_CENTERED_DISPLAY(videoDisplay),
|
||||||
windowSize.Width, windowSize.Height, windowFlags);
|
windowSize.Width, windowSize.Height, windowFlags);
|
||||||
|
|
||||||
// Work around an issue in macOS's GL backend where the window remains permanently black
|
// Work around an issue in macOS's GL backend where the window remains permanently black
|
||||||
@@ -235,11 +254,6 @@ namespace OpenRA.Platforms.Default
|
|||||||
}
|
}
|
||||||
else if (windowMode == WindowMode.PseudoFullscreen)
|
else if (windowMode == WindowMode.PseudoFullscreen)
|
||||||
{
|
{
|
||||||
// Work around a visual glitch in OSX: the window is offset
|
|
||||||
// partially offscreen if the dock is at the left of the screen
|
|
||||||
if (Platform.CurrentPlatform == PlatformType.OSX)
|
|
||||||
SDL.SDL_SetWindowPosition(Window, 0, 0);
|
|
||||||
|
|
||||||
SDL.SDL_SetWindowFullscreen(Window, (uint)SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP);
|
SDL.SDL_SetWindowFullscreen(Window, (uint)SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||||
SDL.SDL_SetHint(SDL.SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
|
SDL.SDL_SetHint(SDL.SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -200,13 +200,6 @@ Container@SETTINGS_PANEL:
|
|||||||
Height: 25
|
Height: 25
|
||||||
Font: Regular
|
Font: Regular
|
||||||
Text: Windowed
|
Text: Windowed
|
||||||
Label@MODE_CHANGES_DESC:
|
|
||||||
X: 100
|
|
||||||
Y: 237
|
|
||||||
Width: 200
|
|
||||||
Height: 15
|
|
||||||
Font: Tiny
|
|
||||||
Text: Video mode changes require restart
|
|
||||||
Container@WINDOW_RESOLUTION:
|
Container@WINDOW_RESOLUTION:
|
||||||
Y: 240
|
Y: 240
|
||||||
Children:
|
Children:
|
||||||
@@ -242,6 +235,27 @@ Container@SETTINGS_PANEL:
|
|||||||
Height: 15
|
Height: 15
|
||||||
Font: Tiny
|
Font: Tiny
|
||||||
Text: Video mode and window size changes require restart
|
Text: Video mode and window size changes require restart
|
||||||
|
Container@DISPLAY_SELECTION:
|
||||||
|
Y: 240
|
||||||
|
Children:
|
||||||
|
Label@DISPLAY_SELECTION_LABEL:
|
||||||
|
X: 15
|
||||||
|
Height: 25
|
||||||
|
Width: 120
|
||||||
|
Align: Right
|
||||||
|
Text: Select Display:
|
||||||
|
DropDownButton@DISPLAY_SELECTION_DROPDOWN:
|
||||||
|
X: 140
|
||||||
|
Width: 160
|
||||||
|
Height: 25
|
||||||
|
Font: Regular
|
||||||
|
Label@MODE_CHANGES_DESC:
|
||||||
|
X: 60
|
||||||
|
Y: 27
|
||||||
|
Width: 200
|
||||||
|
Height: 15
|
||||||
|
Font: Tiny
|
||||||
|
Text: Video mode and display changes require restart
|
||||||
Checkbox@VSYNC_CHECKBOX:
|
Checkbox@VSYNC_CHECKBOX:
|
||||||
X: 310
|
X: 310
|
||||||
Y: 210
|
Y: 210
|
||||||
|
|||||||
@@ -214,13 +214,6 @@ Background@SETTINGS_PANEL:
|
|||||||
Height: 25
|
Height: 25
|
||||||
Font: Regular
|
Font: Regular
|
||||||
Text: Windowed
|
Text: Windowed
|
||||||
Label@MODE_CHANGES_DESC:
|
|
||||||
X: 100
|
|
||||||
Y: 237
|
|
||||||
Width: 200
|
|
||||||
Height: 15
|
|
||||||
Font: Tiny
|
|
||||||
Text: Video mode changes require restart
|
|
||||||
Checkbox@VSYNC_CHECKBOX:
|
Checkbox@VSYNC_CHECKBOX:
|
||||||
X: 310
|
X: 310
|
||||||
Y: 213
|
Y: 213
|
||||||
@@ -263,6 +256,28 @@ Background@SETTINGS_PANEL:
|
|||||||
Height: 15
|
Height: 15
|
||||||
Font: Tiny
|
Font: Tiny
|
||||||
Text: Video mode and window size changes require restart
|
Text: Video mode and window size changes require restart
|
||||||
|
Container@DISPLAY_SELECTION:
|
||||||
|
Y: 240
|
||||||
|
Children:
|
||||||
|
Label@DISPLAY_SELECTION_LABEL:
|
||||||
|
X: 15
|
||||||
|
Height: 25
|
||||||
|
Width: 120
|
||||||
|
Align: Right
|
||||||
|
Text: Select Display:
|
||||||
|
DropDownButton@DISPLAY_SELECTION_DROPDOWN:
|
||||||
|
X: 140
|
||||||
|
Width: 160
|
||||||
|
Height: 25
|
||||||
|
Font: Regular
|
||||||
|
Text: Standard
|
||||||
|
Label@MODE_CHANGES_DESC:
|
||||||
|
X: 60
|
||||||
|
Y: 27
|
||||||
|
Width: 200
|
||||||
|
Height: 15
|
||||||
|
Font: Tiny
|
||||||
|
Text: Video mode and display changes require restart
|
||||||
Checkbox@FRAME_LIMIT_CHECKBOX:
|
Checkbox@FRAME_LIMIT_CHECKBOX:
|
||||||
X: 310
|
X: 310
|
||||||
Y: 243
|
Y: 243
|
||||||
|
|||||||
Reference in New Issue
Block a user