Sorry for the headline, which might sound a little bit provoking, but after the tests I did in the last days, I am not sure if I have the right understanding or if the basic concept behind CRTSwitchRes is wrong.
First of all: My goal is to get an analog RGB output which is scaled the same way like the original consoles do when I connect the emulator to a consumer TV - not to a PC monitor, a professional Sony PVM or even a HDMI flat screen. I played around first with an Raspi 2, but after I learned about the pixel clock limitations on Raspi 1-3 and wanted to get nearly all SD consoles emulated, I built a PC from spare parts and spent some money on an used Radeon R9 280X - the fastest AMD card with an DVI-I connector - and an Ultimate SCART VGA-to-Scart adapter.
The result after having activated CRTSwitchRes in RetroArch is disappointing and does not seem to be right in my opinion when using a consumer CRT, even though there are already lot of demo videos and photos on the web showing the games on CRTs. Some examples:
- The speedometer in Gran Turismo 2 (European = PAL version) is cut on the right of the screen, also the text in the upper left area seems to be too close to the borders of the visible CRT screen
- On some Mega Drive / Genesis games, texts and icons are either cut at the left and right borders or too close to the borders. As consoles are meant to be plug & play and developers had to take care of the overscan area of CRT TV during game development, I don´t think that this is the right output, especially as only few consumer TVs might have offered image shifting and scaling without using a hidden service menu (see also my bug/feature request at https://github.com/libretro/RetroArch/issues/10475).
Therefore, I currently think that switching the resolution to the consoles internal resolution via CRTSwitchRes is wrong - while adjusting the framerate and maybe switching between half and full vertical resolution might be perfectly right. In most documentations and discussions I searched on the web, the NTSC or PAL video standards or at least the vertical resolutions of 480/240 or 576/288 pixels are mentioned as base for the outputs, and that often not all lines or the full width are said to be used.
A good example is the NES and the documentation at https://wiki.nesdev.com/w/index.php/Overscan:
Multiplying the pixel rate by the scanline length gives 39,375,0006/4/11640/(135,000,000/11) = 280 pixels per scanline. The PPU puts signal in 256 of these and a border at the left and right sides." Even more interesting: "There are two ways to emulate the pixel aspect ratio of the NES: scale before padding and pad before scaling. The NES PPU hardware performs the padding first, adding 24 pixels of border to form a 280x240 pixel picture that can be resized to 320x240, 640x480, or 960x720 square pixels, or to 352x240 or 704x480 if your SDTV output circuit produces non-square pixels at 13.5 MHz (Rec. 601/DVD dot clock, 132/35colorburst) or 13.423 MHz (PlayStation dot clock, 15/4colorburst). […]
What CRTSwitchRes does, is changing the TV resolution to the native 256x240 resolution. From my understanding, this means, that my consumer TV fills the whole screen with this resolution, not taking care of the padding on the left and right, so the resulting image is wider than it should be, even if you don´t recognize this at the first sight. This might of course be fixed with the aspect ratio setting - but you might get the point… Same goes e.g. with N64, that always has a resolution of 640x480, but at least on my TV fills the whole horizontal width, hiding pixels within the overscan area.
Another example is the PlayStation like mentioned before: If I start Gran Turismo 2 (Arcade Disc), xrandr tells me that the resolution is switched 6 times until the racing starts: 640x478, 640x480, 320x256, 368x480, 320x240 and 320x256, the last one clearly having cut borders. Regarding the vertical resolution, I found this at http://www.psxdev.net/forum/viewtopic.php?t=3513#p18324:
If you specify less lines, simply more of the screen will be black. If you specify too many lines, some of your graphics will end up in overscan, and not be visible on a CRT. You can never make the GPU output more or less actual lines.
My TV does seem to stay at a certain vertical resolution, so there are at least (correct?) black borders at the top and the bottom e.g. at 480 and 256 pixels vertical resolution, the latter one scaled apparently to 512 pixels, but once again, the horizontal stretching is for sure wrong.
So finally, as a summary, wouldn´t the correct behaviour be to switch to the correct TV standard (640x480 or 768x576 when using square pixels (or superres)), use integer scaling to fill the whole screen based on the vertical resolution as good as possible (i.e. 224px becomes 448px, 448px would stay as-is), center this image and add appropriate borders? Besides, this would solve any shifting problems we currently might have with CRTSwitchRes in certain modes.
You might say: This could be achieved by simply disabling CRTSwitchRes, but then, the automatic framerate adjustment is also disabled and thus the 60.1 Hz refresh rate instead of 54.94 Hz e.g. on NES can only be achieved by additional startup scripts like used before e.g. on RetroPie when CRTSwitchRes was not available yet. Also, automatic NTSC-PAL resolution switching as well as switching between 240p and 480i (or 288p and 576i) is not possible.
So, what is your opinion on this? Or was CRTSwitchRes never intended to be used on console emulation but on Arcade games instead and/or for PC monitors without the consumer TVs´ big overscan area?