High Resolution Dreamcast Video Modes!

If you have any questions on programming, this is the place to ask them, whether you're a newbie or an experienced programmer. Discussion on programming in general is also welcome. We will help you with programming homework, but we will not do your work for you! Any porting requests must be made in Developmental Ideas.
Post Reply
User avatar
Moopthehedgehog
DCEmu Freak
DCEmu Freak
Posts: 84
Joined: Wed Jan 05, 2011 4:25 pm
Has liked: 4 times
Been liked: 33 times

High Resolution Dreamcast Video Modes!

Post by Moopthehedgehog » Sun Feb 16, 2020 7:31 pm

Hi all!

I spent a lot of time the last couple weeks working on getting the Dreamcast to output all kinds of high resolution video modes. It's part of DreamHAL, which I have written about here:
https://dcemulation.org/phpBB/viewtopic ... 9&t=105371

And is hosted here:
https://github.com/Moopthehedgehog/DreamHAL
The files of interest are "startup_support.h" in the "inc" folder and "startup_support.c" in the "startup" folder.

Here's the list of modes I made. All non-HDTV 60Hz and 75Hz modes have been tested across 5 different kinds/brands/sizes of LCD monitors using direct VGA connections, and they all work. The ones marked as "for HDTVs" mean they are made according to HDTV timings, and are meant for something like a Beharbros Gekko box to connect to an HDTV through HDMI (and may not work properly through a VGA port). That said, all the HDTV modes have a non-HDTV equivalent.
Spoiler!

-- Overview of Available Modes --

"PVR 32x32" means the framebuffer is a multiple of 32x32. Modes without that
label are "raw modes" and have no blank pixels or extra pixels, which may be
useful for compatibility testing or software renderers. Modes that only have
a PVR 32x32 version are actually raw modes with framebuffers already multiples
of 32x32, and no extra modification was needed for them.

60Hz:

848x480 @ 60Hz (16:9, DMT, but using a slightly-too-short hsync)
848x480 @ 60Hz (16:9, DMT, but using a slightly-too-short hsync) - PVR 32x32
800x600 @ 60Hz (4:3, DMT, but using a slightly-too-short hsync)
800x600 @ 60Hz (4:3, DMT, but using a slightly-too-short hsync) - PVR 32x32
800x600 @ 60Hz (4:3, CVT)
800x600 @ 60Hz (4:3, CVT) - PVR 32x32
1024x768 @ 60Hz (4:3, DMT)
1024x768 @ 60Hz (4:3, DMT) - PVR 32x32
1152x864 @ 60Hz (4:3, CVT)
1152x864 @ 60Hz (4:3, CVT) - PVR 32x32
720p60 (16:9, DMT & CTA-861) - for HDTVs
720p60 (16:9, DMT & CTA-861) - for HDTVs - PVR 32x32
1280x720 (16:9, CVT) - for monitors that need this instead of HDTV 720p60
1280x720 (16:9, CVT) - for monitors that need this instead of HDTV 720p60 - PVR 32x32
1280x800 @ 60Hz (16:10, DMT & CVT)
1280x800 @ 60Hz (16:10, DMT & CVT) - PVR 32x32
1280x960 @ 60Hz (4:3, DMT) - PVR 32x32
1440x900 @ 60Hz (16:10, DMT & CVT)
1440x900 @ 60Hz (16:10, DMT & CVT) - PVR 32x32

75Hz:

640x480 @ 75Hz (4:3, DMT)
640x480 @ 75Hz (4:3, DMT) - PVR 32x32
800x600 @ 75Hz (4:3, DMT)
800x600 @ 75Hz (4:3, DMT) - PVR 32x32
1024x768 @ 75Hz (4:3, DMT) - PVR 32x32
1152x864 @ 75Hz (4:3, DMT) - PVR 32x32

120Hz (LCD Only - Untested):

480p @ 120Hz (4:3, CTA-861, 720x480) - for HDTVs - PVR 32x32
640x480 @ 120Hz (4:3, CVT, RB) - for monitors that need this instead of HDTV 480p120
640x480 @ 120Hz (4:3, CVT, RB) - PVR 32x32
800x600 @ 120Hz (4:3, DMT & CVT, RB)
1024x768 @ 120Hz (4:3, DMT & CVT, RB)

