HUGO: Split classes with multiple version in separate files
svn-id: r53152
This commit is contained in:
parent
576d6429bc
commit
2978053a00
23 changed files with 2351 additions and 1628 deletions
|
@ -34,10 +34,8 @@
|
||||||
|
|
||||||
#include "common/system.h"
|
#include "common/system.h"
|
||||||
|
|
||||||
#include "hugo/game.h"
|
|
||||||
#include "hugo/hugo.h"
|
#include "hugo/hugo.h"
|
||||||
#include "hugo/display.h"
|
#include "hugo/display.h"
|
||||||
#include "hugo/file.h"
|
|
||||||
#include "hugo/util.h"
|
#include "hugo/util.h"
|
||||||
|
|
||||||
namespace Hugo {
|
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
|
} // End of namespace Hugo
|
||||||
|
|
||||||
|
|
83
engines/hugo/display_v1d.cpp
Normal file
83
engines/hugo/display_v1d.cpp
Normal file
|
@ -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
|
||||||
|
|
83
engines/hugo/display_v1w.cpp
Normal file
83
engines/hugo/display_v1w.cpp
Normal file
|
@ -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
|
||||||
|
|
|
@ -31,10 +31,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common/system.h"
|
#include "common/system.h"
|
||||||
#include "common/file.h"
|
|
||||||
#include "common/savefile.h"
|
#include "common/savefile.h"
|
||||||
|
|
||||||
#include "hugo/game.h"
|
|
||||||
#include "hugo/hugo.h"
|
#include "hugo/hugo.h"
|
||||||
#include "hugo/file.h"
|
#include "hugo/file.h"
|
||||||
#include "hugo/global.h"
|
#include "hugo/global.h"
|
||||||
|
@ -674,405 +672,5 @@ void FileManager::instructions() {
|
||||||
f.close();
|
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
|
} // End of namespace Hugo
|
||||||
|
|
||||||
|
|
101
engines/hugo/file_v1d.cpp
Normal file
101
engines/hugo/file_v1d.cpp
Normal file
|
@ -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
|
||||||
|
|
90
engines/hugo/file_v1w.cpp
Normal file
90
engines/hugo/file_v1w.cpp
Normal file
|
@ -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
|
||||||
|
|
177
engines/hugo/file_v2d.cpp
Normal file
177
engines/hugo/file_v2d.cpp
Normal file
|
@ -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
|
||||||
|
|
200
engines/hugo/file_v3d.cpp
Normal file
200
engines/hugo/file_v3d.cpp
Normal file
|
@ -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
|
||||||
|
|
|
@ -32,13 +32,8 @@
|
||||||
|
|
||||||
#include "common/system.h"
|
#include "common/system.h"
|
||||||
|
|
||||||
#include "hugo/game.h"
|
|
||||||
#include "hugo/hugo.h"
|
#include "hugo/hugo.h"
|
||||||
#include "hugo/intro.h"
|
#include "hugo/intro.h"
|
||||||
#include "hugo/file.h"
|
|
||||||
#include "hugo/display.h"
|
|
||||||
#include "hugo/util.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
|
@ -48,325 +43,4 @@ IntroHandler::IntroHandler(HugoEngine &vm) : _vm(vm) {
|
||||||
IntroHandler::~IntroHandler() {
|
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
|
} // End of namespace Hugo
|
||||||
|
|
172
engines/hugo/intro_v1d.cpp
Normal file
172
engines/hugo/intro_v1d.cpp
Normal file
|
@ -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
|
61
engines/hugo/intro_v1w.cpp
Normal file
61
engines/hugo/intro_v1w.cpp
Normal file
|
@ -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
|
77
engines/hugo/intro_v2d.cpp
Normal file
77
engines/hugo/intro_v2d.cpp
Normal file
|
@ -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
|
57
engines/hugo/intro_v2w.cpp
Normal file
57
engines/hugo/intro_v2w.cpp
Normal file
|
@ -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
|
109
engines/hugo/intro_v3d.cpp
Normal file
109
engines/hugo/intro_v3d.cpp
Normal file
|
@ -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
|
94
engines/hugo/intro_v3w.cpp
Normal file
94
engines/hugo/intro_v3w.cpp
Normal file
|
@ -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
|
|
@ -3,15 +3,32 @@ MODULE := engines/hugo
|
||||||
MODULE_OBJS := \
|
MODULE_OBJS := \
|
||||||
detection.o \
|
detection.o \
|
||||||
display.o \
|
display.o \
|
||||||
|
display_v1d.o \
|
||||||
|
display_v1w.o \
|
||||||
engine.o \
|
engine.o \
|
||||||
file.o \
|
file.o \
|
||||||
|
file_v1d.o \
|
||||||
|
file_v2d.o \
|
||||||
|
file_v3d.o \
|
||||||
|
file_v1w.o \
|
||||||
hugo.o \
|
hugo.o \
|
||||||
intro.o \
|
intro.o \
|
||||||
|
intro_v1d.o \
|
||||||
|
intro_v2d.o \
|
||||||
|
intro_v3d.o \
|
||||||
|
intro_v1w.o \
|
||||||
|
intro_v2w.o \
|
||||||
|
intro_v3w.o \
|
||||||
inventory.o \
|
inventory.o \
|
||||||
mouse.o \
|
mouse.o \
|
||||||
parser.o \
|
parser.o \
|
||||||
|
parser_v1w.o \
|
||||||
|
parser_v1d.o \
|
||||||
|
parser_v2d.o \
|
||||||
route.o \
|
route.o \
|
||||||
schedule.o \
|
schedule.o \
|
||||||
|
schedule_v1d.o \
|
||||||
|
schedule_v3d.o \
|
||||||
sound.o \
|
sound.o \
|
||||||
util.o
|
util.o
|
||||||
|
|
||||||
|
|
|
@ -30,17 +30,11 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// parser.c - handles all keyboard/command input
|
|
||||||
|
|
||||||
#include "common/system.h"
|
#include "common/system.h"
|
||||||
#include "common/keyboard.h"
|
|
||||||
|
|
||||||
#include "hugo/game.h"
|
|
||||||
#include "hugo/hugo.h"
|
#include "hugo/hugo.h"
|
||||||
#include "hugo/parser.h"
|
#include "hugo/parser.h"
|
||||||
#include "hugo/global.h"
|
|
||||||
#include "hugo/file.h"
|
#include "hugo/file.h"
|
||||||
#include "hugo/schedule.h"
|
|
||||||
#include "hugo/display.h"
|
#include "hugo/display.h"
|
||||||
#include "hugo/route.h"
|
#include "hugo/route.h"
|
||||||
#include "hugo/util.h"
|
#include "hugo/util.h"
|
||||||
|
@ -205,395 +199,6 @@ void Parser::command(const char *format, ...) {
|
||||||
lineHandler();
|
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
|
// Locate any member of object name list appearing in command line
|
||||||
bool Parser::isWordPresent(char **wordArr) {
|
bool Parser::isWordPresent(char **wordArr) {
|
||||||
debugC(1, kDebugParser, "isWordPresent(%s)", wordArr[0]);
|
debugC(1, kDebugParser, "isWordPresent(%s)", wordArr[0]);
|
||||||
|
@ -697,408 +302,4 @@ void Parser::showDosInventory() {
|
||||||
Utils::Box(BOX_ANY, "%s", buffer);
|
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
|
} // End of namespace Hugo
|
||||||
|
|
355
engines/hugo/parser_v1d.cpp
Normal file
355
engines/hugo/parser_v1d.cpp
Normal file
|
@ -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
|
434
engines/hugo/parser_v1w.cpp
Normal file
434
engines/hugo/parser_v1w.cpp
Normal file
|
@ -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
|
137
engines/hugo/parser_v2d.cpp
Normal file
137
engines/hugo/parser_v2d.cpp
Normal file
|
@ -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
|
|
@ -33,7 +33,6 @@
|
||||||
// This module contains all the scheduling and timing stuff
|
// This module contains all the scheduling and timing stuff
|
||||||
|
|
||||||
#include "common/system.h"
|
#include "common/system.h"
|
||||||
#include "common/stream.h"
|
|
||||||
|
|
||||||
#include "hugo/game.h"
|
#include "hugo/game.h"
|
||||||
#include "hugo/hugo.h"
|
#include "hugo/hugo.h"
|
||||||
|
@ -239,7 +238,7 @@ event_t *Scheduler::doAction(event_t *curEvent) {
|
||||||
insertActionList(action->a3.actFailIndex);
|
insertActionList(action->a3.actFailIndex);
|
||||||
#endif
|
#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);
|
insertActionList(action->a3.actPassIndex);
|
||||||
break;
|
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;
|
_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
|
} // End of namespace Hugo
|
||||||
|
|
52
engines/hugo/schedule_v1d.cpp
Normal file
52
engines/hugo/schedule_v1d.cpp
Normal file
|
@ -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
|
51
engines/hugo/schedule_v3d.cpp
Normal file
51
engines/hugo/schedule_v3d.cpp
Normal file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue