Add lastMileScaling, fix bugs, and expose options to MRI
This commit is contained in:
		
							parent
							
								
									fb16c8e6d0
								
							
						
					
					
						commit
						bfe889f00a
					
				
					 6 changed files with 130 additions and 24 deletions
				
			
		| 
						 | 
				
			
			@ -203,6 +203,9 @@ DEF_GRA_PROP_B(Fullscreen)
 | 
			
		|||
DEF_GRA_PROP_B(ShowCursor)
 | 
			
		||||
 | 
			
		||||
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) \
 | 
			
		||||
{ \
 | 
			
		||||
| 
						 | 
				
			
			@ -225,6 +228,9 @@ void graphicsBindingInit()
 | 
			
		|||
	INIT_GRA_PROP_BIND( FrameCount, "frame_count" );
 | 
			
		||||
 | 
			
		||||
	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)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -150,6 +150,30 @@
 | 
			
		|||
# 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'
 | 
			
		||||
# (default: executable directory)
 | 
			
		||||
#
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -170,6 +170,8 @@ void Config::read(int argc, char *argv[])
 | 
			
		|||
	PO_DESC(subImageFix, bool, false) \
 | 
			
		||||
	PO_DESC(enableBlitting, bool, true) \
 | 
			
		||||
	PO_DESC(maxTextureSize, int, 0) \
 | 
			
		||||
	PO_DESC(integerScaling.active, bool, false) \
 | 
			
		||||
	PO_DESC(integerScaling.lastMileScaling, bool, true) \
 | 
			
		||||
	PO_DESC(gameFolder, std::string, ".") \
 | 
			
		||||
	PO_DESC(anyAltToggleFS, bool, false) \
 | 
			
		||||
	PO_DESC(enableReset, bool, true) \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,6 +59,12 @@ struct Config
 | 
			
		|||
	bool enableBlitting;
 | 
			
		||||
	int maxTextureSize;
 | 
			
		||||
 | 
			
		||||
	struct
 | 
			
		||||
	{
 | 
			
		||||
		bool active;
 | 
			
		||||
		bool lastMileScaling;
 | 
			
		||||
	} integerScaling;
 | 
			
		||||
 | 
			
		||||
	std::string gameFolder;
 | 
			
		||||
	bool anyAltToggleFS;
 | 
			
		||||
	bool enableReset;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										113
									
								
								src/graphics.cpp
									
										
									
									
									
								
							
							
						
						
									
										113
									
								
								src/graphics.cpp
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -480,7 +480,7 @@ struct GraphicsPrivate
 | 
			
		|||
	Vec2i integerScaleFactor;
 | 
			
		||||
	TEXFBO integerScaleBuffer;
 | 
			
		||||
	bool integerScaleActive;
 | 
			
		||||
	bool integerScaleFixedAspectRatio;
 | 
			
		||||
	bool integerLastMileScaling;
 | 
			
		||||
 | 
			
		||||
	/* Global list of all live Disposables
 | 
			
		||||
	 * (disposed on reset) */
 | 
			
		||||