240Hz (LCD Only - Untested):

480p @ 240Hz (4:3, CTA-861, 720x480) - PVR 32x32
480p @ 239.76Hz (4:3, CTA-861, 720x480) - PVR 32x32

CVT RBv2 Native Modes (LCD Only, probably need one newer than 2013):

640x480 @ 75Hz (4:3, CVT, RBv2) - PVR 32x32
848x480 @ 60Hz (16:9, CVT, RBv2) - PVR 32x32**

** Well, ok, this one's actually 832x480 internally, but the horizontal
"stretch" is just 2%. It's the closest we can get to a real native 16:9 mode,
anyways, because the next step up is 864 wide... Which is too big for 848x480
to work. So if you're looking for a true native widescreen, this is about as
good as it gets.


And this is how I did it:
Spoiler!

-- About These Modes --

The Dreamcast is actually able to output higher resolutions over VGA by taking
advantage of the properties of analog display signalling. Namely, analog
signals are measured in terms of time a signal spends high or low, and this
can be used to make a slow pixel clock appear to output a higher rate than it
should otherwise be capable of doing.

This works because digital displays like LCDs use an analog-to-digital
converter (ADC) to convert analog signals into something they can use. ADCs
work by sampling the RGB signals at specific rates, and each sample then
becomes a pixel. By ensuring the signal timing is correct, and that the LCD
is expecting a higher resolution, we can trick the ADC into sampling the same
spot multiple times. What this does is stretch something like 320 pixels (as
the Dreamcast sees it) into 1280 (as the monitor sees it).

An LCD is made to expect a higher resolution by using the right number of
total vertical lines (so, including blanking), since in analog display
signalling vertical is the "master" signal and horizontal is just whatever
fits between the vertical line signal pulses. That's the core of how this
trick works, and also why the resolutions have an exact vertical line count
despite using weird horizontal pixel counts.

A CRT, by contrast, just keeps moving the electron gun and "smears" the screen
for a bit longer per pixel, since the Dreamcast is feeding the expected timings
for a higher resolution. A CRT may need its picture to be manually widened if
the image comes out looking squished on it, however.

The way to calculate the horizontal pixel count is simple: in VGA mode the
Dreamcast has a 27MHz clock, so you just do

(horizontal parameter) * 27MHz / (DMT pixel clock for desired resolution)

And the vertical line parameters stay the same as each resolution standard
asks for. This does mean that, because the Dreamcast video size registers max
at 10 bits in size, resolutions with vertical lines over 1024 (including
blanking) are not possible to output. But we can do 60Hz 1280x960 and 720p!

So, in simple terms, this ultimately all just means that the signal coming
out over the VGA cable is a valid signal for the higher resolution, but the
Dreamcast thinks it's outputting something else. For example, a 1024x768
signal coming out of the Dreamcast looks like 425x768 internally, since that's
just what it takes to make the signals line up in the right places.


I've documented everything at length in the startup_support.h/.c files, so if you want to use them go for it!

A couple images I took of 1280x720 working are attached. It was pretty awesome seeing modes like 1280x720 and 1440x900 on my 4K monitor!
Attachments
Screen_Shot_2020-02-16_at_15.42.09.png
Screen_Shot_2020-02-16_at_15.46.59.png
These users liked the author Moopthehedgehog for the post (total 4):
|darc|maslevinnymusProtofall
I'm sure Aleron Ives feels weird with his postcount back to <10668
:D
User avatar
ThePerfectK
Insane DCEmu
Insane DCEmu
Posts: 127
Joined: Thu Apr 27, 2006 10:15 am
Has liked: 21 times
Been liked: 19 times

Re: High Resolution Dreamcast Video Modes!

Post by ThePerfectK » Mon Feb 17, 2020 10:59 am

This would be super useful for anamorphic wide-screen. Currently anamorphic wide-screen depends on your TV to be able to stretch 4:3 content to 16:9. I have a couple of monitors which can't do that, so anamorphic wide-screen is impossible on those. This is super useful!
Still Thinking!~~
nymus
DC Developer
DC Developer
Posts: 959
Joined: Tue Feb 11, 2003 4:12 pm
Location: In a Dream
Has liked: 1 time
Been liked: 2 times

