I'm a professional game developer from Wakefield, England, working as a senior programmer for Rebellion North.
I'm a married father of five and I a also sometimes do Retroburn stuff.
Martin 'Bytrix' Caine
Father. C++ Games Programmer. Cyclist. Guitarist.
2013 3d alphalabs amazon apple archivirtual asynchronous battlefield bad company 2 ben 10 bepu beta blackmagic design blog blue marble bootcamp borderlands bsp calibration charity charvel childsplay comments competition content tracker counter-strike crash csgo css3 cycling dear esther deferred deus ex develop conference direct x discipline documentation doom 3 bfg dpi dr bott eidos elite force email deliverability eurogamer expo facebook focus fresnel game development game horizon game republic gamedev games gaming geoip girls make games global offensive grid guitar half-life 2 hawken hd7 hobbyist htc humble indie bundle imac indie indie trials indietrials intensity pro ip-countryside iron man 3 jamulus rift jquery kids kinect launch conference left 4 dead live lost mac mac osx manchester manhacks mass effect 2 matrox maya minecraft mirrors edge montreal morrowind movies museum of the microstar music mxo2 mini mysql nausea network networking nokia normal mapping obj oculus rift omnitrix ouya pedal for pounds php physics playstation suite port25 portal portal 2 positron posters powermta project aedra project euler promotion properties proton pulse ps vita ps4 psn racer reddit rendering retroburn game studios reviews rift racer riftracer roadkill roller coaster sdl2 shadow racers sharks shoct skyrifters snds space cadet spam trap star trek steam stencyl storage super stock sd1 fr superhot team fortress 2 tesselating tesselation texture editor thunderbird thunderclap ticktock games tiga track builder track bulder trials tv twitter uk ultimatrix usergroup vequencer video vireio visual assist visual studio vorpx voucher vr vr cinema war thunder warren web willow windows 8 windows 8.1 windows phone 7 workbench wp7 wp7dev xbla xblig xblig network xbox xbox live indie games xna xnaukug xperia play zombies on the holodeck
Email Deliverability
Sunday, November 8th 2015 / Blog

DPI Scaling in Windows with SDL2

I'm using SDL2 at the base of my own engine to help with cross platform compatibility at the lowest level. We're also using it at work for Z Steel Soldiers (and other games) and we had numerous reports of strange things happening which all sounded like DPI scaling issues to me.

On some machines our games would launch and appear to be clipped off-screen. So you'd only see the top left portion of the screen and couldn't select any buttons or elements that were off screen. The other issue was that the full screen would render, but the mouse would be trapped in the top left portion.

We ran some tests and figured out that changing Windows DPI scaling settings did have an effect and we could get the game in to a situation where it wouldn't fit on screen. We managed to fix this by setting the dpiAware flag in the Application Manifest via Visual Studio. We updated the game on Steam and had many players saying it fixed the issues they were having, but over time some people kept reporting issues on their machines.

I spent some time this morning testing various DPI scaling scenarios on my home machine and found that windows has two entirely different scaling mechanisms. One applies a scale to everything in the system (and was included in Vista, Windows 7, and Windows 8). Windows 8.1 and Windows 10 also include per-monitor DPI scaling (but confusingly still allow you to set the global scale too as per the older method).

It seems that setting the dpiAware flag within Visual Studio only fixed our problems when the player was using the older DPI scaling method. The newer one still results in larger-than-desired windows (which wouldn't fit on the screen). I found a link to some documentation that stated there were newer values which could be set in the manifest, so I tried setting them via Visual Studio. Nothing I entered in to the box had any effect on the resulting manifest, it would always just override and come out with true.

So I knocked up a small manifest and told Visual Studio to parse this in when creating the Application Manifest:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>

This successfully inserted the value True/PM in to the dpiAware tag, and now the game loads up and fills the screen regardless of what DPI scaling settings I have set on any of my monitors!

Now this issue isn't fully related to SDL2, it'll likely happen regardless of what framework you're using but since we relied on the information SDL2 was returning for window size and GL display size, we needed it to report the correct resolution information. With this single manifest setting these calls all return the proper pixel sizes we expect.

If you found this post helpful please leave a comment below:
Tags:   dpi   gamedev   sdl2