PCSX Rearmed - cut rendered image vertically [patch]


CrazyIvan

Member
Joined
Oct 10, 2011
Messages
124
Since there is no option to stretch rendered image vertically beyond screen height I decided to implement one. This could allow to stretch a little more without changing image proportions by clipping upper and lower part of rendered image (something like that is implemented in 'official' ps1 emulator in psp).
This patch adds an option to specify how many 'pixels' (which are actual pixels when height is 240 and scaled accordingly for resolutions that have another height) should be cut from top and bottom of the image (0 to 24).
This option is in 'Display' settings. This option also works correctly with software filters (didn't test much because i have 600MHz unit).
The patch is against latest git code

 
patch updated to correctly handle sub-192px game resolutions, the number of 'lines' to cut can be any value from 0 to 120 but it'll be automatically capped so that resulting image couldn't be wider than pandora screen (after scaling)
 
Update 2 

  • corrected code style to match the one used i this project
  • removed original height tracking; use the height passed as h parameter in pl_vout_flip()
  • use g_menu_menuscreen_* values to limit the number of lines to cut instead of pandora screen resolution, should work correctly even if height is more than width
  • a fix for incorrect y offset calculation with when height > 192 and software filter is being used
  • limits passed to software scalers are now correct
cutimg_patch.txt
 

Attachments

  • cutimg_patch.txt
    5 KB · Views: 272
Last edited by a moderator:
Nice. I take it the idea is for games with borders to eliminate those borders and show the game in full(er) widescreen?


Traditionally I'd refer to this as vertical overscan, whereas to my mind 'reduce image height/reduct v res' suggests reducing vertical detail. Or am I misunderstanding this change? I must admit, I'm not familiar with this source code, so I can't tell exactly what your diffs are doing.
 
A key for this would be great.

I just finished MegaMan X4 and the cut scenes there always had borders on top and bottom.
 
Last edited by a moderator:
Nice. I take it the idea is for games with borders to eliminate those borders and show the game in full(er) widescreen?


Traditionally I'd refer to this as vertical overscan, whereas to my mind 'reduce image height/reduct v res' suggests reducing vertical detail. Or am I misunderstanding this change? I must admit, I'm not familiar with this source code, so I can't tell exactly what your diffs are doing.
Yes, it simulates vertical overscan (you can specify the amount in options).

A key for this would be great.

I just finished MegaMan X4 and the cut scenes there always had borders on top and bottom.
You could reduce these borders but it will affect the game itself the same way.

Another thing to note is that vertical resolution in ps1 is 240 or sometimes 480 and pandora's screen height is 480 px so scaling won't distort anything.

With 'reduced' vertical resolution there should be some artefacts when stretching to pandora's screen height. Also 'integer scaling' option will actually reduce physical size of output picture on screen so '4:3 scaling' or 'fullscreen' scaling options should be used.
 
The "value/120*v_res" units aren't very intuitive since PSX games can set number of lines to whatever they like.. Some set it to 240, some 224, there are even 192 or so, there is also interlace mode with double vertical resolution. You could use percentage or something.

You are also likely to crash because of overflowing the source buffer, it probably didn't show up on the plugin you use since it used much larger buffer than needed.
 
Would this be a good idea to get incorporated into PCSX-ReArmed so it can be changed/toggled on the fly?
 
Last edited by a moderator:
The "value/120*v_res" units aren't very intuitive since PSX games can set number of lines to whatever they like.. Some set it to 240, some 224, there are even 192 or so, there is also interlace mode with double vertical resolution. You could use percentage or something.
It's actually percentage, (value/120*100)%

I wanted it to correspond to one line with 240 resolution with appropriate scaling, that is actually a reason to introduce additional orig_h variable

You are also likely to crash because of overflowing the source buffer, it probably didn't show up on the plugin you use since it used much larger buffer than needed.
I don't see why source buffer size would depend on output resolution, pl_vout_set_mode calls no code that affects emulator state. Also there is no video memory overflow since I changed copy limits accordingly.

There is actually an overflow bug when games request resolution <240 and user selects value which would result in actual vertical resolution <192 because i retained that original lower limit for vertical resolution. I'll try to fix it tomorrow
 
Last edited by a moderator:
The "value/120*v_res" units aren't very intuitive since PSX games can set number of lines to whatever they like.. Some set it to 240, some 224, there are even 192 or so, there is also interlace mode with double vertical resolution. You could use percentage or something.
 
It's actually percentage, (value/120*100)%


I wanted it to correspond to one line with 240 resolution with appropriate scaling, that is actually a reason to introduce additional orig_h variable
Still don't see why you chose 240 base as it often doesn't make sense. For example, PAL games often use 256 and your setting doesn't have much meaning in such case.

Also there is no video memory overflow since I changed copy limits accordingly.
Ok I missed that you updated pl_vout_h.

I think it would be much nicer if this was implemented in plat_gvideo_set_mode() on plat_omap.c . There you can specify amount of lines to skip from top and bottom, and you could make the menu setting specify plain lines instead of that "normalized to 240" thing.  plugin_lib.c is pretty messed up as-is and I don't want to make it even more messy.
 
Last edited by a moderator:
Still don't see why you chose 240 base as it often doesn't make sense. For example, PAL games often use 256 and your setting doesn't have much meaning in such case.
The main idea behind normalization is that the game could use multiple video modes and the number of lines skipped should be changed accordingly. Maybe it should be better if it is normalized for 'current' mode (the mode when user changes the number of lines to skip).

I think it would be much nicer if this was implemented in plat_gvideo_set_mode() on plat_omap.c . There you can specify amount of lines to skip from top and bottom, and you could make the menu setting specify plain lines instead of that "normalized to 240" thing.  plugin_lib.c is pretty messed up as-is and I don't want to make it even more messy.
The main problem is software scalers that request twice the resolution so if user decides to use it the number of lines clipped would decrease twofold (it would require separate tracking of software scaler type in  plat_gvideo_set_mode() and it would introduce real mess because it's another code in another file that should be modified when changing software scalers behaviour, for example adding another scaler or adding 4x scaler for 1080p). Maybe some generic sccaler framework should be implemented (maybe even allow scalers as plugins)? That could clean code a little.

By the way the copying code where I changed copy limits is in pl_vout_flip() and can't be moved elsewhere.  

And another thing about pl_vout_flip(), is h parameter actually internal image height? It doesn't change when I changed output resolution and I didn't dug the code too much

It turned out that there is also special case 'requested resolution is less then 192px tall' that handled separately in pl_vout_set_mode(). So either my code should be where it is now or this special handling should be moved to plat_gvideo_set_mode()
 
Last edited by a moderator:
For double resolution an assumption can be made - if height is > 256, it's double. This is not 100% correct, but would cover 95%+ of the cases.

I don't think it's worth bothering with reducing amount of copying as it's pretty fast NEON code, although it might give a bit benefit in double resolution mode.

I also don't think you should be handling 192 case, you should just do it after current 192 adjustment is made, so you can do it in plat_gvideo_set_mode() too. Current code centers the image and you can cut borders from the result.

Yeah pl_vout_flip() h should be the one the game sets.
 
For double resolution an assumption can be made - if height is > 256, it's double. This is not 100% correct, but would cover 95%+ of the cases.
 Unless it's interlaced 480 mode that is. Or until there'll be 3x or 4x scaler to use with higher res screen.

Actually there is a better alternative - there is pl_vout_scale variable which deals with this problem and I use it in new patch version to calculate proper source offset in pl_vout_flip()

I don't think it's worth bothering with reducing amount of copying as it's pretty fast NEON code, although it might give a bit benefit in double resolution mode.
 It's not about copy optimization, copy limits are there to ensure that there are no writes beyond framebuffer's end (and before its beginning for that matter).

I also don't think you should be handling 192 case, you should just do it after current 192 adjustment is made, so you can do it in plat_gvideo_set_mode() too. Current code centers the image and you can cut borders from the result.
 I need to change buf_yoffset because framebuffer height will change and offset should change accordingly.

By the way, plat_gvideo_set_mode() is one of the functions of video output system abstraction level and right now this function have 3 implementations. Border cutting is generic and not tied to any of these so it should be implemented one level above it and that happens to be inside plugin_lib. Or one can create duplicated code inside any of these implementations and that is always a mess.
 
Last edited by a moderator:
I don't think it's worth bothering with reducing amount of copying as it's pretty fast NEON code, although it might give a bit benefit in double resolution mode.
 
It's not about copy optimization, copy limits are there to ensure that there are no writes beyond framebuffer's end (and before its beginning for that matter).
vout_fbdev_resize() can take care of that if you pass it the args, but as you say you want it on all ports, it has to be done in plugin_lib.
 
Okay, cleaned my code and fixed all bugs I could find, I think the patch is ready.

By the way,I used g_menuscreen_* variables as maximum resolution. Maybe it should be used for correct implementation of resolution_ok() or are there any valid cases when g_menuscreen_* don't represent maximum output resolution? Of course it's not real maximum screen resolution for 'generic' platform (SDL) but I don't think that games should be allowed to go beyond that because it'll lead to randomly resizing main window which is a little confusing. It's better to set correct initial resolution and then don't go beyond it
 
Hi,


Maybe a noob question, but how can I install this patch on pcsx rearmed?


Thx!
 
Not really a noob question, since the answer's not really a noob answer, but basically you need to be able to build the PCSX PND yourself. Here's the source for the latest release. I don't think the patch for this diff has been included even in a later revision, so you'll need to use the patch tool to apply it (or it looks like there may be some patch tool built into git, dunno). Then rebuild and you've got a patched r19.

Or you could hope CrazyIvan pushes it to Notaz' git, and Notaz builds an r20 that includes it along with the rest of us.
 
Thanks for your answer. To be honest, I dont think I will build the source myself. Maybe someone else has build the sources and wants to upload them?


Anyway, it seems like a good idea to have this patch pushed to Notaz' git...
 
Back
Top