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
70 void showOverlay(
bool inGUI)
override {
91 void hideOverlay()
override {
107 Common::Rect getSafeOverlayArea(int16 *width, int16 *height)
const override {
120 const int targetWidth = getOverlayWidth(),
121 targetHeight = getOverlayHeight(),
125 if (width) *width = targetWidth;
126 if (height) *height = targetHeight;
128 int rotatedTargetWidth = targetWidth,
129 rotatedTargetHeight = targetHeight;
131 SWAP(rotatedTargetWidth, rotatedTargetHeight);
136 safeArea.top = ((safeArea.top -
_overlayDrawRect.top) * rotatedTargetHeight) / sourceHeight;
138 safeArea.bottom = ((safeArea.bottom -
_overlayDrawRect.top) * rotatedTargetHeight) / sourceHeight;
143 case Common::kRotationNormal:
146 case Common::kRotation90: {
147 int16 tmp = safeArea.
left;
148 safeArea.
left = safeArea.top;
149 safeArea.top = rotatedTargetWidth - safeArea.
right;
151 safeArea.
right = safeArea.bottom;
152 safeArea.bottom = targetHeight - tmp;
155 case Common::kRotation180: {
158 safeArea.
left = rotatedTargetWidth - safeArea.
right;
159 safeArea.
right = rotatedTargetWidth - tmp;
161 safeArea.top = rotatedTargetHeight - safeArea.bottom;
162 safeArea.bottom = rotatedTargetHeight - tmp;
165 case Common::kRotation270: {
166 int16 tmp = safeArea.
left;
167 safeArea.
left = rotatedTargetHeight - safeArea.bottom;
169 safeArea.bottom = safeArea.
right;
170 safeArea.
right = targetWidth - safeArea.top;
179 void setShakePos(
int shakeXOffset,
int shakeYOffset)
override {
217 if (sourceWidth == 0 || sourceHeight == 0) {
218 error(
"convertVirtualToWindow called without a valid draw rect");
221 int windowX, windowY;
224 case Common::kRotationNormal:
225 windowX = targetX + (x * targetWidth + sourceWidth / 2) / sourceWidth;
226 windowY = targetY + (y * targetHeight + sourceHeight / 2) / sourceHeight;
228 case Common::kRotation90:
229 windowX = targetX + ((y - (sourceHeight - 1)) * targetWidth + sourceHeight / 2) / sourceHeight;
230 windowY = targetY + (x * targetHeight + sourceWidth / 2) / sourceWidth;
232 case Common::kRotation180:
233 windowX = targetX + ((x - (sourceWidth - 1)) * targetWidth + sourceWidth / 2) / sourceWidth;
234 windowY = targetY + ((y - (sourceHeight - 1)) * targetHeight + sourceHeight / 2) / sourceHeight;
236 case Common::kRotation270:
237 windowX = targetX + (y * targetWidth + sourceHeight / 2) / sourceHeight;
238 windowY = targetY + ((x - (sourceWidth - 1)) * targetHeight + sourceWidth / 2) / sourceWidth;
242 return Common::Point(CLIP<int>(windowX, targetX, targetX + targetWidth - 1),
243 CLIP<int>(windowY, targetY, targetY + targetHeight - 1));
261 if (sourceWidth == 0 || sourceHeight == 0) {
262 error(
"convertWindowToVirtual called without a valid draw rect");
265 x = CLIP<int>(x, sourceX, sourceMaxX);
266 y = CLIP<int>(y, sourceY, sourceMaxY);
268 int virtualX, virtualY;
271 case Common::kRotationNormal:
272 virtualX = ((x - sourceX) * targetWidth + sourceWidth / 2) / sourceWidth;
273 virtualY = ((y - sourceY) * targetHeight + sourceHeight / 2) / sourceHeight;
275 case Common::kRotation90:
276 virtualY = targetHeight - 1 - ((x - sourceX) * targetHeight + sourceWidth / 2) / sourceWidth;
277 virtualX = ((y - sourceY) * targetWidth + sourceHeight / 2) / sourceHeight;
279 case Common::kRotation180:
280 virtualX = targetWidth - 1 - ((x - sourceX) * targetWidth + sourceWidth / 2) / sourceWidth;
281 virtualY = targetHeight - 1 - ((y - sourceY) * targetHeight + sourceHeight / 2) / sourceHeight;
283 case Common::kRotation270:
284 virtualY = ((x - sourceX) * targetHeight + sourceWidth / 2) / sourceWidth;
285 virtualX = targetWidth - 1 - ((y - sourceY) * targetWidth + sourceHeight / 2) / sourceHeight;
289 return Common::Point(CLIP<int>(virtualX, 0, targetWidth - 1),
290 CLIP<int>(virtualY, 0, targetHeight - 1));
298 return intToFrac(4) / 3;
301 return intToFrac(getWidth()) / getHeight();
363 if (getOverlayHeight()) {
364 const int16 overlayWidth = getOverlayWidth(),
365 overlayHeight = getOverlayHeight();
366 const frac_t overlayAspect = intToFrac(overlayWidth) / overlayHeight;
367 populateDisplayAreaDrawRect(overlayAspect, overlayWidth, overlayHeight,
397 bool showMouse(
bool visible)
override {
418 if (virtualCursor.
x != x || virtualCursor.
y != y) {
440 if (
_cursorX != x || _cursorY != y) {
555 void populateDisplayAreaDrawRect(
const frac_t displayAspect,
int originalWidth,
int originalHeight,
const Common::Rect &safeArea,
Common::Rect &drawRect)
const {
556 int mode = getStretchMode();
562 if (_rotationMode == Common::kRotation90 || _rotationMode == Common::kRotation270) {
563 SWAP(rotatedSafeArea.
left, rotatedSafeArea.top);
564 SWAP(rotatedSafeArea.
right, rotatedSafeArea.bottom);
565 SWAP(rotatedWindowWidth, rotatedWindowHeight);
567 const int rotatedSafeWidth = rotatedSafeArea.
width(),
568 rotatedSafeHeight = rotatedSafeArea.
height();
575 int width = 0, height = 0;
576 if (mode == STRETCH_CENTER || mode == STRETCH_INTEGRAL || mode == STRETCH_INTEGRAL_AR) {
577 width = originalWidth;
578 height = intToFrac(width) / displayAspect;
579 if (width > rotatedSafeWidth || height > rotatedSafeHeight) {
580 int fac = 1 +
MAX((width - 1) / rotatedSafeWidth, (height - 1) / rotatedSafeHeight);
583 }
else if (mode == STRETCH_INTEGRAL) {
584 int fac =
MIN(rotatedSafeWidth / width, rotatedSafeHeight / height);
587 }
else if (mode == STRETCH_INTEGRAL_AR) {
588 int targetHeight = height;
589 int horizontalFac = rotatedSafeWidth / width;
591 width = originalWidth * horizontalFac;
592 int verticalFac = (targetHeight * horizontalFac + originalHeight / 2) / originalHeight;
593 height = originalHeight * verticalFac;
595 }
while (horizontalFac > 0 && height > rotatedSafeHeight);
596 if (height > rotatedSafeHeight)
597 height = targetHeight;
600 frac_t windowAspect = intToFrac(rotatedSafeWidth) / rotatedSafeHeight;
601 width = rotatedSafeWidth;
602 height = rotatedSafeHeight;
603 if (mode == STRETCH_FIT_FORCE_ASPECT) {
604 frac_t ratio = intToFrac(4) / 3;
605 if (windowAspect < ratio)
606 height = intToFrac(width) / ratio;
607 else if (windowAspect > ratio)
608 width = fracToInt(height * ratio);
609 }
else if (mode != STRETCH_STRETCH) {
610 if (windowAspect < displayAspect)
611 height = intToFrac(width) / displayAspect;
612 else if (windowAspect > displayAspect)
613 width = fracToInt(height * displayAspect);
617 int16 alignX, alignY;
618 switch (_screenAlign & SCREEN_ALIGN_XMASK) {
620 case SCREEN_ALIGN_CENTER:
621 alignX = ((rotatedWindowWidth - width) / 2);
623 case SCREEN_ALIGN_LEFT:
626 case SCREEN_ALIGN_RIGHT:
627 alignX = (rotatedSafeArea.
right - width);
631 switch (_screenAlign & SCREEN_ALIGN_YMASK) {
633 case SCREEN_ALIGN_MIDDLE:
634 alignY = ((rotatedWindowHeight - height) / 2);
636 case SCREEN_ALIGN_TOP:
639 case SCREEN_ALIGN_BOTTOM:
640 alignY = (rotatedSafeArea.bottom - height);
644 rotatedSafeArea.
constrain(alignX, alignY, width, height);
646 alignX += _gameScreenShakeXOffset * width / getWidth();
647 alignY += _gameScreenShakeYOffset * height / getHeight();
649 if (_rotationMode == Common::kRotation90 || _rotationMode == Common::kRotation270) {
650 drawRect.top = alignX;
651 drawRect.
left = alignY;
655 drawRect.
left = alignX;
656 drawRect.top = alignY;
int _gameScreenShakeYOffset
Definition: windowed.h:488
T left
Definition: rect.h:170
Common::Point convertVirtualToWindow(const int x, const int y) const
Definition: windowed.h:209
virtual void handleResizeImpl(const int width, const int height)=0
Common::Rect _gameDrawRect
Definition: windowed.h:493
bool _cursorNeedsRedraw
Definition: windowed.h:541
virtual bool gameNeedsAspectRatioCorrection() const =0
int _windowHeight
Definition: windowed.h:456
bool _overlayVisible
Definition: windowed.h:473
int height
Definition: windowed.h:518
void setHeight(T aHeight)
Definition: rect.h:224
int _cursorX
Definition: windowed.h:552
void SWAP(T &a, T &b)
Definition: util.h:84
bool _cursorVisible
Definition: windowed.h:536
void setWidth(T aWidth)
Definition: rect.h:220
T width() const
Definition: rect.h:217
frac_t getDesiredGameAspectRatio() const
Definition: windowed.h:296
Definition: windowed.h:52
bool _overlayInGUI
Definition: windowed.h:478
bool _forceRedraw
Definition: windowed.h:531
virtual Insets getSafeAreaInsets() const
Definition: windowed.h:324
T height() const
Definition: rect.h:218
Common::Rect drawRect
Definition: windowed.h:508
Common::RotationMode _rotationMode
Definition: windowed.h:467
T right
Definition: rect.h:171
int _windowWidth
Definition: windowed.h:451
Common::Point convertWindowToVirtual(int x, int y) const
Definition: windowed.h:251
bool _cursorLastInActiveArea
Definition: windowed.h:547
void handleResize(const int width, const int height)
Definition: windowed.h:334
int width
Definition: windowed.h:513
virtual void recalculateDisplayAreas()
Definition: windowed.h:344
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: windowed.h:504
void setMousePosition(int x, int y)
Definition: windowed.h:439
Definition: graphics.h:38
void warpMouse(int x, int y) override
Definition: windowed.h:414
T MIN(T a, T b)
Definition: util.h:61
DisplayArea _activeArea
Definition: windowed.h:526
Common::Rect _overlayDrawRect
Definition: windowed.h:499
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:307
int32 frac_t
Definition: frac.h:52
Definition: windowed.h:311
int _screenAlign
Definition: windowed.h:462
int _gameScreenShakeXOffset
Definition: windowed.h:483
virtual void notifyActiveAreaChanged()
Definition: windowed.h:395