From dc0254c1ce10647f179a674e924d17a62640007f Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Thu, 15 Sep 2011 20:50:21 -0400 Subject: PEGASUS: Implement very basic screen updating (new API) --- engines/pegasus/elements.cpp | 11 +++-------- engines/pegasus/graphics.cpp | 37 +++++++++++++++++++++++++++++++++++++ engines/pegasus/graphics.h | 4 ++++ 3 files changed, 44 insertions(+), 8 deletions(-) (limited to 'engines') diff --git a/engines/pegasus/elements.cpp b/engines/pegasus/elements.cpp index 695a6e54b8..f9881e7aaf 100644 --- a/engines/pegasus/elements.cpp +++ b/engines/pegasus/elements.cpp @@ -163,7 +163,7 @@ DropHighlight::DropHighlight(const tDisplayElementID id) : DisplayElement(id) { } void DropHighlight::draw(const Common::Rect &) { - Graphics::Surface *screen = g_system->lockScreen(); + Graphics::Surface *screen = ((PegasusEngine *)g_engine)->_gfx->getWorkArea(); // Since this is only used in two different ways, I'm only // going to implement it in those two ways. Deal with it. @@ -181,8 +181,6 @@ void DropHighlight::draw(const Common::Rect &) { screen->vLine(rect.left - 1, rect.top + 1, rect.bottom - 2, _highlightColor); screen->vLine(rect.right, rect.top + 1, rect.bottom - 2, _highlightColor); } - - g_system->unlockScreen(); } EnergyBar::EnergyBar(const tDisplayElementID id) : DisplayElement(id) { @@ -225,11 +223,8 @@ void EnergyBar::draw(const Common::Rect &r) { Common::Rect levelRect; calcLevelRect(levelRect); - if (r.intersects(levelRect)) { - Graphics::Surface *screen = g_system->lockScreen(); - screen->fillRect(levelRect, _barColor); - g_system->lockScreen(); - } + if (r.intersects(levelRect)) + ((PegasusEngine *)g_engine)->_gfx->getWorkArea()->fillRect(levelRect, _barColor); } void EnergyBar::calcLevelRect(Common::Rect &r) const { diff --git a/engines/pegasus/graphics.cpp b/engines/pegasus/graphics.cpp index abff3df15a..d5d6350ca3 100644 --- a/engines/pegasus/graphics.cpp +++ b/engines/pegasus/graphics.cpp @@ -35,6 +35,9 @@ namespace Pegasus { GraphicsManager::GraphicsManager(PegasusEngine *vm) : _vm(vm) { initGraphics(640, 480, true, NULL); + if (_vm->_system->getScreenFormat().bytesPerPixel == 1) + error("No true color mode available"); + // Old _pictDecoder = new Graphics::PictDecoder(_vm->_system->getScreenFormat()); @@ -45,6 +48,7 @@ GraphicsManager::GraphicsManager(PegasusEngine *vm) : _vm(vm) { _backLayer = kMinAvailableOrder; _frontLayer = kMaxAvailableOrder; _firstDisplayElement = _lastDisplayElement = 0; + _workArea.create(640, 480, _vm->_system->getScreenFormat()); } GraphicsManager::~GraphicsManager() { @@ -57,6 +61,9 @@ GraphicsManager::~GraphicsManager() { delete _cache[i].surface; } } + + // New + _workArea.free(); } Graphics::Surface *GraphicsManager::decodeImage(const Common::String &filename) { @@ -272,5 +279,35 @@ void GraphicsManager::removeDisplayElement(DisplayElement *oldElement) { oldElement->_nextElement = 0; oldElement->_elementIsDisplaying = false; } + +void GraphicsManager::updateDisplay() { + // TODO: Check for cursor move/change + + bool screenDirty = false; + + if (!_dirtyRect.isEmpty()) { + for (DisplayElement *runner = _firstDisplayElement; runner != 0; runner = runner->_nextElement) { + Common::Rect bounds; + runner->getBounds(bounds); + + // TODO: Better logic; it does a bit more work than it probably needs to + // but it should work fine for now. + if (bounds.intersects(_dirtyRect) && runner->validToDraw(_backLayer, _frontLayer)) + runner->draw(bounds); + } + + // Copy only the dirty rect to the screen + g_system->copyRectToScreen((byte *)_workArea.pixels, _workArea.pitch, _dirtyRect.left, _dirtyRect.top, _dirtyRect.width(), _dirtyRect.height()); + + // Mark the screen as dirty + screenDirty = true; + + // Clear the dirty rect + _dirtyRect = Common::Rect(); + } + + if (screenDirty) + g_system->updateScreen(); +} } // End of namespace Pegasus diff --git a/engines/pegasus/graphics.h b/engines/pegasus/graphics.h index d8919e5b5c..d4f9628fa1 100644 --- a/engines/pegasus/graphics.h +++ b/engines/pegasus/graphics.h @@ -66,6 +66,9 @@ public: void invalRect(const Common::Rect &rect); tDisplayOrder getBackOfActiveLayer() const { return _backLayer; } tDisplayOrder getFrontOfActiveLayer() const { return _frontLayer; } + void updateDisplay(); + Graphics::Surface *getWorkArea() { return &_workArea; } + private: PegasusEngine *_vm; @@ -79,6 +82,7 @@ private: Common::Rect _dirtyRect; tDisplayOrder _backLayer, _frontLayer; DisplayElement *_firstDisplayElement, *_lastDisplayElement; + Graphics::Surface _workArea; }; } // End of namespace Pegasus -- cgit v1.2.3