Re: High Resolution Dreamcast Video Modes!

Post by nymus » Tue Feb 18, 2020 3:48 am

BRILLIANT! Thanks. It always wondered why we couldn't output higher resolutions even though the GPU was based on a pc chip.

So, you're saying that the 3D and 2D pipeline would be working optimally with a lower resolution but the ramdac would upscale the image? Maybe a photograph would help demonstrate the effect?

[update]

I tried it out with kos after a few rough modifications. I don't understand the details so I just wanted to see what would happen. I concur, that it is very exciting to see 1024x768 reported by my monitor. (note: my TV did not recognize the 1280x960 that's the default in the source file)

I used the PNG demo which loads a 512x512 png image into the background and scrolls some text over it. I replaced the image with one of 1024x1024 dimensions. I didn't change the pvr details which target a 640x480 resolution.

640x480:
dc-648x480.jpg
1024x768:
dc-1024x768.jpg
Even though the image gets distorted, I think it helps to visualize what's happening a little bit....
behold the mind
inspired by Dreamcast
User avatar
Moopthehedgehog
DCEmu Freak
DCEmu Freak
Posts: 84
Joined: Wed Jan 05, 2011 4:25 pm
Has liked: 4 times
Been liked: 33 times

Re: High Resolution Dreamcast Video Modes!

Post by Moopthehedgehog » Tue Feb 18, 2020 4:14 pm

Oh yeah, the stuff I have in dc_main.c is just my really garbage code for making sure the resolutions were all set correctly. 1280x960 is just one of the higher ones and its framebuffer is exactly the same size as 640x480 so I used it to ensure that my memsets don’t overrun the buffer like they do with the modes with smaller framebuffer sizes—like I said it’s pretty garbage testing code, which is why I didn’t mention it exists because it *will* get removed at some point in the near future.

I wrote in the DreamHAL readme how to actually use it with KOS projects (at the bottom). You may also need to remove the “FPSCR Support” section in the startup_support.h and startup_support.c files if it gives you warnings/errors (general note: if you don’t know what FPSCR is, how to work with it, and how GCC makes important assumptions based on it, you have no reason to keep that section or otherwise worry about FPSCR).

I tend to write my documentation on how to actually use things inside the source files, too, so everything needed to know how to work with the stuff is in there.

As far as how it actually works, as I’ve written extensively, the Dreamcast output basically takes advantage of an analog video property where all video parameters are based on signal timing. You can think of this as like anamorphic widescreen, but using the ADC of the monitor so that the image gets stretched correctly. All of the video modes have a 1:1 vertical scale, but the horizontal size is scaled by various factors specific to the timings of each video mode. 1280x960 thus looks like 1280x960 to the monitor, but the Dreamcast thinks it is 320x960, for example. So you divide all your textures and things by 4 in the horizontal direction and the screens stretch it back out, all because the signal in the VGA cable matches what the screen expects of a higher resolution.
I'm sure Aleron Ives feels weird with his postcount back to <10668
:D
nymus
DC Developer
DC Developer
Posts: 959
Joined: Tue Feb 11, 2003 4:12 pm
Location: In a Dream
Has liked: 1 time
Been liked: 2 times

Re: High Resolution Dreamcast Video Modes!

Post by nymus » Wed Feb 19, 2020 4:54 pm

Exciting stuff! I went back and read the readme which was definitely easier to integrate than the way I had hacked it. The modes output correctly (I tried 800x600, 1024x768 and 720p) but I've been having trouble rendering using the pvr 3d pipeline because I'm not informed on the detailed workings of graphics hardware.

However, I was just too excited about this to sit idly by so I poked and prodded, learning whatever I could along the way, until I finally got something showing in 1024x768. It looks interlaced and offset from the vsync/hsync... thing-a-ma-jigs but I don't care! Dreamcast HD is happening, Moop! I can rest now... for a little while.
dc-hd-sonic-1024x768-unsynched.jpg
behold the mind
inspired by Dreamcast
User avatar
Moopthehedgehog
DCEmu Freak
DCEmu Freak
Posts: 84
Joined: Wed Jan 05, 2011 4:25 pm
Has liked: 4 times
Been liked: 33 times

