Dreamfall Chapters: Book 1 was just released (go buy it), and it’s another game using the Unity engine. Like with another recent Unity title, Wasteland 2, it refused to work with GeDoSaTo. Now, since I like both of these games a lot I invested some time to find out what’s happening, and hopefully fix it.
Without further ado, here are my findings. This is what recent Unity engine games do on Windows if you select “fullscreen” mode. Note that all of this is based on deduction from the behaviour of Dreamfall and Wasteland 2, someone with access to the Unity source probably has a more exact understanding:
- Check the desktop resolution and create a fullscreen window as well as a DirectX device with that size.
- Check the native monitor resolution (using GetMonitorInfo), and reset the device/window to that size.
- Render at whatever resolution you specify in the game settings, to an off-screen surface.
- Stretch that surface to the window.
So, no real fullscreen mode in sight. Why would you do this? Well, it has multiple advantages: you don’t lose your resources switching to another rendering resolution, alt-tab behaviour is much faster and more stable, and you get free, correctly implemented triple buffering if the user is using Aero.
Obviously, this majorly messed up the way GeDoSaTo works — and the same goes for traditional downsampling methods. In the latest version, it’s now possible to downsample Unity games following this scheme, provided you add this magic formula to their configuration file:
It works by “pretending” that both the desktop and monitor are the given renderResolution in size, forcing that to always be reported, and modifying the mouse cursor position used by the game (so that clicks register correctly). GeDoSaTo takes care of actually constraining the fullscreen window to the correct size, and of course performs a high-quality downsampling of the rendering result as always.
Since the resolution you want to downsample from needs to be known before the game requests any, only a single rendering resolution can be provided.
Already in earlier versions, a problem in games using windowed modes was that custom cursors would be lost outside of the rectangular region corresponding to portion of the screen that would be taken up by a window downscaled by the downsampling factor. I figured out why this happens: To make games work, the cursor positions reported to them need to be adjusted (modifyGetCursorPos). This works for any processing within the game, as it thinks it is operating within a larger rendering area.
However, an issue occurs for cursors: I found out that many/most games use the Windows API WindowFromPoint function to check if the mouse is within their window before setting the cursor, passing the modified coordinates. Now obviously, Windows knows what the real window sizes are, and the modified virtual coordinates fall out of them. So I had to apply the reverse transformation in that function.
Anyway, the new version is called “Tokikagura”. Other than the stuff discussed above it also includes some GeDoSaToTool fixes.
By the way, Nvidia’s DSR can’t downsample in these games (for now). Take that big boy corporate version!