| 
						 | 
				
			
			@ -499,22 +499,22 @@ struct GraphicsPrivate
 | 
			
		|||
	      fpsLimiter(frameRate),
 | 
			
		||||
	      frozen(false),
 | 
			
		||||
	      integerScaleFactor(0, 0),
 | 
			
		||||
	      integerScaleActive(true),
 | 
			
		||||
	      integerScaleFixedAspectRatio(rtData->config.fixedAspectRatio)
 | 
			
		||||
	      integerScaleActive(rtData->config.integerScaling.active),
 | 
			
		||||
	      integerLastMileScaling(rtData->config.integerScaling.lastMileScaling)
 | 
			
		||||
	{
 | 
			
		||||
		recalculateScreenSize(rtData);
 | 
			
		||||
		updateScreenResoRatio(rtData);
 | 
			
		||||
 | 
			
		||||
		TEXFBO::init(frozenScene);
 | 
			
		||||
		TEXFBO::allocEmpty(frozenScene, scRes.x, scRes.y);
 | 
			
		||||
		TEXFBO::linkFBO(frozenScene);
 | 
			
		||||
 | 
			
		||||
		if (integerScaleActive)
 | 
			
		||||
		{
 | 
			
		||||
			integerScaleFactor = Vec2i(1, 1);
 | 
			
		||||
			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);
 | 
			
		||||
		screenQuad.setTexPosRect(screenRect, screenRect);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -537,16 +537,28 @@ struct GraphicsPrivate
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	/* Enforces fixed aspect ratio, if desired */
 | 
			
		||||
	void recalculateScreenSize(RGSSThreadData *rtData)
 | 
			
		||||
	void recalculateScreenSize(bool fixedAspectRatio)
 | 
			
		||||
	{
 | 
			
		||||
		scSize = winSize;
 | 
			
		||||
 | 
			
		||||
		if (!rtData->config.fixedAspectRatio)
 | 
			
		||||
		if (!fixedAspectRatio && integerLastMileScaling)
 | 
			
		||||
		{
 | 
			
		||||
			scOffset = Vec2i(0, 0);
 | 
			
		||||
			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 winRatio = (float) winSize.x / winSize.y;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -577,7 +589,7 @@ struct GraphicsPrivate
 | 
			
		|||
		Vec2i newScale(findHighestFittingScale(scRes.x, winSize.x),
 | 
			
		||||
		               findHighestFittingScale(scRes.y, winSize.y));
 | 
			
		||||
 | 
			
		||||
		if (integerScaleFixedAspectRatio)
 | 
			
		||||
		if (threadData->config.fixedAspectRatio)
 | 
			
		||||
		{
 | 
			
		||||
			/* Limit both factors to the smaller of the two */
 | 
			
		||||
			newScale.x = newScale.y = std::min(newScale.x, newScale.y);
 | 
			
		||||
| 
						 | 
				
			
			@ -587,7 +599,6 @@ struct GraphicsPrivate
 | 
			
		|||
			return false;
 | 
			
		||||
 | 
			
		||||
		integerScaleFactor = newScale;
 | 
			
		||||
		Debug() << "Found new scale:" << newScale.x << newScale.y;
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -598,8 +609,6 @@ struct GraphicsPrivate
 | 
			
		|||
		TEXFBO::allocEmpty(integerScaleBuffer, scRes.x * integerScaleFactor.x,
 | 
			
		||||
		                                       scRes.y * integerScaleFactor.y);
 | 
			
		||||
		TEXFBO::linkFBO(integerScaleBuffer);
 | 
			
		||||
 | 
			
		||||
		Debug() << "New buffer size:" << integerScaleBuffer.width << integerScaleBuffer.height;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool integerScaleStepApplicable() const
 | 
			
		||||
| 
						 | 
				
			
			@ -619,17 +628,18 @@ struct GraphicsPrivate
 | 
			
		|||
		{
 | 
			
		||||
			/* Query the acutal size in pixels, not units */
 | 
			
		||||
			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 */
 | 
			
		||||
			glState.viewport.refresh();
 | 
			
		||||
			recalculateScreenSize(threadData);
 | 
			
		||||
			updateScreenResoRatio(threadData);
 | 
			
		||||
 | 
			
		||||
			if (integerScaleActive)
 | 
			
		||||
				if (findHighestIntegerScale())
 | 
			
		||||
					rebuildIntegerScaleBuffer();
 | 
			
		||||
 | 
			
		||||
			SDL_Rect screen = { scOffset.x, scOffset.y, scSize.x, scSize.y };
 | 
			
		||||
			threadData->ethread->notifyGameScreenChange(screen);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -680,17 +690,31 @@ struct GraphicsPrivate
 | 
			
		|||
		metaBlitBufferFlippedScaled(scRes);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void metaBlitBufferFlippedScaled(const Vec2i &sourceSize)
 | 
			
		||||
	void metaBlitBufferFlippedScaled(const Vec2i &sourceSize, bool forceNearestNeighbour = false)
 | 
			
		||||
	{
 | 
			
		||||
		GLMeta::blitRectangle(IntRect(0, 0, sourceSize.x, sourceSize.y),
 | 
			
		||||
		                      IntRect(scOffset.x, scSize.y+scOffset.y, scSize.x, -scSize.y),
 | 
			
		||||
		                      threadData->config.smoothScaling);
 | 
			
		||||
		                      !forceNearestNeighbour && threadData->config.smoothScaling);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void redrawScreen()
 | 
			
		||||
	{
 | 
			
		||||
		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())
 | 
			
		||||
		{
 | 
			
		||||
			assert(integerScaleBuffer.tex != TEX::ID(0));
 | 
			
		||||
| 
						 | 
				
			
			@ -1133,7 +1157,48 @@ bool Graphics::getFixedAspectRatio() const
 | 
			
		|||
void Graphics::setFixedAspectRatio(bool 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,6 +63,9 @@ public:
 | 
			
		|||
	DECL_ATTR( ShowCursor, bool )
 | 
			
		||||
 | 
			
		||||
	DECL_ATTR( FixedAspectRatio, bool )
 | 
			
		||||
	DECL_ATTR( SmoothScaling, bool )
 | 
			
		||||
	DECL_ATTR( IntegerScaling, bool )
 | 
			
		||||
	DECL_ATTR( LastMileScaling, bool )
 | 
			
		||||
 | 
			
		||||
	/* <internal> */
 | 
			
		||||
	Scene *getScreen() const;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue