diff options
author | Filippos Karapetis | 2015-12-10 12:45:21 +0200 |
---|---|---|
committer | Willem Jan Palenstijn | 2015-12-23 21:34:00 +0100 |
commit | aa7ec3654dfc8a01c734c41946db5d8e79f3cf9b (patch) | |
tree | d915aa85800a78488e7e06e1db1ae0ee81833d37 | |
parent | 9f7ad4b5f25e3c9d6437f0ac0e5e26dba4cab330 (diff) | |
download | scummvm-rg350-aa7ec3654dfc8a01c734c41946db5d8e79f3cf9b.tar.gz scummvm-rg350-aa7ec3654dfc8a01c734c41946db5d8e79f3cf9b.tar.bz2 scummvm-rg350-aa7ec3654dfc8a01c734c41946db5d8e79f3cf9b.zip |
LAB: Refactor readPictToMem()
This fixes crashes in the teleporter and the journal, and plugs several
memory leaks
-rw-r--r-- | engines/lab/anim.cpp | 14 | ||||
-rw-r--r-- | engines/lab/dispman.cpp | 39 | ||||
-rw-r--r-- | engines/lab/dispman.h | 3 | ||||
-rw-r--r-- | engines/lab/special.cpp | 56 | ||||
-rw-r--r-- | engines/lab/transitions.cpp | 8 |
5 files changed, 46 insertions, 74 deletions
diff --git a/engines/lab/anim.cpp b/engines/lab/anim.cpp index 936c49223c..20d1473c67 100644 --- a/engines/lab/anim.cpp +++ b/engines/lab/anim.cpp @@ -82,13 +82,13 @@ void Anim::diffNextFrame(bool onlyDiffData) { // Already done. return; - if (_vm->_graphics->_dispBitMap->_drawOnScreen) { - _vm->_graphics->_dispBitMap->_planes[0] = _vm->_graphics->getCurrentDrawingBuffer(); - _vm->_graphics->_dispBitMap->_planes[1] = _vm->_graphics->_dispBitMap->_planes[0] + 0x10000; - _vm->_graphics->_dispBitMap->_planes[2] = _vm->_graphics->_dispBitMap->_planes[1] + 0x10000; - _vm->_graphics->_dispBitMap->_planes[3] = _vm->_graphics->_dispBitMap->_planes[2] + 0x10000; - _vm->_graphics->_dispBitMap->_planes[4] = _vm->_graphics->_dispBitMap->_planes[3] + 0x10000; - } + if (_vm->_graphics->_dispBitMap->_drawOnScreen) + _vm->_graphics->_dispBitMap->_planes[0] = _vm->_graphics->getCurrentDrawingBuffer(); + + _vm->_graphics->_dispBitMap->_planes[1] = _vm->_graphics->_dispBitMap->_planes[0] + 0x10000; + _vm->_graphics->_dispBitMap->_planes[2] = _vm->_graphics->_dispBitMap->_planes[1] + 0x10000; + _vm->_graphics->_dispBitMap->_planes[3] = _vm->_graphics->_dispBitMap->_planes[2] + 0x10000; + _vm->_graphics->_dispBitMap->_planes[4] = _vm->_graphics->_dispBitMap->_planes[3] + 0x10000; _vm->_event->mouseHide(); diff --git a/engines/lab/dispman.cpp b/engines/lab/dispman.cpp index ba2cfc846b..df35f9f29d 100644 --- a/engines/lab/dispman.cpp +++ b/engines/lab/dispman.cpp @@ -80,9 +80,9 @@ void DisplayMan::loadPict(const char *filename) { } /** - * Reads in a picture into the dest bitmap. + * Reads in a picture into the display bitmap. */ -void DisplayMan::readPict(const char *filename, bool playOnce, bool onlyDiffData) { +void DisplayMan::readPict(const char *filename, bool playOnce, bool onlyDiffData, byte *memoryBuffer, uint16 maxHeight) { _vm->_anim->stopDiff(); loadPict(filename); @@ -92,40 +92,15 @@ void DisplayMan::readPict(const char *filename, bool playOnce, bool onlyDiffData if (!_vm->_music->_doNotFilestopSoundEffect) _vm->_music->stopSoundEffect(); - _dispBitMap->_bytesPerRow = _screenWidth; - _dispBitMap->_rows = _screenHeight; - _dispBitMap->_drawOnScreen = true; + _dispBitMap->_bytesPerRow = _screenWidth; + _dispBitMap->_rows = (maxHeight > 0) ? maxHeight : _screenHeight; + _dispBitMap->_drawOnScreen = (memoryBuffer == nullptr); + if (memoryBuffer) + _dispBitMap->_planes[0] = memoryBuffer; _vm->_anim->readDiff(_curBitmap, playOnce, onlyDiffData); } -/** - * Reads in a picture into buffer memory. - */ -byte *DisplayMan::readPictToMem(const char *filename, uint16 width, uint16 height) { - _vm->_anim->stopDiff(); - - loadPict(filename); - - _vm->_music->updateMusic(); - - if (!_vm->_music->_doNotFilestopSoundEffect) - _vm->_music->stopSoundEffect(); - - _dispBitMap->_bytesPerRow = width; - _dispBitMap->_rows = height; - _dispBitMap->_drawOnScreen = false; - _dispBitMap->_planes[0] = _curBitmap; - _dispBitMap->_planes[1] = _dispBitMap->_planes[0] + 0x10000; - _dispBitMap->_planes[2] = _dispBitMap->_planes[1] + 0x10000; - _dispBitMap->_planes[3] = _dispBitMap->_planes[2] + 0x10000; - _dispBitMap->_planes[4] = _dispBitMap->_planes[3] + 0x10000; - - _vm->_anim->readDiff(_curBitmap, true); - - return _curBitmap; -} - void DisplayMan::freePict() { delete _curBitmap; _curBitmap = NULL; diff --git a/engines/lab/dispman.h b/engines/lab/dispman.h index 5938198b87..ad506c4cdf 100644 --- a/engines/lab/dispman.h +++ b/engines/lab/dispman.h @@ -73,9 +73,8 @@ public: virtual ~DisplayMan(); void loadPict(const char *filename); - void readPict(const char *filename, bool playOnce, bool onlyDiffData = false); + void readPict(const char *filename, bool playOnce, bool onlyDiffData = false, byte *memoryBuffer = nullptr, uint16 maxHeight = 0); void freePict(); - byte *readPictToMem(const char *filename, uint16 x, uint16 y); void doScrollBlack(); void copyPage(uint16 width, uint16 height, uint16 nheight, uint16 startline, byte *mem); void doScrollWipe(char *filename); diff --git a/engines/lab/special.cpp b/engines/lab/special.cpp index f0b8152a34..6289cf2583 100644 --- a/engines/lab/special.cpp +++ b/engines/lab/special.cpp @@ -51,7 +51,7 @@ static char *journaltext, *journaltexttitle; static uint16 JPage = 0; static bool lastpage = false; static Image JBackImage, ScreenImage; -static bool GotBackImage = false; +static byte *_blankJournal; static uint16 monitorPage; static const char *TextFileName; @@ -67,16 +67,11 @@ Image *MonButton; #define NOCLEAN 152 -static byte *loadBackPict(const char *fileName, bool tomem) { - byte *res = nullptr; - +static void loadBackPict(const char *fileName) { g_lab->_graphics->FadePalette = hipal; - g_lab->_anim->_noPalChange = true; - if (tomem) - res = g_lab->_graphics->readPictToMem(fileName, g_lab->_graphics->_screenWidth, g_lab->_graphics->_screenHeight); - else - g_lab->_graphics->readPict(fileName, true); + g_lab->_anim->_noPalChange = true; + g_lab->_graphics->readPict(fileName, true); for (uint16 i = 0; i < 16; i++) { hipal[i] = ((g_lab->_anim->_diffPalette[i * 3] >> 2) << 8) + @@ -85,8 +80,6 @@ static byte *loadBackPict(const char *fileName, bool tomem) { } g_lab->_anim->_noPalChange = false; - - return res; } /** @@ -184,12 +177,21 @@ void LabEngine::loadJournalData() { Common::File *journalFile = _resource->openDataFile("P:JImage"); Utils *utils = _utils; - _journalGadgetList.push_back(createButton( 80, utils->vgaScaleY(162) + utils->svgaCord(1), 0, VKEY_LTARROW, new Image(journalFile), new Image(journalFile))); // back - _journalGadgetList.push_back(createButton(144, utils->vgaScaleY(164) - utils->svgaCord(1), 1, VKEY_RTARROW, new Image(journalFile), new Image(journalFile))); // foward _journalGadgetList.push_back(createButton(194, utils->vgaScaleY(162) + utils->svgaCord(1), 2, 0, new Image(journalFile), new Image(journalFile))); // cancel - + _journalGadgetList.push_back(createButton(144, utils->vgaScaleY(164) - utils->svgaCord(1), 1, VKEY_RTARROW, new Image(journalFile), new Image(journalFile))); // forward delete journalFile; + + _anim->_noPalChange = true; + JBackImage._imageData = new byte[_graphics->_screenWidth * _graphics->_screenHeight]; + _graphics->readPict("P:Journal.pic", true, false, JBackImage._imageData); + _anim->_noPalChange = false; + + // Keep a copy of the blank journal + _blankJournal = new byte[_graphics->_screenWidth * _graphics->_screenHeight]; + memcpy(_blankJournal, JBackImage._imageData, _graphics->_screenWidth * _graphics->_screenHeight); + + ScreenImage._imageData = _graphics->getCurrentDrawingBuffer(); } /** @@ -256,15 +258,11 @@ static void turnPage(bool fromLeft) { */ void LabEngine::drawJournal(uint16 wipenum, bool needFade) { _event->mouseHide(); - _music->updateMusic(); - - if (!GotBackImage) - JBackImage._imageData = loadBackPict("P:Journal.pic", true); - drawJournalText(); - ScreenImage._imageData = _graphics->getCurrentDrawingBuffer(); + // TODO: This is only called to set the palette correctly. Refactor, if possible + loadBackPict("P:Journal.pic"); if (wipenum == 0) JBackImage.blitBitmap(0, 0, &ScreenImage, 0, 0, _graphics->_screenWidth, _graphics->_screenHeight, false); @@ -272,7 +270,7 @@ void LabEngine::drawJournal(uint16 wipenum, bool needFade) { turnPage((bool)(wipenum == 1)); Gadget *backGadget = _event->getGadget(0); - Gadget *forwardGadget = _event->getGadget(1); + Gadget *forwardGadget = _event->getGadget(2); if (JPage == 0) disableGadget(backGadget, 15); @@ -284,18 +282,14 @@ void LabEngine::drawJournal(uint16 wipenum, bool needFade) { else enableGadget(forwardGadget); - if (needFade) _graphics->fade(true, 0); - _anim->_noPalChange = true; - JBackImage._imageData = _graphics->readPictToMem("P:Journal.pic", _graphics->_screenWidth, _graphics->_screenHeight); - GotBackImage = true; + // Reset the journal background, so that all the text that has been blitted on it is erased + memcpy(JBackImage._imageData, _blankJournal, _graphics->_screenWidth * _graphics->_screenHeight); eatMessages(); _event->mouseShow(); - - _anim->_noPalChange = false; } /** @@ -343,7 +337,6 @@ void LabEngine::doJournal() { _graphics->blackAllScreen(); lastpage = false; - GotBackImage = false; JBackImage._width = _graphics->_screenWidth; JBackImage._height = _graphics->_screenHeight; @@ -355,15 +348,16 @@ void LabEngine::doJournal() { _music->updateMusic(); loadJournalData(); - drawJournal(0, true); - _event->attachGadgetList(&_journalGadgetList); + drawJournal(0, true); _event->mouseShow(); processJournal(); _event->attachGadgetList(NULL); _graphics->fade(false, 0); _event->mouseHide(); + delete[] _blankJournal; + delete[] JBackImage._imageData; freeButtonList(&_journalGadgetList); _graphics->closeFont(journalFont); @@ -556,7 +550,7 @@ void LabEngine::doMonitor(char *background, char *textfile, bool isinteractive, delete buttonFile; ntext = _resource->getText(textfile); - loadBackPict(background, false); + loadBackPict(background); drawMonText(ntext, monitorFont, x1, y1, x2, y2, isinteractive); _event->mouseShow(); _graphics->fade(true, 0); diff --git a/engines/lab/transitions.cpp b/engines/lab/transitions.cpp index d70da5c548..5f0f419d62 100644 --- a/engines/lab/transitions.cpp +++ b/engines/lab/transitions.cpp @@ -283,12 +283,14 @@ void DisplayMan::doTransWipe(CloseDataPtr *closePtrList, char *filename) { else _vm->_curFileName = _vm->getPictName(closePtrList); - byte *BitMapMem = readPictToMem(_vm->_curFileName, _screenWidth, lastY + 5); + byte *bitMapBuffer = new byte[_screenWidth * (lastY + 5)]; + readPict(_vm->_curFileName, true, false, bitMapBuffer, lastY + 5); + setPalette(_vm->_anim->_diffPalette, 256); imSource._width = _screenWidth; imSource._height = lastY; - imSource._imageData = BitMapMem; + imSource._imageData = bitMapBuffer; imDest._width = _screenWidth; imDest._height = _screenHeight; @@ -319,6 +321,8 @@ void DisplayMan::doTransWipe(CloseDataPtr *closePtrList, char *filename) { } // while } // for i } // for j + + delete[] bitMapBuffer; } /** |