[ion/sdl] Use an areaOfInterest

This commit is contained in:
Romain Goyet
2019-02-27 13:43:28 +01:00
parent 22a8683b81
commit 2a62f9b8ec
3 changed files with 63 additions and 44 deletions

View File

@@ -7,6 +7,8 @@ namespace Layout {
#define X(x) ((x)/(1250.0f))
#define Y(y) ((y)/(2100.0f))
constexpr SDL_FRect areaOfInterest = {X(237), Y(83), X(776), Y(1733)};
static SDL_Rect sFrame;
static void makeAbsolute(SDL_FRect * f, SDL_Rect * r) {
@@ -16,18 +18,50 @@ static void makeAbsolute(SDL_FRect * f, SDL_Rect * r) {
r->h = f->h * sFrame.h;
}
void setFrame(SDL_Rect * rect) {
sFrame.x = rect->x;
sFrame.y = rect->y;
sFrame.w = rect->w;
sFrame.h = rect->h;
}
void recompute(int width, int height) {
float windowWidth = static_cast<float>(width);
float windowHeight = static_cast<float>(height);
void getAreaOfInterest(SDL_FRect * fRect) {
fRect->x = X(237);
fRect->y = Y(83);
fRect->w = X(776);
fRect->h = Y(1733);
float aoiRatio = (areaOfInterest.w / areaOfInterest.h) * (1250.0f/2100.0f);
float windowRatio = windowWidth/windowHeight;
if (aoiRatio > windowRatio) {
// Area of interest is wider than the window (e.g. aoe 16:9, window 4:3)
// There will be "black bars" above and below
// We want the areaOfInterest's rect in pixels to be
// aoiInPixels.w = windowWidth
// aoiInPixels.x = 0
// aoiInPixels.h = windowWidth / (aoiRatio*deviceRatio)
// aoiInPixels.y = (windowHeight - aoiInPixels.h)/2;
// But we also know that
// aoiInPixels.x = sFrame.x + areaOfInterest.x*sFrame.w
// aoiInPixels.y = sFrame.y + areaOfInterest.y*sFrame.h
// aoiInPixels.w = sFrame.w * areaOfInterest.w
// aoiInPixels.h = sFrame.h * areaOfInterest*h
sFrame.w = windowWidth / areaOfInterest.w;
sFrame.h = (windowWidth / aoiRatio) / areaOfInterest.h;
sFrame.x = - areaOfInterest.x * sFrame.w;
sFrame.y = (windowHeight - windowWidth/aoiRatio)/2 - areaOfInterest.y * sFrame.h;
} else {
// Area of interest is taller than the window (e.g. window 16:9, aoe 4:3)
// There will be "black bars" on the sides
// We want the areaOfInterest's rect in pixels to be
// aoiInPixels.h = windowHeight
// aoiInPixels.y = 0
// aoiInPixels.x = windowHeight * aoiRatio
// aoiInPixels.w = (windowWidth - aoiInPixels.w)/2;
// But we also know that
// aoiInPixels.x = sFrame.x + areaOfInterest.x*sFrame.w
// aoiInPixels.y = sFrame.y + areaOfInterest.y*sFrame.h
// aoiInPixels.w = sFrame.w * areaOfInterest.w
// aoiInPixels.h = sFrame.h * areaOfInterest*h
sFrame.h = windowHeight / areaOfInterest.h;
sFrame.w = (windowHeight * aoiRatio) / areaOfInterest.w;
sFrame.y = - areaOfInterest.y * sFrame.h;
sFrame.x = (windowWidth - windowHeight*aoiRatio)/2 - areaOfInterest.x * sFrame.w;
}
}
void getScreenRect(SDL_Rect * rect) {
@@ -39,6 +73,13 @@ void getScreenRect(SDL_Rect * rect) {
makeAbsolute(&fRect, rect);
}
void getBackgroundRect(SDL_Rect * rect) {
rect->x = sFrame.x;
rect->y = sFrame.y;
rect->w = sFrame.w;
rect->h = sFrame.h;
}
Keyboard::Key keyAt(SDL_Point * p) {
for (int i=0; i<Keyboard::NumberOfValidKeys; i++) {
SDL_Rect r;

View File

@@ -8,15 +8,14 @@ namespace Ion {
namespace SDL {
namespace Layout {
void setFrame(SDL_Rect * rect);
void getAreaOfInterest(SDL_FRect * fRect);
void recompute(int width, int height);
void getScreenRect(SDL_Rect * rect);
Ion::Keyboard::Key keyAt(SDL_Point * p);
//Ion::Keyboard::Key keyAtF(SDL_FPoint * p);
void getBackgroundRect(SDL_Rect * rect);
void getKeyRect(int validKeyIndex, SDL_Rect * rect);
Ion::Keyboard::Key keyAt(SDL_Point * p);
}
}
}

View File

@@ -27,7 +27,6 @@ namespace Main {
static SDL_Window * sWindow = nullptr;
static SDL_Renderer * sRenderer = nullptr;
static SDL_Texture * sBackgroundTexture = nullptr;
static SDL_Rect sLayoutRect;
void init() {
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
@@ -60,31 +59,11 @@ void relayout() {
int windowWidth = 0;
int windowHeight = 0;
SDL_GetWindowSize(sWindow, &windowWidth, &windowHeight);
Layout::recompute(windowWidth, windowHeight);
SDL_Rect backgroundRect;
Layout::getBackgroundRect(&backgroundRect);
SDL_FRect areaOfInterest;
Layout::getAreaOfInterest(&areaOfInterest);
float aoiRatio = areaOfInterest.w / areaOfInterest.h;
float windowRatio = static_cast<float>(windowWidth)/static_cast<float>(windowHeight);
if (aoiRatio < windowRatio) {
// Area of interest is wider than the window (aoe is 16:9, window is 4:3)
// There will be "black bars" above and below
sLayoutRect.w = static_cast<float>(windowWidth) / areaOfInterest.w;
sLayoutRect.x = - areaOfInterest.x * sLayoutRect.w; // Compensate the
sLayoutRect.h = sLayoutRect.w / windowRatio;
sLayoutRect.y = - areaOfInterest.y * sLayoutRect.h / 2; // Center vertically
} else {
sLayoutRect.h = static_cast<float>(windowHeight) / areaOfInterest.h;
sLayoutRect.y = - areaOfInterest.y * sLayoutRect.h; // Compensate, align left
sLayoutRect.w = sLayoutRect.h * windowRatio;
sLayoutRect.x = - areaOfInterest.x * sLayoutRect.w / 2; // Center horizontally
// Area of interest is taller than the window
}
Layout::setFrame(&sLayoutRect);
SDL_RenderCopy(sRenderer, sBackgroundTexture, nullptr, &sLayoutRect);
SDL_RenderCopy(sRenderer, sBackgroundTexture, nullptr, &backgroundRect);
SDL_RenderPresent(sRenderer);
refresh();
@@ -95,12 +74,12 @@ void relayout() {
void refresh() {
SDL_Rect screenRect;
Layout::getScreenRect(&screenRect);
SDL_Rect backgroundRect;
Layout::getBackgroundRect(&backgroundRect);
SDL_RenderCopy(sRenderer, sBackgroundTexture, nullptr, &sLayoutRect);
SDL_RenderCopy(sRenderer, sBackgroundTexture, nullptr, &backgroundRect);
Display::draw(sRenderer, &screenRect);
SDL_RenderPresent(sRenderer);
//SDL_UpdateWindowSurface(sWindow);
}
}