From 9a66bc2e9e3638af940053ac58df36b489b3e345 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 20 Mar 2016 20:47:25 -0400 Subject: TITANIC: More graphics code, clipBounds method --- engines/titanic/direct_draw_surface.cpp | 8 +++- engines/titanic/direct_draw_surface.h | 7 +++- engines/titanic/game_view.cpp | 2 +- engines/titanic/screen_manager.h | 2 +- engines/titanic/video_surface.cpp | 72 ++++++++++++++++++++++++++++++++- engines/titanic/video_surface.h | 13 +++++- graphics/managed_surface.cpp | 2 +- 7 files changed, 98 insertions(+), 8 deletions(-) diff --git a/engines/titanic/direct_draw_surface.cpp b/engines/titanic/direct_draw_surface.cpp index 6ce6f2411a..cf7639cf1b 100644 --- a/engines/titanic/direct_draw_surface.cpp +++ b/engines/titanic/direct_draw_surface.cpp @@ -77,7 +77,13 @@ void DirectDrawSurface::fill(const Common::Rect *bounds, uint32 color) { _surface->fillRect(tempBounds, color); } -void DirectDrawSurface::blitFast(const Common::Point &destPos, DirectDrawSurface *srcSurface, Common::Rect *bounds) { +void DirectDrawSurface::blit(const Common::Rect &destRect, DirectDrawSurface *srcSurface, Common::Rect &srcRect) { + assert(srcSurface); + if (!destRect.isEmpty()) + _surface->transBlitFrom(*srcSurface->_surface, srcRect, destRect, (uint)-1); +} + +void DirectDrawSurface::blit(const Common::Point &destPos, DirectDrawSurface *srcSurface, Common::Rect *bounds) { if (bounds) _surface->blitFrom(*srcSurface->_surface, *bounds, destPos); else diff --git a/engines/titanic/direct_draw_surface.h b/engines/titanic/direct_draw_surface.h index 14988583f0..9a93316f7d 100644 --- a/engines/titanic/direct_draw_surface.h +++ b/engines/titanic/direct_draw_surface.h @@ -102,7 +102,12 @@ public: /** * Copy data from a source surfcae into this one */ - void blitFast(const Common::Point &destPos, DirectDrawSurface *srcSurface, Common::Rect *bounds); + void blit(const Common::Rect &destRect, DirectDrawSurface *srcSurface, Common::Rect &srcRect); + + /** + * Copy data from a source surfcae into this one + */ + void blit(const Common::Point &destPos, DirectDrawSurface *srcSurface, Common::Rect *bounds); }; } // End of namespace Titanic diff --git a/engines/titanic/game_view.cpp b/engines/titanic/game_view.cpp index 88ad095f7b..ecdeb85f9a 100644 --- a/engines/titanic/game_view.cpp +++ b/engines/titanic/game_view.cpp @@ -54,7 +54,7 @@ void CGameView::createSurface(const CResourceKey &key) { // Create a fresh surface CScreenManager::setCurrent(); _surface = CScreenManager::_currentScreenManagerPtr->createSurface(key); - _surface->_field3C = true; + _surface->_blitFlag = true; } void CGameView::draw1() { diff --git a/engines/titanic/screen_manager.h b/engines/titanic/screen_manager.h index 8fe51c57b0..ae3424d9fa 100644 --- a/engines/titanic/screen_manager.h +++ b/engines/titanic/screen_manager.h @@ -148,7 +148,7 @@ public: /** * Sets the video mode */ - virtual void setMode(int width, int height, int bpp, uint numBackSurfaces, bool flag2) = 0; + virtual void setMode(int width, int height, int bpp, uint numBackSurfaces, bool flag2); /** * Handles drawing the cursors diff --git a/engines/titanic/video_surface.cpp b/engines/titanic/video_surface.cpp index 503fd6bfc7..b38a8624ea 100644 --- a/engines/titanic/video_surface.cpp +++ b/engines/titanic/video_surface.cpp @@ -30,8 +30,8 @@ int CVideoSurface::_videoSurfaceCounter = 0; CVideoSurface::CVideoSurface(CScreenManager *screenManager) : _screenManager(screenManager), _rawSurface(nullptr), - _field34(nullptr), _pendingLoad(false), _field3C(false), _field40(0), - _field44(4), _field48(0), _field50(1) { + _field34(nullptr), _pendingLoad(false), _blitFlag(false), + _field40(0), _field44(4), _field48(0), _field50(1) { _videoSurfaceNum = _videoSurfaceCounter++; } @@ -46,6 +46,74 @@ void CVideoSurface::setSurface(CScreenManager *screenManager, DirectDrawSurface _ddSurface = surface; } +void CVideoSurface::blitFrom(const Common::Rect &srcRect, const Common::Rect &destRect, CVideoSurface *srcSurface) { + // TODO: Cases when _blitFlag is false + assert(_blitFlag); + error("TODO"); +} + +void CVideoSurface::clipBounds(Common::Rect &srcRect, Common::Rect &destRect, + CVideoSurface *srcSurface, Common::Rect *subRect, Common::Point *pt) { + if (pt) { + srcRect.left = pt->x; + srcRect.top = pt->y; + } else { + srcRect.left = srcRect.top = 0; + } + + if (subRect) { + destRect.right = destRect.left + subRect->width(); + destRect.bottom = destRect.top + subRect->height(); + srcRect = *subRect; + } else { + srcRect.right = srcRect.left + srcSurface->getWidth(); + srcRect.bottom = srcRect.top + srcSurface->getHeight(); + srcRect = Common::Rect(0, 0, srcSurface->getWidth(), srcSurface->getHeight()); + } + + // Clip destination rect to be on-screen + if (destRect.left < 0) { + srcRect.left -= destRect.left; + destRect.left = 0; + } + if (destRect.top < 0) { + srcRect.top -= destRect.top; + destRect.top = 0; + } + if (destRect.right > getWidth()) { + srcRect.right += getWidth() - destRect.right; + destRect.right = getWidth(); + } + if (destRect.bottom > getHeight()) { + srcRect.bottom += getHeight() - destRect.bottom; + destRect.bottom = getHeight(); + } + + // Clip source rect to be within the source surface + if (srcRect.left < 0) { + destRect.left -= srcRect.left; + srcRect.left = 0; + } + if (srcRect.top < 0) { + destRect.top -= srcRect.top; + srcRect.top = 0; + } + if (srcRect.right > srcSurface->getWidth()) { + destRect.right += srcSurface->getWidth() - srcRect.right; + srcRect.right = srcSurface->getWidth(); + } + if (srcRect.bottom > srcSurface->getHeight()) { + destRect.bottom += srcSurface->getHeight() - srcRect.bottom; + srcRect.bottom = srcSurface->getHeight(); + } + + // Validate that the resulting rects are valid + if (destRect.left >= destRect.right || destRect.top >= destRect.bottom + || srcRect.left >= srcRect.right || srcRect.top >= srcRect.bottom) + error("Invalid rect"); +} + + /*------------------------------------------------------------------------*/ OSVideoSurface::OSVideoSurface(CScreenManager *screenManager, DirectDrawSurface *surface) : diff --git a/engines/titanic/video_surface.h b/engines/titanic/video_surface.h index 7efd8b5c37..88ab2e4d45 100644 --- a/engines/titanic/video_surface.h +++ b/engines/titanic/video_surface.h @@ -39,6 +39,12 @@ class CTargaDecode; class CVideoSurface : public ListItem { friend class CJPEGDecode; friend class CTargaDecode; +private: + /** + * Calculates blitting bounds + */ + void clipBounds(Common::Rect &destRect, Common::Rect &srcRect, + CVideoSurface *srcSurface, Common::Rect *bounds2, Common::Point *pt); protected: static int _videoSurfaceCounter; protected: @@ -55,7 +61,7 @@ protected: int _field50; int _lockCount; public: - bool _field3C; + bool _blitFlag; public: CVideoSurface(CScreenManager *screenManager); virtual ~CVideoSurface(); @@ -141,6 +147,11 @@ public: * Frees the underlying surface */ virtual int freeSurface() { return 0; } + + /** + * Blit from another surface + */ + void blitFrom(const Common::Rect &srcRect, const Common::Rect &destRect, CVideoSurface *srcSurface); }; class OSVideoSurface : public CVideoSurface { diff --git a/graphics/managed_surface.cpp b/graphics/managed_surface.cpp index e493ab9f4e..f3d8813f2e 100644 --- a/graphics/managed_surface.cpp +++ b/graphics/managed_surface.cpp @@ -48,7 +48,7 @@ ManagedSurface::ManagedSurface(int width, int height) : ManagedSurface::ManagedSurface(int width, int height, const Graphics::PixelFormat &pixelFormat) : w(_innerSurface.w), h(_innerSurface.h), pitch(_innerSurface.pitch), format(_innerSurface.format), _disposeAfterUse(DisposeAfterUse::NO), _owner(nullptr) { - create(width, height, format); + create(width, height, pixelFormat); } ManagedSurface::ManagedSurface(ManagedSurface &surf, const Common::Rect &bounds) : -- cgit v1.2.3