diff options
Diffstat (limited to 'engines/lab')
27 files changed, 591 insertions, 637 deletions
diff --git a/engines/lab/anim.cpp b/engines/lab/anim.cpp index eb825fb4c0..0c01b072c4 100644 --- a/engines/lab/anim.cpp +++ b/engines/lab/anim.cpp @@ -80,6 +80,9 @@ void Anim::setOutputBuffer(byte *memoryBuffer) { _outputBuffer = memoryBuffer; } +uint16 Anim::getDIFFHeight() { + return _headerdata._height; +} void Anim::diffNextFrame(bool onlyDiffData) { if (_lastBlockHeader == 65535) @@ -90,14 +93,12 @@ void Anim::diffNextFrame(bool onlyDiffData) { byte *startOfBuf = _outputBuffer; int bufPitch = _vm->_graphics->_screenWidth; - if (!_outputBuffer) { + if (!startOfBuf) { startOfBuf = _vm->_graphics->getCurrentDrawingBuffer(); drawOnScreen = true; } byte *endOfBuf = startOfBuf + (int)_diffWidth * _diffHeight; - _vm->_event->mouseHide(); - int curBit = 0; while (1) { @@ -217,7 +218,9 @@ void Anim::diffNextFrame(bool onlyDiffData) { _sampleSpeed = _diffFile->readUint16LE(); _diffFile->skip(2); - _vm->_music->playSoundEffect(_sampleSpeed, _size, _diffFile); + // Sound effects embedded in animations are started here. These are + // usually animation-specific, like door opening sounds, and are not looped + _vm->_music->playSoundEffect(_sampleSpeed, _size, false, _diffFile); break; case 65535: diff --git a/engines/lab/anim.h b/engines/lab/anim.h index 1979aa5979..0118403842 100644 --- a/engines/lab/anim.h +++ b/engines/lab/anim.h @@ -66,12 +66,12 @@ private: uint32 _diffHeight; byte *_outputBuffer; + DIFFHeader _headerdata; public: Anim(LabEngine *vm); - virtual ~Anim(); + ~Anim(); - DIFFHeader _headerdata; char _diffPalette[256 * 3]; bool _waitForEffect; // Wait for each sound effect to finish before continuing. bool _doBlack; // Black the screen before new picture @@ -94,6 +94,8 @@ public: * Stops an animation from running. */ void stopDiffEnd(); + + uint16 getDIFFHeight(); }; } // End of namespace Lab diff --git a/engines/lab/console.cpp b/engines/lab/console.cpp index 31b52da0ba..12eafd3789 100644 --- a/engines/lab/console.cpp +++ b/engines/lab/console.cpp @@ -86,7 +86,7 @@ bool Console::Cmd_DumpSceneResources(int argc, const char **argv) { debugPrintf(" (from %s to %s)", directions[rule->_param1], directions[rule->_param2]); debugPrintf("\n"); - Common::List<Action>::iterator action; + ActionList::iterator action; for (action = rule->_actionList.begin(); action != rule->_actionList.end(); ++action) { debugPrintf(" - %s ('%s', %d, %d, %d)\n", actionTypes[action->_actionType], action->_messages[0].c_str(), action->_param1, action->_param2, action->_param3); } @@ -110,7 +110,7 @@ bool Console::Cmd_FindAction(int argc, const char **argv) { _vm->_resource->readViews(i); for (RuleList::iterator rule = _vm->_rooms[i]._rules.begin(); rule != _vm->_rooms[i]._rules.end(); ++rule) { - Common::List<Action>::iterator action; + ActionList::iterator action; for (action = rule->_actionList.begin(); action != rule->_actionList.end(); ++action) { if (action->_actionType == actionId && (action->_param1 == param1 || param1 == -1) && diff --git a/engines/lab/detection.cpp b/engines/lab/detection.cpp index 0810c4cb44..805594bf6a 100644 --- a/engines/lab/detection.cpp +++ b/engines/lab/detection.cpp @@ -43,7 +43,6 @@ static const ADGameDescription labDescriptions[] = { "", { { "doors", 0, "d77536010e7e5ae17ee066323ceb9585", 2537 }, // game/doors - { "notes11", 0, "63e873f659f8f46f9809d16a2bf653c7", 3562 }, // fonts/notes11 { "noteold.fon", 0, "6c1d90ad55149556e79d3f7bfddb4bd7", 9252 }, // game/spict/noteold.fon { NULL, 0, NULL, 0 } }, @@ -57,7 +56,6 @@ static const ADGameDescription labDescriptions[] = { "Lowres", { { "doors", 0, "d77536010e7e5ae17ee066323ceb9585", 2537 }, // game/doors - { "notes11", 0, "63e873f659f8f46f9809d16a2bf653c7", 3562 }, // fonts/notes11 { "64b", 0, "3a84d41bcc6a782f22e8e954bce09721", 39916 }, // game/pict/h2/64b { NULL, 0, NULL, 0 } }, @@ -71,7 +69,6 @@ static const ADGameDescription labDescriptions[] = { "Rerelease", { { "doors", 0, "d77536010e7e5ae17ee066323ceb9585", 2537 }, // game/doors - { "notes11", 0, "63e873f659f8f46f9809d16a2bf653c7", 3562 }, // fonts/notes11 { "noteold.fon", 0, "6c1d90ad55149556e79d3f7bfddb4bd7", 9252 }, // game/spict/noteold.fon { "wyrmkeep",0, "97c7064c54c28b952d37c4ebff6efa50", 52286 }, // game/spict/intro { NULL, 0, NULL, 0 } @@ -94,7 +91,6 @@ static const ADGameDescription labDescriptions[] = { }; static const char *const directoryGlobs[] = { - "fonts", "game", "pict", "spict", diff --git a/engines/lab/dispman.cpp b/engines/lab/dispman.cpp index 8ff6a61675..5dba424018 100644 --- a/engines/lab/dispman.cpp +++ b/engines/lab/dispman.cpp @@ -57,7 +57,7 @@ DisplayMan::DisplayMan(LabEngine *vm) : _vm(vm) { _screenHeight = 0; for (int i = 0; i < 256 * 3; i++) - _curvgapal[i] = 0; + _curVgaPal[i] = 0; } DisplayMan::~DisplayMan() { @@ -88,10 +88,6 @@ void DisplayMan::readPict(const Common::String filename, bool playOnce, bool onl _vm->_anim->stopDiff(); loadPict(filename); _vm->updateMusicAndEvents(); - - if (!_vm->_music->_loopSoundEffect) - _vm->_music->stopSoundEffect(); - _vm->_anim->setOutputBuffer(memoryBuffer); _vm->_anim->readDiff(_curBitmap, playOnce, onlyDiffData); } @@ -383,10 +379,10 @@ void DisplayMan::rectFill(Common::Rect fillRect, byte color) { height = _screenHeight - fillRect.top; if ((width > 0) && (height > 0)) { - char *d = (char *)getCurrentDrawingBuffer() + fillRect.top * _screenWidth + fillRect.left; + byte *d = getCurrentDrawingBuffer() + fillRect.top * _screenWidth + fillRect.left; while (height-- > 0) { - char *dd = d; + byte *dd = d; int ww = width; while (ww-- > 0) { @@ -458,11 +454,11 @@ void DisplayMan::writeColorRegs(byte *buf, uint16 first, uint16 numReg) { tmp[i] = (buf[i] << 2) | (buf[i] >> 4); // better results than buf[i] * 4 _vm->_system->getPaletteManager()->setPalette(tmp, first, numReg); - memcpy(&(_curvgapal[first * 3]), buf, numReg * 3); + memcpy(&(_curVgaPal[first * 3]), buf, numReg * 3); } void DisplayMan::setPalette(void *newPal, uint16 numColors) { - if (memcmp(newPal, _curvgapal, numColors * 3) != 0) + if (memcmp(newPal, _curVgaPal, numColors * 3) != 0) writeColorRegs((byte *)newPal, 0, numColors); } @@ -473,7 +469,7 @@ byte *DisplayMan::getCurrentDrawingBuffer() { return _displayBuffer; } -void DisplayMan::checkerboardEffect(uint16 penColor, uint16 x1, uint16 y1, uint16 x2, uint16 y2) { +void DisplayMan::checkerBoardEffect(uint16 penColor, uint16 x1, uint16 y1, uint16 x2, uint16 y2) { int w = x2 - x1 + 1; int h = y2 - y1 + 1; @@ -677,20 +673,19 @@ void DisplayMan::doScrollWipe(const Common::String filename) { uint16 nheight = height; uint16 startLine = 0, onRow = 0; - while (onRow < _vm->_anim->_headerdata._height) { + while (onRow < _vm->_anim->getDIFFHeight()) { _vm->updateMusicAndEvents(); if ((by > nheight) && nheight) by = nheight; - if ((startLine + by) > (_vm->_anim->_headerdata._height - height - 1)) + if ((startLine + by) > (_vm->_anim->getDIFFHeight() - height - 1)) break; if (nheight) nheight -= by; copyPage(width, height, nheight, startLine, mem); - screenUpdate(); if (!nheight) @@ -719,7 +714,7 @@ void DisplayMan::doScrollBounce() { byte *mem = _vm->_anim->_scrollScreenBuffer; _vm->updateMusicAndEvents(); - int startLine = _vm->_anim->_headerdata._height - height - 1; + int startLine = _vm->_anim->getDIFFHeight() - height - 1; for (int i = 0; i < 5; i++) { _vm->updateMusicAndEvents(); @@ -738,7 +733,7 @@ void DisplayMan::doScrollBounce() { _vm->_event->mouseShow(); } -void DisplayMan::doTransWipe(CloseDataPtr *closePtrList, const Common::String filename) { +void DisplayMan::doTransWipe(const Common::String filename) { uint16 lastY, linesLast; if (_vm->_isHiRes) { @@ -763,7 +758,7 @@ void DisplayMan::doTransWipe(CloseDataPtr *closePtrList, const Common::String fi } if (j == 0) - checkerboardEffect(0, 0, curY, _screenWidth - 1, curY + 1); + checkerBoardEffect(0, 0, curY, _screenWidth - 1, curY + 1); else rectFill(0, curY, _screenWidth - 1, curY + 1, 0); curY += 4; @@ -773,26 +768,26 @@ void DisplayMan::doTransWipe(CloseDataPtr *closePtrList, const Common::String fi } // for j if (filename.empty()) - _vm->_curFileName = _vm->getPictName(closePtrList); + _vm->_curFileName = _vm->getPictName(true); else if (filename[0] > ' ') _vm->_curFileName = filename; else - _vm->_curFileName = _vm->getPictName(closePtrList); + _vm->_curFileName = _vm->getPictName(true); byte *bitMapBuffer = new byte[_screenWidth * (lastY + 5)]; readPict(_vm->_curFileName, true, false, bitMapBuffer); setPalette(_vm->_anim->_diffPalette, 256); - Image imSource(_vm); - imSource._width = _screenWidth; - imSource._height = lastY; - imSource._imageData = bitMapBuffer; + Image imgSource(_vm); + imgSource._width = _screenWidth; + imgSource._height = lastY; + imgSource.setData(bitMapBuffer, true); - Image imDest(_vm); - imDest._width = _screenWidth; - imDest._height = _screenHeight; - imDest._imageData = getCurrentDrawingBuffer(); + Image imgDest(_vm); + imgDest._width = _screenWidth; + imgDest._height = _screenHeight; + imgDest.setData(getCurrentDrawingBuffer(), false); for (int j = 0; j < 2; j++) { for (int i = 0; i < 2; i++) { @@ -805,14 +800,14 @@ void DisplayMan::doTransWipe(CloseDataPtr *closePtrList, const Common::String fi linesDone = 0; } - imDest._imageData = getCurrentDrawingBuffer(); + imgDest.setData(getCurrentDrawingBuffer(), false); if (j == 0) { - imSource.blitBitmap(0, curY, &imDest, 0, curY, _screenWidth, 2, false); - checkerboardEffect(0, 0, curY, _screenWidth - 1, curY + 1); + imgSource.blitBitmap(0, curY, &imgDest, 0, curY, _screenWidth, 2, false); + checkerBoardEffect(0, 0, curY, _screenWidth - 1, curY + 1); } else { uint16 bitmapHeight = (curY == lastY) ? 1 : 2; - imSource.blitBitmap(0, curY, &imDest, 0, curY, _screenWidth, bitmapHeight, false); + imgSource.blitBitmap(0, curY, &imgDest, 0, curY, _screenWidth, bitmapHeight, false); } curY += 4; linesDone++; @@ -820,31 +815,28 @@ void DisplayMan::doTransWipe(CloseDataPtr *closePtrList, const Common::String fi } // for i } // for j - // Prevent the Image destructor from deleting the drawing buffer - imDest._imageData = nullptr; - // bitMapBuffer will be deleted by the Image destructor } -void DisplayMan::doTransition(TransitionType transitionType, CloseDataPtr *closePtrList, const Common::String filename) { +void DisplayMan::doTransition(TransitionType transitionType, const Common::String filename) { switch (transitionType) { case kTransitionWipe: case kTransitionTransporter: - doTransWipe(closePtrList, filename); + doTransWipe(filename); break; - case kTransitionScrollWipe: + case kTransitionScrollWipe: // only used in scene 7 (street, when teleporting to the surreal maze) doScrollWipe(filename); break; - case kTransitionScrollBlack: + case kTransitionScrollBlack: // only used in scene 7 (street, when teleporting to the surreal maze) doScrollBlack(); break; - case kTransitionScrollBounce: + case kTransitionScrollBounce: // only used in scene 7 (street, when teleporting to the surreal maze) doScrollBounce(); break; - case kTransitionReadFirstFrame: + case kTransitionReadFirstFrame: // only used in scene 7 (street, when teleporting to the surreal maze) readPict(filename, false); break; - case kTransitionReadNextFrame: + case kTransitionReadNextFrame: // only used in scene 7 (street, when teleporting to the surreal maze) _vm->_anim->diffNextFrame(); break; case kTransitionNone: @@ -876,8 +868,8 @@ void DisplayMan::blackAllScreen() { } void DisplayMan::scrollDisplayX(int16 dx, uint16 x1, uint16 y1, uint16 x2, uint16 y2, byte *buffer) { - Image im(_vm); - im._imageData = buffer; + Image img(_vm); + img.setData(buffer, false); if (x1 > x2) SWAP<uint16>(x1, x2); @@ -886,30 +878,27 @@ void DisplayMan::scrollDisplayX(int16 dx, uint16 x1, uint16 y1, uint16 x2, uint1 SWAP<uint16>(y1, y2); if (dx > 0) { - im._width = x2 - x1 + 1 - dx; - im._height = y2 - y1 + 1; + img._width = x2 - x1 + 1 - dx; + img._height = y2 - y1 + 1; - im.readScreenImage(x1, y1); - im.drawImage(x1 + dx, y1); + img.readScreenImage(x1, y1); + img.drawImage(x1 + dx, y1); rectFill(x1, y1, x1 + dx - 1, y2, 0); } else if (dx < 0) { - im._width = x2 - x1 + 1 + dx; - im._height = y2 - y1 + 1; + img._width = x2 - x1 + 1 + dx; + img._height = y2 - y1 + 1; - im.readScreenImage(x1 - dx, y1); - im.drawImage(x1, y1); + img.readScreenImage(x1 - dx, y1); + img.drawImage(x1, y1); rectFill(x2 + dx + 1, y1, x2, y2, 0); } - - // Prevent the Image destructor from deleting the external buffer - im._imageData = nullptr; } void DisplayMan::scrollDisplayY(int16 dy, uint16 x1, uint16 y1, uint16 x2, uint16 y2, byte *buffer) { - Image im(_vm); - im._imageData = buffer; + Image img(_vm); + img.setData(buffer, false); if (x1 > x2) SWAP<uint16>(x1, x2); @@ -918,25 +907,22 @@ void DisplayMan::scrollDisplayY(int16 dy, uint16 x1, uint16 y1, uint16 x2, uint1 SWAP<uint16>(y1, y2); if (dy > 0) { - im._width = x2 - x1 + 1; - im._height = y2 - y1 + 1 - dy; + img._width = x2 - x1 + 1; + img._height = y2 - y1 + 1 - dy; - im.readScreenImage(x1, y1); - im.drawImage(x1, y1 + dy); + img.readScreenImage(x1, y1); + img.drawImage(x1, y1 + dy); rectFill(x1, y1, x2, y1 + dy - 1, 0); } else if (dy < 0) { - im._width = x2 - x1 + 1; - im._height = y2 - y1 + 1 + dy; + img._width = x2 - x1 + 1; + img._height = y2 - y1 + 1 + dy; - im.readScreenImage(x1, y1 - dy); - im.drawImage(x1, y1); + img.readScreenImage(x1, y1 - dy); + img.drawImage(x1, y1); rectFill(x1, y2 + dy + 1, x2, y2, 0); } - - // Prevent the Image destructor from deleting the external buffer - im._imageData = nullptr; } uint16 DisplayMan::fadeNumIn(uint16 num, uint16 res, uint16 counter) { diff --git a/engines/lab/dispman.h b/engines/lab/dispman.h index 2cf58c379f..6d70172f17 100644 --- a/engines/lab/dispman.h +++ b/engines/lab/dispman.h @@ -70,22 +70,12 @@ private: */ Common::String getWord(const char *mainBuffer); - byte _curPen; - Common::File *_curBitmap; - byte _curvgapal[256 * 3]; - -public: - DisplayMan(LabEngine *lab); - virtual ~DisplayMan(); - - void loadPict(const Common::String filename); - void loadBackPict(const Common::String fileName, uint16 *highPal); + void createBox(uint16 y2); /** - * Reads in a picture into the display bitmap. + * Sets up either a low-res or a high-res 256 color screen. */ - void readPict(const Common::String filename, bool playOnce = true, bool onlyDiffData = false, byte *memoryBuffer = nullptr); - void freePict(); + void createScreen(bool hiRes); /** * Scrolls the display to black. @@ -106,12 +96,57 @@ public: /** * Does the transporter wipe. */ - void doTransWipe(CloseDataPtr *closePtrList, const Common::String filename); + void doTransWipe(const Common::String filename); + + /** + * Draws a vertical line. + */ + void drawHLine(uint16 x, uint16 y1, uint16 y2, byte color); + + /** + * Draws a horizontal line. + */ + void drawVLine(uint16 x1, uint16 y, uint16 x2, byte color); + + /** + * Draws the text to the screen. + */ + void drawText(TextFont *tf, uint16 x, uint16 y, uint16 color, const Common::String text); + + /** + * Gets a line of text for flowText; makes sure that its length is less than + * or equal to the maximum width. + */ + Common::String getLine(TextFont *tf, const char **mainBuffer, uint16 lineWidth); + + /** + * Returns the length of a text in the specified font. + */ + uint16 textLength(TextFont *font, const Common::String text); + + bool _actionMessageShown; + byte _curPen; + Common::File *_curBitmap; + byte _curVgaPal[256 * 3]; + byte *_currentDisplayBuffer; + +public: + DisplayMan(LabEngine *lab); + virtual ~DisplayMan(); + + void loadPict(const Common::String filename); + void loadBackPict(const Common::String fileName, uint16 *highPal); + + /** + * Reads in a picture into the display bitmap. + */ + void readPict(const Common::String filename, bool playOnce = true, bool onlyDiffData = false, byte *memoryBuffer = nullptr); + void freePict(); /** * Does a certain number of pre-programmed wipes. */ - void doTransition(TransitionType transitionType, CloseDataPtr *closePtrList, const Common::String filename); + void doTransition(TransitionType transitionType, const Common::String filename); /** * Changes the front screen to black. @@ -127,7 +162,6 @@ public: * Changes the entire screen to black. */ void blackAllScreen(); - void createBox(uint16 y2); /** * Draws the control panel display. @@ -149,11 +183,6 @@ public: void setActionMessage(bool val) { _actionMessageShown = val; } /** - * Sets the pen number to use on all the drawing operations. - */ - void setPen(byte pennum); - - /** * Fills in a rectangle. */ void rectFill(uint16 x1, uint16 y1, uint16 x2, uint16 y2, byte color); @@ -178,23 +207,9 @@ public: int flowText(TextFont *font, int16 spacing, byte penColor, byte backPen, bool fillBack, bool centerh, bool centerv, bool output, Common::Rect textRect, const char *text, Image *targetImage = nullptr); - /** - * Draws a vertical line. - */ - void drawHLine(uint16 x, uint16 y1, uint16 y2, byte color); - - /** - * Draws a horizontal line. - */ - void drawVLine(uint16 x1, uint16 y, uint16 x2, byte color); void screenUpdate(); /** - * Sets up either a low-res or a high-res 256 color screen. - */ - void createScreen(bool hiRes); - - /** * Converts a 16-color Amiga palette to a VGA palette, then sets * the VGA palette. */ @@ -216,7 +231,7 @@ public: /** * Overlays a region on the screen using the desired pen color. */ - void checkerboardEffect(uint16 penColor, uint16 x1, uint16 y1, uint16 x2, uint16 y2); + void checkerBoardEffect(uint16 penColor, uint16 x1, uint16 y1, uint16 x2, uint16 y2); /** * Returns the base address of the current VGA display. @@ -242,34 +257,16 @@ public: void freeFont(TextFont **font); /** - * Returns the length of a text in the specified font. - */ - uint16 textLength(TextFont *font, const Common::String text); - - /** * Returns the height of a specified font. */ uint16 textHeight(TextFont *tf); - /** - * Draws the text to the screen. - */ - void drawText(TextFont *tf, uint16 x, uint16 y, uint16 color, const Common::String text); - - /** - * Gets a line of text for flowText; makes sure that its length is less than - * or equal to the maximum width. - */ - Common::String getLine(TextFont *tf, const char **mainBuffer, uint16 lineWidth); - bool _longWinInFront; bool _lastMessageLong; - bool _actionMessageShown; uint32 _screenBytesPerPage; int _screenWidth; int _screenHeight; byte *_displayBuffer; - byte *_currentDisplayBuffer; uint16 *_fadePalette; }; diff --git a/engines/lab/engine.cpp b/engines/lab/engine.cpp index a01df7ec26..95dcc71923 100644 --- a/engines/lab/engine.cpp +++ b/engines/lab/engine.cpp @@ -39,15 +39,19 @@ #include "lab/music.h" #include "lab/processroom.h" #include "lab/resource.h" -#include "lab/tilepuzzle.h" +#include "lab/speciallocks.h" #include "lab/utils.h" namespace Lab { -// LAB: Labyrinth specific code for the special puzzles -#define SPECIALLOCK 100 -#define SPECIALBRICK 101 -#define SPECIALBRICKNOMOUSE 102 +#define CRUMBSWIDTH 24 +#define CRUMBSHEIGHT 24 + +enum SpecialLock { + kLockCombination = 100, + kLockTiles = 101, + kLockTileSolution = 102 +}; enum Items { kItemHelmet = 1, @@ -103,7 +107,7 @@ void LabEngine::setQuarters(uint16 quarters) { _inventory[kItemQuarter]._quantity = quarters; } -void LabEngine::drawRoomMessage(uint16 curInv, CloseDataPtr closePtr) { +void LabEngine::drawRoomMessage(uint16 curInv, const CloseData *closePtr) { if (_lastTooLong) { _lastTooLong = false; return; @@ -165,7 +169,7 @@ void LabEngine::eatMessages() { } while (msg && !shouldQuit()); } -bool LabEngine::doCloseUp(CloseDataPtr closePtr) { +bool LabEngine::doCloseUp(const CloseData *closePtr) { if (!closePtr) return false; @@ -425,7 +429,7 @@ void LabEngine::mainGameLoop() { // Sets the current picture properly on the screen if (_mainDisplay) - _nextFileName = getPictName(&_closeDataPtr); + _nextFileName = getPictName(true); if (_noUpdateDiff) { // Potentially entered another room @@ -440,16 +444,14 @@ void LabEngine::mainGameLoop() { _roomsFound->inclElement(_roomNum); _curFileName = _nextFileName; - if (_closeDataPtr) { + if (_closeDataPtr && _mainDisplay) { switch (_closeDataPtr->_closeUpType) { - case SPECIALLOCK: - if (_mainDisplay) - _tilePuzzle->showCombination(_curFileName); + case kLockCombination: + _specialLocks->showCombinationLock(_curFileName); break; - case SPECIALBRICK: - case SPECIALBRICKNOMOUSE: - if (_mainDisplay) - _tilePuzzle->showTile(_curFileName, (_closeDataPtr->_closeUpType == SPECIALBRICKNOMOUSE)); + case kLockTiles: + case kLockTileSolution: + _specialLocks->showTileLock(_curFileName, (_closeDataPtr->_closeUpType == kLockTileSolution)); break; default: _graphics->readPict(_curFileName, false); @@ -498,7 +500,7 @@ void LabEngine::mainGameLoop() { gotMessage = true; mayShowCrumbIndicator(); _graphics->screenUpdate(); - if (!fromCrumbs(kMessageButtonUp, code, 0, _event->updateAndGetMousePos(), curInv, curMsg, forceDraw, code, actionMode)) + if (!processEvent(kMessageButtonUp, code, 0, _event->updateAndGetMousePos(), curInv, curMsg, forceDraw, code, actionMode)) break; } } @@ -508,7 +510,7 @@ void LabEngine::mainGameLoop() { } else { gotMessage = true; _followingCrumbs = false; - if (!fromCrumbs(curMsg->_msgClass, curMsg->_code, curMsg->_qualifier, curMsg->_mouse, curInv, curMsg, forceDraw, curMsg->_code, actionMode)) + if (!processEvent(curMsg->_msgClass, curMsg->_code, curMsg->_qualifier, curMsg->_mouse, curInv, curMsg, forceDraw, curMsg->_code, actionMode)) break; } } @@ -533,59 +535,47 @@ void LabEngine::showLab2Teaser() { } } -bool LabEngine::fromCrumbs(uint32 tmpClass, uint16 code, uint16 qualifier, Common::Point tmpPos, +bool LabEngine::processEvent(MessageClass tmpClass, uint16 code, uint16 qualifier, Common::Point tmpPos, uint16 &curInv, IntuiMessage *curMsg, bool &forceDraw, uint16 buttonId, uint16 &actionMode) { - uint32 msgClass = tmpClass; + MessageClass msgClass = tmpClass; Common::Point curPos = tmpPos; - uint16 oldDirection = 0; uint16 lastInv = kItemMap; - bool leftButtonClick = false; - bool rightButtonClick = false; + + if (code == Common::KEYCODE_RETURN) + msgClass = kMessageLeftClick; + + bool leftButtonClick = (msgClass == kMessageLeftClick); + bool rightButtonClick = (msgClass == kMessageRightClick); _anim->_doBlack = false; if (shouldQuit()) return false; - if ((msgClass == kMessageRawKey) && !_graphics->_longWinInFront) { - if (!processKey(curMsg, msgClass, qualifier, curPos, curInv, forceDraw, code)) - return false; - } - - leftButtonClick = (msgClass == kMessageLeftClick); - rightButtonClick = (msgClass == kMessageRightClick); - if (_graphics->_longWinInFront) { - if ((msgClass == kMessageRawKey) || (leftButtonClick || rightButtonClick)) { + if (msgClass == kMessageRawKey || leftButtonClick || rightButtonClick) { _graphics->_longWinInFront = false; _graphics->drawPanel(); drawRoomMessage(curInv, _closeDataPtr); _graphics->screenUpdate(); } - } else if ((msgClass == kMessageButtonUp) && !_alternate) { - processMainButton(curInv, lastInv, oldDirection, forceDraw, buttonId, actionMode); - } else if ((msgClass == kMessageButtonUp) && _alternate) { - processAltButton(curInv, lastInv, buttonId, actionMode); + } else if (msgClass == kMessageRawKey) { + return processKey(curMsg, msgClass, qualifier, curPos, curInv, forceDraw, code); + } else if (msgClass == kMessageButtonUp) { + if (!_alternate) + processMainButton(curInv, lastInv, oldDirection, forceDraw, buttonId, actionMode); + else + processAltButton(curInv, lastInv, buttonId, actionMode); } else if (leftButtonClick && _mainDisplay) { interfaceOff(); _mainDisplay = true; - if (_closeDataPtr) { - switch (_closeDataPtr->_closeUpType) { - case SPECIALLOCK: - if (_mainDisplay) - _tilePuzzle->mouseCombination(curPos); - break; - case SPECIALBRICK: - if (_mainDisplay) - _tilePuzzle->mouseTile(curPos); - break; - default: - performAction(actionMode, curPos, curInv); - break; - } - } else + if (_closeDataPtr && _closeDataPtr->_closeUpType == kLockCombination) + _specialLocks->combinationClick(curPos); + else if (_closeDataPtr && _closeDataPtr->_closeUpType == kLockTiles) + _specialLocks->tileClick(curPos); + else performAction(actionMode, curPos, curInv); mayShowCrumbIndicator(); @@ -610,44 +600,20 @@ bool LabEngine::fromCrumbs(uint32 tmpClass, uint16 code, uint16 qualifier, Commo mayShowCrumbIndicator(); _graphics->screenUpdate(); - } else if (msgClass == kMessageMoveCursorToCloseup) { - CloseDataPtr tmpClosePtr = _closeDataPtr; - - // get next close-up in list after the one pointed to by curPos - setCurrentClose(curPos, &tmpClosePtr, true, true); - - if (tmpClosePtr == _closeDataPtr) { - tmpClosePtr = nullptr; - if (!_closeDataPtr) { - ViewData *vptr = getViewData(_roomNum, _direction); - if (!vptr->_closeUps.empty()) - tmpClosePtr = &(*vptr->_closeUps.begin()); - } else { - if (!_closeDataPtr->_subCloseUps.empty()) - tmpClosePtr = &(*_closeDataPtr->_subCloseUps.begin()); - } - } - if (tmpClosePtr) - _event->setMousePos(Common::Point(_utils->scaleX((tmpClosePtr->_x1 + tmpClosePtr->_x2) / 2), _utils->scaleY((tmpClosePtr->_y1 + tmpClosePtr->_y2) / 2))); } return true; } -bool LabEngine::processKey(IntuiMessage *curMsg, uint32 &msgClass, uint16 &qualifier, Common::Point &curPos, uint16 &curInv, bool &forceDraw, uint16 code) { - if (code == Common::KEYCODE_RETURN) { - // The return key - msgClass = kMessageLeftClick; - qualifier = 0; - curPos = _event->getMousePos(); - } else if ((getPlatform() == Common::kPlatformWindows) && (code == Common::KEYCODE_b)) { +bool LabEngine::processKey(IntuiMessage *curMsg, uint32 msgClass, uint16 &qualifier, Common::Point &curPos, uint16 &curInv, bool &forceDraw, uint16 code) { + if ((getPlatform() == Common::kPlatformWindows) && (code == Common::KEYCODE_b)) { // Start bread crumbs _breadCrumbs[0]._roomNum = 0; _numCrumbs = 0; _droppingCrumbs = true; mayShowCrumbIndicator(); _graphics->screenUpdate(); - } else if ((code == Common::KEYCODE_f) || (code == Common::KEYCODE_r)) { + } else if (getPlatform() == Common::kPlatformWindows && (code == Common::KEYCODE_f || code == Common::KEYCODE_r)) { // Follow bread crumbs if (_droppingCrumbs) { if (_numCrumbs > 0) { @@ -708,10 +674,17 @@ bool LabEngine::processKey(IntuiMessage *curMsg, uint32 &msgClass, uint16 &quali forceDraw = true; interfaceOn(); - } else if (code == Common::KEYCODE_TAB) - msgClass = kMessageMoveCursorToCloseup; - else if (code == Common::KEYCODE_ESCAPE) + } else if (code == Common::KEYCODE_ESCAPE) { _closeDataPtr = nullptr; + } else if (code == Common::KEYCODE_TAB) { + const CloseData *tmpClosePtr = _closeDataPtr; + + // get next close-up in list after the one pointed to by curPos + setCurrentClose(curPos, &tmpClosePtr, true, true); + + if (tmpClosePtr != _closeDataPtr) + _event->setMousePos(Common::Point(_utils->scaleX((tmpClosePtr->_x1 + tmpClosePtr->_x2) / 2), _utils->scaleY((tmpClosePtr->_y1 + tmpClosePtr->_y2) / 2))); + } eatMessages(); @@ -729,7 +702,7 @@ void LabEngine::processMainButton(uint16 &curInv, uint16 &lastInv, uint16 &oldDi case kButtonClose: case kButtonLook: if ((actionMode == 4) && (buttonId == kButtonLook) && _closeDataPtr) { - doMainView(&_closeDataPtr); + doMainView(); _anim->_doBlack = true; _closeDataPtr = nullptr; @@ -745,6 +718,7 @@ void LabEngine::processMainButton(uint16 &curInv, uint16 &lastInv, uint16 &oldDi drawStaticMessage(kTextTakeWhat + buttonId); } break; + case kButtonInventory: eatMessages(); @@ -778,7 +752,7 @@ void LabEngine::processMainButton(uint16 &curInv, uint16 &lastInv, uint16 &oldDi oldDirection = _direction; newDir = processArrow(_direction, buttonId - 6); - doTurn(_direction, newDir, &_closeDataPtr); + doTurn(_direction, newDir); _anim->_doBlack = true; _direction = newDir; forceDraw = true; @@ -789,7 +763,7 @@ void LabEngine::processMainButton(uint16 &curInv, uint16 &lastInv, uint16 &oldDi _closeDataPtr = nullptr; oldRoomNum = _roomNum; - if (doGoForward(&_closeDataPtr)) { + if (doGoForward()) { if (oldRoomNum == _roomNum) _anim->_doBlack = true; } else { @@ -846,6 +820,7 @@ void LabEngine::processMainButton(uint16 &curInv, uint16 &lastInv, uint16 &oldDi mayShowCrumbIndicator(); break; + case kButtonMap: doUse(kItemMap); @@ -981,13 +956,13 @@ void LabEngine::performAction(uint16 actionMode, Common::Point curPos, uint16 &c switch (actionMode) { case 0: // Take something. - if (doActionRule(curPos, actionMode, _roomNum, &_closeDataPtr)) + if (doActionRule(curPos, actionMode, _roomNum)) _curFileName = _newFileName; - else if (takeItem(curPos, &_closeDataPtr)) + else if (takeItem(curPos)) drawStaticMessage(kTextTakeItem); - else if (doActionRule(curPos, kRuleActionTakeDef, _roomNum, &_closeDataPtr)) + else if (doActionRule(curPos, kRuleActionTakeDef, _roomNum)) _curFileName = _newFileName; - else if (doActionRule(curPos, kRuleActionTake, 0, &_closeDataPtr)) + else if (doActionRule(curPos, kRuleActionTake, 0)) _curFileName = _newFileName; else if (curPos.y < (_utils->vgaScaleY(149) + _utils->svgaCord(2))) drawStaticMessage(kTextNothing); @@ -998,9 +973,9 @@ void LabEngine::performAction(uint16 actionMode, Common::Point curPos, uint16 &c case 2: case 3: // Manipulate an object, Open up a "door" or Close a "door" - if (doActionRule(curPos, actionMode, _roomNum, &_closeDataPtr)) + if (doActionRule(curPos, actionMode, _roomNum)) _curFileName = _newFileName; - else if (!doActionRule(curPos, actionMode, 0, &_closeDataPtr)) { + else if (!doActionRule(curPos, actionMode, 0)) { if (curPos.y < (_utils->vgaScaleY(149) + _utils->svgaCord(2))) drawStaticMessage(kTextNothing); } @@ -1008,7 +983,7 @@ void LabEngine::performAction(uint16 actionMode, Common::Point curPos, uint16 &c case 4: { // Look at closeups - CloseDataPtr tmpClosePtr = _closeDataPtr; + const CloseData *tmpClosePtr = _closeDataPtr; setCurrentClose(curPos, &tmpClosePtr, true); if (_closeDataPtr == tmpClosePtr) { @@ -1025,7 +1000,7 @@ void LabEngine::performAction(uint16 actionMode, Common::Point curPos, uint16 &c case 5: if (_conditions->in(curInv)) { // Use an item on something else - if (doOperateRule(curPos, curInv, &_closeDataPtr)) { + if (doOperateRule(curPos, curInv)) { _curFileName = _newFileName; if (!_conditions->in(curInv)) @@ -1125,11 +1100,41 @@ MainButton LabEngine::followCrumbs() { void LabEngine::mayShowCrumbIndicator() { - static Image dropCrumbsImage(24, 24, nullptr, this); + static byte dropCrumbsImageData[CRUMBSWIDTH * CRUMBSHEIGHT] = { + 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, + 0, 4, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 0, + 4, 7, 7, 3, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 7, 7, 4, + 4, 7, 4, 4, 0, 0, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 7, 4, + 4, 7, 4, 0, 0, 0, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 7, 4, + 4, 7, 4, 0, 0, 3, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 3, 2, 3, 0, 4, 7, 4, + 4, 7, 4, 0, 0, 0, 3, 3, 3, 4, 4, 4, 4, 4, 4, 0, 0, 3, 2, 3, 0, 4, 7, 4, + 4, 7, 4, 0, 0, 0, 0, 0, 4, 7, 7, 7, 7, 7, 7, 4, 3, 2, 2, 2, 3, 4, 7, 4, + 4, 7, 4, 0, 0, 0, 0, 4, 7, 7, 4, 4, 4, 4, 7, 7, 4, 3, 3, 3, 0, 4, 7, 4, + 4, 7, 4, 0, 0, 0, 0, 4, 7, 4, 4, 0, 0, 4, 4, 7, 4, 0, 0, 0, 0, 4, 7, 4, + 4, 7, 4, 0, 0, 0, 0, 4, 7, 4, 0, 0, 0, 0, 4, 7, 4, 0, 0, 0, 0, 4, 7, 4, + 4, 7, 4, 0, 0, 0, 0, 4, 4, 4, 3, 0, 0, 0, 4, 7, 4, 0, 0, 0, 0, 4, 7, 4, + 4, 7, 4, 0, 0, 0, 0, 0, 4, 3, 2, 3, 0, 0, 4, 7, 4, 0, 0, 0, 0, 4, 7, 4, + 4, 7, 4, 0, 0, 0, 0, 0, 0, 3, 2, 3, 0, 0, 4, 7, 4, 0, 0, 0, 0, 4, 7, 4, + 4, 7, 4, 0, 0, 0, 0, 0, 3, 2, 2, 2, 3, 4, 4, 7, 4, 0, 0, 0, 0, 4, 7, 4, + 4, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, 7, 4, 0, 0, 0, 0, 4, 7, 4, + 0, 4, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 0, 0, 0, 0, 0, 4, 7, 4, + 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 0, 0, 0, 0, 0, 4, 7, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 3, 0, 0, 0, 0, 4, 7, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 3, 0, 0, 0, 0, 4, 7, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 3, 0, 0, 4, 4, 7, 4, + 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, 7, 4, + 0, 0, 4, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 0, + 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0 + }; + if (getPlatform() != Common::kPlatformWindows) return; if (_droppingCrumbs && _mainDisplay) { + static byte *imgData = new byte[CRUMBSWIDTH * CRUMBSHEIGHT]; + memcpy(imgData, dropCrumbsImageData, CRUMBSWIDTH * CRUMBSHEIGHT); + static Image dropCrumbsImage(CRUMBSWIDTH, CRUMBSHEIGHT, imgData, this); + _event->mouseHide(); dropCrumbsImage.drawMaskImage(612, 4); _event->mouseShow(); @@ -1137,12 +1142,41 @@ void LabEngine::mayShowCrumbIndicator() { } void LabEngine::mayShowCrumbIndicatorOff() { - static Image dropCrumbsOffImage(24, 24, nullptr, this); + static byte dropCrumbsOffImageData[CRUMBSWIDTH * CRUMBSHEIGHT] = { + 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, + 0, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 0, + 4, 8, 8, 3, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 8, 8, 4, + 4, 8, 4, 4, 0, 0, 3, 8, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 8, 4, + 4, 8, 4, 0, 0, 0, 3, 8, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 8, 4, + 4, 8, 4, 0, 0, 3, 8, 8, 8, 3, 0, 0, 0, 0, 0, 0, 0, 3, 8, 3, 0, 4, 8, 4, + 4, 8, 4, 0, 0, 0, 3, 3, 3, 4, 4, 4, 4, 4, 4, 0, 0, 3, 8, 3, 0, 4, 8, 4, + 4, 8, 4, 0, 0, 0, 0, 0, 4, 8, 8, 8, 8, 8, 8, 4, 3, 8, 8, 8, 3, 4, 8, 4, + 4, 8, 4, 0, 0, 0, 0, 4, 8, 8, 4, 4, 4, 4, 8, 8, 4, 3, 3, 3, 0, 4, 8, 4, + 4, 8, 4, 0, 0, 0, 0, 4, 8, 4, 4, 0, 0, 4, 4, 8, 4, 0, 0, 0, 0, 4, 8, 4, + 4, 8, 4, 0, 0, 0, 0, 4, 8, 4, 0, 0, 0, 0, 4, 8, 4, 0, 0, 0, 0, 4, 8, 4, + 4, 8, 4, 0, 0, 0, 0, 4, 4, 4, 3, 0, 0, 0, 4, 8, 4, 0, 0, 0, 0, 4, 8, 4, + 4, 8, 4, 0, 0, 0, 0, 0, 4, 3, 8, 3, 0, 0, 4, 8, 4, 0, 0, 0, 0, 4, 8, 4, + 4, 8, 4, 0, 0, 0, 0, 0, 0, 3, 8, 3, 0, 0, 4, 8, 4, 0, 0, 0, 0, 4, 8, 4, + 4, 8, 4, 0, 0, 0, 0, 0, 3, 8, 8, 8, 3, 4, 4, 8, 4, 0, 0, 0, 0, 4, 8, 4, + 4, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 4, 0, 0, 0, 0, 4, 8, 4, + 0, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 0, 0, 0, 0, 0, 4, 8, 4, + 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 0, 0, 0, 0, 0, 4, 8, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 3, 0, 0, 0, 0, 4, 8, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 3, 0, 0, 0, 0, 4, 8, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 8, 8, 3, 0, 0, 4, 4, 8, 4, + 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 4, + 0, 0, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 0, + 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0 + }; if (getPlatform() != Common::kPlatformWindows) return; if (_mainDisplay) { + static byte *imgData = new byte[CRUMBSWIDTH * CRUMBSHEIGHT]; + memcpy(imgData, dropCrumbsOffImageData, CRUMBSWIDTH * CRUMBSHEIGHT); + static Image dropCrumbsOffImage(CRUMBSWIDTH, CRUMBSHEIGHT, imgData, this); + _event->mouseHide(); dropCrumbsOffImage.drawMaskImage(612, 4); _event->mouseShow(); diff --git a/engines/lab/eventman.cpp b/engines/lab/eventman.cpp index 83c50b9771..d1db854863 100644 --- a/engines/lab/eventman.cpp +++ b/engines/lab/eventman.cpp @@ -137,7 +137,7 @@ void EventManager::initMouse() { _vm->_system->setMouseCursor(mouseData, MOUSE_WIDTH, MOUSE_HEIGHT, 0, 0, 0); _vm->_system->showMouse(false); - setMousePos(Common::Point(0, 0)); + setMousePos(Common::Point(_vm->_graphics->_screenWidth / 2, _vm->_graphics->_screenHeight / 2)); } void EventManager::mouseShow() { @@ -148,13 +148,6 @@ void EventManager::mouseHide() { _vm->_system->showMouse(false); } -Common::Point EventManager::getMousePos() { - if (_vm->_isHiRes) - return _mousePos; - else - return Common::Point(_mousePos.x / 2, _mousePos.y); -} - void EventManager::setMousePos(Common::Point pos) { if (_vm->_isHiRes) _vm->_system->warpMouse(pos.x, pos.y); @@ -191,9 +184,6 @@ void EventManager::processInput() { case Common::KEYCODE_RIGHTBRACKET: _vm->changeVolume(1); break; - case Common::KEYCODE_z: - //saveSettings(); - break; case Common::KEYCODE_d: if (event.kbd.hasFlags(Common::KBD_CTRL)) { // Open debugger console diff --git a/engines/lab/eventman.h b/engines/lab/eventman.h index ec8f824cb2..cb91b12a76 100644 --- a/engines/lab/eventman.h +++ b/engines/lab/eventman.h @@ -38,22 +38,13 @@ namespace Lab { class LabEngine; class Image; -enum MessageClasses { - kMessageLeftClick, - kMessageRightClick, - kMessageButtonUp, - kMessageRawKey, - kMessageMoveCursorToCloseup -}; - struct IntuiMessage { - uint32 _msgClass; + MessageClass _msgClass; uint16 _code; // KeyCode or Button Id uint16 _qualifier; Common::Point _mouse; }; - struct Button { uint16 _x, _y, _buttonId; Common::KeyCode _keyEquiv; // the key which activates this button @@ -92,11 +83,6 @@ private: */ Button *checkNumButtonHit(ButtonList *buttonList, Common::KeyCode key); - /** - * Make a key press have the right case for a button KeyEquiv value. - */ - uint16 makeButtonKeyEquiv(uint16 key); - public: EventManager (LabEngine *vm); @@ -111,11 +97,6 @@ public: void freeButtonList(ButtonList *buttonList); Button *getButton(uint16 id); - /** - * Gets the current mouse co-ordinates. NOTE: On IBM version, will scale - * from virtual to screen co-ordinates automatically. - */ - Common::Point getMousePos(); IntuiMessage *getMsg(); /** diff --git a/engines/lab/image.cpp b/engines/lab/image.cpp index ce0d5431b6..ec516718e8 100644 --- a/engines/lab/image.cpp +++ b/engines/lab/image.cpp @@ -48,53 +48,56 @@ Image::Image(Common::File *s, LabEngine *vm) : _vm(vm) { _imageData = new byte[size]; s->read(_imageData, size); + _autoFree = true; } Image::~Image() { - delete[] _imageData; + if (_autoFree) + delete[] _imageData; } -void Image::blitBitmap(uint16 xs, uint16 ys, Image *imDest, - uint16 xd, uint16 yd, uint16 width, uint16 height, byte masked) { - int w = width; - int h = height; - int destWidth = (imDest) ? imDest->_width : _vm->_graphics->_screenWidth; - int destHeight = (imDest) ? imDest->_height : _vm->_graphics->_screenHeight; - byte *destBuffer = (imDest) ? imDest->_imageData : _vm->_graphics->getCurrentDrawingBuffer(); +void Image::setData(byte *d, bool autoFree) { + if (_autoFree) + delete[] _imageData; + _imageData = d; + _autoFree = autoFree; +} + +void Image::blitBitmap(uint16 srcX, uint16 srcY, Image *imgDest, + uint16 destX, uint16 destY, uint16 width, uint16 height, byte masked) { + int clipWidth = width; + int clipHeight = height; + int destWidth = (imgDest) ? imgDest->_width : _vm->_graphics->_screenWidth; + int destHeight = (imgDest) ? imgDest->_height : _vm->_graphics->_screenHeight; + byte *destBuffer = (imgDest) ? imgDest->_imageData : _vm->_graphics->getCurrentDrawingBuffer(); - if (xd + w > destWidth) - w = destWidth - xd; + if (destX + clipWidth > destWidth) + clipWidth = destWidth - destX; - if (yd + h > destHeight) - h = destHeight - yd; + if (destY + clipHeight > destHeight) + clipHeight = destHeight - destY; - if ((w > 0) && (h > 0)) { - byte *s = _imageData + ys * _width + xs; - byte *d = destBuffer + yd * destWidth + xd; + if ((clipWidth > 0) && (clipHeight > 0)) { + byte *img = _imageData + srcY * _width + srcX; + byte *dest = destBuffer + destY * destWidth + destX; if (!masked) { - while (h-- > 0) { - memcpy(d, s, w); - s += _width; - d += destWidth; + for (int i = 0; i < clipHeight; i++) { + memcpy(dest, img, clipWidth); + img += _width; + dest += destWidth; } } else { - while (h-- > 0) { - byte *ss = s; - byte *dd = d; - int ww = w; - - while (ww-- > 0) { - byte c = *ss++; + for (int i = 0; i < clipHeight; i++) { + for (int j = 0; j < clipWidth; j++) { + byte c = img[j]; if (c) - *dd++ = c - 1; - else - dd++; + dest[j] = c - 1; } - s += _width; - d += destWidth; + img += _width; + dest += destWidth; } } } @@ -109,23 +112,23 @@ void Image::drawMaskImage(uint16 x, uint16 y) { } void Image::readScreenImage(uint16 x, uint16 y) { - int w = _width; - int h = _height; + int clipWidth = _width; + int clipHeight = _height; - if (x + w > _vm->_graphics->_screenWidth) - w = _vm->_graphics->_screenWidth - x; + if (x + clipWidth > _vm->_graphics->_screenWidth) + clipWidth = _vm->_graphics->_screenWidth - x; - if (y + h > _vm->_graphics->_screenHeight) - h = _vm->_graphics->_screenHeight - y; + if (y + clipHeight > _vm->_graphics->_screenHeight) + clipHeight = _vm->_graphics->_screenHeight - y; - if ((w > 0) && (h > 0)) { - byte *s = _imageData; - byte *d = _vm->_graphics->getCurrentDrawingBuffer() + y * _vm->_graphics->_screenWidth + x; + if ((clipWidth > 0) && (clipHeight > 0)) { + byte *img = _imageData; + byte *screen = _vm->_graphics->getCurrentDrawingBuffer() + y * _vm->_graphics->_screenWidth + x; - while (h-- > 0) { - memcpy(s, d, w); - s += _width; - d += _vm->_graphics->_screenWidth; + while (clipHeight-- > 0) { + memcpy(img, screen, clipWidth); + img += _width; + screen += _vm->_graphics->_screenWidth; } } } diff --git a/engines/lab/image.h b/engines/lab/image.h index bac32cd763..0f985e09eb 100644 --- a/engines/lab/image.h +++ b/engines/lab/image.h @@ -47,10 +47,12 @@ public: uint16 _height; byte *_imageData; - Image(LabEngine *vm) : _width(0), _height(0), _imageData(nullptr), _vm(vm) {} - Image(int w, int h, byte *d, LabEngine *vm) : _width(w), _height(h), _imageData(d), _vm(vm) {} + Image(LabEngine *vm) : _width(0), _height(0), _imageData(nullptr), _vm(vm), _autoFree(true) {} + Image(int w, int h, byte *d, LabEngine *vm, bool autoFree = true) : _width(w), _height(h), _imageData(d), _vm(vm), _autoFree(autoFree) {} Image(Common::File *s, LabEngine *vm); - virtual ~Image(); + ~Image(); + + void setData(byte *d, bool autoFree = true); /** * Draws an image to the screen. @@ -70,7 +72,10 @@ public: /** * Blits a piece of one image to another. */ - void blitBitmap(uint16 xs, uint16 ys, Image *ImDest, uint16 xd, uint16 yd, uint16 width, uint16 height, byte masked); + void blitBitmap(uint16 srcX, uint16 srcY, Image *imgDest, uint16 destX, uint16 destY, uint16 width, uint16 height, byte masked); + +private: + bool _autoFree; ///< Free _imageData in destructor? }; } // End of namespace Lab diff --git a/engines/lab/interface.cpp b/engines/lab/interface.cpp index 507e0b27d5..30f2f13fa5 100644 --- a/engines/lab/interface.cpp +++ b/engines/lab/interface.cpp @@ -78,20 +78,13 @@ void EventManager::drawButtonList(ButtonList *buttonList) { void EventManager::toggleButton(Button *button, uint16 disabledPenColor, bool enable) { if (!enable) - _vm->_graphics->checkerboardEffect(disabledPenColor, button->_x, button->_y, button->_x + button->_image->_width - 1, button->_y + button->_image->_height - 1); + _vm->_graphics->checkerBoardEffect(disabledPenColor, button->_x, button->_y, button->_x + button->_image->_width - 1, button->_y + button->_image->_height - 1); else button->_image->drawImage(button->_x, button->_y); button->_isEnabled = enable; } -uint16 EventManager::makeButtonKeyEquiv(uint16 key) { - if (Common::isAlnum(key)) - key = tolower(key); - - return key; -} - Button *EventManager::checkNumButtonHit(ButtonList *buttonList, Common::KeyCode key) { uint16 gkey = key - '0'; diff --git a/engines/lab/intro.cpp b/engines/lab/intro.cpp index 8971c96786..46a20a502b 100644 --- a/engines/lab/intro.cpp +++ b/engines/lab/intro.cpp @@ -83,10 +83,10 @@ void Intro::doPictText(const Common::String filename, bool isScreen) { bool begin = true; Common::File *textFile = _vm->_resource->openDataFile(path); - byte *textBuffer = new byte[textFile->size()]; + char *textBuffer = new char[textFile->size()]; textFile->read(textBuffer, textFile->size()); delete textFile; - byte *curText = textBuffer; + const char *curText = textBuffer; while (1) { if (drawNextText) { @@ -98,10 +98,10 @@ void Intro::doPictText(const Common::String filename, bool isScreen) { if (isScreen) { _vm->_graphics->rectFillScaled(10, 10, 310, 190, 7); - curText += _vm->_graphics->flowText(_font, _vm->_isHiRes ? 0 : -1, 5, 7, false, false, true, true, _vm->_utils->vgaRectScale(14, 11, 306, 189), (char *)curText); + curText += _vm->_graphics->flowText(_font, _vm->_isHiRes ? 0 : -1, 5, 7, false, false, true, true, _vm->_utils->vgaRectScale(14, 11, 306, 189), curText); _vm->_graphics->fade(true); } else - curText += _vm->_graphics->longDrawMessage(Common::String((char *)curText), false); + curText += _vm->_graphics->longDrawMessage(Common::String(curText), false); doneFl = (*curText == 0); @@ -262,16 +262,13 @@ void Intro::play() { _vm->_graphics->_fadePalette = palette; for (int i = 0; i < 16; i++) { - if (_quitIntro) - break; - palette[i] = ((_vm->_anim->_diffPalette[i * 3] >> 2) << 8) + ((_vm->_anim->_diffPalette[i * 3 + 1] >> 2) << 4) + (_vm->_anim->_diffPalette[i * 3 + 2] >> 2); } - _vm->updateMusicAndEvents(); - _vm->_graphics->fade(true); + if (!_quitIntro) + _vm->_graphics->fade(true); for (int times = 0; times < 150; times++) { if (_quitIntro) @@ -289,9 +286,11 @@ void Intro::play() { _vm->waitTOF(); } - _vm->_graphics->fade(false); - _vm->_graphics->blackAllScreen(); - _vm->updateMusicAndEvents(); + if (!_quitIntro) { + _vm->_graphics->fade(false); + _vm->_graphics->blackAllScreen(); + _vm->updateMusicAndEvents(); + } nReadPict("Title.A"); nReadPict("AB"); diff --git a/engines/lab/lab.cpp b/engines/lab/lab.cpp index e942617a26..be299a8236 100644 --- a/engines/lab/lab.cpp +++ b/engines/lab/lab.cpp @@ -44,7 +44,7 @@ #include "lab/music.h" #include "lab/processroom.h" #include "lab/resource.h" -#include "lab/tilepuzzle.h" +#include "lab/speciallocks.h" #include "lab/utils.h" namespace Lab { @@ -85,7 +85,7 @@ LabEngine::LabEngine(OSystem *syst, const ADGameDescription *gameDesc) _graphics = nullptr; _rooms = nullptr; _roomsFound = nullptr; - _tilePuzzle = nullptr; + _specialLocks = nullptr; _utils = nullptr; _console = nullptr; _journalBackImage = nullptr; @@ -151,7 +151,7 @@ LabEngine::~LabEngine() { delete _music; delete _anim; delete _graphics; - delete _tilePuzzle; + delete _specialLocks; delete _utils; delete _console; delete _journalBackImage; @@ -168,7 +168,7 @@ Common::Error LabEngine::run() { _music = new Music(this); _graphics = new DisplayMan(this); _anim = new Anim(this); - _tilePuzzle = new TilePuzzle(this); + _specialLocks = new SpecialLocks(this); _utils = new Utils(this); _console = new Console(this); _journalBackImage = new Image(this); @@ -221,7 +221,12 @@ void LabEngine::drawStaticMessage(byte index) { } void LabEngine::changeVolume(int delta) { - warning("STUB: changeVolume()"); + int sfxPrev = _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType); + int musicPrev = _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType); + int sfxNew = (delta > 0) ? MIN<int>(sfxPrev + 10, Audio::Mixer::kMaxMixerVolume) : MAX<int>(sfxPrev - 10, 0); + int musicNew = (delta > 0) ? MIN<int>(musicPrev + 10, Audio::Mixer::kMaxMixerVolume) : MAX<int>(musicPrev - 10, 0); + _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, sfxNew); + _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, musicNew); } void LabEngine::waitTOF() { diff --git a/engines/lab/lab.h b/engines/lab/lab.h index 0a2e407d92..fd09db0a37 100644 --- a/engines/lab/lab.h +++ b/engines/lab/lab.h @@ -63,7 +63,7 @@ class EventManager; class Image; class Music; class Resource; -class TilePuzzle; +class SpecialLocks; class Utils; struct SaveGameHeader { @@ -87,8 +87,10 @@ struct CrumbData { #define MAX_CRUMBS 128 -typedef CloseData *CloseDataPtr; typedef Common::List<Rule> RuleList; +typedef Common::List<Action> ActionList; +typedef Common::List<CloseData> CloseDataList; +typedef Common::List<ViewData> ViewDataList; enum Direction { kDirectionNorth, @@ -111,6 +113,13 @@ enum MainButton { kButtonMap }; +enum MessageClass { + kMessageLeftClick, + kMessageRightClick, + kMessageButtonUp, + kMessageRawKey +}; + class LabEngine : public Engine { private: bool _interfaceOff; @@ -140,7 +149,7 @@ private: Common::String _newFileName; Common::String _monitorTextFilename; - CloseDataPtr _closeDataPtr; + const CloseData *_closeDataPtr; ButtonList _journalButtonList; ButtonList _mapButtonList; Image *_imgMap, *_imgRoom, *_imgUpArrowRoom, *_imgDownArrowRoom, *_imgBridge; @@ -184,7 +193,7 @@ public: Resource *_resource; RoomData *_rooms; TextFont *_msgFont; - TilePuzzle *_tilePuzzle; + SpecialLocks *_specialLocks; Utils *_utils; Console *_console; GUI::Debugger *getDebugger() { return _console; } @@ -209,7 +218,7 @@ public: /** * Returns the current picture name. */ - Common::String getPictName(CloseDataPtr *closePtrList); + Common::String getPictName(bool useClose); uint16 getQuarters(); void setDirection(uint16 direction) { _direction = direction; }; void setQuarters(uint16 quarters); @@ -230,27 +239,27 @@ private: /** * Processes the action list. */ - void doActions(const Common::List<Action> &actionList, CloseDataPtr *closePtrList); + void doActions(const ActionList &actionList); /** * Goes through the rules if an action is taken. */ - bool doActionRule(Common::Point pos, int16 action, int16 roomNum, CloseDataPtr *closePtrList); + bool doActionRule(Common::Point pos, int16 action, int16 roomNum); /** * Does the work for doActionRule. */ - bool doActionRuleSub(int16 action, int16 roomNum, CloseDataPtr closePtr, CloseDataPtr *setCloseList, bool allowDefaults); + bool doActionRuleSub(int16 action, int16 roomNum, const CloseData *closePtr, bool allowDefaults); /** * Checks whether the close up is one of the special case closeups. */ - bool doCloseUp(CloseDataPtr closePtr); + bool doCloseUp(const CloseData *closePtr); /** * Goes through the rules if the user tries to go forward. */ - bool doGoForward(CloseDataPtr *closePtrList); + bool doGoForward(); /** * Does the journal processing. @@ -260,7 +269,7 @@ private: /** * Goes through the rules if the user tries to go to the main view */ - bool doMainView(CloseDataPtr *closePtrList); + bool doMainView(); /** * Does the map processing. @@ -280,17 +289,17 @@ private: /** * Does the work for doActionRule. */ - bool doOperateRuleSub(int16 itemNum, int16 roomNum, CloseDataPtr closePtr, CloseDataPtr *setCloseList, bool allowDefaults); + bool doOperateRuleSub(int16 itemNum, int16 roomNum, const CloseData *closePtr, bool allowDefaults); /** * Goes through the rules if the user tries to operate an item on an object. */ - bool doOperateRule(Common::Point pos, int16 ItemNum, CloseDataPtr *closePtrList); + bool doOperateRule(Common::Point pos, int16 ItemNum); /** * Goes through the rules if the user tries to turn. */ - bool doTurn(uint16 from, uint16 to, CloseDataPtr *closePtrList); + bool doTurn(uint16 from, uint16 to); /** * If the user hits the "Use" button; things that can get used on themselves. @@ -306,7 +315,7 @@ private: /** * Draws the current direction to the screen. */ - void drawDirection(CloseDataPtr closePtr); + void drawDirection(const CloseData *closePtr); /** * Draws the journal from page x. @@ -336,7 +345,7 @@ private: /** * Draws the message for the room. */ - void drawRoomMessage(uint16 curInv, CloseDataPtr closePtr); + void drawRoomMessage(uint16 curInv, const CloseData *closePtr); void drawStaticMessage(byte index); /** @@ -350,7 +359,7 @@ private: * some of the closeups have the same hit boxes, then this returns the first * occurrence of the object with the same hit box. */ - CloseDataPtr findClosePtrMatch(CloseDataPtr closePtr, Common::List<CloseData> &list); + const CloseData *findClosePtrMatch(const CloseData *closePtr, const CloseDataList &list); /** * Checks if a floor has been visited. @@ -363,7 +372,7 @@ private: MainButton followCrumbs(); void freeMapData(); void freeScreens(); - bool fromCrumbs(uint32 tmpClass, uint16 code, uint16 qualifier, Common::Point tmpPos, + bool processEvent(MessageClass tmpClass, uint16 code, uint16 qualifier, Common::Point tmpPos, uint16 &curInv, IntuiMessage *curMsg, bool &forceDraw, uint16 buttonId, uint16 &actionMode); /** @@ -380,7 +389,7 @@ private: /** * Gets an object, if any, from the user's click on the screen. */ - CloseData *getObject(Common::Point pos, CloseDataPtr closePtr); + const CloseData *getObject(Common::Point pos, const CloseData *closePtr); /** * Returns the floor to show when the up arrow is pressed @@ -455,18 +464,18 @@ private: /** * Sets the current close up data. */ - void setCurrentClose(Common::Point pos, CloseDataPtr *closePtrList, bool useAbsoluteCoords, bool next=false); + void setCurrentClose(Common::Point pos, const CloseData **closePtrList, bool useAbsoluteCoords, bool next=false); /** * Takes the currently selected item. */ - bool takeItem(Common::Point pos, CloseDataPtr *closePtrList); + bool takeItem(Common::Point pos); /** * Does the turn page wipe. */ void turnPage(bool fromLeft); - bool processKey(IntuiMessage *curMsg, uint32 &msgClass, uint16 &qualifier, Common::Point &curPos, uint16 &curInv, bool &forceDraw, uint16 code); + bool processKey(IntuiMessage *curMsg, uint32 msgClass, uint16 &qualifier, Common::Point &curPos, uint16 &curInv, bool &forceDraw, uint16 code); void processMainButton(uint16 &curInv, uint16 &lastInv, uint16 &oldDirection, bool &forceDraw, uint16 buttonId, uint16 &actionMode); void processAltButton(uint16 &curInv, uint16 &lastInv, uint16 buttonId, uint16 &actionMode); void performAction(uint16 actionMode, Common::Point curPos, uint16 &curInv); diff --git a/engines/lab/map.cpp b/engines/lab/map.cpp index 21a0830913..f7b2cfe9ea 100644 --- a/engines/lab/map.cpp +++ b/engines/lab/map.cpp @@ -83,16 +83,14 @@ void LabEngine::loadMapData() { Common::File *mapFile = _resource->openDataFile("Lab:Maps", MKTAG('M', 'A', 'P', '0')); updateMusicAndEvents(); - if (!_music->_loopSoundEffect) - _music->stopSoundEffect(); _maxRooms = mapFile->readUint16LE(); _maps = new MapData[_maxRooms + 1]; // will be freed when the user exits the map - for (int i = 1; i <= _maxRooms; i++) { + for (int i = 0; i <= _maxRooms; i++) { _maps[i]._x = mapFile->readUint16LE(); _maps[i]._y = mapFile->readUint16LE(); _maps[i]._pageNumber = mapFile->readUint16LE(); - _maps[i]._specialID = mapFile->readUint16LE(); + _maps[i]._specialID = (SpecialRoom) mapFile->readUint16LE(); _maps[i]._mapFlags = mapFile->readUint32LE(); } @@ -135,18 +133,18 @@ Common::Rect LabEngine::roomCoords(uint16 curRoom) { Image *curRoomImg = nullptr; switch (_maps[curRoom]._specialID) { - case NORMAL: - case UPARROWROOM: - case DOWNARROWROOM: + case kNormalRoom: + case kUpArrowRoom: + case kDownArrowRoom: curRoomImg = _imgRoom; break; - case BRIDGEROOM: + case kBridgeRoom: curRoomImg = _imgBridge; break; - case VCORRIDOR: + case kVerticalCorridor: curRoomImg = _imgVRoom; break; - case HCORRIDOR: + case kHorizontalCorridor: curRoomImg = _imgHRoom; break; default: @@ -175,12 +173,12 @@ void LabEngine::drawRoomMap(uint16 curRoom, bool drawMarkFl) { uint32 flags = _maps[curRoom]._mapFlags; switch (_maps[curRoom]._specialID) { - case NORMAL: - case UPARROWROOM: - case DOWNARROWROOM: - if (_maps[curRoom]._specialID == NORMAL) + case kNormalRoom: + case kUpArrowRoom: + case kDownArrowRoom: + if (_maps[curRoom]._specialID == kNormalRoom) _imgRoom->drawImage(x, y); - else if (_maps[curRoom]._specialID == DOWNARROWROOM) + else if (_maps[curRoom]._specialID == kDownArrowRoom) _imgDownArrowRoom->drawImage(x, y); else _imgUpArrowRoom->drawImage(x, y); @@ -206,7 +204,7 @@ void LabEngine::drawRoomMap(uint16 curRoom, bool drawMarkFl) { break; - case BRIDGEROOM: + case kBridgeRoom: _imgBridge->drawImage(x, y); drawX = x + (_imgBridge->_width - _imgMapX[_direction]->_width) / 2; @@ -214,7 +212,7 @@ void LabEngine::drawRoomMap(uint16 curRoom, bool drawMarkFl) { break; - case VCORRIDOR: + case kVerticalCorridor: _imgVRoom->drawImage(x, y); offset = (_imgVRoom->_width - _imgPath->_width) / 2; @@ -252,7 +250,7 @@ void LabEngine::drawRoomMap(uint16 curRoom, bool drawMarkFl) { break; - case HCORRIDOR: + case kHorizontalCorridor: _imgHRoom->drawImage(x, y); offset = (_imgRoom->_width - _imgPath->_width) / 2; @@ -339,10 +337,11 @@ void LabEngine::drawMap(uint16 curRoom, uint16 curMsg, uint16 floorNum, bool fad for (int i = 1; i <= _maxRooms; i++) { if ((_maps[i]._pageNumber == floorNum) && _roomsFound->in(i) && _maps[i]._x) { drawRoomMap(i, (bool)(i == curRoom)); - updateMusicAndEvents(); } } + updateMusicAndEvents(); + // Makes sure the X is drawn in corridors // NOTE: this here on purpose just in case there's some weird // condition, like the surreal maze where there are no rooms diff --git a/engines/lab/module.mk b/engines/lab/module.mk index a619cba6ed..7bb86c8c1e 100644 --- a/engines/lab/module.mk +++ b/engines/lab/module.mk @@ -18,7 +18,7 @@ MODULE_OBJS := \ resource.o \ savegame.o \ special.o \ - tilepuzzle.o \ + speciallocks.o \ utils.o # This module can be built as a plugin diff --git a/engines/lab/music.cpp b/engines/lab/music.cpp index 95581aec5c..bdd9d8973f 100644 --- a/engines/lab/music.cpp +++ b/engines/lab/music.cpp @@ -56,21 +56,24 @@ Music::Music(LabEngine *vm) : _vm(vm) { _leftInFile = 0; _musicOn = false; - _loopSoundEffect = false; _queuingAudioStream = nullptr; - _lastMusicRoom = 1; - _doReset = true; + _curRoomMusic = 1; +} + +byte Music::getSoundFlags() { + byte soundFlags = Audio::FLAG_LITTLE_ENDIAN; + if (_vm->getPlatform() == Common::kPlatformWindows) + soundFlags |= Audio::FLAG_16BITS; + else if (_vm->getPlatform() == Common::kPlatformDOS) + soundFlags |= Audio::FLAG_UNSIGNED; + + return soundFlags; } void Music::updateMusic() { if (!_musicOn || (getPlayingBufferCount() >= MAXBUFFERS)) return; - // NOTE: We need to use malloc(), cause this will be freed with free() - // by the music code - byte *musicBuffer = (byte *)malloc(MUSICBUFSIZE); - fillbuffer(musicBuffer); - // Queue a music block, and start the music, if needed bool startMusicFlag = false; @@ -79,13 +82,7 @@ void Music::updateMusic() { startMusicFlag = true; } - byte soundFlags = Audio::FLAG_LITTLE_ENDIAN; - if (_vm->getPlatform() == Common::kPlatformWindows) - soundFlags |= Audio::FLAG_16BITS; - else if (_vm->getPlatform() == Common::kPlatformDOS) - soundFlags |= Audio::FLAG_UNSIGNED; - - _queuingAudioStream->queueBuffer(musicBuffer, MUSICBUFSIZE, DisposeAfterUse::YES, soundFlags); + _queuingAudioStream->queueBuffer(fillBuffer(), MUSICBUFSIZE, DisposeAfterUse::YES, getSoundFlags()); if (startMusicFlag) _vm->_mixer->playStream(Audio::Mixer::kMusicSoundType, &_musicHandle, _queuingAudioStream); @@ -95,26 +92,20 @@ uint16 Music::getPlayingBufferCount() { return (_queuingAudioStream) ? _queuingAudioStream->numQueuedStreams() : 0; } -void Music::playSoundEffect(uint16 sampleSpeed, uint32 length, Common::File *dataFile) { +void Music::playSoundEffect(uint16 sampleSpeed, uint32 length, bool loop, Common::File *dataFile) { pauseBackMusic(); stopSoundEffect(); if (sampleSpeed < 4000) sampleSpeed = 4000; - byte soundFlags = Audio::FLAG_LITTLE_ENDIAN; - if (_vm->getPlatform() == Common::kPlatformWindows) - soundFlags |= Audio::FLAG_16BITS; - else - soundFlags |= Audio::FLAG_UNSIGNED; - // NOTE: We need to use malloc(), cause this will be freed with free() // by the music code byte *soundData = (byte *)malloc(length); dataFile->read(soundData, length); - Audio::SeekableAudioStream *audioStream = Audio::makeRawStream((const byte *)soundData, length, sampleSpeed, soundFlags); - uint loops = (_loopSoundEffect) ? 0 : 1; + Audio::SeekableAudioStream *audioStream = Audio::makeRawStream(soundData, length, sampleSpeed, getSoundFlags()); + uint loops = (loop) ? 0 : 1; Audio::LoopingAudioStream *loopingAudioStream = new Audio::LoopingAudioStream(audioStream, loops); _vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_sfxHandle, loopingAudioStream); } @@ -128,18 +119,24 @@ bool Music::isSoundEffectActive() const { return _vm->_mixer->isSoundHandleActive(_sfxHandle); } -void Music::fillbuffer(byte *musicBuffer) { +byte *Music::fillBuffer() { + // NOTE: We need to use malloc(), cause this will be freed with free() + // by the music code + byte *musicBuffer = (byte *)malloc(MUSICBUFSIZE); + if (MUSICBUFSIZE < _leftInFile) { _file->read(musicBuffer, MUSICBUFSIZE); _leftInFile -= MUSICBUFSIZE; } else { _file->read(musicBuffer, _leftInFile); - memset((char *)musicBuffer + _leftInFile, 0, MUSICBUFSIZE - _leftInFile); + memset(musicBuffer + _leftInFile, 0, MUSICBUFSIZE - _leftInFile); _file->seek(0); _leftInFile = _file->size(); } + + return musicBuffer; } void Music::startMusic(bool restartFl) { @@ -214,17 +211,15 @@ void Music::setMusic(bool on) { } void Music::checkRoomMusic() { - if ((_lastMusicRoom == _vm->_roomNum) || !_musicOn) + if ((_curRoomMusic == _vm->_roomNum) || !_musicOn) return; if (_vm->_roomNum == CLOWNROOM) changeMusic("Music:Laugh"); else if (_vm->_roomNum == DIMROOM) changeMusic("Music:Rm81"); - else if (_doReset) - resetMusic(); - _lastMusicRoom = _vm->_roomNum; + _curRoomMusic = _vm->_roomNum; } void Music::changeMusic(const Common::String filename) { @@ -263,33 +258,27 @@ void Music::resetMusic() { setMusic(false); _vm->updateMusicAndEvents(); - if (!_oldMusicOn) { - _tFile = 0; - return; - } - - _musicOn = _oldMusicOn; - startMusic(false); + if (_oldMusicOn) + startMusic(false); _tFile = 0; } -bool Music::readMusic(const Common::String filename, bool waitTillFinished) { +bool Music::readMusic(const Common::String filename, bool loop, bool waitTillFinished) { Common::File *file = _vm->_resource->openDataFile(filename, MKTAG('D', 'I', 'F', 'F')); _vm->updateMusicAndEvents(); - if (!_loopSoundEffect) - stopSoundEffect(); + stopSoundEffect(); if (!file) return false; _vm->_anim->_doBlack = false; - readSound(waitTillFinished, file); + readSound(waitTillFinished, loop, file); return true; } -void Music::readSound(bool waitTillFinished, Common::File *file) { +void Music::readSound(bool waitTillFinished, bool loop, Common::File *file) { uint32 magicBytes = file->readUint32LE(); if (magicBytes != 1219009121) { warning("readSound: Bad signature, skipping"); @@ -320,7 +309,7 @@ void Music::readSound(bool waitTillFinished, Common::File *file) { uint16 sampleRate = file->readUint16LE(); file->skip(2); - playSoundEffect(sampleRate, soundSize, file); + playSoundEffect(sampleRate, soundSize, loop, file); } else if (soundTag == 65535) { if (waitTillFinished) { while (isSoundEffectActive()) { diff --git a/engines/lab/music.h b/engines/lab/music.h index 42fdf41d67..47c538ee25 100644 --- a/engines/lab/music.h +++ b/engines/lab/music.h @@ -52,12 +52,11 @@ private: Common::File *_file; Common::File *_tFile; - bool _doReset; bool _musicOn; bool _musicPaused; bool _oldMusicOn; - uint16 _lastMusicRoom ; + uint16 _curRoomMusic ; uint32 _tLeftInFile; uint32 _leftInFile; @@ -67,22 +66,21 @@ private: Audio::QueuingAudioStream *_queuingAudioStream; private: - void fillbuffer(byte *musicBuffer); + byte *fillBuffer(); uint16 getPlayingBufferCount(); /** * Pauses the background music. */ void pauseBackMusic(); - void readSound(bool waitTillFinished, Common::File *file); + void readSound(bool waitTillFinished, bool loop, Common::File *file); /** * Starts up the music initially. */ void startMusic(bool restartFl); -public: - bool _loopSoundEffect; + byte getSoundFlags(); public: Music(LabEngine *vm); @@ -107,12 +105,12 @@ public: */ bool initMusic(const Common::String filename); bool isSoundEffectActive() const; - void playSoundEffect(uint16 sampleSpeed, uint32 length, Common::File *dataFile); + void playSoundEffect(uint16 sampleSpeed, uint32 length, bool loop, Common::File *dataFile); /** * Reads in a music file. Ignores any graphics. */ - bool readMusic(const Common::String filename, bool waitTillFinished); + bool readMusic(const Common::String filename, bool loop, bool waitTillFinished); /** * Changes the background music to the original piece playing. @@ -128,7 +126,6 @@ public: * Turns the music on and off. */ void setMusic(bool on); - void setMusicReset(bool reset) { _doReset = reset; } void stopSoundEffect(); /** diff --git a/engines/lab/processroom.cpp b/engines/lab/processroom.cpp index c096c75e21..997eb75dce 100644 --- a/engines/lab/processroom.cpp +++ b/engines/lab/processroom.cpp @@ -56,9 +56,8 @@ ViewData *LabEngine::getViewData(uint16 roomNum, uint16 direction) { if (_rooms[roomNum]._roomMsg.empty()) _resource->readViews(roomNum); - Common::List<ViewData> &views = _rooms[roomNum]._view[direction]; - - Common::List<ViewData>::iterator view; + ViewDataList &views = _rooms[roomNum]._view[direction]; + ViewDataList::iterator view; for (view = views.begin(); view != views.end(); ++view) { if (checkConditions(view->_condition)) @@ -68,14 +67,15 @@ ViewData *LabEngine::getViewData(uint16 roomNum, uint16 direction) { error("No view with matching condition found"); } -CloseData *LabEngine::getObject(Common::Point pos, CloseDataPtr closePtr) { - Common::List<CloseData> *list; +const CloseData *LabEngine::getObject(Common::Point pos, const CloseData *closePtr) { + const CloseDataList *list; if (!closePtr) list = &(getViewData(_roomNum, _direction)->_closeUps); else list = &(closePtr->_subCloseUps); - Common::List<CloseData>::iterator wrkClosePtr; + CloseDataList::const_iterator wrkClosePtr; + for (wrkClosePtr = list->begin(); wrkClosePtr != list->end(); ++wrkClosePtr) { Common::Rect objRect; objRect = _utils->rectScale(wrkClosePtr->_x1, wrkClosePtr->_y1, wrkClosePtr->_x2, wrkClosePtr->_y2); @@ -86,8 +86,8 @@ CloseData *LabEngine::getObject(Common::Point pos, CloseDataPtr closePtr) { return nullptr; } -CloseDataPtr LabEngine::findClosePtrMatch(CloseDataPtr closePtr, Common::List<CloseData> &list) { - Common::List<CloseData>::iterator i; +const CloseData *LabEngine::findClosePtrMatch(const CloseData *closePtr, const CloseDataList &list) { + CloseDataList::const_iterator i; for (i = list.begin(); i != list.end(); ++i) { if ((closePtr->_x1 == i->_x1) && (closePtr->_x2 == i->_x2) && @@ -95,8 +95,7 @@ CloseDataPtr LabEngine::findClosePtrMatch(CloseDataPtr closePtr, Common::List<Cl (closePtr->_depth == i->_depth)) return &(*i); - CloseDataPtr resClosePtr; - resClosePtr = findClosePtrMatch(closePtr, i->_subCloseUps); + const CloseData *resClosePtr = findClosePtrMatch(closePtr, i->_subCloseUps); if (resClosePtr) return resClosePtr; @@ -105,20 +104,20 @@ CloseDataPtr LabEngine::findClosePtrMatch(CloseDataPtr closePtr, Common::List<Cl return nullptr; } -Common::String LabEngine::getPictName(CloseDataPtr *closePtrList) { +Common::String LabEngine::getPictName(bool useClose) { ViewData *viewPtr = getViewData(_roomNum, _direction); - if (*closePtrList) { - *closePtrList = findClosePtrMatch(*closePtrList, viewPtr->_closeUps); + if (useClose && _closeDataPtr) { + _closeDataPtr = findClosePtrMatch(_closeDataPtr, viewPtr->_closeUps); - if (*closePtrList) - return (*closePtrList)->_graphicName; + if (_closeDataPtr) + return _closeDataPtr->_graphicName; } return viewPtr->_graphicName; } -void LabEngine::drawDirection(CloseDataPtr closePtr) { +void LabEngine::drawDirection(const CloseData *closePtr) { if (closePtr && !closePtr->_message.empty()) { _graphics->drawMessage(closePtr->_message, false); return; @@ -172,16 +171,15 @@ uint16 LabEngine::processArrow(uint16 curDirection, uint16 arrow) { return curDirection; } -void LabEngine::setCurrentClose(Common::Point pos, CloseDataPtr *closePtrList, bool useAbsoluteCoords, bool next) { - - Common::List<CloseData> *list; +void LabEngine::setCurrentClose(Common::Point pos, const CloseData **closePtrList, bool useAbsoluteCoords, bool next) { + const CloseDataList *list; if (!*closePtrList) list = &(getViewData(_roomNum, _direction)->_closeUps); else list = &((*closePtrList)->_subCloseUps); - Common::List<CloseData>::iterator closePtr; + CloseDataList::const_iterator closePtr; for (closePtr = list->begin(); closePtr != list->end(); ++closePtr) { Common::Rect target; if (!useAbsoluteCoords) @@ -202,19 +200,26 @@ void LabEngine::setCurrentClose(Common::Point pos, CloseDataPtr *closePtrList, b return; } } + + // If we got here, no match was found. If we want the "next" close-up, + // return the first one in the list, if any. + if (next) { + if (!list->empty()) + *closePtrList = &(*list->begin()); + } } -bool LabEngine::takeItem(Common::Point pos, CloseDataPtr *closePtrList) { - Common::List<CloseData> *list; - if (!*closePtrList) { +bool LabEngine::takeItem(Common::Point pos) { + const CloseDataList *list; + if (!_closeDataPtr) { list = &(getViewData(_roomNum, _direction)->_closeUps); - } else if ((*closePtrList)->_closeUpType < 0) { - _conditions->inclElement(abs((*closePtrList)->_closeUpType)); + } else if (_closeDataPtr->_closeUpType < 0) { + _conditions->inclElement(abs(_closeDataPtr->_closeUpType)); return true; } else - list = &((*closePtrList)->_subCloseUps); + list = &(_closeDataPtr->_subCloseUps); - Common::List<CloseData>::iterator closePtr; + CloseDataList::const_iterator closePtr; for (closePtr = list->begin(); closePtr != list->end(); ++closePtr) { Common::Rect objRect; objRect = _utils->rectScale(closePtr->_x1, closePtr->_y1, closePtr->_x2, closePtr->_y2); @@ -227,25 +232,22 @@ bool LabEngine::takeItem(Common::Point pos, CloseDataPtr *closePtrList) { return false; } -void LabEngine::doActions(const Common::List<Action> &actionList, CloseDataPtr *closePtrList) { - Common::List<Action>::const_iterator action; +void LabEngine::doActions(const ActionList &actionList) { + ActionList::const_iterator action; for (action = actionList.begin(); action != actionList.end(); ++action) { updateMusicAndEvents(); switch (action->_actionType) { case kActionPlaySound: - _music->_loopSoundEffect = false; - _music->readMusic(action->_messages[0], true); + _music->readMusic(action->_messages[0], false, true); break; - case kActionPlaySoundNoWait: - _music->_loopSoundEffect = false; - _music->readMusic(action->_messages[0], false); + case kActionPlaySoundNoWait: // only used in scene 7 (street, when teleporting to the surreal maze) + _music->readMusic(action->_messages[0], false, false); break; case kActionPlaySoundLooping: - _music->_loopSoundEffect = true; - _music->readMusic(action->_messages[0], false); + _music->readMusic(action->_messages[0], true, false); break; case kActionShowDiff: @@ -260,7 +262,6 @@ void LabEngine::doActions(const Common::List<Action> &actionList, CloseDataPtr * if (!action->_messages[0].empty()) // Puts a file into memory _graphics->loadPict(action->_messages[0]); - break; case kActionLoadBitmap: @@ -270,7 +271,7 @@ void LabEngine::doActions(const Common::List<Action> &actionList, CloseDataPtr * error("Unused opcode kActionShowBitmap has been called"); case kActionTransition: - _graphics->doTransition((TransitionType)action->_param1, closePtrList, action->_messages[0].c_str()); + _graphics->doTransition((TransitionType)action->_param1, action->_messages[0].c_str()); break; case kActionNoUpdate: @@ -283,7 +284,7 @@ void LabEngine::doActions(const Common::List<Action> &actionList, CloseDataPtr * break; case kActionShowCurPict: { - Common::String test = getPictName(closePtrList); + Common::String test = getPictName(true); if (test != _curFileName) { _curFileName = test; @@ -308,7 +309,7 @@ void LabEngine::doActions(const Common::List<Action> &actionList, CloseDataPtr * break; case kActionCShowMessage: - if (!*closePtrList) + if (!_closeDataPtr) _graphics->drawMessage(action->_messages[0], true); break; @@ -320,7 +321,7 @@ void LabEngine::doActions(const Common::List<Action> &actionList, CloseDataPtr * if (action->_param1 & 0x8000) { // This is a Wyrmkeep Windows trial version, thus stop at this // point, since we can't check for game payment status - _graphics->readPict(getPictName(closePtrList)); + _graphics->readPict(getPictName(true)); GUI::MessageDialog trialMessage("This is the end of the trial version. You can play the full game using the original interpreter from Wyrmkeep"); trialMessage.runModal(); break; @@ -328,21 +329,21 @@ void LabEngine::doActions(const Common::List<Action> &actionList, CloseDataPtr * _roomNum = action->_param1; _direction = action->_param2 - 1; - *closePtrList = nullptr; + _closeDataPtr = nullptr; _anim->_doBlack = true; break; case kActionSetCloseup: { Common::Point curPos = Common::Point(_utils->scaleX(action->_param1), _utils->scaleY(action->_param2)); - CloseDataPtr tmpClosePtr = getObject(curPos, *closePtrList); + const CloseData *tmpClosePtr = getObject(curPos, _closeDataPtr); if (tmpClosePtr) - *closePtrList = tmpClosePtr; + _closeDataPtr = tmpClosePtr; } break; case kActionMainView: - *closePtrList = nullptr; + _closeDataPtr = nullptr; break; case kActionSubInv: @@ -385,12 +386,10 @@ void LabEngine::doActions(const Common::List<Action> &actionList, CloseDataPtr * case kActionChangeMusic: _music->changeMusic(action->_messages[0]); - _music->setMusicReset(false); break; case kActionResetMusic: _music->resetMusic(); - _music->setMusicReset(true); break; case kActionFillMusic: @@ -407,12 +406,7 @@ void LabEngine::doActions(const Common::List<Action> &actionList, CloseDataPtr * break; case kActionClearSound: - if (_music->_loopSoundEffect) { - _music->_loopSoundEffect = false; - _music->stopSoundEffect(); - } else if (_music->isSoundEffectActive()) - _music->stopSoundEffect(); - + _music->stopSoundEffect(); break; case kActionWinMusic: @@ -470,19 +464,10 @@ void LabEngine::doActions(const Common::List<Action> &actionList, CloseDataPtr * } } - if (_music->_loopSoundEffect) { - _music->_loopSoundEffect = false; - _music->stopSoundEffect(); - } else { - while (_music->isSoundEffectActive()) { - updateMusicAndEvents(); - _anim->diffNextFrame(); - waitTOF(); - } - } + _music->stopSoundEffect(); } -bool LabEngine::doActionRuleSub(int16 action, int16 roomNum, CloseDataPtr closePtr, CloseDataPtr *setCloseList, bool allowDefaults) { +bool LabEngine::doActionRuleSub(int16 action, int16 roomNum, const CloseData *closePtr, bool allowDefaults) { action++; if (closePtr) { @@ -500,7 +485,7 @@ bool LabEngine::doActionRuleSub(int16 action, int16 roomNum, CloseDataPtr closeP ((rule->_param2 == 0) && allowDefaults)) || ((action == 1) && (rule->_param2 == -closePtr->_closeUpType))) { if (checkConditions(rule->_condition)) { - doActions(rule->_actionList, setCloseList); + doActions(rule->_actionList); return true; } } @@ -511,27 +496,27 @@ bool LabEngine::doActionRuleSub(int16 action, int16 roomNum, CloseDataPtr closeP return false; } -bool LabEngine::doActionRule(Common::Point pos, int16 action, int16 roomNum, CloseDataPtr *closePtrList) { +bool LabEngine::doActionRule(Common::Point pos, int16 action, int16 roomNum) { if (roomNum) _newFileName = NOFILE; else _newFileName = _curFileName; - CloseDataPtr curClosePtr = getObject(pos, *closePtrList); + const CloseData *curClosePtr = getObject(pos, _closeDataPtr); - if (doActionRuleSub(action, roomNum, curClosePtr, closePtrList, false)) + if (doActionRuleSub(action, roomNum, curClosePtr, false)) return true; - else if (doActionRuleSub(action, roomNum, *closePtrList, closePtrList, false)) + else if (doActionRuleSub(action, roomNum, _closeDataPtr, false)) return true; - else if (doActionRuleSub(action, roomNum, curClosePtr, closePtrList, true)) + else if (doActionRuleSub(action, roomNum, curClosePtr, true)) return true; - else if (doActionRuleSub(action, roomNum, *closePtrList, closePtrList, true)) + else if (doActionRuleSub(action, roomNum, _closeDataPtr, true)) return true; return false; } -bool LabEngine::doOperateRuleSub(int16 itemNum, int16 roomNum, CloseDataPtr closePtr, CloseDataPtr *setCloseList, bool allowDefaults) { +bool LabEngine::doOperateRuleSub(int16 itemNum, int16 roomNum, const CloseData *closePtr, bool allowDefaults) { if (closePtr) if (closePtr->_closeUpType > 0) { RuleList *rules = &(_rooms[roomNum]._rules); @@ -546,7 +531,7 @@ bool LabEngine::doOperateRuleSub(int16 itemNum, int16 roomNum, CloseDataPtr clos ((rule->_param1 == itemNum) || ((rule->_param1 == 0) && allowDefaults)) && ((rule->_param2 == closePtr->_closeUpType) || ((rule->_param2 == 0) && allowDefaults))) { if (checkConditions(rule->_condition)) { - doActions(rule->_actionList, setCloseList); + doActions(rule->_actionList); return true; } } @@ -556,41 +541,41 @@ bool LabEngine::doOperateRuleSub(int16 itemNum, int16 roomNum, CloseDataPtr clos return false; } -bool LabEngine::doOperateRule(Common::Point pos, int16 ItemNum, CloseDataPtr *closePtrList) { +bool LabEngine::doOperateRule(Common::Point pos, int16 ItemNum) { _newFileName = NOFILE; - CloseDataPtr closePtr = getObject(pos, *closePtrList); + const CloseData *closePtr = getObject(pos, _closeDataPtr); - if (doOperateRuleSub(ItemNum, _roomNum, closePtr, closePtrList, false)) + if (doOperateRuleSub(ItemNum, _roomNum, closePtr, false)) return true; - else if (doOperateRuleSub(ItemNum, _roomNum, *closePtrList, closePtrList, false)) + else if (doOperateRuleSub(ItemNum, _roomNum, _closeDataPtr, false)) return true; - else if (doOperateRuleSub(ItemNum, _roomNum, closePtr, closePtrList, true)) + else if (doOperateRuleSub(ItemNum, _roomNum, closePtr, true)) return true; - else if (doOperateRuleSub(ItemNum, _roomNum, *closePtrList, closePtrList, true)) + else if (doOperateRuleSub(ItemNum, _roomNum, _closeDataPtr, true)) return true; else { _newFileName = _curFileName; - if (doOperateRuleSub(ItemNum, 0, closePtr, closePtrList, false)) + if (doOperateRuleSub(ItemNum, 0, closePtr, false)) return true; - else if (doOperateRuleSub(ItemNum, 0, *closePtrList, closePtrList, false)) + else if (doOperateRuleSub(ItemNum, 0, _closeDataPtr, false)) return true; - else if (doOperateRuleSub(ItemNum, 0, closePtr, closePtrList, true)) + else if (doOperateRuleSub(ItemNum, 0, closePtr, true)) return true; - else if (doOperateRuleSub(ItemNum, 0, *closePtrList, closePtrList, true)) + else if (doOperateRuleSub(ItemNum, 0, _closeDataPtr, true)) return true; } return false; } -bool LabEngine::doGoForward(CloseDataPtr *closePtrList) { +bool LabEngine::doGoForward() { RuleList &rules = _rooms[_roomNum]._rules; for (RuleList::iterator rule = rules.begin(); rule != rules.end(); ++rule) { if ((rule->_ruleType == kRuleTypeGoForward) && (rule->_param1 == (_direction + 1))) { if (checkConditions(rule->_condition)) { - doActions(rule->_actionList, closePtrList); + doActions(rule->_actionList); return true; } } @@ -599,7 +584,7 @@ bool LabEngine::doGoForward(CloseDataPtr *closePtrList) { return false; } -bool LabEngine::doTurn(uint16 from, uint16 to, CloseDataPtr *closePtrList) { +bool LabEngine::doTurn(uint16 from, uint16 to) { from++; to++; @@ -610,7 +595,7 @@ bool LabEngine::doTurn(uint16 from, uint16 to, CloseDataPtr *closePtrList) { ((rule->_ruleType == kRuleTypeTurnFromTo) && (rule->_param1 == from) && (rule->_param2 == to))) { if (checkConditions(rule->_condition)) { - doActions(rule->_actionList, closePtrList); + doActions(rule->_actionList); return true; } } @@ -619,12 +604,12 @@ bool LabEngine::doTurn(uint16 from, uint16 to, CloseDataPtr *closePtrList) { return false; } -bool LabEngine::doMainView(CloseDataPtr *closePtrList) { +bool LabEngine::doMainView() { RuleList &rules = _rooms[_roomNum]._rules; for (RuleList::iterator rule = rules.begin(); rule != rules.end(); ++rule) { if (rule->_ruleType == kRuleTypeGoMainView) { if (checkConditions(rule->_condition)) { - doActions(rule->_actionList, closePtrList); + doActions(rule->_actionList); return true; } } diff --git a/engines/lab/processroom.h b/engines/lab/processroom.h index 5051588ab1..1d53ce01af 100644 --- a/engines/lab/processroom.h +++ b/engines/lab/processroom.h @@ -119,23 +119,20 @@ enum MapDoors { kDoorBottomWest = 128 }; -// Special Map ID's -#define NORMAL 0 -#define UPARROWROOM 1 -#define DOWNARROWROOM 2 -#define BRIDGEROOM 3 -#define VCORRIDOR 4 -#define HCORRIDOR 5 -#define MEDMAZE 6 -#define HEDGEMAZE 7 -#define SURMAZE 8 -#define MULTIMAZEF1 9 -#define MULTIMAZEF2 10 -#define MULTIMAZEF3 11 - -#if defined(WIN32) -#pragma pack(push, 1) -#endif +enum SpecialRoom { + kNormalRoom = 0, + kUpArrowRoom, + kDownArrowRoom, + kBridgeRoom, + kVerticalCorridor, + kHorizontalCorridor, + kMedMaze, + kHedgeMaze, + kSurMaze, + kMultiMazeF1, + kMultiMazeF2, + kMultiMazeF3 +}; struct CloseData { uint16 _x1, _y1, _x2, _y2; @@ -143,13 +140,13 @@ struct CloseData { uint16 _depth; // Level of the closeup. Common::String _graphicName; Common::String _message; - Common::List<CloseData> _subCloseUps; + CloseDataList _subCloseUps; }; struct ViewData { Common::Array<int16> _condition; Common::String _graphicName; - Common::List<CloseData> _closeUps; + CloseDataList _closeUps; }; struct Action { @@ -165,13 +162,13 @@ struct Rule { int16 _param1; int16 _param2; Common::Array<int16> _condition; - Common::List<Action> _actionList; + ActionList _actionList; }; struct RoomData { uint16 _doors[4]; byte _transitionType; - Common::List<ViewData> _view[4]; + ViewDataList _view[4]; RuleList _rules; Common::String _roomMsg; }; @@ -183,14 +180,11 @@ struct InventoryData { }; struct MapData { - uint16 _x, _y, _pageNumber, _specialID; + uint16 _x, _y, _pageNumber; + SpecialRoom _specialID; uint32 _mapFlags; }; -#if defined(WIN32) -#pragma pack(pop) -#endif - } // End of namespace Lab #endif // LAB_PROCESSROOM_H diff --git a/engines/lab/resource.cpp b/engines/lab/resource.cpp index 985a71b490..17535a7659 100644 --- a/engines/lab/resource.cpp +++ b/engines/lab/resource.cpp @@ -253,7 +253,7 @@ void Resource::readRule(Common::File *file, RuleList &rules) { } } -void Resource::readAction(Common::File *file, Common::List<Action>& list) { +void Resource::readAction(Common::File *file, ActionList &list) { list.clear(); while (file->readByte() == 1) { @@ -275,7 +275,7 @@ void Resource::readAction(Common::File *file, Common::List<Action>& list) { } } -void Resource::readCloseUps(uint16 depth, Common::File *file, Common::List<CloseData> &list) { +void Resource::readCloseUps(uint16 depth, Common::File *file, CloseDataList &list) { list.clear(); while (file->readByte() != '\0') { list.push_back(CloseData()); @@ -293,7 +293,7 @@ void Resource::readCloseUps(uint16 depth, Common::File *file, Common::List<Close } } -void Resource::readView(Common::File *file, Common::List<ViewData> &list) { +void Resource::readView(Common::File *file, ViewDataList &list) { list.clear(); while (file->readByte() == 1) { list.push_back(ViewData()); diff --git a/engines/lab/resource.h b/engines/lab/resource.h index 7a7cfb4b95..307eac3068 100644 --- a/engines/lab/resource.h +++ b/engines/lab/resource.h @@ -110,9 +110,9 @@ private: Common::String readString(Common::File *file); Common::Array<int16> readConditions(Common::File *file); void readRule(Common::File *file, RuleList &rules); - void readAction(Common::File *file, Common::List<Action> &action); - void readCloseUps(uint16 depth, Common::File *file, Common::List<CloseData> &close); - void readView(Common::File *file, Common::List<ViewData> &view); + void readAction(Common::File *file, ActionList &action); + void readCloseUps(uint16 depth, Common::File *file, CloseDataList &close); + void readView(Common::File *file, ViewDataList &view); void readStaticText(); Common::String translateFileName(const Common::String filename); diff --git a/engines/lab/savegame.cpp b/engines/lab/savegame.cpp index 0bdaf74865..1564babfc8 100644 --- a/engines/lab/savegame.cpp +++ b/engines/lab/savegame.cpp @@ -43,7 +43,7 @@ #include "lab/labsets.h" #include "lab/music.h" #include "lab/processroom.h" -#include "lab/tilepuzzle.h" +#include "lab/speciallocks.h" namespace Lab { @@ -128,8 +128,8 @@ bool LabEngine::saveGame(int slot, const Common::String desc) { return false; // Load scene pic - CloseDataPtr closePtr = nullptr; - _graphics->readPict(getPictName(&closePtr)); + _graphics->readPict(getPictName(false)); + writeSaveGameHeader(file, desc); file->writeUint16LE(_roomNum); @@ -144,7 +144,7 @@ bool LabEngine::saveGame(int slot, const Common::String desc) { for (int i = 0; i < _roomsFound->_lastElement / (8 * 2); i++) file->writeUint16LE(_roomsFound->_array[i]); - _tilePuzzle->save(file); + _specialLocks->save(file); // Breadcrumbs for (uint i = 0; i < MAX_CRUMBS; i++) { @@ -181,7 +181,7 @@ bool LabEngine::loadGame(int slot) { for (int i = 0; i < _roomsFound->_lastElement / (8 * 2); i++) _roomsFound->_array[i] = file->readUint16LE(); - _tilePuzzle->load(file); + _specialLocks->load(file); // Breadcrumbs for (int i = 0; i < MAX_CRUMBS; i++) { diff --git a/engines/lab/special.cpp b/engines/lab/special.cpp index e15561d9fb..8e503665c7 100644 --- a/engines/lab/special.cpp +++ b/engines/lab/special.cpp @@ -134,7 +134,7 @@ void LabEngine::loadJournalData() { delete journalFile; _anim->_noPalChange = true; - _journalBackImage->_imageData = new byte[_graphics->_screenBytesPerPage]; + _journalBackImage->setData(new byte[_graphics->_screenBytesPerPage]); _graphics->readPict("P:Journal.pic", true, false, _journalBackImage->_imageData); _anim->_noPalChange = false; @@ -232,13 +232,13 @@ void LabEngine::processJournal() { if (!msg) updateMusicAndEvents(); else { - uint32 msgClass = msg->_msgClass; - uint16 buttonId = msg->_code; + MessageClass msgClass = msg->_msgClass; if ((msgClass == kMessageRightClick) || - ((msgClass == kMessageRawKey) && (buttonId == Common::KEYCODE_ESCAPE))) + ((msgClass == kMessageRawKey) && (msg->_code == Common::KEYCODE_ESCAPE))) return; else if (msgClass == kMessageButtonUp) { + uint16 buttonId = msg->_code; if (buttonId == 0) { if (_journalPage >= 2) { _journalPage -= 2; @@ -263,7 +263,7 @@ void LabEngine::doJournal() { _journalBackImage->_width = _graphics->_screenWidth; _journalBackImage->_height = _graphics->_screenHeight; - _journalBackImage->_imageData = nullptr; + _journalBackImage->setData(nullptr, true); updateMusicAndEvents(); loadJournalData(); @@ -276,8 +276,8 @@ void LabEngine::doJournal() { _event->mouseHide(); delete[] _blankJournal; - delete[] _journalBackImage->_imageData; - _blankJournal = _journalBackImage->_imageData = nullptr; + _blankJournal = nullptr; + _journalBackImage->setData(nullptr, true); _event->freeButtonList(&_journalButtonList); _graphics->freeFont(&_journalFont); @@ -333,13 +333,13 @@ void LabEngine::drawMonText(const char *text, TextFont *monitorFont, Common::Rec curText = text + charsDrawn; _lastPage = (*curText == 0); - charsDrawn = _graphics->flowText(monitorFont, yspacing, 2, 0, false, false, false, true, textRect, curText); + _graphics->flowText(monitorFont, yspacing, 2, 0, false, false, false, true, textRect, curText); _event->mouseShow(); } void LabEngine::processMonitor(const char *ntext, TextFont *monitorFont, bool isInteractive, Common::Rect textRect) { Common::String startFileName = _monitorTextFilename; - CloseDataPtr startClosePtr = _closeDataPtr, lastClosePtr[10]; + const CloseData *startClosePtr = _closeDataPtr, *lastClosePtr[10]; uint16 depth = 0; lastClosePtr[0] = _closeDataPtr; @@ -349,15 +349,15 @@ void LabEngine::processMonitor(const char *ntext, TextFont *monitorFont, bool is if (!_closeDataPtr) _closeDataPtr = startClosePtr; - Common::String test; + Common::String filename; if (_closeDataPtr == startClosePtr) - test = startFileName; + filename = startFileName; else - test = _closeDataPtr->_graphicName; + filename = _closeDataPtr->_graphicName; - if (test != _monitorTextFilename) { + if (filename != _monitorTextFilename) { _monitorPage = 0; - _monitorTextFilename = test; + _monitorTextFilename = filename; Common::String text = _resource->getText(_monitorTextFilename); _graphics->fade(false); @@ -374,22 +374,24 @@ void LabEngine::processMonitor(const char *ntext, TextFont *monitorFont, bool is return; } - if (!msg) { + if (!msg) updateMusicAndEvents(); - } else { - uint32 msgClass = msg->_msgClass; - uint16 mouseX = msg->_mouse.x; - uint16 mouseY = msg->_mouse.y; - uint16 code = msg->_code; + else { + MessageClass msgClass = msg->_msgClass; if ((msgClass == kMessageRightClick) || - ((msgClass == kMessageRawKey) && (code == Common::KEYCODE_ESCAPE))) + ((msgClass == kMessageRawKey) && (msg->_code == Common::KEYCODE_ESCAPE))) return; - else if (msgClass == kMessageLeftClick) { + + if (msgClass == kMessageLeftClick) { + int16 mouseX = msg->_mouse.x; + int16 mouseY = msg->_mouse.y; + if ((mouseY >= _utils->vgaScaleY(171)) && (mouseY <= _utils->vgaScaleY(200))) { - if (mouseX <= _utils->vgaScaleX(31)) { + if (mouseX <= _utils->vgaScaleX(31)) return; - } else if (mouseX <= _utils->vgaScaleX(59)) { + + if (mouseX <= _utils->vgaScaleX(59)) { if (isInteractive) { _monitorPage = 0; @@ -409,12 +411,12 @@ void LabEngine::processMonitor(const char *ntext, TextFont *monitorFont, bool is drawMonText(ntext, monitorFont, textRect, isInteractive); } } else if (_monitorPage >= 1) { - // mouseX between 290 and 320 (scaled) + // mouseX is greater than 290 (scaled) _monitorPage -= 1; drawMonText(ntext, monitorFont, textRect, isInteractive); } } else if (isInteractive) { - CloseDataPtr tmpClosePtr = _closeDataPtr; + const CloseData *tmpClosePtr = _closeDataPtr; mouseY = 64 + (mouseY / _monitorButtonHeight) * 42; mouseX = 101; setCurrentClose(Common::Point(mouseX, mouseY), &_closeDataPtr, false); diff --git a/engines/lab/tilepuzzle.cpp b/engines/lab/speciallocks.cpp index 8f21cee4b4..fe70b0f111 100644 --- a/engines/lab/tilepuzzle.cpp +++ b/engines/lab/speciallocks.cpp @@ -38,7 +38,7 @@ #include "lab/image.h" #include "lab/labsets.h" #include "lab/resource.h" -#include "lab/tilepuzzle.h" +#include "lab/speciallocks.h" #include "lab/utils.h" namespace Lab { @@ -69,7 +69,7 @@ const uint16 SOLUTION[4][4] = { const int COMBINATION_X[6] = { 45, 83, 129, 166, 211, 248 }; -TilePuzzle::TilePuzzle(LabEngine *vm) : _vm(vm) { +SpecialLocks::SpecialLocks(LabEngine *vm) : _vm(vm) { for (int i = 0; i < 16; i++) _tiles[i] = nullptr; @@ -85,7 +85,7 @@ TilePuzzle::TilePuzzle(LabEngine *vm) : _vm(vm) { _numberImages[i] = nullptr; } -TilePuzzle::~TilePuzzle() { +SpecialLocks::~SpecialLocks() { for (int i = 0; i < 16; i++) delete _tiles[i]; @@ -95,7 +95,7 @@ TilePuzzle::~TilePuzzle() { } } -void TilePuzzle::mouseTile(Common::Point pos) { +void SpecialLocks::tileClick(Common::Point pos) { Common::Point realPos = _vm->_utils->vgaUnscale(pos); if ((realPos.x < 101) || (realPos.y < 26)) @@ -108,7 +108,7 @@ void TilePuzzle::mouseTile(Common::Point pos) { changeTile(tileX, tileY); } -void TilePuzzle::changeTile(uint16 col, uint16 row) { +void SpecialLocks::changeTile(uint16 col, uint16 row) { int16 scrolltype = -1; if (row > 0) { @@ -174,7 +174,7 @@ void TilePuzzle::changeTile(uint16 col, uint16 row) { } } -void TilePuzzle::mouseCombination(Common::Point pos) { +void SpecialLocks::combinationClick(Common::Point pos) { Common::Point realPos = _vm->_utils->vgaUnscale(pos); if (!Common::Rect(44, 63, 285, 99).contains(realPos)) @@ -197,7 +197,7 @@ void TilePuzzle::mouseCombination(Common::Point pos) { changeCombination(number); } -void TilePuzzle::doTile(bool showsolution) { +void SpecialLocks::doTile(bool showsolution) { uint16 row = 0, col = 0, rowm, colm, num; int16 rows, cols; @@ -235,7 +235,7 @@ void TilePuzzle::doTile(bool showsolution) { } } -void TilePuzzle::showTile(const Common::String filename, bool showSolution) { +void SpecialLocks::showTileLock(const Common::String filename, bool showSolution) { _vm->_anim->_doBlack = true; _vm->_anim->_noPalChange = true; _vm->_graphics->readPict(filename); @@ -255,7 +255,7 @@ void TilePuzzle::showTile(const Common::String filename, bool showSolution) { _vm->_graphics->setPalette(_vm->_anim->_diffPalette, 256); } -void TilePuzzle::doTileScroll(uint16 col, uint16 row, uint16 scrolltype) { +void SpecialLocks::doTileScroll(uint16 col, uint16 row, uint16 scrolltype) { int16 dX = 0, dY = 0, dx = 0, dy = 0, sx = 0, sy = 0; int last = 0; @@ -296,7 +296,15 @@ void TilePuzzle::doTileScroll(uint16 col, uint16 row, uint16 scrolltype) { delete[] buffer; } -void TilePuzzle::changeCombination(uint16 number) { +void SpecialLocks::scrollRaster(int16 dx, int16 dy, uint16 x1, uint16 y1, uint16 x2, uint16 y2, byte *buffer) { + if (dx) + _vm->_graphics->scrollDisplayX(dx, x1, y1, x2, y2, buffer); + + if (dy) + _vm->_graphics->scrollDisplayY(dy, x1, y1, x2, y2, buffer); +} + +void SpecialLocks::changeCombination(uint16 number) { const int solution[6] = { 0, 4, 0, 8, 7, 2 }; Image display(_vm); @@ -308,27 +316,25 @@ void TilePuzzle::changeCombination(uint16 number) { uint16 combnum = _combination[number]; - display._imageData = _vm->_graphics->getCurrentDrawingBuffer(); - display._width = _vm->_graphics->_screenWidth; - display._height = _vm->_graphics->_screenHeight; + display.setData(_vm->_graphics->getCurrentDrawingBuffer(), false); + display._width = _vm->_graphics->_screenWidth; + display._height = _vm->_graphics->_screenHeight; - byte *buffer = new byte[_tiles[1]->_width * _tiles[1]->_height * 2]; + byte *buffer = new byte[_numberImages[1]->_width * _numberImages[1]->_height * 2]; for (int i = 1; i <= (_numberImages[combnum]->_height / 2); i++) { if (_vm->_isHiRes) { if (i & 1) _vm->waitTOF(); - } else + } + else _vm->waitTOF(); - display._imageData = _vm->_graphics->getCurrentDrawingBuffer(); + display.setData(_vm->_graphics->getCurrentDrawingBuffer(), false); _vm->_graphics->scrollDisplayY(2, _vm->_utils->vgaScaleX(COMBINATION_X[number]), _vm->_utils->vgaScaleY(65), _vm->_utils->vgaScaleX(COMBINATION_X[number]) + (_numberImages[combnum])->_width - 1, _vm->_utils->vgaScaleY(65) + (_numberImages[combnum])->_height, buffer); _numberImages[combnum]->blitBitmap(0, (_numberImages[combnum])->_height - (2 * i), &(display), _vm->_utils->vgaScaleX(COMBINATION_X[number]), _vm->_utils->vgaScaleY(65), (_numberImages[combnum])->_width, 2, false); } - // Prevent the Image destructor from deleting the display buffer - display._imageData = nullptr; - delete[] buffer; bool unlocked = true; @@ -341,20 +347,7 @@ void TilePuzzle::changeCombination(uint16 number) { _vm->_conditions->exclElement(COMBINATIONUNLOCKED); } -void TilePuzzle::scrollRaster(int16 dx, int16 dy, uint16 x1, uint16 y1, uint16 x2, uint16 y2, byte *buffer) { - if (dx) - _vm->_graphics->scrollDisplayX(dx, x1, y1, x2, y2, buffer); - - if (dy) - _vm->_graphics->scrollDisplayY(dy, x1, y1, x2, y2, buffer); -} - -void TilePuzzle::doCombination() { - for (int i = 0; i <= 5; i++) - _numberImages[_combination[i]]->drawImage(_vm->_utils->vgaScaleX(COMBINATION_X[i]), _vm->_utils->vgaScaleY(65)); -} - -void TilePuzzle::showCombination(const Common::String filename) { +void SpecialLocks::showCombinationLock(const Common::String filename) { _vm->_anim->_doBlack = true; _vm->_anim->_noPalChange = true; _vm->_graphics->readPict(filename); @@ -364,18 +357,20 @@ void TilePuzzle::showCombination(const Common::String filename) { Common::File *numFile = _vm->_resource->openDataFile("P:Numbers"); - for (int CurBit = 0; CurBit < 10; CurBit++) - _numberImages[CurBit] = new Image(numFile, _vm); + for (int i = 0; i < 10; i++) { + _numberImages[i] = new Image(numFile, _vm); + } delete numFile; - doCombination(); + for (int i = 0; i <= 5; i++) + _numberImages[_combination[i]]->drawImage(_vm->_utils->vgaScaleX(COMBINATION_X[i]), _vm->_utils->vgaScaleY(65)); _vm->_graphics->setPalette(_vm->_anim->_diffPalette, 256); } -void TilePuzzle::save(Common::OutSaveFile *file) { - // Combination lock and tile stuff +void SpecialLocks::save(Common::OutSaveFile *file) { + // Combination lock for (int i = 0; i < 6; i++) file->writeByte(_combination[i]); @@ -385,8 +380,8 @@ void TilePuzzle::save(Common::OutSaveFile *file) { file->writeUint16LE(_curTile[i][j]); } -void TilePuzzle::load(Common::InSaveFile *file) { - // Combination lock and tile stuff +void SpecialLocks::load(Common::InSaveFile *file) { + // Combination lock for (int i = 0; i < 6; i++) _combination[i] = file->readByte(); diff --git a/engines/lab/tilepuzzle.h b/engines/lab/speciallocks.h index dd4abba8ec..424eba242a 100644 --- a/engines/lab/tilepuzzle.h +++ b/engines/lab/speciallocks.h @@ -37,7 +37,7 @@ namespace Lab { class LabEngine; -class TilePuzzle { +class SpecialLocks { private: LabEngine *_vm; Image *_tiles[16]; @@ -46,28 +46,23 @@ private: byte _combination[6]; public: - TilePuzzle(LabEngine *vm); - virtual ~TilePuzzle(); + SpecialLocks(LabEngine *vm); + ~SpecialLocks(); - /** - * Processes mouse clicks and changes the combination. - */ - void mouseTile(Common::Point pos); + void showTileLock(const Common::String filename, bool showSolution); /** - * Processes mouse clicks and changes the combination. + * Processes mouse clicks and changes tile positions. */ - void mouseCombination(Common::Point pos); + void tileClick(Common::Point pos); - /** - * Reads in a backdrop picture. - */ - void showCombination(const Common::String filename); + void showCombinationLock(const Common::String filename); /** - * Reads in a backdrop picture. + * Processes mouse clicks and changes the door combination. */ - void showTile(const Common::String filename, bool showSolution); + void combinationClick(Common::Point pos); + void save(Common::OutSaveFile *file); void load(Common::InSaveFile *file); @@ -78,18 +73,13 @@ private: void changeCombination(uint16 number); /** - * Changes the combination number of one of the slots + * Changes the tile positions in the tile puzzle */ void changeTile(uint16 col, uint16 row); /** * Draws the images of the combination lock to the display bitmap. */ - void doCombination(); - - /** - * Draws the images of the combination lock to the display bitmap. - */ void doTile(bool showsolution); /** |