Implement fixed aspect ratio

This commit is contained in:
Jonas Kulla 2013-09-23 10:39:16 +02:00
parent 7a6c05bba0
commit f00136c489
6 changed files with 53 additions and 16 deletions

View File

@ -2,6 +2,7 @@
debugMode=true
winResizable=true
fullscreen=false
fixedAspectRatio=false
vsync=true
defScreenW=640
defScreenH=480

View File

@ -32,6 +32,7 @@ Config::Config()
: debugMode(false),
winResizable(false),
fullscreen(false),
fixedAspectRatio(false),
vsync(false),
defScreenW(640),
defScreenH(480),
@ -48,6 +49,7 @@ void Config::read()
READ_VAL(debugMode, Bool);
READ_VAL(winResizable, Bool);
READ_VAL(fullscreen, Bool);
READ_VAL(fixedAspectRatio, Bool);
READ_VAL(vsync, Bool);
READ_VAL(defScreenW, Int);
READ_VAL(defScreenH, Int);

View File

@ -33,6 +33,7 @@ struct Config
bool winResizable;
bool fullscreen;
bool fixedAspectRatio;
bool vsync;
int defScreenW;

View File

@ -150,6 +150,7 @@ struct RGSSThreadData
SDL_Window *window;
Vec2 sizeResoRatio;
Vec2i screenOffset;
Config config;

View File

@ -451,11 +451,23 @@ struct Timer
struct GraphicsPrivate
{
/* Screen resolution */
/* Screen resolution, ie. the resolution at which
* RGSS renders at (settable with Graphics.width/height).
* Can only be changed from within RGSS */
Vec2i scRes;
/* Actual screen size */
/* Screen size, to which the rendered frames are scaled up.
* This can be smaller than the window size when fixed aspect
* ratio is enforced */
Vec2i scSize;
/* Actual physical size of the game window */
Vec2i winSize;
/* Offset in the game window at which the scaled game screen
* is blitted inside the game window */
Vec2i scOffset;
ScreenScene screen;
RGSSThreadData *threadData;
@ -477,6 +489,7 @@ struct GraphicsPrivate
GraphicsPrivate()
: scRes(640, 480),
scSize(scRes),
winSize(scRes),
screen(scRes.x, scRes.y),
frameRate(40),
frameCount(0),
@ -515,12 +528,38 @@ struct GraphicsPrivate
Vec2 &ratio = gState->rtData().sizeResoRatio;
ratio.x = (float) scRes.x / scSize.x;
ratio.y = (float) scRes.y / scSize.y;
gState->rtData().screenOffset = scOffset;
}
/* Enforces fixed aspect ratio, if desired */
void recalculateScreenSize()
{
scSize = winSize;
if (!gState->config().fixedAspectRatio)
{
scOffset = Vec2i(0, 0);
return;
}
float resRatio = (float) scRes.x / scRes.y;
float winRatio = (float) winSize.x / winSize.y;
if (resRatio > winRatio)
scSize.y = scSize.x / resRatio;
else if (resRatio < winRatio)
scSize.x = scSize.y * resRatio;
scOffset.x = (winSize.x - scSize.x) / 2.f;
scOffset.y = (winSize.y - scSize.y) / 2.f;
}
void checkResize()
{
if (threadData->windowSizeMsg.pollChange(&scSize.x, &scSize.y))
if (threadData->windowSizeMsg.pollChange(&winSize.x, &winSize.y))
{
recalculateScreenSize();
screen.setScreenSize(scSize.x, scSize.y);
updateScreenResoRatio();
}
@ -549,19 +588,10 @@ struct GraphicsPrivate
FBO::blit(0, 0, 0, 0, scRes.x, scRes.y);
}
void blitBuffer()
{
FBO::blit(0, 0, 0, 0, scRes.x, scRes.y);
}
void blitBufferScaled()
{
FBO::blit(0, 0, scRes.x, scRes.y, 0, 0, scSize.x, scSize.y);
}
void blitBufferFlippedScaled()
{
FBO::blit(0, 0, scRes.x, scRes.y, 0, scSize.y, scSize.x, -scSize.y);
FBO::blit(0, 0, scRes.x, scRes.y,
scOffset.x, scSize.y+scOffset.y, scSize.x, -scSize.y);
}
/* Blits currently bound read FBO to screen (upside-down) */

View File

@ -618,12 +618,14 @@ int Input::dir8Value()
int Input::mouseX()
{
return EventThread::mouseState.x * gState->rtData().sizeResoRatio.x;
RGSSThreadData &rtData = gState->rtData();
return (EventThread::mouseState.x - rtData.screenOffset.x) * rtData.sizeResoRatio.x;
}
int Input::mouseY()
{
return EventThread::mouseState.y * gState->rtData().sizeResoRatio.y;
RGSSThreadData &rtData = gState->rtData();
return (EventThread::mouseState.y - rtData.screenOffset.y) * rtData.sizeResoRatio.y;
}
Input::~Input()