LAB: Refactor readPictToMem()

This fixes crashes in the teleporter and the journal, and plugs several
memory leaks
This commit is contained in:
Filippos Karapetis 2015-12-10 12:45:21 +02:00 committed by Willem Jan Palenstijn
parent 9f7ad4b5f2
commit aa7ec3654d
5 changed files with 46 additions and 74 deletions

View file

@ -82,13 +82,13 @@ void Anim::diffNextFrame(bool onlyDiffData) {
// Already done.
return;
if (_vm->_graphics->_dispBitMap->_drawOnScreen) {
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();

View file

@ -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);
@ -93,39 +93,14 @@ void DisplayMan::readPict(const char *filename, bool playOnce, bool onlyDiffData
_vm->_music->stopSoundEffect();
_dispBitMap->_bytesPerRow = _screenWidth;
_dispBitMap->_rows = _screenHeight;
_dispBitMap->_drawOnScreen = true;
_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;

View file

@ -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);

View file

@ -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,15 +67,10 @@ 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->_anim->_noPalChange = true;
g_lab->_graphics->readPict(fileName, true);
for (uint16 i = 0; i < 16; i++) {
@ -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);

View file

@ -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;
}
/**