elishacloud / dxwrapper

Fixes compatibility issues with older games running on Windows 10/11 by wrapping DirectX dlls. Also allows loading custom libraries with the file extension .asi into game processes.
zlib License
1.16k stars 83 forks source link

Nearest Neighbor rescaling #154

Closed MetalSpork closed 10 months ago

MetalSpork commented 1 year ago

Many games have a native resolution of 800x600, and this does not rescale so well to monitors that have a 1080 resolution. 1920x1200 monitors are rare and it's even rarer to find one with decent specs.

What I would like is if there could be a nearest neighbor rescale where the pixel width looks perfect, but some pixels are vertically truncated.

elishacloud commented 1 year ago

Unfortunately, Nearest Neighbor ( or Point) filtering does not work correctly with this game. There is no easy way to fix this. It is unlikely that we will be able to do that.

With default filtering:

Screenshot 2022-08-09 17-36-28

With Nearest Neighbor filtering (notice the trees):

Screenshot 2022-08-09 17-42-43

nipkownix commented 1 year ago

I think they may be talking about games in general, not just Silent Hill 2?

elishacloud commented 1 year ago

If you want to scale 800x600 to 1080p then I think there are two options to keep the pixel width looking perfect:

  1. use interpolation
  2. add pillar boxes around the picture to fill in the space around the 800x600 image

There are hardware boxes (like the RetroTink 5x Pro) that can do interpolation, but I am not aware of any good software solution for this.

mirh commented 1 year ago

Couldn't you (I mean, someone) tinker with magpie to achieve the same result?

elishacloud commented 1 year ago

I think they need/want a software solution that will convert PC games from smaller resolution to larger resolution, keeping the pixels intact. Normally what happens is that the game runs in 800x600 and then the monitor will convert that to the native screen resolution and blur the output.

The issue with software solutions is that it needs to not only convert the screen resolution but, in most cases, it also needs to adjust the mouse movement, which, incidentally can be quite tricky.

dxwrapper does have the ability to add pillar boxes to some old games, but cannot do the sharp interpolation nor does it correct any mouse movements.

I suppose if you got a hardware device that would just pass through 1080p but do sharp interpolation of resolution smaller than 1080p that would work also. But I am not aware of any device that does that today. The OSSC Pro is supposed to do that, but it is not out yet.

Edit: "do sharp interpolation of resolution smaller than 1080p" - what I mean here is doing sharp scaling without adding too much delay. There are devices out there that will scale everything to 1080, but they all add tons of delay, which can make games unplayable.

mirh commented 1 year ago

I think they need/want a software solution that will convert PC games from smaller resolution to larger resolution, keeping the pixels intact.

Yes, I get that. But isn't that integer scaling, putting aside whatever the odd request of cutting some pixels? Modern amd and nvidia drivers also ship it (but they aren't customizable, so that's why I proposed the software alternative)

Normally what happens is that the game runs in 800x600 and then the monitor will convert that to the native screen resolution and blur the output.

Aktually, I believe in 2022 the default if for either windows or the GPU to take care of the scaling part. So that you don't see the black screen involved with switching mode.

elishacloud commented 1 year ago

But isn't that integer scaling, putting aside whatever the odd request of cutting some pixels?

You can't do integer scaling from 800x600 to 1080. It would just scale it 1:1, which is not scaling at all.

I believe in 2022 the default if for either windows or the GPU to take care of the scaling part.

True. Some GPUs will do scaling for this and supports sharp scaling. My Nvidia card can do this in the Nvidia Control Panel. Good point.

mirh commented 1 year ago

You can't do integer scaling from 800x600 to 1080. It would just scale it 1:1, which is not scaling at all.

Damn, the idiot ball hit me hard. Now everything makes sense. Still.. I feel like this would be way less effort to add to magpie, than here.

The most difficult thing would be probably just to add some hotkey to adjust the cutting position/margin.

