Tales of Symphonia GeDoSaTo plugin

Edit: My article about this sordid affair is now up on PC Gamer.

I never expected that, but Tales of Symphonia was released resolution-locked. I’ve released a preliminary GeDoSaTo plugin for the game to fix that.

Note that when I say “preliminary” I mean with a total development and testing time of less than 3 hours. So if you run into issues, keep that in mind. (Of course, if you get crashes, or the game failing to launch, or anything like that, it might just as well be the game or its DRM system rather than GeDoSaTo)

Things to keep in mind:

  • The game name, for purposes of config files, screenshot paths, etc, is “Symphonia”. This is a bit of a hack due to the silly DRM they use.
  • As always with games with locked rendering resolution, you need to set your desired one from the .ini file ( config\Symphonia\GeDoSaTo.ini ). It looks like this by default:
  • There is a bit of an ugly interaction with some low-res processing going on. I might fix that if I can find the motivation.
  • Keep the in-game resolution setting at 720p, that’s the only thing I tested.

You can get the latest version including this plugin by updating from within GeDoSaTo or with the installer provided here. As always, you can donate to support continuing GeDoSaTo development here.


GeDoSaTo 0.21 – multiple PSHashes, better AO targeting, multi-pass postprocessing etc.

Since the last time I wrote about GeDoSaTo, there have been quite a few changes/improvements. The full changelist is on Github (basically everything under the beta 20 and beta 21 headings), but I feel like some things need further explanation.

Multiple PSHashes can now be specified

This means that it’s easier to get perfect coverage of post-processing injection and hudless screenshots in more games, more situations , and with a larger variety of settings, with a single uniform profile.

Introducing AOHash for the generic depth plugin

It works like the PSHash system, but when the hash is encountered AO is applied (with the GenericDepth plugin). This means you can inject AO before the game renders things like volumetric fog, particles or light overlays:

The way both of these features work is illustrated by the new default profile for Dragon’s Dogma:

hashesI also implemented a depth-based fadeout for AO, this helps work around issues with fog which are not resolved by the new hash targeting ability. You can currently configure it directly in the SAO shader. (Which you can of course customize for each game profile like any shader)

Combining AO hash targeting and the fade-out, it’s possible to get artifact-free AO in e.g. Dragon’s Dogma, which was my main test case.

Multi-pass Postprocessing

Rather than pushing every effect into a single shader (which simply doesn’t even work for some combinations) you can now specify an additional postprocessing pass with e.g. addProcessingPass deband.fx in any settings file. Currently, only the deband shader has been separated out, and you can look at its source here. The system is still not as flexible as I’d like it to be (in order to be able to implement more complex effects without changing GeDoSaTo), but it’s a pretty significant step forward.

Other Stuff

You can get the latest version by updating from within GeDoSaTo or with the installer provided here. As always, you can donate to support continuing GeDoSaTo development here.

And yes, I know that this is not the DX11 support that everyone is asking for all the time. Sadly, that’s on a different level of engineering time requirements.

Graveyard of Forgotten Projects (Part 3)

This is a direct continuation of the first and second parts. Let this partial quote from there serve as an introduction:

This series (hopefully) of blog posts will gather and shortly describe some previously unreleased and/or forgotten projects I’ve worked on over the past decade and a half, starting from 2000. This is by no means a complete listing, I’m still skipping over the vast majority of unfinished ideas and half-baked projects, but I’m trying to include everything which worked to an extent or has some interesting features.

The primary purpose of this is to serve as an archive for myself, because, as you will notice when I go through the list, I’ve already lost a lot of somewhat interesting stuff and would rather not have that happen again. Perhaps one thing or another might also be useful to someone else, but I obviously won’t troubleshoot code I wrote more than a decade ago and haven’t touched since then! And, just to make that clear, it’s also obviously not indicative of my current skills.

I started this series of posts at the beginning of the year, and resolved to do at least 3 before the end, so that’s why this is happening now. The previous two iterations together went up to the end of 2006, covering a lot of abortive game attempts, a released PSP game and some useful tools.

GPU-based Image Processing and Multigrid Solvers

Around that time I had already implemented my bachelor degree project, and relatively shortly later (well, 2 years, but who’s counting) – and it’s highly related, so I’ll include it here – my master degree project.

These projects together ran roughly from 2004 to 2007, and there was no specific GPU computing API at all until their very end. People were just starting to experiment with doing compute on graphics cards using standard graphics APIs, and so everything I worked on during these projects I did in OpenGL. So, my first step was to create a library which makes it easier to do compute on what is essentially a graphics platform:

Object Model OverviewBased on that, during my bachelor work I implemented a lot of image filters, from simple stuff, over arbitrary convolutions, up to non-linear/anisotropic image filtering like Perona-Malik diffusion.

