Add lastMileScaling, fix bugs, and expose options to MRI
This commit is contained in:
parent
fb16c8e6d0
commit
bfe889f00a
|
@ -203,6 +203,9 @@ DEF_GRA_PROP_B(Fullscreen)
|
||||||
DEF_GRA_PROP_B(ShowCursor)
|
DEF_GRA_PROP_B(ShowCursor)
|
||||||
|
|
||||||
DEF_GRA_PROP_B(FixedAspectRatio)
|
DEF_GRA_PROP_B(FixedAspectRatio)
|
||||||
|
DEF_GRA_PROP_B(SmoothScaling)
|
||||||
|
DEF_GRA_PROP_B(IntegerScaling)
|
||||||
|
DEF_GRA_PROP_B(LastMileScaling)
|
||||||
|
|
||||||
#define INIT_GRA_PROP_BIND(PropName, prop_name_s) \
|
#define INIT_GRA_PROP_BIND(PropName, prop_name_s) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -225,6 +228,9 @@ void graphicsBindingInit()
|
||||||
INIT_GRA_PROP_BIND( FrameCount, "frame_count" );
|
INIT_GRA_PROP_BIND( FrameCount, "frame_count" );
|
||||||
|
|
||||||
INIT_GRA_PROP_BIND( FixedAspectRatio, "fixed_aspect_ratio" );
|
INIT_GRA_PROP_BIND( FixedAspectRatio, "fixed_aspect_ratio" );
|
||||||
|
INIT_GRA_PROP_BIND( SmoothScaling, "smooth_scaling" );
|
||||||
|
INIT_GRA_PROP_BIND( IntegerScaling, "integer_scaling" );
|
||||||
|
INIT_GRA_PROP_BIND( LastMileScaling, "last_mile_scaling" );
|
||||||
|
|
||||||
if (rgssVer >= 2)
|
if (rgssVer >= 2)
|
||||||
{
|
{
|
||||||
|
|
|
@ -150,6 +150,30 @@
|
||||||
# maxTextureSize=0
|
# maxTextureSize=0
|
||||||
|
|
||||||
|
|
||||||
|
# Scale up the game screen by an integer amount,
|
||||||
|
# as large as the current window size allows, before
|
||||||
|
# doing any last additional scalings to fill part or
|
||||||
|
# all of the remaining window space (or none at all
|
||||||
|
# if lastMileScaling is disabled).
|
||||||
|
# If fixedAspectRatio is disabled, the integer scale
|
||||||
|
# factors in horizontal and vertical direction can differ
|
||||||
|
# depending on how much space is available, otherwise
|
||||||
|
# they are forced to the smaller of the two.
|
||||||
|
# (default: disabled)
|
||||||
|
#
|
||||||
|
# integerScaling.active = false
|
||||||
|
|
||||||
|
|
||||||
|
# When integer scaling is enabled, this option controls
|
||||||
|
# whether the scaled game screen is further scaled
|
||||||
|
# (with linear interpolation when smoothScaling is enabled)
|
||||||
|
# to fill the rest of the game window.
|
||||||
|
# Note that this option still respects fixedAspectRatio.
|
||||||
|
# (default: enabled)
|
||||||
|
#
|
||||||
|
# integerScaling.lastMileScaling = true
|
||||||
|
|
||||||
|
|
||||||
# Set the base path of the game to '/path/to/game'
|
# Set the base path of the game to '/path/to/game'
|
||||||
# (default: executable directory)
|
# (default: executable directory)
|
||||||
#
|
#
|
||||||
|
|
|
@ -170,6 +170,8 @@ void Config::read(int argc, char *argv[])
|
||||||
PO_DESC(subImageFix, bool, false) \
|
PO_DESC(subImageFix, bool, false) \
|
||||||
PO_DESC(enableBlitting, bool, true) \
|
PO_DESC(enableBlitting, bool, true) \
|
||||||
PO_DESC(maxTextureSize, int, 0) \
|
PO_DESC(maxTextureSize, int, 0) \
|
||||||
|
PO_DESC(integerScaling.active, bool, false) \
|
||||||
|
PO_DESC(integerScaling.lastMileScaling, bool, true) \
|
||||||
PO_DESC(gameFolder, std::string, ".") \
|
PO_DESC(gameFolder, std::string, ".") \
|
||||||
PO_DESC(anyAltToggleFS, bool, false) \
|
PO_DESC(anyAltToggleFS, bool, false) \
|
||||||
PO_DESC(enableReset, bool, true) \
|
PO_DESC(enableReset, bool, true) \
|
||||||
|
|
|
@ -59,6 +59,12 @@ struct Config
|
||||||
bool enableBlitting;
|
bool enableBlitting;
|
||||||
int maxTextureSize;
|
int maxTextureSize;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
bool active;
|
||||||
|
bool lastMileScaling;
|
||||||
|
} integerScaling;
|
||||||
|
|
||||||
std::string gameFolder;
|
std::string gameFolder;
|
||||||
bool anyAltToggleFS;
|
bool anyAltToggleFS;
|
||||||
bool enableReset;
|
bool enableReset;
|
||||||
|
|
113
src/graphics.cpp
113
src/graphics.cpp
|
@ -480,7 +480,7 @@ struct GraphicsPrivate
|
||||||
Vec2i integerScaleFactor;
|
Vec2i integerScaleFactor;
|
||||||
TEXFBO integerScaleBuffer;
|
TEXFBO integerScaleBuffer;
|
||||||
bool integerScaleActive;
|
bool integerScaleActive;
|
||||||
bool integerScaleFixedAspectRatio;
|
bool integerLastMileScaling;
|
||||||
|
|
||||||
/* Global list of all live Disposables
|
/* Global list of all live Disposables
|
||||||
* (disposed on reset) */
|
* (disposed on reset) */
|
||||||
|
@ -499,22 +499,22 @@ struct GraphicsPrivate
|
||||||
fpsLimiter(frameRate),
|
fpsLimiter(frameRate),
|
||||||
frozen(false),
|
frozen(false),
|
||||||
integerScaleFactor(0, 0),
|
integerScaleFactor(0, 0),
|
||||||
integerScaleActive(true),
|
integerScaleActive(rtData->config.integerScaling.active),
|
||||||
integerScaleFixedAspectRatio(rtData->config.fixedAspectRatio)
|
integerLastMileScaling(rtData->config.integerScaling.lastMileScaling)
|
||||||
{
|
{
|
||||||
recalculateScreenSize(rtData);
|
|
||||||
updateScreenResoRatio(rtData);
|
|
||||||
|
|
||||||
TEXFBO::init(frozenScene);
|
|
||||||
TEXFBO::allocEmpty(frozenScene, scRes.x, scRes.y);
|
|
||||||
TEXFBO::linkFBO(frozenScene);
|
|
||||||
|
|
||||||
if (integerScaleActive)
|
if (integerScaleActive)
|
||||||
{
|
{
|
||||||
integerScaleFactor = Vec2i(1, 1);
|
integerScaleFactor = Vec2i(1, 1);
|
||||||
rebuildIntegerScaleBuffer();
|
rebuildIntegerScaleBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recalculateScreenSize(rtData->config.fixedAspectRatio);
|
||||||
|
updateScreenResoRatio(rtData);
|
||||||
|
|
||||||
|
TEXFBO::init(frozenScene);
|
||||||
|
TEXFBO::allocEmpty(frozenScene, scRes.x, scRes.y);
|
||||||
|
TEXFBO::linkFBO(frozenScene);
|
||||||
|
|
||||||
FloatRect screenRect(0, 0, scRes.x, scRes.y);
|
FloatRect screenRect(0, 0, scRes.x, scRes.y);
|
||||||
screenQuad.setTexPosRect(screenRect, screenRect);
|
screenQuad.setTexPosRect(screenRect, screenRect);
|
||||||
|
|
||||||
|
@ -537,16 +537,28 @@ struct GraphicsPrivate
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enforces fixed aspect ratio, if desired */
|
/* Enforces fixed aspect ratio, if desired */
|
||||||
void recalculateScreenSize(RGSSThreadData *rtData)
|
void recalculateScreenSize(bool fixedAspectRatio)
|
||||||
{
|
{
|
||||||
scSize = winSize;
|
scSize = winSize;
|
||||||
|
|
||||||
if (!rtData->config.fixedAspectRatio)
|
if (!fixedAspectRatio && integerLastMileScaling)
|
||||||
{
|
{
|
||||||
scOffset = Vec2i(0, 0);
|
scOffset = Vec2i(0, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Last mile scaling disabled: just center the integer scale buffer
|
||||||
|
* inside the window space */
|
||||||
|
if (integerScaleActive && !integerLastMileScaling)
|
||||||
|
{
|
||||||
|
scOffset.x = (winSize.x - scRes.x * integerScaleFactor.x) / 2;
|
||||||
|
scOffset.y = (winSize.y - scRes.y * integerScaleFactor.y) / 2;
|
||||||
|
|
||||||
|
scSize = Vec2i(scRes.x * integerScaleFactor.x, scRes.y * integerScaleFactor.y);
|
||||||
|
Debug() << scOffset.x << scOffset.y << winSize.x << winSize.y << integerScaleFactor.x << integerScaleFactor.y;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
float resRatio = (float) scRes.x / scRes.y;
|
float resRatio = (float) scRes.x / scRes.y;
|
||||||
float winRatio = (float) winSize.x / winSize.y;
|
float winRatio = (float) winSize.x / winSize.y;
|
||||||
|
|
||||||
|
@ -577,7 +589,7 @@ struct GraphicsPrivate
|
||||||
Vec2i newScale(findHighestFittingScale(scRes.x, winSize.x),
|
Vec2i newScale(findHighestFittingScale(scRes.x, winSize.x),
|
||||||
findHighestFittingScale(scRes.y, winSize.y));
|
findHighestFittingScale(scRes.y, winSize.y));
|
||||||
|
|
||||||
if (integerScaleFixedAspectRatio)
|
if (threadData->config.fixedAspectRatio)
|
||||||
{
|
{
|
||||||
/* Limit both factors to the smaller of the two */
|
/* Limit both factors to the smaller of the two */
|
||||||
newScale.x = newScale.y = std::min(newScale.x, newScale.y);
|
newScale.x = newScale.y = std::min(newScale.x, newScale.y);
|
||||||
|
@ -587,7 +599,6 @@ struct GraphicsPrivate
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
integerScaleFactor = newScale;
|
integerScaleFactor = newScale;
|
||||||
Debug() << "Found new scale:" << newScale.x << newScale.y;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -598,8 +609,6 @@ struct GraphicsPrivate
|
||||||
TEXFBO::allocEmpty(integerScaleBuffer, scRes.x * integerScaleFactor.x,
|
TEXFBO::allocEmpty(integerScaleBuffer, scRes.x * integerScaleFactor.x,
|
||||||
scRes.y * integerScaleFactor.y);
|
scRes.y * integerScaleFactor.y);
|
||||||
TEXFBO::linkFBO(integerScaleBuffer);
|
TEXFBO::linkFBO(integerScaleBuffer);
|
||||||
|
|
||||||
Debug() << "New buffer size:" << integerScaleBuffer.width << integerScaleBuffer.height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool integerScaleStepApplicable() const
|
bool integerScaleStepApplicable() const
|
||||||
|
@ -619,17 +628,18 @@ struct GraphicsPrivate
|
||||||
{
|
{
|
||||||
/* Query the acutal size in pixels, not units */
|
/* Query the acutal size in pixels, not units */
|
||||||
SDL_GL_GetDrawableSize(threadData->window, &winSize.x, &winSize.y);
|
SDL_GL_GetDrawableSize(threadData->window, &winSize.x, &winSize.y);
|
||||||
Debug() << "Reported GL drawable size:" << winSize.x << winSize.y;
|
|
||||||
|
/* Make sure integer buffers are rebuilt before screen offsets are
|
||||||
|
* calculated so we have the final allocated buffer size ready */
|
||||||
|
if (integerScaleActive)
|
||||||
|
if (findHighestIntegerScale())
|
||||||
|
rebuildIntegerScaleBuffer();
|
||||||
|
|
||||||
/* some GL drivers change the viewport on window resize */
|
/* some GL drivers change the viewport on window resize */
|
||||||
glState.viewport.refresh();
|
glState.viewport.refresh();
|
||||||
recalculateScreenSize(threadData);
|
recalculateScreenSize(threadData);
|
||||||
updateScreenResoRatio(threadData);
|
updateScreenResoRatio(threadData);
|
||||||
|
|
||||||
if (integerScaleActive)
|
|
||||||
if (findHighestIntegerScale())
|
|
||||||
rebuildIntegerScaleBuffer();
|
|
||||||
|
|
||||||
SDL_Rect screen = { scOffset.x, scOffset.y, scSize.x, scSize.y };
|
SDL_Rect screen = { scOffset.x, scOffset.y, scSize.x, scSize.y };
|
||||||
threadData->ethread->notifyGameScreenChange(screen);
|
threadData->ethread->notifyGameScreenChange(screen);
|
||||||
}
|
}
|
||||||
|
@ -680,17 +690,31 @@ struct GraphicsPrivate
|
||||||
metaBlitBufferFlippedScaled(scRes);
|
metaBlitBufferFlippedScaled(scRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void metaBlitBufferFlippedScaled(const Vec2i &sourceSize)
|
void metaBlitBufferFlippedScaled(const Vec2i &sourceSize, bool forceNearestNeighbour = false)
|
||||||
{
|
{
|
||||||
GLMeta::blitRectangle(IntRect(0, 0, sourceSize.x, sourceSize.y),
|
GLMeta::blitRectangle(IntRect(0, 0, sourceSize.x, sourceSize.y),
|
||||||
IntRect(scOffset.x, scSize.y+scOffset.y, scSize.x, -scSize.y),
|
IntRect(scOffset.x, scSize.y+scOffset.y, scSize.x, -scSize.y),
|
||||||
threadData->config.smoothScaling);
|
!forceNearestNeighbour && threadData->config.smoothScaling);
|
||||||
}
|
}
|
||||||
|
|
||||||
void redrawScreen()
|
void redrawScreen()
|
||||||
{
|
{
|
||||||
screen.composite();
|
screen.composite();
|
||||||
|
|
||||||
|
// maybe unspaghetti this later
|
||||||
|
if (integerScaleStepApplicable() && !integerLastMileScaling)
|
||||||
|
{
|
||||||
|
GLMeta::blitBeginScreen(winSize);
|
||||||
|
GLMeta::blitSource(screen.getPP().frontBuffer());
|
||||||
|
|
||||||
|
FBO::clear();
|
||||||
|
metaBlitBufferFlippedScaled(scRes, true);
|
||||||
|
GLMeta::blitEnd();
|
||||||
|
|
||||||
|
swapGLBuffer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (integerScaleStepApplicable())
|
if (integerScaleStepApplicable())
|
||||||
{
|
{
|
||||||
assert(integerScaleBuffer.tex != TEX::ID(0));
|
assert(integerScaleBuffer.tex != TEX::ID(0));
|
||||||
|
@ -1133,7 +1157,48 @@ bool Graphics::getFixedAspectRatio() const
|
||||||
void Graphics::setFixedAspectRatio(bool value)
|
void Graphics::setFixedAspectRatio(bool value)
|
||||||
{
|
{
|
||||||
shState->config().fixedAspectRatio = value;
|
shState->config().fixedAspectRatio = value;
|
||||||
p->recalculateScreenSize(p->threadData);
|
p->findHighestIntegerScale();
|
||||||
|
p->recalculateScreenSize(p->threadData->config.fixedAspectRatio);
|
||||||
|
p->updateScreenResoRatio(p->threadData);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Graphics::getSmoothScaling() const
|
||||||
|
{
|
||||||
|
// Same deal as with fixed aspect ratio
|
||||||
|
return shState->config().smoothScaling;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graphics::setSmoothScaling(bool value)
|
||||||
|
{
|
||||||
|
shState->config().smoothScaling = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Graphics::getIntegerScaling() const
|
||||||
|
{
|
||||||
|
return p->integerScaleActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graphics::setIntegerScaling(bool value)
|
||||||
|
{
|
||||||
|
p->integerScaleActive = value;
|
||||||
|
|
||||||
|
p->findHighestIntegerScale();
|
||||||
|
p->rebuildIntegerScaleBuffer();
|
||||||
|
|
||||||
|
p->recalculateScreenSize(p->threadData->config.fixedAspectRatio);
|
||||||
|
p->updateScreenResoRatio(p->threadData);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Graphics::getLastMileScaling() const
|
||||||
|
{
|
||||||
|
return p->integerLastMileScaling;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graphics::setLastMileScaling(bool value)
|
||||||
|
{
|
||||||
|
p->integerLastMileScaling = value;
|
||||||
|
|
||||||
|
p->recalculateScreenSize(p->threadData->config.fixedAspectRatio);
|
||||||
p->updateScreenResoRatio(p->threadData);
|
p->updateScreenResoRatio(p->threadData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,9 @@ public:
|
||||||
DECL_ATTR( ShowCursor, bool )
|
DECL_ATTR( ShowCursor, bool )
|
||||||
|
|
||||||
DECL_ATTR( FixedAspectRatio, bool )
|
DECL_ATTR( FixedAspectRatio, bool )
|
||||||
|
DECL_ATTR( SmoothScaling, bool )
|
||||||
|
DECL_ATTR( IntegerScaling, bool )
|
||||||
|
DECL_ATTR( LastMileScaling, bool )
|
||||||
|
|
||||||
/* <internal> */
|
/* <internal> */
|
||||||
Scene *getScreen() const;
|
Scene *getScreen() const;
|
||||||
|
|
Loading…
Reference in New Issue