Zestiria character shadow improvements, GeDoSaTo injection compatibility

I just pushed a new game-specific plugin for Tales of Zestiria which increases character shadow resolution/detail. It’s just a minor change, but it was annoying me that the in-game shadow setting increased environmental shadow resolution, but only blurred character shadows more. It just doesn’t make sense that shadows (ostensibly from the same light source) would look completely different if they were cast from characters rather than the environment.

It turned out that the character shadows were being rendered at only 64×64 (!), with 128×128 for Sorey, so it’s hardly surprising that they lacked detail. The new game-specific plugin rectifies that, and it’s designed to show similar detail to the game’s “high” environment shadows. Compare:

Original character shadowsModded character shadowsNote how the character shadows are just amorphous blobs in the original image. This would be fine I guess as a design choice if it was uniform, but the environment shadows right next to them are much more sharp and detailed! In the modded version, I tried to unify their appearance so that they look like they belong in the same scene.

GeDoSaTo New Injection Compatibility

By now, I’ve got a lot of feedback on the new injection method. What I expected was for quite a few games to stop working for everyone, while others would still work perfectly. That didn’t really happen to any extent.

The good news is that the new (much safer) injection method seems to have fixed injection issues with the previous version for a large number of people. Perhaps even more importantly, it appears to have completely eliminated both updating issues and crashes in unrelated applications for everyone, which was very important to me. I really don’t want people to download GeDoSaTo and experience random crashes, which was the case for some previous versions.

The bad news is that there are people for whom previous versions worked which report that the new version doesn’t work at all. Worse yet, there’s no pattern which I could discern so far as to who it works for and who it doesn’t work for.

Therefore, I ask both people for whom the new version works and those for whom it doesn’t to report here. I hope we can track down some common reason for the behavior.

GeDoSaTo 0.19 “Chaos Flare” – Completely revamped injection

I just released a new version of GeDoSaTo, 0.19 “Chaos Flare”. This release completely changes the injection method. The goal is to be:

  • More consistent. There is now only one method of injection for everything.
  • More compatible. The first injected dll is extremely small, adheres to the Windows standards for DllMain and has no dependencies on any libraries.
  • Safer. The inital dll is written in a very defensive fashion, always loads correctly, and always unloads itself from processes.

This required switching to a 2-stage injection process. Instead of directly injecting the full GeDoSaTo dll, dragging in all its dependencies, and then checking whether it should unload itself, there is now a separate, minimal “shim” dll which has the sole task of injecting the full GeDoSaTo only into whitelisted processes. The entire injection workflow now looks like this:

injectionIn some more detail, the advantages of this are primarily that the “shim” dll, gedoshim.dll, has no dependencies at all except for kernel32.dll, which can be assumed to be present. Furthermore, it doesn’t perform any extensive processing in its DllMain entry point, but rather defers it to a thread it launches. Finally, it always unloads itself, regardless of what happens. All of these properties together should make it almost impossible for it to crash arbitrary processes, even if something does go wrong.

All of this required somewhat major changes, over the course of which I also got rid of some features which shouldn’t really have been used anyways. There are also some drawbacks to this, the extent of which will only be apparent after more people test this latest release:

  • The blacklist feature is gone completely. Every executable you want to run with GeDoSaTo now needs to be whitelisted. It’s safer, reduces complexity, and is really not much work at all.
  • Due to purging the old dual-injection method, the “delayDetouring” option no longer exists. The hope is that games which required it will now simply work anyway, due to the more solid implementation.
  • As you can already see to some extent in the illustration, it’s possible that the new injection mechanism leads to hooks being initialized only after a game has already performed some processing. This has not occurred in my limited testing so far, but it could nevertheless be an issue.

I’ve also used this opportunity to clean up the interface a bit, particularly in Windows 10, and update the readme for the first time in a while.

I’m looking forward to some user feedback on this release. I knew that these changes have been necessary for a while, but I dragged it out due to the high degree of annoyance caused by the shim dll implementation. String processing in C++ isn’t that great in the first place, but without any libraries (including the standard library!) it’s just terrible.

You can get the latest version and test this injection method with the installer provided here. And, as always, you can donate to support GeDoSaTo development (including annoying injection shims!) here.

Note that the main GeDoSaTo dll still requires the latest VC libraries.

From feedback on Github, it sounds like this update accomplished what it was supposed to. Whew, I’d have hated for all this work to be in vain.

Tales of Zestiria article, and the state of GeDoSaTo stability/compatibility

Starting with the good news, I’ve completed another port analysis for PC Gamer, this time around for the recent Steam release of Tales of Zestiria. In short, it’s about as good as a 30-fps-locked port can be, and I was particularly impressed by its keyboard and mouse input support.