Perona-MalikTo gather and evaluate a good amount of data on all the GPUs popular at the time, I  created a benchmark which reported various performance metrics and released that on Beyond3D. Other programs created were a testing environment for filter development called “ftest” (my naming sense strikes again) and even a C# GUI for comparing various data and generating charts. I lost the source for the latter, but I still have the former. In fact, ftest has no issue running on my current Windows 10 system – not bad for a binary compiled over 10 years ago (no guarantees on this one of course!):

ftestFor my master thesis in 2007 I implemented a multigrid solver for elliptic PDEs using the same framework. I won’t go into too much detail since this is getting kind of long already and we need to get back to the games! In case you are interested, here’s my master thesis.

Muh aka Project Y aka YouMUH!

This is a long story, spanning all the way from 2008 to 2012. This doesn’t mean that I worked on it for 4 years of course, just that I spent a few days on it from time to time, often with months between them. The basic idea for this game was to be a 2.5D side-scrolling platformer/action game starring Youmu Konpaku (who is in the logo of this blog by the way, and has been since its inception. I guess I always thought I’d talk about this project some day).

In any case, looking back on it now, the “game” seems to have been mostly an excuse for me to play around with whatever rendering, modeling or physics technology I was interested in at the time. That doesn’t mean that I didn’t have some idea for how the whole thing would play when it was completed (something like a mixture of Koumajou Densetsu, Bunny must die, and Noitu Love 2), just that completing it never seemed to be the point.

I started working on modeling for the game in 2008, with just a sword in Wings3D. During 2009 I spent a significant amount of time learning Blender and modeling/animating the main character. In 2009 I started with the actual coding, putting a lot of work into implementing deferred shading with a non-photorealistic art style. I created a cross-hatch shading algorithm which was based on a set of consecutively darker hatched base textures. The result looked like this:

muh_2010Subsequently, I spent far too much time with cloth simulation. At that point, this was still uncommon (nonexistent?) in games, and I basically created everything from scratch, starting with the physics simulation, over collision, to the file format used to specify cloth type/behaviour. It was an addition to the .obj file format and looked like this:

It was quite insane, but it worked out not too terribly in the end. I extended the same physics system to handle bone animations (this part worked well) and tried to also go for hair (this didn’t work well). You can see a video of the state ~2011 here. At that point, I had also switched to a more traditional cel shaded look (a decision which I would revert today).

muh_2011During all this time I continually refined the running animation, and looking back at the initial one and the final version I have to say that at least this was a clear track of improvement. The last things I worked on, some time in 2012, was level loading, where again I used a custom format, but at least it was XML-based. This is the final state of the project at this point:

muh_2012Basically, once I got a level loaded (with no materials mind you) I realized that, as a single developer, doing the entire game at a level of graphical sophistication which does the effort I put into just the main character’s skirt and running animation justice would be utterly infeasible. At the same time, doing it any lower level wasn’t going to make me happy, and just doing things again for which I already had a “proof of concept” so to speak would be boring. So, at that point I shelved the project — and a bit later started to work on DSFix, which turned out to be a lot more helpful to far more people.

Nonetheless, I learned a lot doing YouMUH! over the years, including:

  • Modeling and animation in Blender (and that I’m not great at it)
  • Deferred shading
  • Some approaches to non-photorealistic rendering
  • Physics simulation (particularly cloth/hair)
  • Some of the problems that come with trying to integrate neat state-of-the-art code with, well, art

And also, that it’s not a good idea to attempt a medium-fidelity 3D PC game (with bleeding edge features like cloth simulation and NPR) while doing almost everything from scratch and also handling all the code and art on your own. Well, it’s not a good idea if you want to finish something, it’s pretty nice as a hobby and for learning things!

That’s it for this iteration. There’s still one more project I’ve never posted about that I consider significant, and a few smaller ones. But I really wanted to at least reach the 2010s before 2015 is over!

Lightning Returns Plugin for GeDoSaTo (DoF fix, AO)

While playing Lightning Returns, I noticed extremely ugly artifacts/flickering/aliasing whenever DoF was used (particularly in cutscenes) – even at 4k. Turns out the game rendered DoF effects at 720p regardless of the selected rendering resolution.

I fixed that (after spending far too much time on half-baked ideas which turned out more complicated than the real solution) in the latest version of GeDoSaTo. Here’s a comparison (crop from two 3840×2160 screenshots):

Left: default; Right: fixed

Left: default; Right: fixed

I spent some time making sure the DoF effect itself is as close as possible to the intended. I think it worked out pretty well.

While I was at it I also implemented AO support, you can look at a comparison here. It’s disabled by default, so you should enable it in your user .ini if you want to. The performance impact is rather significant.

You can get the latest version including the LR plugin by updating from within GeDoSaTo or with the installer provided here. And, as always, you can donate to support continuing GeDoSaTo development here.

