aboutsummaryrefslogtreecommitdiff
path: root/engines/hopkins
diff options
context:
space:
mode:
Diffstat (limited to 'engines/hopkins')
-rw-r--r--engines/hopkins/anim.cpp85
-rw-r--r--engines/hopkins/anim.h4
-rw-r--r--engines/hopkins/computer.cpp12
-rw-r--r--engines/hopkins/debugger.cpp23
-rw-r--r--engines/hopkins/debugger.h2
-rw-r--r--engines/hopkins/detection_tables.h32
-rw-r--r--engines/hopkins/dialogs.cpp2
-rw-r--r--engines/hopkins/events.cpp2
-rw-r--r--engines/hopkins/font.cpp1
-rw-r--r--engines/hopkins/globals.cpp6
-rw-r--r--engines/hopkins/globals.h2
-rw-r--r--engines/hopkins/graphics.cpp82
-rw-r--r--engines/hopkins/graphics.h7
-rw-r--r--engines/hopkins/hopkins.cpp194
-rw-r--r--engines/hopkins/hopkins.h13
-rw-r--r--engines/hopkins/lines.cpp118
-rw-r--r--engines/hopkins/lines.h10
-rw-r--r--engines/hopkins/menu.cpp6
-rw-r--r--engines/hopkins/objects.cpp71
-rw-r--r--engines/hopkins/objects.h2
-rw-r--r--engines/hopkins/saveload.cpp4
-rw-r--r--engines/hopkins/script.cpp141
-rw-r--r--engines/hopkins/sound.cpp17
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;
}