randyrossi / bmc64

A bare metal Commodore 64 emulator for the Raspberry Pi with true 50hz/60hz smooth scrolling, low input latency and better audio/video sync.
GNU General Public License v3.0
475 stars 56 forks source link

[FR] Implementing CRT Emulation of Vice #188

Open CemTezcan opened 2 years ago

CemTezcan commented 2 years ago

I know there is already a great CRT filter in BMC64, but "CRT Emulation" is something different in Vice. Which is more like a palette manipulation on colors, instead of creating scanlines or phosphor effects. That color manipulations is somewhat very consistent on color blendings between 2 colors where same happens on real CRT screens too. I think that emulation will rock with current CRT / scanline filter when used together! I hope it happens!

CRT emulation can be accessed in Vice for windows by Settings -> Video Settings -> VICII Renderer -> Render Filter -> CRT Emulation

On the following images, you can see how interlaced colors on the background wogether blends as one new color. Real CRT screens also blend these colors like this.

Without CRT emu of Vice

without CRT emulation

With CRT emu of Vice

with CRT emulation

image by Vision https://csdb.dk/release/index.php?id=44655

joerg-knitter commented 2 years ago

[EDIT] This following post makes some false claims, e.g. that the Pi 1-3 is limited to 240p instead of 288p (instead, the composite output is limited to 720px width instead of 768px), and I claim that the scaling is wrong. So read some clarifications in the following posts. [EDIT OFF]

I made a lot of experiments with a real CRT some months ago, but due to limited pixel clock possibilities of the Raspberry Pi 1-3 (you only get 240p as a maximum, while PAL country would need 288p at least - or 576i to be more precise), I finally dumped the CRT - after having seen this: https://www.youtube.com/watch?v=IgHb3TPbFN0 and learned to know "Mr. RetroLust's Lights Off Retroarch Bezels" from https://forums.launchbox-app.com/files/file/1950-mr-retrolusts-lights-off-retroarch-bezels.