New GeDoSaTo Version, Status Update

It’s somewhat traditional (well, since last year) to have a Final Fantasy-related Christmas update.

This time around, I fixed a variety of bugs/missing features which made GeDoSaTo incompatible with Lightning Returns. After doing that, I also quickly discovered a PSHash for hudless screenshots which seems to work pretty well so far. Due to the way the game handles downsampling resolutions, you need to take some care when trying to get hudless downsampled screenshots, look in the .ini for details.

FF13 LR screenshotOther than the strange insistence on having a fixed set of supported resolutions rather than querying the OS Lightning Returns seems to be a pretty good port so far. At the very least, it doesn’t suffer from the random performance issues of the other two games in the trilogy. The gameplay seems fun as well so far.

DX11 / 64 bit status

People still frequently ask about these, so I thought I’d give a status update. For DX11, the vast majority of the relevant APIs are intercepted at this point, what’s missing is porting/reimplementing the support infrastructure required for downsampling and general operation (e.g. the text console, effect loading and application, rendertarget handling etc.) to the API. This is still a non-trivial amount of work.

64 bit support, on the other hand, would mostly just amount to compiling multiple versions of the .dlls, and setting the correct paths in the tool/loader. The only reason I haven’t done it yet is that it seems quite useless without DX11 support, given that 64 bit games are generally also DX11.


The latest version should also fix some other compatibility issues reported over the past few weeks (some, by far not all of them!), and even a few older ones, including installer issues – see the github tracker for details. I just hope it doesn’t introduce new ones, but if it does then do report them on github.

You can get the latest version by updating from within GeDoSaTo or with the installer provided here. And, as always, you can donate to support continuing GeDoSaTo development here.

Happy Holidays everyone!

GeDoSaTo Injection, Once Again

Based on various bug reports and testing, I’ve identified 3 major causes which have contributed to the issues with the new injection system that some users of GeDoSaTo have experienced. Two of these are fixed now, and the other one is a system setting which is reported by GeDoSaToTool for you to fix.

The problems were:

  • Whitelist-based injection was case aware, while previously it was case-insensitive. Since case is based on the launch name of the .exe, this is not always easy to identify, and therefore I made it case-insensitive again.
  • Installing GeDoSaTo to paths with spaces in them would prevent it from working. This was fixed by generating the short path name rather than using the full path for injection.
  • On Windows 8 and 10, if the UEFI secure boot feature is enabled, it prevents the injection mechanism used by GeDoSaTo from working. I’ve added a step to the installation guide about this and also check for and report it as an error in the tool.

Luckily, all of these so far could be fixed without jeopardizing the stability and compatibility improvements of the new injection system.

I’ve also fixed some small issues in the updater/installer, and it now keeps a backup of the replaced executables/dlls until the next update (even though all of them are always available on github).

You can get the latest version by updating from within GeDoSaTo or with the installer provided here. And, as always, you can donate to support continuing GeDoSaTo development here.

Improving Mushihimesama with GeDoSaTo

BannerQuite recently Mushihimesama was released on Steam. It’s one of the best games in its genre of all time, and I urge anyone with even a passing interest in STGs to pick it up.

Sadly, the port has a few annoying issues right now, and while I’m sure that they will be fixed eventually, if you are like me and just can’t wait the latest GeDoSaTo version fixes pretty much all of them.

The issues are (or rather, were ;)):

No support for native resolution

It’s a 2D game, so no big deal, but scaling once is still nicer than scaling twice. This is easily fixed by the forcePresentRes option in GeDoSaTo. It induces some minor artifacts in the menus, but is perfect in-game.

Bad framelimiting logic on some systems

This results in ~57 rather than 60 FPS gameplay. Fixed with the new  timeGetTimeFactor  option which fools the in-game limiter, in conjunction with limiting the framerate with GeDoSaTo instead.

Crashes on pressing “start” at the startup screen

This is by far the most pressing issue, and also affected me. Looking at all the API calls the game makes before crashing, one can determine that it is probably related to how it queries Steam friends. Therefore, I added the capability to intercept the Steam friend API to GeDoSaTo. This was a bit of effort, but sure enough, “pretending” low or zero friends with the resulting new  steamFriendsLimit  option fixes the crashes for good.

Important Note

To use GeDoSaTo with Mushihimesama, set DispFull=1 in Mushihimesama.ini, otherwise it might crash on startup.

You can get the latest version by updating from within GeDoSaTo or with the installer provided here. And, as always, you can donate to support continuing GeDoSaTo development here.

Not that if you use a non-16:9 display, or still experience framepacing issues with the game, check this post.

Injection issues

I haven’t forgotten about the injection issues. From the feedback on Github, it seems like the primary culprit for the vast majority of issues is the “secure boot” option. I’ll add a check for that and make a seperate announcement when it’s done.

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.