diff options
Diffstat (limited to 'engines/hopkins')
-rw-r--r-- | engines/hopkins/anim.cpp | 85 | ||||
-rw-r--r-- | engines/hopkins/anim.h | 4 | ||||
-rw-r--r-- | engines/hopkins/computer.cpp | 12 | ||||
-rw-r--r-- | engines/hopkins/debugger.cpp | 23 | ||||
-rw-r--r-- | engines/hopkins/debugger.h | 2 | ||||
-rw-r--r-- | engines/hopkins/detection_tables.h | 32 | ||||
-rw-r--r-- | engines/hopkins/dialogs.cpp | 2 | ||||
-rw-r--r-- | engines/hopkins/events.cpp | 2 | ||||
-rw-r--r-- | engines/hopkins/font.cpp | 1 | ||||
-rw-r--r-- | engines/hopkins/globals.cpp | 6 | ||||
-rw-r--r-- | engines/hopkins/globals.h | 2 | ||||
-rw-r--r-- | engines/hopkins/graphics.cpp | 82 | ||||
-rw-r--r-- | engines/hopkins/graphics.h | 7 | ||||
-rw-r--r-- | engines/hopkins/hopkins.cpp | 194 | ||||
-rw-r--r-- | engines/hopkins/hopkins.h | 13 | ||||
-rw-r--r-- | engines/hopkins/lines.cpp | 118 | ||||
-rw-r--r-- | engines/hopkins/lines.h | 10 | ||||
-rw-r--r-- | engines/hopkins/menu.cpp | 6 | ||||
-rw-r--r-- | engines/hopkins/objects.cpp | 71 | ||||
-rw-r--r-- | engines/hopkins/objects.h | 2 | ||||
-rw-r--r-- | engines/hopkins/saveload.cpp | 4 | ||||
-rw-r--r-- | engines/hopkins/script.cpp | 141 | ||||
-rw-r--r-- | engines/hopkins/sound.cpp | 17 |
23 files changed, 521 insertions, 315 deletions
diff --git a/engines/hopkins/anim.cpp b/engines/hopkins/anim.cpp index 007197090f..2ec9cec009 100644 --- a/engines/hopkins/anim.cpp +++ b/engines/hopkins/anim.cpp @@ -55,7 +55,7 @@ void AnimationManager::clearAll() { * @param rate2 Delay amount between animation frames * @param rate3 Delay amount after animation finishes */ -void AnimationManager::playAnim(const Common::String &filename, uint32 rate1, uint32 rate2, uint32 rate3, bool skipSeqFl) { +void AnimationManager::playAnim(const Common::String &hiresName, const Common::String &lowresName, uint32 rate1, uint32 rate2, uint32 rate3, bool skipSeqFl) { Common::File f; if (_vm->shouldQuit()) @@ -65,16 +65,10 @@ void AnimationManager::playAnim(const Common::String &filename, uint32 rate1, ui byte *screenP = _vm->_graphicsMan->_backBuffer; - Common::String tmpStr; - // The Windows 95 demo only contains the interlaced version of the BOMBE1 and BOMBE2 videos - if (_vm->getPlatform() == Common::kPlatformWindows && _vm->getIsDemo() && filename == "BOMBE1A.ANM") - tmpStr = "BOMBE1.ANM"; - else if (_vm->getPlatform() == Common::kPlatformWindows && _vm->getIsDemo() && filename == "BOMBE2A.ANM") - tmpStr = "BOMBE2.ANM"; - else - tmpStr = filename; - if (!f.open(tmpStr)) - error("File not found - %s", tmpStr.c_str()); + if (!f.open(hiresName)) { + if (!f.open(lowresName)) + error("Files not found: %s - %s", hiresName.c_str(), lowresName.c_str()); + } f.skip(6); f.read(_vm->_graphicsMan->_palette, 800); @@ -202,7 +196,7 @@ void AnimationManager::playAnim(const Common::String &filename, uint32 rate1, ui /** * Play Animation, type 2 */ -void AnimationManager::playAnim2(const Common::String &filename, uint32 rate1, uint32 rate2, uint32 rate3) { +void AnimationManager::playAnim2(const Common::String &hiresName, const Common::String &lowresName, uint32 rate1, uint32 rate2, uint32 rate3) { int oldScrollPosX = 0; byte *screenP = NULL; Common::File f; @@ -221,8 +215,10 @@ void AnimationManager::playAnim2(const Common::String &filename, uint32 rate1, u _vm->_graphicsMan->_scrollOffset = 0; screenP = _vm->_graphicsMan->_backBuffer; - if (!f.open(filename)) - error("Error opening file - %s", filename.c_str()); + if (!f.open(hiresName)) { + if (!f.open(lowresName)) + error("Error opening files: %s - %s", hiresName.c_str(), lowresName.c_str()); + } f.skip(6); f.read(_vm->_graphicsMan->_palette, 800); @@ -675,42 +671,39 @@ void AnimationManager::playSequence2(const Common::String &file, uint32 rate1, u int frameNumber; Common::File f; - for (;;) { - if (_vm->shouldQuit()) - return; + if (_vm->shouldQuit()) + return; - _vm->_events->_mouseFl = false; - screenP = _vm->_graphicsMan->_backBuffer; + _vm->_events->_mouseFl = false; + screenP = _vm->_graphicsMan->_backBuffer; - if (!f.open(file)) - error("File not found - %s", file.c_str()); + if (!f.open(file)) + error("File not found - %s", file.c_str()); - f.skip(6); - f.read(_vm->_graphicsMan->_palette, 800); - f.skip(4); - size_t nbytes = f.readUint32LE(); - f.skip(14); - f.read(screenP, nbytes); + f.skip(6); + f.read(_vm->_graphicsMan->_palette, 800); + f.skip(4); + size_t nbytes = f.readUint32LE(); + f.skip(14); + f.read(screenP, nbytes); - if (skipSeqFl) { - _vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette); - } else { - _vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette); - _vm->_graphicsMan->display8BitRect(screenP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0); + if (skipSeqFl) { + _vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette); + } else { + _vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette); + _vm->_graphicsMan->display8BitRect(screenP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0); - _vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); - _vm->_graphicsMan->updateScreen(); - } - _vm->_events->_rateCounter = 0; - _vm->_events->_escKeyFl = false; - _vm->_soundMan->loadAnimSound(); - if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) { - do { - _vm->_events->refreshEvents(); - _vm->_soundMan->checkSoundEnd(); - } while (!_vm->shouldQuit() && !_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate1); - } - break; + _vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + _vm->_graphicsMan->updateScreen(); + } + _vm->_events->_rateCounter = 0; + _vm->_events->_escKeyFl = false; + _vm->_soundMan->loadAnimSound(); + if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) { + do { + _vm->_events->refreshEvents(); + _vm->_soundMan->checkSoundEnd(); + } while (!_vm->shouldQuit() && !_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate1); } if (!_vm->_events->_escKeyFl) { @@ -760,7 +753,7 @@ void AnimationManager::playSequence2(const Common::String &file, uint32 rate1, u f.seek(6); f.read(_vm->_graphicsMan->_palette, 800); f.skip(4); - size_t nbytes = f.readUint32LE(); + nbytes = f.readUint32LE(); f.skip(14); f.read(screenP, nbytes); diff --git a/engines/hopkins/anim.h b/engines/hopkins/anim.h index 22f725681a..bf9b55aaae 100644 --- a/engines/hopkins/anim.h +++ b/engines/hopkins/anim.h @@ -64,8 +64,8 @@ public: void loadAnim(const Common::String &animName); void clearAnim(); - void playAnim(const Common::String &filename, uint32 rate1, uint32 rate2, uint32 rate3, bool skipSeqFl = false); - void playAnim2(const Common::String &filename, uint32 rate1, uint32 rate2, uint32 rate3); + void playAnim(const Common::String &hiresName, const Common::String &lowresName, uint32 rate1, uint32 rate2, uint32 rate3, bool skipSeqFl = false); + void playAnim2(const Common::String &hiresName, const Common::String &lowresName, uint32 rate1, uint32 rate2, uint32 rate3); void playSequence(const Common::String &file, uint32 rate1, uint32 rate2, uint32 rate3, bool skipEscFl, bool skipSeqFl, bool noColFl = false); void playSequence2(const Common::String &file, uint32 rate1, uint32 rate2, uint32 rate3, bool skipSeqFl = false); diff --git a/engines/hopkins/computer.cpp b/engines/hopkins/computer.cpp index 467153e4dd..f7b923badf 100644 --- a/engines/hopkins/computer.cpp +++ b/engines/hopkins/computer.cpp @@ -326,13 +326,13 @@ static const char _spanishText[] = "% **** ORDENADOR DEL FBI NUMERO 4985 **** ORDENADOR J.HOPKINS *****\n" "% **** ORDENADOR DEL FBI NUMERO 4998 **** ORDENADOR S.COLLINS *****\n" "% *** ORDENADOR DEL FBI NUMERO 4997 *** ORDENADOR DE ACCESO LIBRE ***\n" -"% LA CONTRASE¥A ES: ALLFREE\n" -"% ESCRIBE CONTRASE¥A ACTUAL\n" +"% LA CONTRASE\0245A ES: ALLFREE\n" +"% ESCRIBE CONTRASE\0245A ACTUAL\n" "% **** ACCESO DENEGADO ****\n" "% 1) *** JUEGO ***\n" "% 0) SALIR DEL ORDENADOR\n" -"% 2) CADAVER EXTRA¥O\n" -"% 3) CADAVER EXTRA¥O\n" +"% 2) CADAVER EXTRA\0245O\n" +"% 3) CADAVER EXTRA\0245O\n" "% 4) SENADOR FERGUSSON\n" "% 5) MATAPERROS\n" "% 2) CIENTIFICO SECUESTRADO.\n" @@ -697,6 +697,10 @@ void ComputerManager::displayBricks() { } displayScore(); + + // Refresh the entire screen + _vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + _vm->_graphicsMan->updateScreen(); } /** diff --git a/engines/hopkins/debugger.cpp b/engines/hopkins/debugger.cpp index 246270c1c2..f111eb50d3 100644 --- a/engines/hopkins/debugger.cpp +++ b/engines/hopkins/debugger.cpp @@ -34,6 +34,8 @@ Debugger::Debugger(HopkinsEngine *vm) : GUI::Debugger() { DCmd_Register("rects", WRAP_METHOD(Debugger, cmd_DirtyRects)); DCmd_Register("teleport", WRAP_METHOD(Debugger, cmd_Teleport)); DCmd_Register("show_room", WRAP_METHOD(Debugger, cmd_ShowCurrentRoom)); + DCmd_Register("zones", WRAP_METHOD(Debugger, cmd_Zones)); + DCmd_Register("lines", WRAP_METHOD(Debugger, cmd_Lines)); } // Turns dirty rects on or off @@ -64,4 +66,25 @@ bool Debugger::cmd_ShowCurrentRoom(int argc, const char **argv) { return true; } +bool Debugger::cmd_Zones(int argc, const char **argv) { +if (argc != 2) { + DebugPrintf("%s: [on | off]\n", argv[0]); + return true; + } else { + _vm->_graphicsMan->_showZones = !strcmp(argv[1], "on"); + return false; + } +} + +bool Debugger::cmd_Lines(int argc, const char **argv) { + if (argc != 2) { + DebugPrintf("%s: [on | off]\n", argv[0]); + return true; + } else { + _vm->_graphicsMan->_showLines = !strcmp(argv[1], "on"); + return false; + } +} + + } // End of namespace Hopkins diff --git a/engines/hopkins/debugger.h b/engines/hopkins/debugger.h index 7f7bffd755..746c54a675 100644 --- a/engines/hopkins/debugger.h +++ b/engines/hopkins/debugger.h @@ -41,6 +41,8 @@ public: bool cmd_DirtyRects(int argc, const char **argv); bool cmd_Teleport(int argc, const char **argv); bool cmd_ShowCurrentRoom(int argc, const char **argv); + bool cmd_Zones(int argc, const char **argv); + bool cmd_Lines(int argc, const char **argv); }; } // End of namespace Hopkins diff --git a/engines/hopkins/detection_tables.h b/engines/hopkins/detection_tables.h index e1937372d2..3e04375fe9 100644 --- a/engines/hopkins/detection_tables.h +++ b/engines/hopkins/detection_tables.h @@ -155,6 +155,38 @@ static const HopkinsGameDescription gameDescriptions[] = { }, }, { + // Hopkins FBI Win95 EN, provided by greencis in bug #3612406 + { + "hopkins", + 0, + { + {"hopkins.exe", 0, "020690049fa1dfcd63a18fdafb139a0e", 421386}, + {"RES_VAN.RES", 0, "f1693ac0b0859c8ecd8cb30ff43cf55f", 38296346}, + AD_LISTEND + }, + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + }, + { + // Hopkins FBI Win95 RU, provided by greencis in bug #3613068 + { + "hopkins", + 0, + { + {"hopkins.exe", 0, "3043fef0bd3bfeba8252647cd090ce09", 419281}, + {"res_van.res", 0, "bf17c710e184a25a6c8e9d1d9503c38e", 32197685}, + AD_LISTEND + }, + Common::RU_RUS, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + }, + { // Hopkins FBI Linux, provided by Strangerke { "hopkins", diff --git a/engines/hopkins/dialogs.cpp b/engines/hopkins/dialogs.cpp index 5b9fb8afc2..6cdfbf47d1 100644 --- a/engines/hopkins/dialogs.cpp +++ b/engines/hopkins/dialogs.cpp @@ -422,6 +422,7 @@ void DialogsManager::showInventory() { if (cursorId != 1 && cursorId != 2 && cursorId != 3 && cursorId != 16) { if (mouseButton == 2) { _vm->_objectsMan->nextObjectIcon(newInventoryItem); + cursorId = _vm->_events->_mouseCursorId; if (cursorId != 23) _vm->_events->changeMouseCursor(cursorId); } @@ -639,6 +640,7 @@ void DialogsManager::showSaveGame() { // Since the original GUI doesn't support save names, use a default name Common::String saveName = Common::String::format("Save #%d", slotNumber); + _vm->_events->refreshScreenAndEvents(); // Save the game _vm->_saveLoad->saveGame(slotNumber, saveName); } diff --git a/engines/hopkins/events.cpp b/engines/hopkins/events.cpp index 58389ef2e9..51c66c4f92 100644 --- a/engines/hopkins/events.cpp +++ b/engines/hopkins/events.cpp @@ -237,7 +237,7 @@ void EventsManager::checkForNextFrameCounter() { void EventsManager::delay(int totalMilli) { uint32 delayEnd = g_system->getMillis() + totalMilli; - while (!g_system->getEventManager()->shouldQuit() && g_system->getMillis() < delayEnd) { + while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd) { g_system->delayMillis(10); } } diff --git a/engines/hopkins/font.cpp b/engines/hopkins/font.cpp index 611327e9a8..ac0eee2866 100644 --- a/engines/hopkins/font.cpp +++ b/engines/hopkins/font.cpp @@ -433,6 +433,7 @@ void FontManager::displayText(int xp, int yp, const Common::String &message, int if (currentChar > 31) { int characterIndex = currentChar - 32; _vm->_graphicsMan->displayFont(_vm->_graphicsMan->_frontBuffer, _font, xp, yp, characterIndex, col); + _vm->_graphicsMan->addDirtyRect(xp, yp, xp + _vm->_objectsMan->getWidth(_font, characterIndex) + 1, yp + _vm->_objectsMan->getHeight(_font, characterIndex) + 1); xp += _vm->_objectsMan->getWidth(_font, characterIndex); } } diff --git a/engines/hopkins/globals.cpp b/engines/hopkins/globals.cpp index 2e7a2195d1..28f22ed99e 100644 --- a/engines/hopkins/globals.cpp +++ b/engines/hopkins/globals.cpp @@ -89,7 +89,7 @@ Globals::Globals(HopkinsEngine *vm) { _menuTextOff = 0; _menuDisplayType = 0; _checkDistanceFl = false; - _characterType = 0; + _characterType = CHARACTER_HOPKINS; _actionMoveTo = false; _actionDirection = DIR_NONE; @@ -134,9 +134,11 @@ Globals::~Globals() { void Globals::setConfig() { // CHECKME: Should be in Globals() but it doesn't work // The Polish version is a translation of the English version. The filenames are the same. + // The Russian version looks like a translation of the English version, based on the filenames. switch (_vm->getLanguage()) { case Common::EN_ANY: case Common::PL_POL: + case Common::RU_RUS: _language = LANG_EN; break; case Common::FR_FRA: @@ -185,8 +187,6 @@ void Globals::clearAll() { } void Globals::loadCharacterData() { - assert(_characterType >= 0 && _characterType <= 2); - const int *srcList[] = { HOPKINS_PERSO_0, HOPKINS_PERSO_1, HOPKINS_PERSO_2 }; const int *srcP = srcList[_characterType]; diff --git a/engines/hopkins/globals.h b/engines/hopkins/globals.h index f86a810c28..94512c3d26 100644 --- a/engines/hopkins/globals.h +++ b/engines/hopkins/globals.h @@ -172,7 +172,7 @@ public: int _characterMaxPosY; int _baseMapColor; int _spriteSize[500]; - int _characterType; + PlayerCharacter _characterType; uint _speed; byte *_answerBuffer; Savegame *_saveData; diff --git a/engines/hopkins/graphics.cpp b/engines/hopkins/graphics.cpp index f978a5803f..ebc5cfa8da 100644 --- a/engines/hopkins/graphics.cpp +++ b/engines/hopkins/graphics.cpp @@ -73,6 +73,8 @@ GraphicsManager::GraphicsManager(HopkinsEngine *vm) { _zoomOutFactor = 0; _width = 0; _specialWidth = 0; + _showZones = false; + _showLines = false; Common::fill(&_paletteBuffer[0], &_paletteBuffer[PALETTE_SIZE * 2], 0); Common::fill(&_colorTable[0], &_colorTable[PALETTE_EXT_BLOCK_SIZE], 0); @@ -663,11 +665,17 @@ uint16 GraphicsManager::mapRGB(byte r, byte g, byte b) { } void GraphicsManager::updateScreen() { - // TODO: Is this okay here? // Display any aras of the screen that need refreshing displayDirtyRects(); displayRefreshRects(); + // Extra checks for debug information + if (_showZones) + displayZones(); + + if (_showLines) + displayLines(); + // Update the screen g_system->updateScreen(); } @@ -1012,7 +1020,7 @@ void GraphicsManager::endDisplayBob() { _vm->_objectsMan->resetBob(idx); } - for (int idx = 1; idx <= 29; ++idx) { + for (int idx = 1; idx < 36; ++idx) { _vm->_objectsMan->_lockedAnims[idx]._enableFl = false; } @@ -1140,6 +1148,7 @@ void GraphicsManager::displayRefreshRects() { screenSurface = g_system->lockScreen(); g_system->copyRectToScreen(_screenBuffer, _screenLineSize, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); } + // Loop through copying over any specified rects to the screen for (uint idx = 0; idx < _refreshRects.size(); ++idx) { const Common::Rect &r = _refreshRects[idx]; @@ -1157,6 +1166,75 @@ void GraphicsManager::displayRefreshRects() { resetRefreshRects(); } +/** + * Display any zones for the current room + */ +void GraphicsManager::displayZones() { + Graphics::Surface *screenSurface = g_system->lockScreen(); + + for (int bobZoneId = 0; bobZoneId <= 48; bobZoneId++) { + int bobId = _vm->_linesMan->_bobZone[bobZoneId]; + if (bobId) { + // Get the rectangle for the zone + Common::Rect r(_vm->_objectsMan->_bob[bobId]._oldX, _vm->_objectsMan->_bob[bobId]._oldY, + _vm->_objectsMan->_bob[bobId]._oldX + _vm->_objectsMan->_bob[bobId]._oldWidth, + _vm->_objectsMan->_bob[bobId]._oldY + _vm->_objectsMan->_bob[bobId]._oldHeight); + + displayDebugRect(screenSurface, r, 0xff0000); + } + } + + for (int squareZoneId = 0; squareZoneId <= 99; squareZoneId++) { + if (_vm->_linesMan->_zone[squareZoneId]._enabledFl && _vm->_linesMan->_squareZone[squareZoneId]._enabledFl) { + Common::Rect r(_vm->_linesMan->_squareZone[squareZoneId]._left, _vm->_linesMan->_squareZone[squareZoneId]._top, + _vm->_linesMan->_squareZone[squareZoneId]._right, _vm->_linesMan->_squareZone[squareZoneId]._bottom); + + displayDebugRect(screenSurface, r, 0x00ff00); + } + } + + g_system->unlockScreen(); +} + +/** + * Display any zones for the current room + */ +void GraphicsManager::displayLines() { + Graphics::Surface *screenSurface = g_system->lockScreen(); + + uint16* pixels = (uint16*)screenSurface->pixels; + + for (int lineIndex = 0; lineIndex < _vm->_linesMan->_linesNumb; lineIndex++) { + int i = 0; + do { + int x = _vm->_linesMan->_lineItem[lineIndex]._lineData[i] - _scrollPosX; + int y = _vm->_linesMan->_lineItem[lineIndex]._lineData[i+1]; + if (x >= 0 && x < SCREEN_WIDTH && y >= 0 && y < SCREEN_HEIGHT) { + pixels[ y * screenSurface->w + x ] = 0xffff; + } + i += 2; + } + while(_vm->_linesMan->_lineItem[lineIndex]._lineData[i] != -1); + } + + g_system->unlockScreen(); +} + + +void GraphicsManager::displayDebugRect(Graphics::Surface *surface, const Common::Rect &srcRect, uint32 color) { + Common::Rect r = srcRect; + + // Move for scrolling offset and adjust to crop on-screen + r.translate(-_scrollPosX, 0); + r.left = MAX(r.left, (int16)0); + r.top = MAX(r.top, (int16)0); + r.right = MIN(r.right, (int16)SCREEN_WIDTH); + r.bottom = MIN(r.bottom, (int16)SCREEN_HEIGHT); + + // If there's an on-screen portion, display it + if (r.isValidRect()) + surface->frameRect(r, color); +} /** * Fast Display of either a compressed or vesa sprite diff --git a/engines/hopkins/graphics.h b/engines/hopkins/graphics.h index b7d7eaa86f..268db7fc2b 100644 --- a/engines/hopkins/graphics.h +++ b/engines/hopkins/graphics.h @@ -118,12 +118,14 @@ public: Common::Array<Common::Rect> _dirtyRects; Common::Array<Common::Rect> _refreshRects; bool _showDirtyRects; + bool _showZones; + bool _showLines; byte *_palettePixels; public: GraphicsManager(HopkinsEngine *vm); ~GraphicsManager(); - + void clearPalette(); void clearScreen(); void clearVesaScreen(); @@ -135,6 +137,9 @@ public: void addRectToArray(Common::Array<Common::Rect> &rects, const Common::Rect &newRect); void displayDirtyRects(); void displayRefreshRects(); + void displayZones(); + void displayLines(); + void displayDebugRect(Graphics::Surface *surface, const Common::Rect &srcRect, uint32 color = 0xffffff); void copySurface(const byte *surface, int x1, int y1, int width, int height, byte *destSurface, int destX, int destY); void loadImage(const Common::String &file); void loadVgaImage(const Common::String &file); diff --git a/engines/hopkins/hopkins.cpp b/engines/hopkins/hopkins.cpp index bf9509c0d4..0d40f69e8f 100644 --- a/engines/hopkins/hopkins.cpp +++ b/engines/hopkins/hopkins.cpp @@ -39,6 +39,7 @@ HopkinsEngine *g_vm; HopkinsEngine::HopkinsEngine(OSystem *syst, const HopkinsGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc), _randomSource("Hopkins") { + DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level"); g_vm = this; _animMan = new AnimationManager(this); _computer = new ComputerManager(this); @@ -172,7 +173,7 @@ bool HopkinsEngine::runWin95Demo() { _globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR"); } - _globals->_characterType = 0; + _globals->_characterType = CHARACTER_HOPKINS; _objectsMan->_mapCarPosX = _objectsMan->_mapCarPosY = 0; memset(_globals->_saveData, 0, 2000); _globals->_exitId = 0; @@ -230,9 +231,9 @@ bool HopkinsEngine::runWin95Demo() { _graphicsMan->clearScreen(); _graphicsMan->clearPalette(); if (!_globals->_censorshipFl) - _animMan->playAnim("BANQUE.ANM", 200, 28, 200); + _animMan->playAnim("BANQUE.ANM", "BANKUK.ANM", 200, 28, 200); else - _animMan->playAnim("BANKUK.ANM", 200, 28, 200); + _animMan->playAnim("BANQUE.ANM", "BANKUK.ANM", 200, 28, 200); _soundMan->_specialSoundNum = 0; _soundMan->removeSample(1); _soundMan->removeSample(2); @@ -394,7 +395,7 @@ bool HopkinsEngine::runWin95Demo() { _globals->_eventMode = EVENTMODE_ALT; // CHECKME! _graphicsMan->clearScreen(); _graphicsMan->clearPalette(); - _animMan->playAnim("JOUR1A.anm", 12, 12, 2000); + _animMan->playAnim("JOUR1A.ANM", "JOUR1A.ANM", 12, 12, 2000); _globals->_eventMode = EVENTMODE_DEFAULT; _globals->_exitId = 300; break; @@ -417,7 +418,7 @@ bool HopkinsEngine::runWin95Demo() { _globals->_eventMode = EVENTMODE_ALT; // CHECKME! _graphicsMan->clearScreen(); _graphicsMan->clearPalette(); - _animMan->playAnim("JOUR4A.anm", 12, 12, 2000); + _animMan->playAnim("JOUR4A.ANM", "JOUR4A.ANM", 12, 12, 2000); _globals->_eventMode = EVENTMODE_DEFAULT; _globals->_exitId = 300; break; @@ -453,7 +454,7 @@ bool HopkinsEngine::runLinuxDemo() { _globals->_eventMode = EVENTMODE_DEFAULT; _globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR"); - _globals->_characterType = 0; + _globals->_characterType = CHARACTER_HOPKINS; _objectsMan->_mapCarPosX = _objectsMan->_mapCarPosY = 0; memset(_globals->_saveData, 0, 2000); _globals->_exitId = 0; @@ -529,9 +530,9 @@ bool HopkinsEngine::runLinuxDemo() { _graphicsMan->_fadingFl = true; if (!_globals->_censorshipFl) - _animMan->playAnim("BANQUE.ANM", 200, 28, 200); + _animMan->playAnim("BANQUE.ANM", "BANKUK.ANM", 200, 28, 200); else - _animMan->playAnim("BANKUK.ANM", 200, 28, 200); + _animMan->playAnim("BANKUK.ANM", "BANQUE.ANM", 200, 28, 200); _soundMan->_specialSoundNum = 0; _soundMan->removeSample(1); _soundMan->removeSample(2); @@ -705,7 +706,7 @@ bool HopkinsEngine::runLinuxDemo() { _graphicsMan->clearScreen(); _graphicsMan->clearPalette(); _graphicsMan->_fadingFl = true; - _animMan->playAnim("JOUR1A.anm", 12, 12, 2000); + _animMan->playAnim("JOUR1A.ANM", "JOUR1A.ANM", 12, 12, 2000); _globals->_eventMode = EVENTMODE_DEFAULT; _globals->_exitId = 300; break; @@ -717,7 +718,7 @@ bool HopkinsEngine::runLinuxDemo() { _graphicsMan->clearScreen(); _graphicsMan->clearPalette(); _graphicsMan->_fadingFl = true; - _animMan->playAnim("JOUR3A.anm", 12, 12, 2000); + _animMan->playAnim("JOUR3A.ANM", "JOUR3A.ANM", 12, 12, 2000); _globals->_eventMode = EVENTMODE_DEFAULT; _globals->_exitId = 300; break; @@ -729,7 +730,7 @@ bool HopkinsEngine::runLinuxDemo() { _graphicsMan->clearScreen(); _graphicsMan->clearPalette(); _graphicsMan->_fadingFl = true; - _animMan->playAnim("JOUR4A.anm", 12, 12, 2000); + _animMan->playAnim("JOUR4A.ANM", "JOUR4A.ANM", 12, 12, 2000); _globals->_eventMode = EVENTMODE_DEFAULT; _globals->_exitId = 300; break; @@ -790,18 +791,21 @@ bool HopkinsEngine::runFull() { _globals->_speed = 2; _globals->_eventMode = EVENTMODE_IGNORE; _graphicsMan->_fadingFl = true; - _animMan->playAnim("MP.ANM", 10, 16, 200); + _animMan->playAnim("MP.ANM", "MP.ANM", 10, 16, 200); } else { - _animMan->playAnim("MP.ANM", 10, 16, 200); + _animMan->playAnim("MP.ANM", "MP.ANM", 10, 16, 200); _graphicsMan->fadeOutLong(); } } + _events->mouseOff(); + if (!_events->_escKeyFl && _startGameSlot == -1) { playIntro(); if (shouldQuit()) return false; } + if (getPlatform() != Common::kPlatformLinux && _startGameSlot == -1) { _graphicsMan->fadeOutShort(); _graphicsMan->loadImage("H2"); @@ -811,14 +815,17 @@ bool HopkinsEngine::runFull() { } _globals->_eventMode = EVENTMODE_DEFAULT; _globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR"); - _globals->_characterType = 0; + _globals->_characterType = CHARACTER_HOPKINS; _objectsMan->_mapCarPosX = _objectsMan->_mapCarPosY = 0; memset(_globals->_saveData, 0, 2000); _globals->_exitId = 0; - if (_startGameSlot != -1) + + if (_startGameSlot != -1) { + _soundMan->playSound(28); _saveLoad->loadGame(_startGameSlot); + } for (;;) { if (_globals->_exitId == 300) @@ -870,11 +877,11 @@ bool HopkinsEngine::runFull() { _graphicsMan->_fadingFl = true; if (!_globals->_censorshipFl) - _animMan->playAnim("BANQUE.ANM", 200, 28, 200); + _animMan->playAnim("BANQUE.ANM", "BANKUK.ANM", 200, 28, 200); else - _animMan->playAnim("BANKUK.ANM", 200, 28, 200); + _animMan->playAnim("BANKUK.ANM", "BANQUE.ANM", 200, 28, 200); } else { - _animMan->playAnim("BANQUE.ANM", 200, 28, 200); + _animMan->playAnim("BANQUE.ANM", "BANKUK.ANM", 200, 28, 200); } _soundMan->_specialSoundNum = 0; @@ -1002,14 +1009,14 @@ bool HopkinsEngine::runFull() { if (getPlatform() == Common::kPlatformLinux) { _soundMan->playSound(29); _graphicsMan->_fadingFl = true; - _animMan->playAnim("PURG1A.ANM", 12, 18, 50); + _animMan->playAnim("PURG1A.ANM", "PURG1.ANM", 12, 18, 50); } else if (getPlatform() == Common::kPlatformWindows) { _soundMan->playSound(29); - _animMan->playAnim("PURG1A.ANM", 12, 18, 50); + _animMan->playAnim("PURG1A.ANM", "PURG1.ANM", 12, 18, 50); _graphicsMan->fadeOutShort(); } else { _soundMan->playSound(6); - _animMan->playAnim("PURG1A.ANM", 12, 18, 50); + _animMan->playAnim("PURG1A.ANM", "PURG1.ANM", 12, 18, 50); _graphicsMan->fadeOutShort(); } _globals->_eventMode = EVENTMODE_DEFAULT; @@ -1046,7 +1053,7 @@ bool HopkinsEngine::runFull() { _soundMan->playSound(6); if (getPlatform() == Common::kPlatformLinux) _graphicsMan->_fadingFl = true; - _animMan->playAnim("PURG2A.ANM", 12, 18, 50); + _animMan->playAnim("PURG2A.ANM", "PURG2.ANM", 12, 18, 50); if (getPlatform() != Common::kPlatformLinux) _graphicsMan->fadeOutShort(); _globals->_eventMode = EVENTMODE_DEFAULT; @@ -1408,7 +1415,7 @@ bool HopkinsEngine::runFull() { _graphicsMan->clearScreen(); _graphicsMan->clearPalette(); _soundMan->playSound(6); - _animMan->playAnim("PURG1A.ANM", 12, 18, 50); + _animMan->playAnim("PURG1A.ANM", "PURG1.ANM", 12, 18, 50); _graphicsMan->fadeOutShort(); _globals->_eventMode = EVENTMODE_DEFAULT; } @@ -1480,7 +1487,7 @@ bool HopkinsEngine::runFull() { _graphicsMan->clearPalette(); if (getPlatform() == Common::kPlatformLinux) _graphicsMan->_fadingFl = true; - _animMan->playAnim("JOUR1A.ANM", 12, 12, 2000); + _animMan->playAnim("JOUR1A.ANM", "JOUR1A.ANM", 12, 12, 2000); _globals->_eventMode = EVENTMODE_DEFAULT; _globals->_exitId = 300; break; @@ -1492,7 +1499,7 @@ bool HopkinsEngine::runFull() { _graphicsMan->clearPalette(); if (getPlatform() == Common::kPlatformLinux) _graphicsMan->_fadingFl = true; - _animMan->playAnim("JOUR3A.ANM", 12, 12, 2000); + _animMan->playAnim("JOUR3A.ANM", "JOUR3A.ANM", 12, 12, 2000); _globals->_eventMode = EVENTMODE_DEFAULT; _globals->_exitId = 300; break; @@ -1504,7 +1511,7 @@ bool HopkinsEngine::runFull() { _graphicsMan->clearPalette(); if (getPlatform() == Common::kPlatformLinux) _graphicsMan->_fadingFl = true; - _animMan->playAnim("JOUR4A.ANM", 12, 12, 2000); + _animMan->playAnim("JOUR4A.ANM", "JOUR4A.ANM", 12, 12, 2000); _globals->_eventMode = EVENTMODE_DEFAULT; _globals->_exitId = 300; break; @@ -1523,7 +1530,7 @@ bool HopkinsEngine::runFull() { //_globals->_exitId = WBASE(); // Handles the 3D Doom level (Windows) _soundMan->stopSound(); _globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR"); - _globals->_characterType = 0; + _globals->_characterType = CHARACTER_HOPKINS; _globals->_eventMode = EVENTMODE_DEFAULT; _graphicsMan->_lineNbr = SCREEN_WIDTH; break; @@ -1534,10 +1541,6 @@ bool HopkinsEngine::runFull() { return true; } -bool HopkinsEngine::shouldQuit() const { - return g_system->getEventManager()->shouldQuit(); -} - int HopkinsEngine::getRandomNumber(int maxNumber) { return _randomSource.getRandomNumber(maxNumber); } @@ -1599,22 +1602,25 @@ void HopkinsEngine::playIntro() { _events->refreshScreenAndEvents(); _soundMan->playSound(16); _animMan->setClearAnimFlag(); - _animMan->playAnim("J1.anm", 12, 12, 50); + + _animMan->playAnim("J1.ANM", "J1.ANM", 12, 12, 50); if (shouldQuit() || _events->_escKeyFl) return; - + _events->mouseOff(); _soundMan->mixVoice(1, 3); - _animMan->playAnim("J2.anm", 12, 12, 50); + _animMan->playAnim("J2.ANM", "J2.ANM", 12, 12, 50); if (shouldQuit() || _events->_escKeyFl) return; + _events->mouseOff(); _soundMan->mixVoice(2, 3); - _animMan->playAnim("J3.anm", 12, 12, 50); + _animMan->playAnim("J3.ANM", "J3.ANM", 12, 12, 50); if (shouldQuit() || _events->_escKeyFl) return; + _events->mouseOff(); _soundMan->mixVoice(3, 3); _graphicsMan->clearScreen(); _graphicsMan->clearPalette(); @@ -1694,7 +1700,7 @@ void HopkinsEngine::playIntro() { _soundMan->_specialSoundNum = 5; _graphicsMan->_fadingFl = true; - _animMan->playAnim("ELEC.ANM", 10, 26, 200); + _animMan->playAnim("ELEC.ANM", "ELEC.ANM", 10, 26, 200); _soundMan->_specialSoundNum = 0; if (shouldQuit() || _events->_escKeyFl) @@ -1781,22 +1787,22 @@ void HopkinsEngine::playIntro() { _soundMan->playSound(3); _soundMan->_specialSoundNum = 1; _animMan->setClearAnimFlag(); - _animMan->playAnim("INTRO1.anm", 10, 24, 18); + _animMan->playAnim("INTRO1.ANM", "INTRO1.ANM", 10, 24, 18); _soundMan->_specialSoundNum = 0; if (shouldQuit() || _events->_escKeyFl) return; - _animMan->playAnim("INTRO2.anm", 10, 24, 18); + _animMan->playAnim("INTRO2.ANM", "INTRO2.ANM", 10, 24, 18); if (shouldQuit() || _events->_escKeyFl) return; - _animMan->playAnim("INTRO3.anm", 10, 24, 200); + _animMan->playAnim("INTRO3.ANM", "INTRO3.ANM", 10, 24, 200); if (shouldQuit() || _events->_escKeyFl) return; _graphicsMan->_fadingFl = true; _animMan->unsetClearAnimFlag(); - _animMan->playAnim("J4.anm", 12, 12, 1000); + _animMan->playAnim("J4.ANM", "J4.ANM", 12, 12, 1000); break; } } @@ -1855,7 +1861,7 @@ void HopkinsEngine::bombExplosion() { _globals->_eventMode = EVENTMODE_IGNORE; _soundMan->_specialSoundNum = 199; _graphicsMan->_fadingFl = true; - _animMan->playAnim("BOMBE2A.ANM", 50, 14, 500); + _animMan->playAnim("BOMBE2A.ANM", "BOMBE2.ANM", 50, 14, 500); _soundMan->_specialSoundNum = 0; _graphicsMan->loadImage("IM15"); _animMan->loadAnim("ANIM15"); @@ -1889,7 +1895,10 @@ void HopkinsEngine::bombExplosion() { } void HopkinsEngine::restoreSystem() { - quitGame(); + // If the game isn't alerady trying to quit, flag that quitting is needed + if (!shouldQuit()) + quitGame(); + _events->refreshEvents(); } @@ -1962,31 +1971,31 @@ void HopkinsEngine::playSubmarineCutscene() { _graphicsMan->clearPalette(); _soundMan->playSound(25); _animMan->setClearAnimFlag(); - _animMan->playAnim("base00a.anm", 10, 18, 18); + _animMan->playAnim("BASE00A.ANM", "BASE00.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("base05a.anm", 10, 18, 18); + _animMan->playAnim("BASE05A.ANM", "BASE05.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("base10a.anm", 10, 18, 18); + _animMan->playAnim("BASE10A.ANM", "BASE10.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("base20a.anm", 10, 18, 18); + _animMan->playAnim("BASE20A.ANM", "BASE20.ANM", 10, 18, 18); // CHECKME: The original code was doing the opposite test, which was a bug. if (!_events->_escKeyFl) - _animMan->playAnim("base30a.anm", 10, 18, 18); + _animMan->playAnim("BASE30A.ANM", "BASE30.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("base40a.anm", 10, 18, 18); + _animMan->playAnim("BASE40A.ANM", "BASE40.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("base50a.anm", 10, 18, 18); + _animMan->playAnim("BASE50A.ANM", "BASE50.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("OC00a.anm", 10, 18, 18); + _animMan->playAnim("OC00A.ANM", "OC00.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("OC05a.anm", 10, 18, 18); + _animMan->playAnim("OC05A.ANM", "OC05.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("OC10a.anm", 10, 18, 18); + _animMan->playAnim("OC10A.ANM", "OC10.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("OC20a.anm", 10, 18, 18); + _animMan->playAnim("OC20A.ANM", "OC20.ANM", 10, 18, 18); if (!_events->_escKeyFl) { _graphicsMan->_fadingFl = true; - _animMan->playAnim("OC30a.anm", 10, 18, 18); + _animMan->playAnim("OC30A.ANM", "OC30.ANM", 10, 18, 18); } _events->_escKeyFl = false; @@ -2108,7 +2117,7 @@ void HopkinsEngine::playEnding() { _soundMan->_specialSoundNum = 200; _soundMan->_skipRefreshFl = true; _graphicsMan->_fadingFl = true; - _animMan->playAnim("BERM.ANM", 100, 24, 300); + _animMan->playAnim("BERM.ANM", "BERM.ANM", 100, 24, 300); _graphicsMan->endDisplayBob(); _soundMan->removeSample(1); _graphicsMan->loadImage("PLAN3"); @@ -2125,15 +2134,16 @@ void HopkinsEngine::playEnding() { _globals->_eventMode = EVENTMODE_IGNORE; _soundMan->_specialSoundNum = 0; _graphicsMan->_fadingFl = true; - _animMan->playAnim("JOUR2A.anm", 12, 12, 1000); + _animMan->playAnim("JOUR2A.anm", "JOUR2A.anm", 12, 12, 1000); _soundMan->playSound(11); _graphicsMan->clearScreen(); _graphicsMan->clearPalette(); - _animMan->playAnim("FF1a.anm", 18, 18, 9); - _animMan->playAnim("FF1a.anm", 9, 18, 9); - _animMan->playAnim("FF1a.anm", 9, 18, 18); - _animMan->playAnim("FF1a.anm", 9, 18, 9); - _animMan->playAnim("FF2a.anm", 24, 24, 100); + _animMan->playAnim("FF1a.anm", "FF1.anm", 18, 18, 9); + _animMan->playAnim("FF1a.anm", "FF1.anm", 9, 18, 9); + _animMan->playAnim("FF1a.anm", "FF1.anm", 9, 18, 18); + _animMan->playAnim("FF1a.anm", "FF1.anm", 9, 18, 9); + _animMan->playAnim("FF2a.anm", "FF2.anm", 24, 24, 100); + _events->mouseOff(); displayCredits(); _globals->_eventMode = EVENTMODE_DEFAULT; _globals->_exitId = 300; @@ -2142,7 +2152,7 @@ void HopkinsEngine::playEnding() { } else { _soundMan->_specialSoundNum = 200; _soundMan->_skipRefreshFl = true; - _animMan->playAnim2("BERM.ANM", 100, 24, 300); + _animMan->playAnim2("BERM.ANM", "BERM.ANM", 100, 24, 300); _objectsMan->stopBobAnimation(7); _objectsMan->setBobAnimation(8); _globals->_introSpeechOffFl = true; @@ -2167,12 +2177,12 @@ void HopkinsEngine::playEnding() { _soundMan->_specialSoundNum = 0; _dialog->enableInvent(); _globals->_disableInventFl = false; - _animMan->playAnim("JOUR4A.anm", 12, 12, 1000); + _animMan->playAnim("JOUR4A.ANM", "JOUR4A.ANM", 12, 12, 1000); _globals->_eventMode = EVENTMODE_DEFAULT; _globals->_exitId = 300; } _globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR"); - _globals->_characterType = 0; + _globals->_characterType = CHARACTER_HOPKINS; _globals->_eventMode = EVENTMODE_DEFAULT; } @@ -2183,36 +2193,36 @@ void HopkinsEngine::playPlaneCutscene() { _graphicsMan->clearPalette(); _animMan->unsetClearAnimFlag(); - _animMan->playAnim("aerop00a.anm", 10, 18, 18); + _animMan->playAnim("AEROP00A.ANM", "AEROP00.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("serop10a.anm", 10, 18, 18); + _animMan->playAnim("SEROP10A.ANM", "SEROP10A.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("aerop20a.anm", 10, 18, 18); + _animMan->playAnim("AEROP20A.ANM", "AEROP20.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("aerop30a.anm", 10, 18, 18); + _animMan->playAnim("AEROP30A.ANM", "AEROP30.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("aerop40a.anm", 10, 18, 18); + _animMan->playAnim("AEROP40A.ANM", "AEROP40.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("aerop50a.anm", 10, 18, 18); + _animMan->playAnim("AEROP50A.ANM", "AEROP50.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("aerop60a.anm", 10, 18, 18); + _animMan->playAnim("AEROP60A.ANM", "AEROP60.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("aerop70a.anm", 10, 18, 18); + _animMan->playAnim("AEROP70A.ANM", "AEROP70.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("trans00a.anm", 10, 18, 18); + _animMan->playAnim("TRANS00A.ANM", "TRANS00.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("trans10a.anm", 10, 18, 18); + _animMan->playAnim("TRANS10A.ANM", "TRANS10.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("trans15a.anm", 10, 18, 18); + _animMan->playAnim("TRANS15A.ANM", "TRANS15.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("trans20a.anm", 10, 18, 18); + _animMan->playAnim("TRANS20A.ANM", "TRANS20.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("trans30a.anm", 10, 18, 18); + _animMan->playAnim("TRANS30A.ANM", "TRANS30.ANM", 10, 18, 18); if (!_events->_escKeyFl) - _animMan->playAnim("trans40a.anm", 10, 18, 18); + _animMan->playAnim("TRANS40A.ANM", "TRANS40.ANM", 10, 18, 18); if (!_events->_escKeyFl) { _graphicsMan->_fadingFl = true; - _animMan->playAnim("PARA00a.anm", 9, 9, 9); + _animMan->playAnim("PARA00A.ANM", "PARA00.ANM", 9, 9, 9); } _events->_escKeyFl = false; @@ -2353,21 +2363,34 @@ void HopkinsEngine::loadCredits() { _globals->_creditsPosY = 440; _globals->_creditsStep = 45; byte *bufPtr; + Common::String filename; switch (_globals->_language) { case LANG_EN: - bufPtr = _fileIO->loadFile("CREAN.TXT"); + filename = "CREAN.TXT"; break; case LANG_FR: - bufPtr = _fileIO->loadFile("CREFR.TXT"); + filename = "CREFR.TXT"; break; case LANG_SP: - bufPtr = _fileIO->loadFile("CREES.TXT"); + filename = "CREES.TXT"; break; default: error("Unhandled language"); break; } + if (!_fileIO->fileExists(filename)) { + _globals->_creditsLineNumb = 1; + _globals->_creditsItem[0]._color = '1'; + _globals->_creditsItem[0]._actvFl = true; + _globals->_creditsItem[0]._linePosY = _globals->_creditsPosY; + strcpy((char *)_globals->_creditsItem[0]._line, "The End"); + _globals->_creditsItem[0]._lineSize = 7; + return; + } + + bufPtr = _fileIO->loadFile(filename); + byte *curPtr = bufPtr; int idxLines = 0; bool loopCond = false; @@ -2441,13 +2464,14 @@ void HopkinsEngine::displayCredits() { _globals->_eventMode = EVENTMODE_CREDITS; _globals->_creditsStartX = _globals->_creditsEndX = _globals->_creditsStartY = _globals->_creditsEndY = -1; int soundId = 28; + do { for (int i = 0; i < _globals->_creditsLineNumb; ++i) { if (_globals->_creditsItem[i]._actvFl) { int nextY = _globals->_creditsPosY + i * _globals->_creditsStep; _globals->_creditsItem[i]._linePosY = nextY; - if ((nextY - 21 >= 0) && (nextY - 21 <= 418)) { + if ((nextY >= 51) && (nextY <= 460)) { int col = 0; switch (_globals->_creditsItem[i]._color) { case '1': @@ -2472,7 +2496,7 @@ void HopkinsEngine::displayCredits() { --_globals->_creditsPosY; if (_globals->_creditsStartX != -1 || _globals->_creditsEndX != -1 || _globals->_creditsStartY != -1 || _globals->_creditsEndY != -1) { _events->refreshScreenAndEvents(); - _graphicsMan->copySurface(_graphicsMan->_backBuffer, 60, 50, 520, 380, _graphicsMan->_frontBuffer, 60, 50); + _graphicsMan->copySurface(_graphicsMan->_backBuffer, 60, 50, 520, 430, _graphicsMan->_frontBuffer, 60, 50); } else { _events->refreshScreenAndEvents(); } @@ -2800,7 +2824,7 @@ void HopkinsEngine::handleOceanMaze(int16 curExitId, Common::String backgroundFi _objectsMan->removeSprite(0); _objectsMan->clearScreen(); _globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR"); - _globals->_characterType = 0; + _globals->_characterType = CHARACTER_HOPKINS; } void HopkinsEngine::syncSoundSettings() { diff --git a/engines/hopkins/hopkins.h b/engines/hopkins/hopkins.h index 499f0c466d..86f15cc7cb 100644 --- a/engines/hopkins/hopkins.h +++ b/engines/hopkins/hopkins.h @@ -59,14 +59,6 @@ */ namespace Hopkins { -enum { - kHopkinsDebugAnimations = 1 << 0, - kHopkinsDebugActions = 1 << 1, - kHopkinsDebugSound = 1 << 2, - kHopkinsDebugMusic = 1 << 3, - kHopkinsDebugScripts = 1 << 4 -}; - #define DEBUG_BASIC 1 #define DEBUG_INTERMEDIATE 2 #define DEBUG_DETAILED 3 @@ -74,7 +66,9 @@ enum { #define SCREEN_WIDTH 640 #define SCREEN_HEIGHT 480 -#define MAX_LINES 400 +enum HopkinsDebugChannels { + kDebugPath = 1 << 0 +}; /** * A wrapper macro used around three character constants, like 'END', to @@ -169,7 +163,6 @@ public: Common::Platform getPlatform() const; uint16 getVersion() const; bool getIsDemo() const; - bool shouldQuit() const; int getRandomNumber(int maxNumber); Common::String generateSaveName(int slotNumber); diff --git a/engines/hopkins/lines.cpp b/engines/hopkins/lines.cpp index 6603708449..e6d5e5ca7f 100644 --- a/engines/hopkins/lines.cpp +++ b/engines/hopkins/lines.cpp @@ -33,10 +33,11 @@ namespace Hopkins { LinesManager::LinesManager(HopkinsEngine *vm) { _vm = vm; - for (int i = 0; i < MAX_LINES; ++i) { + for (int i = 0; i < MAX_LINES + 1; ++i) Common::fill((byte *)&_zoneLine[i], (byte *)&_zoneLine[i] + sizeof(LigneZoneItem), 0); + + for (int i = 0; i < MAX_LINES; ++i) Common::fill((byte *)&_lineItem[i], (byte *)&_lineItem[i] + sizeof(LigneItem), 0); - } for (int i = 0; i < 4000; ++i) Common::fill((byte *)&_smoothRoute[i], (byte *)&_smoothRoute[i] + sizeof(SmoothItem), 0); @@ -98,6 +99,7 @@ LinesManager::~LinesManager() { } int LigneItem::appendToRouteInc(int from, int to, RouteItem *route, int index) { + debugC(5, kDebugPath, "appendToRouteInc(%d, %d, route, %d)", from, to, index); if (to == -1) to = _lineDataEndIdx; @@ -105,7 +107,9 @@ int LigneItem::appendToRouteInc(int from, int to, RouteItem *route, int index) { route[index++].set(_lineData[2*i], _lineData[2*i+1], _directionRouteInc); return index; } + int LigneItem::appendToRouteDec(int from, int to, RouteItem *route, int index) { + debugC(5, kDebugPath, "appendToRouteDecc(%d, %d, route, %d)", from, to, index); if (from == -1) from = _lineDataEndIdx - 1; @@ -118,6 +122,7 @@ int LigneItem::appendToRouteDec(int from, int to, RouteItem *route, int index) { * Load lines */ void LinesManager::loadLines(const Common::String &file) { + debugC(5, kDebugPath, "loadLines(%s)", file.c_str()); resetLines(); _linesNumb = 0; _lastLine = 0; @@ -139,6 +144,7 @@ void LinesManager::loadLines(const Common::String &file) { * Returns the ID of the hotspot under mouse */ int LinesManager::checkInventoryHotspots(int posX, int posY) { + debugC(5, kDebugPath, "checkInventoryHotspots(%d, %d)", posX, posY); int hotspotId = 0; if (posY >= 120 && posY <= 153) hotspotId = checkInventoryHotspotsRow(posX, 1, false); @@ -165,6 +171,7 @@ int LinesManager::checkInventoryHotspots(int posX, int posY) { * Returns the hotspot Id under the mouse, if any. */ int LinesManager::checkInventoryHotspotsRow(int posX, int minZoneNum, bool lastRow) { + debugC(5, kDebugPath, "checkInventoryHotspotsRow(%d, %d, %d)", posX, minZoneNum, lastRow ? 1 : 0); int result = minZoneNum; if (posX >= _vm->_graphicsMan->_scrollOffset + 158 && posX < _vm->_graphicsMan->_scrollOffset + 208) @@ -202,13 +209,14 @@ int LinesManager::checkInventoryHotspotsRow(int posX, int minZoneNum, bool lastR * Add Zone Line */ void LinesManager::addZoneLine(int idx, int fromX, int fromY, int destX, int destY, int bobZoneIdx) { + debugC(5, kDebugPath, "addZoneLine(%d, %d, %d, %d, %d, %d)", idx, fromX, fromY, destX, destY, bobZoneIdx); int16 *zoneData; if (fromX == fromY && fromY == destX && fromY == destY) { _bobZoneFl[bobZoneIdx] = true; _bobZone[bobZoneIdx] = fromY; } else { - assert (idx <= MAX_LINES); + assert(idx < MAX_LINES + 1); _zoneLine[idx]._zoneData = (int16 *)_vm->_globals->freeMemory((byte *)_zoneLine[idx]._zoneData); int distX = abs(fromX - destX); @@ -252,7 +260,8 @@ void LinesManager::addZoneLine(int idx, int fromX, int fromY, int destX, int des * Add Line */ void LinesManager::addLine(int lineIdx, Directions direction, int fromX, int fromY, int destX, int destY) { - assert (lineIdx <= MAX_LINES); + debugC(5, kDebugPath, "addLine(%d, %d, %d, %d, %d, %d)", lineIdx, direction, fromX, fromY, destX, destY); + assert(lineIdx < MAX_LINES); if (_linesNumb < lineIdx) _linesNumb = lineIdx; @@ -265,7 +274,7 @@ void LinesManager::addLine(int lineIdx, Directions direction, int fromX, int fro maxDist = distX; byte *zoneData = _vm->_globals->allocMemory(4 * maxDist + 8); - assert (zoneData); + assert(zoneData); Common::fill(zoneData, zoneData + 4 * maxDist + 8, 0); _lineItem[lineIdx]._lineData = (int16 *)zoneData; @@ -366,6 +375,7 @@ void LinesManager::addLine(int lineIdx, Directions direction, int fromX, int fro * Check collision line */ bool LinesManager::checkCollisionLine(int xp, int yp, int *foundDataIdx, int *foundLineIdx, int startLineIdx, int endLineIdx) { + debugC(5, kDebugPath, "checkCollisionLine(%d, %d, foundDataIdx, foundLineIdx, %d, %d)", xp, yp, startLineIdx ,endLineIdx); int16 *lineData; int left = xp + 4; @@ -425,6 +435,7 @@ bool LinesManager::checkCollisionLine(int xp, int yp, int *foundDataIdx, int *fo * Init route */ void LinesManager::initRoute() { + debugC(5, kDebugPath, "initRoute()"); int lineX = _lineItem[0]._lineData[0]; int lineY = _lineItem[0]._lineData[1]; @@ -461,6 +472,7 @@ void LinesManager::initRoute() { // Avoid obstacle int LinesManager::avoidObstacle(int lineIdx, int lineDataIdx, int routeIdx, int destLineIdx, int destLineDataIdx, RouteItem *route) { + debugC(5, kDebugPath, "avoidObstacle(%d, %d, %d, %d, %d, route)", lineIdx, lineDataIdx, routeIdx, destLineIdx, destLineDataIdx); int curLineIdx = lineIdx; int curLineDataIdx = lineDataIdx; int curRouteIdx = routeIdx; @@ -492,6 +504,7 @@ int LinesManager::avoidObstacle(int lineIdx, int lineDataIdx, int routeIdx, int // Avoid Obstacle, taking into account start/End lind Idx int LinesManager::avoidObstacleOnSegment(int lineIdx, int lineDataIdx, int routeIdx, int destLineIdx, int destLineDataIdx, RouteItem *route, int startLineIdx, int endLineIdx) { + debugC(5, kDebugPath, "avoidObstacleOnSegment(%d, %d, %d, %d, %d, route, %d, %d)", lineIdx, lineDataIdx, routeIdx, destLineIdx, destLineDataIdx, startLineIdx, endLineIdx); int curLineIdx = lineIdx; int curLineDataIdx = lineDataIdx; int curRouteIdx = routeIdx; @@ -534,6 +547,7 @@ int LinesManager::avoidObstacleOnSegment(int lineIdx, int lineDataIdx, int route } bool LinesManager::MIRACLE(int fromX, int fromY, int lineIdx, int destLineIdx, int routeIdx) { + debugC(5, kDebugPath, "MIRACLE(%d, %d, %d, %d, %d)", fromX, fromY, lineIdx, destLineIdx, routeIdx); int newLinesDataIdx = 0; int newLinesIdx = 0; int lineIdxLeft = 0; @@ -775,6 +789,7 @@ bool LinesManager::MIRACLE(int fromX, int fromY, int lineIdx, int destLineIdx, i } int LinesManager::computeRouteIdx(int lineIdx, int dataIdx, int fromX, int fromY, int destX, int destY, int routerIdx, RouteItem *route) { + debugC(5, kDebugPath, "computeRouteIdx(%d, %d, %d, %d, %d, %d, %d)", lineIdx, dataIdx, fromX, fromY, destX, destY, routerIdx); int result = routerIdx; ++_pathFindingMaxDepth; if (_pathFindingMaxDepth > 10) { @@ -1075,6 +1090,7 @@ int LinesManager::computeRouteIdx(int lineIdx, int dataIdx, int fromX, int fromY // Find Route from a point to the other RouteItem *LinesManager::findRoute(int fromX, int fromY, int destX, int destY) { + debugC(5, kDebugPath, "findRoute(%d, %d, %d, %d)", fromX, fromY, destX, destY); int foundLineIdx; int foundDataIdx; int curLineY = 0; @@ -1502,6 +1518,7 @@ RouteItem *LinesManager::findRoute(int fromX, int fromY, int destX, int destY) { } void LinesManager::useRoute0(int idx, int curRouteIdx) { + debugC(5, kDebugPath, "useRoute0(%d, %d)", idx, curRouteIdx); if (idx) { int i = 0; do { @@ -1513,6 +1530,7 @@ void LinesManager::useRoute0(int idx, int curRouteIdx) { } void LinesManager::useRoute1(int idx, int curRouteIdx) { + debugC(5, kDebugPath, "useRoute1(%d, %d)", idx, curRouteIdx); if (idx) { int i = 0; do { @@ -1524,6 +1542,7 @@ void LinesManager::useRoute1(int idx, int curRouteIdx) { } void LinesManager::useRoute2(int idx, int curRouteIdx) { + debugC(5, kDebugPath, "useRoute2(%d, %d)", idx, curRouteIdx); if (idx) { int i = 0; do { @@ -1535,6 +1554,7 @@ void LinesManager::useRoute2(int idx, int curRouteIdx) { } int LinesManager::characterRoute(int fromX, int fromY, int destX, int destY, int startLineIdx, int endLineIdx, int routeIdx) { + debugC(5, kDebugPath, "characterRoute(%d, %d, %d, %d, %d, %d, %d)", fromX, fromY, destX, destY, startLineIdx, endLineIdx, routeIdx); int collDataIdxRoute2 = 0; bool colResult = false; @@ -1561,6 +1581,7 @@ int LinesManager::characterRoute(int fromX, int fromY, int destX, int destY, int case DIR_DOWN_RIGHT: curY += 2; curX += 2; + break; case DIR_DOWN: curY += 2; break; @@ -1967,8 +1988,8 @@ int LinesManager::characterRoute(int fromX, int fromY, int destX, int destY, int _newRouteIdx = curRouteIdx; return 2; } - // CHECKME: Checking essai0[0]._x might make more sense here? - if (_testRoute1[0]._x != -1 && foundLineIdx > collLineIdxRoute0 && collLineIdxRoute1 >= collLineIdxRoute0 && collLineIdxRoute2 >= collLineIdxRoute0 && endLineIdx <= collLineIdxRoute0) { + + if (_testRoute0[0]._x != -1 && foundLineIdx > collLineIdxRoute0 && collLineIdxRoute1 >= collLineIdxRoute0 && collLineIdxRoute2 >= collLineIdxRoute0 && endLineIdx <= collLineIdxRoute0) { _newLineIdx = collLineIdxRoute0; _newLineDataIdx = collDataIdxRoute0; int i = 0; @@ -1985,6 +2006,7 @@ int LinesManager::characterRoute(int fromX, int fromY, int destX, int destY, int } RouteItem *LinesManager::cityMapCarRoute(int x1, int y1, int x2, int y2) { + debugC(5, kDebugPath, "cityMapCarRoute(%d, %d, %d, %d)", x1, y1, x2, y2); RouteItem *result; int arrDelta[10]; int arrDataIdx[10]; @@ -2163,6 +2185,7 @@ RouteItem *LinesManager::cityMapCarRoute(int x1, int y1, int x2, int y2) { } bool LinesManager::checkSmoothMove(int fromX, int fromY, int destX, int destY) { + debugC(5, kDebugPath, "checkSmoothMove(%d, %d, %d, %d)", fromX, fromY, destX, destY); int distX = abs(fromX - destX) + 1; int distY = abs(fromY - destY) + 1; if (distX > distY) @@ -2201,6 +2224,7 @@ bool LinesManager::checkSmoothMove(int fromX, int fromY, int destX, int destY) { } bool LinesManager::makeSmoothMove(int fromX, int fromY, int destX, int destY) { + debugC(5, kDebugPath, "makeSmoothMove(%d, %d, %d, %d)", fromX, fromY, destX, destY); int curX = fromX; int curY = fromY; if (fromX > destX && destY > fromY) { @@ -2218,10 +2242,11 @@ bool LinesManager::makeSmoothMove(int fromX, int fromY, int destX, int destY) { realSpeedX = _vm->_graphicsMan->zoomIn(realSpeedX, spriteSize); realSpeedY = _vm->_graphicsMan->zoomIn(realSpeedY, spriteSize); } + int oldY = curY; for (int i = 0; i < realSpeedX; i++) { --curX; _smoothRoute[smoothIdx]._posX = curX; - if (curY != curY + realSpeedY) + if (curY != oldY + realSpeedY) curY++; _smoothRoute[smoothIdx]._posY = curY; smoothIdx++; @@ -2252,10 +2277,11 @@ bool LinesManager::makeSmoothMove(int fromX, int fromY, int destX, int destY) { realSpeedX = _vm->_graphicsMan->zoomIn(realSpeedX, spriteSize); realSpeedY = _vm->_graphicsMan->zoomIn(realSpeedY, spriteSize); } + int oldY = curY; for (int i = 0; i < realSpeedX; i++) { ++curX; _smoothRoute[smoothIdx]._posX = curX; - if (curY != curY + realSpeedY) + if (curY != oldY + realSpeedY) curY++; _smoothRoute[smoothIdx]._posY = curY; smoothIdx++; @@ -2331,6 +2357,7 @@ bool LinesManager::makeSmoothMove(int fromX, int fromY, int destX, int destY) { } bool LinesManager::PLAN_TEST(int paramX, int paramY, int superRouteIdx, int paramStartLineIdx, int paramEndLineIdx) { + debugC(5, kDebugPath, "PLAN_TEST(%d, %d, %d, %d, %d)", paramX, paramY, superRouteIdx, paramStartLineIdx, paramEndLineIdx); int sideTestUp; int sideTestDown; int sideTestLeft; @@ -2431,6 +2458,7 @@ bool LinesManager::PLAN_TEST(int paramX, int paramY, int superRouteIdx, int para // Test line int LinesManager::testLine(int paramX, int paramY, int *testValue, int *foundLineIdx, int *foundDataIdx) { + debugC(5, kDebugPath, "testLine(%d, %d, testValue, foundLineIdx, foundDataIdx)", paramX, paramY); int16 *lineData; int lineDataEndIdx; int collLineIdx; @@ -2439,21 +2467,22 @@ int LinesManager::testLine(int paramX, int paramY, int *testValue, int *foundLin for (int idx = _lastLine + 1; idx < _linesNumb + 1; idx++) { lineData = _lineItem[idx]._lineData; lineDataEndIdx = _lineItem[idx]._lineDataEndIdx; - if (lineData) { - if (lineData[0] == paramX && lineData[1] == paramY) { - *testValue = 1; - int posX = lineData[2 * (lineDataEndIdx - 1)]; - int posY = lineData[2 * (lineDataEndIdx - 1) + 1]; - if (_lineItem[idx]._directionRouteInc == DIR_DOWN || _lineItem[idx]._directionRouteInc == DIR_UP) - posY += 2; - if (_lineItem[idx]._directionRouteInc == DIR_RIGHT || _lineItem[idx]._directionRouteDec == DIR_LEFT) - posX += 2; - if (!checkCollisionLine(posX, posY, &collDataIdx, &collLineIdx, 0, _lastLine)) - error("Error in test line"); - *foundLineIdx = collLineIdx; - *foundDataIdx = collDataIdx; - return idx; - } + if (!lineData) + continue; + + if (lineData[0] == paramX && lineData[1] == paramY) { + *testValue = 1; + int posX = lineData[2 * (lineDataEndIdx - 1)]; + int posY = lineData[2 * (lineDataEndIdx - 1) + 1]; + if (_lineItem[idx]._directionRouteInc == DIR_DOWN || _lineItem[idx]._directionRouteInc == DIR_UP) + posY += 2; + if (_lineItem[idx]._directionRouteInc == DIR_RIGHT || _lineItem[idx]._directionRouteDec == DIR_LEFT) + posX += 2; + if (!checkCollisionLine(posX, posY, &collDataIdx, &collLineIdx, 0, _lastLine)) + error("Error in test line"); + *foundLineIdx = collLineIdx; + *foundDataIdx = collDataIdx; + return idx; } if (lineDataEndIdx > 0) { @@ -2477,12 +2506,13 @@ int LinesManager::testLine(int paramX, int paramY, int *testValue, int *foundLin } int LinesManager::computeYSteps(int idx) { + debugC(5, kDebugPath, "computeYSteps(%d)", idx); int zoomPct = _vm->_globals->_spriteSize[idx]; - if (_vm->_globals->_characterType == 1) { + if (_vm->_globals->_characterType == CHARACTER_HOPKINS_CLONE) { if (zoomPct < 0) zoomPct = -zoomPct; zoomPct = 20 * (5 * zoomPct - 100) / -80; - } else if (_vm->_globals->_characterType == 2) { + } else if (_vm->_globals->_characterType == CHARACTER_SAMANTHA) { if (zoomPct < 0) zoomPct = -zoomPct; zoomPct = 20 * (5 * zoomPct - 165) / -67; @@ -2498,6 +2528,7 @@ int LinesManager::computeYSteps(int idx) { } void LinesManager::optimizeRoute(RouteItem *route) { + debugC(5, kDebugPath, "optimizeRoute(route)"); if (route[0]._x == -1 && route[0]._y == -1) return; @@ -2544,6 +2575,7 @@ void LinesManager::optimizeRoute(RouteItem *route) { } int LinesManager::getMouseZone() { + debugC(9, kDebugPath, "getMouseZone()"); int result; int xp = _vm->_events->_mousePos.x + _vm->_events->_mouseOffset.x; @@ -2564,6 +2596,11 @@ int LinesManager::getMouseZone() { _zone[bobZoneId]._destY = _vm->_objectsMan->_bob[bobId]._oldHeight + _vm->_objectsMan->_bob[bobId]._oldY + 6; _zone[bobZoneId]._spriteIndex = -1; } + + // WORKAROUND: Avoid allowing hotspots that should remain non-interactive + if (bobZoneId == 24 && _vm->_globals->_curRoomNum == 14) + continue; + return bobZoneId; } } @@ -2632,6 +2669,7 @@ int LinesManager::getMouseZone() { } int LinesManager::checkCollision(int xp, int yp) { + debugC(7, kDebugPath, "checkCollision(%d, %d)", xp, yp); if (_currentSegmentId <= 0) return -1; @@ -2681,6 +2719,7 @@ int LinesManager::checkCollision(int xp, int yp) { // Square Zone void LinesManager::initSquareZones() { + debugC(5, kDebugPath, "initSquareZones()"); for (int idx = 0; idx < 100; ++idx) { SquareZoneItem *curZone = &_squareZone[idx]; curZone->_enabledFl = false; @@ -2693,7 +2732,7 @@ void LinesManager::initSquareZones() { curZone->_maxZoneLineIdx = 0; } - for (int idx = 0; idx < MAX_LINES; ++idx) { + for (int idx = 0; idx < MAX_LINES + 1; ++idx) { int16 *dataP = _zoneLine[idx]._zoneData; if (dataP == NULL) continue; @@ -2723,6 +2762,7 @@ void LinesManager::initSquareZones() { } void LinesManager::clearAll() { + debugC(5, kDebugPath, "clearAll()"); for (int idx = 0; idx < 105; ++idx) { _zone[idx]._destX = 0; _zone[idx]._destY = 0; @@ -2768,6 +2808,7 @@ void LinesManager::clearAll() { * Clear all zones and reset nextLine */ void LinesManager::clearAllZones() { + debugC(5, kDebugPath, "clearAllZones()"); for (int idx = 0; idx < MAX_LINES; ++idx) removeZoneLine(idx); } @@ -2776,38 +2817,37 @@ void LinesManager::clearAllZones() { * Remove Zone Line */ void LinesManager::removeZoneLine(int idx) { - assert (idx <= MAX_LINES); + debugC(5, kDebugPath, "removeZoneLine(%d)", idx); + assert(idx < MAX_LINES + 1); _zoneLine[idx]._zoneData = (int16 *)_vm->_globals->freeMemory((byte *)_zoneLine[idx]._zoneData); } void LinesManager::resetLines() { + debugC(5, kDebugPath, "resetLines()"); for (int idx = 0; idx < MAX_LINES; ++idx) { - removeLine(idx); + _lineItem[idx]._lineData = (int16 *)_vm->_globals->freeMemory((byte *)_lineItem[idx]._lineData); _lineItem[idx]._lineDataEndIdx = 0; _lineItem[idx]._lineData = NULL; } } -// Remove Line -void LinesManager::removeLine(int idx) { - if (idx > MAX_LINES) - error("Attempting to add a line obstacle > MAX_LIGNE."); - _lineItem[idx]._lineData = (int16 *)_vm->_globals->freeMemory((byte *)_lineItem[idx]._lineData); -} - void LinesManager::setMaxLineIdx(int idx) { + debugC(5, kDebugPath, "setMaxLineIdx(%d)", idx); _maxLineIdx = idx; } void LinesManager::resetLastLine() { + debugC(5, kDebugPath, "resetLastLine()"); _lastLine = 0; } void LinesManager::resetLinesNumb() { + debugC(5, kDebugPath, "resetLinesNumb()"); _linesNumb = 0; } void LinesManager::enableZone(int idx) { + debugC(5, kDebugPath, "enableZone(%d)", idx); if (_bobZone[idx]) { _bobZoneFl[idx] = true; } else { @@ -2816,6 +2856,7 @@ void LinesManager::enableZone(int idx) { } void LinesManager::disableZone(int idx) { + debugC(5, kDebugPath, "disableZone(%d)", idx); if (_bobZone[idx]) { _bobZoneFl[idx] = false; } else { @@ -2824,6 +2865,7 @@ void LinesManager::disableZone(int idx) { } void LinesManager::checkZone() { + debugC(9, kDebugPath, "checkZone()"); int mouseX = _vm->_events->getMouseX(); int mouseY = _vm->_events->getMouseY(); int oldMouseY = mouseY; @@ -2854,6 +2896,10 @@ void LinesManager::checkZone() { int zoneId; if (_oldMouseX != mouseX || _oldMouseY != oldMouseY) { zoneId = getMouseZone(); + + // WORKAROUND: Incorrect hotspot zones in the guard's control room + if (_vm->_globals->_curRoomNum == 71 && (zoneId == 14 || zoneId == 12 || zoneId == 17)) + zoneId = _oldMouseZoneId; } else { zoneId = _oldMouseZoneId; } diff --git a/engines/hopkins/lines.h b/engines/hopkins/lines.h index 9e397cca3d..b32dc6e2a5 100644 --- a/engines/hopkins/lines.h +++ b/engines/hopkins/lines.h @@ -40,6 +40,8 @@ struct LigneZoneItem { #define INVALID_LINE_VALUE 1300 +#define MAX_LINES 400 + struct RouteItem; struct LigneItem { @@ -111,13 +113,11 @@ private: int _pathFindingMaxDepth; SmoothItem _smoothRoute[4000]; Directions _smoothMoveDirection; - LigneZoneItem _zoneLine[401]; + LigneZoneItem _zoneLine[MAX_LINES+1]; SegmentItem _segment[101]; - SquareZoneItem _squareZone[101]; int _currentSegmentId; int _maxLineIdx; int _lastLine; - int _linesNumb; int _newLineIdx; int _newLineDataIdx; int _newRouteIdx; @@ -134,7 +134,6 @@ private: RouteItem *_testRoute0; RouteItem *_testRoute1; int16 *_lineBuf; - LigneItem _lineItem[400]; RouteItem _bestRoute[8001]; int _zoneSkipCount; int _oldMouseZoneId; @@ -166,6 +165,9 @@ public: int _bobZone[105]; bool _bobZoneFl[105]; ZoneItem _zone[106]; + SquareZoneItem _squareZone[101]; + LigneItem _lineItem[MAX_LINES]; + int _linesNumb; LinesManager(HopkinsEngine *vm); ~LinesManager(); diff --git a/engines/hopkins/menu.cpp b/engines/hopkins/menu.cpp index 01aa84e4ed..455f4ad8d4 100644 --- a/engines/hopkins/menu.cpp +++ b/engines/hopkins/menu.cpp @@ -50,11 +50,11 @@ int MenuManager::menu() { signed int result; int frameIndex[] = { 0, 0, 0, 0, 0 }; - if (g_system->getEventManager()->shouldQuit()) + if (_vm->shouldQuit()) return -1; result = 0; - while (!g_system->getEventManager()->shouldQuit()) { + while (!_vm->shouldQuit()) { _vm->_objectsMan->_forestFl = false; _vm->_events->_breakoutFl = false; _vm->_globals->_disableInventFl = true; @@ -97,7 +97,7 @@ int MenuManager::menu() { // Loop to make menu selection bool selectionMade = false; do { - if (g_system->getEventManager()->shouldQuit()) + if (_vm->shouldQuit()) return -1; menuIndex = MENU_NONE; diff --git a/engines/hopkins/objects.cpp b/engines/hopkins/objects.cpp index f139ee55ab..f2f547557f 100644 --- a/engines/hopkins/objects.cpp +++ b/engines/hopkins/objects.cpp @@ -41,12 +41,13 @@ ObjectsManager::ObjectsManager(HopkinsEngine *vm) { for (int i = 0; i < 6; ++i) Common::fill((byte *)&_sprite[i], (byte *)&_sprite[i] + sizeof(SpriteItem), 0); - for (int i = 0; i < 36; ++i) + for (int i = 0; i < 36; ++i) { Common::fill((byte *)&_bob[i], (byte *)&_bob[i] + sizeof(BobItem), 0); + Common::fill((byte *)&_lockedAnims[i], (byte *)&_lockedAnims[i] + sizeof(LockAnimItem), 0); + } for (int i = 0; i < 30; ++i) { Common::fill((byte *)&_vBob[i], (byte *)&_vBob[i] + sizeof(VBobItem), 0); - Common::fill((byte *)&_lockedAnims[i], (byte *)&_lockedAnims[i] + sizeof(LockAnimItem), 0); } for (int i = 0; i < 300; ++i) @@ -987,7 +988,7 @@ void ObjectsManager::computeSprite(int idx) { // Before Sort void ObjectsManager::beforeSort(SortMode sortMode, int index, int priority) { ++_sortedDisplayCount; - assert (_sortedDisplayCount <= 48); + assert(_sortedDisplayCount <= 48); _sortedDisplay[_sortedDisplayCount]._sortMode = sortMode; _sortedDisplay[_sortedDisplayCount]._index = index; @@ -1228,7 +1229,7 @@ void ObjectsManager::displayVBob() { * Get Sprite X coordinate */ int ObjectsManager::getSpriteX(int idx) { - assert (idx <= MAX_SPRITE); + assert(idx <= MAX_SPRITE); return _sprite[idx]._spritePos.x; } @@ -1236,7 +1237,7 @@ int ObjectsManager::getSpriteX(int idx) { * Get Sprite Y coordinate */ int ObjectsManager::getSpriteY(int idx) { - assert (idx <= MAX_SPRITE); + assert(idx <= MAX_SPRITE); return _sprite[idx]._spritePos.y; } @@ -1260,12 +1261,12 @@ void ObjectsManager::clearSprite() { } void ObjectsManager::animateSprite(int idx) { - assert (idx <= MAX_SPRITE); + assert(idx <= MAX_SPRITE); _sprite[idx]._animationType = 1; } void ObjectsManager::addStaticSprite(const byte *spriteData, Common::Point pos, int idx, int spriteIndex, int zoomFactor, bool flipFl, int deltaX, int deltaY) { - assert (idx <= MAX_SPRITE); + assert(idx <= MAX_SPRITE); SpriteItem *spr = &_sprite[idx]; spr->_spriteData = spriteData; @@ -1298,7 +1299,7 @@ void ObjectsManager::removeSprite(int idx) { * Set Sprite X coordinate */ void ObjectsManager::setSpriteX(int idx, int xp) { - assert (idx <= MAX_SPRITE); + assert(idx <= MAX_SPRITE); _sprite[idx]._spritePos.x = xp; } @@ -1306,7 +1307,7 @@ void ObjectsManager::setSpriteX(int idx, int xp) { * Set Sprite Y coordinate */ void ObjectsManager::setSpriteY(int idx, int yp) { - assert (idx <= MAX_SPRITE); + assert(idx <= MAX_SPRITE); _sprite[idx]._spritePos.y = yp; } @@ -1314,19 +1315,19 @@ void ObjectsManager::setSpriteY(int idx, int yp) { * Set Sprite Index */ void ObjectsManager::setSpriteIndex(int idx, int spriteIndex) { - assert (idx <= MAX_SPRITE); + assert(idx <= MAX_SPRITE); _sprite[idx]._spriteIndex = spriteIndex; } // Set Sprite Size void ObjectsManager::setSpriteZoom(int idx, int zoomFactor) { - assert (idx <= MAX_SPRITE); + assert(idx <= MAX_SPRITE); if (!_sprite[idx]._rleFl) _sprite[idx]._zoomFactor = zoomFactor; } void ObjectsManager::setFlipSprite(int idx, bool flipFl) { - assert (idx <= MAX_SPRITE); + assert(idx <= MAX_SPRITE); if (!_sprite[idx]._rleFl) _sprite[idx]._flipFl = flipFl; } @@ -2185,7 +2186,7 @@ void ObjectsManager::changeCharacterHead(PlayerCharacter oldCharacter, PlayerCha loc->_pos.y = getSpriteY(0); loc->_startSpriteIndex = 64; loc->_location = _vm->_globals->_screenId; - loc->_zoomFactor = _sprite[0]._animationType; + loc->_zoomFactor = _sprite[0]._zoomFactor; removeSprite(1); addStaticSprite(_headSprites, loc->_pos, 1, 3, loc->_zoomFactor, false, 20, 127); @@ -2198,7 +2199,7 @@ void ObjectsManager::changeCharacterHead(PlayerCharacter oldCharacter, PlayerCha loc = &_vm->_globals->_saveData->_realHopkins; _vm->_globals->_characterSpriteBuf = _vm->_fileIO->loadFile("PERSO.SPR"); - _vm->_globals->_characterType = 0; + _vm->_globals->_characterType = CHARACTER_HOPKINS; addStaticSprite(_vm->_globals->_characterSpriteBuf, loc->_pos, 0, 64, loc->_zoomFactor, false, 34, 190); animateSprite(0); _vm->_globals->loadCharacterData(); @@ -2223,7 +2224,7 @@ void ObjectsManager::changeCharacterHead(PlayerCharacter oldCharacter, PlayerCha loc = &_vm->_globals->_saveData->_samantha; _vm->_globals->_characterSpriteBuf = _vm->_fileIO->loadFile("PSAMAN.SPR"); - _vm->_globals->_characterType = 2; + _vm->_globals->_characterType = CHARACTER_SAMANTHA; addStaticSprite(_vm->_globals->_characterSpriteBuf, loc->_pos, 0, 64, loc->_zoomFactor, false, 20, 127); animateSprite(0); _vm->_globals->loadCharacterData(); @@ -2286,9 +2287,9 @@ void ObjectsManager::changeCharacterHead(PlayerCharacter oldCharacter, PlayerCha // Check Size void ObjectsManager::computeAndSetSpriteSize() { int size = _vm->_globals->_spriteSize[getSpriteY(0)]; - if (_vm->_globals->_characterType == 1) { + if (_vm->_globals->_characterType == CHARACTER_HOPKINS_CLONE) { size = 20 * (5 * abs(size) - 100) / -80; - } else if (_vm->_globals->_characterType == 2) { + } else if (_vm->_globals->_characterType == CHARACTER_SAMANTHA) { size = 20 * (5 * abs(size) - 165) / -67; } setSpriteZoom(0, size); @@ -2675,7 +2676,7 @@ void ObjectsManager::handleSpecialGames() { _vm->_soundMan->_specialSoundNum = 198; _charactersEnabledFl = true; _vm->_animMan->unsetClearAnimFlag(); - _vm->_animMan->playAnim("otage.ANM", 1, 24, 500, true); + _vm->_animMan->playAnim("OTAGE.ANM", "OTAGE.ANM", 1, 24, 500, true); _vm->_soundMan->_specialSoundNum = 0; _vm->_graphicsMan->displayScreen(false); @@ -2889,7 +2890,7 @@ void ObjectsManager::doActionRight(int idx) { showSpecialActionAnimationWithFlip(_gestureBuf, "23,24,25,-1,", 8, false); break; case 6: - showSpecialActionAnimation(_gestureBuf, "24,,23,-1,", 8); + showSpecialActionAnimation(_gestureBuf, "24,23,-1,", 8); break; case 7: showSpecialActionAnimationWithFlip(_gestureBuf, "23,24,25,26,27,-1,", 8, false); @@ -2933,7 +2934,7 @@ void ObjectsManager::doActionDiagRight(int idx) { showSpecialActionAnimation(_gestureBuf, "17,16,15,-1,", 8); break; case 7: - showSpecialActionAnimationWithFlip(_gestureBuf, "15,16,17,18,19,20-1,", 8, false); + showSpecialActionAnimationWithFlip(_gestureBuf, "15,16,17,18,19,20,-1,", 8, false); break; case 8: showSpecialActionAnimation(_gestureBuf, "19,18,17,16,15,-1,", 8); @@ -3035,7 +3036,7 @@ void ObjectsManager::doActionLeft(int idx) { showSpecialActionAnimationWithFlip(_gestureBuf, "23,24,25,-1,", 8, true); break; case 6: - showSpecialActionAnimation(_gestureBuf, "24,,23,-1,", 8); + showSpecialActionAnimation(_gestureBuf, "24,23,-1,", 8); break; case 7: showSpecialActionAnimationWithFlip(_gestureBuf, "23,24,25,26,27,-1,", 8, true); @@ -3087,6 +3088,7 @@ void ObjectsManager::setBobAnimDataIdx(int idx, int animIdx) { * Set Hopkins animation */ void ObjectsManager::setBobAnimation(int idx) { + assert(idx < 36); BobItem *bob = &_bob[idx]; if (!bob->_disabledAnimationFl) return; @@ -3102,6 +3104,7 @@ void ObjectsManager::setBobAnimation(int idx) { * Stop Hopkins animation */ void ObjectsManager::stopBobAnimation(int idx) { + assert(idx < 36); _bob[idx]._disabledAnimationFl = true; } @@ -3438,6 +3441,7 @@ void ObjectsManager::disableVerb(int idx, int a2) { case 13: case 22: curZone->_verbFl8 = 0; + break; case 14: case 21: case 25: @@ -3709,7 +3713,7 @@ void ObjectsManager::handleForest(int screenId, int minX, int maxX, int minY, in } if (_vm->_globals->_saveData->_data[savegameIdx] == 3) { _vm->_graphicsMan->_fadingFl = true; - _vm->_animMan->playAnim("CREVE2.ANM", 100, 24, 500); + _vm->_animMan->playAnim("CREVE2.ANM", "CREVE2.ANM", 100, 24, 500); _vm->_globals->_exitId = 150; _vm->_graphicsMan->_noFadingFl = true; hideBob(1); @@ -3857,30 +3861,29 @@ void ObjectsManager::sceneControl2(const Common::String &backgroundFile, const C _vm->_graphicsMan->setColorPercentage(253, 100, 100, 100); _vm->_graphicsMan->setColorPercentage(251, 100, 100, 100); _vm->_graphicsMan->setColorPercentage(254, 0, 0, 0); - if (_vm->_globals->_characterType) { - if (!_vm->_globals->_saveData->_data[svAlternateSpriteFl] && !_vm->_globals->_saveData->_data[svField356]) { - _vm->_globals->_characterSpriteBuf = _vm->_fileIO->loadFile("PERSO.SPR"); - _vm->_globals->_characterType = 0; - } + if (_vm->_globals->_characterType != CHARACTER_HOPKINS && !_vm->_globals->_saveData->_data[svAlternateSpriteFl] && !_vm->_globals->_saveData->_data[svField356]) { + _vm->_globals->_characterSpriteBuf = _vm->_fileIO->loadFile("PERSO.SPR"); + _vm->_globals->_characterType = CHARACTER_HOPKINS; } - if (!_vm->_globals->_characterType && _vm->_globals->_saveData->_data[svAlternateSpriteFl] == 1) { + + if (_vm->_globals->_characterType == CHARACTER_HOPKINS && _vm->_globals->_saveData->_data[svAlternateSpriteFl] == 1) { _vm->_globals->_characterSpriteBuf = _vm->_fileIO->loadFile("HOPFEM.SPR"); - _vm->_globals->_characterType = 1; + _vm->_globals->_characterType = CHARACTER_HOPKINS_CLONE; } - if (_vm->_globals->_characterType != 2 && _vm->_globals->_saveData->_data[svField356] == 1) { + if (_vm->_globals->_characterType != CHARACTER_SAMANTHA && _vm->_globals->_saveData->_data[svField356] == 1) { _vm->_globals->_characterSpriteBuf = _vm->_fileIO->loadFile("PSAMAN.SPR"); - _vm->_globals->_characterType = 2; + _vm->_globals->_characterType = CHARACTER_SAMANTHA; } _vm->_globals->loadCharacterData(); switch (_vm->_globals->_characterType) { - case 0: + case CHARACTER_HOPKINS: addStaticSprite(_vm->_globals->_characterSpriteBuf, _characterPos, 0, _startSpriteIndex, 0, false, 34, 190); break; - case 1: + case CHARACTER_HOPKINS_CLONE: addStaticSprite(_vm->_globals->_characterSpriteBuf, _characterPos, 0, _startSpriteIndex, 0, false, 28, 155); break; - case 2: + case CHARACTER_SAMANTHA: addStaticSprite(_vm->_globals->_characterSpriteBuf, _characterPos, 0, _startSpriteIndex, 0, false, 20, 127); break; } diff --git a/engines/hopkins/objects.h b/engines/hopkins/objects.h index a5e309344b..5f1f5b1f59 100644 --- a/engines/hopkins/objects.h +++ b/engines/hopkins/objects.h @@ -239,7 +239,7 @@ public: byte *_headSprites; SpriteItem _sprite[6]; BobItem _bob[36]; - LockAnimItem _lockedAnims[30]; + LockAnimItem _lockedAnims[36]; bool _charactersEnabledFl; bool _refreshBobMode10Fl; diff --git a/engines/hopkins/saveload.cpp b/engines/hopkins/saveload.cpp index af0b043641..45b4885c90 100644 --- a/engines/hopkins/saveload.cpp +++ b/engines/hopkins/saveload.cpp @@ -307,6 +307,10 @@ void SaveLoadManager::convertThumb16To8(Graphics::Surface *thumb16, Graphics::Su byte r, g, b; pixelFormat16.colorToRGB(*lineSrcP++, r, g, b); + // Do like in the original and show thumbnail as a grayscale picture + int lum = (r * 21 + g * 72 + b * 7) / 100; + r = g = b = lum; + // Scan the palette for the closest match int difference = 99999, foundIndex = 0; for (int palIndex = 0; palIndex < PALETTE_SIZE; ++palIndex) { diff --git a/engines/hopkins/script.cpp b/engines/hopkins/script.cpp index 6167ac4c23..c39273203d 100644 --- a/engines/hopkins/script.cpp +++ b/engines/hopkins/script.cpp @@ -65,8 +65,6 @@ int ScriptManager::handleOpcode(const byte *dataP) { mesgId = 639; if (mesgId == 8) mesgId = 637; - if (mesgId == 53) - mesgId = 644; if (mesgId == 557) mesgId = 636; if (mesgId == 51) @@ -99,8 +97,6 @@ int ScriptManager::handleOpcode(const byte *dataP) { mesgId = 646; if (mesgId == 604) mesgId = 647; - if (mesgId == 51) - mesgId = 644; if (mesgId == 607) mesgId = 650; if (mesgId == 605) @@ -201,64 +197,70 @@ int ScriptManager::handleOpcode(const byte *dataP) { opcodeType = 1; break; case MKTAG24('S', 'T', 'P'): - if (!_vm->_objectsMan->_disableFl) { - _vm->_objectsMan->_twoCharactersFl = false; - _vm->_objectsMan->_characterPos.x = READ_LE_INT16(dataP + 6); - _vm->_objectsMan->_characterPos.y = READ_LE_INT16(dataP + 8); - _vm->_objectsMan->_startSpriteIndex = dataP[5]; - if (_vm->_objectsMan->_changeHeadFl) { - if (_vm->_globals->_saveData->_data[svField354] == 1 - && _vm->_globals->_saveData->_cloneHopkins._pos.x && _vm->_globals->_saveData->_cloneHopkins._pos.y - && _vm->_globals->_saveData->_cloneHopkins._startSpriteIndex && _vm->_globals->_saveData->_cloneHopkins._location) { - - _vm->_objectsMan->_characterPos = _vm->_globals->_saveData->_cloneHopkins._pos; - _vm->_objectsMan->_startSpriteIndex = _vm->_globals->_saveData->_cloneHopkins._startSpriteIndex; - } - if (_vm->_globals->_saveData->_data[svField356] == 1 - && _vm->_globals->_saveData->_samantha._pos.x && _vm->_globals->_saveData->_samantha._pos.y - && _vm->_globals->_saveData->_samantha._startSpriteIndex && _vm->_globals->_saveData->_samantha._location) { - _vm->_objectsMan->_characterPos = _vm->_globals->_saveData->_samantha._pos; - _vm->_objectsMan->_startSpriteIndex = _vm->_globals->_saveData->_samantha._startSpriteIndex; - } - if (_vm->_globals->_saveData->_data[svField357] == 1 - && _vm->_globals->_saveData->_realHopkins._pos.x && _vm->_globals->_saveData->_realHopkins._pos.y - && _vm->_globals->_saveData->_realHopkins._startSpriteIndex && _vm->_globals->_saveData->_realHopkins._location) { - _vm->_objectsMan->_characterPos = _vm->_globals->_saveData->_realHopkins._pos; - _vm->_objectsMan->_startSpriteIndex = _vm->_globals->_saveData->_realHopkins._startSpriteIndex; - } + if (!_vm->_objectsMan->_disableFl) { + // HACK: This piece of code is a replacement to the missing STE opcode when entering the FBI lab. + if (_vm->_globals->_curRoomNum == 10) { + _vm->_globals->_prevScreenId = _vm->_globals->_screenId; + _vm->_globals->_saveData->_data[svLastPrevScreenId] = _vm->_globals->_screenId; + _vm->_globals->_screenId = _vm->_globals->_saveData->_data[svLastScreenId] = 10; + } + _vm->_objectsMan->_twoCharactersFl = false; + _vm->_objectsMan->_characterPos.x = READ_LE_INT16(dataP + 6); + _vm->_objectsMan->_characterPos.y = READ_LE_INT16(dataP + 8); + _vm->_objectsMan->_startSpriteIndex = dataP[5]; + if (_vm->_objectsMan->_changeHeadFl) { + if (_vm->_globals->_saveData->_data[svField354] == 1 + && _vm->_globals->_saveData->_cloneHopkins._pos.x && _vm->_globals->_saveData->_cloneHopkins._pos.y + && _vm->_globals->_saveData->_cloneHopkins._startSpriteIndex && _vm->_globals->_saveData->_cloneHopkins._location) { + + _vm->_objectsMan->_characterPos = _vm->_globals->_saveData->_cloneHopkins._pos; + _vm->_objectsMan->_startSpriteIndex = _vm->_globals->_saveData->_cloneHopkins._startSpriteIndex; } if (_vm->_globals->_saveData->_data[svField356] == 1 - && _vm->_globals->_saveData->_realHopkins._location == _vm->_globals->_screenId) { - _vm->_objectsMan->addStaticSprite( - _vm->_objectsMan->_headSprites, - _vm->_globals->_saveData->_realHopkins._pos, - 1, - 2, - _vm->_globals->_saveData->_realHopkins._zoomFactor, - false, - 34, - 190); - _vm->_objectsMan->animateSprite(1); - _vm->_objectsMan->_twoCharactersFl = true; + && _vm->_globals->_saveData->_samantha._pos.x && _vm->_globals->_saveData->_samantha._pos.y + && _vm->_globals->_saveData->_samantha._startSpriteIndex && _vm->_globals->_saveData->_samantha._location) { + _vm->_objectsMan->_characterPos = _vm->_globals->_saveData->_samantha._pos; + _vm->_objectsMan->_startSpriteIndex = _vm->_globals->_saveData->_samantha._startSpriteIndex; } if (_vm->_globals->_saveData->_data[svField357] == 1 - && _vm->_globals->_saveData->_data[svField355] == 1 - && _vm->_globals->_saveData->_samantha._location == _vm->_globals->_screenId) { - _vm->_objectsMan->addStaticSprite( - _vm->_objectsMan->_headSprites, - _vm->_globals->_saveData->_samantha._pos, - 1, - 3, - _vm->_globals->_saveData->_samantha._zoomFactor, - false, - 20, - 127); - _vm->_objectsMan->animateSprite(1); - _vm->_objectsMan->_twoCharactersFl = true; + && _vm->_globals->_saveData->_realHopkins._pos.x && _vm->_globals->_saveData->_realHopkins._pos.y + && _vm->_globals->_saveData->_realHopkins._startSpriteIndex && _vm->_globals->_saveData->_realHopkins._location) { + _vm->_objectsMan->_characterPos = _vm->_globals->_saveData->_realHopkins._pos; + _vm->_objectsMan->_startSpriteIndex = _vm->_globals->_saveData->_realHopkins._startSpriteIndex; } } - opcodeType = 1; - _vm->_objectsMan->_changeHeadFl = false; + if (_vm->_globals->_saveData->_data[svField356] == 1 + && _vm->_globals->_saveData->_realHopkins._location == _vm->_globals->_screenId) { + _vm->_objectsMan->addStaticSprite( + _vm->_objectsMan->_headSprites, + _vm->_globals->_saveData->_realHopkins._pos, + 1, + 2, + _vm->_globals->_saveData->_realHopkins._zoomFactor, + false, + 34, + 190); + _vm->_objectsMan->animateSprite(1); + _vm->_objectsMan->_twoCharactersFl = true; + } + if (_vm->_globals->_saveData->_data[svField357] == 1 + && _vm->_globals->_saveData->_data[svField355] == 1 + && _vm->_globals->_saveData->_samantha._location == _vm->_globals->_screenId) { + _vm->_objectsMan->addStaticSprite( + _vm->_objectsMan->_headSprites, + _vm->_globals->_saveData->_samantha._pos, + 1, + 3, + _vm->_globals->_saveData->_samantha._zoomFactor, + false, + 20, + 127); + _vm->_objectsMan->animateSprite(1); + _vm->_objectsMan->_twoCharactersFl = true; + } + } + opcodeType = 1; + _vm->_objectsMan->_changeHeadFl = false; break; case MKTAG24('S', 'T', 'E'): if (!_vm->_objectsMan->_disableFl) { @@ -585,7 +587,7 @@ int ScriptManager::handleOpcode(const byte *dataP) { if (!_vm->_globals->_censorshipFl) { _vm->_soundMan->_specialSoundNum = 16; _vm->_graphicsMan->_fadingFl = true; - _vm->_animMan->playAnim("EGORGE.ANM", 50, 28, 500); + _vm->_animMan->playAnim("EGORGE.ANM", "EGORGE.ANM", 50, 28, 500); _vm->_soundMan->_specialSoundNum = 0; } _vm->_animMan->loadAnim("ASCEN"); @@ -726,7 +728,7 @@ int ScriptManager::handleOpcode(const byte *dataP) { _vm->_animMan->playSequence("grenade.SEQ", 1, 32, 100, false, false); _vm->_soundMan->_specialSoundNum = 0; _vm->_graphicsMan->_fadingFl = true; - _vm->_animMan->playAnim("CREVE17.ANM", 24, 24, 200); + _vm->_animMan->playAnim("CREVE17.ANM", "CREVE17.ANM", 24, 24, 200); _vm->_soundMan->removeSample(1); _vm->_soundMan->removeSample(2); _vm->_soundMan->removeSample(3); @@ -953,21 +955,23 @@ int ScriptManager::handleOpcode(const byte *dataP) { case 56: _vm->_globals->_characterSpriteBuf = _vm->_fileIO->loadFile("HOPFEM.SPR"); - _vm->_globals->_characterType = 1; + _vm->_globals->_characterType = CHARACTER_HOPKINS_CLONE; _vm->_globals->_saveData->_data[svAlternateSpriteFl] = 1; _vm->_globals->loadCharacterData(); _vm->_objectsMan->_sprite[0]._deltaX = 28; _vm->_objectsMan->_sprite[0]._deltaY = 155; + _vm->_objectsMan->_sprite[0]._spriteData = _vm->_globals->_characterSpriteBuf; _vm->_objectsMan->computeAndSetSpriteSize(); break; case 57: _vm->_globals->_characterSpriteBuf = _vm->_fileIO->loadFile("PERSO.SPR"); - _vm->_globals->_characterType = 0; + _vm->_globals->_characterType = CHARACTER_HOPKINS; _vm->_globals->_saveData->_data[svAlternateSpriteFl] = 0; _vm->_globals->loadCharacterData(); _vm->_objectsMan->_sprite[0]._deltaX = 34; _vm->_objectsMan->_sprite[0]._deltaY = 190; + _vm->_objectsMan->_sprite[0]._spriteData = _vm->_globals->_characterSpriteBuf; _vm->_objectsMan->computeAndSetSpriteSize(); break; @@ -1071,6 +1075,7 @@ int ScriptManager::handleOpcode(const byte *dataP) { _vm->_soundMan->playWav(2); playFl = true; } + break; case 6: playFl = false; break; @@ -1395,7 +1400,7 @@ int ScriptManager::handleOpcode(const byte *dataP) { _vm->_globals->_introSpeechOffFl = true; _vm->_talkMan->startAnimatedCharacterDialogue("tourist1.pe2"); _vm->_globals->_introSpeechOffFl = false; - _vm->_animMan->playAnim2("T421.ANM", 100, 14, 500); + _vm->_animMan->playAnim2("T421A.ANM", "T421.ANM", 100, 14, 500); _vm->_events->refreshScreenAndEvents(); _vm->_events->refreshScreenAndEvents(); _vm->_events->refreshScreenAndEvents(); @@ -1957,7 +1962,7 @@ int ScriptManager::handleOpcode(const byte *dataP) { _vm->_animMan->playSequence("SECRET2.SEQ", 1, 12, 100, false, true); _vm->_soundMan->_specialSoundNum = 0; _vm->_graphicsMan->_noFadingFl = true; - _vm->_graphicsMan->fadeOutLong(); + _vm->_graphicsMan->fadeOutShort(); for (int i = 1; i <= 39; i++) { if (_vm->shouldQuit()) @@ -2326,7 +2331,7 @@ int ScriptManager::handleOpcode(const byte *dataP) { if (!_vm->getIsDemo()) { _vm->_graphicsMan->_fadingFl = true; _vm->_graphicsMan->_fadeDefaultSpeed = 1; - _vm->_animMan->playAnim("BOMBE1A.ANM", 100, 18, 100); + _vm->_animMan->playAnim("BOMBE1A.ANM", "BOMBE1.ANM", 100, 18, 100); } _vm->_graphicsMan->loadImage("BOMBEB"); _vm->_graphicsMan->setColorPercentage(252, 100, 100, 100); @@ -2352,7 +2357,7 @@ int ScriptManager::handleOpcode(const byte *dataP) { _vm->_objectsMan->setAndPlayAnim(3, 0, 16, true); _vm->_soundMan->_specialSoundNum = 199; _vm->_graphicsMan->_fadingFl = true; - _vm->_animMan->playAnim("BOMBE2A.ANM", 50, 14, 500); + _vm->_animMan->playAnim("BOMBE2A.ANM", "BOMBE2.ANM", 50, 14, 500); _vm->_soundMan->_specialSoundNum = 0; memset(_vm->_graphicsMan->_frontBuffer, 0, 614400); _vm->_graphicsMan->_noFadingFl = true; @@ -2363,7 +2368,7 @@ int ScriptManager::handleOpcode(const byte *dataP) { _vm->_graphicsMan->fastDisplay(_vm->_globals->_levelSpriteBuf, 513, 163, 7, false); _vm->_objectsMan->setAndPlayAnim(1, 0, 16, true); _vm->_soundMan->_specialSoundNum = 199; - _vm->_animMan->playAnim("BOMBE2A.ANM", 50, 14, 500); + _vm->_animMan->playAnim("BOMBE2A.ANM", "BOMBE2.ANM", 50, 14, 500); _vm->_soundMan->_specialSoundNum = 0; _vm->_graphicsMan->_noFadingFl = true; memset(_vm->_graphicsMan->_frontBuffer, 0, 614400); @@ -2376,7 +2381,7 @@ int ScriptManager::handleOpcode(const byte *dataP) { _vm->_graphicsMan->fadeOutShort(); _vm->_soundMan->_specialSoundNum = 199; _vm->_graphicsMan->_fadingFl = true; - _vm->_animMan->playAnim("BOMBE2A.ANM", 50, 14, 500); + _vm->_animMan->playAnim("BOMBE2A.ANM", "BOMBE2.ANM", 50, 14, 500); _vm->_soundMan->_specialSoundNum = 0; _vm->_graphicsMan->_noFadingFl = true; memset(_vm->_graphicsMan->_frontBuffer, 0, 614400); @@ -2387,7 +2392,7 @@ int ScriptManager::handleOpcode(const byte *dataP) { _vm->_graphicsMan->fastDisplay(_vm->_globals->_levelSpriteBuf, 513, 163, 7, false); _vm->_objectsMan->setAndPlayAnim(6, 0, 16, true); if ((_vm->getPlatform() != Common::kPlatformWindows) || !_vm->getIsDemo()) { - _vm->_animMan->playAnim("BOMBE3A.ANM", 50, 14, 500); + _vm->_animMan->playAnim("BOMBE3A.ANM", "BOMBE3.ANM", 50, 14, 500); memset(_vm->_graphicsMan->_frontBuffer, 0, 614400); } _vm->_globals->_exitId = 6; @@ -2397,7 +2402,7 @@ int ScriptManager::handleOpcode(const byte *dataP) { // Display bomb plan if (!_vm->getIsDemo()) { memcpy(_vm->_graphicsMan->_oldPalette, _vm->_graphicsMan->_palette, 769); - _vm->_animMan->playAnim2("PLAN.ANM", 50, 10, 800); + _vm->_animMan->playAnim2("PLAN.ANM", "PLAN.ANM", 50, 10, 800); } _vm->_graphicsMan->resetDirtyRects(); break; diff --git a/engines/hopkins/sound.cpp b/engines/hopkins/sound.cpp index d8dfba5246..bf816c08a4 100644 --- a/engines/hopkins/sound.cpp +++ b/engines/hopkins/sound.cpp @@ -456,10 +456,8 @@ void SoundManager::checkSounds() { void SoundManager::checkVoiceActivity() { // Check the status of each voice. bool hasActiveVoice = false; - for (int i = 0; i < VOICE_COUNT; ++i) { - checkVoiceStatus(i); - hasActiveVoice |= _voice[i]._status; - } + for (int i = 0; i < VOICE_COUNT; ++i) + hasActiveVoice |= checkVoiceStatus(i); if (!hasActiveVoice && _soundFl) { _soundFl = false; @@ -469,7 +467,6 @@ void SoundManager::checkVoiceActivity() { bool SoundManager::mixVoice(int voiceId, int voiceMode, bool dispTxtFl) { int fileNumber; - int oldMusicVol; bool breakFlag; Common::String prefix; Common::String filename; @@ -575,7 +572,7 @@ bool SoundManager::mixVoice(int voiceId, int voiceMode, bool dispTxtFl) { } } } - oldMusicVol = _musicVolume; + int oldMusicVol = _musicVolume; if (!loadVoice(filename, catPos, catLen, _sWav[20])) { // This case only concerns the English Win95 demo // If it's not possible to load the voice, we force the active flag @@ -634,8 +631,6 @@ void SoundManager::removeSample(int soundIndex) { stopVoice(1); if (checkVoiceStatus(2)) stopVoice(2); - if (checkVoiceStatus(3)) - stopVoice(3); removeWavSample(soundIndex); _sound[soundIndex]._active = false; } @@ -703,7 +698,6 @@ void SoundManager::playSample(int wavIndex, int voiceMode) { switch (voiceMode) { case 5: - case 8: // Case added to identify the former PLAY_SAMPLE2 calls case 9: if (checkVoiceStatus(1)) @@ -715,11 +709,6 @@ void SoundManager::playSample(int wavIndex, int voiceMode) { stopVoice(1); playWavSample(2, wavIndex); break; - case 7: - if (checkVoiceStatus(3)) - stopVoice(1); - playWavSample(3, wavIndex); - break; default: break; } |