22 #ifndef BACKENDS_GRAPHICS_WINDOWED_H 23 #define BACKENDS_GRAPHICS_WINDOWED_H 25 #include "backends/graphics/graphics.h" 26 #include "common/frac.h" 27 #include "common/rect.h" 28 #include "common/config-manager.h" 29 #include "common/textconsole.h" 30 #include "graphics/scaler/aspect.h" 35 STRETCH_INTEGRAL_AR = 2,
38 STRETCH_FIT_FORCE_ASPECT = 5
42 SCREEN_ALIGN_CENTER = 0,
43 SCREEN_ALIGN_LEFT = 1,
44 SCREEN_ALIGN_RIGHT = 2,
45 SCREEN_ALIGN_XMASK = 3,
46 SCREEN_ALIGN_MIDDLE = 0,
48 SCREEN_ALIGN_BOTTOM = 8,
49 SCREEN_ALIGN_YMASK = 12
71 void showOverlay(
bool inGUI)
override {
92 void hideOverlay()
override {
108 Common::Rect getSafeOverlayArea(int16 *width, int16 *height)
const override {
121 const int targetWidth = getOverlayWidth(),
122 targetHeight = getOverlayHeight(),
126 if (width) *width = targetWidth;
127 if (height) *height = targetHeight;
129 int rotatedTargetWidth = targetWidth,
130 rotatedTargetHeight = targetHeight;
132 SWAP(rotatedTargetWidth, rotatedTargetHeight);
137 safeArea.top = ((safeArea.top -
_overlayDrawRect.top) * rotatedTargetHeight) / sourceHeight;
139 safeArea.bottom = ((safeArea.bottom -
_overlayDrawRect.top) * rotatedTargetHeight) / sourceHeight;
144 case Common::kRotationNormal:
147 case Common::kRotation90: {
148 int16 tmp = safeArea.
left;
149 safeArea.
left = safeArea.top;
150 safeArea.top = rotatedTargetWidth - safeArea.
right;
152 safeArea.
right = safeArea.bottom;
153 safeArea.bottom = targetHeight - tmp;
156 case Common::kRotation180: {
159 safeArea.
left = rotatedTargetWidth - safeArea.
right;
160 safeArea.
right = rotatedTargetWidth - tmp;
162 safeArea.top = rotatedTargetHeight - safeArea.bottom;
163 safeArea.bottom = rotatedTargetHeight - tmp;
166 case Common::kRotation270: {
167 int16 tmp = safeArea.
left;
168 safeArea.
left = rotatedTargetHeight - safeArea.bottom;
170 safeArea.bottom = safeArea.
right;
171 safeArea.
right = targetWidth - safeArea.top;
180 void setShakePos(
int shakeXOffset,
int shakeYOffset)
override {
192 void setIgnoreGameSafeArea(
bool ignoreGameSafeArea) {
200 if (insets.left == 0 &&
203 insets.bottom == 0) {
236 if (sourceWidth == 0 || sourceHeight == 0) {
237 error(
"convertVirtualToWindow called without a valid draw rect");
240 int windowX, windowY;
243 case Common::kRotationNormal:
244 windowX = targetX + (x * targetWidth + sourceWidth / 2) / sourceWidth;
245 windowY = targetY + (y * targetHeight + sourceHeight / 2) / sourceHeight;
247 case Common::kRotation90:
248 windowX = targetX + ((y - (sourceHeight - 1)) * targetWidth + sourceHeight / 2) / sourceHeight;
249 windowY = targetY + (x * targetHeight + sourceWidth / 2) / sourceWidth;
251 case Common::kRotation180:
252 windowX = targetX + ((x - (sourceWidth - 1)) * targetWidth + sourceWidth / 2) / sourceWidth;
253 windowY = targetY + ((y - (sourceHeight - 1)) * targetHeight + sourceHeight / 2) / sourceHeight;
255 case Common::kRotation270:
256 windowX = targetX + (y * targetWidth + sourceHeight / 2) / sourceHeight;
257 windowY = targetY + ((x - (sourceWidth - 1)) * targetHeight + sourceWidth / 2) / sourceWidth;
261 return Common::Point(CLIP<int>(windowX, targetX, targetX + targetWidth - 1),
262 CLIP<int>(windowY, targetY, targetY + targetHeight - 1));
280 if (sourceWidth == 0 || sourceHeight == 0) {
281 error(
"convertWindowToVirtual called without a valid draw rect");
284 x = CLIP<int>(x, sourceX, sourceMaxX);
285 y = CLIP<int>(y, sourceY, sourceMaxY);
287 int virtualX, virtualY;
290 case Common::kRotationNormal:
291 virtualX = ((x - sourceX) * targetWidth + sourceWidth / 2) / sourceWidth;
292 virtualY = ((y - sourceY) * targetHeight + sourceHeight / 2) / sourceHeight;
294 case Common::kRotation90:
295 virtualY = targetHeight - 1 - ((x - sourceX) * targetHeight + sourceWidth / 2) / sourceWidth;
296 virtualX = ((y - sourceY) * targetWidth + sourceHeight / 2) / sourceHeight;
298 case Common::kRotation180:
299 virtualX = targetWidth - 1 - ((x - sourceX) * targetWidth + sourceWidth / 2) / sourceWidth;
300 virtualY = targetHeight - 1 - ((y - sourceY) * targetHeight + sourceHeight / 2) / sourceHeight;
302 case Common::kRotation270:
303 virtualY = ((x - sourceX) * targetHeight + sourceWidth / 2) / sourceWidth;
304 virtualX = targetWidth - 1 - ((y - sourceY) * targetWidth + sourceHeight / 2) / sourceHeight;
308 return Common::Point(CLIP<int>(virtualX, 0, targetWidth - 1),
309 CLIP<int>(virtualY, 0, targetHeight - 1));
317 return intToFrac(4) / 3;
320 return intToFrac(getWidth()) / getHeight();
371 insets = {0, 0, 0, 0};
384 if (getOverlayHeight()) {
385 const int16 overlayWidth = getOverlayWidth(),
386 overlayHeight = getOverlayHeight();
387 const frac_t overlayAspect = intToFrac(overlayWidth) / overlayHeight;
388 populateDisplayAreaDrawRect(overlayAspect, overlayWidth, overlayHeight,
418 bool showMouse(
bool visible)
override {
439 if (virtualCursor.
x != x || virtualCursor.
y != y) {
461 if (
_cursorX != x || _cursorY != y) {
581 void populateDisplayAreaDrawRect(
const frac_t displayAspect,
int originalWidth,
int originalHeight,
const Common::Rect &safeArea,
Common::Rect &drawRect)
const {
582 int mode = getStretchMode();
588 if (_rotationMode == Common::kRotation90 || _rotationMode == Common::kRotation270) {
589 SWAP(rotatedSafeArea.
left, rotatedSafeArea.top);
590 SWAP(rotatedSafeArea.
right, rotatedSafeArea.bottom);
591 SWAP(rotatedWindowWidth, rotatedWindowHeight);
593 const int rotatedSafeWidth = rotatedSafeArea.
width(),
594 rotatedSafeHeight = rotatedSafeArea.
height();
601 int width = 0, height = 0;
602 if (mode == STRETCH_CENTER || mode == STRETCH_INTEGRAL || mode == STRETCH_INTEGRAL_AR) {
603 width = originalWidth;
604 height = intToFrac(width) / displayAspect;
605 if (width > rotatedSafeWidth || height > rotatedSafeHeight) {
606 int fac = 1 +
MAX((width - 1) / rotatedSafeWidth, (height - 1) / rotatedSafeHeight);
609 }
else if (mode == STRETCH_INTEGRAL) {
610 int fac =
MIN(rotatedSafeWidth / width, rotatedSafeHeight / height);
613 }
else if (mode == STRETCH_INTEGRAL_AR) {
614 int targetHeight = height;
615 int horizontalFac = rotatedSafeWidth / width;
617 width = originalWidth * horizontalFac;
618 int verticalFac = (targetHeight * horizontalFac + originalHeight / 2) / originalHeight;
619 height = originalHeight * verticalFac;
621 }
while (horizontalFac > 0 && height > rotatedSafeHeight);
622 if (height > rotatedSafeHeight)
623 height = targetHeight;
626 frac_t windowAspect = intToFrac(rotatedSafeWidth) / rotatedSafeHeight;
627 width = rotatedSafeWidth;
628 height = rotatedSafeHeight;
629 if (mode == STRETCH_FIT_FORCE_ASPECT) {
630 frac_t ratio = intToFrac(4) / 3;
631 if (windowAspect < ratio)
632 height = intToFrac(width) / ratio;
633 else if (windowAspect > ratio)
634 width = fracToInt(height * ratio);
635 }
else if (mode != STRETCH_STRETCH) {
636 if (windowAspect < displayAspect)
637 height = intToFrac(width) / displayAspect;
638 else if (windowAspect > displayAspect)
639 width = fracToInt(height * displayAspect);
643 int16 alignX, alignY;
644 switch (_screenAlign & SCREEN_ALIGN_XMASK) {
646 case SCREEN_ALIGN_CENTER:
647 alignX = ((rotatedWindowWidth - width) / 2);
649 case SCREEN_ALIGN_LEFT:
652 case SCREEN_ALIGN_RIGHT:
653 alignX = (rotatedSafeArea.
right - width);
657 switch (_screenAlign & SCREEN_ALIGN_YMASK) {
659 case SCREEN_ALIGN_MIDDLE:
660 alignY = ((rotatedWindowHeight - height) / 2);
662 case SCREEN_ALIGN_TOP:
665 case SCREEN_ALIGN_BOTTOM:
666 alignY = (rotatedSafeArea.bottom - height);
670 rotatedSafeArea.
constrain(alignX, alignY, width, height);
672 alignX += _gameScreenShakeXOffset * width / getWidth();
673 alignY += _gameScreenShakeYOffset * height / getHeight();
675 if (_rotationMode == Common::kRotation90 || _rotationMode == Common::kRotation270) {
676 drawRect.top = alignX;
677 drawRect.
left = alignY;
681 drawRect.
left = alignX;
682 drawRect.top = alignY;
int _gameScreenShakeYOffset
Definition: windowed.h:514
T left
Definition: rect.h:170
Common::Point convertVirtualToWindow(const int x, const int y) const
Definition: windowed.h:228
virtual void handleResizeImpl(const int width, const int height)=0
Common::Rect _gameDrawRect
Definition: windowed.h:519
bool _cursorNeedsRedraw
Definition: windowed.h:567
virtual bool gameNeedsAspectRatioCorrection() const =0
int _windowHeight
Definition: windowed.h:477
bool _overlayVisible
Definition: windowed.h:499
int height
Definition: windowed.h:544
void setHeight(T aHeight)
Definition: rect.h:224
int _cursorX
Definition: windowed.h:578
void SWAP(T &a, T &b)
Definition: util.h:84
bool _cursorVisible
Definition: windowed.h:562
void setWidth(T aWidth)
Definition: rect.h:220
T width() const
Definition: rect.h:217
frac_t getDesiredGameAspectRatio() const
Definition: windowed.h:315
Definition: windowed.h:52
bool _overlayInGUI
Definition: windowed.h:504
bool _forceRedraw
Definition: windowed.h:557
virtual Insets getSafeAreaInsets() const
Definition: windowed.h:343
T height() const
Definition: rect.h:218
Common::Rect drawRect
Definition: windowed.h:534
Common::RotationMode _rotationMode
Definition: windowed.h:488
T right
Definition: rect.h:171
int _windowWidth
Definition: windowed.h:472
bool _ignoreGameSafeArea
Definition: windowed.h:493
Common::Point convertWindowToVirtual(int x, int y) const
Definition: windowed.h:270
bool _cursorLastInActiveArea
Definition: windowed.h:573
void handleResize(const int width, const int height)
Definition: windowed.h:353
int width
Definition: windowed.h:539
virtual void recalculateDisplayAreas()
Definition: windowed.h:363
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: windowed.h:530
void setMousePosition(int x, int y)
Definition: windowed.h:460
Definition: graphics.h:38
void warpMouse(int x, int y) override
Definition: windowed.h:435
T MIN(T a, T b)
Definition: util.h:61
DisplayArea _activeArea
Definition: windowed.h:552
Common::Rect _overlayDrawRect
Definition: windowed.h:525
T MAX(T a, T b)
Definition: util.h:64
RotationMode
Definition: rotationmode.h:44
bool constrain(const ConcreteRect &o)
Definition: rect.h:414
virtual void setSystemMousePosition(const int x, const int y)=0
virtual int getGameRenderScale() const
Definition: windowed.h:326
int32 frac_t
Definition: frac.h:52
Definition: windowed.h:330
int _screenAlign
Definition: windowed.h:483
int _gameScreenShakeXOffset
Definition: windowed.h:509
virtual void notifyActiveAreaChanged()
Definition: windowed.h:416