LAB: Use Common::String for strings, removing a ton of memory leaks

Also, add a method to properly free room views
This commit is contained in:
Filippos Karapetis 2015-12-19 02:12:42 +02:00 committed by Willem Jan Palenstijn
parent eb70efc900
commit 3e8eaa2c35
11 changed files with 138 additions and 130 deletions

View file

@ -66,7 +66,7 @@ DisplayMan::DisplayMan(LabEngine *vm) : _vm(vm) {
DisplayMan::~DisplayMan() { DisplayMan::~DisplayMan() {
freePict(); freePict();
delete _dispBitMap; delete _dispBitMap;
delete[]_displayBuffer; delete[] _displayBuffer;
} }
// From readPict.c. Reads in pictures and animations from disk. // From readPict.c. Reads in pictures and animations from disk.
@ -92,10 +92,10 @@ void DisplayMan::loadBackPict(const char *fileName, uint16 *highPal) {
/** /**
* Reads in a picture into the display bitmap. * Reads in a picture into the display bitmap.
*/ */
void DisplayMan::readPict(const char *filename, bool playOnce, bool onlyDiffData, byte *memoryBuffer, uint16 maxHeight) { void DisplayMan::readPict(Common::String filename, bool playOnce, bool onlyDiffData, byte *memoryBuffer, uint16 maxHeight) {
_vm->_anim->stopDiff(); _vm->_anim->stopDiff();
loadPict(filename); loadPict(filename.c_str());
_vm->_music->updateMusic(); _vm->_music->updateMusic();

View file

@ -74,7 +74,7 @@ public:
void loadPict(const char *filename); void loadPict(const char *filename);
void loadBackPict(const char *fileName, uint16 *highPal); void loadBackPict(const char *fileName, uint16 *highPal);
void readPict(const char *filename, bool playOnce, bool onlyDiffData = false, byte *memoryBuffer = nullptr, uint16 maxHeight = 0); void readPict(Common::String filename, bool playOnce, bool onlyDiffData = false, byte *memoryBuffer = nullptr, uint16 maxHeight = 0);
void freePict(); void freePict();
void doScrollBlack(); void doScrollBlack();
void copyPage(uint16 width, uint16 height, uint16 nheight, uint16 startline, byte *mem); void copyPage(uint16 width, uint16 height, uint16 nheight, uint16 startline, byte *mem);

View file

@ -130,15 +130,15 @@ void LabEngine::drawRoomMessage(uint16 curInv, CloseDataPtr closePtr) {
} }
if (_alternate) { if (_alternate) {
if ((curInv <= _numInv) && _conditions->in(curInv) && _inventory[curInv]._bitmapName) { if ((curInv <= _numInv) && _conditions->in(curInv) && _inventory[curInv]._bitmapName != "") {
if ((curInv == kItemLamp) && _conditions->in(kCondLampOn)) if ((curInv == kItemLamp) && _conditions->in(kCondLampOn))
// LAB: Labyrinth specific // LAB: Labyrinth specific
drawStaticMessage(kTextkLampOn); drawStaticMessage(kTextkLampOn);
else if (_inventory[curInv]._many > 1) { else if (_inventory[curInv]._many > 1) {
Common::String roomMessage = Common::String(_inventory[curInv]._name) + " (" + Common::String::format("%d", _inventory[curInv]._many) + ")"; Common::String roomMessage = _inventory[curInv]._name + " (" + Common::String::format("%d", _inventory[curInv]._many) + ")";
_graphics->drawMessage(roomMessage.c_str()); _graphics->drawMessage(roomMessage.c_str());
} else } else
_graphics->drawMessage(_inventory[curInv]._name); _graphics->drawMessage(_inventory[curInv]._name.c_str());
} }
} else } else
drawDirection(closePtr); drawDirection(closePtr);
@ -219,7 +219,7 @@ bool LabEngine::doCloseUp(CloseDataPtr closePtr) {
case kMonitorMuseum: case kMonitorMuseum:
case kMonitorLibrary: case kMonitorLibrary:
case kMonitorWindow: case kMonitorWindow:
doMonitor(closePtr->_graphicName, closePtr->_message, false, textRect); doMonitor(closePtr->_graphicName.c_str(), closePtr->_message.c_str(), false, textRect);
break; break;
case kMonitorGramophone: case kMonitorGramophone:
textRect.right = 171; textRect.right = 171;
@ -261,7 +261,7 @@ bool LabEngine::doCloseUp(CloseDataPtr closePtr) {
/** /**
* Gets the current inventory name. * Gets the current inventory name.
*/ */
const char *LabEngine::getInvName(uint16 curInv) { Common::String LabEngine::getInvName(uint16 curInv) {
if (_mainDisplay) if (_mainDisplay)
return _inventory[curInv]._bitmapName; return _inventory[curInv]._bitmapName;
@ -401,7 +401,7 @@ void LabEngine::decIncInv(uint16 *curInv, bool decreaseFl) {
interfaceOff(); interfaceOff();
while (newInv && (newInv <= _numInv)) { while (newInv && (newInv <= _numInv)) {
if (_conditions->in(newInv) && _inventory[newInv]._bitmapName) { if (_conditions->in(newInv) && _inventory[newInv]._bitmapName != "") {
_nextFileName = getInvName(newInv); _nextFileName = getInvName(newInv);
*curInv = newInv; *curInv = newInv;
break; break;
@ -477,11 +477,11 @@ void LabEngine::mainGameLoop() {
if (_noUpdateDiff) { if (_noUpdateDiff) {
// Potentially entered another room // Potentially entered another room
_roomsFound->inclElement(_roomNum); _roomsFound->inclElement(_roomNum);
forceDraw |= (strcmp(_nextFileName, _curFileName) != 0); forceDraw |= (_nextFileName != _curFileName);
_noUpdateDiff = false; _noUpdateDiff = false;
_curFileName = _nextFileName; _curFileName = _nextFileName;
} else if (strcmp(_nextFileName, _curFileName) != 0) { } else if (_nextFileName != _curFileName) {
interfaceOff(); interfaceOff();
// Potentially entered another room // Potentially entered another room
_roomsFound->inclElement(_roomNum); _roomsFound->inclElement(_roomNum);
@ -491,19 +491,19 @@ void LabEngine::mainGameLoop() {
switch (_closeDataPtr->_closeUpType) { switch (_closeDataPtr->_closeUpType) {
case SPECIALLOCK: case SPECIALLOCK:
if (_mainDisplay) if (_mainDisplay)
_tilePuzzle->showCombination(_curFileName); _tilePuzzle->showCombination(_curFileName.c_str());
break; break;
case SPECIALBRICK: case SPECIALBRICK:
case SPECIALBRICKNOMOUSE: case SPECIALBRICKNOMOUSE:
if (_mainDisplay) if (_mainDisplay)
_tilePuzzle->showTile(_curFileName, (_closeDataPtr->_closeUpType == SPECIALBRICKNOMOUSE)); _tilePuzzle->showTile(_curFileName.c_str(), (_closeDataPtr->_closeUpType == SPECIALBRICKNOMOUSE));
break; break;
default: default:
_graphics->readPict(_curFileName, false); _graphics->readPict(_curFileName.c_str(), false);
break; break;
} }
} else } else
_graphics->readPict(_curFileName, false); _graphics->readPict(_curFileName.c_str(), false);
drawRoomMessage(curInv, _closeDataPtr); drawRoomMessage(curInv, _closeDataPtr);
forceDraw = false; forceDraw = false;
@ -577,23 +577,8 @@ void LabEngine::mainGameLoop() {
delete _conditions; delete _conditions;
delete _roomsFound; delete _roomsFound;
delete[] _rooms;
if (_rooms) { delete[] _inventory;
delete[] _rooms;
_rooms = nullptr;
}
if (_inventory) {
for (int i = 1; i <= _numInv; i++) {
if (_inventory[i]._name)
delete[] _inventory[i]._name;
if (_inventory[i]._bitmapName)
delete[] _inventory[i]._bitmapName;
}
delete[] _inventory;
}
} }
void LabEngine::showLab2Teaser() { void LabEngine::showLab2Teaser() {
@ -1014,7 +999,7 @@ void LabEngine::processAltButton(uint16 &curInv, uint16 &lastInv, uint16 buttonI
curInv++; curInv++;
} }
if ((curInv <= _numInv) && _conditions->in(curInv) && _inventory[curInv]._bitmapName) if ((curInv <= _numInv) && _conditions->in(curInv) && _inventory[curInv]._bitmapName != "")
_nextFileName = getInvName(curInv); _nextFileName = getInvName(curInv);
break; break;
@ -1112,16 +1097,10 @@ void LabEngine::performAction(uint16 actionMode, Common::Point curPos, uint16 &c
if (_closeDataPtr == tmpClosePtr) { if (_closeDataPtr == tmpClosePtr) {
if (curPos.y < (_utils->vgaScaleY(149) + _utils->svgaCord(2))) if (curPos.y < (_utils->vgaScaleY(149) + _utils->svgaCord(2)))
drawStaticMessage(kTextNothing); drawStaticMessage(kTextNothing);
} } else if (tmpClosePtr->_graphicName != "") {
else if (tmpClosePtr->_graphicName) { _anim->_doBlack = true;
if (*(tmpClosePtr->_graphicName)) { _closeDataPtr = tmpClosePtr;
_anim->_doBlack = true; } else if (curPos.y < (_utils->vgaScaleY(149) + _utils->svgaCord(2)))
_closeDataPtr = tmpClosePtr;
}
else if (curPos.y < (_utils->vgaScaleY(149) + _utils->svgaCord(2)))
drawStaticMessage(kTextNothing);
}
else if (curPos.y < (_utils->vgaScaleY(149) + _utils->svgaCord(2)))
drawStaticMessage(kTextNothing); drawStaticMessage(kTextNothing);
} }
break; break;

View file

@ -96,10 +96,6 @@ LabEngine::LabEngine(OSystem *syst, const ADGameDescription *gameDesc)
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
_invImages[i] = nullptr; _invImages[i] = nullptr;
_curFileName = nullptr;
_nextFileName = nullptr;
_newFileName = nullptr;
_curFileName = " "; _curFileName = " ";
_msgFont = nullptr; _msgFont = nullptr;
_inventory = nullptr; _inventory = nullptr;
@ -120,8 +116,6 @@ LabEngine::LabEngine(OSystem *syst, const ADGameDescription *gameDesc)
_blankJournal = nullptr; _blankJournal = nullptr;
_journalFont = nullptr; _journalFont = nullptr;
_journalText = nullptr;
_journalTextTitle = nullptr;
_journalPage = 0; _journalPage = 0;
_lastPage = false; _lastPage = false;
_monitorPage = 0; _monitorPage = 0;
@ -143,16 +137,21 @@ LabEngine::~LabEngine() {
DebugMan.clearAllDebugChannels(); DebugMan.clearAllDebugChannels();
freeMapData(); freeMapData();
for (uint16 i = 1; i <= _manyRooms; i++)
_resource->freeViews(i);
delete[] _rooms;
delete _event; delete _event;
delete _resource; delete _resource;
delete _music; delete _music;
delete _anim; delete _anim;
delete _graphics; delete _graphics;
delete[] _rooms;
delete _tilePuzzle; delete _tilePuzzle;
delete _utils; delete _utils;
delete _journalBackImage; delete _journalBackImage;
delete _screenImage; delete _screenImage;
_CrtDumpMemoryLeaks();
} }
Common::Error LabEngine::run() { Common::Error LabEngine::run() {

View file

@ -31,7 +31,10 @@
#ifndef LAB_LAB_H #ifndef LAB_LAB_H
#define LAB_LAB_H #define LAB_LAB_H
#define _CRTDBG_MAP_ALLOC
#include "common/system.h" #include "common/system.h"
#include <crtdbg.h>
#include "common/random.h" #include "common/random.h"
#include "common/rect.h" #include "common/rect.h"
#include "common/savefile.h" #include "common/savefile.h"
@ -118,11 +121,11 @@ private:
uint32 _extraGameFeatures; uint32 _extraGameFeatures;
char *_journalText; Common::String _journalText;
char *_journalTextTitle; Common::String _journalTextTitle;
const char *_nextFileName; Common::String _nextFileName;
const char *_newFileName; Common::String _newFileName;
const char *_monitorTextFilename; Common::String _monitorTextFilename;
CloseDataPtr _closeDataPtr; CloseDataPtr _closeDataPtr;
ButtonList _journalButtonList; ButtonList _journalButtonList;
@ -154,7 +157,7 @@ public:
uint32 _crumbTimestamp; uint32 _crumbTimestamp;
const char *_curFileName; Common::String _curFileName;
Anim *_anim; Anim *_anim;
CrumbData _breadCrumbs[MAX_CRUMBS]; CrumbData _breadCrumbs[MAX_CRUMBS];
@ -188,7 +191,7 @@ public:
void changeVolume(int delta); void changeVolume(int delta);
uint16 getDirection() { return _direction; } uint16 getDirection() { return _direction; }
char *getPictName(CloseDataPtr *closePtrList); Common::String getPictName(CloseDataPtr *closePtrList);
uint16 getQuarters(); uint16 getQuarters();
void setDirection(uint16 direction) { _direction = direction; }; void setDirection(uint16 direction) { _direction = direction; };
void setQuarters(uint16 quarters); void setQuarters(uint16 quarters);
@ -205,7 +208,7 @@ private:
void doJournal(); void doJournal();
bool doMainView(CloseDataPtr *closePtrList); bool doMainView(CloseDataPtr *closePtrList);
void doMap(uint16 curRoom); void doMap(uint16 curRoom);
void doMonitor(char *background, char *textfile, bool isinteractive, Common::Rect textRect); void doMonitor(Common::String background, Common::String textfile, bool isinteractive, Common::Rect textRect);
void doNotes(); void doNotes();
bool doOperateRuleSub(int16 itemNum, int16 roomNum, CloseDataPtr closePtr, CloseDataPtr *setCloseList, bool allowDefaults); bool doOperateRuleSub(int16 itemNum, int16 roomNum, CloseDataPtr closePtr, CloseDataPtr *setCloseList, bool allowDefaults);
bool doOperateRule(Common::Point pos, int16 ItemNum, CloseDataPtr *closePtrList); bool doOperateRule(Common::Point pos, int16 ItemNum, CloseDataPtr *closePtrList);
@ -228,7 +231,7 @@ private:
void freeScreens(); void freeScreens();
bool fromCrumbs(uint32 tmpClass, uint16 code, uint16 qualifier, Common::Point tmpPos, bool fromCrumbs(uint32 tmpClass, uint16 code, uint16 qualifier, Common::Point tmpPos,
uint16 &curInv, IntuiMessage *curMsg, bool &forceDraw, uint16 buttonId, uint16 &actionMode); uint16 &curInv, IntuiMessage *curMsg, bool &forceDraw, uint16 buttonId, uint16 &actionMode);
const char *getInvName(uint16 curInv); Common::String getInvName(uint16 curInv);
uint16 getLowerFloor(uint16 floorNum); uint16 getLowerFloor(uint16 floorNum);
CloseData *getObject(Common::Point pos, CloseDataPtr closePtr); CloseData *getObject(Common::Point pos, CloseDataPtr closePtr);
uint16 getUpperFloor(uint16 floorNum); uint16 getUpperFloor(uint16 floorNum);

View file

@ -404,8 +404,8 @@ void LabEngine::drawMap(uint16 curRoom, uint16 curMsg, uint16 floorNum, bool fad
_graphics->flowText(_msgFont, 0, 5, 3, true, true, true, true, _utils->vgaRectScale(14, 75, 134, 97), textPrt); _graphics->flowText(_msgFont, 0, 5, 3, true, true, true, true, _utils->vgaRectScale(14, 75, 134, 97), textPrt);
} }
if (_rooms[curMsg]._roomMsg) if (_rooms[curMsg]._roomMsg != "")
_graphics->flowText(_msgFont, 0, 5, 3, true, true, true, true, _utils->vgaRectScale(14, 148, 134, 186), _rooms[curMsg]._roomMsg); _graphics->flowText(_msgFont, 0, 5, 3, true, true, true, true, _utils->vgaRectScale(14, 148, 134, 186), _rooms[curMsg]._roomMsg.c_str());
if (fadeIn) if (fadeIn)
_graphics->fade(true, 0); _graphics->fade(true, 0);
@ -535,11 +535,11 @@ void LabEngine::processMap(uint16 curRoom) {
} }
if (oldMsg != curMsg) { if (oldMsg != curMsg) {
if (_rooms[curMsg]._roomMsg == nullptr) if (_rooms[curMsg]._roomMsg != "")
_resource->readViews(curMsg); _resource->readViews(curMsg);
char *sptr; const char *sptr;
if ((sptr = _rooms[curMsg]._roomMsg)) { if ((sptr = _rooms[curMsg]._roomMsg.c_str())) {
_event->mouseHide(); _event->mouseHide();
_graphics->setPen(3); _graphics->setPen(3);
_graphics->rectFillScaled(13, 148, 135, 186); _graphics->rectFillScaled(13, 148, 135, 186);

View file

@ -69,7 +69,7 @@ bool LabEngine::checkConditions(int16 *condition) {
* Gets the current ViewDataPointer. * Gets the current ViewDataPointer.
*/ */
ViewData *LabEngine::getViewData(uint16 roomNum, uint16 direction) { ViewData *LabEngine::getViewData(uint16 roomNum, uint16 direction) {
if (!_rooms[roomNum]._roomMsg) if (_rooms[roomNum]._roomMsg == "")
_resource->readViews(roomNum); _resource->readViews(roomNum);
ViewData *view = _rooms[roomNum]._view[direction]; ViewData *view = _rooms[roomNum]._view[direction];
@ -135,7 +135,7 @@ CloseDataPtr LabEngine::findClosePtrMatch(CloseDataPtr closePtr, CloseDataPtr cl
/** /**
* Returns the current picture name. * Returns the current picture name.
*/ */
char *LabEngine::getPictName(CloseDataPtr *closePtrList) { Common::String LabEngine::getPictName(CloseDataPtr *closePtrList) {
ViewData *viewPtr = getViewData(_roomNum, _direction); ViewData *viewPtr = getViewData(_roomNum, _direction);
if (*closePtrList) { if (*closePtrList) {
@ -152,15 +152,15 @@ char *LabEngine::getPictName(CloseDataPtr *closePtrList) {
* Draws the current direction to the screen. * Draws the current direction to the screen.
*/ */
void LabEngine::drawDirection(CloseDataPtr closePtr) { void LabEngine::drawDirection(CloseDataPtr closePtr) {
if (closePtr && closePtr->_message) { if (closePtr && closePtr->_message != "") {
_graphics->drawMessage(closePtr->_message); _graphics->drawMessage(closePtr->_message.c_str());
return; return;
} }
Common::String message; Common::String message;
if (_rooms[_roomNum]._roomMsg) { if (_rooms[_roomNum]._roomMsg != "") {
message += _rooms[_roomNum]._roomMsg; message = Common::String(_rooms[_roomNum]._roomMsg).c_str();
message += ", "; message += ", ";
} }
@ -228,7 +228,7 @@ void LabEngine::setCurrentClose(Common::Point pos, CloseDataPtr *closePtrList, b
else else
target = Common::Rect(_utils->scaleX(closePtr->_x1), _utils->scaleY(closePtr->_y1), _utils->scaleX(closePtr->_x2), _utils->scaleY(closePtr->_y2)); target = Common::Rect(_utils->scaleX(closePtr->_x1), _utils->scaleY(closePtr->_y1), _utils->scaleX(closePtr->_x2), _utils->scaleY(closePtr->_y2));
if (target.contains(pos) && closePtr->_graphicName) { if (target.contains(pos) && closePtr->_graphicName != "") {
*closePtrList = closePtr; *closePtrList = closePtr;
return; return;
} }
@ -320,11 +320,11 @@ void LabEngine::doActions(Action *actionList, CloseDataPtr *closePtrList) {
break; break;
case SHOWCURPICT: { case SHOWCURPICT: {
char *test = getPictName(closePtrList); Common::String test = getPictName(closePtrList);
if (strcmp(test, _curFileName) != 0) { if (test != _curFileName) {
_curFileName = test; _curFileName = test;
_graphics->readPict(_curFileName, true); _graphics->readPict(_curFileName.c_str(), true);
} }
} }
break; break;

View file

@ -95,15 +95,15 @@ struct CloseData {
uint16 _x1, _y1, _x2, _y2; uint16 _x1, _y1, _x2, _y2;
int16 _closeUpType; // if > 0, an object. If < 0, an item int16 _closeUpType; // if > 0, an object. If < 0, an item
uint16 _depth; // Level of the closeup. uint16 _depth; // Level of the closeup.
char *_graphicName; Common::String _graphicName;
char *_message; Common::String _message;
CloseData *_nextCloseUp; CloseData *_nextCloseUp;
CloseData *_subCloseUps; CloseData *_subCloseUps;
}; };
struct ViewData { struct ViewData {
int16 *_condition; int16 *_condition;
char *_graphicName; Common::String _graphicName;
ViewData *_nextCondition; ViewData *_nextCondition;
CloseDataPtr _closeUps; CloseDataPtr _closeUps;
}; };
@ -131,13 +131,13 @@ struct RoomData {
byte _transitionType; byte _transitionType;
ViewData *_view[4]; ViewData *_view[4];
RuleList *_rules; RuleList *_rules;
char *_roomMsg; Common::String _roomMsg;
}; };
struct InventoryData { struct InventoryData {
uint16 _many; uint16 _many;
char *_name; Common::String _name;
char *_bitmapName; Common::String _bitmapName;
}; };
// Map Flags // Map Flags

View file

@ -73,7 +73,7 @@ TextFont *Resource::getFont(const char *fileName) {
return textfont; return textfont;
} }
char *Resource::getText(const char *fileName) { Common::String Resource::getText(const char *fileName) {
Common::File *dataFile = openDataFile(fileName); Common::File *dataFile = openDataFile(fileName);
_vm->_music->updateMusic(); _vm->_music->updateMusic();
@ -87,7 +87,11 @@ char *Resource::getText(const char *fileName) {
*text++ -= (byte)95; *text++ -= (byte)95;
delete dataFile; delete dataFile;
return (char *)buffer;
Common::String str = (char *)buffer;
delete[] buffer;
return str;
} }
bool Resource::readRoomData(const char *fileName) { bool Resource::readRoomData(const char *fileName) {
@ -110,7 +114,7 @@ bool Resource::readRoomData(const char *fileName) {
_vm->_rooms[i]._view[EAST] = nullptr; _vm->_rooms[i]._view[EAST] = nullptr;
_vm->_rooms[i]._view[WEST] = nullptr; _vm->_rooms[i]._view[WEST] = nullptr;
_vm->_rooms[i]._rules = nullptr; _vm->_rooms[i]._rules = nullptr;
_vm->_rooms[i]._roomMsg = nullptr; _vm->_rooms[i]._roomMsg = "";
} }
delete dataFile; delete dataFile;
@ -138,6 +142,8 @@ bool Resource::readViews(uint16 roomNum) {
Common::String fileName = "LAB:Rooms/" + Common::String::format("%d", roomNum); Common::String fileName = "LAB:Rooms/" + Common::String::format("%d", roomNum);
Common::File *dataFile = openDataFile(fileName.c_str(), MKTAG('R', 'O', 'M', '4')); Common::File *dataFile = openDataFile(fileName.c_str(), MKTAG('R', 'O', 'M', '4'));
freeViews(roomNum);
_vm->_rooms[roomNum]._roomMsg = readString(dataFile); _vm->_rooms[roomNum]._roomMsg = readString(dataFile);
_vm->_rooms[roomNum]._view[NORTH] = readView(dataFile); _vm->_rooms[roomNum]._view[NORTH] = readView(dataFile);
_vm->_rooms[roomNum]._view[SOUTH] = readView(dataFile); _vm->_rooms[roomNum]._view[SOUTH] = readView(dataFile);
@ -151,6 +157,25 @@ bool Resource::readViews(uint16 roomNum) {
return true; return true;
} }
void Resource::freeViews(uint16 roomNum) {
for (uint16 i = 0; i < 4; i++) {
delete _vm->_rooms[roomNum]._view[i];
_vm->_rooms[roomNum]._view[i] = nullptr;
}
if (_vm->_rooms[roomNum]._rules) {
for (RuleList::iterator rule = _vm->_rooms[roomNum]._rules->begin(); rule != _vm->_rooms[roomNum]._rules->end(); ++rule) {
delete (*rule)->_actionList;
delete[](*rule)->_condition;
delete *rule;
*rule = nullptr;
}
delete _vm->_rooms[roomNum]._rules;
_vm->_rooms[roomNum]._rules = nullptr;
}
}
Common::String Resource::translateFileName(Common::String filename) { Common::String Resource::translateFileName(Common::String filename) {
filename.toUppercase(); filename.toUppercase();
Common::String fileNameStrFinal; Common::String fileNameStrFinal;
@ -209,17 +234,18 @@ Common::File *Resource::openDataFile(const char *fileName, uint32 fileHeader) {
return dataFile; return dataFile;
} }
char *Resource::readString(Common::File *file) { Common::String Resource::readString(Common::File *file) {
byte size = file->readByte(); byte size = file->readByte();
if (!size) if (!size)
return NULL; return nullptr;
char *str = new char[size];
char *c = str; Common::String str;
char c;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
*c = file->readByte(); c = file->readByte();
// Decrypt char // Decrypt char
*c = (i < size - 1) ? *c - 95 : '\0'; c = (i < size - 1) ? c - 95 : '\0';
c++; str += c;
} }
return str; return str;
@ -247,7 +273,7 @@ RuleList *Resource::readRule(Common::File *file) {
c = file->readByte(); c = file->readByte();
if (c == 1) { if (c == 1) {
Rule *rule = new Rule();; Rule *rule = new Rule();
rule->_ruleType = file->readSint16LE(); rule->_ruleType = file->readSint16LE();
rule->_param1 = file->readSint16LE(); rule->_param1 = file->readSint16LE();
rule->_param2 = file->readSint16LE(); rule->_param2 = file->readSint16LE();
@ -282,13 +308,20 @@ Action *Resource::readAction(Common::File *file) {
if (action->_actionType == SHOWMESSAGES) { if (action->_actionType == SHOWMESSAGES) {
char **messages = (char **)malloc(action->_param1 * 4); char **messages = (char **)malloc(action->_param1 * 4);
Common::String tmp;
for (int i = 0; i < action->_param1; i++) for (int i = 0; i < action->_param1; i++) {
messages[i] = readString(file); tmp = readString(file);
messages[i] = (char *)malloc(tmp.size()); // FIXME: memory leak!
memcpy(messages[i], tmp.c_str(), tmp.size());
}
action->_data = (byte *)messages; action->_data = (byte *)messages;
} else { } else {
action->_data = (byte *)readString(file); Common::String tmp;
tmp = readString(file);
action->_data = (byte *)malloc(tmp.size()); // FIXME: memory leak!
memcpy(action->_data, tmp.c_str(), tmp.size());
} }
action->_nextAction = nullptr; action->_nextAction = nullptr;

View file

@ -101,13 +101,14 @@ public:
bool readRoomData(const char *fileName); bool readRoomData(const char *fileName);
InventoryData *readInventory(const char *fileName); InventoryData *readInventory(const char *fileName);
bool readViews(uint16 roomNum); bool readViews(uint16 roomNum);
void freeViews(uint16 roomNum);
TextFont *getFont(const char *fileName); TextFont *getFont(const char *fileName);
char *getText(const char *fileName); Common::String getText(const char *fileName);
Common::String getStaticText(byte index) const { return _staticText[index]; } Common::String getStaticText(byte index) const { return _staticText[index]; }
private: private:
LabEngine *_vm; LabEngine *_vm;
char *readString(Common::File *file); Common::String readString(Common::File *file);
int16 *readConditions(Common::File *file); int16 *readConditions(Common::File *file);
RuleList *readRule(Common::File *file); RuleList *readRule(Common::File *file);
Action *readAction(Common::File *file); Action *readAction(Common::File *file);

View file

@ -52,13 +52,12 @@ namespace Lab {
*/ */
void LabEngine::doNotes() { void LabEngine::doNotes() {
TextFont *noteFont = _resource->getFont("F:Note.fon"); TextFont *noteFont = _resource->getFont("F:Note.fon");
char *noteText = _resource->getText("Lab:Rooms/Notes"); Common::String noteText = _resource->getText("Lab:Rooms/Notes");
Common::Rect textRect = Common::Rect(_utils->vgaScaleX(25) + _utils->svgaCord(15), _utils->vgaScaleY(50), _utils->vgaScaleX(295) - _utils->svgaCord(15), _utils->vgaScaleY(148)); Common::Rect textRect = Common::Rect(_utils->vgaScaleX(25) + _utils->svgaCord(15), _utils->vgaScaleY(50), _utils->vgaScaleX(295) - _utils->svgaCord(15), _utils->vgaScaleY(148));
_graphics->flowText(noteFont, -2 + _utils->svgaCord(1), 0, 0, false, false, true, true, textRect, noteText); _graphics->flowText(noteFont, -2 + _utils->svgaCord(1), 0, 0, false, false, true, true, textRect, noteText.c_str());
_graphics->setPalette(_anim->_diffPalette, 256); _graphics->setPalette(_anim->_diffPalette, 256);
_graphics->closeFont(noteFont); _graphics->closeFont(noteFont);
delete[] noteText;
} }
/** /**
@ -67,39 +66,35 @@ void LabEngine::doNotes() {
*/ */
void LabEngine::doWestPaper() { void LabEngine::doWestPaper() {
TextFont *paperFont = _resource->getFont("F:News22.fon"); TextFont *paperFont = _resource->getFont("F:News22.fon");
char *paperText = _resource->getText("Lab:Rooms/Date"); Common::String paperText = _resource->getText("Lab:Rooms/Date");
Common::Rect textRect = Common::Rect(_utils->vgaScaleX(57), _utils->vgaScaleY(77) + _utils->svgaCord(2), _utils->vgaScaleX(262), _utils->vgaScaleY(91)); Common::Rect textRect = Common::Rect(_utils->vgaScaleX(57), _utils->vgaScaleY(77) + _utils->svgaCord(2), _utils->vgaScaleX(262), _utils->vgaScaleY(91));
_graphics->flowText(paperFont, 0, 0, 0, false, true, false, true, textRect, paperText); _graphics->flowText(paperFont, 0, 0, 0, false, true, false, true, textRect, paperText.c_str());
_graphics->closeFont(paperFont); _graphics->closeFont(paperFont);
delete[] paperText;
paperFont = _resource->getFont("F:News32.fon"); paperFont = _resource->getFont("F:News32.fon");
paperText = _resource->getText("Lab:Rooms/Headline"); paperText = _resource->getText("Lab:Rooms/Headline");
int fileLen = strlen(paperText) - 1; int fileLen = paperText.size() - 1;
textRect = Common::Rect(_utils->vgaScaleX(57), _utils->vgaScaleY(86) - _utils->svgaCord(2), _utils->vgaScaleX(262), _utils->vgaScaleY(118)); textRect = Common::Rect(_utils->vgaScaleX(57), _utils->vgaScaleY(86) - _utils->svgaCord(2), _utils->vgaScaleX(262), _utils->vgaScaleY(118));
int charsPrinted = _graphics->flowText(paperFont, -8, 0, 0, false, true, false, true, textRect, paperText); int charsPrinted = _graphics->flowText(paperFont, -8, 0, 0, false, true, false, true, textRect, paperText.c_str());
uint16 y; uint16 y;
if (charsPrinted < fileLen) { if (charsPrinted < fileLen) {
y = 130 - _utils->svgaCord(5); y = 130 - _utils->svgaCord(5);
textRect = Common::Rect(_utils->vgaScaleX(57), _utils->vgaScaleY(86) - _utils->svgaCord(2), _utils->vgaScaleX(262), _utils->vgaScaleY(132)); textRect = Common::Rect(_utils->vgaScaleX(57), _utils->vgaScaleY(86) - _utils->svgaCord(2), _utils->vgaScaleX(262), _utils->vgaScaleY(132));
_graphics->flowText(paperFont, -8 - _utils->svgaCord(1), 0, 0, false, true, false, true, textRect, paperText); _graphics->flowText(paperFont, -8 - _utils->svgaCord(1), 0, 0, false, true, false, true, textRect, paperText.c_str());
} else } else
y = 115 - _utils->svgaCord(5); y = 115 - _utils->svgaCord(5);
_graphics->closeFont(paperFont); _graphics->closeFont(paperFont);
delete[] paperText;
paperFont = _resource->getFont("F:Note.fon"); paperFont = _resource->getFont("F:Note.fon");
paperText = _resource->getText("Lab:Rooms/Col1"); paperText = _resource->getText("Lab:Rooms/Col1");
charsPrinted = _graphics->flowText(paperFont, -4, 0, 0, false, false, false, true, _utils->vgaRectScale(45, y, 158, 148), paperText); charsPrinted = _graphics->flowText(paperFont, -4, 0, 0, false, false, false, true, _utils->vgaRectScale(45, y, 158, 148), paperText.c_str());
delete[] paperText;
paperText = _resource->getText("Lab:Rooms/Col2"); paperText = _resource->getText("Lab:Rooms/Col2");
charsPrinted = _graphics->flowText(paperFont, -4, 0, 0, false, false, false, true, _utils->vgaRectScale(162, y, 275, 148), paperText); charsPrinted = _graphics->flowText(paperFont, -4, 0, 0, false, false, false, true, _utils->vgaRectScale(162, y, 275, 148), paperText.c_str());
delete[] paperText;
_graphics->closeFont(paperFont); _graphics->closeFont(paperFont);
_graphics->setPalette(_anim->_diffPalette, 256); _graphics->setPalette(_anim->_diffPalette, 256);
@ -167,11 +162,11 @@ void LabEngine::loadJournalData() {
void LabEngine::drawJournalText() { void LabEngine::drawJournalText() {
uint16 drawingToPage = 1; uint16 drawingToPage = 1;
int charsDrawn = 0; int charsDrawn = 0;
char *curText = _journalText; const char *curText = _journalText.c_str();
while (drawingToPage < _journalPage) { while (drawingToPage < _journalPage) {
_music->updateMusic(); _music->updateMusic();
curText = (char *)(_journalText + charsDrawn); curText = (char *)(_journalText.c_str() + charsDrawn);
charsDrawn += _graphics->flowText(_journalFont, -2, 2, 0, false, false, false, false, _utils->vgaRectScale(52, 32, 152, 148), curText); charsDrawn += _graphics->flowText(_journalFont, -2, 2, 0, false, false, false, false, _utils->vgaRectScale(52, 32, 152, 148), curText);
_lastPage = (*curText == 0); _lastPage = (*curText == 0);
@ -183,20 +178,20 @@ void LabEngine::drawJournalText() {
} }
if (_journalPage <= 1) { if (_journalPage <= 1) {
curText = _journalTextTitle; curText = _journalTextTitle.c_str();
_graphics->flowTextToMem(_journalBackImage, _journalFont, -2, 2, 0, false, true, true, true, _utils->vgaRectScale(52, 32, 152, 148), curText); _graphics->flowTextToMem(_journalBackImage, _journalFont, -2, 2, 0, false, true, true, true, _utils->vgaRectScale(52, 32, 152, 148), curText);
} else { } else {
curText = (char *)(_journalText + charsDrawn); curText = (char *)(_journalText.c_str() + charsDrawn);
charsDrawn += _graphics->flowTextToMem(_journalBackImage, _journalFont, -2, 2, 0, false, false, false, true, _utils->vgaRectScale(52, 32, 152, 148), curText); charsDrawn += _graphics->flowTextToMem(_journalBackImage, _journalFont, -2, 2, 0, false, false, false, true, _utils->vgaRectScale(52, 32, 152, 148), curText);
} }
_music->updateMusic(); _music->updateMusic();
curText = (char *)(_journalText + charsDrawn); curText = (char *)(_journalText.c_str() + charsDrawn);
_lastPage = (*curText == 0); _lastPage = (*curText == 0);
_graphics->flowTextToMem(_journalBackImage, _journalFont, -2, 2, 0, false, false, false, true, _utils->vgaRectScale(171, 32, 271, 148), curText); _graphics->flowTextToMem(_journalBackImage, _journalFont, -2, 2, 0, false, false, false, true, _utils->vgaRectScale(171, 32, 271, 148), curText);
curText = (char *)(_journalText + charsDrawn); curText = (char *)(_journalText.c_str() + charsDrawn);
_lastPage |= (*curText == 0); _lastPage = (*curText == 0);
} }
/** /**
@ -386,7 +381,7 @@ void LabEngine::drawMonText(char *text, TextFont *monitorFont, Common::Rect text
* Processes user input. * Processes user input.
*/ */
void LabEngine::processMonitor(char *ntext, TextFont *monitorFont, bool isInteractive, Common::Rect textRect) { void LabEngine::processMonitor(char *ntext, TextFont *monitorFont, bool isInteractive, Common::Rect textRect) {
const char *startFileName = _monitorTextFilename; Common::String startFileName = _monitorTextFilename;
CloseDataPtr startClosePtr = _closeDataPtr, lastClosePtr[10]; CloseDataPtr startClosePtr = _closeDataPtr, lastClosePtr[10];
uint16 depth = 0; uint16 depth = 0;
@ -397,21 +392,20 @@ void LabEngine::processMonitor(char *ntext, TextFont *monitorFont, bool isIntera
if (!_closeDataPtr) if (!_closeDataPtr)
_closeDataPtr = startClosePtr; _closeDataPtr = startClosePtr;
const char *test; Common::String test;
if (_closeDataPtr == startClosePtr) if (_closeDataPtr == startClosePtr)
test = startFileName; test = startFileName;
else else
test = _closeDataPtr->_graphicName; test = _closeDataPtr->_graphicName;
if (strcmp(test, _monitorTextFilename)) { if (test != _monitorTextFilename) {
_monitorPage = 0; _monitorPage = 0;
_monitorTextFilename = test; _monitorTextFilename = test;
ntext = _resource->getText(_monitorTextFilename); Common::String text = _resource->getText(_monitorTextFilename.c_str());
_graphics->fade(false, 0); _graphics->fade(false, 0);
drawMonText(ntext, monitorFont, textRect, isInteractive); drawMonText((char *)text.c_str(), monitorFont, textRect, isInteractive);
_graphics->fade(true, 0); _graphics->fade(true, 0);
delete[] ntext;
} }
} }
@ -481,7 +475,7 @@ void LabEngine::processMonitor(char *ntext, TextFont *monitorFont, bool isIntera
/** /**
* Does what's necessary for the monitor. * Does what's necessary for the monitor.
*/ */
void LabEngine::doMonitor(char *background, char *textfile, bool isinteractive, Common::Rect textRect) { void LabEngine::doMonitor(Common::String background, Common::String textfile, bool isinteractive, Common::Rect textRect) {
Common::Rect scaledRect = _utils->vgaRectScale(textRect.left, textRect.top, textRect.right, textRect.bottom); Common::Rect scaledRect = _utils->vgaRectScale(textRect.left, textRect.top, textRect.right, textRect.bottom);
_monitorTextFilename = textfile; _monitorTextFilename = textfile;
@ -501,15 +495,14 @@ void LabEngine::doMonitor(char *background, char *textfile, bool isinteractive,
_monitorButton = new Image(buttonFile, this); _monitorButton = new Image(buttonFile, this);
delete buttonFile; delete buttonFile;
char *ntext = _resource->getText(textfile); Common::String ntext = _resource->getText(textfile.c_str());
_graphics->loadBackPict(background, _highPalette); _graphics->loadBackPict(background.c_str(), _highPalette);
drawMonText(ntext, monitorFont, scaledRect, isinteractive); drawMonText((char *)ntext.c_str(), monitorFont, scaledRect, isinteractive);
_event->mouseShow(); _event->mouseShow();
_graphics->fade(true, 0); _graphics->fade(true, 0);
processMonitor(ntext, monitorFont, isinteractive, scaledRect); processMonitor((char *)ntext.c_str(), monitorFont, isinteractive, scaledRect);
_graphics->fade(false, 0); _graphics->fade(false, 0);
_event->mouseHide(); _event->mouseHide();
delete[] ntext;
_graphics->closeFont(monitorFont); _graphics->closeFont(monitorFont);
_graphics->setPen(0); _graphics->setPen(0);