Sunday, March 5, 2017

Raspberry Pi 240p Composite Output

Big news for emulation on Raspberry Pis of any generation: a new firmware update has enabled 240p output through the composite video-out port (a dedicated port on older models and a combo 3.5 mm jack on newer models).

From Raspbian and its derivatives, you can run from a terminal:

sudo rpi-update

and it will automatically install the new firmware. For Lakka, the updated firmware will make its way into the main release at some point, but in the meantime, you'll need to mount your SD/microSD card on another machine and then find the 'boot' directory (for Lakka, this will be located in the ~500 MB partition that holds the system files rather than the bigger partition that holds your games) and make a backup in case anything goes wrong (not likely, but better safe than sorry).

Next, you'll need to download the new firmware files from github (here's a direct link to a zipped download) and copy them into the boot directory, overwriting what's already there. I believe you only really need a subset of the files (bootcode.bin, fixup.dat, fixup_cd.dat, fixup_db.dat, fixup_x.dat, start.elf, start_cd.elf, start_db.elf and start_x.elf), so if it acts strangely, maybe try cutting down to just those files.

In your config.txt, you can use the sdtv_mode directive to change to the new modes (either NTSC or PAL):

Also, make sure your config.txt isn't forcing HDMI output via hdmi_force_hotplug=1 (comment it out, if so) and you might want to force composite output, just to be sure, by adding hdmi_ignore_hotplug=1.

Raspbian and derivatives can now also change modes at runtime using the tvservice program:

Now, you'll notice that the above line still says 720x480 and applications will still see a 480-line resolution (that is, emulators will want to run at 2x scale). That's because the firmware still acts like normal 720x480 (or 576 lines for PAL) and the composite encoder just displays only half the lines.

This is actually to our benefit because it allows us to easily go back and forth at runtime and has the potential for on-the-fly switching (though RetroArch/Lakka doesn't support that and probably never will). It also allows emulators to show interlaced content without freaking out (that is, a "true" 240p resolution would cut off half of the picture, while this setup will just blank out every other line, which is much less obtrusive).

I have some pics here but, hilariously, the one from the new firmware turned out the worst:

RPi 240p Composite

Analogue Nt - RGB-PPU YPbPr

RPi 480i Composite

If you look closely, you can see that the RPi 240p shot has gaps between each scanline (easier to see on the green waves of the hill than on Luigi), while the 480i shot does not. What the still image can't show is that the 240p image is rock-solid stable, while the 480i image flickers sickeningly. Either way, the RPi composite output obviously does proper NTSC encoding, so blending of dithering and so on happens automatically without needing a shader, which is nice. EDIT: the NTSC encoding is (obviously, in retrospect) using the RPi's full 720 horizontal res timing rather than a console's native timing, so effects that depend on NTSC artifacting may or may not look like you would expect. For example, here's what the "tvpassfail" NTSC test ROM *should* look like:

NTSC Pass/Fail test ROM with maister's NTSC 256 px shader

But this is what the RPi's composite output actually shows:

NTSC Pass/Fail test ROM via RPi composite output

There's still crosstalk, of course, but it's spread across more pixels, which breaks the test. Perhaps unsurprisingly, it looks closer to the 320 px NTSC shader output:

NTSC Pass/Fail test ROM with maister's 320 px shader

With this new firmware, the RPi3 is now arguably the best/easiest/cheapest way to do proper 240p emulation on a typical NTSC standard-def television. Previously, a softmodded Wii was the undisputed champ in this area, as it was the only way to do 240p without putting a series of adapters and converters in the mix. The Wii still has an advantage insofar as it can output a high-quality YPbPr signal (i.e., comparable to the Analogue Nt shot above) but the RPi3 has the ability to emulate more consoles, including great Playstation 1 emulation via PCSX-ReARMed and decent N64 emulation via the core formerly known as GLupeN64 (now renamed to just Mupen64Plus-libretro). The Pi2SCART add-on from ArcadeForge can get a cleaner, "pixel perfect" output from emulators on the RPi, but at ~$50, it costs significantly more than the RPi itself, costs as much as a used Wii and requires adapters to work with standard NTSC televisions. So, in my opinion, RPi is the way to go for cheap/easy "240p" emulation on a regular ol' U.S. TV, while the Wii is a step up in visual quality but more of a hassle (and fewer games/consoles available to emulate). Pi2SCART wins in both respects but also adds significant cost.

Look pretty nice. I already use the Wii for 240p and love it... but I would also like to emulate PSX, N64 and some games from NeoGeo which are pretty big for the Wii's memory so I'm very interested on this new feature on the RPi3.

However I have a question that's keeps me from trying it on my RPi3... it generates 240p, right? however not all consoles/games output exactly 240p, SNES output 224 lines as I recall and some other systems like MasterSystem 192 lines, or the GBA 160 lines... I was able to easily setup a proper resolution on Wii to change the displayed lines... How I can achieve this on the RPi? The only way I can think of is using a custom viewport but that will actually leave some blank lines at the top and the bottom of the screen, correct? Otherwise the image will be stretched and will not look good...

It shouldn't matter. The extra lines fall into the overscan area anyway, just as they would on a real console. It can take some fiddling to get it looking right (I know this, not from using the composite-out, which I haven't done much of, but on my arcade monitor using the HDMI-out), but most cores look just fine with integer scaling and overscan cropped.

So far from my experimentations with Lakka and the new firmware there is no way to enable/increase overscan, so the image will always be too small. You need X11 to use xrandr to set overscan so the image (using integer scale, of course) will match native hardware (a real NES, etc.).

Hi Hunter. Made the last post as "Unknown", sorry... I just tried it with a vanilla Lakka and the new firmware with integer scale which gave me more overscan than I was getting before with my fiddled-with settings. I'm thinking we need a way to control overscan width and height independently, as for example the NES's 256x224 isn't a 4:3 AR. One way or the other this will get resolved, and I'm in the process of making a switch to flip between my RPi's Composite output and my actual NES's Composite output on the same TV so I can photograph and compare the two at high resolution with a mounted camera. I'm gunning for phosphor-precision accuracy to the real thing and will be able to test/verify it shortly. The Holy Grail is upon us. I can feel it. :)

I pushed the overscan commit directly to the picodrive repo instead of sending a PR (whoops!) so it should be available in the next LibreElec nightly build. Hopefully, it will get the vertical scaling in proper shape.

> has the potential for on-the-fly switching (though RetroArch/Lakka doesn't support that and probably never will)

I wouldn't say never, because all that needs to happen is allow RA to change display mode when a core calls set_geometry or set_system_av_info, and to allow setting screen resolution based on the core's native resolution. The cores already provide the relevant information to RetroArch in most cases to be able to select a valid modeline (geometry.base_width, geometry.base_height, timing.fps), though there would need to be some way to have a valid range to avoid cases like handheld cores trying to set 144p display modes.