From ecb42156ce6f4530f3e5fcaec68544d2ab552565 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Wed, 17 Nov 2010 19:58:19 +0000 Subject: MOHAWK: Cache the Myst screen buffer This is needed for use with sliders. The screen is now updated fewer times as well. svn-id: r54300 --- engines/mohawk/graphics.cpp | 28 +++++++++++++++++++++++----- engines/mohawk/graphics.h | 6 +++++- engines/mohawk/myst.cpp | 21 ++++++++++++++++++--- engines/mohawk/myst.h | 1 + engines/mohawk/myst_scripts.cpp | 18 ++++++++++++++---- 5 files changed, 61 insertions(+), 13 deletions(-) diff --git a/engines/mohawk/graphics.cpp b/engines/mohawk/graphics.cpp index e4f9a009fd..e0dce6369a 100644 --- a/engines/mohawk/graphics.cpp +++ b/engines/mohawk/graphics.cpp @@ -86,6 +86,11 @@ MystGraphics::MystGraphics(MohawkEngine_Myst* vm) : _vm(vm) { } _pictureFile.entries = NULL; + + // Initialize our buffer + _mainScreen = new Graphics::Surface(); + _mainScreen->create(_vm->_system->getWidth(), _vm->_system->getHeight(), _pixelFormat.bytesPerPixel); + _dirtyScreen = false; } MystGraphics::~MystGraphics() { @@ -93,6 +98,9 @@ MystGraphics::~MystGraphics() { delete _jpegDecoder; delete _pictDecoder; delete[] _pictureFile.entries; + + _mainScreen->free(); + delete _mainScreen; } static const char* picFileNames[] = { @@ -144,7 +152,6 @@ void MystGraphics::copyImageSectionToScreen(uint16 image, Common::Rect src, Comm Graphics::Surface *surface = NULL; - // Myst ME uses JPEG/PICT images instead of compressed Windows Bitmaps for room images, // though there are a few weird ones that use that format. For further nonsense with images, // the Macintosh version stores images in external "picture files." We check them before @@ -210,19 +217,30 @@ void MystGraphics::copyImageSectionToScreen(uint16 image, Common::Rect src, Comm // Convert from bitmap coordinates to surface coordinates uint16 top = surface->h - src.top - height; - _vm->_system->copyRectToScreen((byte *)surface->getBasePtr(src.left, top), surface->pitch, dest.left, dest.top, width, height); + for (uint16 i = 0; i < height; i++) + memcpy(_mainScreen->getBasePtr(dest.left, i + dest.top), surface->getBasePtr(src.left, top + i), width * surface->bytesPerPixel); + surface->free(); delete surface; - } - // FIXME: Remove this and update only at certain points - _vm->_system->updateScreen(); + // Mark the screen as dirty + _dirtyScreen = true; + } } void MystGraphics::copyImageToScreen(uint16 image, Common::Rect dest) { copyImageSectionToScreen(image, Common::Rect(0, 0, 544, 333), dest); } +void MystGraphics::updateScreen() { + if (_dirtyScreen) { + // Only copy the buffer to the screen if it's dirty + _vm->_system->copyRectToScreen((byte *)_mainScreen->pixels, _mainScreen->pitch, 0, 0, _mainScreen->w, _mainScreen->h); + _vm->_system->updateScreen(); + _dirtyScreen = false; + } +} + void MystGraphics::showCursor(void) { CursorMan.showMouse(true); _vm->_needsUpdate = true; diff --git a/engines/mohawk/graphics.h b/engines/mohawk/graphics.h index 9419aad277..e44bba213b 100644 --- a/engines/mohawk/graphics.h +++ b/engines/mohawk/graphics.h @@ -101,6 +101,7 @@ public: void showCursor(); void hideCursor(); void changeCursor(uint16); + void updateScreen(); void drawRect(Common::Rect rect, bool active); private: @@ -108,7 +109,6 @@ private: MystBitmap *_bmpDecoder; Graphics::PictDecoder *_pictDecoder; Graphics::JPEGDecoder *_jpegDecoder; - Graphics::PixelFormat _pixelFormat; struct PictureFile { uint32 pictureCount; @@ -123,6 +123,10 @@ private: Common::File picFile; } _pictureFile; + + Graphics::Surface *_mainScreen; + bool _dirtyScreen; + Graphics::PixelFormat _pixelFormat; }; struct SFXERecord { diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp index 39c460edd5..bed917165c 100644 --- a/engines/mohawk/myst.cpp +++ b/engines/mohawk/myst.cpp @@ -299,9 +299,7 @@ Common::Error MohawkEngine_Myst::run() { _resources[_curResource]->handleMouseUp(); } - for (uint16 i = 0; i < _resources.size(); i++) - if (_resources[i]->isEnabled()) - _resources[i]->drawDataToScreen(); + drawResourceImages(); break; case Common::EVENT_LBUTTONDOWN: if (_curResource >= 0) { @@ -450,6 +448,9 @@ void MohawkEngine_Myst::changeToCard(uint16 card) { error("Unknown sound action %d", soundAction); } + // Update the images of each area too + drawResourceImages(); + // TODO: Handle Script Resources // Run the entrance script (if present) @@ -739,6 +740,8 @@ void MohawkEngine_Myst::runInitScript() { for (uint16 i = 0; i < scriptCount; i++) delete[] scripts[i].values; delete[] scripts; + + _gfx->updateScreen(); } void MohawkEngine_Myst::runExitScript() { @@ -792,6 +795,8 @@ void MohawkEngine_Myst::runExitScript() { for (uint16 i = 0; i < scriptCount; i++) delete[] scripts[i].values; delete[] scripts; + + _gfx->updateScreen(); } void MohawkEngine_Myst::loadHelp(uint16 id) { @@ -930,6 +935,15 @@ void MohawkEngine_Myst::setResourceEnabled(uint16 resourceId, bool enable) { warning("Attempt to change unknown resource enable state"); } +void MohawkEngine_Myst::drawResourceImages() { + for (uint16 i = 0; i < _resources.size(); i++) + if (_resources[i]->isEnabled()) + _resources[i]->drawDataToScreen(); + + // Make sure the screen is updated + _gfx->updateScreen(); +} + static MystResource *loadResource(MohawkEngine_Myst *vm, Common::SeekableReadStream *rlstStream, MystResource *parent) { uint16 type = rlstStream->readUint16LE(); @@ -1605,6 +1619,7 @@ void MystResourceType12::handleAnimation() { // TODO: Probably not final version. Variable/Type 11 Controlled? if (_doAnimation) { _vm->_gfx->copyImageToScreen(_currentFrame++, _frameRect); + _vm->_gfx->updateScreen(); if ((_currentFrame - _firstFrame) >= _numFrames) _doAnimation = false; } diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h index a66456e1c8..29f26704f9 100644 --- a/engines/mohawk/myst.h +++ b/engines/mohawk/myst.h @@ -413,6 +413,7 @@ private: void drawResourceRects(); void checkCurrentResource(); int16 _curResource; + void drawResourceImages(); uint16 _cursorHintCount; MystCursorHint *_cursorHints; diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp index e397d30df3..a4b493eab4 100644 --- a/engines/mohawk/myst_scripts.cpp +++ b/engines/mohawk/myst_scripts.cpp @@ -381,9 +381,10 @@ void MystScriptParser::opcode_4(uint16 op, uint16 var, uint16 argc, uint16 *argv // the general case, rather than this image blit... uint16 var_value = _vm->_varStore->getVar(var); if (var_value < _vm->_view.scriptResCount) { - if (_vm->_view.scriptResources[var_value].type == 1) // TODO: Add Symbols for Types + if (_vm->_view.scriptResources[var_value].type == 1) { // TODO: Add Symbols for Types _vm->_gfx->copyImageToScreen(_vm->_view.scriptResources[var_value].id, Common::Rect(0, 0, 544, 333)); - else + _vm->_gfx->updateScreen(); + } else warning("Opcode %d: Script Resource %d Type Not Image", op, var_value); } else warning("Opcode %d: var %d value %d outside Script Resource Range %d", op, var, var_value, _vm->_view.scriptResCount); @@ -952,7 +953,7 @@ void MystScriptParser::opcode_35(uint16 op, uint16 var, uint16 argc, uint16 *arg debugC(kDebugScript, "\tdelay: %d", delay); _vm->_gfx->copyImageToScreen(imageId, Common::Rect(0, 0, 544, 333)); - _vm->_system->updateScreen(); + _vm->_gfx->updateScreen(); _vm->_system->delayMillis(delay * 100); _vm->changeToCard(cardId); } else @@ -1685,6 +1686,7 @@ void MystScriptParser::opcode_104(uint16 op, uint16 var, uint16 argc, uint16 *ar // TODO: Need to load the image ids from Script Resources structure of VIEW for (uint16 imageId = 3595; imageId <= 3601; imageId++) { _vm->_gfx->copyImageToScreen(imageId, rect); + _vm->_gfx->updateScreen(); _vm->_system->delayMillis(50); } @@ -2515,6 +2517,7 @@ void MystScriptParser::opcode_122(uint16 op, uint16 var, uint16 argc, uint16 *ar // TODO: Need to load the image ids from Script Resources structure of VIEW for (uint16 imageId = 3601; imageId >= 3595; imageId--) { _vm->_gfx->copyImageToScreen(imageId, rect); + _vm->_gfx->updateScreen(); _vm->_system->delayMillis(50); } @@ -3142,8 +3145,10 @@ void MystScriptParser::opcode_200_run() { else rect = Common::Rect(0, 0, 544, 333); - if (curImageIndex != lastImageIndex) + if (curImageIndex != lastImageIndex) { _vm->_gfx->copyImageToScreen(g_opcode200Parameters.imageBaseId + curImageIndex, rect); + _vm->_gfx->updateScreen(); + } // TODO: Comparison with original engine shows that this simple solution // may not be the correct one and the choice of which sound @@ -3165,6 +3170,7 @@ void MystScriptParser::opcode_200_run() { // Note: The modulus by 6 is because the 6th image is the one at imageBaseId _vm->_gfx->copyImageToScreen(g_opcode200Parameters.imageBaseId + curImageIndex % 6, Common::Rect(0, 0, 544, 333)); + _vm->_gfx->updateScreen(); _vm->_varStore->setVar(g_opcode200Parameters.var, curImageIndex + 1); g_opcode200Parameters.lastCardTime = _vm->_system->getMillis(); @@ -3379,6 +3385,7 @@ void MystScriptParser::opcode_201(uint16 op, uint16 var, uint16 argc, uint16 *ar case kIntroStack: _vm->_system->delayMillis(4 * 1000); _vm->_gfx->copyImageToScreen(4, Common::Rect(0, 0, 544, 333)); + _vm->_gfx->updateScreen(); // TODO : Wait until video ends, then change to card 5 break; case kSeleniticStack: @@ -4327,6 +4334,8 @@ void MystScriptParser::opcode_211_run(void) { lastGridState[i] = gridState[i]; } + _vm->_gfx->updateScreen(); + // Var 23 contains boolean for whether pattern matches correct book pattern i.e. Pattern 158 if (gridState[0] == 0xc3 && gridState[1] == 0x6b && gridState[2] == 0xa3 && gridState[3] == 0x93 && gridState[4] == 0xcc && gridState[5] == 0xfa) @@ -4656,6 +4665,7 @@ void MystScriptParser::opcode_298(uint16 op, uint16 var, uint16 argc, uint16 *ar _vm->_system->delayMillis(20 * 1000); for (uint16 imageId = 3001; imageId <= 3012; imageId++) { _vm->_gfx->copyImageToScreen(imageId, Common::Rect(0, 0, 544, 333)); + _vm->_gfx->updateScreen(); _vm->_system->delayMillis(5 * 1000); } break; -- cgit v1.2.3