diff options
43 files changed, 2513 insertions, 564 deletions
diff --git a/engines/access/access.cpp b/engines/access/access.cpp index 0a4e519c91..3fd5c0698c 100644 --- a/engines/access/access.cpp +++ b/engines/access/access.cpp @@ -52,11 +52,10 @@ AccessEngine::AccessEngine(OSystem *syst, const AccessGameDescription *gameDesc) _destIn = nullptr; _current = nullptr; _mouseMode = 0; + _playerDataCount = 0; _currentMan = 0; _currentManOld = -1; _converseMode = 0; - _startAboutBox = 0; - _startTravelBox = 0; _numAnimTimers = 0; _startup = 0; _currentCharFlag = false; @@ -97,11 +96,33 @@ AccessEngine::AccessEngine(OSystem *syst, const AccessGameDescription *gameDesc) for (int i = 0; i < 100; i++) _objectsTable[i] = nullptr; _clearSummaryFlag = false; + + for (int i = 0; i < 60; i++) + TRAVEL[i] = 0; + STARTTRAVELITEM = STARTTRAVELBOX = 0; + for (int i = 0; i < 33; i++) + ASK[i]; + _startAboutItem = _startAboutBox = 0; + _byte26CB5 = 0; + BCNT = 0; + BOXDATASTART = 0; + BOXDATAEND = false; + BOXSELECTY = 0; + BOXSELECTYOLD = -1; + NUMBLINES = 0; + TEMPLIST = nullptr; + _pictureTaken = 0; + + _vidEnd = false; } AccessEngine::~AccessEngine() { delete _animation; delete _bubbleBox; + delete _helpBox; + delete _travelBox; + delete _invBox; + delete _aboutBox; delete _char; delete _debugger; delete _events; @@ -147,7 +168,18 @@ void AccessEngine::initialize() { // Create sub-objects of the engine _animation = new AnimationManager(this); - _bubbleBox = new BubbleBox(this); + _bubbleBox = new BubbleBox(this, TYPE_2, 64, 32, 130, 122, 0, 0, 0, 0, ""); + if (getGameID() == GType_MartianMemorandum) { + _helpBox = new BubbleBox(this, TYPE_1, 64, 24, 146, 122, 1, 32, 2, 76, "HELP"); + _travelBox = new BubbleBox(this, TYPE_1, 64, 32, 194, 122, 1, 24, 2, 74, "TRAVEL"); + _invBox = new BubbleBox(this, TYPE_1, 64, 32, 146, 122, 1, 32, 2, 76, "INVENTORY"); + _aboutBox = new BubbleBox(this, TYPE_1, 64, 32, 194, 122, 1, 32, 2, 76, "ASK ABOUT"); + } else { + _helpBox = nullptr; + _travelBox = nullptr; + _invBox = nullptr; + _aboutBox = nullptr; + } _char = new CharManager(this); _debugger = Debugger::init(this); _events = new EventsManager(this); @@ -416,10 +448,6 @@ void AccessEngine::playVideo(int videoNum, const Common::Point &pt) { } } -void AccessEngine::doLoadSave() { - error("TODO: doLoadSave"); -} - void AccessEngine::freeChar() { _scripts->freeScriptData(); _animation->clearTimers(); @@ -572,6 +600,36 @@ void AccessEngine::writeSavegameHeader(Common::OutSaveFile *out, AccessSavegameH out->writeUint32LE(_events->getFrameCounter()); } +void AccessEngine::SPRINTCHR(char c, int fontNum) { + warning("TODO: SPRINTCHR"); + _fonts._font1.drawChar(_screen, c, _screen->_printOrg); +} + +void AccessEngine::PRINTCHR(Common::String msg, int fontNum) { + _events->hideCursor(); + warning("TODO: PRINTCHR - Handle fontNum"); + + for (int i = 0; msg[i]; i++) { + if (!(_fonts._charSet._hi & 8)) { + _fonts._font1.drawChar(_screen, msg[i], _screen->_printOrg); + continue; + } else if (_fonts._charSet._hi & 2) { + Common::Point oldPos = _screen->_printOrg; + int oldFontLo = _fonts._charFor._lo; + + _fonts._charFor._lo = 0; + _screen->_printOrg.x++; + _screen->_printOrg.y++; + SPRINTCHR(msg[i], fontNum); + + _screen->_printOrg = oldPos; + _fonts._charFor._lo = oldFontLo; + } + SPRINTCHR(msg[i], fontNum); + } + _events->showCursor(); +} + bool AccessEngine::shouldQuitOrRestart() { return shouldQuit() || _restartFl; } diff --git a/engines/access/access.h b/engines/access/access.h index be007e0cb8..a53a659403 100644 --- a/engines/access/access.h +++ b/engines/access/access.h @@ -137,6 +137,10 @@ protected: public: AnimationManager *_animation; BubbleBox *_bubbleBox; + BubbleBox *_helpBox; + BubbleBox *_travelBox; + BubbleBox *_invBox; + BubbleBox *_aboutBox; CharManager *_char; Debugger *_debugger; EventsManager *_events; @@ -173,10 +177,9 @@ public: ImageEntryList _images; int _mouseMode; + int _playerDataCount; int _currentManOld; int _converseMode; - int _startAboutBox; - int _startTravelBox; bool _currentCharFlag; bool _boxSelect; int _scale; @@ -204,6 +207,26 @@ public: uint32 _newDate; int _flags[256]; + // Fields used by MM + // TODO: Refactor + int TRAVEL[60]; + int ASK[40]; + int STARTTRAVELITEM; + int STARTTRAVELBOX; + int _startAboutItem; + int _startAboutBox; + int BOXDATASTART; + bool BOXDATAEND; + int BOXSELECTY; + int BOXSELECTYOLD; + int NUMBLINES; + byte _byte26CB5; + int BCNT; + byte *TEMPLIST; + int _pictureTaken; + // + + bool _vidEnd; bool _clearSummaryFlag; bool _cheatFl; bool _restartFl; @@ -250,8 +273,6 @@ public: void copyBF2Vid(); - void doLoadSave(); - void freeChar(); /** @@ -289,6 +310,9 @@ public: * Write out a savegame header */ void writeSavegameHeader(Common::OutSaveFile *out, AccessSavegameHeader &header); + + void SPRINTCHR(char c, int fontNum); + void PRINTCHR(Common::String msg, int fontNum); }; } // End of namespace Access diff --git a/engines/access/amazon/amazon_game.cpp b/engines/access/amazon/amazon_game.cpp index 4c9df7b8ff..9c39a9bd49 100644 --- a/engines/access/amazon/amazon_game.cpp +++ b/engines/access/amazon/amazon_game.cpp @@ -260,13 +260,24 @@ void AmazonEngine::doEstablish(int screenId, int estabIndex) { _screen->setIconPalette(); _screen->forceFadeIn(); - _fonts._charSet._lo = 1; - _fonts._charSet._hi = 10; - _fonts._charFor._lo = 29; - _fonts._charFor._hi = 32; + if (getGameID() == GType_MartianMemorandum) { + _fonts._charSet._lo = 1; + _fonts._charSet._hi = 10; + _fonts._charFor._lo = 0xF7; + _fonts._charFor._hi = 0xFF; + + _screen->_maxChars = 50; + _screen->_printOrg = _screen->_printStart = Common::Point(24, 18); + } else { + _fonts._charSet._lo = 1; + _fonts._charSet._hi = 10; + _fonts._charFor._lo = 29; + _fonts._charFor._hi = 32; + + _screen->_maxChars = 37; + _screen->_printOrg = _screen->_printStart = Common::Point(48, 35); + } - _screen->_maxChars = 37; - _screen->_printOrg = _screen->_printStart = Common::Point(48, 35); loadEstablish(estabIndex); uint16 msgOffset; if (!isCD()) diff --git a/engines/access/amazon/amazon_logic.cpp b/engines/access/amazon/amazon_logic.cpp index ce2c96b7a2..de53da51cd 100644 --- a/engines/access/amazon/amazon_logic.cpp +++ b/engines/access/amazon/amazon_logic.cpp @@ -1596,7 +1596,7 @@ void River::moveCanoe() { moveCanoe2(); } else { if (events._leftButton && pt.y >= 140) { - if (pt.x < RMOUSE[8][0]) { + if (pt.x < _vm->_room->_rMouse[8][0]) { // Disk icon wasn't clicked _vm->_scripts->printString(BAR_MESSAGE); } else { diff --git a/engines/access/amazon/amazon_player.cpp b/engines/access/amazon/amazon_player.cpp index b1ed501fce..903da6c532 100644 --- a/engines/access/amazon/amazon_player.cpp +++ b/engines/access/amazon/amazon_player.cpp @@ -48,7 +48,7 @@ void AmazonPlayer::load() { _downDelta = -2; _scrollConst = 2; - for (int i = 0; i < PLAYER_DATA_COUNT; ++i) { + for (int i = 0; i < _vm->_playerDataCount; ++i) { _walkOffRight[i] = OVEROFFR[i]; _walkOffLeft[i] = OVEROFFL[i]; _walkOffUp[i] = OVEROFFU[i]; @@ -78,6 +78,22 @@ void AmazonPlayer::load() { _diagDownWalkMin = 0; _diagDownWalkMax = 5; _game->_guard->setPosition(Common::Point(56, 190)); + } else { + for (int i = 0; i < _vm->_playerDataCount; ++i) { + _walkOffRight[i] = SIDEOFFR[i]; + _walkOffLeft[i] = SIDEOFFL[i]; + _walkOffUp[i] = SIDEOFFU[i]; + _walkOffDown[i] = SIDEOFFD[i]; + + _walkOffUR[i].x = DIAGOFFURX[i]; + _walkOffUR[i].y = DIAGOFFURY[i]; + _walkOffDR[i].x = DIAGOFFDRX[i]; + _walkOffDR[i].y = DIAGOFFDRY[i]; + _walkOffUL[i].x = DIAGOFFULX[i]; + _walkOffUL[i].y = DIAGOFFULY[i]; + _walkOffDL[i].x = DIAGOFFDLX[i]; + _walkOffDL[i].y = DIAGOFFDLY[i]; + } } } diff --git a/engines/access/amazon/amazon_resources.cpp b/engines/access/amazon/amazon_resources.cpp index 2010c7d842..5ffb91d9fd 100644 --- a/engines/access/amazon/amazon_resources.cpp +++ b/engines/access/amazon/amazon_resources.cpp @@ -72,6 +72,19 @@ const char *const FILENAMES_DEMO[] = { "CHAPTER.AP", "MUSIC.AP", "SOUND.AP", "INV.AP" }; +const int SIDEOFFR[] = { 5, 5, 5, 5, 5, 5, 5, 5, 0 }; +const int SIDEOFFL[] = { 5, 5, 5, 5, 5, 5, 5, 5, 0 }; +const int SIDEOFFU[] = { 2, 2, 2, 2, 2, 2, 2, 2, 0 }; +const int SIDEOFFD[] = { 2, 2, 2, 2, 2, 2, 2, 2, 0 }; +const int DIAGOFFURX[] = { 4, 5, 2, 2, 3, 4, 2, 2, 0 }; +const int DIAGOFFURY[] = { 2, 3, 2, 2, 2, 3, 1, 1, 0 }; +const int DIAGOFFDRX[] = { 4, 5, 4, 3, 5, 4, 5, 1, 0 }; +const int DIAGOFFDRY[] = { 3, 2, 1, 2, 2, 1, 2, 1, 0 }; +const int DIAGOFFULX[] = { 4, 5, 4, 3, 3, 2, 2, 2, 0 }; +const int DIAGOFFULY[] = { 3, 3, 1, 2, 2, 1, 1, 1, 0 }; +const int DIAGOFFDLX[] = { 4, 5, 3, 3, 5, 4, 6, 1, 0 }; +const int DIAGOFFDLY[] = { 2, 2, 1, 2, 3, 1, 2, 1, 0 }; + const byte MOUSE0[] = { // hotspot x and y, uint16 LE 0, 0, 0, 0, @@ -2406,6 +2419,11 @@ const int CAST_END_OBJ1[4][4] = { { 3, 103, 1300, 10 } }; -} // End of namespace Amazon +const int RMOUSE[10][2] = { + { 0, 35 }, { 0, 0 }, { 36, 70 }, { 71, 106 }, { 107, 141 }, + { 142, 177 }, { 178, 212 }, { 213, 248 }, { 249, 283 }, { 284, 318 } +}; + +} // End of namespace Amazon } // End of namespace Access diff --git a/engines/access/amazon/amazon_resources.h b/engines/access/amazon/amazon_resources.h index a952860bc2..9801fd9dee 100644 --- a/engines/access/amazon/amazon_resources.h +++ b/engines/access/amazon/amazon_resources.h @@ -45,6 +45,19 @@ struct RiverStruct { extern const char *const FILENAMES[]; extern const char *const FILENAMES_DEMO[]; +extern const int SIDEOFFR[]; +extern const int SIDEOFFL[]; +extern const int SIDEOFFU[]; +extern const int SIDEOFFD[]; +extern const int DIAGOFFURX[]; +extern const int DIAGOFFURY[]; +extern const int DIAGOFFDRX[]; +extern const int DIAGOFFDRY[]; +extern const int DIAGOFFULX[]; +extern const int DIAGOFFULY[]; +extern const int DIAGOFFDLX[]; +extern const int DIAGOFFDLY[]; + extern const byte *const CURSORS[10]; extern const int TRAVEL_POS[][2]; @@ -138,11 +151,11 @@ extern const int HELP1COORDS[2][4]; extern const int RIVER1OBJ[23][4]; extern const int CAST_END_OBJ[26][4]; - extern const int CAST_END_OBJ1[4][4]; -} // End of namespace Amazon +extern const int RMOUSE[10][2]; +} // End of namespace Amazon } // End of namespace Access #endif /* ACCESS_AMAZON_RESOURCES_H */ diff --git a/engines/access/amazon/amazon_scripts.cpp b/engines/access/amazon/amazon_scripts.cpp index 92acb3686d..8c49424bc5 100644 --- a/engines/access/amazon/amazon_scripts.cpp +++ b/engines/access/amazon/amazon_scripts.cpp @@ -33,6 +33,8 @@ namespace Amazon { AmazonScripts::AmazonScripts(AccessEngine *vm) : Scripts(vm) { _game = (AmazonEngine *)_vm; + + setOpcodes_v2(); } void AmazonScripts::cLoop() { @@ -379,7 +381,7 @@ typedef void(AmazonScripts::*AmazonScriptMethodPtr)(); void AmazonScripts::executeCommand(int commandIndex) { static const AmazonScriptMethodPtr COMMAND_LIST[] = { - &AmazonScripts::cmdHelp, &AmazonScripts::cmdCycleBack, + &AmazonScripts::cmdHelp_v2, &AmazonScripts::cmdCycleBack, &AmazonScripts::cmdChapter, &AmazonScripts::cmdSetHelp, &AmazonScripts::cmdCenterPanel, &AmazonScripts::cmdMainPanel, &AmazonScripts::CMDRETFLASH @@ -391,7 +393,7 @@ void AmazonScripts::executeCommand(int commandIndex) { Scripts::executeCommand(commandIndex); } -void AmazonScripts::cmdHelp() { +void AmazonScripts::cmdHelp_v2() { Common::String helpMessage = readString(); if (_game->_helpLevel == 0) { diff --git a/engines/access/amazon/amazon_scripts.h b/engines/access/amazon/amazon_scripts.h index e10eefb4f5..6d992667f5 100644 --- a/engines/access/amazon/amazon_scripts.h +++ b/engines/access/amazon/amazon_scripts.h @@ -49,7 +49,7 @@ protected: void setInactive(); void boatWalls(int param1, int param2); - void cmdHelp(); + void cmdHelp_v2(); void cmdCycleBack(); void cmdChapter(); void cmdSetHelp(); diff --git a/engines/access/asurface.cpp b/engines/access/asurface.cpp index 5f4372d5af..526690807a 100644 --- a/engines/access/asurface.cpp +++ b/engines/access/asurface.cpp @@ -54,6 +54,12 @@ SpriteResource::~SpriteResource() { SpriteFrame::SpriteFrame(AccessEngine *vm, Common::SeekableReadStream *stream, int frameSize) { int xSize = stream->readUint16LE(); int ySize = stream->readUint16LE(); + + if (vm->getGameID() == GType_MartianMemorandum) { + int size = stream->readUint16LE(); + if (size != frameSize) + warning("Unexpected file difference: framesize %d - size %d %d - unknown %d", frameSize, xSize, ySize, size); + } create(xSize, ySize); // Empty surface @@ -312,6 +318,21 @@ void ASurface::drawRect() { Graphics::Surface::fillRect(Common::Rect(_orgX1, _orgY1, _orgX2, _orgY2), _lColor); } +void ASurface::drawLine(int x1, int y1, int x2, int y2, int col) { + Graphics::Surface::drawLine(x1, y1, x2, y2, col); +} + +void ASurface::drawLine() { + Graphics::Surface::drawLine(_orgX1, _orgY1, _orgX2, _orgY1, _lColor); +} + +void ASurface::drawBox() { + Graphics::Surface::drawLine(_orgX1, _orgY1, _orgX2, _orgY1, _lColor); + Graphics::Surface::drawLine(_orgX1, _orgY2, _orgX2, _orgY2, _lColor); + Graphics::Surface::drawLine(_orgX2, _orgY1, _orgX2, _orgY1, _lColor); + Graphics::Surface::drawLine(_orgX2, _orgY2, _orgX2, _orgY2, _lColor); +} + void ASurface::flipHorizontal(ASurface &dest) { dest.create(this->w, this->h); for (int y = 0; y < h; ++y) { diff --git a/engines/access/asurface.h b/engines/access/asurface.h index 4fb47b9c09..022e2534c1 100644 --- a/engines/access/asurface.h +++ b/engines/access/asurface.h @@ -95,6 +95,12 @@ public: virtual void drawRect(); + virtual void drawLine(int x1, int y1, int x2, int y2, int col); + + virtual void drawLine(); + + virtual void drawBox(); + virtual void transBlitFrom(ASurface *src, const Common::Point &destPos); virtual void transBlitFrom(ASurface *src, const Common::Rect &bounds); diff --git a/engines/access/bubble_box.cpp b/engines/access/bubble_box.cpp index 28c211991c..c9097bb33c 100644 --- a/engines/access/bubble_box.cpp +++ b/engines/access/bubble_box.cpp @@ -26,13 +26,26 @@ namespace Access { -BubbleBox::BubbleBox(AccessEngine *vm) : Manager(vm) { - _startItem = 0; - _startBox = 0; - _charCol = _rowOff = 0; - _type = TYPE_2; - _bounds = Common::Rect(64, 32, 64 + 130, 32 + 122); - _bubbleDisplStr = ""; +BubbleBox::BubbleBox(AccessEngine *vm, Access::BoxType type, int x, int y, int w, int h, int val1, int val2, int val3, int val4, Common::String title) : Manager(vm) { + _type = type; + _bounds = Common::Rect(x, y, x + w, y + h); + _bubbleDisplStr = title; + _btnId1 = val1; + _btnX1 = val2; + _btnId2 = val3; + _btnX2 = val4; + _btnId3 = _btnX3 = 0; // Unused in MM and Amazon? + BOXSTARTX = BOXSTARTY = 0; + BICONSTARTX = BICONSTARTY = 0; + BOXENDX = BOXENDY = 0; + BOXPSTARTX = BOXPSTARTY = 0; + // Unused in AGoE + for (int i = 0; i < 60; i++) { + _tempList[i] = ""; + _tempListIdx[i] = 0; + } + _btnUpPos = Common::Rect(0, 0, 0, 0); + _btnDownPos = Common::Rect(0, 0, 0, 0); } void BubbleBox::load(Common::SeekableReadStream *stream) { @@ -61,7 +74,7 @@ void BubbleBox::clearBubbles() { } void BubbleBox::placeBubble(const Common::String &msg) { - _vm->_screen->_maxChars = 27; + _vm->_screen->_maxChars = (_vm->getGameID() == GType_MartianMemorandum) ? 30 : 27; placeBubble1(msg); } @@ -69,8 +82,8 @@ void BubbleBox::placeBubble1(const Common::String &msg) { _bubbles.clear(); _vm->_fonts._charSet._lo = 1; _vm->_fonts._charSet._hi = 8; - _vm->_fonts._charFor._lo = 29; - _vm->_fonts._charFor._hi = 32; + _vm->_fonts._charFor._lo = (_vm->getGameID() == GType_MartianMemorandum) ? 247 : 29; + _vm->_fonts._charFor._hi = (_vm->getGameID() == GType_MartianMemorandum) ? 255 : 32; calcBubble(msg); @@ -137,6 +150,35 @@ void BubbleBox::calcBubble(const Common::String &msg) { } void BubbleBox::printBubble(const Common::String &msg) { + if (_vm->getGameID() == GType_MartianMemorandum) + printBubble_v1(msg); + else + printBubble_v2(msg); +} + +void BubbleBox::printBubble_v1(const Common::String &msg) { + drawBubble(_bubbles.size() - 1); + + // Loop through drawing the lines + Common::String s = msg; + Common::String line; + int width = 0; + bool lastLine; + do { + // Get next line + Font &font2 = _vm->_fonts._font2; + lastLine = font2.getLine(s, _vm->_screen->_maxChars * 6, line, width); + // Draw the text + PRINTSTR(line); + + // Move print position + _vm->_screen->_printOrg.y += 6; + _vm->_screen->_printOrg.x = _vm->_screen->_printStart.x; + } while (!lastLine); + +} + +void BubbleBox::printBubble_v2(const Common::String &msg) { drawBubble(_bubbles.size() - 1); // Loop through drawing the lines @@ -170,7 +212,11 @@ void BubbleBox::printBubble(const Common::String &msg) { void BubbleBox::drawBubble(int index) { _bounds = _bubbles[index]; - doBox(0, 0); + if (_vm->getGameID() == GType_MartianMemorandum) { + int btnSelected = 0; + doBox_v1(0, 0, btnSelected); + } else + doBox(0, 0); } void BubbleBox::doBox(int item, int box) { @@ -278,4 +324,440 @@ void BubbleBox::doBox(int item, int box) { delete icons; } +void BubbleBox::SETCURSORPOS(int posX, int posY) { + _vm->_screen->_printStart = _vm->_screen->_printOrg = Common::Point((posX << 3) + _rowOff, posY << 3); + warning("Missing call to SETCURSOR"); +} + +void BubbleBox::PRINTSTR(Common::String msg) { + warning("TODO: Proper implementation of PRINTSTR"); + _vm->_fonts._font1.drawString(_vm->_screen, msg, _vm->_screen->_printOrg); +} + +void BubbleBox::displayBoxData() { + _vm->BOXDATAEND = false; + _rowOff = 2; + _vm->_fonts._charFor._lo = 0xF7; + _vm->_fonts._charFor._hi = 0xFF; + + if (_tempList[0].size() == 0) + return; + + int idx = 0; + if ((_type == TYPE_1) || (_type == TYPE_3)) { + _vm->BCNT = 0; + + if (_tempList[idx].size() == 0) { + _vm->BOXDATAEND = true; + return; + } + + _vm->_events->hideCursor(); + + _vm->_screen->_orgX1 = BOXSTARTX; + _vm->_screen->_orgX2 = BOXENDX; + _vm->_screen->_orgY1 = BOXSTARTY; + _vm->_screen->_orgY2 = BOXENDY; + _vm->_screen->_lColor = 0xFA; + _vm->_screen->drawRect(); + _vm->_events->showCursor(); + } + + _vm->_events->hideCursor(); + int oldPStartY = BOXPSTARTY; + ++BOXPSTARTY; + + idx += _vm->BOXDATASTART; + + while (true) { + SETCURSORPOS(BOXPSTARTX, BOXPSTARTY); + PRINTSTR(_tempList[idx]); + + ++idx; + ++BOXPSTARTY; + ++_vm->BCNT; + if (_tempList[idx].size() == 0) { + BOXPSTARTY = oldPStartY; + _vm->_events->showCursor(); + _vm->BOXDATAEND = true; + return; + } + + if (_vm->BCNT == _vm->NUMBLINES) { + BOXPSTARTY = oldPStartY; + _vm->_events->showCursor(); + return; + } + } +} + +void BubbleBox::drawSelectBox() { + if (_tempList[0].size() == 0) + return; + + if (((_type != TYPE_1) && (_type != TYPE_3)) || !_vm->BCNT) + return; + + if (_vm->BOXSELECTYOLD != -1) { + _vm->_events->hideCursor(); + _vm->_screen->_lColor = 0xFA; + + int val = _vm->BOXSELECTYOLD + BOXPSTARTY + 1; + _vm->_screen->_orgY1 = (val << 3) + 2; + _vm->_screen->_orgY2 = _vm->_screen->_orgY1 + 7; + _vm->_screen->_orgX1 = BOXSTARTX; + _vm->_screen->_orgX2 = BOXENDX; + _vm->_screen->drawBox(); + _vm->_events->showCursor(); + } + + _vm->_events->hideCursor(); + _vm->BOXSELECTYOLD = _vm->BOXSELECTY; + int val = BOXPSTARTY + _vm->BOXSELECTY + 1; + _vm->_screen->_orgY1 = (val << 3) + 2; + _vm->_screen->_orgY2 = _vm->_screen->_orgY1 + 7; + _vm->_screen->_orgX1 = BOXSTARTX; + _vm->_screen->_orgX2 = BOXENDX; + _vm->_screen->_lColor = 0xFE; + _vm->_screen->drawBox(); + _vm->_events->showCursor(); + + if (_type == TYPE_3) + warning("TODO: List filenames"); +} + +int BubbleBox::doBox_v1(int item, int box, int &btnSelected) { + static const int ICONW[] = { 0, 11, 28, 19, 19, 15 }; + + FontManager &fonts = _vm->_fonts; + int retval_ = -1; + + _startItem = item; + _startBox = box; + + // Save state information + _vm->_screen->saveScreen(); + _vm->_screen->setDisplayScan(); + + fonts._charFor._hi = 0xff; + fonts._charSet._lo = 1; + fonts._charSet._hi = 0; + + _vm->_destIn = _vm->_screen; // TODO: Redundant + + if (_type != TYPE_2) { + Common::Rect r = _bounds; + r.left -= 2; + _vm->_screen->saveBlock(r); + } + + // Set the up boundaries and color to use for the box background + _vm->_screen->_orgX1 = _bounds.left - 2; + _vm->_screen->_orgY1 = _bounds.top; + _vm->_screen->_orgX2 = _bounds.right - 2; + _vm->_screen->_orgY2 = _bounds.bottom; + _vm->_screen->_lColor = 0xFB; + + // Draw a background for the entire area + _vm->_screen->drawRect(); + + // Draw the inner box; + ++_vm->_screen->_orgX1; + ++_vm->_screen->_orgY1; + --_vm->_screen->_orgX2; + --_vm->_screen->_orgY2; + _vm->_screen->_lColor = 0xF9; + + // Draw the inner border + _vm->_screen->drawBox(); + + // Get icons data + Resource *iconData = _vm->_files->loadFile("ICONS.LZ"); + SpriteResource *icons = new SpriteResource(_vm, iconData); + delete iconData; + + // Draw upper border + _vm->BCNT = (_vm->_screen->_orgX2 - _vm->_screen->_orgX1) >> 4; + int oldX = _vm->_screen->_orgX1; + for ( ;_vm->BCNT > 0; --_vm->BCNT) { + _vm->_screen->plotImage(icons, 16, Common::Point(_vm->_screen->_orgX1, _vm->_screen->_orgY1)); + _vm->_screen->_orgX1 += 16; + } + + _vm->_screen->_orgX1 = oldX; + int oldY = _vm->_screen->_orgY2; + _vm->_screen->_orgY2 = _vm->_screen->_orgY1 + 8; + _vm->_screen->_lColor = 0xF9; + + BOXSTARTY = _vm->_screen->_orgY2 + 1; + _vm->_screen->_orgY2 = oldY; + + int tmpX = 0; + int tmpY = 0; + if (_type != TYPE_2) { + oldY = _vm->_screen->_orgY1; + --_vm->_screen->_orgY2; + _vm->_screen->_orgY1 = _vm->_screen->_orgY2 - 8; + if (_type == TYPE_3) + _vm->_screen->_orgY1 -= 8; + _vm->_screen->drawRect(); + tmpX = BICONSTARTX = _vm->_screen->_orgX1; + + BOXSTARTX = tmpX + 1; + tmpY = BOXENDY = _vm->_screen->_orgY1; + + if (_type == TYPE_3) + BICONSTARTY = tmpY + 9; + else + BICONSTARTY = tmpY + 1; + + if (_type == TYPE_3) { + _fileStart = Common::Point((tmpX + 2) >> 3, (tmpY + 2) >> 3); + int rowOff = tmpY - (_fileStart.y << 3) + 1; + if (rowOff == 8) { + rowOff = 0; + ++_fileStart.y; + } + _fileOff.y = _rowOff = rowOff; + SETCURSORPOS(_fileStart.x, _fileStart.y); + _vm->_fonts._charFor._lo = 0xF7; + _vm->_fonts._charFor._hi = 0; + PRINTSTR("FILE: "); + _vm->_fonts._charFor._hi = 0xFF; + } + _vm->_screen->_orgY1 = oldY; + } + + if ((_type != TYPE_0) && (_type != TYPE_2)) { + _vm->_screen->_orgY1 += 8; + if (_type == TYPE_3) + _vm->_screen->_orgY2 -= 8; + + _vm->_screen->_orgY2 -= 8; + _btnUpPos.right = _btnDownPos.right = _vm->_screen->_orgX2; + _btnUpPos.left = _btnDownPos.left = _vm->_screen->_orgX1 = _vm->_screen->_orgX2 - 8; + BOXENDX = _vm->_screen->_orgX1 - 1; + _vm->_screen->drawBox(); + + _vm->_screen->_orgY1 += 6; + _vm->_screen->_orgY2 -= 6; + _vm->_screen->drawBox(); + + _btnUpPos.bottom = _vm->_screen->_orgY1 + 1; + _btnUpPos.top = _btnUpPos.bottom - 5; + _btnDownPos.top = _vm->_screen->_orgY2 + 1; + _btnDownPos.bottom = _btnDownPos.top + 6; + + _vm->_screen->_orgX1 += 4; + _vm->_screen->_orgX2 = _vm->_screen->_orgX1; + _vm->_screen->_orgY1 -= 4; + _vm->_screen->_orgY2 += 2; + _vm->_screen->drawLine(); + + ++_vm->_screen->_orgY1; + --_vm->_screen->_orgX1; + ++_vm->_screen->_orgX2; + _vm->_screen->drawLine(); + + ++_vm->_screen->_orgY1; + --_vm->_screen->_orgX1; + ++_vm->_screen->_orgX2; + _vm->_screen->drawLine(); + + _vm->_screen->_orgY1 = _vm->_screen->_orgY2; + _vm->_screen->drawLine(); + + ++_vm->_screen->_orgX1; + --_vm->_screen->_orgX2; + ++_vm->_screen->_orgY1; + _vm->_screen->drawLine(); + + ++_vm->_screen->_orgX1; + --_vm->_screen->_orgX2; + ++_vm->_screen->_orgY1; + _vm->_screen->drawLine(); + } + + int len = _bubbleDisplStr.size(); + int newX = _bounds.top >> 3; + newX = (len - newX) / 2; + + BOXPSTARTX = _bounds.left >> 3; + newX += BOXPSTARTX; + + int newY = _bounds.top >> 3; + int bp = _bounds.top - (newY << 3) + 1; + if (bp == 8) { + ++newY; + bp = 0; + } + + _rowOff = bp; + retval_ = BOXPSTARTY = newY; + + SETCURSORPOS(newX, newY); + + _vm->_fonts._charFor._lo = 0xFF; + _vm->_fonts._font1.drawString(_vm->_screen, _bubbleDisplStr, _vm->_screen->_printOrg); + + if (_type == TYPE_2) { + _vm->_events->showCursor(); + warning("TODO: pop values"); + _vm->_screen->restoreScreen(); + return retval_; + } + + _vm->_destIn = _vm->_screen; + + // Draw buttons + int ICON1T = 0; + int ICON1X = 0; + int ICON1Y = 0; + int ICON2T = 0; + int ICON2X = 0; + int ICON3T = 0; + int ICON3X = 0; + if (_btnId1) { + ICON1T = _btnId1; + ICON1X = BICONSTARTX + _btnX1; + ICON1Y = BICONSTARTY; + _vm->_screen->plotImage(icons, ICON1T + 10, Common::Point(ICON1X, ICON1Y)); + + if (_btnId2) { + ICON2T = _btnId2; + ICON2X = BICONSTARTX + _btnX2; + _vm->_screen->plotImage(icons, ICON2T + 10, Common::Point(ICON2X, BICONSTARTY)); + + if (_btnId3) { + ICON3T = _btnId3; + ICON3X = BICONSTARTX + _btnX3; + _vm->_screen->plotImage(icons, ICON3T + 10, Common::Point(ICON3X, BICONSTARTY)); + } + } + } + + _vm->_screen->restoreScreen(); + _vm->BOXDATASTART = _startItem; + _vm->BOXSELECTYOLD = -1; + _vm->BOXSELECTY = _startBox; + + _vm->NUMBLINES = (_bounds.bottom >> 3) - 2; + if (_type == TYPE_3) + --_vm->NUMBLINES; + + _vm->_events->showCursor(); + displayBoxData(); + drawSelectBox(); + + while (!_vm->shouldQuit()) { + _vm->_events->pollEvents(); + if (!_vm->_events->_leftButton) + continue; + + if (((_type == TYPE_1) || (_type != TYPE_3)) && (_vm->_timers[2]._flag == 0)) { + ++_vm->_timers[2]._flag; + if (_btnUpPos.contains(_vm->_events->_mousePos)) { + if (_vm->BCNT) { + if (_vm->BOXSELECTY != 0) { + --_vm->BOXSELECTY; + drawSelectBox(); + } else if (_vm->BOXDATASTART != 0) { + --_vm->BOXDATASTART; + displayBoxData(); + drawSelectBox(); + } + } + continue; + } else if (_btnDownPos.contains(_vm->_events->_mousePos)) { + if (_vm->BCNT) { + if (_vm->BCNT == _vm->NUMBLINES) { + if (_vm->BCNT != _vm->BOXSELECTY + 1) { + ++_vm->BOXSELECTY; + drawSelectBox(); + } else if (!_vm->BOXDATAEND) { + ++_vm->BOXDATASTART; + displayBoxData(); + drawSelectBox(); + } + } else if (_vm->BCNT != _vm->BOXSELECTY + 1) { + ++_vm->BOXSELECTY; + drawSelectBox(); + } + } + continue; + } + } + + if ((_vm->_events->_mousePos.x >= BOXSTARTX) && (_vm->_events->_mousePos.x <= BOXENDX) + && (_vm->_events->_mousePos.y >= BOXSTARTY) && (_vm->_events->_mousePos.y <= BOXENDY)) { + int val = (_vm->_events->_mousePos.x >> 3) - BOXPSTARTY; + if (val > _vm->BCNT) + continue; + --val; + if (_type == TYPE_3) + _vm->_boxSelect = val; + else { + btnSelected = 1; + if (_vm->BOXSELECTY == val) + break; + _vm->BOXSELECTY = val; + _vm->_events->debounceLeft(); + drawSelectBox(); + continue; + } + } + + if ((_vm->_events->_mousePos.y >= ICON1Y) && (_vm->_events->_mousePos.y <= ICON1Y + 8) + && (_vm->_events->_mousePos.x >= ICON1X)) { + btnSelected = 1; + if (_vm->_events->_mousePos.x < ICON1X + ICONW[ICON1T]) + break; + + if ((_vm->_events->_mousePos.x >= ICON2X) && (_vm->_events->_mousePos.x < ICON2X + ICONW[ICON2T])) { + btnSelected = 2; + break; + } + + if ((_vm->_events->_mousePos.x >= ICON3X) && (_vm->_events->_mousePos.x < ICON3X + ICONW[ICON3T])) { + btnSelected = 3; + break; + } + + if (_type != TYPE_3) + continue; + + if ((_vm->_events->_mousePos.x < tmpX) || (_vm->_events->_mousePos.x > tmpX + 144)) + continue; + + if ((_vm->_events->_mousePos.y < tmpY) || (_vm->_events->_mousePos.y > tmpY + 8)) + continue; + + warning("TODO: sub175B5 - List of files"); + } + } + + _vm->_events->hideCursor(); + _vm->_screen->restoreBlock(); + _vm->_events->showCursor(); + _vm->_events->debounceLeft(); + if (_vm->BCNT == 0) + retval_ = -1; + else + retval_ = _vm->BOXDATASTART + _vm->BOXSELECTY; + return retval_; +} + +void BubbleBox::getList(const char *const data[], int *flags) { + int srcIdx = 0; + int destIdx = 0; + while (data[srcIdx]) { + if (flags[srcIdx]) { + _tempList[destIdx] = Common::String(data[srcIdx]); + _tempListIdx[destIdx] = srcIdx; + ++destIdx; + } + srcIdx++; + } + _tempList[destIdx] = ""; +} } // End of namespace Access diff --git a/engines/access/bubble_box.h b/engines/access/bubble_box.h index 0b3f139520..6bf752d1a3 100644 --- a/engines/access/bubble_box.h +++ b/engines/access/bubble_box.h @@ -36,23 +36,46 @@ namespace Access { class AccessEngine; -enum BoxType { TYPE_2 = 2, TYPE_4 = 4 }; +enum BoxType { TYPE_0 = 0, TYPE_1 = 1, TYPE_2 = 2, TYPE_3 = 3, TYPE_4 = 4 }; class BubbleBox : public Manager { private: int _startItem, _startBox; int _charCol, _rowOff; Common::Point _fileStart; + Common::Point _fileOff; + int BOXSTARTX, BOXSTARTY; + int BOXENDX, BOXENDY; + int BICONSTARTX, BICONSTARTY; + int BOXPSTARTX, BOXPSTARTY; + + void displayBoxData(); + void drawSelectBox(); + /** + * Prints a text bubble and it's contents + */ + void printBubble_v1(const Common::String &msg); + void printBubble_v2(const Common::String &msg); + public: BoxType _type; Common::Rect _bounds; Common::StringArray _nameIndex; Common::String _bubbleTitle; Common::String _bubbleDisplStr; - + Common::String _tempList[60]; + int _tempListIdx[60]; + int _btnId1; + int _btnX1; + int _btnId2; + int _btnX2; + int _btnId3; + int _btnX3; + Common::Rect _btnUpPos; + Common::Rect _btnDownPos; Common::Array<Common::Rect> _bubbles; public: - BubbleBox(AccessEngine *vm); + BubbleBox(AccessEngine *vm, Access::BoxType type, int x, int y, int w, int h, int val1, int val2, int val3, int val4, Common::String title); void load(Common::SeekableReadStream *stream); @@ -78,6 +101,11 @@ public: void drawBubble(int index); void doBox(int item, int box); + + int doBox_v1(int item, int box, int &btnSelected); + void getList(const char *const data[], int *flags); + void SETCURSORPOS(int posX, int posY); + void PRINTSTR(Common::String msg); }; } // End of namespace Access diff --git a/engines/access/char.cpp b/engines/access/char.cpp index b359bcf13a..aca7262952 100644 --- a/engines/access/char.cpp +++ b/engines/access/char.cpp @@ -27,15 +27,25 @@ namespace Access { -CharEntry::CharEntry(const byte *data) { +CharEntry::CharEntry(const byte *data, AccessEngine *vm) { Common::MemoryReadStream s(data, 999); _charFlag = s.readByte(); - _estabIndex = s.readSint16LE(); - _screenFile.load(s); + if (vm->getGameID() == GType_MartianMemorandum) { + _screenFile.load(s); + _estabIndex = s.readSint16LE(); + } else { + _estabIndex = s.readSint16LE(); + _screenFile.load(s); + } + _paletteFile.load(s); _startColor = s.readUint16LE(); - _numColors = s.readUint16LE(); + if (vm->getGameID() == GType_MartianMemorandum) { + int lastColor = s.readUint16LE(); + _numColors = lastColor - _startColor; + } else + _numColors = s.readUint16LE(); // Load cells for (byte cell = s.readByte(); cell != 0xff; cell = s.readByte()) { @@ -73,12 +83,18 @@ CharManager::CharManager(AccessEngine *vm) : Manager(vm) { // Setup character list if (_vm->isDemo()) { for (int i = 0; i < 27; ++i) - _charTable.push_back(CharEntry(Amazon::CHARTBL_DEMO[i])); + _charTable.push_back(CharEntry(Amazon::CHARTBL_DEMO[i], vm)); } else { for (int i = 0; i < 37; ++i) - _charTable.push_back(CharEntry(Amazon::CHARTBL[i])); + _charTable.push_back(CharEntry(Amazon::CHARTBL[i], vm)); } break; + + case GType_MartianMemorandum: + for (int i = 0; i < 27; ++i) + _charTable.push_back(CharEntry(Martian::CHARTBL_MM[i], vm)); + break; + default: error("Unknown game"); } @@ -152,8 +168,14 @@ void CharManager::charMenu() { screen.saveScreen(); screen.setDisplayScan(); - screen.plotImage(spr, 17, Common::Point(0, 176)); - screen.plotImage(spr, 18, Common::Point(155, 176)); + if (_vm->getGameID() == GType_MartianMemorandum) { + screen.plotImage(spr, 17, Common::Point(0, 184)); + screen.plotImage(spr, 18, Common::Point(193, 184)); + } else if (_vm->getGameID() == GType_Amazon) { + screen.plotImage(spr, 17, Common::Point(0, 176)); + screen.plotImage(spr, 18, Common::Point(155, 176)); + } else + error("Game not supported"); screen.restoreScreen(); delete spr; diff --git a/engines/access/char.h b/engines/access/char.h index 6fb4934978..f2828e9779 100644 --- a/engines/access/char.h +++ b/engines/access/char.h @@ -41,7 +41,7 @@ public: FileIdent _scriptFile; Common::Array<ExtraCell> _extraCells; public: - CharEntry(const byte *data); + CharEntry(const byte *data, AccessEngine *vm); CharEntry(); }; diff --git a/engines/access/detection_tables.h b/engines/access/detection_tables.h index 88a64470c5..124f5fcf0d 100644 --- a/engines/access/detection_tables.h +++ b/engines/access/detection_tables.h @@ -75,7 +75,22 @@ static const AccessGameDescription gameDescriptions[] = { { "martian", nullptr, - AD_ENTRY1s("r00.ap", "af98db5ee7f9ef86c6b1f43187a3691b", 31), + AD_ENTRY1s("r01.ap", "c081daca9b0cfd710157cf946e343df6", 39352), + Common::EN_ANY, + Common::kPlatformDOS, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + GType_MartianMemorandum, + 0 + }, + + { + // Martian Memorandum + { + "martian", + "Demo", + AD_ENTRY1s("r01.rm", "c2facf9c43047211289044ee39a2322a", 2313), Common::EN_ANY, Common::kPlatformDOS, ADGF_NO_FLAGS, diff --git a/engines/access/inventory.cpp b/engines/access/inventory.cpp index df499ba705..d14f116376 100644 --- a/engines/access/inventory.cpp +++ b/engines/access/inventory.cpp @@ -31,10 +31,17 @@ namespace Access { void InventoryEntry::load(const Common::String &name, const int *data) { _value = ITEM_NOT_FOUND; _name = name; - _otherItem1 = *data++; - _newItem1 = *data++; - _otherItem2 = *data++; - _newItem2 = *data; + if (data) { + _otherItem1 = *data++; + _newItem1 = *data++; + _otherItem2 = *data++; + _newItem2 = *data; + } else { + _otherItem1 = -1; + _newItem1 = -1; + _otherItem2 = -1; + _newItem2 = -1; + } } int InventoryEntry::checkItem(int itemId) { @@ -67,20 +74,20 @@ InventoryManager::InventoryManager(AccessEngine *vm) : Manager(vm) { names = Amazon::INVENTORY_NAMES; combineP = &Amazon::COMBO_TABLE[0][0]; _inv.resize(85); + for (uint i = 0; i < _inv.size(); ++i, combineP += 4) + _inv[i].load(names[i], combineP); break; case GType_MartianMemorandum: names = Martian::INVENTORY_NAMES; - combineP = &Martian::COMBO_TABLE[0][0]; - _inv.resize(54); + combineP = nullptr; + _inv.resize(55); + for (uint i = 0; i < _inv.size(); ++i) + _inv[i].load(names[i], nullptr); break; default: error("Unknown game"); } - for (uint i = 0; i < _inv.size(); ++i, combineP += 4) { - _inv[i].load(names[i], combineP); - } - for (uint i = 0; i < 26; ++i) { const int *r = INVCOORDS[i]; _invCoords.push_back(Common::Rect(r[0], r[2], r[1], r[3])); @@ -209,6 +216,31 @@ int InventoryManager::newDisplayInv() { return result; } +int InventoryManager::displayInv() { + int *inv = (int *) malloc (Martian::INVENTORY_SIZE * sizeof(int)); + + for (int i = 0; i < Martian::INVENTORY_SIZE; i++) + inv[i] = _inv[i]._value; + _vm->_events->forceSetCursor(CURSOR_CROSSHAIRS); + _vm->_invBox->getList(Martian::INVENTORY_NAMES, inv); + + int btnSelected = 0; + int boxX = _vm->_invBox->doBox_v1(_startInvItem, _startInvBox, btnSelected); + _startInvItem = _vm->BOXDATASTART; + _startInvBox= _vm->BOXSELECTY; + + if (boxX == -1) + btnSelected = 2; + + if (btnSelected != 2) + _vm->_useItem = _vm->_invBox->_tempListIdx[boxX]; + else + _vm->_useItem = -1; + + free(inv); + return 0; +} + void InventoryManager::savedFields() { Screen &screen = *_vm->_screen; Room &room = *_vm->_room; diff --git a/engines/access/inventory.h b/engines/access/inventory.h index 6a9390eda9..1d88bf4555 100644 --- a/engines/access/inventory.h +++ b/engines/access/inventory.h @@ -128,6 +128,7 @@ public: void refreshInventory(); int newDisplayInv(); + int displayInv(); /** * Synchronize savegame data diff --git a/engines/access/martian/martian_game.cpp b/engines/access/martian/martian_game.cpp index 4e4a5135a6..69ca4d3a5a 100644 --- a/engines/access/martian/martian_game.cpp +++ b/engines/access/martian/martian_game.cpp @@ -35,108 +35,256 @@ MartianEngine::MartianEngine(OSystem *syst, const AccessGameDescription *gameDes } MartianEngine::~MartianEngine() { + _introObjects = _spec7Objects = nullptr; } -void MartianEngine::playGame() { - // Do introduction - doIntroduction(); - if (shouldQuit()) - return; +void MartianEngine::initObjects() { + _room = new MartianRoom(this); + _scripts = new MartianScripts(this); +} - // Setup the game - setupGame(); +void MartianEngine::configSelect() { + // No implementation required in MM +} - _screen->clearScreen(); - _screen->setPanel(0); - _screen->forceFadeOut(); +void MartianEngine::initVariables() { + warning("TODO: initVariables"); + + // Set player room and position + _player->_roomNumber = 7; + + _inventory->_startInvItem = 0; + _inventory->_startInvBox = 0; + Common::fill(&_objectsTable[0], &_objectsTable[100], (SpriteResource *)nullptr); + _player->_playerOff = false; + + // Setup timers + const int TIMER_DEFAULTS[] = { 4, 10, 8, 1, 1, 1, 1, 2 }; + for (int i = 0; i < 32; ++i) { + TimerEntry te; + te._initTm = te._timer = (i < 8) ? TIMER_DEFAULTS[i] : 1; + te._flag = 1; + + _timers.push_back(te); + } + + _player->_playerX = _player->_rawPlayer.x = TRAVEL_POS[_player->_roomNumber][0]; + _player->_playerY = _player->_rawPlayer.y = TRAVEL_POS[_player->_roomNumber][1]; + _room->_selectCommand = -1; + _events->setNormalCursor(CURSOR_CROSSHAIRS); + _mouseMode = 0; + _numAnimTimers = 0; + + for (int i = 0; i < 60; i++) + TRAVEL[i] = 0; + TRAVEL[7] = 1; + + for (int i = 0; i < 40; i++) + ASK[i] = 0; + ASK[33] = 1; +} + +void MartianEngine::setNoteParams() { + _events->hideCursor(); + + _screen->_orgX1 = 58; + _screen->_orgY1 = 124; + _screen->_orgX2 = 297; + _screen->_orgY2 = 199; + _screen->_lColor = 51; + _screen->drawRect(); _events->showCursor(); +} - // Setup and execute the room - _room = new MartianRoom(this); - _scripts = new MartianScripts(this); - _room->doRoom(); +void MartianEngine::displayNote(const Common::String &msg) { + _fonts._charSet._lo = 1; + _fonts._charSet._hi = 8; + _fonts._charFor._lo = 0; + _fonts._charFor._hi = 255; + + _screen->_maxChars = 40; + _screen->_printOrg = _screen->_printStart = Common::Point(59, 124); + + setNoteParams(); + + Common::String lines = msg; + Common::String line; + int width = 0; + bool lastLine = false; + do { + lastLine = _fonts._font1.getLine(lines, _screen->_maxChars * 6, line, width); + _bubbleBox->PRINTSTR(line); + _screen->_printOrg = Common::Point(_screen->_printStart.x, _screen->_printOrg.y + 6); + + if (_screen->_printOrg.y == 196) { + _events->waitKeyMouse(); + setNoteParams(); + _screen->_printOrg = _screen->_printStart; + } + } while (!lastLine); + _events->waitKeyMouse(); } -void MartianEngine::doIntroduction() { - _screen->setInitialPalettte(); - _events->setCursor(CURSOR_ARROW); +void MartianEngine::doSpecial5(int param1) { + warning("TODO: Push midi song"); + _midi->stopSong(); + _midi->_byte1F781 = false; + _midi->loadMusic(47, 4); + _midi->midiPlay(); + _screen->setDisplayScan(); + _events->clearEvents(); + _screen->forceFadeOut(); + _events->hideCursor(); + _files->loadScreen("DATA.SC"); _events->showCursor(); - _screen->setPanel(0); + _screen->setIconPalette(); + _screen->forceFadeIn(); + + Resource *cellsRes = _files->loadFile("CELLS00.LZ"); + _objectsTable[0] = new SpriteResource(this, cellsRes); + delete cellsRes; + + _timers[20]._timer = _timers[20]._initTm = 30; + Resource *notesRes = _files->loadFile("NOTES.DAT"); + notesRes->_stream->skip(param1 * 2); + int pos = notesRes->_stream->readUint16LE(); + notesRes->_stream->seek(pos); + Common::String msg = ""; + byte c; + while ((c = (char)notesRes->_stream->readByte()) != '\0') + msg += c; + + displayNote(msg); + + _midi->stopSong(); + _midi->freeMusic(); + + warning("TODO: Pop Midi"); + // _midi->_byte1F781 = true; +} + +void MartianEngine::playGame() { + // Initialize Amazon game-specific objects + initObjects(); - // TODO: Worry about implementing full intro sequence later - return; + // Setup the game + setupGame(); + configSelect(); - doTitle(); - if (shouldQuit()) - return; + if (_loadSaveSlot == -1) { + // Do introduction + doCredits(); + if (shouldQuit()) + return; - if (!_skipStart) { - _screen->setPanel(3); - doOpening(); + // Display Notes screen + doSpecial5(4); if (shouldQuit()) return; + _screen->forceFadeOut(); + } - if (!_skipStart) { - //doTent(); - if (shouldQuit()) - return; + do { + _restartFl = false; + _screen->clearScreen(); + _screen->setPanel(0); + _screen->forceFadeOut(); + _events->showCursor(); + + initVariables(); + + // If there's a pending savegame to load, load it + if (_loadSaveSlot != -1) { + loadGameState(_loadSaveSlot); + _loadSaveSlot = -1; } - } - doTitle(); + // Execute the room + _room->doRoom(); + } while (_restartFl); } -void MartianEngine::doTitle() { - /* - _screen->setDisplayScan(); - _destIn = &_buffer2; - - _screen->forceFadeOut(); +bool MartianEngine::showCredits() { _events->hideCursor(); + _screen->clearScreen(); + _destIn = _screen; - _sound->queueSound(0, 98, 30); - - _files->_setPaletteFlag = false; - _files->loadScreen(0, 3); - - _buffer2.blitFrom(*_screen); - _buffer1.blitFrom(*_screen); - _screen->forceFadeIn(); - _sound->playSound(1); + int posX = _creditsStream->readSint16LE(); + int posY = 0; - Resource *spriteData = _files->loadFile(0, 2); - _objectsTable[0] = new SpriteResource(this, spriteData); - delete spriteData; + while(posX != -1) { + posY = _creditsStream->readSint16LE(); + int frameNum = _creditsStream->readSint16LE(); + _screen->plotImage(_introObjects, frameNum, Common::Point(posX, posY)); - _sound->playSound(1); + posX = _creditsStream->readSint16LE(); + } - _files->_setPaletteFlag = false; - _files->loadScreen(0, 4); - _sound->playSound(1); + posY = _creditsStream->readSint16LE(); + if (posY == -1) { + _events->showCursor(); + _screen->forceFadeOut(); + return true; + } - _buffer2.blitFrom(*_screen); - _buffer1.blitFrom(*_screen); - _sound->playSound(1); + _screen->forceFadeIn(); + _timers[3]._timer = _timers[3]._initTm = posY; - const int COUNTDOWN[6] = { 2, 0x80, 1, 0x7d, 0, 0x87 }; - for (_pCount = 0; _pCount < 3; ++_pCount) { - _buffer2.blitFrom(_buffer1); - int id = READ_LE_UINT16(COUNTDOWN + _pCount * 4); - int xp = READ_LE_UINT16(COUNTDOWN + _pCount * 4 + 2); - _screen->plotImage(_objectsTable[0], id, Common::Point(xp, 71)); + while (!shouldQuit() && !_events->isKeyMousePressed() && _timers[3]._timer) { + _events->pollEventsAndWait(); } - // TODO: More to do - delete _objectsTable[0]; - */ + _events->showCursor(); + _screen->forceFadeOut(); + + if (_events->_rightButton) + return true; + else + return false; } -void MartianEngine::doOpening() { - warning("TODO doOpening"); +void MartianEngine::doCredits() { + _midi->_byte1F781 = false; + _midi->loadMusic(47, 3); + _midi->midiPlay(); + _screen->setDisplayScan(); + _events->hideCursor(); + _screen->forceFadeOut(); + Resource *data = _files->loadFile(41, 1); + _introObjects = new SpriteResource(this, data); + delete data; + + _files->loadScreen(41, 0); + _buffer2.copyFrom(*_screen); + _buffer1.copyFrom(*_screen); + _events->showCursor(); + _creditsStream = new Common::MemoryReadStream(CREDIT_DATA, 180); + + if (!showCredits()) { + _screen->copyFrom(_buffer2); + _screen->forceFadeIn(); + + _events->_vbCount = 550; + while (!shouldQuit() && !_events->isKeyMousePressed() && _events->_vbCount > 0) + _events->pollEventsAndWait(); + + _screen->forceFadeOut(); + while (!shouldQuit() && !_events->isKeyMousePressed()&& !showCredits()) + _events->pollEventsAndWait(); + + warning("TODO: Free word_21E2B"); + _midi->freeMusic(); + } } void MartianEngine::setupGame() { + // Load death list + _deaths.resize(20); + for (int i = 0; i < 20; ++i) { + _deaths[i]._screenId = Martian::DEATH_SCREENS[i]; + _deaths[i]._msg = Martian::DEATHMESSAGE[i]; + } // Setup timers const int TIMER_DEFAULTS[] = { 4, 10, 8, 1, 1, 1, 1, 2 }; @@ -159,8 +307,56 @@ void MartianEngine::setupGame() { _player->_playerY = _player->_rawPlayer.y = TRAVEL_POS[_player->_roomNumber][1]; } -void MartianEngine::drawHelp() { - error("TODO: drawHelp"); +void MartianEngine::showDeathText(Common::String msg) { + Common::String line = ""; + int width = 0; + bool lastLine; + do { + lastLine = _fonts._font2.getLine(msg, _screen->_maxChars * 6, line, width); + // Draw the text + _bubbleBox->PRINTSTR(line); + + _screen->_printOrg.y += 6; + _screen->_printOrg.x = _screen->_printStart.x; + + if (_screen->_printOrg.y == 180) { + _events->waitKeyMouse(); + _screen->copyBuffer(&_buffer2); + _screen->_printOrg.y = _screen->_printStart.y; + } + } while (!lastLine); + _events->waitKeyMouse(); +} + +void MartianEngine::dead(int deathId) { + // Load and display death screen + _events->hideCursor(); + _screen->forceFadeOut(); + _files->loadScreen(48, _deaths[deathId]._screenId); + _screen->setIconPalette(); + _buffer2.copyBuffer(_screen); + _screen->forceFadeIn(); + _events->showCursor(); + + // Setup fonts + _fonts._charSet._hi = 10; + _fonts._charSet._lo = 1; + _fonts._charFor._lo = 247; + _fonts._charFor._hi = 255; + _screen->_maxChars = 50; + _screen->_printOrg = Common::Point(24, 18); + _screen->_printStart = Common::Point(24, 18); + + // Display death message + showDeathText(_deaths[deathId]._msg); + + _screen->forceFadeOut(); + _room->clearRoom(); + freeChar(); + + // The original was jumping to the restart label in main + _restartFl = true; + _events->pollEvents(); } } // End of namespace Martian diff --git a/engines/access/martian/martian_game.h b/engines/access/martian/martian_game.h index a83b67a288..9ef6c05c29 100644 --- a/engines/access/martian/martian_game.h +++ b/engines/access/martian/martian_game.h @@ -32,40 +32,41 @@ namespace Martian { class MartianEngine : public AccessEngine { private: bool _skipStart; - + SpriteResource *_introObjects; + Common::MemoryReadStream *_creditsStream; /** * Do the game introduction */ - void doIntroduction(); + void doCredits(); - /** - * Do title sequence - */ - void doTitle(); - - /** - * Do opening sequence - */ - void doOpening(); + bool showCredits(); /** * Setup variables for the game */ void setupGame(); + void initObjects(); + void configSelect(); + void initVariables(); protected: /** * Play the game */ virtual void playGame(); - virtual void dead(int deathId) {} + virtual void dead(int deathId); + + void setNoteParams(); + void displayNote(const Common::String &msg); public: - MartianEngine(OSystem *syst, const AccessGameDescription *gameDesc); + SpriteResource *_spec7Objects; + MartianEngine(OSystem *syst, const AccessGameDescription *gameDesc); virtual ~MartianEngine(); - void drawHelp(); + void doSpecial5(int param1); + void showDeathText(Common::String msg); virtual void establish(int esatabIndex, int sub) {}; }; diff --git a/engines/access/martian/martian_player.cpp b/engines/access/martian/martian_player.cpp new file mode 100644 index 0000000000..598664a600 --- /dev/null +++ b/engines/access/martian/martian_player.cpp @@ -0,0 +1,67 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/scummsys.h" +#include "access/access.h" +#include "access/room.h" +#include "access/martian/martian_game.h" +#include "access/martian/martian_player.h" +#include "access/martian/martian_resources.h" + +namespace Access { + +namespace Martian { + +MartianPlayer::MartianPlayer(AccessEngine *vm) : Player(vm) { + _game = (MartianEngine *)vm; +} + +void MartianPlayer::load() { + Player::load(); + + // Overwrite game-specific values + _playerOffset.x = _vm->_screen->_scaleTable1[20]; + _playerOffset.y = _vm->_screen->_scaleTable1[52]; + _leftDelta = -9; + _rightDelta = 33; + _upDelta = 5; + _downDelta = -5; + _scrollConst = 5; + + for (int i = 0; i < _vm->_playerDataCount; ++i) { + _walkOffRight[i] = SIDEOFFR[i]; + _walkOffLeft[i] = SIDEOFFL[i]; + _walkOffUp[i] = SIDEOFFU[i]; + _walkOffDown[i] = SIDEOFFD[i]; + } + + _sideWalkMin = 0; + _sideWalkMax = 7; + _upWalkMin = 8; + _upWalkMax = 14; + _downWalkMin = 15; + _downWalkMax = 23; +} + +} // End of namespace Martian + +} // End of namespace Access diff --git a/engines/access/martian/martian_player.h b/engines/access/martian/martian_player.h new file mode 100644 index 0000000000..63a21a1c24 --- /dev/null +++ b/engines/access/martian/martian_player.h @@ -0,0 +1,48 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef ACCESS_MARTIAN_PLAYER_H +#define ACCESS_MARTIAN_PLAYER_H + +#include "common/scummsys.h" +#include "access/player.h" + +namespace Access { + +namespace Martian { + +class MartianEngine; + +class MartianPlayer : public Player { +private: + MartianEngine *_game; +public: + MartianPlayer(AccessEngine *vm); + Resource *_texPal; + virtual void load(); +}; + +} // End of namespace Martian + +} // End of namespace Access + +#endif /* ACCESS_MARTIAN_PLAYER_H */ diff --git a/engines/access/martian/martian_resources.cpp b/engines/access/martian/martian_resources.cpp index d2b5dfd5d0..2ae61141e7 100644 --- a/engines/access/martian/martian_resources.cpp +++ b/engines/access/martian/martian_resources.cpp @@ -41,47 +41,96 @@ const char *const FILENAMES[] = { }; const byte MOUSE0[] = { - 0, 0, 0, 0, 0, 2, 0xF7, 5, 0, 3, 0xF7, 0xF7, 5, 0, 3, - 0xF7, 0xF7, 5, 0, 4, 0xF7, 0xF7, 0xF7, 5, 0, 4, 0xF7, - 0xF7, 0xF7, 5, 0, 5, 0xF7, 0xF7, 0xF7, 0xF7, 5, 0, 5, - 0xF7, 0xF7, 0xF7, 0xF7, 5, 0, 6, 0xF7, 0xF7, 0xF7, 0xF7, - 0xF7, 5, 0, 6, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 5, 0, 7, - 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 5, 0, 6, 0xF7, 0xF7, - 0xF7, 0xF7, 0xF7, 5, 0, 5, 0xF7, 0xF7, 0xF7, 0xF7, 5, - 2, 3, 0xF7, 0xF7, 5, 3, 3, 0xF7, 0xF7, 5, 3, 3, 0xF7, - 0xF7, 5, 4, 2, 0xF7, 5 + // hotspot x and y, uint16 LE + 0, 0, 0, 0, + // byte 1: number of skipped pixels + // byte 2: number of plotted pixels + // then, pixels + 0, 2, 0xF7, 5, + 0, 3, 0xF7, 0xF7, 5, + 0, 3, 0xF7, 0xF7, 5, + 0, 4, 0xF7, 0xF7, 0xF7, 5, + 0, 4, 0xF7, 0xF7, 0xF7, 5, + 0, 5, 0xF7, 0xF7, 0xF7, 0xF7, 5, + 0, 5, 0xF7, 0xF7, 0xF7, 0xF7, 5, + 0, 6, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 5, + 0, 6, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 5, + 0, 7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 5, + 0, 6, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 5, + 0, 5, 0xF7, 0xF7, 0xF7, 0xF7, 5, + 2, 3, 0xF7, 0xF7, 5, + 3, 3, 0xF7, 0xF7, 5, + 3, 3, 0xF7, 0xF7, 5, + 4, 2, 0xF7, 5 }; const byte MOUSE1[] = { - 7, 0, 7, 0, 6, 1, 0xF7, 4, 5, 0xFF, 0xFF, 0, 0xFF, 0xFF, - 3, 7, 0xFF, 0, 0, 0, 0, 0, 0xFF, 2, 9, 0xFF, 0, 0, 0, - 0xF7, 0, 0, 0, 0xFF, 1, 11, 0xFF, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0xFF, 1, 11, 0xFF, 0, 0, 0, 0, 0xF7, 0, 0, - 0, 0, 0xFF, 0, 13, 0xF7, 0, 0, 0xF7, 0, 0xF7, 0, 0xF7, - 0, 0xF7, 0, 0, 0xF7, 1, 11, 0xFF, 0, 0, 0, 0, 0xF7, - 0, 0, 0, 0, 0xFF, 1, 11, 0xFF, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0xFF, 2, 9, 0xFF, 0, 0, 0, 0xF7, 0, 0, 0, 0xFF, - 3, 7, 0xFF, 0, 0, 0, 0, 0, 0xFF, 4, 5, 0xFF, 0xFF, 0, - 0xFF, 0xFF, 6, 1, 0xF7, 0, 0, 0, 0, 0, 0 + // hotspot x and y, uint16 LE + 7, 0, 7, 0, + // byte 1: number of skipped pixels + // byte 2: number of plotted pixels + // then, pixels + 6, 1, 0xF7, + 4, 5, 0xFF, 0xFF, 0, 0xFF, 0xFF, + 3, 7, 0xFF, 0, 0, 0, 0, 0, 0xFF, + 2, 9, 0xFF, 0, 0, 0, 0xF7, 0, 0, 0, 0xFF, + 1, 11, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, + 1, 11, 0xFF, 0, 0, 0, 0, 0xF7, 0, 0, 0, 0, 0xFF, + 0, 13, 0xF7, 0, 0, 0xF7, 0, 0xF7, 0, 0xF7, 0, 0xF7, 0, 0, 0xF7, + 1, 11, 0xFF, 0, 0, 0, 0, 0xF7, 0, 0, 0, 0, 0xFF, + 1, 11, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, + 2, 9, 0xFF, 0, 0, 0, 0xF7, 0, 0, 0, 0xFF, + 3, 7, 0xFF, 0, 0, 0, 0, 0, 0xFF, + 4, 5, 0xFF, 0xFF, 0, 0xFF, 0xFF, + 6, 1, 0xF7, + 0, 0, + 0, 0, + 0, 0 }; const byte MOUSE2[] = { - 8, 0, 8, 0, 0, 0, 0, 0, 7, 2, 4, 5, 7, 2, 4, 5, 7, 2, - 4, 5, 7, 2, 4, 5, 7, 2, 4, 5, 2, 12, 4, 4, 4, 4, 4, - 0, 4, 4, 4, 4, 4, 5, 7, 2, 4, 5, 7, 2, 4, 5, 7, 2, 4, - 5, 7, 2, 4, 5, 7, 2, 4, 5, 0, 0, 0, 0, 0, 0 + // hotspot x and y, uint16 LE + 8, 0, 8, 0, + // byte 1: number of skipped pixels + // byte 2: number of plotted pixels + // then, pixels + 0, 0, + 0, 0, + 7, 2, 4, 5, + 7, 2, 4, 5, + 7, 2, 4, 5, + 7, 2, 4, 5, + 7, 2, 4, 5, + 2, 12, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 5, + 7, 2, 4, 5, + 7, 2, 4, 5, + 7, 2, 4, 5, + 7, 2, 4, 5, + 7, 2, 4, 5, + 0, 0, + 0, 0, + 0, 0 }; const byte MOUSE3[] = { - 0, 0, 0, 0, 0, 11, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 0, 12, 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 5, 0, 12, - 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 5, 0, 12, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 5, 0, 12, 6, 6, 6, 6, 6, 5, - 6, 6, 6, 6, 6, 5, 0, 12, 6, 6, 6, 6, 5, 0, 0, 6, 6, - 6, 6, 5, 0, 12, 6, 6, 6, 6, 6, 0, 6, 6, 6, 6, 6, 5, - 0, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 0, 12, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 0, 12, 6, 6, 6, - 6, 6, 5, 6, 6, 6, 6, 6, 5, 0, 12, 6, 6, 6, 6, 6, 5, - 6, 6, 6, 6, 6, 5, 0, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 5, 1, 11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, - 0, 0, 0, 0, 0 + // hotspot x and y, uint16 LE + 0, 0, 0, 0, + // byte 1: number of skipped pixels + // byte 2: number of plotted pixels + // then, pixels + 0, 11, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 0, 12, 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 5, + 0, 12, 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 5, + 0, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, + 0, 12, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 5, + 0, 12, 6, 6, 6, 6, 5, 0, 0, 6, 6, 6, 6, 5, + 0, 12, 6, 6, 6, 6, 6, 0, 6, 6, 6, 6, 6, 5, + 0, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, + 0, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, + 0, 12, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 5, + 0, 12, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 5, + 0, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, + 1, 11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, + 0, 0, + 0, 0 }; const byte *const CURSORS[4] = { MOUSE0, MOUSE1, MOUSE2, MOUSE3 }; @@ -139,17 +188,19 @@ const int TRAVEL_POS[][2] = { { -1, 21 } }; +const int INVENTORY_SIZE = 55; const char *const INVENTORY_NAMES[] = { - "CAMERA", "LENS", "PHOTOS", "MAIL", "GUN", "CASH", "COMLINK", "AMMO", - "LOCKPICK KIT", "EARRING", "RECIEPTS", "PAPER", "LADDER", "BOOTS", - "DOCUMENTS", "KNIFE", "DAGGER", "KEYS", "ROCK", "LOG", "SHOVEL", - "STONE", "REMOTE CONTROL", "FOOD AND WATER", "DOOR CARD KEY", + "CAMERA", "LENS", "PHOTOS", "MAIL", "GUN", + "CASH", "COMLINK", "AMMO", "LOCKPICK KIT", "EARRING", + "RECIEPTS", "PAPER", "LADDER", "BOOTS", "DOCUMENTS", + "KNIFE", "DAGGER", "KEYS", "ROCK", "LOG", + "SHOVEL", "STONE", "REMOTE CONTROL", "FOOD AND WATER", "DOOR CARD KEY", "FLASHLIGHT", "INTERLOCK KEY", "TOOLS", "REBREATHER", "JET PACK", - "ROD", "HCL2", "SAFE CARD KEY", "TUNING FORK", "STONE", "ROSE", - "KEY", "NOTE", "ALLEN WRENCH", "HOVER BOARD", "BLUE PRINTS", - "LETTER", "MEMORANDUM", "MARKERS", "FILM", "ANDRETTI FILM", - "GLASSES", "AMULET", "FACIAL KIT", "CAT FOOD", "MONKEY WRENCH", - "BIG DICK CARD", "BRA", "BOLT" + "ROD", "HCL2", "SAFE CARD KEY", "TUNING FORK", "STONE", + "ROSE", "KEY", "NOTE", "ALLEN WRENCH", "HOVER BOARD", + "BLUE PRINTS", "LETTER", "MEMORANDUM", "MARKERS", "FILM", + "ANDRETTI FILM", "GLASSES", "AMULET", "FACIAL KIT", "CAT FOOD", + "MONKEY WRENCH", "BIG DICK CARD", "BRA", "BOLT", nullptr }; const byte ROOM_TABLE1[] = { @@ -436,12 +487,12 @@ const char *const ROOM_DESCR[] = { const int ROOM_NUMB = 48; -const byte CHAR_TABLE0[] = { +const byte MMCHAR_0[] = { 0x02, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE2[] = { +const byte MMCHAR_2[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x32, 0x33, 0x00, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x33, 0x00, 0x00, 0x00, 0x33, @@ -454,13 +505,13 @@ const byte CHAR_TABLE2[] = { 0x00, 0x12, 0x00, 0x33, 0x00, 0x0a, 0x00, 0x33, 0x00, 0x13, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE3[] = { +const byte MMCHAR_3[] = { 0x02, 0x31, 0x00, 0x03, 0x00, 0x35, 0x00, 0x37, 0x00, 0x02, 0x00, 0x80, 0x00, 0xf7, 0x00, 0x4b, 0x37, 0x00, 0x01, 0x00, 0xff, 0x37, 0x00, 0x03, 0x00, 0x37, 0x00, 0x00, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE4[] = { +const byte MMCHAR_4[] = { 0x01, 0x31, 0x00, 0x0a, 0x00, 0x36, 0x00, 0x35, 0x00, 0x02, 0x00, 0x80, 0x00, 0xf7, 0x00, 0x49, 0x35, 0x00, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x35, 0x00, 0x00, 0x00, 0x35, @@ -473,7 +524,7 @@ const byte CHAR_TABLE4[] = { 0x00, 0x13, 0x00, 0x35, 0x00, 0x0b, 0x00, 0x35, 0x00, 0x14, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE5[] = { +const byte MMCHAR_5[] = { 0x01, 0x31, 0x00, 0x08, 0x00, 0x37, 0x00, 0x34, 0x00, 0x02, 0x00, 0x80, 0x00, 0xf7, 0x00, 0x48, 0x34, 0x00, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x34, 0x00, 0x00, 0x00, 0x43, @@ -490,31 +541,31 @@ const byte CHAR_TABLE5[] = { 0x00, 0x0f, 0x00, 0x43, 0x00, 0x0d, 0x00, 0x34, 0x00, 0x10, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE6[] = { +const byte MMCHAR_6[] = { 0x02, 0x31, 0x00, 0x03, 0x00, 0x38, 0x00, 0x44, 0x00, 0x03, 0x00, 0x80, 0x00, 0xf7, 0x00, 0x4e, 0x44, 0x00, 0x01, 0x00, 0xff, 0x44, 0x00, 0x02, 0x00, 0x44, 0x00, 0x00, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE7[] = { +const byte MMCHAR_7[] = { 0x02, 0x31, 0x00, 0x01, 0x00, 0x39, 0x00, 0x38, 0x00, 0x02, 0x00, 0x80, 0x00, 0xf7, 0x00, 0x4c, 0x38, 0x00, 0x01, 0x00, 0xff, 0x38, 0x00, 0x03, 0x00, 0x38, 0x00, 0x00, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE8[] = { +const byte MMCHAR_8[] = { 0x03, 0xff, 0xff, 0xff, 0xff, 0x3a, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x3b, 0x00, 0x01, 0x00, 0xff, 0x3b, 0x00, 0x02, 0x00, 0x3b, 0x00, 0x00, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE9[] = { +const byte MMCHAR_9[] = { 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x59, 0x4a, 0x00, 0x01, 0x00, 0xff, 0x4a, 0x00, 0x02, 0x00, 0x4a, 0x00, 0x00, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE10[] = { +const byte MMCHAR_10[] = { 0x01, 0x31, 0x00, 0x0a, 0x00, 0x3c, 0x00, 0x36, 0x00, 0x02, 0x00, 0x80, 0x00, 0xf7, 0x00, 0x4a, 0x36, 0x00, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x36, 0x00, 0x00, 0x00, 0x36, @@ -532,19 +583,19 @@ const byte CHAR_TABLE10[] = { 0x00, 0x36, 0x00, 0x11, 0x00, 0x36, 0x00, 0x21, 0x00, 0x36, 0x00, 0x12, 0x00, 0x36, 0x00, 0x22, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE11[] = { +const byte MMCHAR_11[] = { 0x03, 0xff, 0xff, 0xff, 0xff, 0x3d, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x55, 0x45, 0x00, 0x01, 0x00, 0xff, 0x45, 0x00, 0x02, 0x00, 0x45, 0x00, 0x00, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE12[] = { +const byte MMCHAR_12[] = { 0x03, 0xff, 0xff, 0xff, 0xff, 0x3e, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0x00, 0x01, 0x00, 0xff, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE13[] = { +const byte MMCHAR_13[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x46, 0x00, 0x02, 0x00, 0x80, 0x00, 0xf7, 0x00, 0x56, 0x46, 0x00, 0x01, 0x00, 0xff, 0x46, 0x00, 0x03, 0x00, 0x46, 0x00, 0x00, 0x00, 0x46, @@ -557,7 +608,7 @@ const byte CHAR_TABLE13[] = { 0x00, 0x14, 0x00, 0x46, 0x00, 0x0c, 0x00, 0x46, 0x00, 0x15, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE15[] = { +const byte MMCHAR_15[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0x41, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x57, 0x47, 0x00, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x47, 0x00, 0x00, 0x00, 0x47, @@ -565,43 +616,43 @@ const byte CHAR_TABLE15[] = { 0x00, 0x47, 0x00, 0x06, 0x00, 0x47, 0x00, 0x04, 0x00, 0x47, 0x00, 0x07, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE16[] = { +const byte MMCHAR_16[] = { 0x03, 0xff, 0xff, 0xff, 0xff, 0x42, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x54, 0x41, 0x00, 0x01, 0x00, 0xff, 0x41, 0x00, 0x02, 0x00, 0x41, 0x00, 0x00, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE18[] = { +const byte MMCHAR_18[] = { 0x02, 0x31, 0x00, 0x07, 0x00, 0x44, 0x00, 0x3c, 0x00, 0x03, 0x00, 0x80, 0x00, 0xf7, 0x00, 0x50, 0x3c, 0x00, 0x01, 0x00, 0xff, 0x3c, 0x00, 0x02, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE19[] = { +const byte MMCHAR_19[] = { 0x02, 0x31, 0x00, 0x07, 0x00, 0x45, 0x00, 0x3d, 0x00, 0x03, 0x00, 0x80, 0x00, 0xf7, 0x00, 0x51, 0x3d, 0x00, 0x01, 0x00, 0xff, 0x3d, 0x00, 0x02, 0x00, 0x3d, 0x00, 0x00, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE20[] = { +const byte MMCHAR_20[] = { 0x02, 0x31, 0x00, 0x02, 0x00, 0x46, 0x00, 0x48, 0x00, 0x02, 0x00, 0x80, 0x00, 0xf7, 0x00, 0x58, 0x48, 0x00, 0x01, 0x00, 0xff, 0x48, 0x00, 0x03, 0x00, 0x48, 0x00, 0x00, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE21[] = { +const byte MMCHAR_21[] = { 0x02, 0x31, 0x00, 0x07, 0x00, 0x47, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x80, 0x00, 0xf7, 0x00, 0x52, 0x3e, 0x00, 0x01, 0x00, 0xff, 0x3e, 0x00, 0x02, 0x00, 0x3e, 0x00, 0x00, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE23[] = { +const byte MMCHAR_23[] = { 0x02, 0x31, 0x00, 0x08, 0x00, 0x49, 0x00, 0x3f, 0x00, 0x03, 0x00, 0x80, 0x00, 0xf7, 0x00, 0x53, 0x3f, 0x00, 0x01, 0x00, 0xff, 0x3f, 0x00, 0x02, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xff, 0xff, }; -const byte CHAR_TABLE24[] = { +const byte MMCHAR_24[] = { 0x02, 0x32, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x47, 0x32, 0x00, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x32, 0x00, 0x01, 0x00, 0x32, @@ -612,13 +663,13 @@ const byte CHAR_TABLE24[] = { 0x00, 0x08, 0x00, 0x32, 0x00, 0x0f, 0x00, 0x32, 0x00, 0x09, 0x00, 0x32, 0x00, 0x10, 0x00, 0xff, 0xff }; -const byte CHAR_TABLE25[] = { +const byte MMCHAR_25[] = { 0x02, 0x39, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x39, 0x00, 0x00, 0x00, 0x39, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF }; -const byte CHAR_TABLE26[] = { +const byte MMCHAR_26[] = { 0x01, 0x3a, 0x00, 0x01, 0x00, 0x0a, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x3a, 0x00, 0x02, 0x00, 0xff, 0x3a, 0x00, 0x03, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x42, @@ -638,7 +689,7 @@ const byte CHAR_TABLE26[] = { 0x00, 0x3a, 0x00, 0x14, 0x00, 0x42, 0x00, 0x11, 0x00, 0x3a, 0x00, 0x15, 0x00, 0xff, 0xff }; -const byte CHAR_TABLE27[] = { +const byte MMCHAR_27[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x58, 0x49, 0x00, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x49, 0x00, 0x00, 0x00, 0x49, @@ -650,73 +701,144 @@ const byte CHAR_TABLE27[] = { 0x00, 0x49, 0x00, 0x10, 0x00, 0x49, 0x00, 0x09, 0x00, 0x49, 0x00, 0x11, 0x00, 0xff, 0xff, }; -const byte *const CHAR_TABLE[] = { - CHAR_TABLE0, nullptr, CHAR_TABLE2, CHAR_TABLE3, CHAR_TABLE4, CHAR_TABLE5, - CHAR_TABLE6, CHAR_TABLE7, CHAR_TABLE8, CHAR_TABLE9, CHAR_TABLE10, - CHAR_TABLE11, CHAR_TABLE12, CHAR_TABLE13, nullptr, CHAR_TABLE15, - CHAR_TABLE16, nullptr, CHAR_TABLE18, CHAR_TABLE19, CHAR_TABLE20, - CHAR_TABLE21, nullptr, CHAR_TABLE23, CHAR_TABLE24, CHAR_TABLE25, - CHAR_TABLE26, CHAR_TABLE27 + +// HACK: MMCHAR_0 has been used to replace the missing CHAR: 1, 14, 17 and 22 +const byte *const CHARTBL_MM[] = { + MMCHAR_0, MMCHAR_0, MMCHAR_2, MMCHAR_3, MMCHAR_4, + MMCHAR_5, MMCHAR_6, MMCHAR_7, MMCHAR_8, MMCHAR_9, + MMCHAR_10, MMCHAR_11, MMCHAR_12, MMCHAR_13, MMCHAR_0, + MMCHAR_15, MMCHAR_16, MMCHAR_0, MMCHAR_18, MMCHAR_19, + MMCHAR_20, MMCHAR_21, MMCHAR_0, MMCHAR_23, MMCHAR_24, + MMCHAR_25, MMCHAR_26, MMCHAR_27 }; -// TODO: Fix that array -const int COMBO_TABLE[54][4] = { - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 }, - { -1, -1, -1, -1 } +const int SIDEOFFR[] = { 4, 0, 7, 10, 3, 1, 2, 13, 0, 0, 0, 0 }; +const int SIDEOFFL[] = { 11, 6, 1, 4, 10, 6, 1, 4, 0, 0, 0, 0 }; +const int SIDEOFFU[] = { 1, 2, 0, 2, 2, 1, 1, 0, 0, 0, 0, 0 }; +const int SIDEOFFD[] = { 2, 0, 1, 1, 0, 1, 1, 1, 2, 0, 0, 0 }; + +const byte CREDIT_DATA[] = { + 0x1F, 0x00, 0x49, 0x00, 0x00, 0x00, 0xB7, 0x00, 0x49, 0x00, + 0x01, 0x00, 0x79, 0x00, 0x6F, 0x00, 0x02, 0x00, 0xFF, 0xFF, + 0xEA, 0x01, 0x75, 0x00, 0x46, 0x00, 0x03, 0x00, 0x46, 0x00, + 0x5E, 0x00, 0x04, 0x00, 0xFF, 0xFF, 0xEA, 0x01, 0x72, 0x00, + 0x3E, 0x00, 0x05, 0x00, 0x46, 0x00, 0x57, 0x00, 0x04, 0x00, + 0x5C, 0x00, 0x6E, 0x00, 0x06, 0x00, 0xFF, 0xFF, 0xEA, 0x01, + 0x63, 0x00, 0x48, 0x00, 0x07, 0x00, 0x2A, 0x00, 0x65, 0x00, + 0x08, 0x00, 0xFF, 0xFF, 0xEA, 0x01, 0x7E, 0x00, 0x39, 0x00, + 0x09, 0x00, 0x5C, 0x00, 0x57, 0x00, 0x06, 0x00, 0x45, 0x00, + 0x6B, 0x00, 0x04, 0x00, 0xFF, 0xFF, 0xEA, 0x01, 0x5F, 0x00, + 0x46, 0x00, 0x0A, 0x00, 0x67, 0x00, 0x62, 0x00, 0x0B, 0x00, + 0x47, 0x00, 0x76, 0x00, 0x0C, 0x00, 0xFF, 0xFF, 0xEA, 0x01, + 0x62, 0x00, 0x38, 0x00, 0x0D, 0x00, 0x47, 0x00, 0x55, 0x00, + 0x0E, 0x00, 0x49, 0x00, 0x6A, 0x00, 0x0F, 0x00, 0xFF, 0xFF, + 0xEA, 0x01, 0x18, 0x00, 0x22, 0x00, 0x10, 0x00, 0x17, 0x00, + 0x3E, 0x00, 0x11, 0x00, 0x16, 0x00, 0x52, 0x00, 0x12, 0x00, + 0xEE, 0x00, 0x7B, 0x00, 0x13, 0x00, 0xB5, 0x00, 0x93, 0x00, + 0x0B, 0x00, 0xFF, 0xFF, 0xF4, 0x01, 0xFF, 0xFF, 0xFF, 0xFF }; -} // End of namespace Martian +const byte ICON_DATA[] = { + 0x3F, 0x3F, 0x00, 0x00, 0x07, 0x16, + 0x00, 0x0A, 0x1A, 0x00, 0x0D, 0x1F, + 0x00, 0x11, 0x28, 0x00, 0x15, 0x30, + 0x00, 0x19, 0x39, 0x00, 0x1B, 0x3F, + 0x00, 0x2D, 0x3A +}; + +const int RMOUSE[10][2] = { + { 7, 36 }, { 38, 68 }, { 70, 99 }, { 102, 125 }, { 128, 152 }, + { 155, 185 }, { 188, 216 }, { 219, 260 }, { 263, 293 }, { 295, 314 } +}; + +const char *const TRAVDATA[] = { + "GALACTIC PICTURES", "TERRAFORM", "WASHROOM", "MR. BIG", "ALEXIS' HOME", + "JOHNNY FEDORA", "JUNKYARD IN", "TEX'S OFFICE", "MURDER SCENE", "PLAZA HOTEL", + "RESTAURANT", "GIFT SHOP", "LOVE SCENE", "RICK LOGAN", "HUT", + "SMUGGLERS BASE", "PYRAMID", "CASINO", "CAS LOBBY", "BAR", + "DUCTWORK", "RESTROOM", "OFFICE", "SAFE", "ALLEY", + "POWER PLANT", "PLANT OFFICE", "PLANT ROOM", "TEMPLE", "IN TEMPLE", + "JANE MANSFIELD'S HOME", "AEROBICS ACADEMY", "DR. LAWRENCE BARKLEY", "COLONISTS CAMP", "IN SLUM", + "REMOTE OUTPOST", "WALK", "CAVE", "PRISON", "ORACLE", + "JOCQUES SPARROW", "MAC MALDEN", "CHANTAL VARGAS", "GUY CALLABERO", "ROCKWELL BACHE", + "FERRIS COLLETTE", "NORA DESMOND ALEXANDER", "LOWELL PERCIVAL", "MICHELE BLOODWORTH", "BRADLEY ERICSON", + "COOPER BRADBURY", nullptr +}; + +const char *const ASKTBL[] = { + "NONE", "MARSHALL ALEXANDER", "TERRAFORM CORP.", "COLLIER STANTON", "ROCKWELL BACHE", + "JOCQUES SPARROW", "NORA DESMOND ALEXANDER", "GALACTIC PICTURES", "LAWRENCE BARKLEY", "TMS", + "MAC MALDEN", "STANTON EXPEDITION", "LOWELL PERCIVAL", "CHANTAL VARGAS", "RICK LOGAN", + "ALEXIS ALEXANDER", "FERRIS COLLETT", "GUY CALLABERO", "ORACLE STONE", "THOMAS DANGERFIELD", + "JANE MANSFIELD", "STACY CRAWFORD", "DICK CASTRO", "ROCKY BULLWINKEL", "DEACON HAWKE", + "NATHAN BLOODWORTH", "MICHELLE BLOODWORTH", "BRADLEY ERICSON", "COOPER BRADBURY", "MARTIAN MEMORANDUM", + "JOHNNY FEDORA", "RHONDA FOXWORTH", "ANGELO ANDRETTI", "TEX MURPHY", "ROBERT BLOODWORTH", + "LARRRY HAMMOND", nullptr +}; + +byte HELP[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +}; +const byte DEATH_SCREENS[] = { + 5, 5, 3, 3, 7, 4, 6, 2, 2, 2, 1, 5, 3, 5, 2, 8, 5, 3, 8, 5 +}; + +const char *const DEATHMESSAGE[] = { + "A VICIOUS THUG PULLS OUT HIS GUN AND AIR CONDITIONS YOUR BRAIN.", + "BIG DICK COMES BACK AND ANNOUNCES YOUR TIME IS UP. ONE OF HIS BOYS PROCEEDS TO PART YOUR EYEBROWS.", + "ALTHOUGH HIS FIRST SHOT MISSED, THE PUNK FINDS YOU AND TURNS YOU INTO A DOUGHNUT.", + "THE CREEP SPOTS YOU. HE TURNS AND FIRES HIS WEAPON. IT BURNS A HOLE A BUZZARD CAN FLY THROUGH.", + "OBVIOUSLY RICK LOGAN HAS A FEW TRICK UP HIS SLEEVE. A TREMENDOUS WEIGHT HITS YOUR HEAD. YOU MUMBLE; WATCH OUT FOR THAT TREE...", + "SLOWLY SINKING IN THE SLIMY OOZE, YOU THINK OF SEVERAL JELLO WRESTLING MATCHES YOU'VE ATTENDED. BUT NO MORE...", + "THE PATH SUDDENLY GIVES WAY AND YOU FEEL MANY STAKES TEAR THROUGH YOUR FLESH. HOW DO YOU LIKE YOUR STAKE", + "THE SNAKE SINKS ITS FANGS INTO YOU LEG. THE POISON WORKS QUICKLY. THE SNAKE THEN SWALLOWS YOU WHOLE.", + "YOU FADE AWAY, GLOWING LIKE A LIGHTBULB.", + "YOU TOUCH THE BUBBLING RADIOACTIVE SELTZER. IT IMMEDIATELY CAUSES VITAL ORGANS TO ELONGATE AND EXPLODE. YOU DIE WITH AN ABSURD AND FOOLISH LOOK ON YOUR FACE.", + "THE DOGS PRETTY HUNGRY. IT WON'T TAKE HIM LONG TO FINISH SO SIT BACK AND ENJOY IT.", + "ROCKY DOESN'T LIKE BEING FOLLOWED. HE DECIDES TO BEAT YOU. WITHIN AND INCH OF YOUR LIFE. UNFORTUNATELY, HE MISJUDGED THE DISTANCE", + "YOU STUMBLE INTO DEADLY LASER FIRE.", + "THE OUTPOST AND YOUR BODY PARTS ARE BLOWN TO KINGDOM COME.", + "YOU REACH THE TOP, BUT YOUR AIR SOON RUNS OUT LEAVING YOU BREATHLESS.", + "YOU DIE IN THE FIERY EXPLOSION.", + "YOU FALL HUNDREDS OF FEET TO YOUR DEATH.", + "YOU WALK ONTO A PRESSURE SENSITIVE SECURITY PAD. A LASER ZEROS IN AND BLOWS A HOLE THE SIZE OF A SUBARU TIRE THROUGH YOU.", + "DANGERFIELD'S EXPERIMENT BACKFIRES. IT RELEASES A DEMON FROM HIS SUBCONSCIOUS WHICH DESTROYS THE ENTIRE PLANET.", + "ONCE DANGERFIELD GETS OUT OF HIS CHAMBER, HE PULLS OUT A WEAPON AND LETS YOU HAVE IT." +}; + +const char *const SPEC7MESSAGE = { + "THOMAS DANGERFIELD'S MAD EXPERIMENT OF ATTEMPTING TO HARNESS THE STONE'S POWER, ENDED HIS LIFE. DANGERFIELD WAS A DECENT HUMAN " \ + "BEING ONCE, BUT WAS DRIVEN INSANE BY HIS QUEST FOR THE ULTIMATE POWER. ALEXIS AND I DECIDE THAT DEACON HAWKE IS THE ONLY " \ + "LOGICAL CHOICE FOR THE STONE. WE ARRIVE AT THE TEMPLE WHERE SHE IS WAITING FOR US. SHE TURNS AND WHISPERS; 'YOU HAVE RETURNED " \ + "THE STONE TO THE MISTRESS OF THE LIGHT. YOU HAVE SURELY SAVED THE WORLD FROM ANNIHILATION BUT YOU MUST CONTINUE TO BE DILIGENT. " \ + "MANKIND MAY YET PROVE TO BE THE AUTHOR OF HIS OWN DEMISE. REVERENCE LIFE. PROTECT THE LIVING THINGS AND RECYCLE. AND NOW FOR " \ + "THE SAFETY OF MANKIND, I MUST TAKE THE STONE. PERHAPS SOMEDAY, WHEN THE HUMAN RACE IS READY, IT WILL BE RETURNED. UNTIL THEN "\ + "FAREWELL...'" +}; + +const byte _byte1EEB5[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, + 1 +}; + +const int PICTURERANGE[][2] = { +// { min X, max X}, {min Y, max Y} + { 20, 30 }, { 82, 87 }, + { 20, 30 }, { 105, 110 }, + { 0, 8 }, { 92, 100 }, + { 42, 46 }, { 92, 100 }, + { 9, 41 }, { 88, 104 }, + { 9, 41 }, { 117, 133 }, + { -1, -1 } +}; + +} // End of namespace Martian } // End of namespace Access diff --git a/engines/access/martian/martian_resources.h b/engines/access/martian/martian_resources.h index a52967d42a..4ffc4de9ab 100644 --- a/engines/access/martian/martian_resources.h +++ b/engines/access/martian/martian_resources.h @@ -31,22 +31,46 @@ namespace Martian { extern const char *const FILENAMES[]; +extern const int SIDEOFFR[]; +extern const int SIDEOFFL[]; +extern const int SIDEOFFU[]; +extern const int SIDEOFFD[]; + extern const byte *const CURSORS[4]; extern const int TRAVEL_POS[][2]; +extern const int INVENTORY_SIZE; extern const char *const INVENTORY_NAMES[]; extern const byte *const ROOM_TABLE[]; extern const char *const ROOM_DESCR[]; extern const int ROOM_NUMB; -extern const byte *const CHAR_TABLE[]; +extern const byte *const CHARTBL_MM[]; -extern const int COMBO_TABLE[54][4]; +extern const int SIDEOFFR[]; +extern const int SIDEOFFL[]; +extern const int SIDEOFFU[]; +extern const int SIDEOFFD[]; -} // End of namespace Martian +extern const byte CREDIT_DATA[]; +extern const byte ICON_DATA[]; + +extern const int RMOUSE[10][2]; + +extern byte HELP[]; +extern const char *const ASKTBL[]; +extern const char *const TRAVDATA[]; +extern const byte DEATH_SCREENS[]; +extern const char *const DEATHMESSAGE[]; +extern const char *const SPEC7MESSAGE; + +extern const byte _byte1EEB5[]; +extern const int PICTURERANGE[][2]; + +} // End of namespace Martian } // End of namespace Access #endif /* ACCESS_MARTIAN_RESOURCES_H */ diff --git a/engines/access/martian/martian_room.cpp b/engines/access/martian/martian_room.cpp index e9d1b9d8cf..d5b03db246 100644 --- a/engines/access/martian/martian_room.cpp +++ b/engines/access/martian/martian_room.cpp @@ -43,72 +43,47 @@ void MartianRoom::loadRoom(int roomNumber) { } void MartianRoom::reloadRoom() { - loadRoom(_vm->_player->_roomNumber); - - if (_roomFlag != 1) { - _vm->_currentMan = _roomFlag; - _vm->_currentManOld = _roomFlag; - _vm->_manScaleOff = 0; - - switch (_vm->_currentMan) { - case 0: - _vm->_player->loadSprites("MAN.LZ"); - break; - - case 2: - _vm->_player->loadSprites("JMAN.LZ"); - break; +// _vm->_currentMan = _roomFlag; +// _vm->_currentManOld = _roomFlag; +// _vm->_manScaleOff = 0; - case 3: - _vm->_player->loadSprites("OVERHEAD.LZ"); - _vm->_manScaleOff = 1; - break; + _vm->_player->loadTexPalette(); + _vm->_player->loadSprites("TEX.LZ"); - default: - break; - } - } + loadRoom(_vm->_player->_roomNumber); reloadRoom1(); } void MartianRoom::reloadRoom1() { - if (_vm->_player->_roomNumber == 29 || _vm->_player->_roomNumber == 31 - || _vm->_player->_roomNumber == 42 || _vm->_player->_roomNumber == 44) { - //Resource *spriteData = _vm->_files->loadFile("MAYA.LZ"); - //_vm->_inactive._spritesPtr = new SpriteResource(_vm, spriteData); - //delete spriteData; - _vm->_currentCharFlag = false; - } - _selectCommand = -1; - _vm->_events->setNormalCursor(CURSOR_CROSSHAIRS); - _vm->_mouseMode = 0; - _vm->_boxSelect = true; + _vm->_boxSelect = false; //-1 _vm->_player->_playerOff = false; - _vm->_screen->fadeOut(); + _vm->_screen->forceFadeOut(); + _vm->_events->hideCursor(); _vm->_screen->clearScreen(); + _vm->_events->showCursor(); roomSet(); + _vm->_player->load(); - // TODO: Refactor + if (_vm->_player->_roomNumber != 47) + _vm->_player->calcManScale(); + _vm->_events->hideCursor(); + roomMenu(); _vm->_screen->setBufferScan(); setupRoom(); setWallCodes(); buildScreen(); + _vm->copyBF2Vid(); - if (!_vm->_screen->_vesaMode) { - _vm->copyBF2Vid(); - } else if (_vm->_player->_roomNumber != 20 && _vm->_player->_roomNumber != 24 - && _vm->_player->_roomNumber != 33) { - _vm->_screen->setPalette(); - _vm->copyBF2Vid(); - } - + _vm->_screen->setManPalette(); + _vm->_events->showCursor(); _vm->_player->_frame = 0; _vm->_oldRects.clear(); _vm->_newRects.clear(); + _vm->_events->clearEvents(); } void MartianRoom::roomSet() { @@ -116,6 +91,12 @@ void MartianRoom::roomSet() { _vm->_scripts->_sequence = 1000; _vm->_scripts->searchForSequence(); _vm->_scripts->executeScript(); + + for (int i = 0; i < 30; i++) + _byte26CD2[i] = 0; + + for (int i = 0; i < 10; i++) + _byte26CBC[i] = 0; } void MartianRoom::roomMenu() { @@ -126,16 +107,31 @@ void MartianRoom::roomMenu() { _vm->_screen->saveScreen(); _vm->_screen->setDisplayScan(); _vm->_destIn = _vm->_screen; // TODO: Redundant - _vm->_screen->plotImage(spr, 0, Common::Point(0, 177)); - _vm->_screen->plotImage(spr, 1, Common::Point(143, 177)); + _vm->_screen->plotImage(spr, 0, Common::Point(5, 184)); + _vm->_screen->plotImage(spr, 1, Common::Point(155, 184)); _vm->_screen->restoreScreen(); delete spr; } void MartianRoom::mainAreaClick() { + Common::Point &mousePos = _vm->_events->_mousePos; + Common::Point pt = _vm->_events->calcRawMouse(); + Screen &screen = *_vm->_screen; + Player &player = *_vm->_player; + + if (_selectCommand == -1) { + player._moveTo = pt; + player._playerMove = true; + } else if (mousePos.x >= screen._windowXAdd && + mousePos.x <= (screen._windowXAdd + screen._vWindowBytesWide) && + mousePos.y >= screen._windowYAdd && + mousePos.y <= (screen._windowYAdd + screen._vWindowLinesTall)) { + if (checkBoxes1(pt) >= 0) { + checkBoxes3(); + } + } } } // End of namespace Martian - } // End of namespace Access diff --git a/engines/access/martian/martian_room.h b/engines/access/martian/martian_room.h index 85529ce8f0..11501b6e57 100644 --- a/engines/access/martian/martian_room.h +++ b/engines/access/martian/martian_room.h @@ -39,6 +39,9 @@ private: MartianEngine *_game; void roomSet(); + + int _byte26CD2[30]; + int _byte26CBC[10]; protected: virtual void loadRoom(int roomNumber); @@ -52,8 +55,6 @@ public: virtual ~MartianRoom(); - virtual void loadRoomData(const byte *roomData) { warning("TODO - loadRoomData"); } - virtual void init4Quads() { } virtual void roomMenu(); diff --git a/engines/access/martian/martian_scripts.cpp b/engines/access/martian/martian_scripts.cpp index 0578872092..a9b5de5597 100644 --- a/engines/access/martian/martian_scripts.cpp +++ b/engines/access/martian/martian_scripts.cpp @@ -34,7 +34,300 @@ MartianScripts::MartianScripts(AccessEngine *vm) : Scripts(vm) { _game = (MartianEngine *)_vm; } +void MartianScripts::cmdSpecial0() { + _vm->_sound->stopSound(); + _vm->_midi->stopSong(); + + _vm->_midi->loadMusic(47, 1); + _vm->_midi->midiPlay(); + _vm->_midi->setLoop(true); + + _vm->_events->_vbCount = 300; + while (!_vm->shouldQuit() && _vm->_events->_vbCount > 0) + _vm->_events->pollEventsAndWait(); + + _vm->_screen->forceFadeOut(); + _vm->_files->loadScreen("HOUSE.SC"); + + _vm->_video->setVideo(_vm->_screen, Common::Point(46, 30), "HVID.VID", 20); + + do { + _vm->_video->playVideo(); + if (_vm->_video->_videoFrame == 4) { + _vm->_screen->flashPalette(16); + _vm->_sound->playSound(4); + do { + _vm->_events->pollEvents(); + } while (!_vm->shouldQuit() && _vm->_sound->_playingSound); + _vm->_timers[31]._timer = _vm->_timers[31]._initTm = 40; + } + } while (!_vm->_video->_videoEnd && !_vm->shouldQuit()); + + if (_vm->_video->_videoEnd) { + _vm->_screen->flashPalette(12); + _vm->_sound->playSound(4); + do { + _vm->_events->pollEvents(); + } while (!_vm->shouldQuit() && _vm->_sound->_playingSound); + _vm->_midi->stopSong(); + _vm->_midi->freeMusic(); + warning("TODO: Pop Midi"); + } +} + +void MartianScripts::cmdSpecial1(int param1) { + _vm->_events->hideCursor(); + + if (param1 != -1) { + _vm->_files->loadScreen(49, param1); + _vm->_buffer2.copyBuffer(_vm->_screen); + } + + _vm->_screen->setIconPalette(); + _vm->_screen->forceFadeIn(); + _vm->_events->showCursor(); +} + +void MartianScripts::cmdSpecial3() { + _vm->_screen->forceFadeOut(); + _vm->_events->hideCursor(); + _vm->_files->loadScreen(57, 3); + _vm->_buffer2.copyFrom(*_vm->_screen); + + _vm->_screen->setIconPalette(); + _vm->_events->showCursor(); + _vm->_screen->forceFadeIn(); +} + +void MartianScripts::doIntro(int param1) { + _game->doSpecial5(param1); +} + +void MartianScripts::cmdSpecial6() { + _vm->_midi->stopSong(); + _vm->_screen->setDisplayScan(); + _vm->_events->clearEvents(); + _vm->_screen->forceFadeOut(); + _vm->_events->hideCursor(); + _vm->_files->loadScreen(49, 9); + _vm->_events->showCursor(); + _vm->_screen->setIconPalette(); + _vm->_screen->forceFadeIn(); + + Resource *cellsRes = _vm->_files->loadFile("CELLS00.LZ"); + _vm->_objectsTable[0] = new SpriteResource(_vm, cellsRes); + delete cellsRes; + + _vm->_timers[20]._timer = _vm->_timers[20]._initTm = 30; + _vm->_fonts._charSet._lo = 1; + _vm->_fonts._charSet._hi = 10; + _vm->_fonts._charFor._lo = 1; + _vm->_fonts._charFor._hi = 255; + + _vm->_screen->_maxChars = 50; + _vm->_screen->_printOrg = _vm->_screen->_printStart = Common::Point(24, 18); + + Resource *notesRes = _vm->_files->loadFile("ETEXT.DAT"); + notesRes->_stream->seek(72); + + // Read the message + Common::String msg = ""; + byte c; + while ((c = (char)notesRes->_stream->readByte()) != '\0') + msg += c; + + //display the message + _game->showDeathText(msg); + + delete notesRes; + delete _vm->_objectsTable[0]; + _vm->_objectsTable[0] = nullptr; + _vm->_midi->stopSong(); +} + +void MartianScripts::cmdSpecial7() { + _vm->_room->clearRoom(); + _vm->_midi->loadMusic(47, 8); + + _vm->_sound->freeSounds(); + Resource *sound = _vm->_sound->loadSound(46, 14); + _vm->_sound->_soundTable.push_back(SoundEntry(sound, 1)); + + _vm->_screen->setDisplayScan(); + _vm->_screen->forceFadeOut(); + _vm->_events->hideCursor(); + + _vm->_files->loadScreen(40, 3); + _vm->_buffer1.copyBuffer(_vm->_screen); + _vm->_buffer2.copyBuffer(_vm->_screen); + + _vm->_events->showCursor(); + _vm->_screen->setIconPalette(); + _vm->_screen->forceFadeIn(); + + // Load objects specific to this special scene + Resource *data = _vm->_files->loadFile(40, 2); + _game->_spec7Objects = new SpriteResource(_vm, data); + delete data; + + // Load animation data + _vm->_animation->freeAnimationData(); + Resource *animResource = _vm->_files->loadFile(40, 1); + _vm->_animation->loadAnimations(animResource); + delete animResource; + + // Load script + Resource *newScript = _vm->_files->loadFile(40, 0); + _vm->_scripts->setScript(newScript); + + _vm->_images.clear(); + _vm->_oldRects.clear(); + _vm->_scripts->_sequence = 0; + + _vm->_sound->playSound(0); + + do { + charLoop(); + } while (_vm->_flags[134] != 1); + + do { + _vm->_events->pollEvents(); + } while (!_vm->shouldQuit() && _vm->_sound->_playingSound); + + _game->_numAnimTimers = 0; + _vm->_animation->freeAnimationData(); + _vm->_scripts->freeScriptData(); + _vm->_sound->freeSounds(); + + _vm->_screen->forceFadeOut(); + _vm->_midi->midiPlay(); + _vm->_midi->setLoop(true); + _vm->_events->hideCursor(); + + _vm->_files->loadScreen(40, 4); + _vm->_buffer1.copyBuffer(_vm->_screen); + _vm->_buffer2.copyBuffer(_vm->_screen); + + _vm->_events->showCursor(); + _vm->_screen->setIconPalette(); + _vm->_screen->forceFadeIn(); + + // Setup fonts + _vm->_fonts._charSet._hi = 10; + _vm->_fonts._charSet._lo = 1; + _vm->_fonts._charFor._lo = 247; + _vm->_fonts._charFor._hi = 255; + _vm->_screen->_maxChars = 50; + _vm->_screen->_printOrg = Common::Point(24, 18); + _vm->_screen->_printStart = Common::Point(24, 18); + + // Display death message + _game->showDeathText(Common::String(SPEC7MESSAGE)); + + _vm->_events->showCursor(); + _vm->_screen->copyBuffer(&_vm->_buffer1); + _vm->_events->hideCursor(); + + _vm->_video->setVideo(_vm->_screen, Common::Point(120, 16), FileIdent(40, 5), 10); + + while (!_vm->shouldQuit() && !_vm->_video->_videoEnd) { + _vm->_video->playVideo(); + _vm->_events->pollEventsAndWait(); + } + + _vm->_sound->freeSounds(); + sound = _vm->_sound->loadSound(40, 8); + _vm->_sound->_soundTable.push_back(SoundEntry(sound, 1)); + sound = _vm->_sound->loadSound(40, 9); + _vm->_sound->_soundTable.push_back(SoundEntry(sound, 1)); + sound = _vm->_sound->loadSound(40, 10); + _vm->_sound->_soundTable.push_back(SoundEntry(sound, 1)); + + _vm->_screen->forceFadeOut(); + _vm->_files->loadScreen(40, 7); + _vm->_destIn = _vm->_screen; + + _vm->_screen->plotImage(_game->_spec7Objects, 8, Common::Point(104, 176)); + _vm->_screen->plotImage(_game->_spec7Objects, 7, Common::Point(102, 160)); + _vm->_events->showCursor(); + _vm->_screen->forceFadeIn(); + + _vm->_events->_vbCount = 100; + while (!_vm->shouldQuit() && _vm->_events->_vbCount > 0) + _vm->_events->pollEventsAndWait(); + + _vm->_sound->playSound(0); + do { + _vm->_events->pollEvents(); + } while (!_vm->shouldQuit() && _vm->_sound->_playingSound); + + _vm->_events->_vbCount = 80; + while (!_vm->shouldQuit() && _vm->_events->_vbCount > 0) + _vm->_events->pollEventsAndWait(); + + _vm->_sound->playSound(1); + do { + _vm->_events->pollEvents(); + } while (!_vm->shouldQuit() && _vm->_sound->_playingSound); + + _vm->_events->_vbCount = 80; + while (!_vm->shouldQuit() && _vm->_events->_vbCount > 0) + _vm->_events->pollEventsAndWait(); + + _vm->_sound->playSound(2); + do { + _vm->_events->pollEvents(); + } while (!_vm->shouldQuit() && _vm->_sound->_playingSound); + + _vm->_sound->freeSounds(); + + delete _game->_spec7Objects; + _game->_spec7Objects = nullptr; + + _vm->_events->hideCursor(); + _vm->_screen->forceFadeOut(); + _vm->_files->loadScreen(40, 6); + _vm->_events->showCursor(); + _vm->_screen->forceFadeIn(); + + _vm->_events->waitKeyMouse(); + _vm->_midi->stopSong(); + _vm->_midi->freeMusic(); + + // The original was jumping to the restart label in main + _vm->_restartFl = true; + _vm->_events->pollEvents(); +} + void MartianScripts::executeSpecial(int commandIndex, int param1, int param2) { + switch (commandIndex) { + case 0: + cmdSpecial0(); + break; + case 1: + cmdSpecial1(param1); + break; + case 2: + warning("TODO: cmdSpecial2"); + break; + case 3: + cmdSpecial3(); + break; + case 4: + warning("TODO: cmdSpecial4"); + break; + case 5: + doIntro(param1); + break; + case 6: + cmdSpecial6(); + break; + case 7: + cmdSpecial7(); + break; + default: + warning("Unexpected Special code %d - Skipped", commandIndex); + } } typedef void(MartianScripts::*MartianScriptMethodPtr)(); diff --git a/engines/access/martian/martian_scripts.h b/engines/access/martian/martian_scripts.h index fc7495fc47..9c2141276e 100644 --- a/engines/access/martian/martian_scripts.h +++ b/engines/access/martian/martian_scripts.h @@ -35,9 +35,18 @@ class MartianEngine; class MartianScripts : public Scripts { private: MartianEngine *_game; + + void cmdSpecial0(); + void cmdSpecial1(int param1); + void cmdSpecial3(); + void doIntro(int param1); + void cmdSpecial6(); + void cmdSpecial7(); + protected: virtual void executeSpecial(int commandIndex, int param1, int param2); virtual void executeCommand(int commandIndex); + public: MartianScripts(AccessEngine *vm); }; diff --git a/engines/access/module.mk b/engines/access/module.mk index b6961aeca9..f7cf7f2261 100644 --- a/engines/access/module.mk +++ b/engines/access/module.mk @@ -28,6 +28,7 @@ MODULE_OBJS := \ amazon/amazon_room.o \ amazon/amazon_scripts.o \ martian/martian_game.o \ + martian/martian_player.o \ martian/martian_resources.o \ martian/martian_room.o \ martian/martian_scripts.o diff --git a/engines/access/player.cpp b/engines/access/player.cpp index 5a2b98293f..ead24025a2 100644 --- a/engines/access/player.cpp +++ b/engines/access/player.cpp @@ -26,24 +26,25 @@ #include "access/access.h" #include "access/resources.h" #include "access/amazon/amazon_player.h" +#include "access/martian/martian_player.h" namespace Access { Player *Player::init(AccessEngine *vm) { switch (vm->getGameID()) { case GType_Amazon: + vm->_playerDataCount = 8; return new Amazon::AmazonPlayer(vm); + case GType_MartianMemorandum: + vm->_playerDataCount = 10; + return new Martian::MartianPlayer(vm); default: + vm->_playerDataCount = 8; return new Player(vm); } } Player::Player(AccessEngine *vm) : Manager(vm), ImageEntry() { - Common::fill(&_walkOffRight[0], &_walkOffRight[PLAYER_DATA_COUNT], 0); - Common::fill(&_walkOffLeft[0], &_walkOffLeft[PLAYER_DATA_COUNT], 0); - Common::fill(&_walkOffUp[0], &_walkOffUp[PLAYER_DATA_COUNT], 0); - Common::fill(&_walkOffDown[0], &_walkOffDown[PLAYER_DATA_COUNT], 0); - _playerSprites = nullptr; _playerSprites1 = nullptr; _manPal1 = nullptr; @@ -78,14 +79,36 @@ Player::Player(AccessEngine *vm) : Manager(vm), ImageEntry() { _downWalkMin = _downWalkMax = 0; _diagUpWalkMin = _diagUpWalkMax = 0; _diagDownWalkMin = _diagDownWalkMax = 0; + _walkOffRight = _walkOffLeft = nullptr; + _walkOffUp = _walkOffDown = nullptr; + _walkOffUR = _walkOffDR = nullptr; + _walkOffUL = _walkOffDL = nullptr; } Player::~Player() { delete _playerSprites; delete[] _manPal1; + delete[] _walkOffRight; + delete[] _walkOffLeft; + delete[] _walkOffUp; + delete[] _walkOffDown; + delete[] _walkOffUR; + delete[] _walkOffDR; + delete[] _walkOffUL; + delete[] _walkOffDL; } void Player::load() { + int dataCount = _vm->_playerDataCount; + _walkOffRight = new int[dataCount]; + _walkOffLeft = new int[dataCount]; + _walkOffUp = new int[dataCount]; + _walkOffDown = new int[dataCount]; + _walkOffUR = new Common::Point[dataCount]; + _walkOffDR = new Common::Point[dataCount]; + _walkOffUL = new Common::Point[dataCount]; + _walkOffDL = new Common::Point[dataCount]; + _playerOffset.x = _vm->_screen->_scaleTable1[25]; _playerOffset.y = _vm->_screen->_scaleTable1[67]; _leftDelta = -3; @@ -94,21 +117,6 @@ void Player::load() { _downDelta = -10; _scrollConst = 5; - for (int i = 0; i < PLAYER_DATA_COUNT; ++i) { - _walkOffRight[i] = SIDEOFFR[i]; - _walkOffLeft[i] = SIDEOFFL[i]; - _walkOffUp[i] = SIDEOFFU[i]; - _walkOffDown[i] = SIDEOFFD[i]; - _walkOffUR[i].x = DIAGOFFURX[i]; - _walkOffUR[i].y = DIAGOFFURY[i]; - _walkOffDR[i].x = DIAGOFFDRX[i]; - _walkOffDR[i].y = DIAGOFFDRY[i]; - _walkOffUL[i].x = DIAGOFFULX[i]; - _walkOffUL[i].y = DIAGOFFULY[i]; - _walkOffDL[i].x = DIAGOFFDLX[i]; - _walkOffDL[i].y = DIAGOFFDLY[i]; - } - _sideWalkMin = 0; _sideWalkMax = 7; _upWalkMin = 16; @@ -122,16 +130,35 @@ void Player::load() { _playerSprites = _playerSprites1; if (_manPal1) { - Common::copy(_manPal1 + 0x270, _manPal1 + 0x270 + 0x60, _vm->_screen->_manPal); + // Those values are from MM as Amazon doesn't use it + Common::copy(_manPal1 + 0x2A0, _manPal1 + 0x2A0 + 0x42, _vm->_screen->_manPal); } else { Common::fill(_vm->_screen->_manPal, _vm->_screen->_manPal + 0x60, 0); } } +void Player::loadTexPalette() { + Resource *_texPal = _vm->_files->loadFile("TEXPAL.COL"); + int size = _texPal->_size; + assert(size == 768); + _manPal1 = new byte[size]; + memcpy(_manPal1, _texPal->data(), size); +} + void Player::loadSprites(const Common::String &name) { freeSprites(); Resource *data = _vm->_files->loadFile(name); + +#if 0 + Common::DumpFile *outFile = new Common::DumpFile(); + Common::String outName = name + ".dump"; + outFile->open(outName); + outFile->write(data->data(), data->_size); + outFile->finalize(); + outFile->close(); +#endif + _playerSprites1 = new SpriteResource(_vm, data); delete data; } @@ -357,7 +384,7 @@ void Player::walkRight() { if (_frame > _sideWalkMax) _frame = _sideWalkMin; - plotCom(0); + plotCom0(); } } @@ -634,15 +661,19 @@ void Player::checkMove() { } void Player::plotCom(int flags) { - _flags &= ~2; - _flags &= ~8; + _flags &= ~IMGFLAG_BACKWARDS; + _flags &= ~IMGFLAG_UNSCALED; _flags |= flags; plotCom3(); } +void Player::plotCom0() { + plotCom(_vm->getGameID() == GType_Amazon ? 0 : IMGFLAG_BACKWARDS); +} + void Player::plotCom1() { - plotCom(2); + plotCom(_vm->getGameID() == GType_Amazon ? IMGFLAG_BACKWARDS : 0); } void Player::plotCom2() { @@ -709,8 +740,12 @@ void Player::checkScroll() { } } -bool Player::scrollUp() { - _scrollAmount = -(_vm->_screen->_clipHeight - _playerY - _scrollThreshold); +bool Player::scrollUp(int forcedAmount) { + if (forcedAmount == -1) + _scrollAmount = -(_vm->_screen->_clipHeight - _playerY - _scrollThreshold); + else + _scrollAmount = forcedAmount; + if ((_vm->_scrollRow + _vm->_screen->_vWindowHeight) >= _vm->_room->_playFieldHeight) return true; @@ -737,8 +772,12 @@ bool Player::scrollUp() { return false; } -bool Player::scrollDown() { - _scrollAmount = -(_playerY - _scrollThreshold); +bool Player::scrollDown(int forcedAmount) { + if (forcedAmount == -1) + _scrollAmount = -(_playerY - _scrollThreshold); + else + _scrollAmount = forcedAmount; + _scrollFlag = true; _vm->_scrollY -= _scrollAmount; if (_vm->_scrollY >= 0) @@ -762,9 +801,13 @@ bool Player::scrollDown() { return true; } -bool Player::scrollLeft() { +bool Player::scrollLeft(int forcedAmount) { Screen &screen = *_vm->_screen; - _scrollAmount = -(_vm->_screen->_clipWidth - _playerX - _scrollThreshold); + if (forcedAmount == -1) + _scrollAmount = -(_vm->_screen->_clipWidth - _playerX - _scrollThreshold); + else + _scrollAmount = forcedAmount; + if ((_vm->_scrollCol + screen._vWindowWidth) == _vm->_room->_playFieldWidth) { _scrollEnd = 2; _vm->_scrollX = 0; @@ -789,8 +832,12 @@ bool Player::scrollLeft() { } } -bool Player::scrollRight() { - _scrollAmount = -(_playerX - _scrollThreshold); +bool Player::scrollRight(int forcedAmount) { + if (forcedAmount == -1) + _scrollAmount = -(_playerX - _scrollThreshold); + else + _scrollAmount = forcedAmount; + _scrollFlag = true; _vm->_scrollX -= _scrollAmount; diff --git a/engines/access/player.h b/engines/access/player.h index 329cc15ed2..3c554556dd 100644 --- a/engines/access/player.h +++ b/engines/access/player.h @@ -31,8 +31,6 @@ namespace Access { -#define PLAYER_DATA_COUNT 8 - enum Direction { NONE = 0, UP = 1, @@ -58,11 +56,11 @@ protected: int _diagUpWalkMin, _diagUpWalkMax; int _diagDownWalkMin, _diagDownWalkMax; SpriteResource *_playerSprites1; - byte *_manPal1; int _scrollEnd; int _inactiveYOff; void plotCom(int v1); + void plotCom0(); void plotCom1(); void plotCom2(); void plotCom3(); @@ -76,22 +74,19 @@ protected: void walkUpRight(); void walkDownRight(); void checkScrollUp(); - bool scrollUp(); - bool scrollDown(); - bool scrollLeft(); - bool scrollRight(); public: Direction _playerDirection; SpriteResource *_playerSprites; // Fields in original Player structure - int _walkOffRight[PLAYER_DATA_COUNT]; - int _walkOffLeft[PLAYER_DATA_COUNT]; - int _walkOffUp[PLAYER_DATA_COUNT]; - int _walkOffDown[PLAYER_DATA_COUNT]; - Common::Point _walkOffUR[PLAYER_DATA_COUNT]; - Common::Point _walkOffDR[PLAYER_DATA_COUNT]; - Common::Point _walkOffUL[PLAYER_DATA_COUNT]; - Common::Point _walkOffDL[PLAYER_DATA_COUNT]; + byte *_manPal1; + int *_walkOffRight; + int *_walkOffLeft; + int *_walkOffUp; + int *_walkOffDown; + Common::Point *_walkOffUR; + Common::Point *_walkOffDR; + Common::Point *_walkOffUL; + Common::Point *_walkOffDL; byte _rawTempL; int _rawXTemp; byte _rawYTempL; @@ -125,6 +120,8 @@ public: virtual void load(); + void loadTexPalette(); + void loadSprites(const Common::String &name); void freeSprites(); @@ -137,6 +134,10 @@ public: void calcPlayer(); + bool scrollUp(int forcedAmount = -1); + bool scrollDown(int forcedAmount = -1); + bool scrollLeft(int forcedAmount = -1); + bool scrollRight(int forcedAmount = -1); void checkScroll(); void checkMove(); diff --git a/engines/access/resources.cpp b/engines/access/resources.cpp index 04948404d0..8699a4a82f 100644 --- a/engines/access/resources.cpp +++ b/engines/access/resources.cpp @@ -46,24 +46,6 @@ const byte INITIAL_PALETTE[18 * 3] = { 0x00, 0x00, 0x00 }; -const int SIDEOFFR[] = { 5, 5, 5, 5, 5, 5, 5, 5, 0 }; -const int SIDEOFFL[] = { 5, 5, 5, 5, 5, 5, 5, 5, 0 }; -const int SIDEOFFU[] = { 2, 2, 2, 2, 2, 2, 2, 2, 0 }; -const int SIDEOFFD[] = { 2, 2, 2, 2, 2, 2, 2, 2, 0 }; -const int DIAGOFFURX[] = { 4, 5, 2, 2, 3, 4, 2, 2, 0 }; -const int DIAGOFFURY[] = { 2, 3, 2, 2, 2, 3, 1, 1, 0 }; -const int DIAGOFFDRX[] = { 4, 5, 4, 3, 5, 4, 5, 1, 0 }; -const int DIAGOFFDRY[] = { 3, 2, 1, 2, 2, 1, 2, 1, 0 }; -const int DIAGOFFULX[] = { 4, 5, 4, 3, 3, 2, 2, 2, 0 }; -const int DIAGOFFULY[] = { 3, 3, 1, 2, 2, 1, 1, 1, 0 }; -const int DIAGOFFDLX[] = { 4, 5, 3, 3, 5, 4, 6, 1, 0 }; -const int DIAGOFFDLY[] = { 2, 2, 1, 2, 3, 1, 2, 1, 0 }; - -const int RMOUSE[10][2] = { - { 0, 35 }, { 0, 0 }, { 36, 70 }, { 71, 106 }, { 107, 141 }, - { 142, 177 }, { 178, 212 }, { 213, 248 }, { 249, 283 }, { 284, 318 } -}; - const char *const GENERAL_MESSAGES[] = { "LOOKING THERE REVEALS NOTHING OF INTEREST.", // LOOK_MESSAGE "THAT DOESN'T OPEN.", // OPEN_MESSAGE diff --git a/engines/access/resources.h b/engines/access/resources.h index 8d59b1b1f1..07b8e5ada9 100644 --- a/engines/access/resources.h +++ b/engines/access/resources.h @@ -29,21 +29,6 @@ namespace Access { extern const byte INITIAL_PALETTE[18 * 3]; -extern const int SIDEOFFR[]; -extern const int SIDEOFFL[]; -extern const int SIDEOFFU[]; -extern const int SIDEOFFD[]; -extern const int DIAGOFFURX[]; -extern const int DIAGOFFURY[]; -extern const int DIAGOFFDRX[]; -extern const int DIAGOFFDRY[]; -extern const int DIAGOFFULX[]; -extern const int DIAGOFFULY[]; -extern const int DIAGOFFDLX[]; -extern const int DIAGOFFDLY[]; - -extern const int RMOUSE[10][2]; - extern const char *const GENERAL_MESSAGES[]; extern const int INVCOORDS[][4]; diff --git a/engines/access/room.cpp b/engines/access/room.cpp index 607259ec6f..46e8d2c8d8 100644 --- a/engines/access/room.cpp +++ b/engines/access/room.cpp @@ -38,6 +38,23 @@ Room::Room(AccessEngine *vm) : Manager(vm) { _selectCommand = 0; _conFlag = false; _selectCommand = -1; + + switch (vm->getGameID()) { + case GType_Amazon: + for (int i = 0; i < 10; i++) { + _rMouse[i][0] = Amazon::RMOUSE[i][0]; + _rMouse[i][1] = Amazon::RMOUSE[i][1]; + } + break; + case GType_MartianMemorandum: + for (int i = 0; i < 10; i++) { + _rMouse[i][0] = Martian::RMOUSE[i][0]; + _rMouse[i][1] = Martian::RMOUSE[i][1]; + } + break; + default: + error("Game not supported"); + } } Room::~Room() { @@ -55,6 +72,91 @@ void Room::freeTileData() { _tile = nullptr; } +void Room::clearCamera() { + _vm->_player->_scrollFlag = true; + _vm->_events->hideCursor(); + + _vm->_screen->_orgX1 = 48; + _vm->_screen->_orgY1 = 24; + _vm->_screen->_orgX2 = 274; + _vm->_screen->_orgY2 = 152; + _vm->_screen->_lColor = 0; + _vm->_screen->drawRect(); + + _vm->_events->showCursor(); + + _vm->_events->_vbCount = 4; + while (!_vm->shouldQuit() && _vm->_events->_vbCount > 0) + _vm->_events->pollEventsAndWait(); +} + +void Room::takePicture() { + _vm->_events->pollEvents(); + if (!_vm->_events->_leftButton) + return; + + Common::Array<Common::Rect> pictureCoords; + for (int i = 0; Martian::PICTURERANGE[i][0] != -1; i += 2) { + pictureCoords.push_back(Common::Rect(Martian::PICTURERANGE[i][0], Martian::PICTURERANGE[i + 1][0], + Martian::PICTURERANGE[i][1], Martian::PICTURERANGE[i + 1][1])); + } + + int result = _vm->_events->checkMouseBox1(pictureCoords); + + if (result == 4) { + _vm->_events->debounceLeft(); + if (_vm->_inventory->_inv[44]._value != ITEM_IN_INVENTORY) { + Common::String msg = "YOU HAVE NO MORE FILM."; + _vm->_scripts->doCmdPrint_v1(msg); + return; + } + + // TODO: simplify the second part of the test when tested + if ((_vm->_scrollCol < 35) || ((_vm->_scrollRow >= 10) && (_vm->_scrollRow >= 20))){ + Common::String msg = "THAT ISN'T INTERESTING ENOUGH TO WASTE FILM ON."; + _vm->_scripts->doCmdPrint_v1(msg); + return; + } + + if (_vm->_inventory->_inv[26]._value != ITEM_USED) { + Common::String msg = "ALTHOUGH IT WOULD MAKE A NICE PICTURE, YOU MAY FIND SOMETHING MORE INTERESTING TO USE YOUR FILM ON."; + _vm->_scripts->doCmdPrint_v1(msg); + return; + } + + Common::String msg = "THAT PHOTO MAY COME IN HANDY SOME DAY."; + _vm->_scripts->doCmdPrint_v1(msg); + _vm->_inventory->_inv[8]._value = ITEM_IN_INVENTORY; + _vm->_pictureTaken++; + if (_vm->_pictureTaken == 16) + _vm->_inventory->_inv[44]._value = ITEM_USED; + + _vm->_events->debounceLeft(); + _vm->_sound->playSound(0); + clearCamera(); + return; + } else if (result == 5) { + if (_vm->_flags[26] != 2) { + _vm->_video->closeVideo(); + _vm->_video->_videoEnd = true; + } + _vm->_player->_roomNumber = 7; + _vm->_room->_function = FN_CLEAR1; + return; + } else if (result >= 0) + _vm->_player->_move = (Direction)(result + 1); + + _vm->_player->_scrollFlag = false; + if (_vm->_player->_move == UP) + _vm->_player->scrollDown(2); + else if (_vm->_player->_move == DOWN) + _vm->_player->scrollUp(2); + else if (_vm->_player->_move == LEFT) + _vm->_player->scrollRight(2); + else if (_vm->_player->_move == RIGHT) + _vm->_player->scrollLeft(2); +} + void Room::doRoom() { bool reloadFlag = false; @@ -84,9 +186,13 @@ void Room::doRoom() { _vm->_events->pollEventsAndWait(); _vm->_canSaveLoad = false; - _vm->_player->walk(); - _vm->_midi->midiRepeat(); - _vm->_player->checkScroll(); + if ((_vm->getGameID() == GType_MartianMemorandum) && (_vm->_player->_roomNumber == 47)) { + takePicture(); + } else { + _vm->_player->walk(); + _vm->_midi->midiRepeat(); + _vm->_player->checkScroll(); + } doCommands(); if (_vm->shouldQuitOrRestart()) @@ -136,7 +242,8 @@ void Room::doRoom() { } else { _vm->plotList(); - if (_vm->_events->_mousePos.y < 177) + if (((_vm->getGameID() == GType_MartianMemorandum) && (_vm->_events->_mousePos.y < 184)) || + ((_vm->getGameID() == GType_Amazon) && (_vm->_events->_mousePos.y < 177))) _vm->_events->setCursor(_vm->_events->_normalMouse); else _vm->_events->setCursor(CURSOR_ARROW); @@ -173,8 +280,8 @@ void Room::loadRoomData(const byte *roomData) { _vm->_establishFlag = false; if (roomInfo._estIndex != -1) { _vm->_establishFlag = true; - if (_vm->_establishTable[roomInfo._estIndex] != 1) { - _vm->_establishTable[roomInfo._estIndex] = 1; + if (!_vm->_establishTable[roomInfo._estIndex]) { + _vm->_establishTable[roomInfo._estIndex] = true; _vm->establish(0, roomInfo._estIndex); } } @@ -455,8 +562,8 @@ void Room::doCommands() { if (_vm->_events->_mouseRow >= 22) { // Mouse in user interface area for (commandId = 0; commandId < 10; ++commandId) { - if (_vm->_events->_mousePos.x >= RMOUSE[commandId][0] && - _vm->_events->_mousePos.x < RMOUSE[commandId][1]) + if (_vm->_events->_mousePos.x >= _rMouse[commandId][0] && + _vm->_events->_mousePos.x < _rMouse[commandId][1]) break; } if (commandId < 10) @@ -489,9 +596,6 @@ void Room::cycleCommand(int incr) { } void Room::handleCommand(int commandId) { - if (commandId == 1) - --commandId; - if (commandId == 9) { _vm->_events->debounceLeft(); _vm->_canSaveLoad = true; @@ -510,41 +614,92 @@ void Room::executeCommand(int commandId) { EventsManager &events = *_vm->_events; _selectCommand = commandId; - switch (commandId) { - case 0: - events.forceSetCursor(CURSOR_LOOK); - break; - case 2: - events.forceSetCursor(CURSOR_USE); - break; - case 3: - events.forceSetCursor(CURSOR_TAKE); - break; - case 4: - events.setCursor(CURSOR_ARROW); - if (_vm->_inventory->newDisplayInv() == 2) { - commandOff(); + if (_vm->getGameID() == GType_MartianMemorandum) { + switch (commandId) { + case 4: + events.setCursor(CURSOR_ARROW); + if (_vm->_inventory->displayInv() == 2) { + commandOff(); + return; + } + if (_vm->_useItem == 39) { + if (_vm->_player->_roomNumber == 23) + _vm->_currentMan = 1; + commandOff(); + return; + } else if (_vm->_useItem == 6) { + _vm->_flags[3] = 2; + _vm->_scripts->converse1(24); + + _conFlag = true; + while (_conFlag && !_vm->shouldQuitOrRestart()) { + _conFlag = false; + _vm->_scripts->executeScript(); + } + + _vm->_boxSelect = true; + return; + } + break; + case 7: + walkCursor(); return; + case 8: { + EventsManager &events = *_vm->_events; + + events.forceSetCursor(CURSOR_CROSSHAIRS); + _vm->_scripts->_sequence = 10000; + _vm->_scripts->searchForSequence(); + + _conFlag = true; + while (_conFlag && !_vm->shouldQuitOrRestart()) { + _conFlag = false; + _vm->_scripts->executeScript(); + } + + _vm->_boxSelect = true; + return; + } + default: + // No set cursor in MM. Forcing to CROSSHAIRS + events.setCursor(CURSOR_CROSSHAIRS); + break; + } + } else { + switch (commandId) { + case 0: + case 1: + events.forceSetCursor(CURSOR_LOOK); + break; + case 2: + events.forceSetCursor(CURSOR_USE); + break; + case 3: + events.forceSetCursor(CURSOR_TAKE); + break; + case 4: + events.setCursor(CURSOR_ARROW); + if (_vm->_inventory->newDisplayInv() == 2) { + commandOff(); + return; + } + break; + case 5: + events.forceSetCursor(CURSOR_CLIMB); + break; + case 6: + events.forceSetCursor(CURSOR_TALK); + break; + case 7: + walkCursor(); + return; + case 8: + events.forceSetCursor(CURSOR_HELP); + break; + default: + break; } - break; - case 5: - events.forceSetCursor(CURSOR_CLIMB); - break; - case 6: - events.forceSetCursor(CURSOR_TALK); - break; - case 7: - walkCursor(); - return; - case 8: - events.forceSetCursor(CURSOR_HELP); - break; - default: - break; } - - // Draw the default toolbar menu at the bottom of the screen - roomMenu(); _vm->_screen->saveScreen(); _vm->_screen->setDisplayScan(); @@ -555,7 +710,7 @@ void Room::executeCommand(int commandId) { // Draw the button as selected _vm->_screen->plotImage(spr, _selectCommand + 2, - Common::Point(RMOUSE[_selectCommand][0], 176)); + Common::Point(_rMouse[_selectCommand][0], (_vm->getGameID() == GType_MartianMemorandum) ? 184 : 176)); _vm->_screen->restoreScreen(); _vm->_boxSelect = true; diff --git a/engines/access/room.h b/engines/access/room.h index eec273e3f4..12e7375428 100644 --- a/engines/access/room.h +++ b/engines/access/room.h @@ -72,6 +72,8 @@ private: int calcLR(int yp); int calcUD(int xp); + void takePicture(); + /** * Cycles forwards or backwards through the list of commands */ @@ -103,6 +105,8 @@ protected: */ void executeCommand(int commandId); + void clearCamera(); + virtual void reloadRoom() = 0; virtual void reloadRoom1() = 0; @@ -126,6 +130,7 @@ public: byte *_tile; int _selectCommand; bool _conFlag; + int _rMouse[10][2]; public: Room(AccessEngine *vm); diff --git a/engines/access/screen.cpp b/engines/access/screen.cpp index 2ecbb4f430..9392decead 100644 --- a/engines/access/screen.cpp +++ b/engines/access/screen.cpp @@ -113,6 +113,16 @@ void Screen::setInitialPalettte() { g_system->getPaletteManager()->setPalette(INITIAL_PALETTE, 0, 18); } +void Screen::setManPalette() { + Common::copy(_vm->_screen->_manPal, _vm->_screen->_manPal + 0x42, _rawPalette + 672); +} + +void Screen::setIconPalette() { + if (_vm->getGameID() == GType_MartianMemorandum) { + Common::copy(Martian::ICON_DATA, Martian::ICON_DATA + 0x1B, _rawPalette + 741); + } +} + void Screen::loadPalette(int fileNum, int subfile) { Resource *res = _vm->_files->loadFile(fileNum, subfile); byte *palette = res->data(); @@ -267,6 +277,11 @@ void Screen::drawRect() { ASurface::drawRect(); } +void Screen::drawBox() { + addDirtyRect(Common::Rect(_orgX1, _orgY1, _orgX2, _orgY2)); + ASurface::drawBox(); +} + void Screen::transBlitFrom(ASurface *src, const Common::Point &destPos) { addDirtyRect(Common::Rect(destPos.x, destPos.y, destPos.x + src->w, destPos.y + src->h)); ASurface::transBlitFrom(src, destPos); @@ -322,6 +337,10 @@ void Screen::cyclePaletteBackwards() { } } +void Screen::flashPalette(int count) { + warning("TODO: Implement flashPalette"); +} + void Screen::addDirtyRect(const Common::Rect &r) { _dirtyRects.push_back(r); assert(r.isValidRect() && r.width() > 0 && r.height() > 0); diff --git a/engines/access/screen.h b/engines/access/screen.h index d45a533f9a..52485e5c7c 100644 --- a/engines/access/screen.h +++ b/engines/access/screen.h @@ -92,6 +92,8 @@ public: virtual void drawRect(); + virtual void drawBox(); + virtual void transBlitFrom(ASurface *src, const Common::Point &destPos); virtual void transBlitFrom(ASurface *src, const Common::Rect &bounds); @@ -137,7 +139,12 @@ public: /** * Set icon palette */ - void setIconPalette() {} + void setIconPalette(); + + /** + * Set Tex palette (Martian Memorandum) + */ + void setManPalette(); void loadPalette(int fileNum, int subfile); @@ -151,6 +158,8 @@ public: void getPalette(byte *pal); + void flashPalette(int count); + /** * Copy a buffer to the screen */ diff --git a/engines/access/scripts.cpp b/engines/access/scripts.cpp index 1bd24894d7..b20189049e 100644 --- a/engines/access/scripts.cpp +++ b/engines/access/scripts.cpp @@ -39,12 +39,101 @@ Scripts::Scripts(AccessEngine *vm) : Manager(vm) { _choiceStart = 0; _charsOrg = Common::Point(0, 0); _texsOrg = Common::Point(0, 0); + setOpcodes(); } Scripts::~Scripts() { freeScriptData(); } +void Scripts::setOpcodes() { + COMMAND_LIST[0] = &Scripts::cmdObject; + COMMAND_LIST[1] = &Scripts::cmdEndObject; + COMMAND_LIST[2] = &Scripts::cmdJumpLook; + COMMAND_LIST[3] = &Scripts::cmdJumpHelp; + COMMAND_LIST[4] = &Scripts::cmdJumpGet; + COMMAND_LIST[5] = &Scripts::cmdJumpMove; + COMMAND_LIST[6] = &Scripts::cmdJumpUse; + COMMAND_LIST[7] = &Scripts::cmdJumpTalk; + COMMAND_LIST[8] = &Scripts::cmdNull; + COMMAND_LIST[9] = &Scripts::cmdPrint_v1; + COMMAND_LIST[10] = &Scripts::cmdRetPos; + COMMAND_LIST[11] = &Scripts::cmdAnim; + COMMAND_LIST[12] = &Scripts::cmdSetFlag; + COMMAND_LIST[13] = &Scripts::cmdCheckFlag; + COMMAND_LIST[14] = &Scripts::cmdGoto; + COMMAND_LIST[15] = &Scripts::cmdAddScore; + COMMAND_LIST[16] = &Scripts::cmdSetInventory; + COMMAND_LIST[17] = &Scripts::cmdCheckInventory; + COMMAND_LIST[18] = &Scripts::cmdSetTex; + COMMAND_LIST[19] = &Scripts::cmdNewRoom; + COMMAND_LIST[20] = &Scripts::cmdConverse; + COMMAND_LIST[21] = &Scripts::cmdCheckFrame; + COMMAND_LIST[22] = &Scripts::cmdCheckAnim; + COMMAND_LIST[23] = &Scripts::cmdSnd; + COMMAND_LIST[24] = &Scripts::cmdRetNeg; + COMMAND_LIST[25] = &Scripts::cmdRetPos; + COMMAND_LIST[26] = &Scripts::cmdCheckLoc; + COMMAND_LIST[27] = &Scripts::cmdSetAnim; + COMMAND_LIST[28] = &Scripts::cmdDispInv_v1; + COMMAND_LIST[29] = &Scripts::cmdSetAbout; + COMMAND_LIST[30] = &Scripts::cmdSetTimer; + COMMAND_LIST[31] = &Scripts::cmdCheckTimer; + COMMAND_LIST[32] = &Scripts::cmdSetTravel; + COMMAND_LIST[33] = &Scripts::cmdJumpGoto; + COMMAND_LIST[34] = &Scripts::cmdSetVideo; + COMMAND_LIST[35] = &Scripts::cmdPlayVideo; + COMMAND_LIST[36] = &Scripts::cmdPlotImage; + COMMAND_LIST[37] = &Scripts::cmdSetDisplay; + COMMAND_LIST[38] = &Scripts::cmdSetBuffer; + COMMAND_LIST[39] = &Scripts::cmdSetScroll; + COMMAND_LIST[40] = &Scripts::cmdSaveRect; + COMMAND_LIST[41] = &Scripts::cmdVideoEnded; + COMMAND_LIST[42] = &Scripts::cmdSetBufVid; + COMMAND_LIST[43] = &Scripts::cmdPlayBufVid; + COMMAND_LIST[44] = &Scripts::cmdRemoveLast; + COMMAND_LIST[45] = &Scripts::cmdDoTravel; + COMMAND_LIST[46] = &Scripts::cmdCheckAbout; + COMMAND_LIST[47] = &Scripts::cmdSpecial; + COMMAND_LIST[48] = &Scripts::cmdSetCycle; + COMMAND_LIST[49] = &Scripts::cmdCycle; + COMMAND_LIST[50] = &Scripts::cmdCharSpeak; + COMMAND_LIST[51] = &Scripts::cmdTexSpeak; + COMMAND_LIST[52] = &Scripts::cmdTexChoice; + COMMAND_LIST[53] = &Scripts::cmdWait; + COMMAND_LIST[54] = &Scripts::cmdSetConPos; + COMMAND_LIST[55] = &Scripts::cmdCheckVFrame; + COMMAND_LIST[56] = &Scripts::cmdJumpChoice; + COMMAND_LIST[57] = &Scripts::cmdReturnChoice; + COMMAND_LIST[58] = &Scripts::cmdClearBlock; + COMMAND_LIST[59] = &Scripts::cmdLoadSound; + COMMAND_LIST[60] = &Scripts::cmdFreeSound; + COMMAND_LIST[61] = &Scripts::cmdSetVideoSound; + COMMAND_LIST[62] = &Scripts::cmdPlayVideoSound; + COMMAND_LIST[63] = &Scripts::cmdPrintWatch; + COMMAND_LIST[64] = &Scripts::cmdDispAbout; + COMMAND_LIST[65] = &Scripts::cmdPushLocation; + COMMAND_LIST[66] = &Scripts::cmdCheckTravel; + COMMAND_LIST[67] = &Scripts::cmdBlock; + COMMAND_LIST[68] = &Scripts::cmdPlayerOff; + COMMAND_LIST[69] = &Scripts::cmdPlayerOn; + COMMAND_LIST[70] = &Scripts::cmdDead; + COMMAND_LIST[71] = &Scripts::cmdFadeOut; + COMMAND_LIST[72] = &Scripts::cmdEndVideo; + COMMAND_LIST[73] = &Scripts::cmdHelp_v1; +} + +void Scripts::setOpcodes_v2() { + COMMAND_LIST[9] = &Scripts::cmdPrint_v2; + COMMAND_LIST[15] = &Scripts::cmdSetInventory; + COMMAND_LIST[28] = &Scripts::cmdDispInv_v2; + COMMAND_LIST[29] = &Scripts::cmdSetTimer; + COMMAND_LIST[32] = &Scripts::cmdJumpGoto; + COMMAND_LIST[40] = &Scripts::cmdVideoEnded; + COMMAND_LIST[45] = COMMAND_LIST[46] = &Scripts::cmdSpecial; + COMMAND_LIST[63] = COMMAND_LIST[64] = COMMAND_LIST[66] = COMMAND_LIST[67] = &Scripts::cmdPushLocation; +} + void Scripts::setScript(Resource *res, bool restartFlag) { _resource = res; _data = res->_stream; @@ -86,6 +175,50 @@ void Scripts::charLoop() { _endFlag = endFlag; } +void Scripts::clearWatch() { + _vm->_events->hideCursor(); + _vm->_screen->_orgX1 = 128; + _vm->_screen->_orgY1 = 57; + _vm->_screen->_orgX2 = 228; + _vm->_screen->_orgY2 = 106; + _vm->_screen->_lColor = 0; + _vm->_screen->drawRect(); + + _vm->_events->showCursor(); +} + +void Scripts::printWatch() { + _vm->_fonts._charSet._lo = 8; + _vm->_fonts._charSet._hi = 2; + _vm->_fonts._charFor._lo = 2; + _vm->_fonts._charFor._hi = 255; + + _vm->_screen->_maxChars = 19; + _vm->_screen->_printOrg = Common::Point(128, 58); + _vm->_screen->_printStart = Common::Point(128, 58); + clearWatch(); + + Common::String msg = readString(); + Common::String line = ""; + int width = 0; + bool lastLine; + do { + lastLine = _vm->_fonts._font2.getLine(msg, _vm->_screen->_maxChars * 6, line, width); + // Draw the text + _vm->_bubbleBox->PRINTSTR(line); + + _vm->_screen->_printOrg.y += 6; + _vm->_screen->_printOrg.x = _vm->_screen->_printStart.x; + + if (_vm->_screen->_printOrg.y == 106) { + _vm->_events->waitKeyMouse(); + clearWatch(); + _vm->_screen->_printOrg.y = _vm->_screen->_printStart.y; + } + } while (!lastLine); + _vm->_events->waitKeyMouse(); +} + void Scripts::findNull() { // No implementation required in ScummVM, the strings in the script files are already skipped by the use of readByte() } @@ -109,37 +242,7 @@ int Scripts::executeScript() { return _returnCode; } -typedef void(Scripts::*ScriptMethodPtr)(); - void Scripts::executeCommand(int commandIndex) { - static const ScriptMethodPtr COMMAND_LIST[] = { - &Scripts::cmdObject, &Scripts::cmdEndObject, &Scripts::cmdJumpLook, - &Scripts::cmdJumpHelp, &Scripts::cmdJumpGet, &Scripts::cmdJumpMove, - &Scripts::cmdJumpUse, &Scripts::cmdJumpTalk, &Scripts::cmdNull, - &Scripts::cmdPrint, &Scripts::cmdRetPos, &Scripts::cmdAnim, - &Scripts::cmdSetFlag, &Scripts::cmdCheckFlag, &Scripts::cmdGoto, - &Scripts::cmdAddScore, &Scripts::cmdSetInventory, &Scripts::cmdCheckInventory, - &Scripts::cmdSetTex, &Scripts::cmdNewRoom, &Scripts::cmdConverse, - &Scripts::cmdCheckFrame, &Scripts::cmdCheckAnim, &Scripts::cmdSnd, - &Scripts::cmdRetNeg, &Scripts::cmdRetPos, &Scripts::cmdCheckLoc, - &Scripts::cmdSetAnim, &Scripts::cmdDispInv, &Scripts::cmdSetAbout, - &Scripts::cmdSetTimer, &Scripts::cmdCheckTimer, &Scripts::cmdSetTravel, - &Scripts::cmdJumpGoto, &Scripts::cmdSetVideo, &Scripts::cmdPlayVideo, - &Scripts::cmdPlotImage, &Scripts::cmdSetDisplay, &Scripts::cmdSetBuffer, - &Scripts::cmdSetScroll, &Scripts::cmdSaveRect, &Scripts::cmdVideoEnded, - &Scripts::cmdSetBufVid, &Scripts::cmdPlayBufVid, &Scripts::cmdRemoveLast, - &Scripts::cmdDoTravel, &Scripts::cmdCheckAbout, &Scripts::cmdSpecial, - &Scripts::cmdSetCycle, &Scripts::cmdCycle, &Scripts::cmdCharSpeak, - &Scripts::cmdTexSpeak, &Scripts::cmdTexChoice, &Scripts::cmdWait, - &Scripts::cmdSetConPos, &Scripts::cmdCheckVFrame, &Scripts::cmdJumpChoice, - &Scripts::cmdReturnChoice, &Scripts::cmdClearBlock, &Scripts::cmdLoadSound, - &Scripts::cmdFreeSound, &Scripts::cmdSetVideoSound, &Scripts::cmdPlayVideoSound, - &Scripts::cmdPrintWatch, &Scripts::cmdDispAbout, &Scripts::cmdPushLocation, - &Scripts::cmdCheckTravel, &Scripts::cmdBlock, &Scripts::cmdPlayerOff, - &Scripts::cmdPlayerOn, &Scripts::cmdDead, &Scripts::cmdFadeOut, - &Scripts::cmdEndVideo - }; - (this->*COMMAND_LIST[commandIndex])(); } @@ -198,18 +301,36 @@ void Scripts::cmdNull() { #define PRINT_TIMER 25 -void Scripts::cmdPrint() { +void Scripts::cmdPrint_v2() { // Get a text line for display Common::String msg = readString(); printString(msg); } -void Scripts::printString(const Common::String &msg) { +void Scripts::doCmdPrint_v1(Common::String msg) { _vm->_screen->_printOrg = Common::Point(20, 42); - _vm->_screen->_printStart = Common::Point(20, 42); - _vm->_timers[PRINT_TIMER]._timer = 50; - _vm->_timers[PRINT_TIMER]._initTm = 50; - ++_vm->_timers[PRINT_TIMER]._flag; + _vm->_screen->_printStart = Common::Point(20, 32); + _vm->_bubbleBox->placeBubble(msg); + _vm->_events->waitKeyMouse(); + _vm->_events->hideCursor(); + _vm->_screen->restoreBlock(); + _vm->_events->showCursor(); + findNull(); +} + +void Scripts::cmdPrint_v1() { + Common::String msg = readString(); + doCmdPrint_v1(msg); +} + +void Scripts::printString(const Common::String &msg) { + if (_vm->getGameID() != GType_MartianMemorandum) { + _vm->_screen->_printOrg = Common::Point(20, 42); + _vm->_screen->_printStart = Common::Point(20, 42); + _vm->_timers[PRINT_TIMER]._timer = 50; + _vm->_timers[PRINT_TIMER]._initTm = 50; + ++_vm->_timers[PRINT_TIMER]._flag; + } // Display the text in a bubble, and wait for a keypress or mouse click _vm->_bubbleBox->placeBubble(msg); @@ -268,11 +389,6 @@ void Scripts::cmdGoto() { } void Scripts::cmdAddScore() { - if (!_vm->isDemo()) { - cmdSetInventory(); - return; - } - _data->skip(1); } @@ -338,8 +454,8 @@ void Scripts::cmdNewRoom() { cmdRetPos(); } -void Scripts::cmdConverse() { - _vm->_conversation = _data->readUint16LE(); +void Scripts::converse1(int val) { + _vm->_conversation = val; _vm->_room->clearRoom(); _vm->freeChar(); _vm->_char->loadChar(_vm->_conversation); @@ -355,6 +471,11 @@ void Scripts::cmdConverse() { } } +void Scripts::cmdConverse() { + int val = _data->readUint16LE(); + converse1(val); +} + void Scripts::cmdCheckFrame() { int id = _data->readUint16LE(); Animation *anim = _vm->_animation->findAnimation(id); @@ -409,17 +530,19 @@ void Scripts::cmdSetAnim() { _vm->_animation->setAnimTimer(anim); } -void Scripts::cmdDispInv() { +void Scripts::cmdDispInv_v1() { + _vm->_inventory->displayInv(); +} + +void Scripts::cmdDispInv_v2() { _vm->_inventory->newDisplayInv(); } void Scripts::cmdSetAbout() { - if (!_vm->isDemo()) { - cmdSetTimer(); - return; - } - - error("TODO: DEMO - cmdSetAbout"); + int idx = _data->readByte(); + int val = _data->readByte(); + _vm->ASK[idx] = val; + _vm->_startAboutBox = _vm->_startAboutItem = 0; } void Scripts::cmdSetTimer() { @@ -461,11 +584,10 @@ void Scripts::cmdCheckTimer() { } void Scripts::cmdSetTravel() { - if (!_vm->isDemo()) { - cmdJumpGoto(); - return; - } - error("TODO: DEMO - cmdSetTravel"); + int idx = _data->readByte(); + int dest = _data->readByte(); + _vm->TRAVEL[idx] = dest; + _vm->STARTTRAVELITEM = _vm->STARTTRAVELBOX = 0; } void Scripts::cmdJumpGoto() { @@ -517,11 +639,11 @@ void Scripts::cmdSetScroll() { } void Scripts::cmdSaveRect() { - if (!_vm->isDemo()) { - cmdVideoEnded(); - return; - } - error("TODO: DEMO - cmdSaveRect"); + int x = _vm->_screen->_lastBoundsX; + int y = _vm->_screen->_lastBoundsY; + int w = _vm->_screen->_lastBoundsW; + int h = _vm->_screen->_lastBoundsH; + _vm->_newRects.push_back(Common::Rect(x, y, x + w, x + h)); } void Scripts::cmdVideoEnded() { @@ -553,19 +675,81 @@ void Scripts::cmdRemoveLast() { } void Scripts::cmdDoTravel() { - if (!_vm->isDemo()) { - cmdSpecial(); + while (true) { + _vm->_travelBox->getList(Martian::TRAVDATA, _vm->TRAVEL); + int btnSelected = 0; + int boxX = _vm->_travelBox->doBox_v1(_vm->STARTTRAVELITEM, _vm->STARTTRAVELBOX, btnSelected); + _vm->STARTTRAVELITEM = _vm->BOXDATASTART; + _vm->STARTTRAVELBOX = _vm->BOXSELECTY; + + if (boxX == -1) + btnSelected = 2; + + if (btnSelected != 2) { + int idx = _vm->_travelBox->_tempListIdx[boxX]; + if (Martian::_byte1EEB5[idx] != _vm->_byte26CB5) { + _vm->_bubbleBox->_bubbleTitle = "TRAVEL"; + _vm->_bubbleBox->PRINTSTR("YOU CAN'T GET THERE FROM HERE."); + continue; + } + if (_vm->_player->_roomNumber != idx) { + _vm->_player->_roomNumber = idx; + _vm->_room->_function = FN_CLEAR1; + if (Martian::TRAVEL_POS[idx][0] == -1) { + _vm->_player->_roomNumber = idx; + _vm->_room->_conFlag = true; + _vm->_scripts->converse1(Martian::TRAVEL_POS[idx][1]); + return; + } + _vm->_player->_rawPlayer = Common::Point(Martian::TRAVEL_POS[idx][0], Martian::TRAVEL_POS[idx][1]); + cmdRetPos(); + return; + } + } + + if (_vm->_player->_roomNumber == -1) + continue; + return; } - error("TODO: DEMO - cmdDoTravel"); } -void Scripts::cmdCheckAbout() { - if (!_vm->isDemo()) { - cmdSpecial(); - return; +void Scripts::cmdHelp_v1() { + int idx = 0; + for (int i = 0; i < 40; i++) { + byte c = _data->readByte(); + if (c != 0xFF) { + Common::String tmpStr = c + readString(); + if (Martian::HELP[i]) { + _vm->_helpBox->_tempList[idx] = tmpStr; + _vm->_helpBox->_tempListIdx[idx] = i; + ++idx; + } + } else + break; } - error("TODO: DEMO - cmdCheckAbout"); + _vm->_helpBox->_tempList[idx] = ""; + + int btnSelected = 0; + int boxX = _vm->_helpBox->doBox_v1(0, 0, btnSelected); + + if (boxX == -1) + btnSelected = 2; + + if (btnSelected != 2) + _vm->_useItem = _vm->_helpBox->_tempListIdx[boxX]; + else + _vm->_useItem = -1; +} + +void Scripts::cmdCheckAbout() { + int idx = _data->readSint16LE(); + int val = _data->readSint16LE(); + + if (_vm->ASK[idx] == val) + cmdGoto(); + else + _data->skip(2); } void Scripts::cmdSpecial() { @@ -574,7 +758,7 @@ void Scripts::cmdSpecial() { int p2 = _data->readUint16LE(); if (_specialFunction == 1) { - if (_vm->_establishTable[p2] == 1) + if (_vm->_establishTable[p2]) return; _vm->_screen->savePalette(); @@ -616,33 +800,48 @@ void Scripts::cmdCharSpeak() { void Scripts::cmdTexSpeak() { _vm->_screen->_printOrg = _texsOrg; _vm->_screen->_printStart = _texsOrg; - _vm->_screen->_maxChars = 20; + _vm->_screen->_maxChars = (_vm->getGameID() == GType_MartianMemorandum) ? 23 : 20; byte v; Common::String tmpStr = ""; while ((v = _data->readByte()) != 0) tmpStr += (char)v; - _vm->_bubbleBox->_bubbleDisplStr = Common::String("JASON"); + if (_vm->getGameID() == GType_MartianMemorandum) + _vm->_bubbleBox->_bubbleDisplStr = Common::String("TEX"); + else + _vm->_bubbleBox->_bubbleDisplStr = Common::String("JASON"); + _vm->_bubbleBox->placeBubble1(tmpStr); findNull(); } #define BTN_COUNT 6 void Scripts::cmdTexChoice() { - static const int BTN_RANGES[BTN_COUNT][2] = { - { 0, 76 }, { 77, 154 }, { 155, 232 }, { 233, 276 }, { 0, 0 }, - { 277, 319 } + // MM is defining 2 times the last range in the original. + static const int BTN_RANGES_v1[BTN_COUNT][2] = { + { 0, 60 }, { 64, 124 }, { 129, 192 }, { 194, 227 }, { 233, 292 }, { 297, 319 } + }; + + static const int BTN_RANGES_v2[BTN_COUNT][2] = { + { 0, 76 }, { 77, 154 }, { 155, 232 }, { 233, 276 }, { 0, 0 }, { 277, 319 } }; + _vm->_oldRects.clear(); _choiceStart = _data->pos() - 1; _vm->_fonts._charSet._lo = 1; _vm->_fonts._charSet._hi = 8; - _vm->_fonts._charFor._lo = 55; _vm->_fonts._charFor._hi = 255; + + if (_vm->getGameID() == GType_MartianMemorandum) { + _vm->_fonts._charFor._lo = 247; + _vm->_screen->_maxChars = 23; + } else { + _vm->_fonts._charFor._lo = 55; + _vm->_screen->_maxChars = 20; + } - _vm->_screen->_maxChars = 20; _vm->_screen->_printOrg = _texsOrg; _vm->_screen->_printStart = _texsOrg; @@ -659,7 +858,7 @@ void Scripts::cmdTexChoice() { Common::Array<Common::Rect> responseCoords; responseCoords.push_back(_vm->_bubbleBox->_bounds); - _vm->_screen->_printOrg.y = _vm->_bubbleBox->_bounds.bottom + 11; + _vm->_screen->_printOrg.y = _vm->_bubbleBox->_bounds.bottom + ((_vm->getGameID() == GType_MartianMemorandum) ? 20 : 11); findNull(); @@ -672,7 +871,7 @@ void Scripts::cmdTexChoice() { _vm->_bubbleBox->calcBubble(tmpStr); _vm->_bubbleBox->printBubble(tmpStr); responseCoords.push_back(_vm->_bubbleBox->_bounds); - _vm->_screen->_printOrg.y = _vm->_bubbleBox->_bounds.bottom + 11; + _vm->_screen->_printOrg.y = _vm->_bubbleBox->_bounds.bottom + ((_vm->getGameID() == GType_MartianMemorandum) ? 20 : 11); } findNull(); @@ -687,7 +886,7 @@ void Scripts::cmdTexChoice() { _vm->_bubbleBox->calcBubble(tmpStr); _vm->_bubbleBox->printBubble(tmpStr); responseCoords.push_back(_vm->_bubbleBox->_bounds); - _vm->_screen->_printOrg.y = _vm->_bubbleBox->_bounds.bottom + 11; + _vm->_screen->_printOrg.y = _vm->_bubbleBox->_bounds.bottom + ((_vm->getGameID() == GType_MartianMemorandum) ? 20 : 11); } findNull(); @@ -702,11 +901,13 @@ void Scripts::cmdTexChoice() { _vm->_bubbleBox->_bubbleDisplStr = _vm->_bubbleBox->_bubbleTitle; if (_vm->_events->_leftButton) { - if (_vm->_events->_mouseRow >= 22) { + if (_vm->_events->_mouseRow >= ((_vm->getGameID() == GType_MartianMemorandum) ? 23 : 22)) { _vm->_events->debounceLeft(); int x = _vm->_events->_mousePos.x; for (int i = 0; i < BTN_COUNT; i++) { - if ((x >= BTN_RANGES[i][0]) && (x < BTN_RANGES[i][1])) { + if (((_vm->getGameID() == GType_MartianMemorandum) && (x >= BTN_RANGES_v1[i][0]) && (x < BTN_RANGES_v1[i][1])) + || ((_vm->getGameID() == GType_Amazon) && (x >= BTN_RANGES_v2[i][0]) && (x < BTN_RANGES_v2[i][1]))) { + choice = i; break; } @@ -827,39 +1028,46 @@ void Scripts::cmdPlayVideoSound() { } void Scripts::cmdPrintWatch() { - if (!_vm->isDemo()) { - cmdPushLocation(); - return; - } - error("TODO: DEMO - cmdPrintWatch"); + printWatch(); + findNull(); } void Scripts::cmdDispAbout() { - if (!_vm->isDemo()) { - cmdPushLocation(); - return; - } - error("TODO: DEMO - cmdDispAbout"); + _vm->_travelBox->getList(Martian::ASKTBL, _vm->ASK); + int btnSelected = 0; + int boxX = _vm->_aboutBox->doBox_v1(_vm->_startAboutItem, _vm->_startAboutBox, btnSelected); + _vm->_startAboutItem = _vm->BOXDATASTART; + _vm->_startAboutBox = _vm->BOXSELECTY; + + if (boxX == -1) + btnSelected = 2; + + if (btnSelected == 2) + _vm->_useItem = -1; + else + _vm->_useItem = _vm->_travelBox->_tempListIdx[boxX]; } void Scripts::cmdPushLocation() { - error("TODO cmdPushLocation"); + _choiceStart = _data->pos() - 1; } void Scripts::cmdCheckTravel() { - if (!_vm->isDemo()) { - cmdPushLocation(); - return; - } - error("TODO: DEMO - cmdCheckTravel"); + int idx = _data->readSint16LE(); + int val = _data->readUint16LE(); + + if (_vm->TRAVEL[idx] == val) + cmdGoto(); + else + _data->skip(2); } void Scripts::cmdBlock() { - if (!_vm->isDemo()) { - cmdPushLocation(); - return; - } - error("TODO: DEMO - cmdBlock"); + error("TODO: cmdBlock"); + int val1 = _data->readSint16LE(); + int val2 = _data->readUint16LE(); + int val3 = _data->readSint16LE(); + int val4 = _data->readUint16LE(); } void Scripts::cmdPlayerOff() { diff --git a/engines/access/scripts.h b/engines/access/scripts.h index cfadf6d901..07fd6acfb1 100644 --- a/engines/access/scripts.h +++ b/engines/access/scripts.h @@ -35,18 +35,25 @@ class Scripts; #define SCRIPT_START_BYTE 0xE0 #define ROOM_SCRIPT 2000 +typedef void(Scripts::*ScriptMethodPtr)(); + class Scripts : public Manager { private: Resource *_resource; int _specialFunction; - void charLoop(); + void clearWatch(); + void printWatch(); + protected: Common::SeekableReadStream *_data; + ScriptMethodPtr COMMAND_LIST[100]; virtual void executeSpecial(int commandIndex, int param1, int param2) = 0; virtual void executeCommand(int commandIndex); + void charLoop(); + /** * Read a null terminated string from the script */ @@ -61,7 +68,8 @@ protected: void cmdJumpUse(); void cmdJumpTalk(); void cmdNull(); - void cmdPrint(); + void cmdPrint_v1(); + void cmdPrint_v2(); void cmdAnim(); void cmdSetFlag(); void cmdCheckFlag(); @@ -83,7 +91,8 @@ protected: void cmdRetNeg(); void cmdCheckLoc(); void cmdSetAnim(); - void cmdDispInv(); + void cmdDispInv_v1(); + void cmdDispInv_v2(); void cmdSetAbout(); void cmdSetTimer(); void cmdCheckTimer(); @@ -127,7 +136,8 @@ protected: void cmdDead(); void cmdFadeOut(); void cmdEndVideo(); - void cmdHelp(); + void cmdHelp_v1(); + void cmdHelp_v2(); void cmdCycleBack(); void cmdSetHelp(); public: @@ -138,11 +148,15 @@ public: int _choice; int32 _choiceStart; Common::Point _charsOrg, _texsOrg; + public: Scripts(AccessEngine *vm); virtual ~Scripts(); + void setOpcodes(); + void setOpcodes_v2(); + void setScript(Resource *data, bool restartFlag = false); void freeScriptData(); @@ -152,6 +166,7 @@ public: int executeScript(); void findNull(); + void doCmdPrint_v1(Common::String msg); /** * Print a given message to the screen in a bubble box @@ -161,6 +176,7 @@ public: // Script commands that need to be public void cmdFreeSound(); void cmdRetPos(); + void converse1(int val); }; } // End of namespace Access diff --git a/engines/access/sound.cpp b/engines/access/sound.cpp index 69133d082d..f2dc0fdf4c 100644 --- a/engines/access/sound.cpp +++ b/engines/access/sound.cpp @@ -200,6 +200,7 @@ MusicManager::MusicManager(AccessEngine *vm) : _vm(vm) { _tempMusic = nullptr; _isLooping = false; _driver = nullptr; + _byte1F781 = false; MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MT32); MusicType musicType = MidiDriver::getMusicType(dev); diff --git a/engines/access/sound.h b/engines/access/sound.h index 014c6651fb..e11a6b9730 100644 --- a/engines/access/sound.h +++ b/engines/access/sound.h @@ -56,6 +56,7 @@ private: void playSound(Resource *res, int priority, bool loop); public: Common::Array<SoundEntry> _soundTable; + bool _playingSound; public: SoundManager(AccessEngine *vm, Audio::Mixer *mixer); ~SoundManager(); @@ -84,6 +85,7 @@ private: public: Resource *_music; + bool _byte1F781; public: MusicManager(AccessEngine *vm); diff --git a/engines/access/video.cpp b/engines/access/video.cpp index 63d0aa5c89..5fc5f6762c 100644 --- a/engines/access/video.cpp +++ b/engines/access/video.cpp @@ -48,17 +48,13 @@ VideoPlayer::~VideoPlayer() { closeVideo(); } - -void VideoPlayer::setVideo(ASurface *vidSurface, const Common::Point &pt, const FileIdent &videoFile, int rate) { +void VideoPlayer::setVideo(ASurface *vidSurface, const Common::Point &pt, int rate) { _vidSurface = vidSurface; vidSurface->_orgX1 = pt.x; vidSurface->_orgY1 = pt.y; _vm->_timers[31]._timer = rate; _vm->_timers[31]._initTm = rate; - // Open up video stream - _videoData = _vm->_files->loadFile(videoFile); - // Load in header _header._frameCount = _videoData->_stream->readUint16LE(); _header._width = _videoData->_stream->readUint16LE(); @@ -91,6 +87,20 @@ void VideoPlayer::setVideo(ASurface *vidSurface, const Common::Point &pt, const _videoEnd = false; } +void VideoPlayer::setVideo(ASurface *vidSurface, const Common::Point &pt, const Common::String filename, int rate) { + // Open up video stream + _videoData = _vm->_files->loadFile(filename); + + setVideo(vidSurface, pt, rate); +} + +void VideoPlayer::setVideo(ASurface *vidSurface, const Common::Point &pt, const FileIdent &videoFile, int rate) { + // Open up video stream + _videoData = _vm->_files->loadFile(videoFile); + + setVideo(vidSurface, pt, rate); +} + void VideoPlayer::closeVideo() { delete _videoData; _videoData = nullptr; diff --git a/engines/access/video.h b/engines/access/video.h index 17825db367..83c8995d3e 100644 --- a/engines/access/video.h +++ b/engines/access/video.h @@ -51,6 +51,7 @@ private: Common::Rect _videoBounds; void getFrame(); + void setVideo(ASurface *vidSurface, const Common::Point &pt, int rate); public: int _videoFrame; bool _soundFlag; @@ -64,6 +65,7 @@ public: * Start up a video */ void setVideo(ASurface *vidSurface, const Common::Point &pt, const FileIdent &videoFile, int rate); + void setVideo(ASurface *vidSurface, const Common::Point &pt, const Common::String filename, int rate); /** * Decodes a frame of the video |