Arisotura / blargSnes

SNES emulator for the 3DS.
193 stars 33 forks source link

More accurate scaling options. #24

Open vaguerant opened 8 years ago

vaguerant commented 8 years ago

Some of the scaling settings currently are a bit iffy and there's one or two additional ones I'd like to see, but I'm too incompetent to make a PR, so here's an issue instead; my apologies.

First up, 4:3.

case 3: // 4:3
            x1 = 0.0f; x2 = 240.0f;
            y1 = 40.0f; y2 = 360.0f;
            break;

This doesn't make sense based on the way the SNES video signal works. When games are running in 224-line mode, there are still 240 lines in the video signal being output by the SNES, it's just that the first and last eight are left blank. To scale the 224-line picture to 4:3 means scaling it vertically when a TV would have instead displayed 4:something-slightly-less-than-3-with-letterboxes-padding-out-the-area-to-3 (or more accurately, the letterboxes would have been in overscan). I mean, maybe some users manually calibrated their TVs to fit the 256*224 picture but then they would have lost a big chunk of 239-line games.

How 4:3 should look instead:

case 3: // 4:3
if (SNES_Status->ScreenHeight == 239)
            {
                x1 = 1.0f; x2 = 240.0f;
            }
            else
            {
                x1 = 8.0f; x2 = 232.0f;
            }
            y1 = 40.0f; y2 = 360.0f;
            break;

Otherwise, if you're attached to the idea of the 224-line picture calibrated to fill the TV screen (current 4:3), I think it'd make sense for this to be added as a sort of "4:3 Letterbox" scalemode--although the letterbox will only appear when running 224-line games so the name might be considered a bit sketchy.

I really, really, really very much do not understand how Cropped 4:3 works. Again though, it seems weird to crop the 224-line mode as if that's the full image. It would be more correct to crop if running 239 lines but leave uncropped (i.e. "cropping the letterbox") if running 224 lines. I seriously don't understand the math going on here and stuff, but here's the current Cropped 4:3:

case 4: // cropped 4:3
            {
                float bigy = ((float)SNES_Status->ScreenHeight * 240.0f) / (float)(SNES_Status->ScreenHeight-16);
                float margin = (bigy - 240.0f) / 2.0f;
                x1 = -margin; x2 = 240.0f+margin;
                y1 = 29.0f; y2 = 371.0f;
            }
            break;

And I think what makes more sense to me is Cropped 4:3 where only 239-line mode is cropped using the following. The code here is probably all messed up; as is clear by now, I don't know what I'm doing.

case 4: // cropped 4:3
if (SNES_Status->ScreenHeight == 239)
            {
                float bigy = ((float)SNES_Status->ScreenHeight * 240.0f) / (float)(SNES_Status->ScreenHeight-16);
                float margin = (bigy - 240.0f) / 2.0f;
                x1 = -margin; x2 = 240.0f+margin;
            }
            else
            {
                x1 = 1.0f; x2 = 240.0f;
            }
                y1 = 29.0f; y2 = 371.0f;
            break;

Getting toward the end, an additional scalemode I'd like to see is 8:7 PAR Letterbox:

case 5: // 8:7 par letterbox
if (SNES_Status->ScreenHeight == 239)
            {
                x1 = 1.0f; x2 = 240.0f;
            }
            else
            {
                x1 = 8.0f; x2 = 232.0f;
            }
            y1 = 54.0f; y2 = 346.0f;
break;

This is based on the dot clock rate for the SNES as documented on PinEight. The SNES should have pixels 8:7, which this does with its 292*ScreenHeight display, with my example here using the same letterboxing as I suggested in 4:3. To round things out, I'll do a version of the 8:7 PAR scaling that's rigged up to fill the full screen height. Personally I don't give a damn about this mode but maybe somebody wants full-height 8:7 display.

8:7 PAR Full-Height:

case 6: // 8:7 par fullheight
if (SNES_Status->ScreenHeight == 239)
            {
                x1 = 1.0f; x2 = 240.0f;
                y1 = 54.0f; y2 = 346.0f;
            }
            else
            {
                x1 = 1.0f; x2 = 240.0f;
                y1 = 44.0f; y2 = 356.0f;
            }
break;

More apologies if I horribly screwed these up. I hope they're still sensible or if not that what I was intending can still be gleaned from them. Basically the information I want to get across is: there are 240 lines even in 224 line mode on SNES so those extra 16 lines should be factored into any scaling operation, and SNES pixels are canonically shaped 8:7.

Thanks for your time, sorry for the nonsense.