I apologize in advance for this. This post is a bit of a stream-of-consciousness list of issues I’ve encountered that could be solved with more information from the core.
I use the “database” style so that users don’t need to change parameters for each new game (or change parameters when a game changes modes, in some cases). They just need to pick the system. There are still some issues, though.
For one thing, you need at least three values to derive the chroma phase for a given position:
- Chroma subcarrier cycles per dot (chroma subcarrier clock / dot clock).
- Chroma subcarrier cycles per line.
- Number of lines per frame/field.
(Or some variation of those. For example, you can use the dot clock frequency, hsync frequency, and vsync frequency. Or you can use the active line time, total line time, and frame time. In the end, you need to know information about the position in the line, the line, and the frame/field.)
Even with three values, we’re only really getting the relative phase correct. The phase is shifting by the correct amount but the zeroes are not necessarily in the correct place. Consoles may not even be consistent about this. For example, the NES seems to have 6 (I think?) different initialization states and you don’t know which you’ll get when you turn it on. The relative phase might be good enough, though.
I detect which mode (e.g. 256px or 320px for Genesis) is being used by the width of the original input. Requiring the user to manually select the mode isn’t ideal, first because it is cumbersome to change settings with each game, and second because some games change modes on the fly (especially on consoles like the PSX). Some cores optionally display borders around the image (for Genesis, for example), which has to be accounted for. This works for the most part, but upscaling breaks it. If the core provided the chroma information, this could work even with upscaling. Some systems can switch modes in the middle of a frame or maybe even scanline, which probably isn’t possible to deal with even if we get more info from the cores (although I don’t have an example of this actually occurring).
The NES/SNES are slightly more complicated because of the one skipped dot in one line every odd frame. And even this isn’t always the case. Battletoads on NES, for example, doesn’t do this. There’s no way for us to know which behavior is correct without input from the core or explicit configuration by the user.
The PCEngine is another issue, because developers could choose whether the frame should be 262 lines or 263, and this leads to different artifacts. 263 looks much better. Again, there’s no way for us to know which is correct without input from the core or explicit configuration by the user.
Regarding interlacing, the pause trick can work but is cumbersome for games that switch back and forth (some games use interlacing for the menus, for example). It would be nice to know if we are supposed to be displaying an odd field or an even field.
Ultimately, I don’t expect to actually get these parameters. It seems like it would be quite a bit of work and would require buy-in from all the relevant core maintainers. Still, it is good to know what our limitations are.