Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[POC/discuss]Interlacing offset Fix #752

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Zer0xFF
Copy link
Contributor

@Zer0xFF Zer0xFF commented May 9, 2019

I noticed this really annoying screen shake in few games, and after some investigating it turned out to be related to games that support interlacing, the short version of it is, one of the pair of frames needed to be offset'ed by 1 pixel (per display size) to fix.

this seem to work for all games I've tested with few exception:

  • ever blue seem to require 3 pixel offset

  • Champions of Norrath US version, seems to require offset of half a pixel offset (?) (but I also think texture play a part here, in that if you step per frame, you can see that the texture (for the menu) actually changes, in that it loses it border top or bottom with alternating frame, thus exaggerate the effect)

  • future tactics, will this work well with it, during the initial loading screen, you can see the text shake, though I haven't noticed this during game play or even the start menu... idle loop skip? or need a better frame indicator than m_nCSR?

  • Dark Cloud, in the 1st area, the character is stable, but the mountain in the background seems to be be offset'ed, so its now shaking XD

  • as a side effect of offsetting the image by a pixel, the top and bottom border of the game appears to be shaking

so, I posted this mainly to ask if you suggest applying this patch somewhere else? perhaps to the frame buffer itself? maybe however the interlaced frame is processed can be changed? we can offset the buffer by adding an extra line(duplicate the previous/next row) (though this won't work when the window size is 2x the original game, as then we'd need to offset by 2 pixels)

@jpd002
Copy link
Owner

jpd002 commented May 9, 2019

From what I understand, the games provide a 640x240 field every 60th of second and the CRT interface is supposed to handle updating the odd/even lines. I think the games are free to provide whatever image they want (I think some games downscale for example). They're not necessarily providing an image and then another image with a +1 offset, which is why I think the offset trick doesn't work every time.

I think the best way to handle this would be to emulate the CRT interface's behavior and apply the field to the output using the offset value (ie.: just render one line out of two). A deinterlacing filter could also be applied. Such a thing could probably be done through the presentation shader.

Also, there might be bugs in the way the emulator reports system information which might cause the games to select a interlaced mode instead of a progressive mode. That's something that could be investigated too.

@Zer0xFF
Copy link
Contributor Author

Zer0xFF commented May 9, 2019

oh so if im understand this correct, then currently the image is stretched in order fill the output? and so the entire output (as oppose to half) is updated every frame?

Also, there might be bugs in the way the emulator reports system information which might cause the games to select a interlaced mode instead of a progressive mode. That's something that could be investigated too.

is there anything beside sc_GetOsdConfigParam that might influence game config?
as I've used the structure provided in ps2sdk repo and tried all the video output config combinations
and I don't see it influencing any thing

@jpd002
Copy link
Owner

jpd002 commented May 9, 2019

The algorithm would be something like this:

int offset = CSR.field ? 1 : 0;
for(int line = 0; i < 240; i++)
{
  uint8* srcLine = field[i];
  uint8* dstLine = crtOutput[(i * 2) + offset];
  memcpy(dstLine, srcLine, 640);
}

This is executed every 60th of a second. Every other line are unchanged from the previous frame. crtOutput is what is displayed on the emulator Window.

I thought the screenType field from ConfigParam could make a difference. I might be mistaken though, I just had this vague impression that games could set CrtMode to values that depend on the console settings.

@Zer0xFF
Copy link
Contributor Author

Zer0xFF commented May 10, 2019

I thought the screenType field from ConfigParam could make a difference. I might be mistaken though, I just had this vague impression that games could set CrtMode to values that depend on the console settings.

well, games I tried are numbered so maybe it does? now my memory of CRT is as vague as my maths exam skills, I'd imagine TVs back then didn't support progressive (?) so if a game was going to support it, it'd most likely be an in game option, so it can be toggled on and off

The algorithm would be something like this

hehe, I hacked together the presentation shader to do something similar... prepare to cringe XD

however, this seem to resolve the shaking in future tactics and ever blue, though ever blue looks like shit with this hack, the shake is still there in jak & dexter, Champions of Norrath, dark cloud

(ofc, with this solution, we get interlacing artifcate during motion)

Screenshot 2019-05-10 at 01 20 37
maybe this is what the artist really wanted it to look like XD
(btw this is not a shake, thats how it looks even when paused with the new commit)

edit: I realise now that to fix the shake, we have to offset the odd frames by 1, since as of now, instead of offsetting it, im just taking the odd frames.

@uyjulian
Copy link