Re: High Resolution Dreamcast Video Modes!

Post by Moopthehedgehog » Thu Feb 20, 2020 12:34 am

Yeah, I don’t know much about working with the holly either, but if using it you should probably stick to the PVR 32x32 modes—that’s why I made them: no overdraw, no wasting pixels.

The Dell 1702fp is one of the monitors I tested, seems like your model is a much updated version of it. It’s a 5:4 monitor (max res 1280x1024) so you can’t use any of the 16:9 modes like 1280x720 or 720p. Well, I mean, the monitor will accept it but probably think it’s 960x720. 1024x768 should be fine, though, since that’s 4:3... :/ (Not only that but the mode labeled 720p is explicitly meant for HDTVs through HDMI only; 1280x720 is the one for 16:9 widescreen monitors. Because for some reason there are two different standards for 720—an HDTV one and a monitor one...)

That definitely doesn’t look right, though. It should look right if you multiply the horizontal axis of the image by the horizontal scale in the file (STARTUP_video_params.video_scale_multiplier holds that float), and then copy the image directly from RAM to the framebuffer. That’s the first test; it should look right there. If not, then something is wrong.

It’s possible I missed something: Maybe there’s a PVR register or kos setting that needs to be changed that I missed? Maybe there’s something else going on? Maybe it’s not me? I can only guess because I don’t use KOS myself and I was just trying to configure the video output hardware. That at least is something I could test pretty extensively, so I’m confident in the VGA signal.
I'm sure Aleron Ives feels weird with his postcount back to <10668
:D
nymus
DC Developer
DC Developer
Posts: 959
Joined: Tue Feb 11, 2003 4:12 pm
Location: In a Dream
Has liked: 1 time
Been liked: 2 times

Re: High Resolution Dreamcast Video Modes!

Post by nymus » Thu Feb 20, 2020 8:14 am

Moopthehedgehog wrote:
Thu Feb 20, 2020 12:34 am
That definitely doesn’t look right, though. It should look right if you multiply the horizontal axis of the image by the horizontal scale in the file (STARTUP_video_params.video_scale_multiplier holds that float), and then copy the image directly from RAM to the framebuffer. That’s the first test; it should look right there. If not, then something is wrong.
Aha! That makes sense! Thanks. I've also noticed that kos internally configures some pvr parts with an assumed 640x480 resolution so those might need to be modified. All in all, this is such a wonderful success. Best of luck in everything!

I'll take some time to study video rendering/timings/output. It's fun how something previously incomprehensible can become a pleasure to explore when it connects to a personal passion. Your explanations of the timings have made the concepts of back porch, mode lines, blank periods etc much easier to understand and I think I'm slowly putting it all together...
These users liked the author nymus for the post:
|darc|
behold the mind
inspired by Dreamcast
User avatar
Moopthehedgehog
DCEmu Freak
DCEmu Freak
Posts: 84
Joined: Wed Jan 05, 2011 4:25 pm
Has liked: 4 times
Been liked: 33 times

Re: High Resolution Dreamcast Video Modes!

Post by Moopthehedgehog » Thu Feb 20, 2020 9:54 am

nymus wrote:
Thu Feb 20, 2020 8:14 am
Aha! That makes sense! Thanks. I've also noticed that kos internally configures some pvr parts with an assumed 640x480 resolution so those might need to be modified.
If you are referring to the vid_init() function in init.c, that's what I'm overriding by writing those 3 KOS parameters.

But, if you find that KOS uses video parameters other than the 3 I stated to overwrite (I just did a full project search for the vid_mode global struct, which may not have been thorough enough), please let me know and I will modify things accordingly. As far as I can tell KOS only uses vid_mode->width, vid_mode->height, and vid_mode->pm, and all the other stuff from that struct is used to configure the video registers (at least, so I thought), so we don't actually need them. Maybe we do need them and I need to change them all? Or perhaps KOS needs to be updated to not hardcode some things, which will then require overwriting more parameters?

