aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippos Karapetis2015-12-10 12:45:21 +0200
committerWillem Jan Palenstijn2015-12-23 21:34:00 +0100
commitaa7ec3654dfc8a01c734c41946db5d8e79f3cf9b (patch)
treed915aa85800a78488e7e06e1db1ae0ee81833d37
parent9f7ad4b5f25e3c9d6437f0ac0e5e26dba4cab330 (diff)
downloadscummvm-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.cpp14
-rw-r--r--engines/lab/dispman.cpp39
-rw-r--r--engines/lab/dispman.h3
-rw-r--r--engines/lab/special.cpp56
-rw-r--r--engines/lab/transitions.cpp8
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;
}
/**