My C64 emulation currently looks like this (screenshot from a Android RetroArch setup, but looks the same on my Odroid N2 with Batocera (which also uses RetroArch): Screenshot_20210530-200759_RetroArch

I would really love to get something more advanced like this in BMC64 because this feels like real CRT simulation, but this also means more sophisticated shaders as well as overlay capabilities. However, I agree that at least this basic CRT effect of Vice would be a welcome addition.

CemTezcan commented 2 years ago

I made a lot of experiments with a real CRT some months ago, but due to limited pixel clock possibilities of the Raspberry Pi 1-3 (you only get 240p as a maximum, while PAL country would need 288p at least - or 576i to be more precise), I finally dumped the CRT - after having seen this: https://www.youtube.com/watch?v=IgHb3TPbFN0 and learned to know "Mr. RetroLust's Lights Off Retroarch Bezels" from https://forums.launchbox-app.com/files/file/1950-mr-retrolusts-lights-off-retroarch-bezels.

My C64 emulation currently looks like this (screenshot from a Android RetroArch setup, but looks the same on my Odroid N2 with Batocera (which also uses RetroArch): https://user-images.githubusercontent.com/6067036/128646534-0b4ecb2f-313b-406e-8c52-436ec616d41b.jpg

I would really love to get something more advanced like this in BMC64 because this feels like real CRT simulation, but this also means more sophisticated shaders as well as overlay capabilities. However, I agree that at least this basic CRT effect of Vice would be a welcome addition.

Looking really really good but still not bare metal :(. But what I'm referring as CRT emulation is not the CRT look, it's a color post process that Vice has.

Anyway, imho, best CRT emulation on C64 emulation so far is Micro64. It has even specific animated IC and antenna signal glitches! https://user-images.githubusercontent.com/53312532/128674143-81449816-4fb7-45db-89f6-61946e932160.png

About real CRT, Raspberry Pi analog AV is the killer on this. On a Commodore 1702 monitor, I connected BMC64 through video jack, and real C64 through chroma luma. And by switching the input by the switch on the monitor, I can't even recognize which one is real C64.

Check this out: https://youtu.be/qK6QrnSo5F0

joerg-knitter commented 2 years ago

I would prefer RGB output due to less color noise etc., so the analog AV with composite signal is not the right solution. Furthermore, due to the limitations of the Raspberry Pi 1-3, we don´t get the right/original aspect ratio on PAL resolution. See some arguments and discussion by me e.g. at https://www.lemon64.com/forum/viewtopic.php?p=908952#908952 (there is some more explanation on this some pages before in this forum thread). If you correct the aspect ratio in BMC64, you get scaling artifacts: https://www.lemon64.com/forum/viewtopic.php?p=910515#910515. Of course, you might use the output aspect ratio and use monitor settings. In my case, I used a "normal" TV where the horizontal scaling could not be adjusted.

However, it is interesting that you don´t see any difference when switching between BMC64 and a real C64 - I would really interested why this is the case because it is all against what I read and wrote in the above mentioned threads - there must be a difference in outputting 240 (Pi) against 288 (or 284; real C64) vertical lines in my opinion...

Since the pixel clock of an Raspberryp Pi 4 does not seem to be that limited, I would jump again on the BMC64 waggon back again once a port is available (and re-buy a CRT) or when shaders and overlays would also be available in BMC64 (using an (O)LED then).

Until then, I am going to stay with RetroArch hoping for an upcoming runahead option for this core (does not seem to be available currently).

CemTezcan commented 2 years ago

@joerg-knitter Sorry, I couldn't check what is the argument there, since all of this is not the subject of this feature request. Maybe they are out-of-date with latest updates, I don't know.

But the key on getting my results is to get pixel perfect scaling on "vertical" resolution. Horizontal resolution has not so much of importance so I keep the main ratio by adjusting the side borders. So even I don't have pixel perfect resolution horizontally, it keeps smooth scrolling since there is a "bilinear filtering" done on the framebuffer of the BMC64.

So yes, you can have perfect ratio with pixel perfect scanlines on a real CRT screen (doesn't matter if it's a TV or 1702 monitor, I don't do hardware scaling), since you can see that real C64 has the same aspect ratio on my video.

https://youtu.be/qK6QrnSo5F0

P.S. It needs to be presented as Progressive Scan PAL of course. Otherwise you get tracing artifacts on analog signal. sdtv_mode = 18

20210809_141756

mcgurk commented 2 years ago

@joerg-knitter When talking about some individual real CRT-display, there is no "perfect" aspect ratio. Image is multiple ways distorted. Many tv's have "service menu" where geometry can be adjusted. Geometry changes over time.

Raspberry Pi video output is very flexible. More than any other device I know. It supports real 288p and with modeline it can be adjusted very specifically. How many device supports analog progressive SD-output @50.125Hz? Pi's output is as close original as needed as we see in CemTezcan's great video. (if I understand modeline numbers correctly, pixelclock and image geometry is actually 100% same as real C64)

And if composite is not enough, with VGA666 you can get RGB-output from DPI: vga666_commando

joerg-knitter commented 2 years ago

Regarding the pixel clock limitations: There is a long thread with a conclusion that the problems with lower frequency settings have only been resolved with the Raspi 4: https://github.com/raspberrypi/firmware/issues/734#issuecomment-508007705.

@CemTezcan I have to admit that I just gave your video a closer look - I did not understand first, that you compare the RPi output to that of an original C64 - impressive indeed, and using composite really seems to be comparable to the original one, thanks for this! I assume, we talk about a PAL setup here? If it was NTSC, it would technically totally understand that the output was the same... The sdtv_mode=18 should not have the exact same pixelclock etc. as it uses 50Hz, 720x576 Pixels while the original C64 has 50.125Hz and something like 403x284 pixels (https://dustlayer.com/vic-ii/2013/4/25/vic-ii-for-beginners-beyond-the-screen-rasters-cycle) - if the author is right.

I saw that my research and posts are older >1 year, and I can´t remember exactly. Therefore, claiming above that the Raspi cannot do 288px was definately wrong. It was not a limitation of the vertical pixels (240p vs. 288p), but I apparently I saw limitations in the horizontal resolution: "The frambuffer size of the RPi seems to be limited in composite mode to 720px and not 768px (PAL), while the horizontal resolution of the emulator is 384px, therefore integer scaling is not possible." See the results here: https://www.lemon64.com/forum/viewtopic.php?p=910515#910515

From my tests, I thought to have never got the right output with VGA666 for PAL resolution, believing that the upper and lower borders were too thick, see https://www.lemon64.com/forum/viewtopic.php?p=908692#908692 and the analysis of outputs of the real PAL machines at http://hitmen.c02.at/temp/palstuff/ and https://dustlayer.com/vic-ii/2013/4/25/vic-ii-for-beginners-beyond-the-screen-rasters-cycle .

But indeed, this is offtopic, but I would really love to read more about it and why I might be/have been wrong with all the figures, researches and calculations... ;)

mcgurk commented 2 years ago

@joerg-knitter You have wrong assumptions. I can only say that trust that signal is identical. There is no scaling. No scaling artifacts like in your link. Every pixel is in same place, same size and same pixel aspect ratio as in real C64. Every scanline is in same place and every frame takes same amount of time. Framebuffer resolution doesn't matter, it is just area in raspberry Pi memory. Framebuffer resolution/size doesn't define video signal geometry.

Real CRT-television image is a mess in modern days standards. Overscan and place of active image alters highly. In many Vic20 games even had support to move active picture area. Old computer monitors had separate potentiometers for centering image and resizing it. So if you remember that real C64 image was always in right aspect ratio and center of screen, you probably remember wrong.

C64 doesn't output exactly standard PAL-signal, but here is information about timings of PAL-video signal and how video signal looks like: http://martin.hinner.info/vga/pal.html

joerg-knitter commented 2 years ago

Ok, even though I miss arguments here or at the Lemon64 forum with a pointing where exactly I have been wrong, I might have got it now.

I have re-read my arguments and also tested sdtv_mode = 18 back then, and looking at the Giana Sisters intro, there was some "wobbling" visible in the scrolling bricks. I think that those are clearly scaling artifacts, simply because the 384 pixels of the emulator don´t fit into the 720 pixels horizontal resolution - you would have to set it to 768 pixels instead which is not possible on the Raspberry Pi 0-3.

However, you get this solved by using your own modeline. And my wrong assumption was apparently, and that was the real missing point, that the image is wider as it is support to be when using 1920px instead of 2x 768px (or 4x 384px). In fact, the CRT TV does not make a difference between 1920px and 1536px as long the relation between border and main area stays the same - which is the case. So, despite of a lot of screenshots etc. that show a kind-of 4:3 main area, it might indeed have used the vertical scaling potentiometer back then - although I believe that I also started with a "normal" CRT TV before I also got a Commodore monitor. I knew that the overscan differs from CRT to CRT, but I though it would be a kind of equal between vertical and horizontal resolution.

So thanks for your hints and especially for the great video above.

CemTezcan commented 2 years ago

@joerg-knitter Glad you like the video. Wobbling shouldn't be happening. It means we may have different setups. I just recorded this. If you set your monitor's refresh rate to 50Hz, you can see what I see (I mean no wobbling smooth scrolling). https://www.youtube.com/watch?v=74QUCkWvD_0

For a double check, I remind you to set scaling interpolation ON. So horizontal integer scaling won't be needed. Also setting the horizontal scale as I did on this image may help: https://user-images.githubusercontent.com/53312532/128699192-bcb476f6-0c36-49d0-93b8-e44f4dab3810.jpg

joerg-knitter commented 2 years ago

@CemTezcan I think, I also found the reason on this: I never used scaling interpolation due to the additional blur; I preferred integer scaling. This wobbling effect is difficult to describe - it is as if the bricks permanently get a little bit smaller and then thicker again during scrolling due to this non-interpolated scaling from 384px to 720px. If I remember correctly, I could see this especially on the edges of the "THE G" letters. To avoid blurring, I used the pixel perfect output described in the chapter "Perfect DPI -> (Real) CRT Scanlines" at https://github.com/randyrossi/bmc64, and my described behaviour was cause by never having seen scaling interpolation as a good alternative.

I cannot see extensive blur on your video, but you use an Commodore 1702 monitor which has 13 inch size (if I googled correctly), my CRT TV was a JVC AV-21KM35N which was a 20 inch CRT. Here, the additional blur was clearly visible.

I posted my former setup (not 720x288, just 1920x288) and settings here (upper screen): https://www.lemon64.com/forum/viewtopic.php?p=908692#908692. In the same thread, the user vma also said that the look is completely the same compared to the original, but at this point of time we clearly couldn´t agree at least on the point that you get a better image quality using RGB/VGA output instead of Composite... I also did not believe that the scaling is the same, but this is something we could resolve here at least ;)

But as mentioned before: Thanks again for your hints and this interesting discussion! Unfortunately, as I wrote, I don´t have the CRT anymore, and I also sold my Raspis in favour of an Odroid N2 using bezels and CRT shaders with Batocera, so I cannot reproduce it anymore and post videos (at least not at this point). However, this discussion makes my interest growing again - maybe I need to get this TV back on eBay for 10€ and buy a Raspi3 again to get this fascinating technical replica back again...

CemTezcan commented 2 years ago

@joerg-knitter I'm sure RGB/VGA would be cleaner than composite, but after a point it looks like using C64 with a super clean pixels on an LCD screens which I don'tlike :) CRT scanlines are better when they hit each horizontal line on low res. Hence, high res framebuffer on a CRT monitor with VGA has too many scanlines for each horizontal line, so they won't be recognizable. That makes us to use artificial scanlines which are also not my taste on a CRT :)

Anyway, please check my setup. I fill the screen with "G" letters. Still no recognizable pixel streching. I know what causes wobbling. it happens when you get wrong resolution from left to right, so framebuffer scales some pixels by 2x and rest by 1x to make them fit to the overal columns. It's not necessary if you're using scaling interpolation in my case. So I don't think it's caused by the screen size.

Also there is a bug on BMC64 that you need to shift your framebuffer 1 pixel (or any "odd" number of pixels) up or down to match the scanlines on screen with composite signal. In my case I moved the FB -17 pixels.

this is my settings image

these are uniform G letters Untitled Untitled2

mcgurk commented 2 years ago

I remembered something essential wrong: composite out of Raspberry Pi is not as flexible as DPI/HDMI. So I take everything back when talking about composite output. It cannot do 50.125Hz or fully mimic C64 video signal.

I had to put my setup up just for testing and I used default VGA666 50.125Hz settings from README.md. I don't know if comparing composite image with RGB image is good test, but only geometry thing that differs is location of image. TV is Salora 22L30 from 1987 or 1988 with Scart-connector at back. Image with stock boot screen is from real C64C with composite scart cable and Retroreplay image is from BMC64. Notice: Interpolation is OFF and scaling is integer.

There is also image of my DPI->Scart-adapter. Many adapters and instructions from internet uses extra components for combining vsync and hsync to csync, but Raspberry can do it itself with config.txt line: dpi_output_format=0x105 # add this to get csync from DE/GPIO1/pin28 So adapter can be done from VGA666-adapter with just soldering cable.

bmc64_VGA666_CRT

CemTezcan commented 2 years ago

Hello @randyrossi, do you think is there a hope for this effect? Is it possible?

randyrossi commented 2 years ago

Probably possible. Do you have any info on how it is implemented? A shader?

On Sat, Sep 4, 2021, 2:48 PM CemTezcan, @.***> wrote:

Hello @randyrossi https://github.com/randyrossi, do you think is there a hope for this effect? Is it possible?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/randyrossi/bmc64/issues/188#issuecomment-913021037, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAI3HKH6I55MTFY72PG7OLTUAJSYZANCNFSM5BXJSRVA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

CemTezcan commented 2 years ago

I'm not a coder but It looks like its an implemented standard feature of vice.

https://vice-emu.sourceforge.io/vice_7.html

As a console command, there is:

-VICIIfilter <Mode>
Select rendering filter (VICIIFilter). (0: None, 1: CRT emulation, 2: Scale2x)
CemTezcan commented 2 years ago

Hello again Randy, Do you think is there a hope for this?

randyrossi commented 2 years ago

I think BMC64's renderer is the 8-bit depth 1x1 PAL renderer which doesn't support that filter. To use VICE's filter, the renderer would have to be changed and then all the code that passes the data to the GPU would need to be revisited (since the format will change). It's probably possible but a lot of work. It could also end up taxing the Pi more too because the higher bit renderers will take more time to do their job. I think shaders are better for filters. So you may have better luck finding one that implements the kind of look you want and integrating that.

On Fri, Oct 1, 2021 at 12:55 PM CemTezcan @.***> wrote:

Hello again Randy, Do you think is there a hope for this?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/randyrossi/bmc64/issues/188#issuecomment-932392413, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAI3HKAGFS4GCVFQV3J3Q5LUEXRXVANCNFSM5BXJSRVA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

-- Randy Rossi

CemTezcan commented 2 years ago

I think BMC64's renderer is the 8-bit depth 1x1 PAL renderer which doesn't support that filter. To use VICE's filter, the renderer would have to be changed and then all the code that passes the data to the GPU would need to be revisited (since the format will change). It's probably possible but a lot of work. It could also end up taxing the Pi more too because the higher bit renderers will take more time to do their job. I think shaders are better for filters. So you may have better luck finding one that implements the kind of look you want and integrating that. On Fri, Oct 1, 2021 at 12:55 PM CemTezcan @.***> wrote: Hello again Randy, Do you think is there a hope for this? — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#188 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAI3HKAGFS4GCVFQV3J3Q5LUEXRXVANCNFSM5BXJSRVA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub. -- Randy Rossi - "There are only two things that are hard about computer science; Naming things, Cache Invalidation, and Off-by-one errors."

Thanks for clarifying Randy. What about glsl shaders? I used quite some of them. Can fetch some useful ones by competing them visually. Do you think that they can be applied? For example crt_lotte_mathias.glsl.

https://github.com/libretro/glsl-shaders/blob/master/crt/shaders/crt-mattias.glsl

randyrossi commented 2 years ago

It could probably be made to work. BMC64's shaders are in shaders/crt-pi-idx.gls and shaders/crt-pi-rgb.gls so those can get replaced with different algorithms. I think the VICE shaders use just the -idx version and just the Plus4Emu that's rgb. There's an expectation for certain attributes to be present from the main code but you could replace the shaders with your own code and ignore the parameters to test. But it would take some coding skills. There's an intermediate step to get the rgb from the index. Maybe it would be easier to run Plus4Emu and install that shader to see how it behaves.

On Fri, Oct 1, 2021 at 2:38 PM CemTezcan @.***> wrote:

I think BMC64's renderer is the 8-bit depth 1x1 PAL renderer which doesn't support that filter. To use VICE's filter, the renderer would have to be changed and then all the code that passes the data to the GPU would need to be revisited (since the format will change). It's probably possible but a lot of work. It could also end up taxing the Pi more too because the higher bit renderers will take more time to do their job. I think shaders are better for filters. So you may have better luck finding one that implements the kind of look you want and integrating that. … <#m7533211549620128293> On Fri, Oct 1, 2021 at 12:55 PM CemTezcan @.***> wrote: Hello again Randy, Do you think is there a hope for this? — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#188 (comment) https://github.com/randyrossi/bmc64/issues/188#issuecomment-932392413>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAI3HKAGFS4GCVFQV3J3Q5LUEXRXVANCNFSM5BXJSRVA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub . -- Randy Rossi - "There are only two things that are hard about computer science; Naming things, Cache Invalidation, and Off-by-one errors."

Tha ms for clarifying Randy. What about glsl shaders? I used quite some of them. Can fetch some useful ones by competing them visually. Do you think that they can be applied? For example crt_lotte_mathias.glsl.

https://github.com/libretro/glsl-shaders/blob/master/crt/shaders/crt-mattias.glsl

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/randyrossi/bmc64/issues/188#issuecomment-932465799, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAI3HKCPR62UGHHI5DDHE43UEX52LANCNFSM5BXJSRVA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

-- Randy Rossi