To mark the occasion I’ve also pushed a profile for the game to the GeDoSaTo repository, which allows correct mouse mapping while downsampling and includes a PSHash for HuD toggling and HuD-less post-processing/screenshots.

Talking about GeDoSaTo, I’m well aware that the most recent version introduced serious compatibility/injection issues for some, and I’ve already invested some time in trying to pin those down. At this point, I’m still not sure what’s going on, but my best guess is that it’s related not to any code change but to switching to the latest version of Visual Studio and its runtime library. In general, getting the redistributable for Visual Studio 15 might help.

Overall, I fear like the only solid solution to this issue is creating a separate “shim” .dll for GeDoSaTo which doesn’t link any CRT library, injecting only that in all processes, and making the decision whether to actually load GeDoSaTo in that separate dll. This is a heavier undertaking, and I plan to give it a go this weekend.

If anyone has any ideas (well, viable ideas, not pure speculation) about other potential causes for these recent issues I’d be happy to hear it.

Sayonara 544p

Sayonara Umihara Kawase recently got a PC port. I was pretty enthused about this since I like quirky physics platformers. Sadly, the port turned out to be resolution locked in perhaps one of the worst ways seen to date. People believed it to render at 960×544 (Vita resolution), but the truth is even stranger.

Anyway, this sunday at around noon I thought I could give fixing it a try, given that the game should be DX9 according to the Steam requirements. Well, after buying it, the first thing I learned was that it is actually DX11. This turned what I was hoping for would be a quick fix into a longer struggle, but nonetheless I managed to unlock the resolution (it’s what I do after all).

In the process of that I also learned that internally, the game actually renders to a 896×512 portion of a 1024×512 rendertarget !! That’s, IMHO, even more insane than the 960×544 1:1 Vita port people expected.

Anyway, the result looked like this:

Which is a pretty decent upgrade from this:

However, the background texture, specifically the bricks on the right, are really really awful. Too awful to be truly improved by anything other than someone going in and replacing them with a redrawn version, but nonetheless I was apparently hyper-motivated today so I tried.

I integrated the texture scaling code I wrote for PPSSPP a while back into GeDoSaTo, and (somewhat surprisingly to me) even managed to apply it to Umihara without making everything explode. It’s very limited in when it works right now, but there’s nothing in principle preventing it from being potentially applied to all kinds of DX9 and DX11 games if there is a desire for that.

Anyway, the final result, with hybrid xbrz+bicubic texture scaling, looks like this:

Which clears up the pixelly mess of bricks slightly, though obviously you can’t expect miracles from an automatic process.

I started at around noon, and what I intended to be a fun few hours coding romp leaves me here at 22:40, but I think it was worth it. I hope the other 2 people who are both into ultra-niche Japanese physics platformers and rendering quality enjoy it!

All of this is integrated in the latest version of GeDoSaTo, 0.18 “Disharmonized Genesis”. You can get the latest version with the installer provided here. And, as always, you can donate to support GeDoSaTo development here.

GeDoSaTo FPS capping, modding controversies

FPS Capping

I recently started implementing FPS capping in GeDoSaTo. For those not familiar with the term, basically you want to achieve a consistent framerate in a given game, and in order to do that you cap the framerate at a given maximum.

In practice, this is usually done by simply inserting waiting periods after you are done with a given frame. E.g. if you want to cap to 30 FPS, you would wait until you reach a frametime of 33.3 ms.

There are multiple external tools which already do this (e.g. NVidia drivers have an option, RTSS can do it, some games have a built-in cap, …) so up to now I wasn’t interested in doing the same in GeDoSaTo — though I was sometimes frustrated by the lack of fine-grained control in external tools. However, I recently had an idea on how to improve upon the commonly employed method for doing this, in order to perhaps slightly improve input lag in a capped scenario.

fps_cappingThe image above shows 3 use cases: uncapped framerate, a traditional 30 FPS limit implementation (“Capped”) and my new method (“Predictive”). As you can see, the traditional method simply inserts a waiting period after each frame. However, this means that you are potentially losing a few milliseconds of input latency for no good reason.

Instead, with predictive FPS capping, GeDoSaTo keeps track of the frame times for previous frames, and takes a set fraction (configurable) of that as a predictive waiting period before each frame. The result (for games which do synchronous input sampling on the rendering thread or at least on another thread synchronized with it) is that the input after waiting is used for the new frame, reducing input lag by some fraction of the frame time.

The only dangerous aspect of this method is if there is a sudden spike in frame rendering times. For example, in F2 in the picture you can see that the frame almost doesn’t get done in time. If it were to cross the threshold, predictive FPS capping would result in a framedrop which would not happen in a traditional FPS limiting scheme. For this reason, the ratio of how much waiting time should be moved to the start of the frame is configurable — you can use a low value like 0.25 for a game with very erratic frametimes and something like 0.9 for one with extremely consistent performance.

