aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/hugo/display.cpp80
-rw-r--r--engines/hugo/display_v1d.cpp83
-rw-r--r--engines/hugo/display_v1w.cpp83
-rw-r--r--engines/hugo/file.cpp402
-rw-r--r--engines/hugo/file_v1d.cpp101
-rw-r--r--engines/hugo/file_v1w.cpp90
-rw-r--r--engines/hugo/file_v2d.cpp177
-rw-r--r--engines/hugo/file_v3d.cpp200
-rw-r--r--engines/hugo/intro.cpp326
-rw-r--r--engines/hugo/intro_v1d.cpp172
-rw-r--r--engines/hugo/intro_v1w.cpp61
-rw-r--r--engines/hugo/intro_v2d.cpp77
-rw-r--r--engines/hugo/intro_v2w.cpp57
-rw-r--r--engines/hugo/intro_v3d.cpp109
-rw-r--r--engines/hugo/intro_v3w.cpp94
-rw-r--r--engines/hugo/module.mk17
-rw-r--r--engines/hugo/parser.cpp799
-rw-r--r--engines/hugo/parser_v1d.cpp355
-rw-r--r--engines/hugo/parser_v1w.cpp434
-rw-r--r--engines/hugo/parser_v2d.cpp137
-rw-r--r--engines/hugo/schedule.cpp22
-rw-r--r--engines/hugo/schedule_v1d.cpp52
-rw-r--r--engines/hugo/schedule_v3d.cpp51
23 files changed, 2351 insertions, 1628 deletions
diff --git a/engines/hugo/display.cpp b/engines/hugo/display.cpp
index 74b9d4636b..3a8d0d4e89 100644
--- a/engines/hugo/display.cpp
+++ b/engines/hugo/display.cpp
@@ -34,10 +34,8 @@
#include "common/system.h"
-#include "hugo/game.h"
#include "hugo/hugo.h"
#include "hugo/display.h"
-#include "hugo/file.h"
#include "hugo/util.h"
namespace Hugo {
@@ -442,83 +440,5 @@ void Screen::drawRectangle(bool filledFl, uint16 x1, uint16 y1, uint16 x2, uint1
}
}
-Screen_v1d::Screen_v1d(HugoEngine &vm) : Screen(vm) {
-}
-
-Screen_v1d::~Screen_v1d() {
-}
-
-// Load font file, construct font ptrs and reverse data bytes
-// TODO: This uses hardcoded fonts in hugo.dat, it should be replaced
-// by a proper implementation of .FON files
-void Screen_v1d::loadFont(int16 fontId) {
- debugC(2, kDebugDisplay, "loadFont(%d)", fontId);
-
- static bool fontLoadedFl[NUM_FONTS] = {false, false, false};
-
- _fnt = fontId - FIRST_FONT; // Set current font number
-
- if (fontLoadedFl[_fnt]) // If already loaded, return
- return;
-
- fontLoadedFl[_fnt] = true;
-
- memcpy(_fontdata[_fnt], _vm._arrayFont[_fnt], _vm._arrayFontSize[_fnt]);
- _font[_fnt][0] = _fontdata[_fnt]; // Store height,width of fonts
-
- int16 offset = 2; // Start at fontdata[2] ([0],[1] used for height,width)
-
- // Setup the font array (127 characters)
- for (int i = 1; i < 128; i++) {
- _font[_fnt][i] = _fontdata[_fnt] + offset;
- byte height = *(_fontdata[_fnt] + offset);
- byte width = *(_fontdata[_fnt] + offset + 1);
-
- int16 size = height * ((width + 7) >> 3);
- for (int j = 0; j < size; j++)
- Utils::reverseByte(&_fontdata[_fnt][offset + 2 + j]);
-
- offset += 2 + size;
- }
-}
-
-Screen_v1w::Screen_v1w(HugoEngine &vm) : Screen(vm) {
-}
-
-Screen_v1w::~Screen_v1w() {
-}
-
-// Load font file, construct font ptrs and reverse data bytes
-void Screen_v1w::loadFont(int16 fontId) {
- debugC(2, kDebugDisplay, "loadFont(%d)", fontId);
-
- static bool fontLoadedFl[NUM_FONTS] = {false, false, false};
-
- _fnt = fontId - FIRST_FONT; // Set current font number
-
- if (fontLoadedFl[_fnt]) // If already loaded, return
- return;
-
- fontLoadedFl[_fnt] = true;
- _vm.file().readUIFItem(fontId, _fontdata[_fnt]);
-
- // Compile font ptrs. Note: First ptr points to height,width of font
- _font[_fnt][0] = _fontdata[_fnt]; // Store height,width of fonts
-
- int16 offset = 2; // Start at fontdata[2] ([0],[1] used for height,width)
-
- // Setup the font array (127 characters)
- for (int i = 1; i < 128; i++) {
- _font[_fnt][i] = _fontdata[_fnt] + offset;
- byte height = *(_fontdata[_fnt] + offset);
- byte width = *(_fontdata[_fnt] + offset + 1);
-
- int16 size = height * ((width + 7) >> 3);
- for (int j = 0; j < size; j++)
- Utils::reverseByte(&_fontdata[_fnt][offset + 2 + j]);
-
- offset += 2 + size;
- }
-}
} // End of namespace Hugo
diff --git a/engines/hugo/display_v1d.cpp b/engines/hugo/display_v1d.cpp
new file mode 100644
index 0000000000..6cf20d413f
--- /dev/null
+++ b/engines/hugo/display_v1d.cpp
@@ -0,0 +1,83 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on original Hugo Trilogy source code
+ *
+ * Copyright (c) 1989-1995 David P. Gray
+ *
+ */
+
+// Display.c - DIB related code for HUGOWIN
+
+#include "common/system.h"
+
+#include "hugo/hugo.h"
+#include "hugo/display.h"
+#include "hugo/util.h"
+
+namespace Hugo {
+
+Screen_v1d::Screen_v1d(HugoEngine &vm) : Screen(vm) {
+}
+
+Screen_v1d::~Screen_v1d() {
+}
+
+// Load font file, construct font ptrs and reverse data bytes
+// TODO: This uses hardcoded fonts in hugo.dat, it should be replaced
+// by a proper implementation of .FON files
+void Screen_v1d::loadFont(int16 fontId) {
+ debugC(2, kDebugDisplay, "loadFont(%d)", fontId);
+
+ static bool fontLoadedFl[NUM_FONTS] = {false, false, false};
+
+ _fnt = fontId - FIRST_FONT; // Set current font number
+
+ if (fontLoadedFl[_fnt]) // If already loaded, return
+ return;
+
+ fontLoadedFl[_fnt] = true;
+
+ memcpy(_fontdata[_fnt], _vm._arrayFont[_fnt], _vm._arrayFontSize[_fnt]);
+ _font[_fnt][0] = _fontdata[_fnt]; // Store height,width of fonts
+
+ int16 offset = 2; // Start at fontdata[2] ([0],[1] used for height,width)
+
+ // Setup the font array (127 characters)
+ for (int i = 1; i < 128; i++) {
+ _font[_fnt][i] = _fontdata[_fnt] + offset;
+ byte height = *(_fontdata[_fnt] + offset);
+ byte width = *(_fontdata[_fnt] + offset + 1);
+
+ int16 size = height * ((width + 7) >> 3);
+ for (int j = 0; j < size; j++)
+ Utils::reverseByte(&_fontdata[_fnt][offset + 2 + j]);
+
+ offset += 2 + size;
+ }
+}
+} // End of namespace Hugo
+
diff --git a/engines/hugo/display_v1w.cpp b/engines/hugo/display_v1w.cpp
new file mode 100644
index 0000000000..c98374dcde
--- /dev/null
+++ b/engines/hugo/display_v1w.cpp
@@ -0,0 +1,83 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on original Hugo Trilogy source code
+ *
+ * Copyright (c) 1989-1995 David P. Gray
+ *
+ */
+
+// Display.c - DIB related code for HUGOWIN
+
+#include "common/system.h"
+
+#include "hugo/hugo.h"
+#include "hugo/display.h"
+#include "hugo/file.h"
+#include "hugo/util.h"
+
+namespace Hugo {
+
+Screen_v1w::Screen_v1w(HugoEngine &vm) : Screen(vm) {
+}
+
+Screen_v1w::~Screen_v1w() {
+}
+
+// Load font file, construct font ptrs and reverse data bytes
+void Screen_v1w::loadFont(int16 fontId) {
+ debugC(2, kDebugDisplay, "loadFont(%d)", fontId);
+
+ static bool fontLoadedFl[NUM_FONTS] = {false, false, false};
+
+ _fnt = fontId - FIRST_FONT; // Set current font number
+
+ if (fontLoadedFl[_fnt]) // If already loaded, return
+ return;
+
+ fontLoadedFl[_fnt] = true;
+ _vm.file().readUIFItem(fontId, _fontdata[_fnt]);
+
+ // Compile font ptrs. Note: First ptr points to height,width of font
+ _font[_fnt][0] = _fontdata[_fnt]; // Store height,width of fonts
+
+ int16 offset = 2; // Start at fontdata[2] ([0],[1] used for height,width)
+
+ // Setup the font array (127 characters)
+ for (int i = 1; i < 128; i++) {
+ _font[_fnt][i] = _fontdata[_fnt] + offset;
+ byte height = *(_fontdata[_fnt] + offset);
+ byte width = *(_fontdata[_fnt] + offset + 1);
+
+ int16 size = height * ((width + 7) >> 3);
+ for (int j = 0; j < size; j++)
+ Utils::reverseByte(&_fontdata[_fnt][offset + 2 + j]);
+
+ offset += 2 + size;
+ }
+}
+} // End of namespace Hugo
+
diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp
index 68271b1f4e..fa8d5b9947 100644
--- a/engines/hugo/file.cpp
+++ b/engines/hugo/file.cpp
@@ -31,10 +31,8 @@
*/
#include "common/system.h"
-#include "common/file.h"
#include "common/savefile.h"
-#include "hugo/game.h"
#include "hugo/hugo.h"
#include "hugo/file.h"
#include "hugo/global.h"
@@ -674,405 +672,5 @@ void FileManager::instructions() {
f.close();
}
-FileManager_v1d::FileManager_v1d(HugoEngine &vm) : FileManager(vm) {
-}
-
-FileManager_v1d::~FileManager_v1d() {
-}
-
-void FileManager_v1d::openDatabaseFiles() {
- debugC(1, kDebugFile, "openDatabaseFiles");
-}
-
-void FileManager_v1d::closeDatabaseFiles() {
- debugC(1, kDebugFile, "closeDatabaseFiles");
-}
-
-void FileManager_v1d::readOverlay(int screenNum, image_pt image, ovl_t overlayType) {
-// Open and read in an overlay file, close file
- debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum);
-
- const char *ovl_ext[] = {".b", ".o", ".ob"};
- char *buf = (char *) malloc(2048 + 1); // Buffer for file access
-
- strcat(strcpy(buf, _vm._screenNames[screenNum]), ovl_ext[overlayType]);
-
- if (!fileExists(buf)) {
- for (uint32 i = 0; i < OVL_SIZE; i++)
- image[i] = 0;
- return;
- }
-
- if (!_sceneryArchive1.open(buf))
- Utils::Error(FILE_ERR, "%s", buf);
-
- image_pt tmpImage = image; // temp ptr to overlay file
-
- _sceneryArchive1.read(tmpImage, OVL_SIZE);
- _sceneryArchive1.close();
-}
-
-void FileManager_v1d::readBackground(int screenIndex) {
-// Read a PCX image into dib_a
- debugC(1, kDebugFile, "readBackground(%d)", screenIndex);
-
- char *buf = (char *) malloc(2048 + 1); // Buffer for file access
- strcat(strcpy(buf, _vm._screenNames[screenIndex]), ".ART");
- if (!_sceneryArchive1.open(buf))
- Utils::Error(FILE_ERR, "%s", buf);
- // Read the image into dummy seq and static dib_a
- seq_t dummySeq; // Image sequence structure for Read_pcx
- readPCX(_sceneryArchive1, &dummySeq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]);
-
- _sceneryArchive1.close();
-}
-
-char *FileManager_v1d::fetchString(int index) {
- debugC(1, kDebugFile, "fetchString(%d)", index);
-
- return _vm._stringtData[index];
-}
-
-FileManager_v2d::FileManager_v2d(HugoEngine &vm) : FileManager(vm) {
-}
-
-FileManager_v2d::~FileManager_v2d() {
-}
-
-void FileManager_v2d::openDatabaseFiles() {
- debugC(1, kDebugFile, "openDatabaseFiles");
-
- if (!_stringArchive.open(STRING_FILE))
- Utils::Error(FILE_ERR, "%s", STRING_FILE);
- if (!_sceneryArchive1.open("scenery.dat"))
- Utils::Error(FILE_ERR, "%s", "scenery.dat");
- if (!_objectsArchive.open(OBJECTS_FILE))
- Utils::Error(FILE_ERR, "%s", OBJECTS_FILE);
-}
-
-void FileManager_v2d::closeDatabaseFiles() {
- debugC(1, kDebugFile, "closeDatabaseFiles");
-
- _stringArchive.close();
- _sceneryArchive1.close();
- _objectsArchive.close();
-}
-
-void FileManager_v2d::readBackground(int screenIndex) {
-// Read a PCX image into dib_a
- debugC(1, kDebugFile, "readBackground(%d)", screenIndex);
-
- _sceneryArchive1.seek((uint32) screenIndex * sizeof(sceneBlock_t), SEEK_SET);
-
- sceneBlock_t sceneBlock; // Read a database header entry
- sceneBlock.scene_off = _sceneryArchive1.readUint32LE();
- sceneBlock.scene_len = _sceneryArchive1.readUint32LE();
- sceneBlock.b_off = _sceneryArchive1.readUint32LE();
- sceneBlock.b_len = _sceneryArchive1.readUint32LE();
- sceneBlock.o_off = _sceneryArchive1.readUint32LE();
- sceneBlock.o_len = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_off = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_len = _sceneryArchive1.readUint32LE();
-
- _sceneryArchive1.seek(sceneBlock.scene_off, SEEK_SET);
-
- // Read the image into dummy seq and static dib_a
- seq_t dummySeq; // Image sequence structure for Read_pcx
- readPCX(_sceneryArchive1, &dummySeq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]);
-}
-
-void FileManager_v2d::readOverlay(int screenNum, image_pt image, ovl_t overlayType) {
-// Open and read in an overlay file, close file
- debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum);
-
- image_pt tmpImage = image; // temp ptr to overlay file
- _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET);
-
- sceneBlock_t sceneBlock; // Database header entry
- sceneBlock.scene_off = _sceneryArchive1.readUint32LE();
- sceneBlock.scene_len = _sceneryArchive1.readUint32LE();
- sceneBlock.b_off = _sceneryArchive1.readUint32LE();
- sceneBlock.b_len = _sceneryArchive1.readUint32LE();
- sceneBlock.o_off = _sceneryArchive1.readUint32LE();
- sceneBlock.o_len = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_off = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_len = _sceneryArchive1.readUint32LE();
-
- uint32 i = 0;
- switch (overlayType) {
- case BOUNDARY:
- _sceneryArchive1.seek(sceneBlock.b_off, SEEK_SET);
- i = sceneBlock.b_len;
- break;
- case OVERLAY:
- _sceneryArchive1.seek(sceneBlock.o_off, SEEK_SET);
- i = sceneBlock.o_len;
- break;
- case OVLBASE:
- _sceneryArchive1.seek(sceneBlock.ob_off, SEEK_SET);
- i = sceneBlock.ob_len;
- break;
- default:
- Utils::Error(FILE_ERR, "%s", "Bad ovl_type");
- break;
- }
- if (i == 0) {
- for (i = 0; i < OVL_SIZE; i++)
- image[i] = 0;
- return;
- }
-
- // Read in the overlay file using MAC Packbits. (We're not proud!)
- int16 k = 0; // byte count
- do {
- int8 data = _sceneryArchive1.readByte(); // Read a code byte
- if ((byte)data == 0x80) // Noop
- k = k;
- else if (data >= 0) { // Copy next data+1 literally
- for (i = 0; i <= (byte)data; i++, k++)
- *tmpImage++ = _sceneryArchive1.readByte();
- } else { // Repeat next byte -data+1 times
- int16 j = _sceneryArchive1.readByte();
-
- for (i = 0; i < (byte)(-data + 1); i++, k++)
- *tmpImage++ = j;
- }
- } while (k < OVL_SIZE);
-}
-
-char *FileManager_v2d::fetchString(int index) {
-// Fetch string from file, decode and return ptr to string in memory
- debugC(1, kDebugFile, "fetchString(%d)", index);
-
- // Get offset to string[index] (and next for length calculation)
- _stringArchive.seek((uint32)index * sizeof(uint32), SEEK_SET);
- uint32 off1, off2;
- if (_stringArchive.read((char *)&off1, sizeof(uint32)) == 0)
- Utils::Error(FILE_ERR, "%s", "String offset");
- if (_stringArchive.read((char *)&off2, sizeof(uint32)) == 0)
- Utils::Error(FILE_ERR, "%s", "String offset");
-
- // Check size of string
- if ((off2 - off1) >= MAX_BOX)
- Utils::Error(FILE_ERR, "%s", "Fetched string too long!");
-
- // Position to string and read it into gen purpose _textBoxBuffer
- _stringArchive.seek(off1, SEEK_SET);
- if (_stringArchive.read(_textBoxBuffer, (uint16)(off2 - off1)) == 0)
- Utils::Error(FILE_ERR, "%s", "Fetch_string");
-
- // Null terminate, decode and return it
- _textBoxBuffer[off2-off1] = '\0';
- _vm.scheduler().decodeString(_textBoxBuffer);
- return _textBoxBuffer;
-}
-
-
-FileManager_v1w::FileManager_v1w(HugoEngine &vm) : FileManager_v2d(vm) {
-}
-
-FileManager_v1w::~FileManager_v1w() {
-}
-
-void FileManager_v1w::readOverlay(int screenNum, image_pt image, ovl_t overlayType) {
-// Open and read in an overlay file, close file
- debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum);
-
- image_pt tmpImage = image; // temp ptr to overlay file
- _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET);
-
- sceneBlock_t sceneBlock; // Database header entry
- sceneBlock.scene_off = _sceneryArchive1.readUint32LE();
- sceneBlock.scene_len = _sceneryArchive1.readUint32LE();
- sceneBlock.b_off = _sceneryArchive1.readUint32LE();
- sceneBlock.b_len = _sceneryArchive1.readUint32LE();
- sceneBlock.o_off = _sceneryArchive1.readUint32LE();
- sceneBlock.o_len = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_off = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_len = _sceneryArchive1.readUint32LE();
-
- uint32 i = 0;
- switch (overlayType) {
- case BOUNDARY:
- _sceneryArchive1.seek(sceneBlock.b_off, SEEK_SET);
- i = sceneBlock.b_len;
- break;
- case OVERLAY:
- _sceneryArchive1.seek(sceneBlock.o_off, SEEK_SET);
- i = sceneBlock.o_len;
- break;
- case OVLBASE:
- _sceneryArchive1.seek(sceneBlock.ob_off, SEEK_SET);
- i = sceneBlock.ob_len;
- break;
- default:
- Utils::Error(FILE_ERR, "%s", "Bad ovl_type");
- break;
- }
- if (i == 0) {
- for (i = 0; i < OVL_SIZE; i++)
- image[i] = 0;
- return;
- }
- _sceneryArchive1.read(tmpImage, OVL_SIZE);
-}
-
-FileManager_v3d::FileManager_v3d(HugoEngine &vm) : FileManager_v2d(vm) {
-}
-
-FileManager_v3d::~FileManager_v3d() {
-}
-
-void FileManager_v3d::readBackground(int screenIndex) {
-// Read a PCX image into dib_a
- debugC(1, kDebugFile, "readBackground(%d)", screenIndex);
-
- _sceneryArchive1.seek((uint32) screenIndex * sizeof(sceneBlock_t), SEEK_SET);
-
- sceneBlock_t sceneBlock; // Read a database header entry
- sceneBlock.scene_off = _sceneryArchive1.readUint32LE();
- sceneBlock.scene_len = _sceneryArchive1.readUint32LE();
- sceneBlock.b_off = _sceneryArchive1.readUint32LE();
- sceneBlock.b_len = _sceneryArchive1.readUint32LE();
- sceneBlock.o_off = _sceneryArchive1.readUint32LE();
- sceneBlock.o_len = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_off = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_len = _sceneryArchive1.readUint32LE();
-
- seq_t dummySeq; // Image sequence structure for Read_pcx
- if (screenIndex < 20) {
- _sceneryArchive1.seek(sceneBlock.scene_off, SEEK_SET);
- // Read the image into dummy seq and static dib_a
- readPCX(_sceneryArchive1, &dummySeq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]);
- } else {
- _sceneryArchive2.seek(sceneBlock.scene_off, SEEK_SET);
- // Read the image into dummy seq and static dib_a
- readPCX(_sceneryArchive2, &dummySeq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]);
- }
-}
-
-void FileManager_v3d::openDatabaseFiles() {
- debugC(1, kDebugFile, "openDatabaseFiles");
-
- if (!_stringArchive.open(STRING_FILE))
- Utils::Error(FILE_ERR, "%s", STRING_FILE);
- if (!_sceneryArchive1.open("scenery1.dat"))
- Utils::Error(FILE_ERR, "%s", "scenery1.dat");
- if (!_sceneryArchive2.open("scenery2.dat"))
- Utils::Error(FILE_ERR, "%s", "scenery2.dat");
- if (!_objectsArchive.open(OBJECTS_FILE))
- Utils::Error(FILE_ERR, "%s", OBJECTS_FILE);
-}
-
-void FileManager_v3d::closeDatabaseFiles() {
- debugC(1, kDebugFile, "closeDatabaseFiles");
-
- _stringArchive.close();
- _sceneryArchive1.close();
- _sceneryArchive2.close();
- _objectsArchive.close();
-}
-
-void FileManager_v3d::readOverlay(int screenNum, image_pt image, ovl_t overlayType) {
-// Open and read in an overlay file, close file
- debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum);
-
- image_pt tmpImage = image; // temp ptr to overlay file
- _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET);
-
- sceneBlock_t sceneBlock; // Database header entry
- sceneBlock.scene_off = _sceneryArchive1.readUint32LE();
- sceneBlock.scene_len = _sceneryArchive1.readUint32LE();
- sceneBlock.b_off = _sceneryArchive1.readUint32LE();
- sceneBlock.b_len = _sceneryArchive1.readUint32LE();
- sceneBlock.o_off = _sceneryArchive1.readUint32LE();
- sceneBlock.o_len = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_off = _sceneryArchive1.readUint32LE();
- sceneBlock.ob_len = _sceneryArchive1.readUint32LE();
-
- uint32 i = 0;
-
- if (screenNum < 20) {
- switch (overlayType) {
- case BOUNDARY:
- _sceneryArchive1.seek(sceneBlock.b_off, SEEK_SET);
- i = sceneBlock.b_len;
- break;
- case OVERLAY:
- _sceneryArchive1.seek(sceneBlock.o_off, SEEK_SET);
- i = sceneBlock.o_len;
- break;
- case OVLBASE:
- _sceneryArchive1.seek(sceneBlock.ob_off, SEEK_SET);
- i = sceneBlock.ob_len;
- break;
- default:
- Utils::Error(FILE_ERR, "%s", "Bad ovl_type");
- break;
- }
- if (i == 0) {
- for (i = 0; i < OVL_SIZE; i++)
- image[i] = 0;
- return;
- }
-
- // Read in the overlay file using MAC Packbits. (We're not proud!)
- int16 k = 0; // byte count
- do {
- int8 data = _sceneryArchive1.readByte();// Read a code byte
- if ((byte)data == 0x80) // Noop
- k = k;
- else if (data >= 0) { // Copy next data+1 literally
- for (i = 0; i <= (byte)data; i++, k++)
- *tmpImage++ = _sceneryArchive1.readByte();
- } else { // Repeat next byte -data+1 times
- int16 j = _sceneryArchive1.readByte();
-
- for (i = 0; i < (byte)(-data + 1); i++, k++)
- *tmpImage++ = j;
- }
- } while (k < OVL_SIZE);
- } else {
- switch (overlayType) {
- case BOUNDARY:
- _sceneryArchive2.seek(sceneBlock.b_off, SEEK_SET);
- i = sceneBlock.b_len;
- break;
- case OVERLAY:
- _sceneryArchive2.seek(sceneBlock.o_off, SEEK_SET);
- i = sceneBlock.o_len;
- break;
- case OVLBASE:
- _sceneryArchive2.seek(sceneBlock.ob_off, SEEK_SET);
- i = sceneBlock.ob_len;
- break;
- default:
- Utils::Error(FILE_ERR, "%s", "Bad ovl_type");
- break;
- }
- if (i == 0) {
- for (i = 0; i < OVL_SIZE; i++)
- image[i] = 0;
- return;
- }
-
- // Read in the overlay file using MAC Packbits. (We're not proud!)
- int16 k = 0; // byte count
- do {
- int8 data = _sceneryArchive2.readByte();// Read a code byte
- if ((byte)data == 0x80) // Noop
- k = k;
- else if (data >= 0) { // Copy next data+1 literally
- for (i = 0; i <= (byte)data; i++, k++)
- *tmpImage++ = _sceneryArchive2.readByte();
- } else { // Repeat next byte -data+1 times
- int16 j = _sceneryArchive2.readByte();
-
- for (i = 0; i < (byte)(-data + 1); i++, k++)
- *tmpImage++ = j;
- }
- } while (k < OVL_SIZE);
- }
-}
} // End of namespace Hugo
diff --git a/engines/hugo/file_v1d.cpp b/engines/hugo/file_v1d.cpp
new file mode 100644
index 0000000000..b6239aa5dc
--- /dev/null
+++ b/engines/hugo/file_v1d.cpp
@@ -0,0 +1,101 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on original Hugo Trilogy source code
+ *
+ * Copyright (c) 1989-1995 David P. Gray
+ *
+ */
+
+#include "common/system.h"
+
+#include "hugo/hugo.h"
+#include "hugo/file.h"
+#include "hugo/display.h"
+#include "hugo/util.h"
+
+namespace Hugo {
+FileManager_v1d::FileManager_v1d(HugoEngine &vm) : FileManager(vm) {
+}
+
+FileManager_v1d::~FileManager_v1d() {
+}
+
+void FileManager_v1d::openDatabaseFiles() {
+ debugC(1, kDebugFile, "openDatabaseFiles");
+}
+
+void FileManager_v1d::closeDatabaseFiles() {
+ debugC(1, kDebugFile, "closeDatabaseFiles");
+}
+
+void FileManager_v1d::readOverlay(int screenNum, image_pt image, ovl_t overlayType) {
+// Open and read in an overlay file, close file
+ debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum);
+
+ const char *ovl_ext[] = {".b", ".o", ".ob"};
+ char *buf = (char *) malloc(2048 + 1); // Buffer for file access
+
+ strcat(strcpy(buf, _vm._screenNames[screenNum]), ovl_ext[overlayType]);
+
+ if (!fileExists(buf)) {
+ for (uint32 i = 0; i < OVL_SIZE; i++)
+ image[i] = 0;
+ return;
+ }
+
+ if (!_sceneryArchive1.open(buf))
+ Utils::Error(FILE_ERR, "%s", buf);
+
+ image_pt tmpImage = image; // temp ptr to overlay file
+
+ _sceneryArchive1.read(tmpImage, OVL_SIZE);
+ _sceneryArchive1.close();
+}
+
+void FileManager_v1d::readBackground(int screenIndex) {
+// Read a PCX image into dib_a
+ debugC(1, kDebugFile, "readBackground(%d)", screenIndex);
+
+ char *buf = (char *) malloc(2048 + 1); // Buffer for file access
+ strcat(strcpy(buf, _vm._screenNames[screenIndex]), ".ART");
+ if (!_sceneryArchive1.open(buf))
+ Utils::Error(FILE_ERR, "%s", buf);
+ // Read the image into dummy seq and static dib_a
+ seq_t dummySeq; // Image sequence structure for Read_pcx
+ readPCX(_sceneryArchive1, &dummySeq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]);
+
+ _sceneryArchive1.close();
+}
+
+char *FileManager_v1d::fetchString(int index) {
+ debugC(1, kDebugFile, "fetchString(%d)", index);
+
+ return _vm._stringtData[index];
+}
+
+} // End of namespace Hugo
+
diff --git a/engines/hugo/file_v1w.cpp b/engines/hugo/file_v1w.cpp
new file mode 100644
index 0000000000..6ab21a853e
--- /dev/null
+++ b/engines/hugo/file_v1w.cpp
@@ -0,0 +1,90 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on original Hugo Trilogy source code
+ *
+ * Copyright (c) 1989-1995 David P. Gray
+ *
+ */
+
+#include "common/system.h"
+
+#include "hugo/hugo.h"
+#include "hugo/file.h"
+#include "hugo/util.h"
+
+namespace Hugo {
+FileManager_v1w::FileManager_v1w(HugoEngine &vm) : FileManager_v2d(vm) {
+}
+
+FileManager_v1w::~FileManager_v1w() {
+}
+
+void FileManager_v1w::readOverlay(int screenNum, image_pt image, ovl_t overlayType) {
+// Open and read in an overlay file, close file
+ debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum);
+
+ image_pt tmpImage = image; // temp ptr to overlay file
+ _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET);
+
+ sceneBlock_t sceneBlock; // Database header entry
+ sceneBlock.scene_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.scene_len = _sceneryArchive1.readUint32LE();
+ sceneBlock.b_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.b_len = _sceneryArchive1.readUint32LE();
+ sceneBlock.o_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.o_len = _sceneryArchive1.readUint32LE();
+ sceneBlock.ob_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.ob_len = _sceneryArchive1.readUint32LE();
+
+ uint32 i = 0;
+ switch (overlayType) {
+ case BOUNDARY:
+ _sceneryArchive1.seek(sceneBlock.b_off, SEEK_SET);
+ i = sceneBlock.b_len;
+ break;
+ case OVERLAY:
+ _sceneryArchive1.seek(sceneBlock.o_off, SEEK_SET);
+ i = sceneBlock.o_len;
+ break;
+ case OVLBASE:
+ _sceneryArchive1.seek(sceneBlock.ob_off, SEEK_SET);
+ i = sceneBlock.ob_len;
+ break;
+ default:
+ Utils::Error(FILE_ERR, "%s", "Bad ovl_type");
+ break;
+ }
+ if (i == 0) {
+ for (i = 0; i < OVL_SIZE; i++)
+ image[i] = 0;
+ return;
+ }
+ _sceneryArchive1.read(tmpImage, OVL_SIZE);
+}
+
+} // End of namespace Hugo
+
diff --git a/engines/hugo/file_v2d.cpp b/engines/hugo/file_v2d.cpp
new file mode 100644
index 0000000000..43de3fac4c
--- /dev/null
+++ b/engines/hugo/file_v2d.cpp
@@ -0,0 +1,177 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on original Hugo Trilogy source code
+ *
+ * Copyright (c) 1989-1995 David P. Gray
+ *
+ */
+
+#include "common/system.h"
+
+#include "hugo/hugo.h"
+#include "hugo/file.h"
+#include "hugo/global.h"
+#include "hugo/schedule.h"
+#include "hugo/display.h"
+#include "hugo/util.h"
+
+namespace Hugo {
+FileManager_v2d::FileManager_v2d(HugoEngine &vm) : FileManager(vm) {
+}
+
+FileManager_v2d::~FileManager_v2d() {
+}
+
+void FileManager_v2d::openDatabaseFiles() {
+ debugC(1, kDebugFile, "openDatabaseFiles");
+
+ if (!_stringArchive.open(STRING_FILE))
+ Utils::Error(FILE_ERR, "%s", STRING_FILE);
+ if (!_sceneryArchive1.open("scenery.dat"))
+ Utils::Error(FILE_ERR, "%s", "scenery.dat");
+ if (!_objectsArchive.open(OBJECTS_FILE))
+ Utils::Error(FILE_ERR, "%s", OBJECTS_FILE);
+}
+
+void FileManager_v2d::closeDatabaseFiles() {
+ debugC(1, kDebugFile, "closeDatabaseFiles");
+
+ _stringArchive.close();
+ _sceneryArchive1.close();
+ _objectsArchive.close();
+}
+
+void FileManager_v2d::readBackground(int screenIndex) {
+// Read a PCX image into dib_a
+ debugC(1, kDebugFile, "readBackground(%d)", screenIndex);
+
+ _sceneryArchive1.seek((uint32) screenIndex * sizeof(sceneBlock_t), SEEK_SET);
+
+ sceneBlock_t sceneBlock; // Read a database header entry
+ sceneBlock.scene_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.scene_len = _sceneryArchive1.readUint32LE();
+ sceneBlock.b_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.b_len = _sceneryArchive1.readUint32LE();
+ sceneBlock.o_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.o_len = _sceneryArchive1.readUint32LE();
+ sceneBlock.ob_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.ob_len = _sceneryArchive1.readUint32LE();
+
+ _sceneryArchive1.seek(sceneBlock.scene_off, SEEK_SET);
+
+ // Read the image into dummy seq and static dib_a
+ seq_t dummySeq; // Image sequence structure for Read_pcx
+ readPCX(_sceneryArchive1, &dummySeq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]);
+}
+
+void FileManager_v2d::readOverlay(int screenNum, image_pt image, ovl_t overlayType) {
+// Open and read in an overlay file, close file
+ debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum);
+
+ image_pt tmpImage = image; // temp ptr to overlay file
+ _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET);
+
+ sceneBlock_t sceneBlock; // Database header entry
+ sceneBlock.scene_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.scene_len = _sceneryArchive1.readUint32LE();
+ sceneBlock.b_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.b_len = _sceneryArchive1.readUint32LE();
+ sceneBlock.o_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.o_len = _sceneryArchive1.readUint32LE();
+ sceneBlock.ob_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.ob_len = _sceneryArchive1.readUint32LE();
+
+ uint32 i = 0;
+ switch (overlayType) {
+ case BOUNDARY:
+ _sceneryArchive1.seek(sceneBlock.b_off, SEEK_SET);
+ i = sceneBlock.b_len;
+ break;
+ case OVERLAY:
+ _sceneryArchive1.seek(sceneBlock.o_off, SEEK_SET);
+ i = sceneBlock.o_len;
+ break;
+ case OVLBASE:
+ _sceneryArchive1.seek(sceneBlock.ob_off, SEEK_SET);
+ i = sceneBlock.ob_len;
+ break;
+ default:
+ Utils::Error(FILE_ERR, "%s", "Bad ovl_type");
+ break;
+ }
+ if (i == 0) {
+ for (i = 0; i < OVL_SIZE; i++)
+ image[i] = 0;
+ return;
+ }
+
+ // Read in the overlay file using MAC Packbits. (We're not proud!)
+ int16 k = 0; // byte count
+ do {
+ int8 data = _sceneryArchive1.readByte(); // Read a code byte
+ if ((byte)data == 0x80) // Noop
+ k = k;
+ else if (data >= 0) { // Copy next data+1 literally
+ for (i = 0; i <= (byte)data; i++, k++)
+ *tmpImage++ = _sceneryArchive1.readByte();
+ } else { // Repeat next byte -data+1 times
+ int16 j = _sceneryArchive1.readByte();
+
+ for (i = 0; i < (byte)(-data + 1); i++, k++)
+ *tmpImage++ = j;
+ }
+ } while (k < OVL_SIZE);
+}
+
+char *FileManager_v2d::fetchString(int index) {
+// Fetch string from file, decode and return ptr to string in memory
+ debugC(1, kDebugFile, "fetchString(%d)", index);
+
+ // Get offset to string[index] (and next for length calculation)
+ _stringArchive.seek((uint32)index * sizeof(uint32), SEEK_SET);
+ uint32 off1, off2;
+ if (_stringArchive.read((char *)&off1, sizeof(uint32)) == 0)
+ Utils::Error(FILE_ERR, "%s", "String offset");
+ if (_stringArchive.read((char *)&off2, sizeof(uint32)) == 0)
+ Utils::Error(FILE_ERR, "%s", "String offset");
+
+ // Check size of string
+ if ((off2 - off1) >= MAX_BOX)
+ Utils::Error(FILE_ERR, "%s", "Fetched string too long!");
+
+ // Position to string and read it into gen purpose _textBoxBuffer
+ _stringArchive.seek(off1, SEEK_SET);
+ if (_stringArchive.read(_textBoxBuffer, (uint16)(off2 - off1)) == 0)
+ Utils::Error(FILE_ERR, "%s", "Fetch_string");
+
+ // Null terminate, decode and return it
+ _textBoxBuffer[off2-off1] = '\0';
+ _vm.scheduler().decodeString(_textBoxBuffer);
+ return _textBoxBuffer;
+}
+} // End of namespace Hugo
+
diff --git a/engines/hugo/file_v3d.cpp b/engines/hugo/file_v3d.cpp
new file mode 100644
index 0000000000..e4809a7208
--- /dev/null
+++ b/engines/hugo/file_v3d.cpp
@@ -0,0 +1,200 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on original Hugo Trilogy source code
+ *
+ * Copyright (c) 1989-1995 David P. Gray
+ *
+ */
+
+#include "common/system.h"
+
+#include "hugo/hugo.h"
+#include "hugo/file.h"
+#include "hugo/global.h"
+#include "hugo/display.h"
+#include "hugo/util.h"
+
+namespace Hugo {
+FileManager_v3d::FileManager_v3d(HugoEngine &vm) : FileManager_v2d(vm) {
+}
+
+FileManager_v3d::~FileManager_v3d() {
+}
+
+void FileManager_v3d::readBackground(int screenIndex) {
+// Read a PCX image into dib_a
+ debugC(1, kDebugFile, "readBackground(%d)", screenIndex);
+
+ _sceneryArchive1.seek((uint32) screenIndex * sizeof(sceneBlock_t), SEEK_SET);
+
+ sceneBlock_t sceneBlock; // Read a database header entry
+ sceneBlock.scene_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.scene_len = _sceneryArchive1.readUint32LE();
+ sceneBlock.b_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.b_len = _sceneryArchive1.readUint32LE();
+ sceneBlock.o_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.o_len = _sceneryArchive1.readUint32LE();
+ sceneBlock.ob_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.ob_len = _sceneryArchive1.readUint32LE();
+
+ seq_t dummySeq; // Image sequence structure for Read_pcx
+ if (screenIndex < 20) {
+ _sceneryArchive1.seek(sceneBlock.scene_off, SEEK_SET);
+ // Read the image into dummy seq and static dib_a
+ readPCX(_sceneryArchive1, &dummySeq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]);
+ } else {
+ _sceneryArchive2.seek(sceneBlock.scene_off, SEEK_SET);
+ // Read the image into dummy seq and static dib_a
+ readPCX(_sceneryArchive2, &dummySeq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]);
+ }
+}
+
+void FileManager_v3d::openDatabaseFiles() {
+ debugC(1, kDebugFile, "openDatabaseFiles");
+
+ if (!_stringArchive.open(STRING_FILE))
+ Utils::Error(FILE_ERR, "%s", STRING_FILE);
+ if (!_sceneryArchive1.open("scenery1.dat"))
+ Utils::Error(FILE_ERR, "%s", "scenery1.dat");
+ if (!_sceneryArchive2.open("scenery2.dat"))
+ Utils::Error(FILE_ERR, "%s", "scenery2.dat");
+ if (!_objectsArchive.open(OBJECTS_FILE))
+ Utils::Error(FILE_ERR, "%s", OBJECTS_FILE);
+}
+
+void FileManager_v3d::closeDatabaseFiles() {
+ debugC(1, kDebugFile, "closeDatabaseFiles");
+
+ _stringArchive.close();
+ _sceneryArchive1.close();
+ _sceneryArchive2.close();
+ _objectsArchive.close();
+}
+
+void FileManager_v3d::readOverlay(int screenNum, image_pt image, ovl_t overlayType) {
+// Open and read in an overlay file, close file
+ debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum);
+
+ image_pt tmpImage = image; // temp ptr to overlay file
+ _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET);
+
+ sceneBlock_t sceneBlock; // Database header entry
+ sceneBlock.scene_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.scene_len = _sceneryArchive1.readUint32LE();
+ sceneBlock.b_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.b_len = _sceneryArchive1.readUint32LE();
+ sceneBlock.o_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.o_len = _sceneryArchive1.readUint32LE();
+ sceneBlock.ob_off = _sceneryArchive1.readUint32LE();
+ sceneBlock.ob_len = _sceneryArchive1.readUint32LE();
+
+ uint32 i = 0;
+
+ if (screenNum < 20) {
+ switch (overlayType) {
+ case BOUNDARY:
+ _sceneryArchive1.seek(sceneBlock.b_off, SEEK_SET);
+ i = sceneBlock.b_len;
+ break;
+ case OVERLAY:
+ _sceneryArchive1.seek(sceneBlock.o_off, SEEK_SET);
+ i = sceneBlock.o_len;
+ break;
+ case OVLBASE:
+ _sceneryArchive1.seek(sceneBlock.ob_off, SEEK_SET);
+ i = sceneBlock.ob_len;
+ break;
+ default:
+ Utils::Error(FILE_ERR, "%s", "Bad ovl_type");
+ break;
+ }
+ if (i == 0) {
+ for (i = 0; i < OVL_SIZE; i++)
+ image[i] = 0;
+ return;
+ }
+
+ // Read in the overlay file using MAC Packbits. (We're not proud!)
+ int16 k = 0; // byte count
+ do {
+ int8 data = _sceneryArchive1.readByte();// Read a code byte
+ if ((byte)data == 0x80) // Noop
+ k = k;
+ else if (data >= 0) { // Copy next data+1 literally
+ for (i = 0; i <= (byte)data; i++, k++)
+ *tmpImage++ = _sceneryArchive1.readByte();
+ } else { // Repeat next byte -data+1 times
+ int16 j = _sceneryArchive1.readByte();
+
+ for (i = 0; i < (byte)(-data + 1); i++, k++)
+ *tmpImage++ = j;
+ }
+ } while (k < OVL_SIZE);
+ } else {
+ switch (overlayType) {
+ case BOUNDARY:
+ _sceneryArchive2.seek(sceneBlock.b_off, SEEK_SET);
+ i = sceneBlock.b_len;
+ break;
+ case OVERLAY:
+ _sceneryArchive2.seek(sceneBlock.o_off, SEEK_SET);
+ i = sceneBlock.o_len;
+ break;
+ case OVLBASE:
+ _sceneryArchive2.seek(sceneBlock.ob_off, SEEK_SET);
+ i = sceneBlock.ob_len;
+ break;
+ default:
+ Utils::Error(FILE_ERR, "%s", "Bad ovl_type");
+ break;
+ }
+ if (i == 0) {
+ for (i = 0; i < OVL_SIZE; i++)
+ image[i] = 0;
+ return;
+ }
+
+ // Read in the overlay file using MAC Packbits. (We're not proud!)
+ int16 k = 0; // byte count
+ do {
+ int8 data = _sceneryArchive2.readByte();// Read a code byte
+ if ((byte)data == 0x80) // Noop
+ k = k;
+ else if (data >= 0) { // Copy next data+1 literally
+ for (i = 0; i <= (byte)data; i++, k++)
+ *tmpImage++ = _sceneryArchive2.readByte();
+ } else { // Repeat next byte -data+1 times
+ int16 j = _sceneryArchive2.readByte();
+
+ for (i = 0; i < (byte)(-data + 1); i++, k++)
+ *tmpImage++ = j;
+ }
+ } while (k < OVL_SIZE);
+ }
+}
+} // End of namespace Hugo
+
diff --git a/engines/hugo/intro.cpp b/engines/hugo/intro.cpp
index 499f0136e9..b818bef027 100644
--- a/engines/hugo/intro.cpp
+++ b/engines/hugo/intro.cpp
@@ -32,13 +32,8 @@
#include "common/system.h"
-#include "hugo/game.h"
#include "hugo/hugo.h"
#include "hugo/intro.h"
-#include "hugo/file.h"
-#include "hugo/display.h"
-#include "hugo/util.h"
-
namespace Hugo {
@@ -48,325 +43,4 @@ IntroHandler::IntroHandler(HugoEngine &vm) : _vm(vm) {
IntroHandler::~IntroHandler() {
}
-intro_v1w::intro_v1w(HugoEngine &vm) : IntroHandler(vm) {
-}
-
-intro_v1w::~intro_v1w() {
-}
-
-void intro_v1w::preNewGame() {
- // Auto-start a new game
- _vm.file().restoreGame(-1);
- _vm.getGameStatus().viewState = V_INTROINIT;
-}
-
-void intro_v1w::introInit() {
-}
-
-bool intro_v1w::introPlay() {
- return true;
-}
-
-intro_v2w::intro_v2w(HugoEngine &vm) : IntroHandler(vm) {
-}
-
-intro_v2w::~intro_v2w() {
-}
-
-void intro_v2w::preNewGame() {
-}
-
-void intro_v2w::introInit() {
-}
-
-bool intro_v2w::introPlay() {
- return true;
-}
-
-intro_v3w::intro_v3w(HugoEngine &vm) : IntroHandler(vm) {
-}
-
-intro_v3w::~intro_v3w() {
-}
-
-void intro_v3w::preNewGame() {
-}
-
-void intro_v3w::introInit() {
-// Hugo 3 - show map and set up for introPlay()
-//#if STORY
- _vm.file().readBackground(22); // display screen MAP_3w
- _vm.screen().displayBackground();
- introTicks = 0;
- _vm.screen().loadFont(0);
-//#endif
-}
-
-bool intro_v3w::introPlay() {
- byte introSize = _vm.getIntroSize();
-
-// Hugo 3 - Preamble screen before going into game. Draws path of Hugo's plane.
-// Called every tick. Returns TRUE when complete
-//TODO : Add proper check of story mode
-//#if STORY
- if (introTicks < introSize) {
- // Scale viewport x_intro,y_intro to screen (offsetting y)
- _vm.screen().writeStr(_vm._introX[introTicks], _vm._introY[introTicks] - DIBOFF_Y, "x", _TBRIGHTWHITE);
- _vm.screen().displayBackground();
-
-
- // Text boxes at various times
- switch (introTicks) {
- case 4:
- Utils::Box(BOX_OK, "%s", _vm._textIntro[kIntro1]);
- break;
- case 9:
- Utils::Box(BOX_OK, "%s", _vm._textIntro[kIntro2]);
- break;
- case 35:
- Utils::Box(BOX_OK, "%s", _vm._textIntro[kIntro3]);
- break;
- }
- }
-
- return (++introTicks >= introSize);
-//#else //STORY
-// return true;
-//#endif //STORY
-}
-
-intro_v1d::intro_v1d(HugoEngine &vm) : IntroHandler(vm) {
-}
-
-intro_v1d::~intro_v1d() {
-}
-
-void intro_v1d::preNewGame() {
-}
-
-void intro_v1d::introInit() {
- introTicks = 0;
-}
-
-bool intro_v1d::introPlay() {
- static int state = 0;
- byte introSize = _vm.getIntroSize();
-
- if (introTicks < introSize) {
- switch (state++) {
- case 0:
- _vm.screen().drawRectangle(true, 0, 0, 319, 199, _TMAGENTA);
- _vm.screen().drawRectangle(true, 10, 10, 309, 189, _TBLACK);
- break;
-
- case 1:
- _vm.screen().drawShape(20, 92,_TLIGHTMAGENTA,_TMAGENTA);
- _vm.screen().drawShape(250,92,_TLIGHTMAGENTA,_TMAGENTA);
-
- // HACK: use of TROMAN, size 10-5
- _vm.screen().loadFont(0);
-
- char buffer[80];
- if (_boot.registered)
- strcpy(buffer, "Registered Version");
- else
- strcpy(buffer, "Shareware Version");
- _vm.screen().writeStr(CENTER, 163, buffer, _TLIGHTMAGENTA);
- _vm.screen().writeStr(CENTER, 176, COPYRIGHT, _TLIGHTMAGENTA);
-
- if (scumm_stricmp(_boot.distrib, "David P. Gray")) {
- sprintf(buffer, "Distributed by %s.", _boot.distrib);
- _vm.screen().writeStr(CENTER, 75, buffer, _TMAGENTA);
- }
-
- // HACK: use of SCRIPT size 24-16
- _vm.screen().loadFont(2);
-
- strcpy(buffer, "Hugo's");
- _vm.screen().writeStr(CENTER, 20, buffer, _TMAGENTA);
-
- //HACK: use of TROMAN, size 30-24
- strcpy(buffer, "House of Horrors !");
- _vm.screen().writeStr(CENTER, 50, buffer, _TLIGHTMAGENTA);
- break;
- case 2:
- _vm.screen().drawRectangle(true, 82, 92, 237, 138, _TBLACK);
- // HACK: use of TROMAN, size 16-9
- _vm.screen().loadFont(2);
-
- strcpy(buffer, "S t a r r i n g :");
- _vm.screen().writeStr(CENTER, 95, buffer, _TMAGENTA);
- break;
- case 3:
- // HACK: use of TROMAN size 20-9
- _vm.screen().loadFont(2);
-
- strcpy(buffer, "Hugo !");
- _vm.screen().writeStr(CENTER, 115, buffer, _TLIGHTMAGENTA);
- break;
- case 4:
- _vm.screen().drawRectangle(true, 82, 92, 237, 138, _TBLACK);
- // HACK: use of TROMAN size 16-9
- _vm.screen().loadFont(2);
-
- strcpy(buffer, "P r o d u c e d b y :");
- _vm.screen().writeStr(CENTER, 95, buffer, _TMAGENTA);
- break;
- case 5:
- // HACK: use of TROMAN size 16-9
- _vm.screen().loadFont(2);
-
- strcpy(buffer, "David P Gray !");
- _vm.screen().writeStr(CENTER, 115, buffer, _TLIGHTMAGENTA);
- break;
- case 6:
- _vm.screen().drawRectangle(true, 82, 92, 237, 138, _TBLACK);
- // HACK: use of TROMAN size 16-9
- _vm.screen().loadFont(2);
-
- strcpy(buffer, "D i r e c t e d b y :");
- _vm.screen().writeStr(CENTER, 95, buffer, _TMAGENTA);
- break;
- case 7:
- // HACK: use of TROMAN size 16-9
- _vm.screen().loadFont(2);
-
- strcpy(buffer, "David P Gray !");
- _vm.screen().writeStr(CENTER, 115, buffer, _TLIGHTMAGENTA);
- break;
- case 8:
- _vm.screen().drawRectangle(true, 82, 92, 237, 138, _TBLACK);
- // HACK: use of TROMAN size 16-9
- _vm.screen().loadFont(2);
-
- strcpy(buffer, "M u s i c b y :");
- _vm.screen().writeStr(CENTER, 95, buffer, _TMAGENTA);
- break;
- case 9:
- // HACK: use of TROMAN size 16-9
- _vm.screen().loadFont(2);
-
- strcpy(buffer, "David P Gray !");
- _vm.screen().writeStr(CENTER, 115, buffer, _TLIGHTMAGENTA);
- break;
- case 10:
- _vm.screen().drawRectangle(true, 82, 92, 237, 138, _TBLACK);
- // HACK: use of TROMAN size 20-14
- _vm.screen().loadFont(2);
-
- strcpy(buffer, "E n j o y !");
- _vm.screen().writeStr(CENTER, 100, buffer, _TLIGHTMAGENTA);
- break;
- }
-
- _vm.screen().displayBackground();
- g_system->updateScreen();
- g_system->delayMillis(1000);
- }
-
- return (++introTicks >= introSize);
-}
-
-intro_v2d::intro_v2d(HugoEngine &vm) : IntroHandler(vm) {
-}
-
-intro_v2d::~intro_v2d() {
-}
-
-void intro_v2d::preNewGame() {
-}
-
-void intro_v2d::introInit() {
- _vm.screen().loadFont(0);
- _vm.file().readBackground(_vm._numScreens - 1); // display splash screen
-
- char buffer[128];
-
- if (_boot.registered)
- sprintf(buffer, "%s Registered Version", COPYRIGHT);
- else
- sprintf(buffer, "%s Shareware Version", COPYRIGHT);
- _vm.screen().writeStr(CENTER, 186, buffer, _TLIGHTRED);
-
- if (scumm_stricmp(_boot.distrib, "David P. Gray")) {
- sprintf(buffer, "Distributed by %s.", _boot.distrib);
- _vm.screen().writeStr(CENTER, 1, buffer, _TLIGHTRED);
- }
-
- _vm.screen().displayBackground();
- g_system->updateScreen();
- g_system->delayMillis(5000);
-}
-
-bool intro_v2d::introPlay() {
- return true;
-}
-
-//TODO : Add code for intro H3 DOS
-intro_v3d::intro_v3d(HugoEngine &vm) : IntroHandler(vm) {
-}
-
-intro_v3d::~intro_v3d() {
-}
-
-void intro_v3d::preNewGame() {
-}
-
-void intro_v3d::introInit() {
- _vm.screen().loadFont(0);
- _vm.file().readBackground(_vm._numScreens - 1); // display splash screen
-
- char buffer[128];
- if (_boot.registered)
- sprintf(buffer, "%s Registered Version", COPYRIGHT);
- else
- sprintf(buffer,"%s Shareware Version", COPYRIGHT);
-
- _vm.screen().writeStr(CENTER, 190, buffer, _TBROWN);
-
- if (scumm_stricmp(_boot.distrib, "David P. Gray")) {
- sprintf(buffer, "Distributed by %s.", _boot.distrib);
- _vm.screen().writeStr(CENTER, 0, buffer, _TBROWN);
- }
-
- _vm.screen().displayBackground();
- g_system->updateScreen();
- g_system->delayMillis(5000);
-
- _vm.file().readBackground(22); // display screen MAP_3d
- _vm.screen().displayBackground();
- introTicks = 0;
-}
-
-bool intro_v3d::introPlay() {
- byte introSize = _vm.getIntroSize();
-
-// Hugo 3 - Preamble screen before going into game. Draws path of Hugo's plane.
-// Called every tick. Returns TRUE when complete
-//TODO : Add proper check of story mode
-//#if STORY
- if (introTicks < introSize) {
- _vm.screen().writeStr(_vm._introX[introTicks], _vm._introY[introTicks] - DIBOFF_Y, "x", _TBRIGHTWHITE);
- _vm.screen().displayBackground();
-
- // Text boxes at various times
- switch (introTicks) {
- case 4:
- Utils::Box(BOX_OK, "%s", _vm._textIntro[kIntro1]);
- break;
- case 9:
- Utils::Box(BOX_OK, "%s", _vm._textIntro[kIntro2]);
- break;
- case 35:
- Utils::Box(BOX_OK, "%s", _vm._textIntro[kIntro3]);
- break;
- }
- }
-
- return (++introTicks >= introSize);
-//#else //STORY
-// return true;
-//#endif //STORY
-}
-
} // End of namespace Hugo
diff --git a/engines/hugo/intro_v1d.cpp b/engines/hugo/intro_v1d.cpp
new file mode 100644
index 0000000000..0e3067f0e9
--- /dev/null
+++ b/engines/hugo/intro_v1d.cpp
@@ -0,0 +1,172 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on original Hugo Trilogy source code
+ *
+ * Copyright (c) 1989-1995 David P. Gray
+ *
+ */
+
+#include "common/system.h"
+
+#include "hugo/hugo.h"
+#include "hugo/intro.h"
+#include "hugo/display.h"
+
+namespace Hugo {
+intro_v1d::intro_v1d(HugoEngine &vm) : IntroHandler(vm) {
+}
+
+intro_v1d::~intro_v1d() {
+}
+
+void intro_v1d::preNewGame() {
+}
+
+void intro_v1d::introInit() {
+ introTicks = 0;
+}
+
+bool intro_v1d::introPlay() {
+ static int state = 0;
+ byte introSize = _vm.getIntroSize();
+
+ if (introTicks < introSize) {
+ switch (state++) {
+ case 0:
+ _vm.screen().drawRectangle(true, 0, 0, 319, 199, _TMAGENTA);
+ _vm.screen().drawRectangle(true, 10, 10, 309, 189, _TBLACK);
+ break;
+
+ case 1:
+ _vm.screen().drawShape(20, 92,_TLIGHTMAGENTA,_TMAGENTA);
+ _vm.screen().drawShape(250,92,_TLIGHTMAGENTA,_TMAGENTA);
+
+ // HACK: use of TROMAN, size 10-5
+ _vm.screen().loadFont(0);
+
+ char buffer[80];
+ if (_boot.registered)
+ strcpy(buffer, "Registered Version");
+ else
+ strcpy(buffer, "Shareware Version");
+ _vm.screen().writeStr(CENTER, 163, buffer, _TLIGHTMAGENTA);
+ _vm.screen().writeStr(CENTER, 176, COPYRIGHT, _TLIGHTMAGENTA);
+
+ if (scumm_stricmp(_boot.distrib, "David P. Gray")) {
+ sprintf(buffer, "Distributed by %s.", _boot.distrib);
+ _vm.screen().writeStr(CENTER, 75, buffer, _TMAGENTA);
+ }
+
+ // HACK: use of SCRIPT size 24-16
+ _vm.screen().loadFont(2);
+
+ strcpy(buffer, "Hugo's");
+ _vm.screen().writeStr(CENTER, 20, buffer, _TMAGENTA);
+
+ // HACK: use of TROMAN, size 30-24
+ strcpy(buffer, "House of Horrors !");
+ _vm.screen().writeStr(CENTER, 50, buffer, _TLIGHTMAGENTA);
+ break;
+ case 2:
+ _vm.screen().drawRectangle(true, 82, 92, 237, 138, _TBLACK);
+ // HACK: use of TROMAN, size 16-9
+ _vm.screen().loadFont(2);
+
+ strcpy(buffer, "S t a r r i n g :");
+ _vm.screen().writeStr(CENTER, 95, buffer, _TMAGENTA);
+ break;
+ case 3:
+ // HACK: use of TROMAN size 20-9
+ _vm.screen().loadFont(2);
+
+ strcpy(buffer, "Hugo !");
+ _vm.screen().writeStr(CENTER, 115, buffer, _TLIGHTMAGENTA);
+ break;
+ case 4:
+ _vm.screen().drawRectangle(true, 82, 92, 237, 138, _TBLACK);
+ // HACK: use of TROMAN size 16-9
+ _vm.screen().loadFont(2);
+
+ strcpy(buffer, "P r o d u c e d b y :");
+ _vm.screen().writeStr(CENTER, 95, buffer, _TMAGENTA);
+ break;
+ case 5:
+ // HACK: use of TROMAN size 16-9
+ _vm.screen().loadFont(2);
+
+ strcpy(buffer, "David P Gray !");
+ _vm.screen().writeStr(CENTER, 115, buffer, _TLIGHTMAGENTA);
+ break;
+ case 6:
+ _vm.screen().drawRectangle(true, 82, 92, 237, 138, _TBLACK);
+ // HACK: use of TROMAN size 16-9
+ _vm.screen().loadFont(2);
+
+ strcpy(buffer, "D i r e c t e d b y :");
+ _vm.screen().writeStr(CENTER, 95, buffer, _TMAGENTA);
+ break;
+ case 7:
+ // HACK: use of TROMAN size 16-9
+ _vm.screen().loadFont(2);
+
+ strcpy(buffer, "David P Gray !");
+ _vm.screen().writeStr(CENTER, 115, buffer, _TLIGHTMAGENTA);
+ break;
+ case 8:
+ _vm.screen().drawRectangle(true, 82, 92, 237, 138, _TBLACK);
+ // HACK: use of TROMAN size 16-9
+ _vm.screen().loadFont(2);
+
+ strcpy(buffer, "M u s i c b y :");
+ _vm.screen().writeStr(CENTER, 95, buffer, _TMAGENTA);
+ break;
+ case 9:
+ // HACK: use of TROMAN size 16-9
+ _vm.screen().loadFont(2);
+
+ strcpy(buffer, "David P Gray !");
+ _vm.screen().writeStr(CENTER, 115, buffer, _TLIGHTMAGENTA);
+ break;
+ case 10:
+ _vm.screen().drawRectangle(true, 82, 92, 237, 138, _TBLACK);
+ // HACK: use of TROMAN size 20-14
+ _vm.screen().loadFont(2);
+
+ strcpy(buffer, "E n j o y !");
+ _vm.screen().writeStr(CENTER, 100, buffer, _TLIGHTMAGENTA);
+ break;
+ }
+
+ _vm.screen().displayBackground();
+ g_system->updateScreen();
+ g_system->delayMillis(1000);
+ }
+
+ return (++introTicks >= introSize);
+}
+
+} // End of namespace Hugo
diff --git a/engines/hugo/intro_v1w.cpp b/engines/hugo/intro_v1w.cpp
new file mode 100644
index 0000000000..38921fd3e4
--- /dev/null
+++ b/engines/hugo/intro_v1w.cpp
@@ -0,0 +1,61 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on original Hugo Trilogy source code
+ *
+ * Copyright (c) 1989-1995 David P. Gray
+ *
+ */
+
+#include "common/system.h"
+
+#include "hugo/hugo.h"
+#include "hugo/intro.h"
+#include "hugo/file.h"
+
+
+
+namespace Hugo {
+intro_v1w::intro_v1w(HugoEngine &vm) : IntroHandler(vm) {
+}
+
+intro_v1w::~intro_v1w() {
+}
+
+void intro_v1w::preNewGame() {
+ // Auto-start a new game
+ _vm.file().restoreGame(-1);
+ _vm.getGameStatus().viewState = V_INTROINIT;
+}
+
+void intro_v1w::introInit() {
+}
+
+bool intro_v1w::introPlay() {
+ return true;
+}
+
+} // End of namespace Hugo
diff --git a/engines/hugo/intro_v2d.cpp b/engines/hugo/intro_v2d.cpp
new file mode 100644
index 0000000000..bfae11b77e
--- /dev/null
+++ b/engines/hugo/intro_v2d.cpp
@@ -0,0 +1,77 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on original Hugo Trilogy source code
+ *
+ * Copyright (c) 1989-1995 David P. Gray
+ *
+ */
+
+#include "common/system.h"
+
+#include "hugo/hugo.h"
+#include "hugo/intro.h"
+#include "hugo/file.h"
+#include "hugo/display.h"
+
+namespace Hugo {
+
+intro_v2d::intro_v2d(HugoEngine &vm) : IntroHandler(vm) {
+}
+
+intro_v2d::~intro_v2d() {
+}
+
+void intro_v2d::preNewGame() {
+}
+
+void intro_v2d::introInit() {
+ _vm.screen().loadFont(0);
+ _vm.file().readBackground(_vm._numScreens - 1); // display splash screen
+
+ char buffer[128];
+
+ if (_boot.registered)
+ sprintf(buffer, "%s Registered Version", COPYRIGHT);
+ else
+ sprintf(buffer, "%s Shareware Version", COPYRIGHT);
+ _vm.screen().writeStr(CENTER, 186, buffer, _TLIGHTRED);
+
+ if (scumm_stricmp(_boot.distrib, "David P. Gray")) {
+ sprintf(buffer, "Distributed by %s.", _boot.distrib);
+ _vm.screen().writeStr(CENTER, 1, buffer, _TLIGHTRED);
+ }
+
+ _vm.screen().displayBackground();
+ g_system->updateScreen();
+ g_system->delayMillis(5000);
+}
+
+bool intro_v2d::introPlay() {
+ return true;
+}
+
+} // End of namespace Hugo
diff --git a/engines/hugo/intro_v2w.cpp b/engines/hugo/intro_v2w.cpp
new file mode 100644
index 0000000000..f68761eac9
--- /dev/null
+++ b/engines/hugo/intro_v2w.cpp
@@ -0,0 +1,57 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on original Hugo Trilogy source code
+ *
+ * Copyright (c) 1989-1995 David P. Gray
+ *
+ */
+
+#include "common/system.h"
+
+#include "hugo/hugo.h"
+#include "hugo/intro.h"
+
+
+namespace Hugo {
+
+intro_v2w::intro_v2w(HugoEngine &vm) : IntroHandler(vm) {
+}
+
+intro_v2w::~intro_v2w() {
+}
+
+void intro_v2w::preNewGame() {
+}
+
+void intro_v2w::introInit() {
+}
+
+bool intro_v2w::introPlay() {
+ return true;
+}
+
+} // End of namespace Hugo
diff --git a/engines/hugo/intro_v3d.cpp b/engines/hugo/intro_v3d.cpp
new file mode 100644
index 0000000000..3dd2a58d8b
--- /dev/null
+++ b/engines/hugo/intro_v3d.cpp
@@ -0,0 +1,109 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on original Hugo Trilogy source code
+ *
+ * Copyright (c) 1989-1995 David P. Gray
+ *
+ */
+
+#include "common/system.h"
+
+#include "hugo/hugo.h"
+#include "hugo/intro.h"
+#include "hugo/file.h"
+#include "hugo/display.h"
+#include "hugo/util.h"
+
+
+namespace Hugo {
+intro_v3d::intro_v3d(HugoEngine &vm) : IntroHandler(vm) {
+}
+
+intro_v3d::~intro_v3d() {
+}
+
+void intro_v3d::preNewGame() {
+}
+
+void intro_v3d::introInit() {
+ _vm.screen().loadFont(0);
+ _vm.file().readBackground(_vm._numScreens - 1); // display splash screen
+
+ char buffer[128];
+ if (_boot.registered)
+ sprintf(buffer, "%s Registered Version", COPYRIGHT);
+ else
+ sprintf(buffer,"%s Shareware Version", COPYRIGHT);
+
+ _vm.screen().writeStr(CENTER, 190, buffer, _TBROWN);
+
+ if (scumm_stricmp(_boot.distrib, "David P. Gray")) {
+ sprintf(buffer, "Distributed by %s.", _boot.distrib);
+ _vm.screen().writeStr(CENTER, 0, buffer, _TBROWN);
+ }
+
+ _vm.screen().displayBackground();
+ g_system->updateScreen();
+ g_system->delayMillis(5000);
+
+ _vm.file().readBackground(22); // display screen MAP_3d
+ _vm.screen().displayBackground();
+ introTicks = 0;
+}
+
+bool intro_v3d::introPlay() {
+ byte introSize = _vm.getIntroSize();
+
+// Hugo 3 - Preamble screen before going into game. Draws path of Hugo's plane.
+// Called every tick. Returns TRUE when complete
+//TODO : Add proper check of story mode
+//#if STORY
+ if (introTicks < introSize) {
+ _vm.screen().writeStr(_vm._introX[introTicks], _vm._introY[introTicks] - DIBOFF_Y, "x", _TBRIGHTWHITE);
+ _vm.screen().displayBackground();
+
+ // Text boxes at various times
+ switch (introTicks) {
+ case 4:
+ Utils::Box(BOX_OK, "%s", _vm._textIntro[kIntro1]);
+ break;
+ case 9:
+ Utils::Box(BOX_OK, "%s", _vm._textIntro[kIntro2]);
+ break;
+ case 35:
+ Utils::Box(BOX_OK, "%s", _vm._textIntro[kIntro3]);
+ break;
+ }
+ }
+
+ return (++introTicks >= introSize);
+//#else //STORY
+// return true;
+//#endif //STORY
+}
+
+} // End of namespace Hugo
diff --git a/engines/hugo/intro_v3w.cpp b/engines/hugo/intro_v3w.cpp
new file mode 100644
index 0000000000..924fa46805
--- /dev/null
+++ b/engines/hugo/intro_v3w.cpp
@@ -0,0 +1,94 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on original Hugo Trilogy source code
+ *
+ * Copyright (c) 1989-1995 David P. Gray
+ *
+ */
+
+#include "common/system.h"
+
+#include "hugo/hugo.h"
+#include "hugo/intro.h"
+#include "hugo/file.h"
+#include "hugo/display.h"
+#include "hugo/util.h"
+
+namespace Hugo {
+
+intro_v3w::intro_v3w(HugoEngine &vm) : IntroHandler(vm) {
+}
+
+intro_v3w::~intro_v3w() {
+}
+
+void intro_v3w::preNewGame() {
+}
+
+void intro_v3w::introInit() {
+// Hugo 3 - show map and set up for introPlay()
+//#if STORY
+ _vm.file().readBackground(22); // display screen MAP_3w
+ _vm.screen().displayBackground();
+ introTicks = 0;
+ _vm.screen().loadFont(0);
+//#endif
+}
+
+bool intro_v3w::introPlay() {
+ byte introSize = _vm.getIntroSize();
+
+// Hugo 3 - Preamble screen before going into game. Draws path of Hugo's plane.
+// Called every tick. Returns TRUE when complete
+//TODO : Add proper check of story mode
+//#if STORY
+ if (introTicks < introSize) {
+ // Scale viewport x_intro,y_intro to screen (offsetting y)
+ _vm.screen().writeStr(_vm._introX[introTicks], _vm._introY[introTicks] - DIBOFF_Y, "x", _TBRIGHTWHITE);
+ _vm.screen().displayBackground();
+
+
+ // Text boxes at various times
+ switch (introTicks) {
+ case 4:
+ Utils::Box(BOX_OK, "%s", _vm._textIntro[kIntro1]);
+ break;
+ case 9:
+ Utils::Box(BOX_OK, "%s", _vm._textIntro[kIntro2]);
+ break;
+ case 35:
+ Utils::Box(BOX_OK, "%s", _vm._textIntro[kIntro3]);
+ break;
+ }
+ }
+
+ return (++introTicks >= introSize);
+//#else //STORY
+// return true;
+//#endif //STORY
+}
+} // End of namespace Hugo
diff --git a/engines/hugo/module.mk b/engines/hugo/module.mk
index f7aa45a2c2..1f2b3ac65e 100644
--- a/engines/hugo/module.mk
+++ b/engines/hugo/module.mk
@@ -3,15 +3,32 @@ MODULE := engines/hugo
MODULE_OBJS := \
detection.o \
display.o \
+ display_v1d.o \
+ display_v1w.o \
engine.o \
file.o \
+ file_v1d.o \
+ file_v2d.o \
+ file_v3d.o \
+ file_v1w.o \
hugo.o \
intro.o \
+ intro_v1d.o \
+ intro_v2d.o \
+ intro_v3d.o \
+ intro_v1w.o \
+ intro_v2w.o \
+ intro_v3w.o \
inventory.o \
mouse.o \
parser.o \
+ parser_v1w.o \
+ parser_v1d.o \
+ parser_v2d.o \
route.o \
schedule.o \
+ schedule_v1d.o \
+ schedule_v3d.o \
sound.o \
util.o
diff --git a/engines/hugo/parser.cpp b/engines/hugo/parser.cpp
index d116dda5f3..0a4ca3a5a8 100644
--- a/engines/hugo/parser.cpp
+++ b/engines/hugo/parser.cpp
@@ -30,17 +30,11 @@
*
*/
-// parser.c - handles all keyboard/command input
-
#include "common/system.h"
-#include "common/keyboard.h"
-#include "hugo/game.h"
#include "hugo/hugo.h"
#include "hugo/parser.h"
-#include "hugo/global.h"
#include "hugo/file.h"
-#include "hugo/schedule.h"
#include "hugo/display.h"
#include "hugo/route.h"
#include "hugo/util.h"
@@ -205,395 +199,6 @@ void Parser::command(const char *format, ...) {
lineHandler();
}
-Parser_v1w::Parser_v1w(HugoEngine &vm) : Parser(vm) {
-}
-
-Parser_v1w::~Parser_v1w() {
-}
-
-// Test whether command line contains a verb allowed by this object.
-// If it does, and the object is near and passes the tests in the command
-// list then carry out the actions in the action list and return TRUE
-bool Parser_v1w::isObjectVerb(object_t *obj, char *comment) {
- debugC(1, kDebugParser, "isObjectVerb(object_t *obj, %s)", comment);
-
- // First, find matching verb in cmd list
- uint16 cmdIndex = obj->cmdIndex; // ptr to list of commands
- if (cmdIndex == 0) // No commands for this obj
- return false;
-
- int i;
- for (i = 0; _vm._cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd
- if (isWordPresent(_vm._arrayVerbs[_vm._cmdList[cmdIndex][i].verbIndex])) // Was this verb used?
- break;
- }
-
- if (_vm._cmdList[cmdIndex][i].verbIndex == 0) // No verbs used.
- return false;
-
- // Verb match found. Check if object is Near
- char *verb = *_vm._arrayVerbs[_vm._cmdList[cmdIndex][i].verbIndex];
- if (!isNear(obj, verb, comment))
- return false;
-
- // Check all required objects are being carried
- cmd *cmnd = &_vm._cmdList[cmdIndex][i]; // ptr to struct cmd
- if (cmnd->reqIndex) { // At least 1 thing in list
- uint16 *reqs = _vm._arrayReqs[cmnd->reqIndex]; // ptr to list of required objects
- for (i = 0; reqs[i]; i++) { // for each obj
- if (!isCarrying(reqs[i])) {
- Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataNoCarryIndex]);
- return true;
- }
- }
- }
-
- // Required objects are present, now check state is correct
- if ((obj->state != cmnd->reqState) && (cmnd->reqState != DONT_CARE)) {
- Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataWrongIndex]);
- return true;
- }
-
- // Everything checked. Change the state and carry out any actions
- if (cmnd->reqState != DONT_CARE) // Don't change new state if required state didn't care
- obj->state = cmnd->newState;
- Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataDoneIndex]);
- _vm.scheduler().insertActionList(cmnd->actIndex);
-
- // See if any additional generic actions
- if ((verb == _vm._arrayVerbs[_vm._look][0]) || (verb == _vm._arrayVerbs[_vm._take][0]) || (verb == _vm._arrayVerbs[_vm._drop][0]))
- isGenericVerb(obj, comment);
- return true;
-}
-
-// Test whether command line contains one of the generic actions
-bool Parser_v1w::isGenericVerb(object_t *obj, char *comment) {
- debugC(1, kDebugParser, "isGenericVerb(object_t *obj, %s)", comment);
-
- if (!obj->genericCmd)
- return false;
-
- // Following is equivalent to switch, but couldn't do one
- if (isWordPresent(_vm._arrayVerbs[_vm._look]) && isNear(obj, _vm._arrayVerbs[_vm._look][0], comment)) {
- // Test state-dependent look before general look
- if ((obj->genericCmd & LOOK_S) == LOOK_S) {
- Utils::Box(BOX_ANY, "%s", _vm._textData[obj->stateDataIndex[obj->state]]);
- warning("isGenericVerb: use of state dependant look - To be validated");
- } else {
- if ((LOOK & obj->genericCmd) == LOOK) {
- if (_vm._textData[obj->dataIndex])
- Utils::Box(BOX_ANY, "%s", _vm._textData[obj->dataIndex]);
- else
- return false;
- } else {
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBUnusual]);
- }
- }
- } else if (isWordPresent(_vm._arrayVerbs[_vm._take]) && isNear(obj, _vm._arrayVerbs[_vm._take][0], comment)) {
- if (obj->carriedFl)
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBHave]);
- else if ((TAKE & obj->genericCmd) == TAKE)
- takeObject(obj);
- else if (obj->cmdIndex != 0) // No comment if possible commands
- return false;
- else if (!obj->verbOnlyFl && (TAKE & obj->genericCmd) == TAKE) // Make sure not taking object in context!
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoUse]);
- else
- return false;
- } else if (isWordPresent(_vm._arrayVerbs[_vm._drop])) {
- if (!obj->carriedFl && ((DROP & obj->genericCmd) == DROP))
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBDontHave]);
- else if (obj->carriedFl && ((DROP & obj->genericCmd) == DROP))
- dropObject(obj);
- else if (obj->cmdIndex == 0)
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNeed]);
- else
- return false;
- } else { // It was not a generic cmd
- return false;
- }
-
- return true;
-}
-
-// Test whether hero is close to object. Return TRUE or FALSE
-// If object not near, return suitable comment; may be another object close
-// If radius is -1, treat radius as infinity
-// Verb is included to determine correct comment if not near
-bool Parser_v1w::isNear(object_t *obj, char *verb, char *comment) {
- debugC(1, kDebugParser, "isNear(object_t *obj, %s, %s)", verb, comment);
-
- if (obj->carriedFl) // Object is being carried
- return true;
-
- if (obj->screenIndex != *_vm._screen_p) {
- // Not in same screen
- if (obj->objValue)
- strcpy(comment, _vm._textParser[kCmtAny1]);
- else
- strcpy(comment, _vm._textParser[kCmtAny2]);
- return false;
- }
-
- if (obj->cycling == INVISIBLE) {
- if (obj->seqNumb) {
- // There is an image
- strcpy(comment, _vm._textParser[kCmtAny3]);
- return false;
- } else {
- // No image, assume visible
- if ((obj->radius < 0) ||
- ((abs(obj->x - _vm._hero->x) <= obj->radius) &&
- (abs(obj->y - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) {
- return true;
- } else {
- // User is not close enough
- if (obj->objValue && (verb != _vm._arrayVerbs[_vm._take][0]))
- strcpy(comment, _vm._textParser[kCmtAny1]);
- else
- strcpy(comment, _vm._textParser[kCmtClose]);
- return false;
- }
- }
- }
-
- if ((obj->radius < 0) ||
- ((abs(obj->x - _vm._hero->x) <= obj->radius) &&
- (abs(obj->y + obj->currImagePtr->y2 - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) {
- return true;
- } else {
- // User is not close enough
- if (obj->objValue && (verb != _vm._arrayVerbs[_vm._take][0]))
- strcpy(comment, _vm._textParser[kCmtAny1]);
- else
- strcpy(comment, _vm._textParser[kCmtClose]);
- return false;
- }
- return true;
-}
-
-// Do all things necessary to carry an object
-void Parser_v1w::takeObject(object_t *obj) {
- debugC(1, kDebugParser, "takeObject(object_t *obj)");
-
- obj->carriedFl = true;
- if (obj->seqNumb) { // Don't change if no image to display
- obj->cycling = INVISIBLE;
- }
- _vm.adjustScore(obj->objValue);
-
- if (obj->seqNumb > 0) // If object has an image, force walk to dropped
- obj->viewx = -1; // (possibly moved) object next time taken!
- Utils::Box(BOX_ANY, TAKE_TEXT, _vm._arrayNouns[obj->nounIndex][TAKE_NAME]);
-}
-
-// Do all necessary things to drop an object
-void Parser_v1w::dropObject(object_t *obj) {
- debugC(1, kDebugParser, "dropObject(object_t *obj)");
-
- obj->carriedFl = false;
- obj->screenIndex = *_vm._screen_p;
- if ((obj->seqNumb > 1) || (obj->seqList[0].imageNbr > 1))
- obj->cycling = CYCLE_FORWARD;
- else
- obj->cycling = NOT_CYCLING;
- obj->x = _vm._hero->x - 1;
- obj->y = _vm._hero->y + _vm._hero->currImagePtr->y2 - 1;
- obj->y = (obj->y + obj->currImagePtr->y2 < YPIX) ? obj->y : YPIX - obj->currImagePtr->y2 - 10;
- _vm.adjustScore(-obj->objValue);
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBOk]);
-}
-
-// Search for matching verbs in background command list.
-// Noun is not required. Return TRUE if match found
-// Note that if the background command list has match set TRUE then do not
-// print text if there are any recognizable nouns in the command line
-bool Parser_v1w::isCatchallVerb(objectList_t obj) {
- debugC(1, kDebugParser, "isCatchallVerb(object_list_t obj)");
-
- for (int i = 0; obj[i].verbIndex != 0; i++) {
- if (isWordPresent(_vm._arrayVerbs[obj[i].verbIndex]) && obj[i].nounIndex == 0 &&
- (!obj[i].matchFl || !findNoun()) &&
- ((obj[i].roomState == DONT_CARE) ||
- (obj[i].roomState == _vm._screenStates[*_vm._screen_p]))) {
- Utils::Box(BOX_ANY, "%s", _vm.file().fetchString(obj[i].commentIndex));
- _vm.scheduler().processBonus(obj[i].bonusIndex);
-
- // If this is LOOK (without a noun), show any takeable objects
- if (*(_vm._arrayVerbs[obj[i].verbIndex]) == _vm._arrayVerbs[_vm._look][0])
- showTakeables();
-
- return true;
- }
- }
- return false;
-}
-
-// Search for matching verb/noun pairs in background command list
-// Print text for possible background object. Return TRUE if match found
-bool Parser_v1w::isBackgroundWord(objectList_t obj) {
- debugC(1, kDebugParser, "isBackgroundWord(object_list_t obj)");
-
- for (int i = 0; obj[i].verbIndex != 0; i++) {
- if (isWordPresent(_vm._arrayVerbs[obj[i].verbIndex]) &&
- isWordPresent(_vm._arrayNouns[obj[i].nounIndex]) &&
- ((obj[i].roomState == DONT_CARE) ||
- (obj[i].roomState == _vm._screenStates[*_vm._screen_p]))) {
- Utils::Box(BOX_ANY, "%s", _vm.file().fetchString(obj[i].commentIndex));
- _vm.scheduler().processBonus(obj[i].bonusIndex);
- return true;
- }
- }
- return false;
-}
-
-// Parse the user's line of text input. Generate events as necessary
-void Parser_v1w::lineHandler() {
- debugC(1, kDebugParser, "lineHandler()");
-
- status_t &gameStatus = _vm.getGameStatus();
-
- // Toggle God Mode
- if (!strncmp(_line, "PPG", 3)) {
- _vm.sound().playSound(!_vm._soundTest, BOTH_CHANNELS, HIGH_PRI);
- gameStatus.godModeFl ^= 1;
- return;
- }
-
- Utils::strlwr(_line); // Convert to lower case
-
- // God Mode cheat commands:
- // goto <screen> Takes hero to named screen
- // fetch <object name> Hero carries named object
- // fetch all Hero carries all possible objects
- // find <object name> Takes hero to screen containing named object
- if (gameStatus.godModeFl) {
- // Special code to allow me to go straight to any screen
- if (strstr(_line, "goto")) {
- for (int i = 0; i < _vm._numScreens; i++) {
- if (!strcmp(&_line[strlen("goto") + 1], _vm._screenNames[i])) {
- _vm.scheduler().newScreen(i);
- return;
- }
- }
- }
-
- // Special code to allow me to get objects from anywhere
- if (strstr(_line, "fetch all")) {
- for (int i = 0; i < _vm._numObj; i++) {
- if (_vm._objects[i].genericCmd & TAKE)
- takeObject(&_vm._objects[i]);
- }
- return;
- }
-
- if (strstr(_line, "fetch")) {
- for (int i = 0; i < _vm._numObj; i++) {
- if (!strcmp(&_line[strlen("fetch") + 1], _vm._arrayNouns[_vm._objects[i].nounIndex][0])) {
- takeObject(&_vm._objects[i]);
- return;
- }
- }
- }
-
- // Special code to allow me to goto objects
- if (strstr(_line, "find")) {
- for (int i = 0; i < _vm._numObj; i++) {
- if (!strcmp(&_line[strlen("find") + 1], _vm._arrayNouns[_vm._objects[i].nounIndex][0])) {
- _vm.scheduler().newScreen(_vm._objects[i].screenIndex);
- return;
- }
- }
- }
- }
-
- // Special meta commands
- // EXIT/QUIT
- if (!strcmp("exit", _line) || strstr(_line, "quit")) {
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBExit]);
- return;
- }
-
- // SAVE/RESTORE
- if (!strcmp("save", _line) && gameStatus.viewState == V_PLAY) {
- _vm.file().saveGame(gameStatus.saveSlot, "Current game");
- return;
- }
-
- if (!strcmp("restore", _line) && (gameStatus.viewState == V_PLAY || gameStatus.viewState == V_IDLE)) {
- _vm.file().restoreGame(gameStatus.saveSlot);
- _vm.scheduler().restoreScreen(*_vm._screen_p);
- gameStatus.viewState = V_PLAY;
- return;
- }
-
- // Empty line
- if (*_line == '\0') // Empty line
- return;
- if (strspn(_line, " ") == strlen(_line)) // Nothing but spaces!
- return;
-
- if (gameStatus.gameOverFl) {
- // No commands allowed!
- Utils::gameOverMsg();
- return;
- }
-
- char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby
-
- // Test for nearby objects referenced explicitly
- for (int i = 0; i < _vm._numObj; i++) {
- object_t *obj = &_vm._objects[i];
- if (isWordPresent(_vm._arrayNouns[obj->nounIndex])) {
- if (isObjectVerb(obj, farComment) || isGenericVerb(obj, farComment))
- return;
- }
- }
-
- // Test for nearby objects that only require a verb
- // Note comment is unused if not near.
- for (int i = 0; i < _vm._numObj; i++) {
- object_t *obj = &_vm._objects[i];
- if (obj->verbOnlyFl) {
- char contextComment[XBYTES * 5] = ""; // Unused comment for context objects
- if (isObjectVerb(obj, contextComment) || isGenericVerb(obj, contextComment))
- return;
- }
- }
-
- // No objects match command line, try background and catchall commands
- if (isBackgroundWord(_vm._backgroundObjects[*_vm._screen_p]))
- return;
- if (isCatchallVerb(_vm._backgroundObjects[*_vm._screen_p]))
- return;
- if (isBackgroundWord(_vm._catchallList))
- return;
- if (isCatchallVerb(_vm._catchallList))
- return;
-
- // If a not-near comment was generated, print it
- if (*farComment != '\0') {
- Utils::Box(BOX_ANY, "%s", farComment);
- return;
- }
-
- // Nothing matches. Report recognition success to user.
- char *verb = findVerb();
- char *noun = findNoun();
- if (verb == _vm._arrayVerbs[_vm._look][0] && _maze.enabledFl) {
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBMaze]);
- showTakeables();
- } else if (verb && noun) { // A combination I didn't think of
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoPoint]);
- } else if (noun) {
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoun]);
- } else if (verb) {
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBVerb]);
- } else {
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBEh]);
- }
-}
-
// Locate any member of object name list appearing in command line
bool Parser::isWordPresent(char **wordArr) {
debugC(1, kDebugParser, "isWordPresent(%s)", wordArr[0]);
@@ -697,408 +302,4 @@ void Parser::showDosInventory() {
Utils::Box(BOX_ANY, "%s", buffer);
}
-Parser_v1d::Parser_v1d(HugoEngine &vm) : Parser(vm) {
-}
-
-Parser_v1d::~Parser_v1d() {
-}
-
-// Locate word in list of nouns and return ptr to string in noun list
-// If n is NULL, start at beginning of list, else with n
-char *Parser_v1d::findNextNoun(char *noun) {
- debugC(1, kDebugParser, "findNextNoun(%s)", noun);
-
- int currNounIndex = -1;
- if (noun) { // If noun not NULL, find index
- for (currNounIndex = 0; _vm._arrayNouns[currNounIndex]; currNounIndex++) {
- if (noun == _vm._arrayNouns[currNounIndex][0])
- break;
- }
- }
- for (int i = currNounIndex + 1; _vm._arrayNouns[i]; i++) {
- for (int j = 0; strlen(_vm._arrayNouns[i][j]); j++) {
- if (strstr(_line, _vm._arrayNouns[i][j]))
- return _vm._arrayNouns[i][0];
- }
- }
- return 0;
-}
-
-// Test whether hero is close to object. Return TRUE or FALSE
-// If no noun specified, check context flag in object before other tests.
-// If object not near, return suitable string; may be similar object closer
-// If radius is -1, treat radius as infinity
-bool Parser_v1d::isNear(char *verb, char *noun, object_t *obj, char *comment) {
- debugC(1, kDebugParser, "isNear(%s, %s, obj, %s)", verb, noun, comment);
-
- if (!noun && !obj->verbOnlyFl) { // No noun specified & object not context senesitive
- return false;
- } else if (noun && (noun != _vm._arrayNouns[obj->nounIndex][0])) { // Noun specified & not same as object
- return false;
- } else if (obj->carriedFl) { // Object is being carried
- return true;
- } else if (obj->screenIndex != *_vm._screen_p) { // Not in same screen
- if (obj->objValue)
- strcpy (comment, _vm._textParser[kCmtAny4]);
- return false;
- }
-
- if (obj->cycling == INVISIBLE) {
- if (obj->seqNumb) { // There is an image
- strcpy(comment, _vm._textParser[kCmtAny5]);
- return false;
- } else { // No image, assume visible
- if ((obj->radius < 0) ||
- ((abs(obj->x - _vm._hero->x) <= obj->radius) &&
- (abs(obj->y - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) {
- return true;
- } else {
- // User is either not close enough (stationary, valueless objects)
- // or is not carrying it (small, portable objects of value)
- if (noun) { // Don't say unless object specified
- if (obj->objValue && (verb != _vm._arrayVerbs[_vm._take][0]))
- strcpy(comment, _vm._textParser[kCmtAny4]);
- else
- strcpy(comment, _vm._textParser[kCmtClose]);
- }
- return false;
- }
- }
- }
-
- if ((obj->radius < 0) ||
- ((abs(obj->x - _vm._hero->x) <= obj->radius) &&
- (abs(obj->y + obj->currImagePtr->y2 - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) {
- return true;
- } else {
- // User is either not close enough (stationary, valueless objects)
- // or is not carrying it (small, portable objects of value)
- if (noun) { // Don't say unless object specified
- if (obj->objValue && (verb != _vm._arrayVerbs[_vm._take][0]))
- strcpy(comment, _vm._textParser[kCmtAny4]);
- else
- strcpy(comment, _vm._textParser[kCmtClose]);
- }
- return false;
- }
-
- return true;
-}
-
-// Test whether supplied verb is one of the common variety for this object
-// say_ok needed for special case of take/drop which may be handled not only
-// here but also in a cmd_list with a donestr string simultaneously
-bool Parser_v1d::isGenericVerb(char *word, object_t *obj) {
- debugC(1, kDebugParser, "isGenericVerb(%s, object_t *obj)", word);
-
- if (!obj->genericCmd)
- return false;
-
- // Following is equivalent to switch, but couldn't do one
- if (word == _vm._arrayVerbs[_vm._look][0]) {
- if ((LOOK & obj->genericCmd) == LOOK)
- Utils::Box(BOX_ANY, "%s", _vm._textData[obj->dataIndex]);
- else
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBUnusual_1d]);
- } else if (word == _vm._arrayVerbs[_vm._take][0]) {
- if (obj->carriedFl)
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBHave]);
- else if ((TAKE & obj->genericCmd) == TAKE)
- takeObject(obj);
- else if (!obj->verbOnlyFl) // Make sure not taking object in context!
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoUse]);
- else
- return false;
- } else if (word == _vm._arrayVerbs[_vm._drop][0]) {
- if (!obj->carriedFl)
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBDontHave]);
- else if ((DROP & obj->genericCmd) == DROP)
- dropObject(obj);
- else
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNeed]);
- } else { // It was not a generic cmd
- return false;
- }
-
- return true;
-}
-
-// Test whether supplied verb is included in the list of allowed verbs for
-// this object. If it is, then perform the tests on it from the cmd list
-// and if it passes, perform the actions in the action list. If the verb
-// is catered for, return TRUE
-bool Parser_v1d::isObjectVerb(char *word, object_t *obj) {
- debugC(1, kDebugParser, "isObjectVerb(%s, object_t *obj)", word);
-
- // First, find matching verb in cmd list
- uint16 cmdIndex = obj->cmdIndex; // ptr to list of commands
- if (!cmdIndex) // No commands for this obj
- return false;
-
- int i;
- for (i = 0; _vm._cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd
- if (!strcmp(word, _vm._arrayVerbs[_vm._cmdList[cmdIndex][i].verbIndex][0])) // Is this verb catered for?
- break;
- }
-
- if (_vm._cmdList[cmdIndex][i].verbIndex == 0) // No
- return false;
-
- // Verb match found, check all required objects are being carried
- cmd *cmnd = &_vm._cmdList[cmdIndex][i]; // ptr to struct cmd
- if (cmnd->reqIndex) { // At least 1 thing in list
- uint16 *reqs = _vm._arrayReqs[cmnd->reqIndex]; // ptr to list of required objects
- for (i = 0; reqs[i]; i++) { // for each obj
- if (!isCarrying(reqs[i])) {
- Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataNoCarryIndex]);
- return true;
- }
- }
- }
-
- // Required objects are present, now check state is correct
- if ((obj->state != cmnd->reqState) && (cmnd->reqState != DONT_CARE)){
- Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataWrongIndex]);
- return true;
- }
-
- // Everything checked. Change the state and carry out any actions
- if (cmnd->reqState != DONT_CARE) // Don't change new state if required state didn't care
- obj->state = cmnd->newState;
- Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataDoneIndex]);
- _vm.scheduler().insertActionList(cmnd->actIndex);
- // Special case if verb is Take or Drop. Assume additional generic actions
- if ((word == _vm._arrayVerbs[_vm._take][0]) || (word == _vm._arrayVerbs[_vm._drop][0]))
- isGenericVerb(word, obj);
- return true;
-}
-
-// Print text for possible background object. Return TRUE if match found
-// Only match if both verb and noun found. Test_ca will match verb-only
-bool Parser_v1d::isBackgroundWord(char *noun, char *verb, objectList_t obj) {
- debugC(1, kDebugParser, "isBackgroundWord(%s, %s, object_list_t obj)", noun, verb);
-
- if (!noun)
- return false;
-
- for (int i = 0; obj[i].verbIndex; i++) {
- if ((verb == _vm._arrayVerbs[obj[i].verbIndex][0]) && (noun == _vm._arrayNouns[obj[i].nounIndex][0])) {
- Utils::Box(BOX_ANY, "%s", _vm.file().fetchString(obj[i].commentIndex));
- return true;
- }
- }
- return false;
-}
-
-// Do all things necessary to carry an object
-void Parser_v1d::takeObject(object_t *obj) {
- debugC(1, kDebugParser, "takeObject(object_t *obj)");
-
- obj->carriedFl = true;
- if (obj->seqNumb) // Don't change if no image to display
- obj->cycling = ALMOST_INVISIBLE;
-
- _vm.adjustScore(obj->objValue);
-
- Utils::Box(BOX_ANY, TAKE_TEXT, _vm._arrayNouns[obj->nounIndex][TAKE_NAME]);
-}
-
-// Do all necessary things to drop an object
-void Parser_v1d::dropObject(object_t *obj) {
- debugC(1, kDebugParser, "dropObject(object_t *obj)");
-
- obj->carriedFl = false;
- obj->screenIndex = *_vm._screen_p;
- if (obj->seqNumb) // Don't change if no image to display
- obj->cycling = NOT_CYCLING;
- obj->x = _vm._hero->x - 1;
- obj->y = _vm._hero->y + _vm._hero->currImagePtr->y2 - 1;
- _vm.adjustScore(-obj->objValue);
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBOk]);
-}
-
-// Print text for possible background object. Return TRUE if match found
-// If test_noun TRUE, must have a noun given
-bool Parser_v1d::isCatchallVerb(bool testNounFl, char *noun, char *verb, objectList_t obj) {
- debugC(1, kDebugParser, "isCatchallVerb(%d, %s, %s, object_list_t obj)", (testNounFl) ? 1 : 0, noun, verb);
-
- if (testNounFl && !noun)
- return false;
-
- for (int i = 0; obj[i].verbIndex; i++) {
- if ((verb == _vm._arrayVerbs[obj[i].verbIndex][0]) && ((noun == _vm._arrayNouns[obj[i].nounIndex][0]) || (obj[i].nounIndex == 0))) {
- Utils::Box(BOX_ANY, "%s", _vm.file().fetchString(obj[i].commentIndex));
- return true;
- }
- }
- return false;
-}
-
-// Parse the user's line of text input. Generate events as necessary
-void Parser_v1d::lineHandler() {
- debugC(1, kDebugParser, "lineHandler()");
-
- object_t *obj;
- status_t &gameStatus = _vm.getGameStatus();
- char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby
-
-// Reset_prompt_line ();
- Utils::strlwr(_line); // Convert to lower case
-
- if (!strcmp("exit", _line) || strstr(_line, "quit")) {
- if (Utils::Box(BOX_YESNO, "%s", _vm._textParser[kTBExit_1d]) != 0)
- _vm.endGame();
- return;
- }
-
- // SAVE/RESTORE
- if (!strcmp("save", _line)) {
- if (gameStatus.gameOverFl)
- Utils::gameOverMsg();
- else
-// _vm.file().saveOrRestore(true);
- warning("STUB: saveOrRestore()");
- return;
- }
-
- if (!strcmp("restore", _line)) {
-// _vm.file().saveOrRestore(false);
- warning("STUB: saveOrRestore()");
- return;
- }
-
- if (*_line == '\0') // Empty line
- return;
-
- if (strspn(_line, " ") == strlen(_line)) // Nothing but spaces!
- return;
-
- if (gameStatus.gameOverFl) { // No commands allowed!
- Utils::gameOverMsg();
- return;
- }
-
- // Find the first verb in the line
- char *verb = findVerb();
- char *noun = 0; // Noun not found yet
-
- if (verb) { // OK, verb found. Try to match with object
- do {
- noun = findNextNoun(noun); // Find a noun in the line
- // Must try at least once for objects allowing verb-context
- for (int i = 0; i < _vm._numObj; i++) {
- obj = &_vm._objects[i];
- if (isNear(verb, noun, obj, farComment)) {
- if (isObjectVerb(verb, obj) // Foreground object
- || isGenericVerb(verb, obj)) // Common action type
- return;
- }
- }
- if ((*farComment == '\0') && isBackgroundWord(noun, verb, _vm._backgroundObjects[*_vm._screen_p]))
- return;
- } while (noun);
- }
- noun = findNextNoun(noun);
- if (*farComment != '\0') // An object matched but not near enough
- Utils::Box(BOX_ANY, "%s", farComment);
- else if (!isCatchallVerb(true, noun, verb, _vm._catchallList) &&
- !isCatchallVerb(false, noun, verb, _vm._backgroundObjects[*_vm._screen_p]) &&
- !isCatchallVerb(false, noun, verb, _vm._catchallList))
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBEh_1d]);
-}
-
-Parser_v2d::Parser_v2d(HugoEngine &vm) : Parser_v1d(vm) {
-}
-
-Parser_v2d::~Parser_v2d() {
-}
-
-// Parse the user's line of text input. Generate events as necessary
-void Parser_v2d::lineHandler() {
- debugC(1, kDebugParser, "lineHandler()");
-
- object_t *obj;
- status_t &gameStatus = _vm.getGameStatus();
- char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby
-
-// Reset_prompt_line ();
- Utils::strlwr(_line); // Convert to lower case
-
- if (!strcmp("exit", _line) || strstr(_line, "quit")) {
- if (Utils::Box(BOX_YESNO, "%s", _vm._textParser[kTBExit_1d]) != 0)
- _vm.endGame();
- else
- return;
- }
-
- // SAVE/RESTORE
- if (!strcmp("save", _line)) {
- _config.soundFl = false;
- if (gameStatus.gameOverFl)
- Utils::gameOverMsg();
- else
-// _vm.file().saveOrRestore(true);
- warning("STUB: saveOrRestore()");
- return;
- }
-
- if (!strcmp("restore", _line)) {
- _config.soundFl = false;
-// _vm.file().saveOrRestore(false);
- warning("STUB: saveOrRestore()");
- return;
- }
-
- if (!strlen(_line)) // Empty line
- return;
-
- if (strspn(_line, " ") == strlen(_line)) // Nothing but spaces!
- return;
-
- if (gameStatus.gameOverFl) { // No commands allowed!
- Utils::gameOverMsg();
- return;
- }
-
- // Find the first verb in the line
- char *verb = findVerb();
- char *noun = 0; // Noun not found yet
-
- if (verb) { // OK, verb found. Try to match with object
- do {
- noun = findNextNoun(noun); // Find a noun in the line
- // Must try at least once for objects allowing verb-context
- for (int i = 0; i < _vm._numObj; i++) {
- obj = &_vm._objects[i];
- if (isNear(verb, noun, obj, farComment)) {
- if (isObjectVerb(verb, obj) // Foreground object
- || isGenericVerb(verb, obj)) // Common action type
- return;
- }
- }
- if ((*farComment != '\0') && isBackgroundWord(noun, verb, _vm._backgroundObjects[*_vm._screen_p]))
- return;
- } while (noun);
- }
-
- noun = findNextNoun(noun);
- if ( !isCatchallVerb(true, noun, verb, _vm._backgroundObjects[*_vm._screen_p])
- && !isCatchallVerb(true, noun, verb, _vm._catchallList)
- && !isCatchallVerb(false, noun, verb, _vm._backgroundObjects[*_vm._screen_p])
- && !isCatchallVerb(false, noun, verb, _vm._catchallList)) {
- if (*farComment != '\0') { // An object matched but not near enough
- Utils::Box(BOX_ANY, "%s", farComment);
- } else if (_maze.enabledFl && (verb == _vm._arrayVerbs[_vm._look][0])) {
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBMaze]);
- showTakeables();
- } else if (verb && noun) { // A combination I didn't think of
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoUse_2d]);
- } else if (verb || noun) {
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoun]);
- } else {
- Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBEh_2d]);
- }
- }
-}
-
} // End of namespace Hugo
diff --git a/engines/hugo/parser_v1d.cpp b/engines/hugo/parser_v1d.cpp
new file mode 100644
index 0000000000..9364cd9532
--- /dev/null
+++ b/engines/hugo/parser_v1d.cpp
@@ -0,0 +1,355 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on original Hugo Trilogy source code
+ *
+ * Copyright (c) 1989-1995 David P. Gray
+ *
+ */
+
+// parser.c - handles all keyboard/command input
+
+#include "common/system.h"
+
+#include "hugo/hugo.h"
+#include "hugo/parser.h"
+#include "hugo/file.h"
+#include "hugo/schedule.h"
+#include "hugo/util.h"
+
+namespace Hugo {
+
+Parser_v1d::Parser_v1d(HugoEngine &vm) : Parser(vm) {
+}
+
+Parser_v1d::~Parser_v1d() {
+}
+
+// Locate word in list of nouns and return ptr to string in noun list
+// If n is NULL, start at beginning of list, else with n
+char *Parser_v1d::findNextNoun(char *noun) {
+ debugC(1, kDebugParser, "findNextNoun(%s)", noun);
+
+ int currNounIndex = -1;
+ if (noun) { // If noun not NULL, find index
+ for (currNounIndex = 0; _vm._arrayNouns[currNounIndex]; currNounIndex++) {
+ if (noun == _vm._arrayNouns[currNounIndex][0])
+ break;
+ }
+ }
+ for (int i = currNounIndex + 1; _vm._arrayNouns[i]; i++) {
+ for (int j = 0; strlen(_vm._arrayNouns[i][j]); j++) {
+ if (strstr(_line, _vm._arrayNouns[i][j]))
+ return _vm._arrayNouns[i][0];
+ }
+ }
+ return 0;
+}
+
+// Test whether hero is close to object. Return TRUE or FALSE
+// If no noun specified, check context flag in object before other tests.
+// If object not near, return suitable string; may be similar object closer
+// If radius is -1, treat radius as infinity
+bool Parser_v1d::isNear(char *verb, char *noun, object_t *obj, char *comment) {
+ debugC(1, kDebugParser, "isNear(%s, %s, obj, %s)", verb, noun, comment);
+
+ if (!noun && !obj->verbOnlyFl) { // No noun specified & object not context senesitive
+ return false;
+ } else if (noun && (noun != _vm._arrayNouns[obj->nounIndex][0])) { // Noun specified & not same as object
+ return false;
+ } else if (obj->carriedFl) { // Object is being carried
+ return true;
+ } else if (obj->screenIndex != *_vm._screen_p) { // Not in same screen
+ if (obj->objValue)
+ strcpy (comment, _vm._textParser[kCmtAny4]);
+ return false;
+ }
+
+ if (obj->cycling == INVISIBLE) {
+ if (obj->seqNumb) { // There is an image
+ strcpy(comment, _vm._textParser[kCmtAny5]);
+ return false;
+ } else { // No image, assume visible
+ if ((obj->radius < 0) ||
+ ((abs(obj->x - _vm._hero->x) <= obj->radius) &&
+ (abs(obj->y - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) {
+ return true;
+ } else {
+ // User is either not close enough (stationary, valueless objects)
+ // or is not carrying it (small, portable objects of value)
+ if (noun) { // Don't say unless object specified
+ if (obj->objValue && (verb != _vm._arrayVerbs[_vm._take][0]))
+ strcpy(comment, _vm._textParser[kCmtAny4]);
+ else
+ strcpy(comment, _vm._textParser[kCmtClose]);
+ }
+ return false;
+ }
+ }
+ }
+
+ if ((obj->radius < 0) ||
+ ((abs(obj->x - _vm._hero->x) <= obj->radius) &&
+ (abs(obj->y + obj->currImagePtr->y2 - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) {
+ return true;
+ } else {
+ // User is either not close enough (stationary, valueless objects)
+ // or is not carrying it (small, portable objects of value)
+ if (noun) { // Don't say unless object specified
+ if (obj->objValue && (verb != _vm._arrayVerbs[_vm._take][0]))
+ strcpy(comment, _vm._textParser[kCmtAny4]);
+ else
+ strcpy(comment, _vm._textParser[kCmtClose]);
+ }
+ return false;
+ }
+
+ return true;
+}
+
+// Test whether supplied verb is one of the common variety for this object
+// say_ok needed for special case of take/drop which may be handled not only
+// here but also in a cmd_list with a donestr string simultaneously
+bool Parser_v1d::isGenericVerb(char *word, object_t *obj) {
+ debugC(1, kDebugParser, "isGenericVerb(%s, object_t *obj)", word);
+
+ if (!obj->genericCmd)
+ return false;
+
+ // Following is equivalent to switch, but couldn't do one
+ if (word == _vm._arrayVerbs[_vm._look][0]) {
+ if ((LOOK & obj->genericCmd) == LOOK)
+ Utils::Box(BOX_ANY, "%s", _vm._textData[obj->dataIndex]);
+ else
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBUnusual_1d]);
+ } else if (word == _vm._arrayVerbs[_vm._take][0]) {
+ if (obj->carriedFl)
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBHave]);
+ else if ((TAKE & obj->genericCmd) == TAKE)
+ takeObject(obj);
+ else if (!obj->verbOnlyFl) // Make sure not taking object in context!
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoUse]);
+ else
+ return false;
+ } else if (word == _vm._arrayVerbs[_vm._drop][0]) {
+ if (!obj->carriedFl)
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBDontHave]);
+ else if ((DROP & obj->genericCmd) == DROP)
+ dropObject(obj);
+ else
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNeed]);
+ } else { // It was not a generic cmd
+ return false;
+ }
+
+ return true;
+}
+
+// Test whether supplied verb is included in the list of allowed verbs for
+// this object. If it is, then perform the tests on it from the cmd list
+// and if it passes, perform the actions in the action list. If the verb
+// is catered for, return TRUE
+bool Parser_v1d::isObjectVerb(char *word, object_t *obj) {
+ debugC(1, kDebugParser, "isObjectVerb(%s, object_t *obj)", word);
+
+ // First, find matching verb in cmd list
+ uint16 cmdIndex = obj->cmdIndex; // ptr to list of commands
+ if (!cmdIndex) // No commands for this obj
+ return false;
+
+ int i;
+ for (i = 0; _vm._cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd
+ if (!strcmp(word, _vm._arrayVerbs[_vm._cmdList[cmdIndex][i].verbIndex][0])) // Is this verb catered for?
+ break;
+ }
+
+ if (_vm._cmdList[cmdIndex][i].verbIndex == 0) // No
+ return false;
+
+ // Verb match found, check all required objects are being carried
+ cmd *cmnd = &_vm._cmdList[cmdIndex][i]; // ptr to struct cmd
+ if (cmnd->reqIndex) { // At least 1 thing in list
+ uint16 *reqs = _vm._arrayReqs[cmnd->reqIndex]; // ptr to list of required objects
+ for (i = 0; reqs[i]; i++) { // for each obj
+ if (!isCarrying(reqs[i])) {
+ Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataNoCarryIndex]);
+ return true;
+ }
+ }
+ }
+
+ // Required objects are present, now check state is correct
+ if ((obj->state != cmnd->reqState) && (cmnd->reqState != DONT_CARE)){
+ Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataWrongIndex]);
+ return true;
+ }
+
+ // Everything checked. Change the state and carry out any actions
+ if (cmnd->reqState != DONT_CARE) // Don't change new state if required state didn't care
+ obj->state = cmnd->newState;
+ Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataDoneIndex]);
+ _vm.scheduler().insertActionList(cmnd->actIndex);
+ // Special case if verb is Take or Drop. Assume additional generic actions
+ if ((word == _vm._arrayVerbs[_vm._take][0]) || (word == _vm._arrayVerbs[_vm._drop][0]))
+ isGenericVerb(word, obj);
+ return true;
+}
+
+// Print text for possible background object. Return TRUE if match found
+// Only match if both verb and noun found. Test_ca will match verb-only
+bool Parser_v1d::isBackgroundWord(char *noun, char *verb, objectList_t obj) {
+ debugC(1, kDebugParser, "isBackgroundWord(%s, %s, object_list_t obj)", noun, verb);
+
+ if (!noun)
+ return false;
+
+ for (int i = 0; obj[i].verbIndex; i++) {
+ if ((verb == _vm._arrayVerbs[obj[i].verbIndex][0]) && (noun == _vm._arrayNouns[obj[i].nounIndex][0])) {
+ Utils::Box(BOX_ANY, "%s", _vm.file().fetchString(obj[i].commentIndex));
+ return true;
+ }
+ }
+ return false;
+}
+
+// Do all things necessary to carry an object
+void Parser_v1d::takeObject(object_t *obj) {
+ debugC(1, kDebugParser, "takeObject(object_t *obj)");
+
+ obj->carriedFl = true;
+ if (obj->seqNumb) // Don't change if no image to display
+ obj->cycling = ALMOST_INVISIBLE;
+
+ _vm.adjustScore(obj->objValue);
+
+ Utils::Box(BOX_ANY, TAKE_TEXT, _vm._arrayNouns[obj->nounIndex][TAKE_NAME]);
+}
+
+// Do all necessary things to drop an object
+void Parser_v1d::dropObject(object_t *obj) {
+ debugC(1, kDebugParser, "dropObject(object_t *obj)");
+
+ obj->carriedFl = false;
+ obj->screenIndex = *_vm._screen_p;
+ if (obj->seqNumb) // Don't change if no image to display
+ obj->cycling = NOT_CYCLING;
+ obj->x = _vm._hero->x - 1;
+ obj->y = _vm._hero->y + _vm._hero->currImagePtr->y2 - 1;
+ _vm.adjustScore(-obj->objValue);
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBOk]);
+}
+
+// Print text for possible background object. Return TRUE if match found
+// If test_noun TRUE, must have a noun given
+bool Parser_v1d::isCatchallVerb(bool testNounFl, char *noun, char *verb, objectList_t obj) {
+ debugC(1, kDebugParser, "isCatchallVerb(%d, %s, %s, object_list_t obj)", (testNounFl) ? 1 : 0, noun, verb);
+
+ if (testNounFl && !noun)
+ return false;
+
+ for (int i = 0; obj[i].verbIndex; i++) {
+ if ((verb == _vm._arrayVerbs[obj[i].verbIndex][0]) && ((noun == _vm._arrayNouns[obj[i].nounIndex][0]) || (obj[i].nounIndex == 0))) {
+ Utils::Box(BOX_ANY, "%s", _vm.file().fetchString(obj[i].commentIndex));
+ return true;
+ }
+ }
+ return false;
+}
+
+// Parse the user's line of text input. Generate events as necessary
+void Parser_v1d::lineHandler() {
+ debugC(1, kDebugParser, "lineHandler()");
+
+ object_t *obj;
+ status_t &gameStatus = _vm.getGameStatus();
+ char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby
+
+// Reset_prompt_line ();
+ Utils::strlwr(_line); // Convert to lower case
+
+ if (!strcmp("exit", _line) || strstr(_line, "quit")) {
+ if (Utils::Box(BOX_YESNO, "%s", _vm._textParser[kTBExit_1d]) != 0)
+ _vm.endGame();
+ return;
+ }
+
+ // SAVE/RESTORE
+ if (!strcmp("save", _line)) {
+ if (gameStatus.gameOverFl)
+ Utils::gameOverMsg();
+ else
+// _vm.file().saveOrRestore(true);
+ warning("STUB: saveOrRestore()");
+ return;
+ }
+
+ if (!strcmp("restore", _line)) {
+// _vm.file().saveOrRestore(false);
+ warning("STUB: saveOrRestore()");
+ return;
+ }
+
+ if (*_line == '\0') // Empty line
+ return;
+
+ if (strspn(_line, " ") == strlen(_line)) // Nothing but spaces!
+ return;
+
+ if (gameStatus.gameOverFl) { // No commands allowed!
+ Utils::gameOverMsg();
+ return;
+ }
+
+ // Find the first verb in the line
+ char *verb = findVerb();
+ char *noun = 0; // Noun not found yet
+
+ if (verb) { // OK, verb found. Try to match with object
+ do {
+ noun = findNextNoun(noun); // Find a noun in the line
+ // Must try at least once for objects allowing verb-context
+ for (int i = 0; i < _vm._numObj; i++) {
+ obj = &_vm._objects[i];
+ if (isNear(verb, noun, obj, farComment)) {
+ if (isObjectVerb(verb, obj) // Foreground object
+ || isGenericVerb(verb, obj)) // Common action type
+ return;
+ }
+ }
+ if ((*farComment == '\0') && isBackgroundWord(noun, verb, _vm._backgroundObjects[*_vm._screen_p]))
+ return;
+ } while (noun);
+ }
+ noun = findNextNoun(noun);
+ if (*farComment != '\0') // An object matched but not near enough
+ Utils::Box(BOX_ANY, "%s", farComment);
+ else if (!isCatchallVerb(true, noun, verb, _vm._catchallList) &&
+ !isCatchallVerb(false, noun, verb, _vm._backgroundObjects[*_vm._screen_p]) &&
+ !isCatchallVerb(false, noun, verb, _vm._catchallList))
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBEh_1d]);
+}
+
+} // End of namespace Hugo
diff --git a/engines/hugo/parser_v1w.cpp b/engines/hugo/parser_v1w.cpp
new file mode 100644
index 0000000000..417b31e794
--- /dev/null
+++ b/engines/hugo/parser_v1w.cpp
@@ -0,0 +1,434 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on original Hugo Trilogy source code
+ *
+ * Copyright (c) 1989-1995 David P. Gray
+ *
+ */
+
+// parser.c - handles all keyboard/command input
+
+#include "common/system.h"
+
+#include "hugo/hugo.h"
+#include "hugo/parser.h"
+#include "hugo/file.h"
+#include "hugo/schedule.h"
+#include "hugo/util.h"
+#include "hugo/sound.h"
+
+namespace Hugo {
+Parser_v1w::Parser_v1w(HugoEngine &vm) : Parser(vm) {
+}
+
+Parser_v1w::~Parser_v1w() {
+}
+
+// Test whether command line contains a verb allowed by this object.
+// If it does, and the object is near and passes the tests in the command
+// list then carry out the actions in the action list and return TRUE
+bool Parser_v1w::isObjectVerb(object_t *obj, char *comment) {
+ debugC(1, kDebugParser, "isObjectVerb(object_t *obj, %s)", comment);
+
+ // First, find matching verb in cmd list
+ uint16 cmdIndex = obj->cmdIndex; // ptr to list of commands
+ if (cmdIndex == 0) // No commands for this obj
+ return false;
+
+ int i;
+ for (i = 0; _vm._cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd
+ if (isWordPresent(_vm._arrayVerbs[_vm._cmdList[cmdIndex][i].verbIndex])) // Was this verb used?
+ break;
+ }
+
+ if (_vm._cmdList[cmdIndex][i].verbIndex == 0) // No verbs used.
+ return false;
+
+ // Verb match found. Check if object is Near
+ char *verb = *_vm._arrayVerbs[_vm._cmdList[cmdIndex][i].verbIndex];
+ if (!isNear(obj, verb, comment))
+ return false;
+
+ // Check all required objects are being carried
+ cmd *cmnd = &_vm._cmdList[cmdIndex][i]; // ptr to struct cmd
+ if (cmnd->reqIndex) { // At least 1 thing in list
+ uint16 *reqs = _vm._arrayReqs[cmnd->reqIndex]; // ptr to list of required objects
+ for (i = 0; reqs[i]; i++) { // for each obj
+ if (!isCarrying(reqs[i])) {
+ Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataNoCarryIndex]);
+ return true;
+ }
+ }
+ }
+
+ // Required objects are present, now check state is correct
+ if ((obj->state != cmnd->reqState) && (cmnd->reqState != DONT_CARE)) {
+ Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataWrongIndex]);
+ return true;
+ }
+
+ // Everything checked. Change the state and carry out any actions
+ if (cmnd->reqState != DONT_CARE) // Don't change new state if required state didn't care
+ obj->state = cmnd->newState;
+ Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataDoneIndex]);
+ _vm.scheduler().insertActionList(cmnd->actIndex);
+
+ // See if any additional generic actions
+ if ((verb == _vm._arrayVerbs[_vm._look][0]) || (verb == _vm._arrayVerbs[_vm._take][0]) || (verb == _vm._arrayVerbs[_vm._drop][0]))
+ isGenericVerb(obj, comment);
+ return true;
+}
+
+// Test whether command line contains one of the generic actions
+bool Parser_v1w::isGenericVerb(object_t *obj, char *comment) {
+ debugC(1, kDebugParser, "isGenericVerb(object_t *obj, %s)", comment);
+
+ if (!obj->genericCmd)
+ return false;
+
+ // Following is equivalent to switch, but couldn't do one
+ if (isWordPresent(_vm._arrayVerbs[_vm._look]) && isNear(obj, _vm._arrayVerbs[_vm._look][0], comment)) {
+ // Test state-dependent look before general look
+ if ((obj->genericCmd & LOOK_S) == LOOK_S) {
+ Utils::Box(BOX_ANY, "%s", _vm._textData[obj->stateDataIndex[obj->state]]);
+ warning("isGenericVerb: use of state dependant look - To be validated");
+ } else {
+ if ((LOOK & obj->genericCmd) == LOOK) {
+ if (_vm._textData[obj->dataIndex])
+ Utils::Box(BOX_ANY, "%s", _vm._textData[obj->dataIndex]);
+ else
+ return false;
+ } else {
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBUnusual]);
+ }
+ }
+ } else if (isWordPresent(_vm._arrayVerbs[_vm._take]) && isNear(obj, _vm._arrayVerbs[_vm._take][0], comment)) {
+ if (obj->carriedFl)
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBHave]);
+ else if ((TAKE & obj->genericCmd) == TAKE)
+ takeObject(obj);
+ else if (obj->cmdIndex != 0) // No comment if possible commands
+ return false;
+ else if (!obj->verbOnlyFl && (TAKE & obj->genericCmd) == TAKE) // Make sure not taking object in context!
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoUse]);
+ else
+ return false;
+ } else if (isWordPresent(_vm._arrayVerbs[_vm._drop])) {
+ if (!obj->carriedFl && ((DROP & obj->genericCmd) == DROP))
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBDontHave]);
+ else if (obj->carriedFl && ((DROP & obj->genericCmd) == DROP))
+ dropObject(obj);
+ else if (obj->cmdIndex == 0)
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNeed]);
+ else
+ return false;
+ } else { // It was not a generic cmd
+ return false;
+ }
+
+ return true;
+}
+
+// Test whether hero is close to object. Return TRUE or FALSE
+// If object not near, return suitable comment; may be another object close
+// If radius is -1, treat radius as infinity
+// Verb is included to determine correct comment if not near
+bool Parser_v1w::isNear(object_t *obj, char *verb, char *comment) {
+ debugC(1, kDebugParser, "isNear(object_t *obj, %s, %s)", verb, comment);
+
+ if (obj->carriedFl) // Object is being carried
+ return true;
+
+ if (obj->screenIndex != *_vm._screen_p) {
+ // Not in same screen
+ if (obj->objValue)
+ strcpy(comment, _vm._textParser[kCmtAny1]);
+ else
+ strcpy(comment, _vm._textParser[kCmtAny2]);
+ return false;
+ }
+
+ if (obj->cycling == INVISIBLE) {
+ if (obj->seqNumb) {
+ // There is an image
+ strcpy(comment, _vm._textParser[kCmtAny3]);
+ return false;
+ } else {
+ // No image, assume visible
+ if ((obj->radius < 0) ||
+ ((abs(obj->x - _vm._hero->x) <= obj->radius) &&
+ (abs(obj->y - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) {
+ return true;
+ } else {
+ // User is not close enough
+ if (obj->objValue && (verb != _vm._arrayVerbs[_vm._take][0]))
+ strcpy(comment, _vm._textParser[kCmtAny1]);
+ else
+ strcpy(comment, _vm._textParser[kCmtClose]);
+ return false;
+ }
+ }
+ }
+
+ if ((obj->radius < 0) ||
+ ((abs(obj->x - _vm._hero->x) <= obj->radius) &&
+ (abs(obj->y + obj->currImagePtr->y2 - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) {
+ return true;
+ } else {
+ // User is not close enough
+ if (obj->objValue && (verb != _vm._arrayVerbs[_vm._take][0]))
+ strcpy(comment, _vm._textParser[kCmtAny1]);
+ else
+ strcpy(comment, _vm._textParser[kCmtClose]);
+ return false;
+ }
+ return true;
+}
+
+// Do all things necessary to carry an object
+void Parser_v1w::takeObject(object_t *obj) {
+ debugC(1, kDebugParser, "takeObject(object_t *obj)");
+
+ obj->carriedFl = true;
+ if (obj->seqNumb) { // Don't change if no image to display
+ obj->cycling = INVISIBLE;
+ }
+ _vm.adjustScore(obj->objValue);
+
+ if (obj->seqNumb > 0) // If object has an image, force walk to dropped
+ obj->viewx = -1; // (possibly moved) object next time taken!
+ Utils::Box(BOX_ANY, TAKE_TEXT, _vm._arrayNouns[obj->nounIndex][TAKE_NAME]);
+}
+
+// Do all necessary things to drop an object
+void Parser_v1w::dropObject(object_t *obj) {
+ debugC(1, kDebugParser, "dropObject(object_t *obj)");
+
+ obj->carriedFl = false;
+ obj->screenIndex = *_vm._screen_p;
+ if ((obj->seqNumb > 1) || (obj->seqList[0].imageNbr > 1))
+ obj->cycling = CYCLE_FORWARD;
+ else
+ obj->cycling = NOT_CYCLING;
+ obj->x = _vm._hero->x - 1;
+ obj->y = _vm._hero->y + _vm._hero->currImagePtr->y2 - 1;
+ obj->y = (obj->y + obj->currImagePtr->y2 < YPIX) ? obj->y : YPIX - obj->currImagePtr->y2 - 10;
+ _vm.adjustScore(-obj->objValue);
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBOk]);
+}
+
+// Search for matching verbs in background command list.
+// Noun is not required. Return TRUE if match found
+// Note that if the background command list has match set TRUE then do not
+// print text if there are any recognizable nouns in the command line
+bool Parser_v1w::isCatchallVerb(objectList_t obj) {
+ debugC(1, kDebugParser, "isCatchallVerb(object_list_t obj)");
+
+ for (int i = 0; obj[i].verbIndex != 0; i++) {
+ if (isWordPresent(_vm._arrayVerbs[obj[i].verbIndex]) && obj[i].nounIndex == 0 &&
+ (!obj[i].matchFl || !findNoun()) &&
+ ((obj[i].roomState == DONT_CARE) ||
+ (obj[i].roomState == _vm._screenStates[*_vm._screen_p]))) {
+ Utils::Box(BOX_ANY, "%s", _vm.file().fetchString(obj[i].commentIndex));
+ _vm.scheduler().processBonus(obj[i].bonusIndex);
+
+ // If this is LOOK (without a noun), show any takeable objects
+ if (*(_vm._arrayVerbs[obj[i].verbIndex]) == _vm._arrayVerbs[_vm._look][0])
+ showTakeables();
+
+ return true;
+ }
+ }
+ return false;
+}
+
+// Search for matching verb/noun pairs in background command list
+// Print text for possible background object. Return TRUE if match found
+bool Parser_v1w::isBackgroundWord(objectList_t obj) {
+ debugC(1, kDebugParser, "isBackgroundWord(object_list_t obj)");
+
+ for (int i = 0; obj[i].verbIndex != 0; i++) {
+ if (isWordPresent(_vm._arrayVerbs[obj[i].verbIndex]) &&
+ isWordPresent(_vm._arrayNouns[obj[i].nounIndex]) &&
+ ((obj[i].roomState == DONT_CARE) ||
+ (obj[i].roomState == _vm._screenStates[*_vm._screen_p]))) {
+ Utils::Box(BOX_ANY, "%s", _vm.file().fetchString(obj[i].commentIndex));
+ _vm.scheduler().processBonus(obj[i].bonusIndex);
+ return true;
+ }
+ }
+ return false;
+}
+
+// Parse the user's line of text input. Generate events as necessary
+void Parser_v1w::lineHandler() {
+ debugC(1, kDebugParser, "lineHandler()");
+
+ status_t &gameStatus = _vm.getGameStatus();
+
+ // Toggle God Mode
+ if (!strncmp(_line, "PPG", 3)) {
+ _vm.sound().playSound(!_vm._soundTest, BOTH_CHANNELS, HIGH_PRI);
+ gameStatus.godModeFl ^= 1;
+ return;
+ }
+
+ Utils::strlwr(_line); // Convert to lower case
+
+ // God Mode cheat commands:
+ // goto <screen> Takes hero to named screen
+ // fetch <object name> Hero carries named object
+ // fetch all Hero carries all possible objects
+ // find <object name> Takes hero to screen containing named object
+ if (gameStatus.godModeFl) {
+ // Special code to allow me to go straight to any screen
+ if (strstr(_line, "goto")) {
+ for (int i = 0; i < _vm._numScreens; i++) {
+ if (!strcmp(&_line[strlen("goto") + 1], _vm._screenNames[i])) {
+ _vm.scheduler().newScreen(i);
+ return;
+ }
+ }
+ }
+
+ // Special code to allow me to get objects from anywhere
+ if (strstr(_line, "fetch all")) {
+ for (int i = 0; i < _vm._numObj; i++) {
+ if (_vm._objects[i].genericCmd & TAKE)
+ takeObject(&_vm._objects[i]);
+ }
+ return;
+ }
+
+ if (strstr(_line, "fetch")) {
+ for (int i = 0; i < _vm._numObj; i++) {
+ if (!strcmp(&_line[strlen("fetch") + 1], _vm._arrayNouns[_vm._objects[i].nounIndex][0])) {
+ takeObject(&_vm._objects[i]);
+ return;
+ }
+ }
+ }
+
+ // Special code to allow me to goto objects
+ if (strstr(_line, "find")) {
+ for (int i = 0; i < _vm._numObj; i++) {
+ if (!strcmp(&_line[strlen("find") + 1], _vm._arrayNouns[_vm._objects[i].nounIndex][0])) {
+ _vm.scheduler().newScreen(_vm._objects[i].screenIndex);
+ return;
+ }
+ }
+ }
+ }
+
+ // Special meta commands
+ // EXIT/QUIT
+ if (!strcmp("exit", _line) || strstr(_line, "quit")) {
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBExit]);
+ return;
+ }
+
+ // SAVE/RESTORE
+ if (!strcmp("save", _line) && gameStatus.viewState == V_PLAY) {
+ _vm.file().saveGame(gameStatus.saveSlot, "Current game");
+ return;
+ }
+
+ if (!strcmp("restore", _line) && (gameStatus.viewState == V_PLAY || gameStatus.viewState == V_IDLE)) {
+ _vm.file().restoreGame(gameStatus.saveSlot);
+ _vm.scheduler().restoreScreen(*_vm._screen_p);
+ gameStatus.viewState = V_PLAY;
+ return;
+ }
+
+ // Empty line
+ if (*_line == '\0') // Empty line
+ return;
+ if (strspn(_line, " ") == strlen(_line)) // Nothing but spaces!
+ return;
+
+ if (gameStatus.gameOverFl) {
+ // No commands allowed!
+ Utils::gameOverMsg();
+ return;
+ }
+
+ char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby
+
+ // Test for nearby objects referenced explicitly
+ for (int i = 0; i < _vm._numObj; i++) {
+ object_t *obj = &_vm._objects[i];
+ if (isWordPresent(_vm._arrayNouns[obj->nounIndex])) {
+ if (isObjectVerb(obj, farComment) || isGenericVerb(obj, farComment))
+ return;
+ }
+ }
+
+ // Test for nearby objects that only require a verb
+ // Note comment is unused if not near.
+ for (int i = 0; i < _vm._numObj; i++) {
+ object_t *obj = &_vm._objects[i];
+ if (obj->verbOnlyFl) {
+ char contextComment[XBYTES * 5] = ""; // Unused comment for context objects
+ if (isObjectVerb(obj, contextComment) || isGenericVerb(obj, contextComment))
+ return;
+ }
+ }
+
+ // No objects match command line, try background and catchall commands
+ if (isBackgroundWord(_vm._backgroundObjects[*_vm._screen_p]))
+ return;
+ if (isCatchallVerb(_vm._backgroundObjects[*_vm._screen_p]))
+ return;
+ if (isBackgroundWord(_vm._catchallList))
+ return;
+ if (isCatchallVerb(_vm._catchallList))
+ return;
+
+ // If a not-near comment was generated, print it
+ if (*farComment != '\0') {
+ Utils::Box(BOX_ANY, "%s", farComment);
+ return;
+ }
+
+ // Nothing matches. Report recognition success to user.
+ char *verb = findVerb();
+ char *noun = findNoun();
+ if (verb == _vm._arrayVerbs[_vm._look][0] && _maze.enabledFl) {
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBMaze]);
+ showTakeables();
+ } else if (verb && noun) { // A combination I didn't think of
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoPoint]);
+ } else if (noun) {
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoun]);
+ } else if (verb) {
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBVerb]);
+ } else {
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBEh]);
+ }
+}
+
+} // End of namespace Hugo
diff --git a/engines/hugo/parser_v2d.cpp b/engines/hugo/parser_v2d.cpp
new file mode 100644
index 0000000000..adaf5e9f9f
--- /dev/null
+++ b/engines/hugo/parser_v2d.cpp
@@ -0,0 +1,137 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on original Hugo Trilogy source code
+ *
+ * Copyright (c) 1989-1995 David P. Gray
+ *
+ */
+
+// parser.c - handles all keyboard/command input
+
+#include "common/system.h"
+
+#include "hugo/hugo.h"
+#include "hugo/parser.h"
+#include "hugo/util.h"
+
+namespace Hugo {
+
+Parser_v2d::Parser_v2d(HugoEngine &vm) : Parser_v1d(vm) {
+}
+
+Parser_v2d::~Parser_v2d() {
+}
+
+// Parse the user's line of text input. Generate events as necessary
+void Parser_v2d::lineHandler() {
+ debugC(1, kDebugParser, "lineHandler()");
+
+ object_t *obj;
+ status_t &gameStatus = _vm.getGameStatus();
+ char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby
+
+// Reset_prompt_line ();
+ Utils::strlwr(_line); // Convert to lower case
+
+ if (!strcmp("exit", _line) || strstr(_line, "quit")) {
+ if (Utils::Box(BOX_YESNO, "%s", _vm._textParser[kTBExit_1d]) != 0)
+ _vm.endGame();
+ else
+ return;
+ }
+
+ // SAVE/RESTORE
+ if (!strcmp("save", _line)) {
+ _config.soundFl = false;
+ if (gameStatus.gameOverFl)
+ Utils::gameOverMsg();
+ else
+// _vm.file().saveOrRestore(true);
+ warning("STUB: saveOrRestore()");
+ return;
+ }
+
+ if (!strcmp("restore", _line)) {
+ _config.soundFl = false;
+// _vm.file().saveOrRestore(false);
+ warning("STUB: saveOrRestore()");
+ return;
+ }
+
+ if (*_line == '\0') // Empty line
+ return;
+
+ if (strspn(_line, " ") == strlen(_line)) // Nothing but spaces!
+ return;
+
+ if (gameStatus.gameOverFl) { // No commands allowed!
+ Utils::gameOverMsg();
+ return;
+ }
+
+ // Find the first verb in the line
+ char *verb = findVerb();
+ char *noun = 0; // Noun not found yet
+
+ if (verb) { // OK, verb found. Try to match with object
+ do {
+ noun = findNextNoun(noun); // Find a noun in the line
+ // Must try at least once for objects allowing verb-context
+ for (int i = 0; i < _vm._numObj; i++) {
+ obj = &_vm._objects[i];
+ if (isNear(verb, noun, obj, farComment)) {
+ if (isObjectVerb(verb, obj) // Foreground object
+ || isGenericVerb(verb, obj)) // Common action type
+ return;
+ }
+ }
+ if ((*farComment != '\0') && isBackgroundWord(noun, verb, _vm._backgroundObjects[*_vm._screen_p]))
+ return;
+ } while (noun);
+ }
+
+ noun = findNextNoun(noun);
+ if ( !isCatchallVerb(true, noun, verb, _vm._backgroundObjects[*_vm._screen_p])
+ && !isCatchallVerb(true, noun, verb, _vm._catchallList)
+ && !isCatchallVerb(false, noun, verb, _vm._backgroundObjects[*_vm._screen_p])
+ && !isCatchallVerb(false, noun, verb, _vm._catchallList)) {
+ if (*farComment != '\0') { // An object matched but not near enough
+ Utils::Box(BOX_ANY, "%s", farComment);
+ } else if (_maze.enabledFl && (verb == _vm._arrayVerbs[_vm._look][0])) {
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBMaze]);
+ showTakeables();
+ } else if (verb && noun) { // A combination I didn't think of
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoUse_2d]);
+ } else if (verb || noun) {
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoun]);
+ } else {
+ Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBEh_2d]);
+ }
+ }
+}
+
+} // End of namespace Hugo
diff --git a/engines/hugo/schedule.cpp b/engines/hugo/schedule.cpp
index 439e651e8c..22eb99c6dd 100644
--- a/engines/hugo/schedule.cpp
+++ b/engines/hugo/schedule.cpp
@@ -33,7 +33,6 @@
// This module contains all the scheduling and timing stuff
#include "common/system.h"
-#include "common/stream.h"
#include "hugo/game.h"
#include "hugo/hugo.h"
@@ -239,7 +238,7 @@ event_t *Scheduler::doAction(event_t *curEvent) {
insertActionList(action->a3.actFailIndex);
#endif
-//HACK: As the answer is not read, currently it's always considered correct
+ // HACK: As the answer is not read, currently it's always considered correct
insertActionList(action->a3.actPassIndex);
break;
}
@@ -674,23 +673,4 @@ void Scheduler::swapImages(int objNumb1, int objNumb2) {
_vm._objects[objNumb1].y += _vm._objects[objNumb2].currImagePtr->y2 - _vm._objects[objNumb1].currImagePtr->y2;
}
-Scheduler_v1d::Scheduler_v1d(HugoEngine &vm) : Scheduler(vm) {
-}
-
-Scheduler_v1d::~Scheduler_v1d() {
-}
-
-const char *Scheduler_v1d::getCypher() {
- return "Copyright 1991, Gray Design Associates";
-}
-
-Scheduler_v3d::Scheduler_v3d(HugoEngine &vm) : Scheduler(vm) {
-}
-
-Scheduler_v3d::~Scheduler_v3d() {
-}
-
-const char *Scheduler_v3d::getCypher() {
- return "Copyright 1992, Gray Design Associates";
-}
} // End of namespace Hugo
diff --git a/engines/hugo/schedule_v1d.cpp b/engines/hugo/schedule_v1d.cpp
new file mode 100644
index 0000000000..81daf639f6
--- /dev/null
+++ b/engines/hugo/schedule_v1d.cpp
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on original Hugo Trilogy source code
+ *
+ * Copyright (c) 1989-1995 David P. Gray
+ *
+ */
+
+// This module contains all the scheduling and timing stuff
+
+#include "common/system.h"
+
+#include "hugo/hugo.h"
+#include "hugo/schedule.h"
+
+namespace Hugo {
+
+Scheduler_v1d::Scheduler_v1d(HugoEngine &vm) : Scheduler(vm) {
+}
+
+Scheduler_v1d::~Scheduler_v1d() {
+}
+
+const char *Scheduler_v1d::getCypher() {
+ return "Copyright 1991, Gray Design Associates";
+}
+
+} // End of namespace Hugo
diff --git a/engines/hugo/schedule_v3d.cpp b/engines/hugo/schedule_v3d.cpp
new file mode 100644
index 0000000000..9421b0f5f9
--- /dev/null
+++ b/engines/hugo/schedule_v3d.cpp
@@ -0,0 +1,51 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on original Hugo Trilogy source code
+ *
+ * Copyright (c) 1989-1995 David P. Gray
+ *
+ */
+
+// This module contains all the scheduling and timing stuff
+
+#include "common/system.h"
+
+#include "hugo/hugo.h"
+#include "hugo/schedule.h"
+
+namespace Hugo {
+
+Scheduler_v3d::Scheduler_v3d(HugoEngine &vm) : Scheduler(vm) {
+}
+
+Scheduler_v3d::~Scheduler_v3d() {
+}
+
+const char *Scheduler_v3d::getCypher() {
+ return "Copyright 1992, Gray Design Associates";
+}
+} // End of namespace Hugo