MetalSpork commented 1 year ago

@elishacloud I'm admittedly a little confused as to why Silent Hill 2 came up. Additionally, I was actually interested in nearest neighbor filtering that isn't pixel-width perfect. I think, in some cases, that looks nicer than the usual bilinear filtering (which is what dxwrapper uses, if I'm not mistaken).

elishacloud commented 1 year ago

I'm admittedly a little confused as to why Silent Hill 2 came up.

Sorry I got confused on which thread I was on. I did a lot of testing for nearest neighbor filtering for Silent Hill 2.

What I would like is if there could be a nearest neighbor rescale where the pixel width looks perfect, but some pixels are vertically truncated.

Unfortunalty this would not be easy to do for Direct3D, Direct3D8 or Direct3D9 games. However, by default, dxwrapper does nearest neighbor filtering for games using Dd7to9.

If the game is using DirectDraw and Dd7to9 works for the game you could set the following for games native resolution of 800x600. This will clip 60 pixels, 30 from the top and 30 from the bottom.

[Compatibility]
Dd7to9                     = 1

[Dd7to9]
DdrawClippedWidth          = 800
DdrawClippedHeight         = 540
DdrawOverrideWidth         = 1920
DdrawOverrideHeight        = 1080
DdrawIntegerScalingClamp   = 1
DdrawMaintainAspectRatio   = 1

Edit: This trick may not work on all DirectDraw games depending on how they use the mouse. Mouse movements may be out of sync with the graphics.

Ghost-Terms commented 1 year ago

@elishacloud I think the two of you have been talking past each other. From what I can gather, he's referring to the difference between these two scaling algorithms:

scaling

Scaling like how it's done on the left is what he's requesting, but dxwrapper only does scaling like how it's done on the right.

As far as the "vertical truncation" goes, here's what that Megaman sprite looks like with 3x Nearest Neighbor width and 2x Nearest Neighbor height, which is what I think he's asking for when you can't do integer scaling:

verticaltruncation

elishacloud commented 1 year ago

Scaling like how it's done on the left is what he's requesting, but dxwrapper only does scaling like how it's done on the right.

dxwrapper does not scale it that way. That scaling is normally done by the video card or monitor. dxwrapper just outputs at the resolution of the game and the video card/monitor will scale it to fit the resolution of the monitor, usually making it look like some kind of bilinear scaling.

There is only one option in dxwrapper to allow it to scale DirectDraw games. In this mode it does Nearest Neighbor scaling (a.k.a. Point Filtering), as you can see here. I explain how to do this scaling in dxwrapper in the comment above. However, if you are not using a DirectDraw game then dxwrapper does not do any scaling at all.

Note: It is a lot of work for me to add scaling to 3D games. But if I ever do I will make options for Nearest Neighbor, Bilinear and others.

Ghost-Terms commented 1 year ago

I explain how to do this scaling in dxwrapper in the comment above.

Doesn't that only work if you want an exact 1:1 pixel rescale? I'd certainly like it if you could make it possible to rescale a DirectDraw game like this:

verticaltruncation

elishacloud commented 1 year ago

Doesn't that only work if you want an exact 1:1 pixel rescale?

dxwrapper only does 1:1 scaling if both DdrawIntegerScalingClamp and DdrawMaintainAspectRatio are enabled.

I'd certainly like it if you could make it possible to rescale a DirectDraw game like this:

dxwrapper can rescale like that. Just enable the following options:

Dd7to9                     = 1
DdrawOverrideWidth         = 1920
DdrawOverrideHeight        = 1080

Here is a screenshot of Diablo 1, which uses DirectDraw. Notice how the screen is stretched, but it is still nearest neighbor (click on it to see the full image):

image

Ghost-Terms commented 1 year ago

Ah, I didn't know it could do that, nice.

elishacloud commented 10 months ago

Closing issue. If there are more questions you can reopen it.