COMMON: Allow games to use overlay for something else than GUI

This can be used for subtitles without changing the mouse coordinates.
This commit is contained in:
Le Philousophe 2022-11-05 14:11:20 +01:00 committed by Eugene Sandulenko
parent c04b48db55
commit 87bad2cc7d
43 changed files with 229 additions and 133 deletions

View file

@ -154,13 +154,19 @@ void AndroidGraphicsManager::displayMessageOnOSD(const Common::U32String &msg) {
JNI::displayMessageOnOSD(msg);
}
void AndroidGraphicsManager::showOverlay() {
if (_overlayVisible)
void AndroidGraphicsManager::showOverlay(bool inGUI) {
if (_overlayVisible && inGUI == _overlayInGUI)
return;
// Don't change touch mode when not changing mouse coordinates
if (inGUI) {
_old_touch_mode = JNI::getTouchMode();
// not in 3D, in overlay
dynamic_cast<OSystem_Android *>(g_system)->applyTouchSettings(false, true);
} else if (_overlayInGUI) {
// Restore touch mode active before overlay was shown
JNI::setTouchMode(_old_touch_mode);
}
OpenGL::OpenGLGraphicsManager::showOverlay();
}
@ -169,8 +175,10 @@ void AndroidGraphicsManager::hideOverlay() {
if (!_overlayVisible)
return;
if (_overlayInGUI) {
// Restore touch mode active before overlay was shown
JNI::setTouchMode(_old_touch_mode);
}
OpenGL::OpenGLGraphicsManager::hideOverlay();
}

View file

@ -90,7 +90,7 @@ public:
protected:
void setSystemMousePosition(const int x, const int y) override {}
void showOverlay() override;
void showOverlay(bool inGUI) override;
void hideOverlay() override;

View file

@ -86,7 +86,7 @@ public:
virtual void setFocusRectangle(const Common::Rect& rect) = 0;
virtual void clearFocusRectangle() = 0;
virtual void showOverlay() = 0;
virtual void showOverlay(bool inGUI) = 0;
virtual void hideOverlay() = 0;
virtual bool isOverlayVisible() const = 0;
virtual Graphics::PixelFormat getOverlayFormat() const = 0;

View file

@ -71,7 +71,7 @@ public:
void setFocusRectangle(const Common::Rect& rect) override {}
void clearFocusRectangle() override {}
void showOverlay() override { _overlayVisible = true; }
void showOverlay(bool inGUI) override { _overlayVisible = true; }
void hideOverlay() override { _overlayVisible = false; }
bool isOverlayVisible() const override { return _overlayVisible; }
Graphics::PixelFormat getOverlayFormat() const override { return Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); }

View file

