System scaling detection

Hello fellow gamedevs,

I’m facing an issue regarding Windows scaling with my DesktopGL project.

In the options of my game, users can choose between the various resolutions that are accepted by the adapter. ( using GraphicsAdapter.SupportedDisplayModes ).
Users can also choose wether the game is in fullscreen, windowed or borderless. Nothing really fancy there. The user chooses the resolution and the mode, and voilà.

My problem is that when windows scaling is not 100% ( which seems to occur a lot more than i thought ), then the list of resolutions is becoming a problem :
Let’s say the player has a 1080p screen and a scaling set to 150%.
If the players set the game to 1920x1080, in windowed mode, then the game window will be displayed with a 1.5 size factor, leading to a window larger than the screen, and parts of the game screen not visible ( which can eventually prevent the user for changing back the resolution ).

My question is :
Is there a monogame way to handle such case and to get the OS scaling, or a list of supported resolutions taking the scaling into account ?
How do you usually handle such case ?

Thanks in advance.

I’m not sure if there’s a MonoGame way to do this… others may know. I’m not even sure if other operating systems do this, or if it’s only Windows. With that in mind though, you can solve this in a fairly straightforward way on a per platform basis…

In common code…

public interface IDesktopScale
{
  float Scale { get; }
}

public class MainGame : Game // ie, your game class
{
  private IDesktopScale _desktopScale;

  public MainGame(IDesktopScale desktopScale)
  {
    _desktopScale = desktopScale ?? throw new ArgumentNullException();
  }
}

In your Windows entrypoint (likely Program.cs)

public class WindowsDesktopScale : IDesktopScale
{
  public float Scale { get; private set; }

  public WindowsDesktopScale()
  {
    // It looks like it's stored in the registry for Windows.
    // See here: https://stackoverflow.com/questions/32607468/get-scale-of-screen
    int DPI = (int)Registry.GetValue("HKEY_CURRENT_USER\\Control Panel\\Desktop", "LogPixels", 96);
    this.Scale = 96/(float)DPI;
  }
}

static void Main()
{
  var game = new MainGame(new WindowsDesktopScale());
  game.Run();
}

For any other operating systems you support you would need to implement that interface. If that OS doesn’t support desktop scaling, just have it set the scale value to 1.0f and you’re good to go. Now your game can use _desktopScale in whatever window resolution calculations you wish.

Hope that helps :slight_smile:

1 Like

Weird, I haven’t encountered any issues with scaling when I’ve tested my game, but I don’t use SupportedDisplayModes in my code.

If the game resolution is equal to the monitor resolution in window mode, the full window won’t be able to fit on screen even without scaling, because the total size of the window is the game resolution plus the title bar or whatever it’s called. Unless the window is borderless, obviously.

You should just be able to ignore scaling by directly setting your game resolution and window size.