The SCE recommended way for games to support progressive were to hold triangle and cross at game bootup.
There was never an OSD configuration option to enable progressive mode, especially since SCE never built in a way to recover from incorrect configuration (attempt to use progressive output on displays/outputs not supporting it)

@rcaridade145
Copy link
Contributor

I found these lists concerning progressive scan. https://en.everybodywiki.com/List_of_PlayStation_2_games_with_alternative_display_modes
http://www.benoitren.be/

From what i've read deinterlacing may not solve all problems

https://forums.pcsx2.net/Thread-What-is-interlacing-and-what-does-it-do

"In the case of PCSX2, that setting handles deinterlacing. If a game is running in an interlaced mode, those are different methods of stitching the interlaced frames together and outputting one progressive frame. Some have bobbing, jittering, or blur issues, depending on what game it is, and that's just because they're all different methods."

I'll leave here also the links i've found on pcsx2 considering this

PCSX2/pcsx2#1525
PCSX2/pcsx2#1458

https://forums.pcsx2.net/Thread-No-interlacing-codes

Hope it helps

@ramapcsx2
Copy link

Everblue is a particularly bad example, not representative of the PS2 library.
It'd be nice to deinterlace it properly, but I wouldn't focus on this title ;)

@Zer0xFF
Copy link
Contributor Author

Zer0xFF commented May 11, 2019

Thanks @rcaridade145 and @ramapcsx2 for the input.
links did provide a good read.

so, assuming the info was accurate and the PCSX2 team didn't miss anything, then its fair to say we'd need multiple implementation to solve this?

@jpd002 do you have any more input into this? is there a 1 fit solution?

so with the last commit, we have weaving and blending (commented out)(assuming they're correctly implemented, the hacky nature aside), and the current default implementation is line doubling is different implementation, though they dont fix the shake, for that we could have an axis offset as well (that'd work for all of them) and can be user adjusted?

also for double lines you can just increase the resolution to compensate for lost vertical resolution.

P.S I also tried frame skipping, which works well, beside the obvious flow... frame skipped XD

@rcaridade145
Copy link
Contributor

rcaridade145 commented May 13, 2019

Just some other info i found on this subject

https://blizzz.ovh/rgb/processing.html .

240p ps2 games

http://www.xrz87.org/port-fx/240p.html


if(framebuffer)
{
std::swap(framebuffer->m_texture, framebuffer->m_texture2);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this works since most games use double buffering. You will end up with different framebuffer pointers every frame. You could try keeping the last framebuffer used if you'd like to do a quick test, but I don't think it would be a reliable method in the long run.

@jpd002
Copy link
Owner

jpd002 commented May 30, 2019

I don't think there's a 1 fit all solution for this.

I think we should first implement the weaving properly which should get rid of the shaking (but will cause combing). This should emulate what happens on a real television.

Then we can think of adding support for deinterlacing methods which will enhance specific games and add options to enable them in the settings menu.

@rcaridade145
Copy link
Contributor

@Zer0xFF
Copy link
Contributor Author

Zer0xFF commented Jun 5, 2019

@rcaridade145 thanks for the links, the shader has a description and it seems to be what we need, they're also licensed under public domain, which is great :)

I'll get back to this once I get a chance

@toccata10
Copy link

Trying again the ps2 emulation, I finally stumble upon this:
https://forums.pcsx2.net/Thread-No-interlacing-codes
That was finally the solution on Pcsx2 to have, at last, a non shaking picture.
I tried before that, the integrated deinterlacers, the retroarch deinterlacer shaders. All these gave very poor results: blurry or shaky image.
Applying the cheats made ps2 emulation (on Pcsx2) so much better. So, maybe it could be possible to implement the support for this as I doubt that any deinterlacing will give good results on Lcd screens.
A workaround is patching the iso with something like https://www.psx-place.com/resources/ps2-patch-engine.694/
I was successful on Samurai_Spirits_Tenkaichi_Kenkakuden[JPN]: it's then well accepted on purei (otherwise the image is so shaky) and gives a very stable picture.
Some games are more difficult to patch than others.

@Zer0xFF
Copy link
Contributor Author

Zer0xFF commented Jul 1, 2020

I've seen that before, and its an interesting approach, one that i like, as stated in that post, interlaced will probably never be 100% reproducible on a modern screen. though i wonder how does sceGsSetHalfOffset work, is it an internal library function, or is it link to a syscall, or an IOP which we control on HLE side.

having said that, I do think we should still solve it traditionally, aka implementing interlacing, then also have this kind of option (potentially through cheat code).

once i get some free time, ill try to finish my other PRs and get back to this to see what i can do about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants