mirror of
https://github.com/Marat-Tanalin/bsnes-mt.git
synced 2024-05-31 18:47:21 -04:00
Support for optional 8:7 PAR instead of 4:3 AR
This commit is contained in:
parent
f7d82b8732
commit
dcdfafdbee
|
@ -18,6 +18,10 @@ static constexpr double defaultAspectX = 4.0,
|
|||
defaultAspectY = 3.0,
|
||||
defaultAspect = defaultAspectX / defaultAspectY;
|
||||
|
||||
static constexpr double par = 8.0 / 7.0,
|
||||
parAspect = par * origWidth / origHeight,
|
||||
parOverAspect = par * origWidth / origOverHeight;
|
||||
|
||||
auto getWidth(bool aspectCorrection) -> uint32_t {
|
||||
return aspectCorrection ? std::round(origHeight * defaultAspect) : origWidth;
|
||||
}
|
||||
|
@ -34,6 +38,10 @@ auto getAspectY(bool showOverscan) -> double {
|
|||
return showOverscan ? defaultAspectY * overscanRatio : defaultAspectY;
|
||||
}
|
||||
|
||||
auto getParAspect(bool showOverscan) -> double {
|
||||
return showOverscan ? parOverAspect : parAspect;
|
||||
}
|
||||
|
||||
auto getHeightForPar1(uint32_t width, uint32_t height) -> uint32_t {
|
||||
return (height == origHeight || height == origOverHeight)
|
||||
? (width == origWidth ? origHeight : origDoubleHeight)
|
||||
|
@ -42,10 +50,13 @@ auto getHeightForPar1(uint32_t width, uint32_t height) -> uint32_t {
|
|||
|
||||
auto calculateScaledSizeScale(
|
||||
uint32_t areaWidth, uint32_t areaHeight,
|
||||
bool aspectCorrection, bool showOverscan
|
||||
bool aspectCorrection, bool showOverscan,
|
||||
bool parInsteadOfAr
|
||||
) -> is::Size
|
||||
{
|
||||
double aspect = aspectCorrection ? defaultAspect : (double)origWidth / origHeight;
|
||||
double aspect = aspectCorrection
|
||||
? (parInsteadOfAr ? parAspect : defaultAspect)
|
||||
: (double)origWidth / origHeight;
|
||||
|
||||
if (showOverscan) {
|
||||
aspect /= overscanRatio;
|
||||
|
@ -76,42 +87,68 @@ auto calculateScaledSizeScale(
|
|||
auto calculateScaledSizeCenter(
|
||||
uint32_t areaWidth, uint32_t areaHeight,
|
||||
uint32_t imageWidth, uint32_t imageHeight,
|
||||
bool aspectCorrection, bool showOverscan
|
||||
bool aspectCorrection, bool showOverscan,
|
||||
bool parInsteadOfAr
|
||||
) -> is::Size
|
||||
{
|
||||
return aspectCorrection
|
||||
? is::calculateSizeCorrectedPerfectY(
|
||||
areaWidth, areaHeight,
|
||||
imageHeight,
|
||||
defaultAspectX, getAspectY(showOverscan)
|
||||
)
|
||||
: is::calculateSize(
|
||||
if (!aspectCorrection) {
|
||||
return is::calculateSize(
|
||||
areaWidth, areaHeight,
|
||||
imageWidth, getHeightForPar1(imageWidth, imageHeight)
|
||||
);
|
||||
}
|
||||
|
||||
double aspectX, aspectY;
|
||||
|
||||
if (parInsteadOfAr) {
|
||||
aspectX = getParAspect(showOverscan);
|
||||
aspectY = 1.0;
|
||||
}
|
||||
else {
|
||||
aspectX = defaultAspectX;
|
||||
aspectY = getAspectY(showOverscan);
|
||||
}
|
||||
|
||||
return is::calculateSizeCorrectedPerfectY(
|
||||
areaWidth, areaHeight,
|
||||
imageHeight,
|
||||
aspectX, aspectY
|
||||
);
|
||||
}
|
||||
|
||||
auto calculateScaledSizePerfect(
|
||||
uint32_t areaWidth, uint32_t areaHeight,
|
||||
uint32_t imageWidth, uint32_t imageHeight,
|
||||
bool aspectCorrection, bool showOverscan
|
||||
bool aspectCorrection, bool showOverscan,
|
||||
bool parInsteadOfAr
|
||||
) -> is::Size
|
||||
{
|
||||
if (aspectCorrection) {
|
||||
return is::calculateSizeCorrected(
|
||||
areaWidth, areaHeight,
|
||||
imageWidth, imageHeight,
|
||||
defaultAspectX, getAspectY(showOverscan)
|
||||
if (!aspectCorrection) {
|
||||
uint32_t imageHeightForPar1 = getHeightForPar1(imageWidth, imageHeight);
|
||||
uint32_t imageOverHeightForPar1 = imageHeightForPar1 == origHeight ? origOverHeight : origDoubleOverHeight;
|
||||
|
||||
return is::calculateSize(
|
||||
areaWidth, areaHeight,
|
||||
imageWidth,
|
||||
showOverscan ? imageOverHeightForPar1 : imageHeightForPar1
|
||||
);
|
||||
}
|
||||
|
||||
uint32_t imageHeightForPar1 = getHeightForPar1(imageWidth, imageHeight);
|
||||
uint32_t imageOverHeightForPar1 = imageHeightForPar1 == origHeight ? origOverHeight : origDoubleOverHeight;
|
||||
double aspectX, aspectY;
|
||||
|
||||
return is::calculateSize(
|
||||
areaWidth, areaHeight,
|
||||
imageWidth,
|
||||
showOverscan ? imageOverHeightForPar1 : imageHeightForPar1
|
||||
if (parInsteadOfAr) {
|
||||
aspectX = getParAspect(showOverscan);
|
||||
aspectY = 1.0;
|
||||
}
|
||||
else {
|
||||
aspectX = defaultAspectX;
|
||||
aspectY = getAspectY(showOverscan);
|
||||
}
|
||||
|
||||
return is::calculateSizeCorrected(
|
||||
areaWidth, areaHeight,
|
||||
imageWidth, imageHeight,
|
||||
aspectX, aspectY
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
#include "integer-scaling/IntegerScaling.h"
|
||||
|
||||
|
@ -17,24 +16,28 @@ auto getWidth(bool aspectCorrection, uint32_t width) -> uint32_t;
|
|||
auto getHeight(bool showOverscan, uint32_t height) -> uint32_t;
|
||||
|
||||
auto getAspectY(bool showOverscan) -> double;
|
||||
auto getParAspect(bool showOverscan) -> double;
|
||||
|
||||
auto getHeightForPar1(uint32_t width, uint32_t height) -> uint32_t;
|
||||
|
||||
auto calculateScaledSizeScale(
|
||||
uint32_t areaWidth, uint32_t areaHeight,
|
||||
bool aspectCorrection, bool showOverscan
|
||||
bool aspectCorrection, bool showOverscan,
|
||||
bool parInsteadOfAr
|
||||
) -> is::Size;
|
||||
|
||||
auto calculateScaledSizeCenter(
|
||||
uint32_t areaWidth, uint32_t areaHeight,
|
||||
uint32_t imageWidth, uint32_t imageHeight,
|
||||
bool aspectCorrection, bool showOverscan
|
||||
bool aspectCorrection, bool showOverscan,
|
||||
bool parInsteadOfAr
|
||||
) -> is::Size;
|
||||
|
||||
auto calculateScaledSizePerfect(
|
||||
uint32_t areaWidth, uint32_t areaHeight,
|
||||
uint32_t imageWidth, uint32_t imageHeight,
|
||||
bool aspectCorrection, bool showOverscan
|
||||
bool aspectCorrection, bool showOverscan,
|
||||
bool parInsteadOfAr
|
||||
) -> is::Size;
|
||||
|
||||
} // namespace bsnesMt::scaling
|
|
@ -53,6 +53,7 @@ Menu.Settings.Output.PixelPerfect = "Pixel-Perfect"
|
|||
Menu.Settings.Output.Scale = "Scale"
|
||||
Menu.Settings.Output.Stretch = "Stretch"
|
||||
Menu.Settings.Output.AspectRatioCorrection = "Aspect-Ratio Correction"
|
||||
Menu.Settings.Output.parInsteadOfAr = "8:7 PAR instead of 4:3 AR"
|
||||
Menu.Settings.Output.ShowOverscanArea = "Show Overscan Area"
|
||||
Menu.Settings.Output.scalingInfo = "Scaling Info in Status Bar"
|
||||
Menu.Settings.Output.HiresBlurEmulation = "Hires Blur Emulation"
|
||||
|
|
|
@ -53,6 +53,7 @@ Menu.Settings.Output.PixelPerfect = "Целочисленное масштаби
|
|||
Menu.Settings.Output.Scale = "Масштабирование с сохранением пропорций"
|
||||
Menu.Settings.Output.Stretch = "Растяжение без сохранения пропорций"
|
||||
Menu.Settings.Output.AspectRatioCorrection = "Коррекция соотношения сторон"
|
||||
Menu.Settings.Output.parInsteadOfAr = "PAR 8:7 вместо AR 4:3"
|
||||
Menu.Settings.Output.ShowOverscanArea = "Показать область «overscan»"
|
||||
Menu.Settings.Output.scalingInfo = "Информация о масштабировании в строке состояния"
|
||||
Menu.Settings.Output.HiresBlurEmulation = "Эмуляция размытия в режиме высокого разрешения"
|
||||
|
|
|
@ -105,6 +105,15 @@ auto Presentation::create() -> void {
|
|||
//resizeWindow(); // Commented-out by MT.
|
||||
});
|
||||
|
||||
/* MT. */
|
||||
parInsteadOfAr.setText(bmt::get("Menu.Settings.Output.parInsteadOfAr").data())
|
||||
.setChecked(settings.video.parInsteadOfAr)
|
||||
.onToggle([&] {
|
||||
settings.video.parInsteadOfAr = parInsteadOfAr.checked();
|
||||
video.clear(); // MT.
|
||||
});
|
||||
/* /MT. */
|
||||
|
||||
showOverscanArea.setText(bmt::get("Menu.Settings.Output.ShowOverscanArea").data())
|
||||
.setChecked(settings.video.overscan)
|
||||
.onToggle([&] {
|
||||
|
|
|
@ -50,6 +50,7 @@ struct Presentation : Window {
|
|||
Group outputGroup{¢erViewport, &perfectViewport, &scaleViewport, &stretchViewport}; // `&perfectViewport,` added by MT.
|
||||
MenuSeparator outputSeparator{&outputMenu};
|
||||
MenuCheckItem aspectCorrection{&outputMenu};
|
||||
MenuCheckItem parInsteadOfAr{&outputMenu};
|
||||
MenuCheckItem showOverscanArea{&outputMenu};
|
||||
MenuCheckItem scalingInfo{&outputMenu}; // MT.
|
||||
MenuCheckItem blurEmulation{&outputMenu};
|
||||
|
|
|
@ -35,13 +35,15 @@ auto Program::viewportSize(uint& scaledWidth, uint& scaledHeight, uint width, ui
|
|||
}
|
||||
|
||||
bool aspectCorrection = settings.video.aspectCorrection,
|
||||
showOverscan = settings.video.overscan;
|
||||
showOverscan = settings.video.overscan,
|
||||
parInsteadOfAr = settings.video.parInsteadOfAr;
|
||||
|
||||
if (outputSetting == "Pixel-Perfect") {
|
||||
auto scaledSize = bmi::calculateScaledSizePerfect(
|
||||
areaWidth, areaHeight,
|
||||
width, height,
|
||||
aspectCorrection, showOverscan
|
||||
aspectCorrection, showOverscan,
|
||||
parInsteadOfAr
|
||||
);
|
||||
|
||||
scaledWidth = scaledSize.width;
|
||||
|
@ -51,7 +53,8 @@ auto Program::viewportSize(uint& scaledWidth, uint& scaledHeight, uint width, ui
|
|||
auto scaledSize = bmi::calculateScaledSizeCenter(
|
||||
areaWidth, areaHeight,
|
||||
width, height,
|
||||
aspectCorrection, showOverscan
|
||||
aspectCorrection, showOverscan,
|
||||
parInsteadOfAr
|
||||
);
|
||||
|
||||
scaledWidth = scaledSize.width;
|
||||
|
@ -60,7 +63,8 @@ auto Program::viewportSize(uint& scaledWidth, uint& scaledHeight, uint width, ui
|
|||
else if (outputSetting == "Scale") {
|
||||
auto scaledSize = bmi::calculateScaledSizeScale(
|
||||
areaWidth, areaHeight,
|
||||
aspectCorrection, showOverscan
|
||||
aspectCorrection, showOverscan,
|
||||
parInsteadOfAr
|
||||
);
|
||||
|
||||
scaledWidth = scaledSize.width;
|
||||
|
|
|
@ -73,6 +73,7 @@ auto Settings::process(bool load) -> void {
|
|||
bind(text, "Video/Output", video.output);
|
||||
bind(natural, "Video/Multiplier", video.multiplier);
|
||||
bind(boolean, "Video/AspectCorrection", video.aspectCorrection);
|
||||
bind(boolean, "Video/ParInsteadOfAr", video.parInsteadOfAr); // MT.
|
||||
bind(boolean, "Video/Overscan", video.overscan);
|
||||
bind(boolean, "Video/ScalingInfo", video.scalingInfo); // MT.
|
||||
bind(boolean, "Video/Blur", video.blur);
|
||||
|
|
|
@ -25,6 +25,7 @@ struct Settings : Markup::Node {
|
|||
string output = "Pixel-Perfect"; // Changed from "Scale" by MT.
|
||||
uint multiplier = 2;
|
||||
bool aspectCorrection = true;
|
||||
bool parInsteadOfAr = false; // MT.
|
||||
bool overscan = false;
|
||||
bool scalingInfo = false; // MT.
|
||||
bool blur = false;
|
||||
|
|
Loading…
Reference in a new issue