@ -636,35 +636,56 @@ void OpenGLGraphicsManager::updateScreen() {
// Clear the screen buffer.
GL_CALL(glClear(GL_COLOR_BUFFER_BIT));
if (!_overlayVisible) {
if (!_overlayInGUI) {
// The scissor test is enabled to:
// - Clip the cursor to the game screen
// - Clip the game screen when the shake offset is non-zero
_backBuffer.enableScissorTest(true);
}
// Don't draw cursor if it's not visible or there is none
bool drawCursor = _cursorVisible && _cursor;
// Alpha blending is disabled when drawing the screen
_backBuffer.enableBlend(Framebuffer::kBlendModeDisabled);
// First step: Draw the (virtual) game screen.
_pipeline->drawTexture(_gameScreen->getGLTexture(), _gameDrawRect.left, _gameDrawRect.top, _gameDrawRect.width(), _gameDrawRect.height());
// Second step: Draw the overlay if visible.
if (_overlayVisible) {
// Second step: Draw the cursor if necessary and we are not in GUI and it
#if !USE_FORCED_GLES
// Overlay must not be scaled and its cursor won't be either
if (_libretroPipeline) {
// If we are in game, draw the cursor through scaler
// This has the disadvantage of having overlay (subtitles) drawn above it
// but the cursor will look nicer
if (!_overlayInGUI && drawCursor) {
_backBuffer.enableBlend(Framebuffer::kBlendModePremultipliedTransparency);
_pipeline->drawTexture(_cursor->getGLTexture(),
_cursorX - _cursorHotspotXScaled + _shakeOffsetScaled.x,
_cursorY - _cursorHotspotYScaled + _shakeOffsetScaled.y,
_cursorWidthScaled, _cursorHeightScaled);
drawCursor = false;
// Everything we need to clip has been clipped
_backBuffer.enableScissorTest(false);
}
// Overlay must not be scaled and its cursor won't be either
_libretroPipeline->finishScaling();
}
#endif
// Third step: Draw the overlay if visible.
if (_overlayVisible) {
int dstX = (_windowWidth - _overlayDrawRect.width()) / 2;
int dstY = (_windowHeight - _overlayDrawRect.height()) / 2;
_backBuffer.enableBlend(Framebuffer::kBlendModeTraditionalTransparency);
_pipeline->drawTexture(_overlay->getGLTexture(), dstX, dstY, _overlayDrawRect.width(), _overlayDrawRect.height());
}
// Third step: Draw the cursor if necessary.
if (_cursorVisible && _cursor) {
// Fourth step: Draw the cursor if we didn't before.
if (drawCursor) {
_backBuffer.enableBlend(Framebuffer::kBlendModePremultipliedTransparency);
_pipeline->drawTexture(_cursor->getGLTexture(),
@ -673,13 +694,7 @@ void OpenGLGraphicsManager::updateScreen() {
_cursorWidthScaled, _cursorHeightScaled);
}
#if !USE_FORCED_GLES
if (_libretroPipeline) {
_libretroPipeline->finishScaling();
}
#endif
if (!_overlayVisible) {
if (!_overlayInGUI) {
_backBuffer.enableScissorTest(false);
}
@ -1448,8 +1463,8 @@ void OpenGLGraphicsManager::recalculateDisplayAreas() {
_gameDrawRect.width(),
_gameDrawRect.height());
_shakeOffsetScaled = Common::Point(_gameScreenShakeXOffset * _activeArea.drawRect.width() / _activeArea.width,
_gameScreenShakeYOffset * _activeArea.drawRect.height() / _activeArea.height);
_shakeOffsetScaled = Common::Point(_gameScreenShakeXOffset * _gameDrawRect.width() / _currentState.gameWidth,
_gameScreenShakeYOffset * _gameDrawRect.height() / _currentState.gameHeight);
// Update the cursor position to adjust for new display area.
setMousePosition(_cursorX, _cursorY);

View file

@ -1092,7 +1092,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
(_cursorNeedsRedraw && _mouseBackup.x <= _currentShakeXOffset)) {
SDL_Rect blackrect = {0, 0, (Uint16)(_gameScreenShakeXOffset * _videoMode.scaleFactor), (Uint16)(_videoMode.screenHeight * _videoMode.scaleFactor)};
if (_videoMode.aspectRatioCorrection && !_overlayVisible)
if (_videoMode.aspectRatioCorrection && !_overlayInGUI)
blackrect.h = real2Aspect(blackrect.h - 1) + 1;
SDL_FillRect(_hwScreen, &blackrect, 0);
@ -1105,7 +1105,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
(_cursorNeedsRedraw && _mouseBackup.y <= _currentShakeYOffset)) {
SDL_Rect blackrect = {0, 0, (Uint16)(_videoMode.screenWidth * _videoMode.scaleFactor), (Uint16)(_gameScreenShakeYOffset * _videoMode.scaleFactor)};
if (_videoMode.aspectRatioCorrection && !_overlayVisible)
if (_videoMode.aspectRatioCorrection && !_overlayInGUI)
blackrect.h = real2Aspect(blackrect.h - 1) + 1;
SDL_FillRect(_hwScreen, &blackrect, 0);
@ -1224,7 +1224,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
dst_x *= scale1;
dst_y *= scale1;
if (_videoMode.aspectRatioCorrection && !_overlayVisible)
if (_videoMode.aspectRatioCorrection && !_overlayInGUI)
dst_y = real2Aspect(dst_y);
_scaler->scale((byte *)srcSurf->pixels + (r->x + _maxExtraPixels) * 2 + (r->y + _maxExtraPixels) * srcPitch, srcPitch,
@ -1237,7 +1237,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
r->h = dst_h * scale1;
#ifdef USE_ASPECT
if (_videoMode.aspectRatioCorrection && orig_dst_y < height && !_overlayVisible)
if (_videoMode.aspectRatioCorrection && orig_dst_y < height && !_overlayInGUI)
r->h = stretch200To240((uint8 *) _hwScreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1, _videoMode.filtering, convertSDLPixelFormat(_hwScreen->format));
#endif
}
@ -1263,7 +1263,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
// We draw the focus rectangle on top of everything, to assure it's easily visible.
// Of course when the overlay is visible we do not show it, since it is only for game
// specific focus.
if (_enableFocusRect && !_overlayVisible) {
if (_enableFocusRect && !_overlayInGUI) {
int x = _focusRect.left + _currentShakeXOffset;
int y = _focusRect.top + _currentShakeYOffset;
@ -1281,7 +1281,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
w *= scale1;
h *= scale1;
if (_videoMode.aspectRatioCorrection && !_overlayVisible)
if (_videoMode.aspectRatioCorrection && !_overlayInGUI)
y = real2Aspect(y);
if (h > 0 && w > 0) {
@ -1437,7 +1437,7 @@ void SurfaceSdlGraphicsManager::copyRectToScreen(const void *buf, int pitch, int
assert(h > 0 && y + h <= _videoMode.screenHeight);
assert(w > 0 && x + w <= _videoMode.screenWidth);
addDirtyRect(x, y, w, h);
addDirtyRect(x, y, w, h, false);
// Try to lock the screen surface
if (SDL_LockSurface(_screen) == -1)
@ -1502,7 +1502,7 @@ void SurfaceSdlGraphicsManager::fillScreen(uint32 col) {
unlockScreen();
}
void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool realCoordinates) {
void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool inOverlay, bool realCoordinates) {
if (_forceRedraw)
return;
@ -1513,7 +1513,7 @@ void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool re
int height, width;
if (!_overlayVisible && !realCoordinates) {
if (!inOverlay && !realCoordinates) {
width = _videoMode.screenWidth;
height = _videoMode.screenHeight;
} else {
@ -1552,7 +1552,7 @@ void SurfaceSdlGraphicsManager::addDirtyRect(int x, int y, int w, int h, bool re
}
#ifdef USE_ASPECT
if (_videoMode.aspectRatioCorrection && !_overlayVisible && !realCoordinates)
if (_videoMode.aspectRatioCorrection && !_overlayInGUI && !realCoordinates)
makeRectStretchable(x, y, w, h, _videoMode.filtering);
#endif
@ -1662,7 +1662,7 @@ void SurfaceSdlGraphicsManager::setFocusRectangle(const Common::Rect &rect) {
// We just fake this as a dirty rect for now, to easily force an screen update whenever
// the rect changes.
addDirtyRect(_focusRect.left, _focusRect.top, _focusRect.width(), _focusRect.height());
addDirtyRect(_focusRect.left, _focusRect.top, _focusRect.width(), _focusRect.height(), _overlayVisible);
#endif
}
@ -1676,7 +1676,7 @@ void SurfaceSdlGraphicsManager::clearFocusRectangle() {
// We just fake this as a dirty rect for now, to easily force an screen update whenever
// the rect changes.
addDirtyRect(_focusRect.left, _focusRect.top, _focusRect.width(), _focusRect.height());
addDirtyRect(_focusRect.left, _focusRect.top, _focusRect.width(), _focusRect.height(), _overlayVisible);
#endif
}
@ -1771,7 +1771,7 @@ void SurfaceSdlGraphicsManager::copyRectToOverlay(const void *buf, int pitch, in
return;
// Mark the modified region as dirty
addDirtyRect(x, y, w, h);
addDirtyRect(x, y, w, h, true);
if (SDL_LockSurface(_overlayscreen) == -1)
error("SDL_LockSurface failed: %s", SDL_GetError());
@ -2106,11 +2106,11 @@ void SurfaceSdlGraphicsManager::undrawMouse() {
// When we switch bigger overlay off mouse jumps. Argh!
// This is intended to prevent undrawing offscreen mouse
if (!_overlayVisible && (x >= _videoMode.screenWidth || y >= _videoMode.screenHeight))
if (!_overlayInGUI && (x >= _videoMode.screenWidth || y >= _videoMode.screenHeight))
return;
if (_mouseBackup.w != 0 && _mouseBackup.h != 0)
addDirtyRect(x, y, _mouseBackup.w, _mouseBackup.h);
addDirtyRect(x, y, _mouseBackup.w, _mouseBackup.h, _overlayInGUI);
}
void SurfaceSdlGraphicsManager::drawMouse() {
@ -2128,7 +2128,7 @@ void SurfaceSdlGraphicsManager::drawMouse() {
dst.x = virtualCursor.x;
dst.y = virtualCursor.y;
if (!_overlayVisible) {
if (!_overlayInGUI) {
scale = _videoMode.scaleFactor;
dst.w = _mouseCurState.vW;
dst.h = _mouseCurState.vH;
@ -2161,7 +2161,7 @@ void SurfaceSdlGraphicsManager::drawMouse() {
dst.x += _currentShakeXOffset;
dst.y += _currentShakeYOffset;
if (_videoMode.aspectRatioCorrection && !_overlayVisible)
if (_videoMode.aspectRatioCorrection && !_overlayInGUI)
dst.y = real2Aspect(dst.y);
dst.x = scale * dst.x - _mouseCurState.rHotX;
@ -2178,7 +2178,7 @@ void SurfaceSdlGraphicsManager::drawMouse() {
// The screen will be updated using real surface coordinates, i.e.
// they will not be scaled or aspect-ratio corrected.
addDirtyRect(dst.x, dst.y, dst.w, dst.h, true);
addDirtyRect(dst.x, dst.y, dst.w, dst.h, _overlayInGUI, true);
}
#pragma mark -
@ -2643,10 +2643,12 @@ void SurfaceSdlGraphicsManager::SDL_UpdateRects(SDL_Surface *screen, int numrect
SDL_UpdateTexture(_screenTexture, nullptr, screen->pixels, screen->pitch);
SDL_Rect viewport;
viewport.x = _activeArea.drawRect.left;
viewport.y = _activeArea.drawRect.top;
viewport.w = _activeArea.drawRect.width();
viewport.h = _activeArea.drawRect.height();
Common::Rect &drawRect = (_overlayVisible) ? _overlayDrawRect : _gameDrawRect;
viewport.x = drawRect.left;
viewport.y = drawRect.top;
viewport.w = drawRect.width();
viewport.h = drawRect.height();
SDL_RenderClear(_renderer);
SDL_RenderCopy(_renderer, _screenTexture, nullptr, &viewport);

View file

@ -403,7 +403,7 @@ protected:
Common::Rect _focusRect;
#endif
virtual void addDirtyRect(int x, int y, int w, int h, bool realCoordinates = false);
virtual void addDirtyRect(int x, int y, int w, int h, bool inOverlay, bool realCoordinates = false);
virtual void drawMouse();
virtual void undrawMouse();

View file

@ -44,6 +44,7 @@ public:
_windowWidth(0),
_windowHeight(0),
_overlayVisible(false),
_overlayInGUI(false),
_gameScreenShakeXOffset(0),
_gameScreenShakeYOffset(0),
_forceRedraw(false),
@ -53,13 +54,22 @@ public:
_cursorNeedsRedraw(false),
_cursorLastInActiveArea(true) {}
void showOverlay() override {
if (_overlayVisible)
return;
void showOverlay(bool inGUI) override {
_overlayInGUI = inGUI;
if (inGUI) {
_activeArea.drawRect = _overlayDrawRect;
_activeArea.width = getOverlayWidth();
_activeArea.height = getOverlayHeight();
} else {
_activeArea.drawRect = _gameDrawRect;
_activeArea.width = getWidth();
_activeArea.height = getHeight();
}
if (_overlayVisible)
return;
_overlayVisible = true;
_forceRedraw = true;
notifyActiveAreaChanged();
@ -69,6 +79,8 @@ public:
if (!_overlayVisible)
return;
_overlayInGUI = true;
_activeArea.drawRect = _gameDrawRect;
_activeArea.width = getWidth();
_activeArea.height = getHeight();
@ -203,7 +215,7 @@ protected:
populateDisplayAreaDrawRect(overlayAspect, getOverlayWidth(), getOverlayHeight(), _overlayDrawRect);
}
if (_overlayVisible) {
if (_overlayInGUI) {
_activeArea.drawRect = _overlayDrawRect;
_activeArea.width = getOverlayWidth();
_activeArea.height = getOverlayHeight();
@ -296,6 +308,11 @@ protected:
*/
bool _overlayVisible;
/**
* Whether when overlay is shown, mouse coordinates depend on window or game screen size
*/
bool _overlayInGUI;
/**
* The offset by which the screen is moved horizontally.
*/

View file

@ -322,7 +322,8 @@ void AndroidGraphics3dManager::updateScreen() {
_game_texture->drawTextureRect();
if (_show_overlay) {
if (_overlay_background && _overlay_background->getTextureName() != 0) {
// If the overlay is in game we expect the game to continue drawing
if (_overlay_in_gui && _overlay_background && _overlay_background->getTextureName() != 0) {
GLCALL(_overlay_background->drawTextureRect());
}
GLCALL(_overlay_texture->drawTextureRect());
@ -491,18 +492,24 @@ bool AndroidGraphics3dManager::getFeatureState(OSystem::Feature f) const {
}
}
void AndroidGraphics3dManager::showOverlay() {
void AndroidGraphics3dManager::showOverlay(bool inGUI) {
ENTER();
if (_show_overlay) {
if (_show_overlay && inGUI == _overlay_in_gui) {
return;
}
if (inGUI) {
_old_touch_mode = JNI::getTouchMode();
// in 3D, in overlay
dynamic_cast<OSystem_Android *>(g_system)->applyTouchSettings(true, true);
} else if (_overlay_in_gui) {
// Restore touch mode active before overlay was shown
JNI::setTouchMode(_old_touch_mode);
}
_show_overlay = true;
_overlay_in_gui = inGUI;
_force_redraw = true;
// If there is a game running capture the screen, so that it can be shown "below" the overlay.
@ -546,10 +553,14 @@ void AndroidGraphics3dManager::hideOverlay() {
_overlay_background->release();
if (_overlay_in_gui) {
// Restore touch mode active before overlay was shown
JNI::setTouchMode(_old_touch_mode);
warpMouse(_game_texture->width() / 2, _game_texture->height() / 2);
}
_overlay_in_gui = false;
// double buffered, flip twice
clearScreen(kClearUpdate, 2);

View file

@ -70,7 +70,7 @@ public:
virtual void setFeatureState(OSystem::Feature f, bool enable) override;
virtual bool getFeatureState(OSystem::Feature f) const override;
virtual void showOverlay() override;
virtual void showOverlay(bool inGUI) override;
virtual void hideOverlay() override;
virtual void clearOverlay() override;
virtual void grabOverlay(Graphics::Surface &surface) const override;
@ -172,6 +172,7 @@ private:
GLESTexture *_overlay_background;
GLESTexture *_overlay_texture;
bool _show_overlay;
bool _overlay_in_gui;
// Mouse layer
GLESBaseTexture *_mouse_texture;

View file

@ -649,7 +649,8 @@ void OpenGLSdlGraphics3dManager::updateScreen() {
if (_overlayVisible) {
_overlayScreen->update();
if (_overlayBackground) {
// If the overlay is in game we expect the game to continue calling OpenGL
if (_overlayBackground && _overlayInGUI) {
_overlayBackground->update();
}
@ -685,11 +686,12 @@ int16 OpenGLSdlGraphics3dManager::getWidth() const {
#pragma mark --- Overlays ---
#pragma mark -
void OpenGLSdlGraphics3dManager::showOverlay() {
if (_overlayVisible) {
void OpenGLSdlGraphics3dManager::showOverlay(bool inGUI) {
if (_overlayVisible && _overlayInGUI == inGUI) {
return;
}
WindowedGraphicsManager::showOverlay();
WindowedGraphicsManager::showOverlay(inGUI);
delete _overlayBackground;
_overlayBackground = nullptr;

View file

@ -92,7 +92,7 @@ public:
void clearFocusRectangle() override {}
// GraphicsManager API - Overlay
void showOverlay() override;
void showOverlay(bool inGUI) override;
void hideOverlay() override;
Graphics::PixelFormat getOverlayFormat() const override { return _overlayFormat; }
void clearOverlay() override;

View file

@ -198,8 +198,8 @@ void ModularGraphicsBackend::clearFocusRectangle() {
_graphicsManager->clearFocusRectangle();
}
void ModularGraphicsBackend::showOverlay() {
_graphicsManager->showOverlay();
void ModularGraphicsBackend::showOverlay(bool inGUI) {
_graphicsManager->showOverlay(inGUI);
}
void ModularGraphicsBackend::hideOverlay() {

View file

@ -101,7 +101,7 @@ public:
void setFocusRectangle(const Common::Rect& rect) override final;
void clearFocusRectangle() override final;
void showOverlay() override final;
void showOverlay(bool inGUI) override final;
void hideOverlay() override final;
bool isOverlayVisible() const override final;
Graphics::PixelFormat getOverlayFormat() const override final;

View file

@ -277,7 +277,7 @@ void OSystem_3DS::destroyEvents() {
}
void OSystem_3DS::transformPoint(touchPosition &point) {
if (!_overlayVisible) {
if (!_overlayInGUI) {
point.px = static_cast<float>(point.px) / _gameBottomTexture.getScaleX() - _gameBottomTexture.getPosX();
point.py = static_cast<float>(point.py) / _gameBottomTexture.getScaleY() - _gameBottomTexture.getPosY();
}
@ -286,7 +286,7 @@ void OSystem_3DS::transformPoint(touchPosition &point) {
}
void OSystem_3DS::clipPoint(touchPosition &point) {
if (_overlayVisible) {
if (_overlayInGUI) {
point.px = CLIP<uint16>(point.px, 0, getOverlayWidth() - 1);
point.py = CLIP<uint16>(point.py, 0, getOverlayHeight() - 1);
} else {

View file

@ -263,7 +263,7 @@ void OSystem_3DS::updateSize() {
_gameBottomTexture.setPosition(_gameBottomX, _gameBottomY);
_gameTopTexture.setOffset(0, 0);
_gameBottomTexture.setOffset(0, 0);
if (_overlayVisible) {
if (_overlayInGUI) {
_cursorTexture.setScale(1.f, 1.f);
} else if (config.screen == kScreenTop) {
_cursorTexture.setScale(_gameTopTexture.getScaleX(), _gameTopTexture.getScaleY());
@ -329,7 +329,7 @@ OSystem::TransactionError OSystem_3DS::endGFXTransaction() {
}
float OSystem_3DS::getScaleRatio() const {
if (_overlayVisible) {
if (_overlayInGUI) {
return 1.0;
} else if (config.screen == kScreenTop) {
return _gameTopTexture.getScaleX();
@ -457,7 +457,7 @@ void OSystem_3DS::updateScreen() {
}
if (_cursorVisible && config.showCursor && config.screen == kScreenTop) {
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, _modelviewLocation, _cursorTexture.getMatrix());
_cursorTexture.setFilteringMode(!_overlayVisible && _filteringEnabled);
_cursorTexture.setFilteringMode(!_overlayInGUI && _filteringEnabled);
_cursorTexture.render();
}
}
@ -486,7 +486,7 @@ void OSystem_3DS::updateScreen() {
}
if (_cursorVisible && config.showCursor) {
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, _modelviewLocation, _cursorTexture.getMatrix());
_cursorTexture.setFilteringMode(!_overlayVisible && _filteringEnabled);
_cursorTexture.setFilteringMode(!_overlayInGUI && _filteringEnabled);
_cursorTexture.render();
}
}
@ -609,13 +609,15 @@ void OSystem_3DS::updateMagnify() {
}
}
void OSystem_3DS::showOverlay() {
void OSystem_3DS::showOverlay(bool inGUI) {
_overlayInGUI = inGUI;
_overlayVisible = true;
updateSize();
}
void OSystem_3DS::hideOverlay() {
_overlayVisible = false;
_overlayInGUI = false;
updateSize();
}

View file

@ -81,6 +81,7 @@ OSystem_3DS::OSystem_3DS():
_gameTextureDirty(false),
_filteringEnabled(true),
_overlayVisible(false),
_overlayInGUI(false),
_screenChangeId(0),
_magnifyMode(MODE_MAGOFF),
exiting(false),

View file

@ -153,7 +153,7 @@ public:
void setShakePos(int shakeXOffset, int shakeYOffset);
void setFocusRectangle(const Common::Rect &rect);
void clearFocusRectangle();
void showOverlay();
void showOverlay(bool inGUI);
void hideOverlay();
bool isOverlayVisible() const { return _overlayVisible; }
Graphics::PixelFormat getOverlayFormat() const;
@ -241,6 +241,7 @@ private:
int _screenShakeXOffset;
int _screenShakeYOffset;
bool _overlayVisible;
bool _overlayInGUI;
int _screenChangeId;
DVLB_s *_dvlb;

View file

@ -154,7 +154,7 @@ public:
int16 getOverlayHeight();
int16 getOverlayWidth();
bool isOverlayVisible() const { return _overlay_visible; }
void showOverlay();
void showOverlay(bool inGUI);
void hideOverlay();
void clearOverlay();
void grabOverlay(Graphics::Surface &surface);
@ -193,6 +193,7 @@ public:
bool _overlay_visible, _overlay_dirty, _screen_dirty;
int _screen_buffer, _overlay_buffer, _mouse_buffer;
bool _aspect_stretch, _softkbd_on, _enable_cursor_palette;
bool _overlay_in_gui;
float _overlay_fade, _xscale, _yscale, _top_offset;
int _softkbd_motion;

View file

@ -45,7 +45,7 @@ OSystem_Dreamcast::OSystem_Dreamcast()
: _devpoll(0), screen(NULL), mouse(NULL), overlay(NULL), _softkbd(this),
_ms_buf(NULL), _mixer(NULL),
_current_shake_x_pos(0), _current_shake_y_pos(0), _aspect_stretch(false), _softkbd_on(false),
_softkbd_motion(0), _enable_cursor_palette(false), _screenFormat(0)
_softkbd_motion(0), _enable_cursor_palette(false), _overlay_in_gui(false), _screenFormat(0)
{
memset(screen_tx, 0, sizeof(screen_tx));
memset(mouse_tx, 0, sizeof(mouse_tx));

View file

@ -634,14 +634,16 @@ void OSystem_Dreamcast::mouseToSoftKbd(int x, int y, int &rx, int &ry) const
}
void OSystem_Dreamcast::showOverlay()
void OSystem_Dreamcast::showOverlay(bool inGUI)
{
_overlay_in_gui = inGUI;
_overlay_visible = true;
clearOverlay();
}
void OSystem_Dreamcast::hideOverlay()
{
_overlay_in_gui = false;
_overlay_visible = false;
}

View file

@ -215,7 +215,7 @@ bool OSystem_Dreamcast::pollEvent(Common::Event &event)
if (_ms_cur_y>=_screen_h) _ms_cur_y=_screen_h-1;
event.mouse.x = _ms_cur_x;
event.mouse.y = _ms_cur_y;
if (_overlay_visible) {
if (_overlay_in_gui) {
event.mouse.x -= _overlay_x;
event.mouse.y -= _overlay_y;
}

View file

@ -408,7 +408,9 @@ void OSystem_DS::updateScreen() {
if (_overlay.isVisible()) {
_overlay.update();
} else {
}
if (_framebuffer.isVisible()) {
if (_paletteDirty) {
dmaCopyHalfWords(3, _palette, BG_PALETTE, 256 * 2);
#ifdef DISABLE_TEXT_CONSOLE
@ -430,12 +432,14 @@ void OSystem_DS::setShakePos(int shakeXOffset, int shakeYOffset) {
DS::setShakePos(shakeXOffset, shakeYOffset);
}
void OSystem_DS::showOverlay() {
void OSystem_DS::showOverlay(bool inGUI) {
_overlayInGUI = inGUI;
_overlay.reset();
_overlay.show();
}
void OSystem_DS::hideOverlay() {
_overlayInGUI = false;
_overlay.hide();
}
@ -471,7 +475,7 @@ Graphics::PixelFormat OSystem_DS::getOverlayFormat() const {
}
Common::Point OSystem_DS::transformPoint(int16 x, int16 y) {
if (_overlay.isVisible())
if (_overlayInGUI)
return Common::Point(x, y);
else
return _framebuffer.realToScaled(x, y);
@ -484,7 +488,7 @@ bool OSystem_DS::showMouse(bool visible) {
}
void OSystem_DS::warpMouse(int x, int y) {
if (_overlay.isVisible())
if (_overlayInGUI)
_cursorPos = Common::Point(x, y);
else
_cursorPos = _framebuffer.scaledToReal(x, y);

View file

@ -46,7 +46,7 @@ OSystem_DS *OSystem_DS::_instance = NULL;
OSystem_DS::OSystem_DS()
: _eventSource(NULL), _disableCursorPalette(true),
_graphicsMode(GFX_HWSCALE), _stretchMode(100),
_paletteDirty(false), _cursorDirty(false),
_paletteDirty(false), _cursorDirty(false), _overlayInGUI(false),
_pfCLUT8(Graphics::PixelFormat::createFormatCLUT8()),
_pfABGR1555(Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15)),
_callbackTimer(10), _currentTimeMillis(0), _subScreenActive(true)

View file

@ -59,6 +59,7 @@ protected:
int _cursorHotY;
uint32 _cursorKey;
bool _cursorVisible;
bool _overlayInGUI;
DSEventSource *_eventSource;
DS::Keyboard *_keyboard;
@ -107,7 +108,7 @@ public:
virtual void updateScreen();
virtual void setShakePos(int shakeXOffset, int shakeYOffset);
virtual void showOverlay();
virtual void showOverlay(bool inGUI);
virtual void hideOverlay();
virtual bool isOverlayVisible() const;
virtual void clearOverlay();

View file

@ -69,7 +69,7 @@ enum UIViewTapDescription {
struct VideoContext {
VideoContext() : asprectRatioCorrection(), screenWidth(), screenHeight(), overlayVisible(false),
overlayWidth(), overlayHeight(), mouseX(), mouseY(),
overlayInGUI(false), overlayWidth(), overlayHeight(), mouseX(), mouseY(),
mouseHotspotX(), mouseHotspotY(), mouseWidth(), mouseHeight(),
mouseIsVisible(), filtering(false), shakeXOffset(), shakeYOffset() {
}
@ -81,6 +81,7 @@ struct VideoContext {
// Overlay state
bool overlayVisible;
bool overlayInGUI;
uint overlayWidth, overlayHeight;
Graphics::Surface overlayTexture;

View file

@ -230,7 +230,7 @@ bool OSystem_iOS7::handleEvent_secondMouseUp(Common::Event &event, int x, int y)
if (curTime - _lastSecondaryDown < 400) {
//printf("Right tap!\n");
if (curTime - _lastSecondaryTap < 400 && !_videoContext->overlayVisible) {
if (curTime - _lastSecondaryTap < 400 && !_videoContext->overlayInGUI) {
//printf("Right escape!\n");
event.type = Common::EVENT_KEYDOWN;
_queuedInputEvent.type = Common::EVENT_KEYUP;
@ -283,8 +283,8 @@ bool OSystem_iOS7::handleEvent_mouseDragged(Common::Event &event, int x, int y)
mouseNewPosX = (int)(_videoContext->mouseX - deltaX / 0.5f);
mouseNewPosY = (int)(_videoContext->mouseY - deltaY / 0.5f);
int widthCap = _videoContext->overlayVisible ? _videoContext->overlayWidth : _videoContext->screenWidth;
int heightCap = _videoContext->overlayVisible ? _videoContext->overlayHeight : _videoContext->screenHeight;
int widthCap = _videoContext->overlayInGUI ? _videoContext->overlayWidth : _videoContext->screenWidth;
int heightCap = _videoContext->overlayInGUI ? _videoContext->overlayHeight : _videoContext->screenHeight;
if (mouseNewPosX < 0)
mouseNewPosX = 0;

View file

@ -164,7 +164,7 @@ public:
void unlockScreen() override;
void setShakePos(int shakeXOffset, int shakeYOffset) override;
void showOverlay() override;
void showOverlay(bool inGUI) override;
void hideOverlay() override;
bool isOverlayVisible() const override { return _videoContext->overlayVisible; }
void clearOverlay() override;

View file

@ -355,9 +355,10 @@ void OSystem_iOS7::setShakePos(int shakeXOffset, int shakeYOffset) {
_mouseDirty = true;
}
void OSystem_iOS7::showOverlay() {
void OSystem_iOS7::showOverlay(bool inGUI) {
//printf("showOverlay()\n");
_videoContext->overlayVisible = true;
_videoContext->overlayInGUI = inGUI;
dirtyFullOverlayScreen();
updateScreen();
execute_on_main_thread(^ {
@ -369,6 +370,7 @@ void OSystem_iOS7::showOverlay() {
void OSystem_iOS7::hideOverlay() {
//printf("hideOverlay()\n");
_videoContext->overlayVisible = false;
_videoContext->overlayInGUI = false;
_dirtyOverlayRects.clear();
dirtyFullScreen();
execute_on_main_thread(^ {

View file

@ -522,7 +522,7 @@ uint getSizeNextPOT(uint size) {
CGRect *rect;
int maxWidth, maxHeight;
if (!_videoContext.overlayVisible) {
if (!_videoContext.overlayInGUI) {
rect = &_gameScreenRect;
maxWidth = _videoContext.screenWidth;
maxHeight = _videoContext.screenHeight;
@ -533,7 +533,7 @@ uint getSizeNextPOT(uint size) {
}
if (!maxWidth || !maxHeight) {
printf("WARNING: updateMouseCursorScaling called when screen was not ready (%d)!\n", _videoContext.overlayVisible);
printf("WARNING: updateMouseCursorScaling called when screen was not ready (%d)!\n", _videoContext.overlayInGUI);
return;
}
@ -787,7 +787,7 @@ uint getSizeNextPOT(uint size) {
CGRect *area;
int width, height, offsetX, offsetY;
if (_videoContext.overlayVisible) {
if (_videoContext.overlayInGUI) {
area = &_overlayRect;
width = _videoContext.overlayWidth;
height = _videoContext.overlayHeight;

View file

@ -53,7 +53,7 @@ enum UIViewSwipeDirection {
struct VideoContext {
VideoContext() : asprectRatioCorrection(), screenWidth(), screenHeight(), overlayVisible(false),
overlayWidth(), overlayHeight(), mouseX(), mouseY(),
overlayInGUI(false), overlayWidth(), overlayHeight(), mouseX(), mouseY(),
mouseHotspotX(), mouseHotspotY(), mouseWidth(), mouseHeight(),
mouseIsVisible(), filtering(false),
shakeXOffset(), shakeYOffset() {
@ -66,6 +66,7 @@ struct VideoContext {
// Overlay state
bool overlayVisible;
bool overlayInGUI;
uint overlayWidth, overlayHeight;
Graphics::Surface overlayTexture;

View file

@ -318,7 +318,7 @@ const char *iPhone_getDocumentsDir() {
CGRect *rect;
int maxWidth, maxHeight;
if (!_videoContext.overlayVisible) {
if (!_videoContext.overlayInGUI) {
rect = &_gameScreenRect;
maxWidth = _videoContext.screenWidth;
maxHeight = _videoContext.screenHeight;
@ -329,7 +329,7 @@ const char *iPhone_getDocumentsDir() {
}
if (!maxWidth || !maxHeight) {
printf("WARNING: updateMouseCursorScaling called when screen was not ready (%d)!\n", _videoContext.overlayVisible);
printf("WARNING: updateMouseCursorScaling called when screen was not ready (%d)!\n", _videoContext.overlayInGUI);
return;
}
@ -626,7 +626,7 @@ const char *iPhone_getDocumentsDir() {
CGRect *area;
int width, height, offsetX, offsetY;
if (_videoContext.overlayVisible) {
if (_videoContext.overlayInGUI) {
area = &_overlayRect;
width = _videoContext.overlayWidth;
height = _videoContext.overlayHeight;

View file

@ -182,7 +182,7 @@ bool OSystem_IPHONE::handleEvent_secondMouseUp(Common::Event &event, int x, int
if (curTime - _lastSecondaryDown < 400) {
//printf("Right tap!\n");
if (curTime - _lastSecondaryTap < 400 && !_videoContext->overlayVisible) {
if (curTime - _lastSecondaryTap < 400 && !_videoContext->overlayInGUI) {
//printf("Right escape!\n");
event.type = Common::EVENT_KEYDOWN;
_queuedInputEvent.type = Common::EVENT_KEYUP;
@ -235,8 +235,8 @@ bool OSystem_IPHONE::handleEvent_mouseDragged(Common::Event &event, int x, int y
mouseNewPosX = (int)(_videoContext->mouseX - deltaX / 0.5f);
mouseNewPosY = (int)(_videoContext->mouseY - deltaY / 0.5f);
int widthCap = _videoContext->overlayVisible ? _videoContext->overlayWidth : _videoContext->screenWidth;
int heightCap = _videoContext->overlayVisible ? _videoContext->overlayHeight : _videoContext->screenHeight;
int widthCap = _videoContext->overlayInGUI ? _videoContext->overlayWidth : _videoContext->screenWidth;
int heightCap = _videoContext->overlayInGUI ? _videoContext->overlayHeight : _videoContext->screenHeight;
if (mouseNewPosX < 0)
mouseNewPosX = 0;

View file

@ -145,7 +145,7 @@ public:
virtual void unlockScreen();
virtual void setShakePos(int shakeXOffset, int shakeYOffset);
virtual void showOverlay();
virtual void showOverlay(bool inGUI);
virtual void hideOverlay();
virtual bool isOverlayVisible() const { return _videoContext->overlayVisible; }
virtual void clearOverlay();

View file

@ -279,9 +279,10 @@ void OSystem_IPHONE::setShakePos(int shakeXOffset, int shakeYOffset) {
_mouseDirty = true;
}
void OSystem_IPHONE::showOverlay() {
void OSystem_IPHONE::showOverlay(bool inGUI) {
//printf("showOverlay()\n");
_videoContext->overlayVisible = true;
_videoContext->overlayInGUI = inGUI;
dirtyFullOverlayScreen();
updateScreen();
[g_iPhoneViewInstance performSelectorOnMainThread:@selector(updateMouseCursorScaling) withObject:nil waitUntilDone: YES];
@ -291,6 +292,7 @@ void OSystem_IPHONE::showOverlay() {
void OSystem_IPHONE::hideOverlay() {
//printf("hideOverlay()\n");
_videoContext->overlayVisible = false;
_videoContext->overlayInGUI = false;
_dirtyOverlayRects.clear();
dirtyFullScreen();
[g_iPhoneViewInstance performSelectorOnMainThread:@selector(updateMouseCursorScaling) withObject:nil waitUntilDone: YES];

View file

@ -109,6 +109,7 @@ protected:
uint16 _overlayHeight, _overlayWidth;
bool _overlayVisible;
bool _overlayInGUI;
bool _disableFpsLimit; // When this is enabled, the system doesn't limit screen updates
@ -164,7 +165,7 @@ public:
virtual void unlockScreen();
virtual void setShakePos(int shakeXOffset, int shakeYOffset);
virtual void showOverlay();
virtual void showOverlay(bool inGUI);
virtual void hideOverlay();
virtual bool isOverlayVisible() const { return _overlayVisible; }
virtual void clearOverlay();

View file

@ -90,6 +90,7 @@ OSystem_N64::OSystem_N64() {
_disableFpsLimit = false;
_overlayVisible = false;
_overlayInGUI = false;
_shakeXOffset = 0;
_shakeYOffset = 0;
@ -613,27 +614,34 @@ void OSystem_N64::setShakePos(int shakeXOffset, int shakeYOffset) {
return;
}
void OSystem_N64::showOverlay() {
void OSystem_N64::showOverlay(bool inGUI) {
_overlayInGUI = inGUI;
if (inGUI) {
// Change min/max mouse coords
_mouseMaxX = _overlayWidth;
_mouseMaxY = _overlayHeight;
// Relocate the mouse cursor given the new limitations
warpMouse(_mouseX, _mouseY);
}
_overlayVisible = true;
_dirtyOffscreen = true;
}
void OSystem_N64::hideOverlay() {
if (_overlayInGUI) {
// Change min/max mouse coords
_mouseMaxX = _gameWidth;
_mouseMaxY = _gameHeight;
// Relocate the mouse cursor given the new limitations
warpMouse(_mouseX, _mouseY);
}
_overlayVisible = false;
_overlayInGUI = false;
// Clear double buffered display
clearAllVideoBuffers();

View file

@ -229,13 +229,15 @@ void OSystem_PSP::setShakePos(int shakeXOffset, int shakeYOffset) {
_screen.setShakePos(shakeXOffset, shakeYOffset);
}
void OSystem_PSP::showOverlay() {
void OSystem_PSP::showOverlay(bool inGUI) {
DEBUG_ENTER_FUNC();
_pendingUpdate = false;
_overlay.setVisible(true);
if (inGUI) {
_cursor.setLimits(_overlay.getWidth(), _overlay.getHeight());
_cursor.useGlobalScaler(false); // mouse with overlay is 1:1
}
}
void OSystem_PSP::hideOverlay() {
DEBUG_ENTER_FUNC();

View file

@ -101,7 +101,7 @@ public:
void setShakePos(int shakeXOffset, int shakeYOffset);
// Overlay related
void showOverlay();
void showOverlay(bool inGUI);
void hideOverlay();
bool isOverlayVisible() const;
void clearOverlay();

View file

@ -39,6 +39,7 @@
OSystem_Wii::OSystem_Wii() :
_startup_time(0),
_overlayInGUI(false),
_cursorDontScale(true),
_cursorPaletteDisabled(true),
_cursorPalette(NULL),

View file

@ -75,6 +75,7 @@ private:
gfx_screen_coords_t _coordsOverlay;
gfx_tex_t _texOverlay;
bool _overlayDirty;
bool _overlayInGUI;
u32 _lastScreenUpdate;
u16 _currentWidth, _currentHeight;
@ -173,7 +174,7 @@ public:
void unlockScreen() override;
void setShakePos(int shakeXOffset, int shakeYOffset) override;
void showOverlay() override;
void showOverlay(bool inGUI) override;
void hideOverlay() override;
bool isOverlayVisible() const override { return _overlayVisible; }
void clearOverlay() override;

View file

@ -113,7 +113,7 @@ void OSystem_Wii::deinitGfx() {
}
void OSystem_Wii::updateScreenResolution() {
if (_overlayVisible) {
if (_overlayInGUI) {
_currentWidth = _overlayWidth;
_currentHeight = _overlayHeight;
} else {
@ -554,17 +554,23 @@ void OSystem_Wii::setShakePos(int shakeXOffset, int shakeYOffset) {
_coordsGame.y -= f32(shakeYOffset) * _currentYScale;
}
void OSystem_Wii::showOverlay() {
void OSystem_Wii::showOverlay(bool inGUI) {
if (inGUI) {
_mouseX = _overlayWidth / 2;
_mouseY = _overlayHeight / 2;
}
_overlayInGUI = inGUI;
_overlayVisible = true;
updateScreenResolution();
gfx_tex_set_bilinear_filter(&_texMouse, true);
}
void OSystem_Wii::hideOverlay() {
if (_overlayInGUI) {
_mouseX = _gameWidth / 2;
_mouseY = _gameHeight / 2;
}
_overlayInGUI = false;
_overlayVisible = false;
updateScreenResolution();
gfx_tex_set_bilinear_filter(&_texMouse, _bilinearFilter);

View file

@ -1181,10 +1181,13 @@ public:
* and then manually compose whatever graphics we want to show in the overlay.
* This works because we assume the game to be "paused" whenever an overlay
* is active.
*
* @param inGame Whether the overlay is used to display GUI or in game images
*
*/
/** Activate the overlay mode. */
virtual void showOverlay() = 0;
virtual void showOverlay(bool inGUI = true) = 0;
/** Deactivate the overlay mode. */
virtual void hideOverlay() = 0;