How do you spell ‘DPI’ ?
Summary
I was able to find a good place in OBS’ code to fix the issue, but it doesn’t seem likely that the PR will be accepted in its current form.
Background & Part 1
There’s a general overview here:
As you can see from what I previously wrote (or just from the image above) there is a problem when using OBS to capture EUIV- the rendered pointer in OBS doesn’t match where it should be, it is offset by the amount of scaling applied to the game.
Windows Scaling
‘Scaling?’, you might ask. Windows offers scaling to make things look bigger:
This is helpful to make things bigger from a “make them more perceptible” perspective, but the other benefit is for folks who have monitors bigger than what their graphics card can handle. Like mine! I have a graphics card which is now seven years old. For folks like me who have card that would struggle trying to push 1440p or 4K, a game can be run in 1080p, and then scaled up- looking bigger on the monitor without actually making the game render more pixels.
Scaling isn’t a ‘free’ operation, but we’re talking about a relatively simple mathematical scale here, not a fancy fill-in-missing-detail ‘AI’ upscale. I haven’t benchmarked it, but it’s got to be less resource intensive than asking the game to render more detail.
Now actually Windows is smart enough to let games handle their own scaling, which means you have everything looking bigger around a tiny game Window. You have to tell Windows that you do indeed want it to handle scaling for each game:
via Properties ? Compatibility ? High DPI options ? High DPI scaling override ? [x] Override [], performed by: ? System
You can also tell it to scale by some other amount, if you wish. Or you could have Windows do no scaling, except for particular games.
Overall, it’s a helpful system.
Offset Cursor Fix, v1
Note: getting set up for compilation in Windows was an interesting process. Whereas in Arch I can pretty much grab a PKGBUILD, or clone a repo and ./configure; make;
there were a few hoops to jump through for building on Windows. That said, the instructions on the OBS Wiki were good- they worked when followed!
The problem is it causes the information that OBS receives about the cursor to be incorrect. I mentioned a ‘quick-and-dirty fix’ involving dividing by the scaling amount, which worked:
Rather than guddling in a deep function, I proposed changes to the win-capture
plugin’s game-capture.c
.
It adds a property to the ‘game capture’ source type “Cursor DPI Offset”, which lets the user specify the scaling factor they are using and applies the offset based on that.
I had set up preset options based on what Windows options for scaling factors:
But it was pointed out to me that just letting the user specify a scaling factor directly might be neater. In fact, it is possible to set an entirely custom scaling factor, so that was a good idea.
Good Enough versus Perfect (with obligatory coffee analogy!)
I proposed the PR and was told that it would be a better idea to fix the underlying issue rather than provide an option as a band-aid. I thought I had- the cursor was in the wrong position for some users, the new property moves the cursor position so it gets rendered in the correct position. But actually they meant fix the underlying “cursor position reported by API is wrong” issue.
Ah.
I’m going to go out on a limb and say that it’s natural to be a little disappointed when the world doesn’t immediately shower one with praise and adulation for the cleverness and perspicacity of one’s solution to a problem.
At least I was, having spent hours setting up, familiarising myself with a new codebase and working a fairly unfamiliar language (notes to self: long
is an *integer* type, and for debug printing %l
is *not* the way to print those!) and then working out a reasonably flexible solution for those who need it. The latter is important, for a reason that the OBS dev blog touches on: “Every single new line of code has a maintenance cost.“.
I was fairly mindful of this. There have been hundreds of folks asking over the years across the OBS Discord, forum, Reddit and elsewhere about an “offset OBS cursor”. Maintenance-wise, I was at pains to make it obvious what the changes to game_capture_render_cursor()
were doing.
But looking at it from the dev team’s side, what they suggest is the more ‘correct’ approach. And that gets into the good enough-vs-perfect debate, which is obviously important for a program used by tens of thousands (millions?)*.
Doing it the way they would like is not technically beyond my capability — with enough time and effort anything is possible! — but it requires familiarity with the Windows API which I don’t have and would not be too confident about.
Another way of looking at would be the user perspective versus the developer perspective:
- user: “this has been an issue for years, here’s something which addresses it and gets the right behaviour out of the program”
- developer: “the wrong behaviour is still in there somewhere, that just takes an extra step to make ti come out looking right”
or if you’d prefer an analogy:
A coffee machine produces all sorts of different drinks from different varieties of bean, and is used by loads of different people in a building.
Lots get their coffee right, but some want a particular blend in a smaller mug to make it look more full, and is easier to handle.
But the machine thinks that because the mug is smaller the liquid must be smaller too, so it doesn’t heat it as much.
The people who run the machine say that’s not a great fix- it’s confusing for the people who don’t need their coffee heated more, and even those who do want extra heat have to know where to look to find it and enter by how much. It would be better to fix the problem that makes the coffee machine under-heat the liquid.
So who’s right?
The users want their coffee, or their cursor rendered correctly. They’ve put up workarounds for years- adding a bunch of hot water to the coffee, which dilutes it; or just not capturing the cursor.
The developers want the coffee machine to work right. They are concerned with keeping it running smoothly in the future, in terms of maintenance and when they add a feature, like tea. None of them use a smaller mug, or run capture games in a scaled window, so there’s no strong impetus to fix it.
There needs to be a compromise- the user proposing the change has to adapt their fix to what the devs want, or the devs can accept a temporary* fix.
* “Nothing is so permanent as a temporary fix” is an old adage, attributed in one form to Milton Friedman: Nothing is so permanent as a temporary government program.”
Personally, I’d like to get a fix into OBS for the folks like me who are scaling for reasons of poor eyesight, and I’ll look at the Windows API to see if there’s a way to figure things out about the captured game window.
The Stinger
The last wrinkle is that not all scaled games show the issue- EUIV does, Streets of Rogue does. Risk of Rain 2 doesn’t, Mahjong Nagomi doesn’t. Complicates things somewhat…
Pingback: Fixing OBS Offset Cursor Issue, Part 3 (investigating with Python-C++ interfaces!) – Rob's Blog