Here are the new configuration options (which can be configured as per-game user profiles, like always)

The busy waiting or sleeping option is there for completeness, but outside of running on a laptop battery I don’t really see why you would not use busy waiting. In my tests it’s a lot more exact.

Note that you can use floating point numbers as the frame limit, I find it often useful to go with e.g. 30.5 FPS if I want a solid 30 in order to overcome unmeasured overheads.

Modding Controversies

Since my last blog post there have been two pretty large controversies about modding. The first was regarding paid mods for Skyrim. I was asked to provide a comment for PCGamesN, which was used in this article. My full comment, which is provided on the second page of the article, sums up my feelings on the issue. I have to admit that I was most disappointed by the level of vitriol some (purported) members of the community stooped to.
The other issue was once again the old friction between modding and multiplayer. Both in DS2 and GTAV, people who claimed to be using only mods which do not affect gameplay in an unfair way were relegated to the cheater pool in online multiplayer. This is a very delicate issue. It is extremely hard or even impossible for a game to assess whether a in-memory modification is benevolent or not, so I can certainly understand “no online modding” policies in principle. in the end, that is just another instance which shows why developer-supported modding is the way to go: in such a setup, it’s easy to control which modding functionality is available in what game mode.

GeDoSaTo 0.16 Christmas Release

As a holiday special so to speak, today I’m releasing GeDoSaTo 0.16.

The TL;DR version of the updates is this:

  • Fixed a number of memory leaks which caused instability in pretty much all games. In some (most?) it was unnoticeable, but in Final Fantasy 13 and 13-2 crashes could occur as early as after 15 minutes of playtime.
    All of that should be fixed now.
  • As a result of that fix, if you are looking to find a PSHash or VSHash for a game (and only then!) you should enable the new trackShaders option.
  • I’ve also improved keybinding modifier support and borderless fullscreen support.

You can get the latest version with the installer provided here. And, as always, you can donate to support GeDoSaTo development here.

Happy holidays everyone!


The long version for those who are interested:

I’ve been chasing the sporadic crashing issues on and off since the release of FF13. For the longest while, I assumed that they had to be related to screenshot taking, as that was when they first and most often occured. I tried many things related to that (pre-allocating buffers, using the library in a way that causes no additional memory allocations, …) but it turns out that this was, more or less, useless, as I was looking in the entirely wrong place.

When I finally realized that, despite the issue only appearing in the FFs, it had to be a general memory leak in all of GeDoSaTo, I manually checked every single instance of new in the code for the corresponding delete . This was less work than it sounds since I try to write modern C++ where you very rarely call those directly. Over the course of this, I found a few issues, specifically  operator delete  being called instead of operator delete [] . However, since those were arrays of POD types, while bad practice and undefined behavior it wasn’t the issue I was looking for either.

Afterwards, I made a few abortive attempts to use existing leak checking tools, but like many tools designed to make programmer’s lives easier they are really hard or impossible to apply in the — very unusual, admittedly — interception use case of GeDoSaTo. It would certainly be a good idea to implement a stand-alone executable testbench at some point, but these things, they take time.

Yesterday, I finally made the breakthrough. My new approach was to fill the memory almost completely at start-up so as to more quickly reproduce the issue. Then, I got a repeated crash during loading in FF13-2. This reminded me of earlier studies of FF log files, and that it loads far more separate shaders than any other engine I’ve looked at, and some of them 3 times each. And it continues to do so heavily throughout the game, which is somewhat unusual. This lead me to looking at the shader management code, and there I finally found the culprit.

And, as is almost always the case, looking back after finding the bug it seems painfully obvious: to enable things like PSHash HuD rendering identification or injection of postprocessing or AO in the case of specific plugins, I keep a map of all shader pointers and their names (which are derived from their code so as to be reproducible across runs). However, I never remove entries from that map. As it is impossible to know when an entry is save to remove without fully instrumenting shaders (which seems like overkill for this purpose) I’ve solved the issue by adding the new  trackShaders  option. If it is not set (the default), shaders will still be identified if they were set as PSHashes or VSHashes, but only those will be tracked. The only reason to enable the flag is to look for a new hash in a new game.

GeDoSaTo updates / DSfix in the Dark Souls Steamworks version


I just pushed a new GeDoSaTo update. Among some smaller stuff, it also includes two significant changes:

  1. Fixes to the Borderless Windowed mode forcing behaviour, which should greatly increase compatibility of that setting (and hopefully not break it in anything it already worked with!).
  2. A new “performance tracing” feature which I used in an upcoming article for PC Gamer, and which I’ll describe a bit more below.

Performance tracing allows you to record the performance of a segment of gameplay to a file. There is a keybinding for it ( togglePerfTrace) which you can configure like any other keybinding (now including modifier keys!), and after recording a sequence it will output a file such as this:

