saturn resolution management modes now work like psx
This commit is contained in:
parent
2a15502999
commit
85cf6e80cd
|
@ -171,6 +171,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
|
|||
|
||||
_core.SetControllerData(_controllerDeck.Poll(controller));
|
||||
|
||||
SetVideoParameters();
|
||||
|
||||
return new LibSaturnus.FrameInfo { ResetPushed = controller.IsPressed("Reset") ? 1 : 0 };
|
||||
}
|
||||
|
||||
|
@ -180,9 +182,22 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
|
|||
|
||||
public class Settings
|
||||
{
|
||||
// extern bool setting_ss_correct_aspect;
|
||||
[DefaultValue(true)]
|
||||
public bool CorrectAspectRatio { get; set; }
|
||||
public enum ResolutionModeTypes
|
||||
{
|
||||
[Display(Name = "Pixel Pro")]
|
||||
PixelPro,
|
||||
[Display(Name = "Hardcode Debug")]
|
||||
HardcoreDebug,
|
||||
[Display(Name = "Mednafen (5:4 AR)")]
|
||||
Mednafen,
|
||||
[Display(Name = "Tweaked Mednafen (5:4 AR)")]
|
||||
TweakedMednafen,
|
||||
}
|
||||
|
||||
[DisplayName("Resolution Mode")]
|
||||
[DefaultValue(ResolutionModeTypes.PixelPro)]
|
||||
[Description("Method for managing varying resolutions")]
|
||||
public ResolutionModeTypes ResolutionMode { get; set; }
|
||||
|
||||
// extern bool setting_ss_h_blend;
|
||||
[DisplayName("Horizontal Blend")]
|
||||
|
@ -425,9 +440,12 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
|
|||
{
|
||||
var ret = Settings.NeedsReboot(_settings, s);
|
||||
_settings = s;
|
||||
var sls = _isPal ? s.ScanlineStartPal + 16 : s.ScanlineStartNtsc;
|
||||
var sle = _isPal ? s.ScanlineEndPal + 16 : s.ScanlineEndNtsc;
|
||||
_core.SetVideoParameters(s.CorrectAspectRatio, s.HBlend, s.HOverscan, sls, sle);
|
||||
|
||||
|
||||
//todo natt - is this safe? this is now called before every frameadvance
|
||||
//(the correct aspect ratio is no longer an option for other reasons)
|
||||
//_core.SetVideoParameters(s.CorrectAspectRatio, s.HBlend, s.HOverscan, sls, sle);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -443,6 +461,19 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
|
|||
return ret;
|
||||
}
|
||||
|
||||
private void SetVideoParameters()
|
||||
{
|
||||
var s = _settings;
|
||||
var sls = _isPal ? s.ScanlineStartPal + 16 : s.ScanlineStartNtsc;
|
||||
var sle = _isPal ? s.ScanlineEndPal + 16 : s.ScanlineEndNtsc;
|
||||
|
||||
bool correctAspect = true;
|
||||
if (_settings.ResolutionMode == Settings.ResolutionModeTypes.PixelPro)
|
||||
correctAspect = false;
|
||||
|
||||
_core.SetVideoParameters(correctAspect, _settings.HBlend, _settings.HOverscan, sls, sle);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IStatable
|
||||
|
@ -461,6 +492,12 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
|
|||
_nextDiskSignal = reader.ReadBoolean();
|
||||
// any managed pointers that we sent to the core need to be resent now!
|
||||
SetCdCallbacks();
|
||||
|
||||
//todo natt: evaluate the philosophy of this.
|
||||
//i think it's sound: loadstate will replace the last values set by frontend; so this should re-assert them.
|
||||
//or we could make sure values from the frontend are stored in a segment designed with the appropriate waterboxing rules, but that seems tricky...
|
||||
//anyway, in this case, I did it before frameadvance instead, so that's just as good (probably?)
|
||||
//PutSettings(_settings);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -572,33 +609,102 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
|
|||
|
||||
protected override void FrameAdvancePost()
|
||||
{
|
||||
//overkill for constants, but here for future use
|
||||
//TODO: can we force the videoprovider to add a prescale instead of having to do it in software here?
|
||||
//TODO: if not, actually do it in software, instead of relying on the virtual sizes
|
||||
//TODO: find a reason why relying on the virtual sizes is actually not good enough?
|
||||
|
||||
//TODO: export VDP2 display area width from emulator and add option to aggressively crop overscan - OR - add that logic to core
|
||||
|
||||
//mednafen:
|
||||
//takes 320x240 -> 302x240(nominal) --> 1.2583333333333333333333333333333
|
||||
//mednafen, for reference:
|
||||
//if (PAL)
|
||||
//{
|
||||
// gi->nominal_width = (ShowHOverscan ? 365 : 354);
|
||||
// gi->fb_height = 576;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// gi->nominal_width = (ShowHOverscan ? 302 : 292);
|
||||
// gi->fb_height = 480;
|
||||
//}
|
||||
//gi->nominal_height = LineVisLast + 1 - LineVisFirst;
|
||||
//gi->lcm_width = (ShowHOverscan ? 10560 : 10240);
|
||||
//gi->lcm_height = (LineVisLast + 1 - LineVisFirst) * 2;
|
||||
//if (!CorrectAspect)
|
||||
//{
|
||||
// gi->nominal_width = (ShowHOverscan ? 352 : 341);
|
||||
// gi->lcm_width = gi->nominal_width * 2;
|
||||
//}
|
||||
|
||||
//we return 330x240 now. Those are bonus columns so we want a wider AR technically
|
||||
//mednafen crunches 320 to 302 --> 1.0596026490066225165562913907285 ratio
|
||||
//so we take 330 / 1.0596026490066225165562913907285 = 311.43749999999999999999999999999
|
||||
//but we don't actually want to do that; we're optimized for 1x window sizes; lets expand height instead of crunching width
|
||||
//at any rate we have our AR as (330 / (320/302)) / 240 = 1.29765625
|
||||
//let's size up instead.. solve VX/VY = (330 / (320/302)) / 240 for VX=330;
|
||||
//330 / VY = (330 / (320/302)) / 240
|
||||
//330 * 240 / (330 / (320/302)) = VY
|
||||
//330 * 240 * 320 / 330 / 302 = VY
|
||||
//240 * 320 / 302 = VY
|
||||
//254.3 = VY -> Final answer 330x254
|
||||
bool isHorz2x = false, isVert2x = false;
|
||||
|
||||
if (!_isPal && BufferWidth <= 330) // more research will be needed for PAL or other alternate modes
|
||||
//note: these work with PAL also
|
||||
//these are all with CorrectAR.
|
||||
//with IncorrectAR, only 352 and 341 will show up
|
||||
//that is, 330 is forced to 352 so mednafen's presentation can display it pristine no matter what mode it is
|
||||
//(it's mednafen's equivalent of a more debuggish mode, I guess)
|
||||
if (BufferWidth == 352) { } //a large basic framebuffer size
|
||||
else if (BufferWidth == 341) { } //a large basic framebuffer size with overscan cropped
|
||||
else if (BufferWidth == 330) { } //a small basic framebuffer
|
||||
else if (BufferWidth == 320) { } //a small basic framebuffer with overscan cropped
|
||||
else isHorz2x = true;
|
||||
|
||||
int slStart = _isPal ? _settings.ScanlineStartPal : _settings.ScanlineStartNtsc;
|
||||
int slEnd = _isPal ? _settings.ScanlineEndPal : _settings.ScanlineEndNtsc;
|
||||
int slHeight = (slEnd - slStart) + 1;
|
||||
|
||||
if (BufferHeight == slHeight) { }
|
||||
else isVert2x = true;
|
||||
|
||||
switch (_settings.ResolutionMode)
|
||||
{
|
||||
_virtualWidth = BufferWidth;
|
||||
_virtualHeight = BufferHeight * 254 / 240;
|
||||
}
|
||||
else
|
||||
{
|
||||
_virtualWidth = BufferWidth;
|
||||
_virtualHeight = BufferHeight;
|
||||
case Settings.ResolutionModeTypes.HardcoreDebug:
|
||||
_virtualWidth = BufferWidth;
|
||||
_virtualHeight = BufferHeight;
|
||||
break;
|
||||
|
||||
case Settings.ResolutionModeTypes.Mednafen:
|
||||
//this is mednafen's "correct AR" case.
|
||||
//note that this will shrink a width from 330 to 302 (that's the nature of mednafen)
|
||||
//that makes the bios saturn orb get stretched vertically
|
||||
//note: these are never high resolution (use a 2x window size if you want to see high resolution content)
|
||||
if (_isPal)
|
||||
{
|
||||
_virtualWidth = (_settings.HOverscan ? 365 : 354);
|
||||
_virtualHeight = slHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
_virtualWidth = (_settings.HOverscan ? 302 : 292);
|
||||
_virtualHeight = slHeight;
|
||||
}
|
||||
break;
|
||||
|
||||
case Settings.ResolutionModeTypes.TweakedMednafen:
|
||||
//same as mednafen but stretch up
|
||||
//base case is 330x254
|
||||
if (_isPal)
|
||||
{
|
||||
//this can be the same as Mednafen mode? we don't shrink down in any case, so it must be OK
|
||||
_virtualWidth = (_settings.HOverscan ? 365 : 354);
|
||||
_virtualHeight = slHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
//ideally we want a height of 254, but we may have changed the overscan settings
|
||||
_virtualWidth = (_settings.HOverscan ? 330 : 320);
|
||||
_virtualHeight = BufferHeight * 254 / 240;
|
||||
}
|
||||
break;
|
||||
|
||||
case Settings.ResolutionModeTypes.PixelPro:
|
||||
//mednafen makes sure we always get 352 or 341 (if overscan cropped)
|
||||
//really the only thing we do
|
||||
//(that's not the best solution for us [not what psx does], but it will do for now)
|
||||
_virtualWidth = BufferWidth * (isHorz2x ? 1 : 2); //not a mistake, we scale to make it bigger if it isn't already
|
||||
_virtualHeight = BufferHeight * (isVert2x ? 1 : 2); //not a mistake
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue