diff options
Diffstat (limited to 'engines/hugo')
-rw-r--r-- | engines/hugo/display.cpp | 80 | ||||
-rw-r--r-- | engines/hugo/display_v1d.cpp | 83 | ||||
-rw-r--r-- | engines/hugo/display_v1w.cpp | 83 | ||||
-rw-r--r-- | engines/hugo/file.cpp | 402 | ||||
-rw-r--r-- | engines/hugo/file_v1d.cpp | 101 | ||||
-rw-r--r-- | engines/hugo/file_v1w.cpp | 90 | ||||
-rw-r--r-- | engines/hugo/file_v2d.cpp | 177 | ||||
-rw-r--r-- | engines/hugo/file_v3d.cpp | 200 | ||||
-rw-r--r-- | engines/hugo/intro.cpp | 326 | ||||
-rw-r--r-- | engines/hugo/intro_v1d.cpp | 172 | ||||
-rw-r--r-- | engines/hugo/intro_v1w.cpp | 61 | ||||
-rw-r--r-- | engines/hugo/intro_v2d.cpp | 77 | ||||
-rw-r--r-- | engines/hugo/intro_v2w.cpp | 57 | ||||
-rw-r--r-- | engines/hugo/intro_v3d.cpp | 109 | ||||
-rw-r--r-- | engines/hugo/intro_v3w.cpp | 94 | ||||
-rw-r--r-- | engines/hugo/module.mk | 17 | ||||
-rw-r--r-- | engines/hugo/parser.cpp | 799 | ||||
-rw-r--r-- | engines/hugo/parser_v1d.cpp | 355 | ||||
-rw-r--r-- | engines/hugo/parser_v1w.cpp | 434 | ||||
-rw-r--r-- | engines/hugo/parser_v2d.cpp | 137 | ||||
-rw-r--r-- | engines/hugo/schedule.cpp | 22 | ||||
-rw-r--r-- | engines/hugo/schedule_v1d.cpp | 52 | ||||
-rw-r--r-- | engines/hugo/schedule_v3d.cpp | 51 |
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 |