aboutsummaryrefslogtreecommitdiff
path: root/engines/hopkins
diff options
context:
space:
mode:
Diffstat (limited to 'engines/hopkins')
-rw-r--r--engines/hopkins/debugger.cpp12
-rw-r--r--engines/hopkins/debugger.h1
-rw-r--r--engines/hopkins/detection.cpp1
-rw-r--r--engines/hopkins/detection_tables.h134
-rw-r--r--engines/hopkins/graphics.cpp37
-rw-r--r--engines/hopkins/graphics.h6
-rw-r--r--engines/hopkins/hopkins.cpp53
-rw-r--r--engines/hopkins/hopkins.h13
-rw-r--r--engines/hopkins/lines.cpp106
-rw-r--r--engines/hopkins/lines.h4
10 files changed, 192 insertions, 175 deletions
diff --git a/engines/hopkins/debugger.cpp b/engines/hopkins/debugger.cpp
index 762df0adaa..f111eb50d3 100644
--- a/engines/hopkins/debugger.cpp
+++ b/engines/hopkins/debugger.cpp
@@ -35,6 +35,7 @@ Debugger::Debugger(HopkinsEngine *vm) : GUI::Debugger() {
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
@@ -75,4 +76,15 @@ if (argc != 2) {
}
}
+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 16b5f872d6..746c54a675 100644
--- a/engines/hopkins/debugger.h
+++ b/engines/hopkins/debugger.h
@@ -42,6 +42,7 @@ public:
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.cpp b/engines/hopkins/detection.cpp
index a42597415b..9d16b0ab51 100644
--- a/engines/hopkins/detection.cpp
+++ b/engines/hopkins/detection.cpp
@@ -67,6 +67,7 @@ static const PlainGameDescriptor hopkinsGames[] = {
const static char *directoryGlobs[] = {
"voice",
+ "link",
0
};
diff --git a/engines/hopkins/detection_tables.h b/engines/hopkins/detection_tables.h
index 3e04375fe9..c3ff563f6f 100644
--- a/engines/hopkins/detection_tables.h
+++ b/engines/hopkins/detection_tables.h
@@ -24,12 +24,11 @@ namespace Hopkins {
static const HopkinsGameDescription gameDescriptions[] = {
{
- // Hopkins FBI Linux Demo 1.00
+ // Hopkins FBI Linux Demo UK 1.00 and 1.02
{
"hopkins",
- "Linux Demo v1.00",
+ "Linux Demo",
{
- {"Hopkins-PDemo.bin", 0, "88b4d6e14b9b1407083cb3d1213c0fa7", 272027},
{"RES_VAN.RES", 0, "29414c05be8f9fe794c61572a65def12", 16060544},
AD_LISTEND
},
@@ -39,32 +38,14 @@ static const HopkinsGameDescription gameDescriptions[] = {
GUIO1(GUIO_NONE)
},
},
-
- {
- // Hopkins FBI Linux Demo 1.02
- {
- "hopkins",
- "Linux Demo v1.02",
- {
- {"Hopkins-PDemo.bin", 0, "f82f4e698f3a189419351be0de2b2f8e", 273760},
- {"RES_VAN.RES", 0, "29414c05be8f9fe794c61572a65def12", 16060544},
- AD_LISTEND
- },
- Common::EN_ANY,
- Common::kPlatformLinux,
- ADGF_DEMO,
- GUIO1(GUIO_NONE)
- },
- },
-
{
// Hopkins FBI OS/2, provided by Strangerke
{
"hopkins",
0,
{
- {"Hopkins.exe", 0, "63d45f882278e5a9fa1027066223e5d9", 292864},
{"ENG_VOI.RES", 0, "fa5789d1d8c19d160bce44a33e742fdf", 66860711},
+ {"CREAN.TXT", 0, "e13aa69d9e043f066776e1d0ef98fdf5", 1871},
AD_LISTEND
},
Common::EN_ANY,
@@ -74,93 +55,41 @@ static const HopkinsGameDescription gameDescriptions[] = {
},
},
{
- // Hopkins FBI Win95 Demo, provided by Strangerke
- // CHECKME: No voice! a second file is required though... Also, it has multi-language support
- {
- "hopkins",
- "Win95 Demo",
- {
- {"Hopkins.exe", 0, "0c9ebfe371f4dcf84a49f333f04839a0", 376897},
- AD_LISTEND
- },
- Common::EN_ANY,
- Common::kPlatformWindows,
- ADGF_DEMO,
- GUIO1(GUIO_NONE)
- },
- },
- {
- // Hopkins FBI Win95 Polish Demo, provided by Strangerke
- {
- "hopkins",
- "Win95 Demo",
- {
- {"Hopkins.exe", 0, "7595c0b9374739b212ee9f8f412ac716", 307200},
- {"RES_VAN.RES", 0, "8262cfba261c200af4451902689dffe0", 12233202},
- AD_LISTEND
- },
- Common::PL_POL,
- Common::kPlatformWindows,
- ADGF_DEMO,
- GUIO1(GUIO_NONE)
- },
- },
- {
- // Hopkins FBI Win95 Spanish
- {
- "hopkins",
- 0,
- {
- {"Hopkins.exe", 0, "31c837378bb2e0b2573befea44956d3f", 421386},
- {"RES_VES.RES", 0, "77ee08896466ae88cc1af3bf1a0bf78c", 32882302},
- AD_LISTEND
- },
- Common::ES_ESP,
- Common::kPlatformWindows,
- ADGF_NO_FLAGS,
- GUIO1(GUIO_NONE)
- },
- },
- {
- // Hopkins FBI Win95, provided by Strangerke
+ // Hopkins FBI BeOS, provided by Strangerke & Eriktorbjorn
{
"hopkins",
0,
{
- {"Hopkins.exe", 0, "277a5c144bf9ec7d8450ae37afb85090", 419281},
- {"RES_VAN.RES", 0, "f1693ac0b0859c8ecd8cb30ff43cf55f", 38296346},
+ {"ENG_VOI.RES", 0, "fa5789d1d8c19d160bce44a33e742fdf", 66860711},
AD_LISTEND
},
Common::EN_ANY,
- Common::kPlatformWindows,
+ Common::kPlatformBeOS,
ADGF_NO_FLAGS,
GUIO1(GUIO_NONE)
},
},
{
- // Hopkins FBI Win95, provided by alexbevi
- // Dec 15 1998 hopkins.exe
+ // Hopkins FBI Win95 Spanish
{
"hopkins",
0,
{
- {"Hopkins.exe", 0, "a587762dd50d5933e1c89f9975180764", 378694},
- {"RES_VAN.RES", 0, "f1693ac0b0859c8ecd8cb30ff43cf55f", 38296346},
+ {"RES_VES.RES", 0, "77ee08896466ae88cc1af3bf1a0bf78c", 32882302},
AD_LISTEND
},
- Common::EN_ANY,
+ Common::ES_ESP,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
GUIO1(GUIO_NONE)
},
},
{
- // Hopkins FBI Win95 EN, provided by greencis in bug #3612406
+ // Hopkins FBI Win95 UK, provided by Strangerke, alexbevi, greencis
{
"hopkins",
0,
{
- {"hopkins.exe", 0, "020690049fa1dfcd63a18fdafb139a0e", 421386},
{"RES_VAN.RES", 0, "f1693ac0b0859c8ecd8cb30ff43cf55f", 38296346},
AD_LISTEND
},
@@ -176,7 +105,6 @@ static const HopkinsGameDescription gameDescriptions[] = {
"hopkins",
0,
{
- {"hopkins.exe", 0, "3043fef0bd3bfeba8252647cd090ce09", 419281},
{"res_van.res", 0, "bf17c710e184a25a6c8e9d1d9503c38e", 32197685},
AD_LISTEND
},
@@ -192,7 +120,6 @@ static const HopkinsGameDescription gameDescriptions[] = {
"hopkins",
0,
{
- {"Hopkins.bin", 0, "71611380cb31744bf909b8319a65e6e6", 275844},
{"RES_VFR.RES", 0, "0490d4d1aa71075ebf71cc79e5dc7894", 39817945},
AD_LISTEND
},
@@ -208,7 +135,6 @@ static const HopkinsGameDescription gameDescriptions[] = {
"hopkins",
0,
{
- {"Hopkins.bin", 0, "71611380cb31744bf909b8319a65e6e6", 275844},
{"RES_VAN.RES", 0, "29414c05be8f9fe794c61572a65def12", 38832455},
AD_LISTEND
},
@@ -218,61 +144,53 @@ static const HopkinsGameDescription gameDescriptions[] = {
GUIO1(GUIO_NONE)
},
},
-
{
- // Hopkins FBI BeOS, provided by Strangerke
+ // Hopkins FBI Win95, French, provided by SylvainTV
{
"hopkins",
0,
{
- {"ENG_VOI.RES", 0, "fa5789d1d8c19d160bce44a33e742fdf", 66860711},
- {"Hopkins_ FBI", 0, "8940ce2e618c42691b66aad5d6c223b0", 757936},
+ {"RES_VFR.RES", 0, "b8a3849063c9eeefe80e82cfce1ad3cd", 39269361},
AD_LISTEND
},
- Common::EN_ANY,
- Common::kPlatformBeOS,
+ Common::FR_FRA,
+ Common::kPlatformWindows,
ADGF_NO_FLAGS,
GUIO1(GUIO_NONE)
},
- },
+ },
{
- // Hopkins FBI BeOS, uninstalled, provided by eriktorbjorn
+ // Hopkins FBI Win95 Demo, provided by Strangerke
+ // CHECKME: No voice! a second file is required though... Also, it has multi-language support
{
"hopkins",
- 0,
+ "Win95 Demo",
{
- {"ENG_VOI.RES", 0, "fa5789d1d8c19d160bce44a33e742fdf", 66860711},
- {"Hopkins.pkg", 0, "72f97806dd3d5fc0c0eb24196f180618", 285017},
+ {"Hopkins.exe", 0, "0c9ebfe371f4dcf84a49f333f04839a0", 376897},
AD_LISTEND
},
Common::EN_ANY,
- Common::kPlatformBeOS,
- ADGF_NO_FLAGS,
+ Common::kPlatformWindows,
+ ADGF_DEMO,
GUIO1(GUIO_NONE)
},
-
},
-
{
- // Hopkins FBI Win32, French uninstalled, provided by SylvainTV
+ // Hopkins FBI Win95 Polish Demo, provided by Strangerke
{
"hopkins",
- 0,
+ "Win95 Demo",
{
- {"Hopkins.exe", 0, "277a5c144bf9ec7d8450ae37afb85090", 419281},
- {"RES_VFR.RES", 0, "b8a3849063c9eeefe80e82cfce1ad3cd", 39269361},
+ {"RES_VAN.RES", 0, "8262cfba261c200af4451902689dffe0", 12233202},
AD_LISTEND
},
- Common::FR_FRA,
+ Common::PL_POL,
Common::kPlatformWindows,
- ADGF_NO_FLAGS,
+ ADGF_DEMO,
GUIO1(GUIO_NONE)
},
-
},
-
-
{ AD_TABLE_END_MARKER }
};
diff --git a/engines/hopkins/graphics.cpp b/engines/hopkins/graphics.cpp
index aa71b2c4c0..ebc5cfa8da 100644
--- a/engines/hopkins/graphics.cpp
+++ b/engines/hopkins/graphics.cpp
@@ -74,6 +74,7 @@ GraphicsManager::GraphicsManager(HopkinsEngine *vm) {
_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);
@@ -672,6 +673,9 @@ void GraphicsManager::updateScreen() {
if (_showZones)
displayZones();
+ if (_showLines)
+ displayLines();
+
// Update the screen
g_system->updateScreen();
}
@@ -1176,7 +1180,7 @@ void GraphicsManager::displayZones() {
_vm->_objectsMan->_bob[bobId]._oldX + _vm->_objectsMan->_bob[bobId]._oldWidth,
_vm->_objectsMan->_bob[bobId]._oldY + _vm->_objectsMan->_bob[bobId]._oldHeight);
- displayDebugRect(screenSurface, r);
+ displayDebugRect(screenSurface, r, 0xff0000);
}
}
@@ -1185,14 +1189,39 @@ void GraphicsManager::displayZones() {
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);
+ 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) {
+
+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
@@ -1204,7 +1233,7 @@ void GraphicsManager::displayDebugRect(Graphics::Surface *surface, const Common:
// If there's an on-screen portion, display it
if (r.isValidRect())
- surface->frameRect(r, 0xffffff);
+ surface->frameRect(r, color);
}
/**
diff --git a/engines/hopkins/graphics.h b/engines/hopkins/graphics.h
index 142de129b9..268db7fc2b 100644
--- a/engines/hopkins/graphics.h
+++ b/engines/hopkins/graphics.h
@@ -119,12 +119,13 @@ public:
Common::Array<Common::Rect> _refreshRects;
bool _showDirtyRects;
bool _showZones;
+ bool _showLines;
byte *_palettePixels;
public:
GraphicsManager(HopkinsEngine *vm);
~GraphicsManager();
-
+
void clearPalette();
void clearScreen();
void clearVesaScreen();
@@ -137,7 +138,8 @@ public:
void displayDirtyRects();
void displayRefreshRects();
void displayZones();
- void displayDebugRect(Graphics::Surface *surface, const Common::Rect &srcRect);
+ 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 87d4600187..b023a2fedb 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);
@@ -87,14 +88,15 @@ Common::String HopkinsEngine::generateSaveName(int slot) {
* Returns true if it is currently okay to restore a game
*/
bool HopkinsEngine::canLoadGameStateCurrently() {
- return !_globals->_exitId && !_globals->_cityMapEnabledFl && _events->_mouseFl;
+ return !_globals->_exitId && !_globals->_cityMapEnabledFl && _events->_mouseFl && _globals->_curRoomNum != 0;
}
/**
* Returns true if it is currently okay to save the game
*/
bool HopkinsEngine::canSaveGameStateCurrently() {
- return !_globals->_exitId && !_globals->_cityMapEnabledFl && _events->_mouseFl;
+ return !_globals->_exitId && !_globals->_cityMapEnabledFl && _events->_mouseFl
+ && _globals->_curRoomNum != 0 && !isUnderwaterSubScene();
}
/**
@@ -166,24 +168,24 @@ bool HopkinsEngine::runWin95Demo() {
if (_events->_rateCounter > 700)
_globals->_speed = 3;
- if (_startGameSlot == -1) {
+ if (_startGameSlot == -1)
_graphicsMan->fadeOutLong();
- _globals->_eventMode = EVENTMODE_IGNORE;
- _globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR");
- }
+
+ _globals->_eventMode = EVENTMODE_IGNORE;
+ _globals->_characterSpriteBuf = _fileIO->loadFile("PERSO.SPR");
_globals->_characterType = CHARACTER_HOPKINS;
_objectsMan->_mapCarPosX = _objectsMan->_mapCarPosY = 0;
memset(_globals->_saveData, 0, 2000);
_globals->_exitId = 0;
- if (_startGameSlot != -1)
- _saveLoad->loadGame(_startGameSlot);
-
if (getLanguage() != Common::PL_POL)
if (!displayAdultDisclaimer())
return Common::kNoError;
+ if (_startGameSlot != -1)
+ _saveLoad->loadGame(_startGameSlot);
+
for (;;) {
if (_globals->_exitId == 300)
_globals->_exitId = 0;
@@ -400,14 +402,27 @@ bool HopkinsEngine::runWin95Demo() {
break;
case 151:
- _soundMan->playSound(28);
- _globals->_eventMode = EVENTMODE_ALT; // CHECKME!
- _graphicsMan->clearScreen();
- _graphicsMan->clearPalette();
- _graphicsMan->loadImage("njour3a");
- _graphicsMan->fadeInLong();
- _events->delay(5000);
- _graphicsMan->fadeOutLong();
+ if (_fileIO->fileExists("JOUR3A.ANM")) {
+ // The Polish demo uses the animation file than the complete versions
+ _soundMan->playSound(16);
+ _globals->_eventMode = EVENTMODE_IGNORE;
+
+ _graphicsMan->clearScreen();
+ _graphicsMan->clearPalette();
+ _graphicsMan->_fadingFl = true;
+ _animMan->playAnim("JOUR3A.ANM", "JOUR3A.ANM", 12, 12, 2000);
+ } else {
+ // The other demos only display a nag screen
+ _soundMan->playSound(28);
+ _globals->_eventMode = EVENTMODE_ALT; // CHECKME!
+ _graphicsMan->clearScreen();
+ _graphicsMan->clearPalette();
+ _graphicsMan->loadImage("njour3a");
+ _graphicsMan->fadeInLong();
+ _events->delay(5000);
+ _graphicsMan->fadeOutLong();
+ }
+
_globals->_exitId = 300;
_globals->_eventMode = EVENTMODE_DEFAULT;
break;
@@ -2881,4 +2896,8 @@ bool HopkinsEngine::displayAdultDisclaimer() {
}
}
+bool HopkinsEngine::isUnderwaterSubScene() {
+ return (_globals->_curRoomNum >= 77) && (_globals->_curRoomNum <= 89);
+}
+
} // End of namespace Hopkins
diff --git a/engines/hopkins/hopkins.h b/engines/hopkins/hopkins.h
index 7af7f962b3..777fd1c335 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,6 +66,10 @@ enum {
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
+enum HopkinsDebugChannels {
+ kDebugPath = 1 << 0
+};
+
/**
* A wrapper macro used around three character constants, like 'END', to
* ensure portability. Typical usage: MKTAG24('E','N','D').
@@ -101,6 +97,7 @@ private:
void playUnderwaterBaseCutscene();
void playPlaneCutscene();
void playEnding();
+ bool isUnderwaterSubScene();
/**
* Displays the map screen in the underground base.
diff --git a/engines/hopkins/lines.cpp b/engines/hopkins/lines.cpp
index 791db4267a..aa708fdfb2 100644
--- a/engines/hopkins/lines.cpp
+++ b/engines/hopkins/lines.cpp
@@ -99,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;
@@ -106,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;
@@ -119,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;
@@ -140,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);
@@ -166,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)
@@ -203,6 +209,7 @@ 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) {
@@ -253,6 +260,7 @@ 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) {
+ debugC(5, kDebugPath, "addLine(%d, %d, %d, %d, %d, %d)", lineIdx, direction, fromX, fromY, destX, destY);
assert(lineIdx < MAX_LINES);
if (_linesNumb < lineIdx)
@@ -367,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;
@@ -426,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];
@@ -462,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;
@@ -493,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;
@@ -535,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;
@@ -776,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) {
@@ -931,48 +945,44 @@ int LinesManager::computeRouteIdx(int lineIdx, int dataIdx, int fromX, int fromY
if (destX >= minLineX && destX <= maxLineX && destY >= minLineY && destY <= maxLineY) {
int curY = destY;
int linesIdxUp = -1;
- for (;;) {
+ do {
--curY;
- if (!checkCollisionLine(destX, curY, &foundDataIdx, &foundLineIdx, startLineIdx, endLineIdx))
+ if (checkCollisionLine(destX, curY, &foundDataIdx, &foundLineIdx, startLineIdx, endLineIdx)) {
+ linesIdxUp = foundLineIdx;
break;
+ }
+ } while (curY && curY >= minLineY);
- linesIdxUp = foundLineIdx;
- if (!curY || minLineY > curY)
- break;
- }
curY = destY;
int lineIdxDown = -1;
- for (;;) {
+ do {
++curY;
- if (!checkCollisionLine(destX, curY, &foundDataIdx, &foundLineIdx, startLineIdx, endLineIdx))
+ if (checkCollisionLine(destX, curY, &foundDataIdx, &foundLineIdx, startLineIdx, endLineIdx)) {
+ lineIdxDown = foundLineIdx;
break;
+ }
+ } while (curY < _vm->_globals->_characterMaxPosY && curY < maxLineY);
- lineIdxDown = foundLineIdx;
- if (_vm->_globals->_characterMaxPosY <= curY || maxLineY <= curY)
- break;
- }
int curX = destX;
int lineIdxRight = -1;
- for (;;) {
+ do {
++curX;
- if (!checkCollisionLine(curX, destY, &foundDataIdx, &foundLineIdx, startLineIdx, endLineIdx))
+ if (checkCollisionLine(curX, destY, &foundDataIdx, &foundLineIdx, startLineIdx, endLineIdx)) {
+ lineIdxRight = foundLineIdx;
break;
+ }
+ } while (curX < _vm->_graphicsMan->_maxX && curX < maxLineX);
- lineIdxRight = foundLineIdx;
-
- if (_vm->_graphicsMan->_maxX <= curX || maxLineX <= curX)
- break;
- }
curX = destX;
int lineIdxLeft = -1;
- for(;;) {
+ do {
--curX;
- if (!checkCollisionLine(curX, destY, &foundDataIdx, &foundLineIdx, startLineIdx, endLineIdx))
+ if (checkCollisionLine(curX, destY, &foundDataIdx, &foundLineIdx, startLineIdx, endLineIdx)) {
+ lineIdxLeft = foundLineIdx;
break;
- lineIdxLeft = foundLineIdx;
- if (curX <= 0 || minLineX >= curX)
- break;
- }
+ }
+ } while (curX > 0 && curX > minLineX);
+
if (lineIdxRight != -1 && lineIdxLeft != -1 && linesIdxUp != -1 && lineIdxDown != -1) {
route[routerIdx].invalidate();
return -1;
@@ -1076,6 +1086,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;
@@ -1503,6 +1514,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 {
@@ -1514,6 +1526,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 {
@@ -1525,6 +1538,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 {
@@ -1536,6 +1550,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;
@@ -1969,8 +1984,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;
@@ -1987,6 +2002,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];
@@ -2165,6 +2181,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)
@@ -2203,6 +2220,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) {
@@ -2335,6 +2353,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;
@@ -2435,6 +2454,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;
@@ -2482,6 +2502,7 @@ 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 == CHARACTER_HOPKINS_CLONE) {
if (zoomPct < 0)
@@ -2503,6 +2524,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;
@@ -2549,6 +2571,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;
@@ -2569,6 +2592,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;
}
}
@@ -2637,6 +2665,7 @@ int LinesManager::getMouseZone() {
}
int LinesManager::checkCollision(int xp, int yp) {
+ debugC(7, kDebugPath, "checkCollision(%d, %d)", xp, yp);
if (_currentSegmentId <= 0)
return -1;
@@ -2686,6 +2715,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;
@@ -2728,6 +2758,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;
@@ -2773,6 +2804,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);
}
@@ -2781,37 +2813,37 @@ void LinesManager::clearAllZones() {
* Remove Zone Line
*/
void LinesManager::removeZoneLine(int idx) {
+ 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) {
- assert(idx < MAX_LINES);
- _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 {
@@ -2820,6 +2852,7 @@ void LinesManager::enableZone(int idx) {
}
void LinesManager::disableZone(int idx) {
+ debugC(5, kDebugPath, "disableZone(%d)", idx);
if (_bobZone[idx]) {
_bobZoneFl[idx] = false;
} else {
@@ -2828,6 +2861,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;
@@ -2858,6 +2892,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 27229aa105..b32dc6e2a5 100644
--- a/engines/hopkins/lines.h
+++ b/engines/hopkins/lines.h
@@ -118,7 +118,6 @@ private:
int _currentSegmentId;
int _maxLineIdx;
int _lastLine;
- int _linesNumb;
int _newLineIdx;
int _newLineDataIdx;
int _newRouteIdx;
@@ -135,7 +134,6 @@ private:
RouteItem *_testRoute0;
RouteItem *_testRoute1;
int16 *_lineBuf;
- LigneItem _lineItem[MAX_LINES];
RouteItem _bestRoute[8001];
int _zoneSkipCount;
int _oldMouseZoneId;
@@ -168,6 +166,8 @@ public:
bool _bobZoneFl[105];
ZoneItem _zone[106];
SquareZoneItem _squareZone[101];
+ LigneItem _lineItem[MAX_LINES];
+ int _linesNumb;
LinesManager(HopkinsEngine *vm);
~LinesManager();