diff --git a/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs b/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs index ae368bb51b..51b51f6293 100644 --- a/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs +++ b/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs @@ -31,11 +31,18 @@ namespace OpenRA.Platforms.Default internal Size SurfaceSize { get; private set; } public event Action OnWindowScaleChanged = (before, after) => { }; + [DllImport("user32.dll")] + static extern bool SetProcessDPIAware(); + public Sdl2GraphicsDevice(Size windowSize, WindowMode windowMode) { Console.WriteLine("Using SDL 2 with OpenGL renderer"); WindowSize = windowSize; + // Disable legacy scaling on Windows + if (Platform.CurrentPlatform == PlatformType.Windows) + SetProcessDPIAware(); + SDL.SDL_Init(SDL.SDL_INIT_NOPARACHUTE | SDL.SDL_INIT_VIDEO); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DOUBLEBUFFER, 1); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_RED_SIZE, 8); @@ -55,10 +62,7 @@ namespace OpenRA.Platforms.Default Console.WriteLine("Using resolution: {0}x{1}", WindowSize.Width, WindowSize.Height); - var windowFlags = SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL; - if (Platform.CurrentPlatform == PlatformType.OSX) - windowFlags |= SDL.SDL_WindowFlags.SDL_WINDOW_ALLOW_HIGHDPI; - + var windowFlags = SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL.SDL_WindowFlags.SDL_WINDOW_ALLOW_HIGHDPI; window = SDL.SDL_CreateWindow("OpenRA", SDL.SDL_WINDOWPOS_CENTERED, SDL.SDL_WINDOWPOS_CENTERED, WindowSize.Width, WindowSize.Height, windowFlags); @@ -75,6 +79,15 @@ namespace OpenRA.Platforms.Default SurfaceSize = new Size(width, height); WindowScale = width * 1f / WindowSize.Width; } + else if (Platform.CurrentPlatform == PlatformType.Windows) + { + float ddpi, hdpi, vdpi; + if (SDL.SDL_GetDisplayDPI(0, out ddpi, out hdpi, out vdpi) == 0) + { + WindowScale = ddpi / 96; + WindowSize = new Size((int)(SurfaceSize.Width / WindowScale), (int)(SurfaceSize.Height / WindowScale)); + } + } Console.WriteLine("Using window scale {0:F2}", WindowScale); diff --git a/OpenRA.Platforms.Default/Sdl2Input.cs b/OpenRA.Platforms.Default/Sdl2Input.cs index dd19d34467..f69b5d76a8 100644 --- a/OpenRA.Platforms.Default/Sdl2Input.cs +++ b/OpenRA.Platforms.Default/Sdl2Input.cs @@ -40,6 +40,16 @@ namespace OpenRA.Platforms.Default | ((raw & (int)SDL.SDL_Keymod.KMOD_SHIFT) != 0 ? Modifiers.Shift : 0); } + int2 EventPosition(Sdl2GraphicsDevice device, int x, int y) + { + // On Windows and Linux (X11) events are given in surface coordinates + // These must be scaled to our effective window coordinates + if (Platform.CurrentPlatform != PlatformType.OSX && device.WindowSize != device.SurfaceSize) + return new int2((int)(x / device.WindowScale), (int)(y / device.WindowScale)); + + return new int2(x, y); + } + public void PumpInput(Sdl2GraphicsDevice device, IInputHandler inputHandler) { var mods = MakeModifiers((int)SDL.SDL_GetModState()); @@ -88,8 +98,7 @@ namespace OpenRA.Platforms.Default var button = MakeButton(e.button.button); lastButtonBits |= button; - var pos = new int2(e.button.x, e.button.y); - + var pos = EventPosition(device, e.button.x, e.button.y); inputHandler.OnMouseInput(new MouseInput( MouseInputEvent.Down, button, scrollDelta, pos, mods, MultiTapDetection.DetectFromMouse(e.button.button, pos))); @@ -108,7 +117,7 @@ namespace OpenRA.Platforms.Default var button = MakeButton(e.button.button); lastButtonBits &= ~button; - var pos = new int2(e.button.x, e.button.y); + var pos = EventPosition(device, e.button.x, e.button.y); inputHandler.OnMouseInput(new MouseInput( MouseInputEvent.Up, button, scrollDelta, pos, mods, MultiTapDetection.InfoFromMouse(e.button.button))); @@ -118,9 +127,10 @@ namespace OpenRA.Platforms.Default case SDL.SDL_EventType.SDL_MOUSEMOTION: { + var pos = EventPosition(device, e.motion.x, e.motion.y); pendingMotion = new MouseInput( MouseInputEvent.Move, lastButtonBits, scrollDelta, - new int2(e.motion.x, e.motion.y), mods, 0); + pos, mods, 0); break; }