The first 3 lines give general information, including the total frames measured, total duration in milliseconds and average FPS over that duration. The following 3 lines give 99, 95 and 75 percentile effective frame times. These give you a quick idea of the overall smoothness of a game.

Finally, the rest of the file is a CSV (comma-separated value) recording of each frame’s times. The individual measurements are (i) CPU time from the start of the frame to the present call, (ii) GPU time according to D3D API measurements, and (iii) effective frame time from one present call to the next. You can use this detailed data to do analysis or generate graphs in your favourite statistics tool, like e.g. this one representing frame time distribution:

I realize that tools doing something very similar already exist, but they may not report all the information, or not be open source, or not be compatible with GeDoSaTo, so I integrated the functionality.

Dark Souls update / DSfix compatibility

The Dark Souls Steamworks migration update is now live. As I expected, most DSfix functionality I implemented (which is based on API call interception) remains operational, but the framerate unlocking (based on binary hooks) does not work with the new version. This part was implemented by Nwks, so we should hope that he is still around and interested in updating it for the latest version. If not, I can try, but it lies outside my expertise and could potentially take a lot of time (which I’d rather spend on other projects). Of course, there’s also the chance for anyone else to step in, as all the code is available on github.

For now, you can use DSfix with the new version as long as you disable the framerate unlocking feature in the .ini file.

Upsampling with GeDoSaTo, other small updates

The past day or two I have been looking into making GeDoSaTo a better tool for upsampling (as opposed to its usual downsampling use case). This might seem meaningless at first, but it’s useful in a few cases.

The most important such case are retro games (or modern retro-inspired indie games) which are stuck at a specific low resolution. In such cases, GeDoSaTo can be used to provide a nearest neighbour (or high-quality bicubic) upsampling, which often looks better than a straight bilinear filter. Now recently, someone integrated Timothy Lottes’ great CRT shader with GeDoSaTo. However, this only works if the shader has a sufficient number of pixels to work with. In order to support this use case, GeDoSaTo can now optionally perform postprocessing after upsampling.

Final Fantasy 6 in BSNES

Final Fantasy 6 in BSNES

The resulting pattern for fixed-resolution games is this: add the fixed resolution as a rendering res in the config file, use nearest neighbour upsampling to your display resolution, and then run the CRT shader. This works well for both emulators and low-native-res 2D titles. Obviously, a lot of tweaking can be done to get the CRT to look just like you want it (sharpness of pixels/scanlines, gamma, bloom etc.). Here’s a gallery with some of my results.

In other news, I also implemented a few small requested features:

  • You can now set the timeout for on-screen messages from GeDoSaTo, or disable them completely.
  • Settings can be reloaded on the fly just like shaders with a keybinding, but note that not all of them take effect immediately. This is mostly useful for trying out pshashes and such.
  • More than one action can now be bound to a key/button at a time.

As always, you can get the full version here or update. By the way, if the update ever fails (i.e. immediately prompts you to update again) delete the .dll and run the installer again. And also as always, if you’d like to you can donate here.

Also, buy Valkyria Chronicles.

Forcing Anisotropic Filtering with GeDoSaTo (in FF13 and elsewhere)

I just added a new option to GeDoSaTo, forceAnisoLevel.

You can use this option in any game, but it only makes sense in a select few. If you force anisotropic filtering in the driver, it’s smart about which surfaces and original filtering types it overrides – that’s why it very rarely breaks games, and this makes perfect sense for a driver option.

However, specifically in the case of running stuff at resolutions it was not built for and downsampling, it is sometimes beneficial to apply filtering even to surfaces specified to be point filtered, which is something the driver doesn’t do (as it could often break shaders).

The main reason I added this feature is FF13, or more specifically its HUD and menus. These are point filtered by default (since they are rendered 1:1 at 1280×720), which looks terrible at higher resolutions. This setting alleviates the issue, though of course higher-res UI assets would still be preferable. Here’s an example of the difference:

To use it, add a user-level FF13 settings file (if you don’t already have one) and add the line forceAnisoLevel 16 to it. See here for details on settings files – I have seen that this causes quite some confusion and sometimes erroneous bug reports.

As always, you can get the latest version by grabbing the installer here or simply update, and if you want to you can donate here.

How recent Unity games do stuff, and a new GeDoSaTo version

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:

  1. Check the desktop resolution and create a fullscreen window as well as a DirectX device with that size.
  2. Check the native monitor resolution (using GetMonitorInfo), and reset the device/window to that size.
  3. Render at whatever resolution you specify in the game settings, to an off-screen surface.
  4. 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.

Cursor Sidenote

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.

As always, grab the installer here or simply update, and if you want to you can donate here.

By the way, Nvidia’s DSR can’t downsample in these games (for now). Take that big boy corporate version!