From e2aafb603e279506c85d00f4b9fb698934994b2c Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 24 Feb 2011 00:09:25 +0100 Subject: SDL: Move focus rectangle dummy implementations to .cpp file. --- backends/graphics/sdl/sdl-graphics.cpp | 5 +++++ backends/graphics/sdl/sdl-graphics.h | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'backends') diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp index 15d896c57a..05cc4ff04a 100644 --- a/backends/graphics/sdl/sdl-graphics.cpp +++ b/backends/graphics/sdl/sdl-graphics.cpp @@ -1396,6 +1396,11 @@ void SdlGraphicsManager::setShakePos(int shake_pos) { _newShakePos = shake_pos; } +void SdlGraphicsManager::setFocusRectangle(const Common::Rect& rect) { +} + +void SdlGraphicsManager::clearFocusRectangle() { +} #pragma mark - #pragma mark --- Overlays --- diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h index 0daaab104c..f912fc881b 100644 --- a/backends/graphics/sdl/sdl-graphics.h +++ b/backends/graphics/sdl/sdl-graphics.h @@ -114,8 +114,8 @@ public: virtual void fillScreen(uint32 col); virtual void updateScreen(); virtual void setShakePos(int shakeOffset); - virtual void setFocusRectangle(const Common::Rect& rect) {} - virtual void clearFocusRectangle() {} + virtual void setFocusRectangle(const Common::Rect& rect); + virtual void clearFocusRectangle(); virtual void showOverlay(); virtual void hideOverlay(); -- cgit v1.2.3 From 466030443a925b27625a7151679e252dc956c817 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 24 Feb 2011 01:11:16 +0100 Subject: SDL: Add a debug focus rect implementation. This implementation currently draws a rect frame around the focus rect area. --- backends/graphics/sdl/sdl-graphics.cpp | 100 ++++++++++++++++++++++++++++++++- backends/graphics/sdl/sdl-graphics.h | 9 +++ 2 files changed, 107 insertions(+), 2 deletions(-) (limited to 'backends') diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp index 05cc4ff04a..3cda8aabac 100644 --- a/backends/graphics/sdl/sdl-graphics.cpp +++ b/backends/graphics/sdl/sdl-graphics.cpp @@ -141,7 +141,11 @@ SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *sdlEventSource) _currentShakePos(0), _newShakePos(0), _paletteDirtyStart(0), _paletteDirtyEnd(0), _screenIsLocked(false), - _graphicsMutex(0), _transactionMode(kTransactionNone) { + _graphicsMutex(0), +#ifdef USE_SDL_DEBUG_FOCUSRECT + _enableFocusRect(false), _focusRect(), +#endif + _transactionMode(kTransactionNone) { if (SDL_InitSubSystem(SDL_INIT_VIDEO) == -1) { error("Could not initialize SDL: %s", SDL_GetError()); @@ -1103,6 +1107,79 @@ void SdlGraphicsManager::internUpdateScreen() { SDL_BlitSurface(_osdSurface, 0, _hwscreen, 0); } #endif + +#ifdef USE_SDL_DEBUG_FOCUSRECT + // 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) { + int y = _focusRect.top + _currentShakePos; + int h = 0; + int x = _focusRect.left * scale1; + int w = _focusRect.width() * scale1; + + if (y < height) { + h = _focusRect.height(); + if (h > height - y) + h = height - y; + + y *= scale1; + + if (_videoMode.aspectRatioCorrection && !_overlayVisible) + y = real2Aspect(y); + + if (h > 0 && w > 0) { + SDL_LockSurface(_hwscreen); + + // Use white as color for now. + Uint32 rectColor = SDL_MapRGB(_hwscreen->format, 0xFF, 0xFF, 0xFF); + + // First draw the top and bottom lines + // then draw the left and right lines + if (_hwscreen->format->BytesPerPixel == 2) { + uint16 *top = (uint16 *)((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 2); + uint16 *bottom = (uint16 *)((byte *)_hwscreen->pixels + (y + h) * _hwscreen->pitch + x * 2); + byte *left = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 2); + byte *right = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + (x + w - 1) * 2); + + while (w--) { + *top++ = rectColor; + *bottom++ = rectColor; + } + + while (h--) { + *(uint16 *)left = rectColor; + *(uint16 *)right = rectColor; + + left += _hwscreen->pitch; + right += _hwscreen->pitch; + } + } else if (_hwscreen->format->BytesPerPixel == 4) { + uint32 *top = (uint32 *)((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 4); + uint32 *bottom = (uint32 *)((byte *)_hwscreen->pixels + (y + h) * _hwscreen->pitch + x * 4); + byte *left = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + x * 4); + byte *right = ((byte *)_hwscreen->pixels + y * _hwscreen->pitch + (x + w - 1) * 4); + + while (w--) { + *top++ = rectColor; + *bottom++ = rectColor; + } + + while (h--) { + *(uint32 *)left = rectColor; + *(uint32 *)right = rectColor; + + left += _hwscreen->pitch; + right += _hwscreen->pitch; + } + } + + SDL_UnlockSurface(_hwscreen); + } + } + } +#endif + // Finally, blit all our changes to the screen SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList); } @@ -1396,10 +1473,29 @@ void SdlGraphicsManager::setShakePos(int shake_pos) { _newShakePos = shake_pos; } -void SdlGraphicsManager::setFocusRectangle(const Common::Rect& rect) { +void SdlGraphicsManager::setFocusRectangle(const Common::Rect &rect) { +#ifdef USE_SDL_DEBUG_FOCUSRECT + _enableFocusRect = true; + _focusRect = rect; + + // It's gross but we actually sometimes get rects, which are not inside the screen bounds, + // thus we need to clip the rect here... + _focusRect.clip(_videoMode.screenWidth, _videoMode.screenHeight); + + // 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()); +#endif } void SdlGraphicsManager::clearFocusRectangle() { +#ifdef USE_SDL_DEBUG_FOCUSRECT + _enableFocusRect = false; + + // 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()); +#endif } #pragma mark - diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h index f912fc881b..a5a8b2b385 100644 --- a/backends/graphics/sdl/sdl-graphics.h +++ b/backends/graphics/sdl/sdl-graphics.h @@ -35,6 +35,10 @@ #include "backends/platform/sdl/sdl-sys.h" +#ifndef RELEASE_BUILD +// Define this to allow for focus rectangle debugging +#define USE_SDL_DEBUG_FOCUSRECT +#endif #if !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) // Uncomment this to enable the 'on screen display' code. @@ -301,6 +305,11 @@ protected: */ OSystem::MutexRef _graphicsMutex; +#ifdef USE_SDL_DEBUG_FOCUSRECT + bool _enableFocusRect; + Common::Rect _focusRect; +#endif + virtual void addDirtyRect(int x, int y, int w, int h, bool realCoordinates = false); virtual void drawMouse(); -- cgit v1.2.3 From 87f260a66c94f4632a2f646dd64f45f9f02d027f Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 24 Feb 2011 01:15:27 +0100 Subject: SDL: Add config file variable to enable the focus rect debug code. The variable is named "use_sdl_debug_focusrect" for now. The debug code is still only enabled, when a ScummVM debug version is built though. --- backends/graphics/sdl/sdl-graphics.cpp | 15 ++++++++++++++- backends/graphics/sdl/sdl-graphics.h | 1 + 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp index 3cda8aabac..dc63c88b5c 100644 --- a/backends/graphics/sdl/sdl-graphics.cpp +++ b/backends/graphics/sdl/sdl-graphics.cpp @@ -143,7 +143,7 @@ SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *sdlEventSource) _screenIsLocked(false), _graphicsMutex(0), #ifdef USE_SDL_DEBUG_FOCUSRECT - _enableFocusRect(false), _focusRect(), + _enableFocusRectDebugCode(false), _enableFocusRect(false), _focusRect(), #endif _transactionMode(kTransactionNone) { @@ -172,6 +172,11 @@ SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *sdlEventSource) } #endif +#ifdef USE_SDL_DEBUG_FOCUSRECT + if (ConfMan.hasKey("use_sdl_debug_focusrect")) + _enableFocusRectDebugCode = ConfMan.getBool("use_sdl_debug_focusrect"); +#endif + SDL_ShowCursor(SDL_DISABLE); memset(&_oldVideoMode, 0, sizeof(_oldVideoMode)); @@ -1475,6 +1480,10 @@ void SdlGraphicsManager::setShakePos(int shake_pos) { void SdlGraphicsManager::setFocusRectangle(const Common::Rect &rect) { #ifdef USE_SDL_DEBUG_FOCUSRECT + // Only enable focus rectangle debug code, when the user wants it + if (!_enableFocusRectDebugCode) + return; + _enableFocusRect = true; _focusRect = rect; @@ -1490,6 +1499,10 @@ void SdlGraphicsManager::setFocusRectangle(const Common::Rect &rect) { void SdlGraphicsManager::clearFocusRectangle() { #ifdef USE_SDL_DEBUG_FOCUSRECT + // Only enable focus rectangle debug code, when the user wants it + if (!_enableFocusRectDebugCode) + return; + _enableFocusRect = false; // We just fake this as a dirty rect for now, to easily force an screen update whenever diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h index a5a8b2b385..f467c38d5f 100644 --- a/backends/graphics/sdl/sdl-graphics.h +++ b/backends/graphics/sdl/sdl-graphics.h @@ -306,6 +306,7 @@ protected: OSystem::MutexRef _graphicsMutex; #ifdef USE_SDL_DEBUG_FOCUSRECT + bool _enableFocusRectDebugCode; bool _enableFocusRect; Common::Rect _focusRect; #endif -- cgit v1.2.3 From 7f139f8dcfab740d6dacc2ea5e3a916618e7ce8f Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 24 Feb 2011 01:19:10 +0100 Subject: SDL: Output a warning in case the focus rect does not fit inside the screen. Sadly it seems the engines do not care whether their focus rect really fits inside the game screen. To ease finding such instances (which might cause odd clipping by the backend) I added a warning for them. --- backends/graphics/sdl/sdl-graphics.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'backends') diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp index dc63c88b5c..09c4f39636 100644 --- a/backends/graphics/sdl/sdl-graphics.cpp +++ b/backends/graphics/sdl/sdl-graphics.cpp @@ -1487,6 +1487,9 @@ void SdlGraphicsManager::setFocusRectangle(const Common::Rect &rect) { _enableFocusRect = true; _focusRect = rect; + if (rect.left < 0 || rect.top < 0 || rect.right > _videoMode.screenWidth || rect.bottom > _videoMode.screenHeight) + warning("SdlGraphicsManager::setFocusRectangle: Got a rect which does not fit inside the screen bounds: %d,%d,%d,%d", rect.left, rect.top, rect.right, rect.bottom); + // It's gross but we actually sometimes get rects, which are not inside the screen bounds, // thus we need to clip the rect here... _focusRect.clip(_videoMode.screenWidth, _videoMode.screenHeight); -- cgit v1.2.3