By the way, I explicitly did not mention which register does what regarding screen output because I do not want people going in and messing with those--bad settings can burn out CRTs, and I discovered even some LCDs don't have adequate protection on their VGA inputs from bad signals! That's one of the reasons I made so many modes; hopefully the selection is wide enough that people won't feel the need to "make new ones" and blow something out in the process. However, I do know how to calculate all the VESA parameters and related for everything I made, and that's why I'm requesting anyone please let me know if I need to override more of the KOS parameters instead of going in guns blazing.
nymus wrote:
Thu Feb 20, 2020 8:14 am
I'll take some time to study video rendering/timings/output. It's fun how something previously incomprehensible can become a pleasure to explore when it connects to a personal passion. Your explanations of the timings have made the concepts of back porch, mode lines, blank periods etc much easier to understand and I think I'm slowly putting it all together...
I'm not sure you really need to do that (well, unless you really want to, of course). VESA's standards are freely available from their site, in any case: https://vesa.org/vesa-standards/
I'm sure Aleron Ives feels weird with his postcount back to <10668
:D
User avatar
Moopthehedgehog
DCEmu Freak
DCEmu Freak
Posts: 84
Joined: Wed Jan 05, 2011 4:25 pm
Has liked: 4 times
Been liked: 33 times

Re: High Resolution Dreamcast Video Modes!

Post by Moopthehedgehog » Thu Feb 20, 2020 2:53 pm

Hmm, so apparently KOS assumes RGB565 (16-bit color), potentially in more than just vid_init. So if you set the color mode to FB_RGB565 and use one of the PVR 32x32 resolutions, it may show up properly. If it works, it means something in KOS needs to be changed to allow for the other RGB modes.
I'm sure Aleron Ives feels weird with his postcount back to <10668
:D
nymus
DC Developer
DC Developer
Posts: 959
Joined: Tue Feb 11, 2003 4:12 pm
Location: In a Dream
Has liked: 1 time
Been liked: 2 times

Re: High Resolution Dreamcast Video Modes!

Post by nymus » Sun Feb 23, 2020 3:06 pm

I just wanted to post a better picture.

The 1152x864 and 800x600 rendered correctly whereas the others I tried were just garbled like before. I gave up on trying to figure out the stretching/squishing algorithm because just writing pixels to the screen is a huge task for me.

Not bad looking for a 400x400 stretched bitmap.
dc-1152x864.jpg
behold the mind
inspired by Dreamcast
User avatar
Moopthehedgehog
DCEmu Freak
DCEmu Freak
Posts: 84
Joined: Wed Jan 05, 2011 4:25 pm
Has liked: 4 times
Been liked: 33 times

Re: High Resolution Dreamcast Video Modes!

Post by Moopthehedgehog » Mon Feb 24, 2020 1:50 am

I'm not sure what's difficult about multiplying a texture's horizontal dimension by STARTUP_video_params.video_scale_multiplier; that's all there is to it. There's no fancy algorithm or anything like that. If that doesn't work right, it means my scale might be off by a tiny bit. Sounds like that might be the case.

EDIT: Well, it may also be a good idea to floor (or truncate to int) the output. i.e. scaled_hsize = floor(actual_hsize * STARTUP_video_params.video_scale_multiplier). My math header has some blisteringly fast floor functions that may be useful for this. Or just manually scale the image down on a PC first and load the squished image directly.

The easiest way to check that my scale is wrong is to multiply by h_framebuffer / h_ resolution, so like for 1152x864 PVR 32x32 would be multiplying the horizontal by 384.0f / 1152.0f.
I'm sure Aleron Ives feels weird with his postcount back to <10668
:D
User avatar
Moopthehedgehog
DCEmu Freak
DCEmu Freak
Posts: 84
Joined: Wed Jan 05, 2011 4:25 pm
Has liked: 4 times
Been liked: 33 times

Re: High Resolution Dreamcast Video Modes!

Post by Moopthehedgehog » Mon Feb 24, 2020 3:24 am

Ok, I think I fixed it. Just pushed an update to the DreamHAL repo.
I'm sure Aleron Ives feels weird with his postcount back to <10668
:D
Post Reply