Initial commit
This commit is contained in:
3
engines/neverhood/POTFILES
Normal file
3
engines/neverhood/POTFILES
Normal file
@@ -0,0 +1,3 @@
|
||||
engines/neverhood/dialogs.cpp
|
||||
engines/neverhood/menumodule.cpp
|
||||
engines/neverhood/metaengine.cpp
|
||||
55
engines/neverhood/background.cpp
Normal file
55
engines/neverhood/background.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/background.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Background
|
||||
|
||||
Background::Background(NeverhoodEngine *vm, int objectPriority)
|
||||
: Entity(vm, objectPriority), _surface(nullptr), _spriteResource(vm) {
|
||||
// Empty
|
||||
}
|
||||
|
||||
Background::Background(NeverhoodEngine *vm, uint32 fileHash, int objectPriority, int surfacePriority)
|
||||
: Entity(vm, objectPriority), _surface(nullptr), _spriteResource(vm) {
|
||||
|
||||
_spriteResource.load(fileHash);
|
||||
createSurface(surfacePriority, _spriteResource.getDimensions().width, _spriteResource.getDimensions().height);
|
||||
_surface->drawSpriteResource(_spriteResource);
|
||||
|
||||
}
|
||||
|
||||
void Background::createSurface(int surfacePriority, int16 width, int16 height) {
|
||||
_surface .reset(new BaseSurface(_vm, surfacePriority, width, height, "background"));
|
||||
_surface->setTransparent(false);
|
||||
_spriteResource.getPosition().x = width;
|
||||
_spriteResource.getPosition().y = height;
|
||||
}
|
||||
|
||||
void Background::load(uint32 fileHash) {
|
||||
_spriteResource.load(fileHash);
|
||||
if (_surface)
|
||||
_surface->drawSpriteResource(_spriteResource);
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
47
engines/neverhood/background.h
Normal file
47
engines/neverhood/background.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_BACKGROUND_H
|
||||
#define NEVERHOOD_BACKGROUND_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/entity.h"
|
||||
#include "neverhood/graphics.h"
|
||||
#include "neverhood/resource.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Background : public Entity {
|
||||
public:
|
||||
Background(NeverhoodEngine *vm, int objectPriority);
|
||||
Background(NeverhoodEngine *vm, uint32 fileHash, int objectPriority, int surfacePriority);
|
||||
Common::SharedPtr<BaseSurface> getSurface() { return _surface; }
|
||||
void createSurface(int surfacePriority, int16 width, int16 height);
|
||||
void load(uint32 fileHash);
|
||||
SpriteResource& getSpriteResource() { return _spriteResource; }
|
||||
protected:
|
||||
Common::SharedPtr<BaseSurface> _surface;
|
||||
SpriteResource _spriteResource;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_BACKGROUND_H */
|
||||
144
engines/neverhood/blbarchive.cpp
Normal file
144
engines/neverhood/blbarchive.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/compression/dcl.h"
|
||||
#include "neverhood/blbarchive.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
BlbArchive::BlbArchive() : _extData(nullptr) {
|
||||
}
|
||||
|
||||
BlbArchive::~BlbArchive() {
|
||||
delete[] _extData;
|
||||
}
|
||||
|
||||
bool BlbArchive::open(const Common::Path &filename, bool isOptional) {
|
||||
BlbHeader header;
|
||||
uint16 *extDataOffsets;
|
||||
|
||||
_entries.clear();
|
||||
|
||||
if (!_fd.open(filename)) {
|
||||
if (!isOptional)
|
||||
error("BlbArchive::open() Could not open %s", filename.toString(Common::Path::kNativeSeparator).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
header.id1 = _fd.readUint32LE();
|
||||
header.id2 = _fd.readUint16LE();
|
||||
header.extDataSize = _fd.readUint16LE();
|
||||
header.fileSize = _fd.readUint32LE();
|
||||
header.fileCount = _fd.readUint32LE();
|
||||
|
||||
if (header.id1 != 0x2004940 || header.id2 != 7 || header.fileSize != _fd.size()) {
|
||||
error("BlbArchive::open() %s seems to be corrupt", filename.toString(Common::Path::kNativeSeparator).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
debug(4, "%s: fileCount = %d", filename.toString(Common::Path::kNativeSeparator).c_str(), header.fileCount);
|
||||
|
||||
_entries.reserve(header.fileCount);
|
||||
|
||||
// Load file hashes
|
||||
for (uint i = 0; i < header.fileCount; i++) {
|
||||
BlbArchiveEntry entry;
|
||||
entry.fileHash = _fd.readUint32LE();
|
||||
_entries.push_back(entry);
|
||||
}
|
||||
|
||||
extDataOffsets = new uint16[header.fileCount];
|
||||
|
||||
// Load file records
|
||||
for (uint i = 0; i < header.fileCount; i++) {
|
||||
BlbArchiveEntry &entry = _entries[i];
|
||||
entry.type = _fd.readByte();
|
||||
entry.comprType = _fd.readByte();
|
||||
entry.extData = nullptr;
|
||||
extDataOffsets[i] = _fd.readUint16LE();
|
||||
entry.timeStamp = _fd.readUint32LE();
|
||||
entry.offset = _fd.readUint32LE();
|
||||
entry.diskSize = _fd.readUint32LE();
|
||||
entry.size = _fd.readUint32LE();
|
||||
debug(4, "%08X: %03d, %02X, %04X, %08X, %08X, %08X, %08X",
|
||||
entry.fileHash, entry.type, entry.comprType, extDataOffsets[i], entry.timeStamp,
|
||||
entry.offset, entry.diskSize, entry.size);
|
||||
}
|
||||
|
||||
// Load ext data
|
||||
if (header.extDataSize > 0) {
|
||||
_extData = new byte[header.extDataSize];
|
||||
_fd.read(_extData, header.extDataSize);
|
||||
for (uint i = 0; i < header.fileCount; i++)
|
||||
_entries[i].extData = extDataOffsets[i] > 0 ? _extData + extDataOffsets[i] - 1 : nullptr;
|
||||
}
|
||||
|
||||
delete[] extDataOffsets;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BlbArchive::load(uint index, byte *buffer, uint32 size) {
|
||||
load(&_entries[index], buffer, size);
|
||||
}
|
||||
|
||||
void BlbArchive::load(BlbArchiveEntry *entry, byte *buffer, uint32 size) {
|
||||
Common::StackLock lock(_mutex);
|
||||
|
||||
_fd.seek(entry->offset);
|
||||
|
||||
switch (entry->comprType) {
|
||||
case 1: // Uncompressed
|
||||
if (size == 0)
|
||||
size = entry->diskSize;
|
||||
_fd.read(buffer, size);
|
||||
break;
|
||||
case 3: {// DCL-compressed
|
||||
memset(buffer, 0, size);
|
||||
if (!Common::decompressDCL(&_fd, buffer, entry->diskSize, entry->size))
|
||||
warning("BlbArchive::load() Error during decompression of %08X (offset: %d, disk size: %d, size: %d)",
|
||||
entry->fileHash, entry->offset, entry->diskSize, entry->size);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
error("BlbArchive::load() Unknown compression type %d", entry->comprType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
byte *BlbArchive::getEntryExtData(uint index) {
|
||||
return getEntryExtData(&_entries[index]);
|
||||
}
|
||||
|
||||
byte *BlbArchive::getEntryExtData(BlbArchiveEntry *entry) {
|
||||
return entry->extData;
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *BlbArchive::createStream(uint index) {
|
||||
return createStream(&_entries[index]);
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *BlbArchive::createStream(BlbArchiveEntry *entry) {
|
||||
return new Common::SafeMutexedSeekableSubReadStream(&_fd, entry->offset, entry->offset + entry->diskSize,
|
||||
DisposeAfterUse::NO, _mutex);
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
76
engines/neverhood/blbarchive.h
Normal file
76
engines/neverhood/blbarchive.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_BLBARCHIVE_H
|
||||
#define NEVERHOOD_BLBARCHIVE_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/file.h"
|
||||
#include "common/mutex.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/substream.h"
|
||||
#include "neverhood/neverhood.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
struct BlbHeader {
|
||||
uint32 id1;
|
||||
uint16 id2;
|
||||
uint16 extDataSize;
|
||||
int32 fileSize;
|
||||
uint32 fileCount;
|
||||
};
|
||||
|
||||
struct BlbArchiveEntry {
|
||||
uint32 fileHash;
|
||||
byte type;
|
||||
byte comprType;
|
||||
byte *extData;
|
||||
uint32 timeStamp;
|
||||
uint32 offset;
|
||||
uint32 diskSize;
|
||||
uint32 size;
|
||||
};
|
||||
|
||||
class BlbArchive {
|
||||
public:
|
||||
BlbArchive();
|
||||
~BlbArchive();
|
||||
bool open(const Common::Path &filename, bool isOptional);
|
||||
void load(uint index, byte *buffer, uint32 size);
|
||||
void load(BlbArchiveEntry *entry, byte *buffer, uint32 size);
|
||||
byte *getEntryExtData(uint index);
|
||||
byte *getEntryExtData(BlbArchiveEntry *entry);
|
||||
uint32 getSize(uint index) { return _entries[index].size; }
|
||||
BlbArchiveEntry *getEntry(uint index) { return &_entries[index]; }
|
||||
uint getCount() { return _entries.size(); }
|
||||
Common::SeekableReadStream *createStream(uint index);
|
||||
Common::SeekableReadStream *createStream(BlbArchiveEntry *entry);
|
||||
private:
|
||||
Common::File _fd;
|
||||
Common::Mutex _mutex;
|
||||
Common::Array<BlbArchiveEntry> _entries;
|
||||
byte *_extData;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_BLBARCHIVE_H */
|
||||
3
engines/neverhood/configure.engine
Normal file
3
engines/neverhood/configure.engine
Normal file
@@ -0,0 +1,3 @@
|
||||
# This file is included from the main "configure" script
|
||||
# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] [components]
|
||||
add_engine neverhood "Neverhood" yes "" "" "highres"
|
||||
268
engines/neverhood/console.cpp
Normal file
268
engines/neverhood/console.cpp
Normal file
@@ -0,0 +1,268 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/console.h"
|
||||
#include "gui/debugger.h"
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/gamemodule.h"
|
||||
#include "neverhood/navigationscene.h"
|
||||
#include "neverhood/scene.h"
|
||||
#include "neverhood/smackerscene.h"
|
||||
#include "neverhood/sound.h"
|
||||
#include "neverhood/modules/module1600.h"
|
||||
#include "neverhood/modules/module3000_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
Console::Console(NeverhoodEngine *vm) : GUI::Debugger(), _vm(vm) {
|
||||
registerCmd("cheat", WRAP_METHOD(Console, Cmd_Cheat));
|
||||
registerCmd("checkresource", WRAP_METHOD(Console, Cmd_CheckResource));
|
||||
registerCmd("dumpresource", WRAP_METHOD(Console, Cmd_DumpResource));
|
||||
registerCmd("dumpvars", WRAP_METHOD(Console, Cmd_Dumpvars));
|
||||
registerCmd("playsound", WRAP_METHOD(Console, Cmd_PlaySound));
|
||||
registerCmd("scene", WRAP_METHOD(Console, Cmd_Scene));
|
||||
registerCmd("surfaces", WRAP_METHOD(Console, Cmd_Surfaces));
|
||||
}
|
||||
|
||||
Console::~Console() {
|
||||
}
|
||||
|
||||
bool Console::Cmd_Scene(int argc, const char **argv) {
|
||||
if (argc != 3) {
|
||||
int currentModule = _vm->_gameModule->getCurrentModuleNum();
|
||||
int previousModule = _vm->_gameModule->getPreviousModuleNum();
|
||||
int scenenNum = _vm->gameState().sceneNum;
|
||||
SceneType sceneType = ((GameModule *)_vm->_gameModule->_childObject)->getSceneType();
|
||||
|
||||
const char *sceneTypes[] = { "normal", "smacker", "navigation" };
|
||||
|
||||
debugPrintf("Current module: %d, previous module: %d, scene %d (%s scene)\n", currentModule, previousModule, scenenNum, sceneTypes[sceneType]);
|
||||
|
||||
if (sceneType == kSceneTypeNormal) {
|
||||
Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
|
||||
// Normal scenes have a background and a cursor file hash
|
||||
debugPrintf("Background hash: 0x%x, cursor hash: 0x%x\n", scene->getBackgroundFileHash(), scene->getCursorFileHash());
|
||||
} else if (sceneType == kSceneTypeSmacker) {
|
||||
SmackerScene *scene = (SmackerScene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
|
||||
// Smacker scenes have a file hash, or a list of hashes
|
||||
// TODO: Only the first file hash is shown - any additional hashes, found in
|
||||
// scenes with a list of hashes (two scenes in module 1100 and the making of
|
||||
// video) aren't shown yet
|
||||
debugPrintf("File hash: 0x%x\n", scene->getSmackerFileHash());
|
||||
} else if (sceneType == kSceneTypeNavigation) {
|
||||
NavigationScene *scene = (NavigationScene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
|
||||
// Navigation scenes have a navigation list and its index
|
||||
NavigationList *navigationList = _vm->_staticData->getNavigationList(scene->getNavigationListId());
|
||||
int navigationIndex = scene->getGlobalVar(V_NAVIGATION_INDEX);
|
||||
NavigationItem curNavigation = (*navigationList)[navigationIndex];
|
||||
debugPrintf("Navigation list ID: 0x%x, index: %d\n", scene->getNavigationListId(), navigationIndex);
|
||||
debugPrintf("File hash: 0x%x, cursor hash: 0x%x, Smacker hashes: [left: 0x%x, middle: 0x%x, right: 0x%x\n",
|
||||
curNavigation.fileHash, curNavigation.mouseCursorFileHash,
|
||||
curNavigation.leftSmackerFileHash, curNavigation.middleSmackerFileHash, curNavigation.rightSmackerFileHash);
|
||||
}
|
||||
|
||||
debugPrintf("Use %s <module> <scene> to change scenes\n", argv[0]);
|
||||
debugPrintf("Modules are incremental by 100, from 1000 to 3000\n");
|
||||
} else {
|
||||
int newModule = atoi(argv[1]);
|
||||
int newScene = atoi(argv[2]);
|
||||
|
||||
_vm->gameState().sceneNum = newScene;
|
||||
_vm->_gameModule->createModule(newModule, -1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Console::Cmd_Surfaces(int argc, const char **argv) {
|
||||
if (_vm->_gameModule->_childObject) {
|
||||
((Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject)->printSurfaces(this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Console::Cmd_Cheat(int argc, const char **argv) {
|
||||
if (argc < 2) {
|
||||
debugPrintf("Cheats for various puzzles in the game\n");
|
||||
debugPrintf("Use %s <cheatname> to use a cheat.\n", argv[0]);
|
||||
debugPrintf("Cheats:\n-------\n");
|
||||
debugPrintf(" buttons - enables all 3 buttons on the door in the purple building, module 3000, scene 9\n");
|
||||
debugPrintf(" cannon - sets the correct cannon combination in module 3000, scene 8\n");
|
||||
debugPrintf(" dice - shows the correct dice combination in the teddy bear puzzle, module 1100, scene 6\n");
|
||||
debugPrintf(" memory - solves the memory puzzle, module 1400, scene 4\n");
|
||||
debugPrintf(" music - shows the correct index in the radio music puzzle, module 2800, scene 1\n");
|
||||
debugPrintf(" radio - enables the radio, module 3000, scene 9 - same as pulling the rightmost cord in the flytrap room\n");
|
||||
debugPrintf(" symbols - solves the symbols puzzle, module 1600, scene 8. Only available in that room\n");
|
||||
debugPrintf(" tubes - shows the correct test tube combination in module 2800, scenes 7 and 10\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
Common::String cheatName = argv[1];
|
||||
int moduleNum = _vm->_gameModule->getCurrentModuleNum();
|
||||
int sceneNum = _vm->gameState().sceneNum;
|
||||
|
||||
if (cheatName == "buttons") {
|
||||
Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
|
||||
|
||||
scene->setSubVar(VA_LOCKS_DISABLED, 0x304008D2, 1); // kScene3010ButtonNameHashes[0]
|
||||
scene->setSubVar(VA_LOCKS_DISABLED, 0x40119852, 1); // kScene3010ButtonNameHashes[1]
|
||||
scene->setSubVar(VA_LOCKS_DISABLED, 0x01180951, 1); // kScene3010ButtonNameHashes[2]
|
||||
|
||||
debugPrintf("All 3 door buttons have been enabled\n");
|
||||
} else if (cheatName == "cannon") {
|
||||
Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
scene->setSubVar(VA_CURR_CANNON_SYMBOLS, i, scene->getSubVar(VA_GOOD_CANNON_SYMBOLS_1, i));
|
||||
|
||||
for (int i = 3; i < 6; i++)
|
||||
scene->setSubVar(VA_CURR_CANNON_SYMBOLS, i, scene->getSubVar(VA_GOOD_CANNON_SYMBOLS_2, i - 3));
|
||||
|
||||
debugPrintf("Puzzle solved\n");
|
||||
} else if (cheatName == "dice") {
|
||||
Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
|
||||
debugPrintf("Good: (%d %d %d), current: (%d %d %d)\n",
|
||||
scene->getSubVar(VA_GOOD_DICE_NUMBERS, 0), scene->getSubVar(VA_GOOD_DICE_NUMBERS, 1), scene->getSubVar(VA_GOOD_DICE_NUMBERS, 2),
|
||||
scene->getSubVar(VA_CURR_DICE_NUMBERS, 0), scene->getSubVar(VA_CURR_DICE_NUMBERS, 1), scene->getSubVar(VA_CURR_DICE_NUMBERS, 2)
|
||||
);
|
||||
} else if (cheatName == "memory") {
|
||||
Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
|
||||
|
||||
// Autosolve all tiles and leave only two matching tiles closed
|
||||
for (int i = 0; i < 48; i++)
|
||||
scene->setSubVar(VA_IS_TILE_MATCH, i, 1);
|
||||
|
||||
// Close the top left tile
|
||||
scene->setSubVar(VA_IS_TILE_MATCH, 0, 0);
|
||||
|
||||
// Find and close the pair of the top left tile
|
||||
for (int i = 0; i < 48; i++) {
|
||||
if (i != 0 && scene->getSubVar(VA_TILE_SYMBOLS, i) == scene->getSubVar(VA_TILE_SYMBOLS, 0)) {
|
||||
scene->setSubVar(VA_IS_TILE_MATCH, i, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
debugPrintf("Puzzle solved\n");
|
||||
} else if (cheatName == "music") {
|
||||
Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
|
||||
debugPrintf("Good music index: %d, current radio music index: %d\n", scene->getGlobalVar(V_CURR_RADIO_MUSIC_INDEX), scene->getGlobalVar(V_GOOD_RADIO_MUSIC_INDEX));
|
||||
} else if (cheatName == "radio") {
|
||||
Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
|
||||
scene->setGlobalVar(V_RADIO_ENABLED, 1);
|
||||
|
||||
debugPrintf("The radio has been enabled\n");
|
||||
} else if (cheatName == "symbols") {
|
||||
if (moduleNum == 1600 && sceneNum == 8) {
|
||||
Scene1609 *scene = ((Scene1609 *)((Module1600 *)_vm->_gameModule->_childObject)->_childObject);
|
||||
|
||||
for (int index = 0; index < 12; index++) {
|
||||
scene->_asSymbols[index]->change((int)scene->getSubVar(VA_CODE_SYMBOLS, index) + 12, index == (int)scene->getSubVar(VA_CODE_SYMBOLS, scene->_noisySymbolIndex));
|
||||
}
|
||||
|
||||
scene->_changeCurrentSymbol = false;
|
||||
scene->_symbolPosition = 11;
|
||||
scene->_countdown1 = 36;
|
||||
|
||||
debugPrintf("Puzzle solved\n");
|
||||
} else {
|
||||
debugPrintf("Only available in module 1600, scene 8\n");
|
||||
}
|
||||
} else if (cheatName == "tubes") {
|
||||
Scene *scene = (Scene *)((GameModule *)_vm->_gameModule->_childObject)->_childObject;
|
||||
debugPrintf("Tube set 1: %d %d %d\n", scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 0), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 1), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, 2));
|
||||
debugPrintf("Tube set 2: %d %d %d\n", scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 0), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 1), scene->getSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, 2));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Console::Cmd_Dumpvars(int argc, const char **argv) {
|
||||
_vm->_gameVars->dumpVars(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Console::Cmd_PlaySound(int argc, const char **argv) {
|
||||
if (argc < 2) {
|
||||
debugPrintf("Usage: %s <sound hash>\n", argv[0]);
|
||||
} else {
|
||||
uint32 soundHash = strtol(argv[1], nullptr, 0);
|
||||
AudioResourceManSoundItem *soundItem = new AudioResourceManSoundItem(_vm, soundHash);
|
||||
soundItem->setVolume(100);
|
||||
soundItem->playSound(false);
|
||||
while (soundItem->isPlaying()) {
|
||||
_vm->_system->delayMillis(10);
|
||||
}
|
||||
delete soundItem;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Console::Cmd_CheckResource(int argc, const char **argv) {
|
||||
const char *resourceNames[] = { "unknown", "unknown", "bitmap", "palette", "animation", "data", "text", "sound", "music", "unknown", "video" };
|
||||
|
||||
if (argc < 2) {
|
||||
debugPrintf("Gets information about a resource\n");
|
||||
debugPrintf("Usage: %s <resource hash>\n", argv[0]);
|
||||
} else {
|
||||
uint32 resourceHash = strtol(argv[1], nullptr, 0);
|
||||
ResourceHandle handle;
|
||||
|
||||
_vm->_res->queryResource(resourceHash, handle);
|
||||
if (!handle.isValid()) {
|
||||
debugPrintf("Invalid resource hash\n");
|
||||
} else {
|
||||
debugPrintf("Resource type: %d (%s). Size: %d bytes\n", handle.type(), resourceNames[handle.type()], handle.size());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Console::Cmd_DumpResource(int argc, const char **argv) {
|
||||
if (argc < 3) {
|
||||
debugPrintf("Dumps a resource to disk\n");
|
||||
debugPrintf("Usage: %s <resource hash> <output file>\n", argv[0]);
|
||||
} else {
|
||||
uint32 resourceHash = strtol(argv[1], nullptr, 0);
|
||||
const char *outFileName = argv[2];
|
||||
ResourceHandle handle;
|
||||
|
||||
_vm->_res->queryResource(resourceHash, handle);
|
||||
if (!handle.isValid()) {
|
||||
debugPrintf("Invalid resource hash\n");
|
||||
} else {
|
||||
_vm->_res->loadResource(handle, _vm->applyResourceFixes());
|
||||
Common::DumpFile outFile;
|
||||
outFile.open(outFileName);
|
||||
outFile.write(handle.data(), handle.size());
|
||||
outFile.finalize();
|
||||
outFile.close();
|
||||
_vm->_res->unloadResource(handle);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
50
engines/neverhood/console.h
Normal file
50
engines/neverhood/console.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_CONSOLE_H
|
||||
#define NEVERHOOD_CONSOLE_H
|
||||
|
||||
#include "gui/debugger.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class NeverhoodEngine;
|
||||
|
||||
class Console : public GUI::Debugger {
|
||||
public:
|
||||
Console(NeverhoodEngine *vm);
|
||||
~Console(void) override;
|
||||
|
||||
private:
|
||||
NeverhoodEngine *_vm;
|
||||
|
||||
bool Cmd_Scene(int argc, const char **argv);
|
||||
bool Cmd_Surfaces(int argc, const char **argv);
|
||||
bool Cmd_Cheat(int argc, const char **argv);
|
||||
bool Cmd_Dumpvars(int argc, const char **argv);
|
||||
bool Cmd_PlaySound(int argc, const char **argv);
|
||||
bool Cmd_CheckResource(int argc, const char **argv);
|
||||
bool Cmd_DumpResource(int argc, const char **argv);
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
#endif
|
||||
4
engines/neverhood/credits.pl
Normal file
4
engines/neverhood/credits.pl
Normal file
@@ -0,0 +1,4 @@
|
||||
begin_section("Neverhood");
|
||||
add_person("Benjamin Haisch", "john_doe", "");
|
||||
add_person("Filippos Karapetis", "bluegr", "");
|
||||
end_section();
|
||||
164
engines/neverhood/detection.cpp
Normal file
164
engines/neverhood/detection.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "base/plugins.h"
|
||||
|
||||
#include "engines/advancedDetector.h"
|
||||
#include "common/file.h"
|
||||
|
||||
#include "neverhood/detection.h"
|
||||
|
||||
static const PlainGameDescriptor neverhoodGames[] = {
|
||||
{"neverhood", "The Neverhood"},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const ADGameDescription gameDescriptions[] = {
|
||||
|
||||
// Neverhood English version
|
||||
{
|
||||
"neverhood",
|
||||
nullptr,
|
||||
AD_ENTRY1s("hd.blb", "22958d968458c9ff221aee38577bb2b2", 4279716),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformWindows,
|
||||
ADGF_DROPPLATFORM,
|
||||
GUIO1(GUIO_NONE)
|
||||
},
|
||||
|
||||
// Neverhood English big demo version
|
||||
{
|
||||
"neverhood",
|
||||
"Big Demo",
|
||||
AD_ENTRY1s("nevdemo.blb", "e637221d296f9a25ff22eaed96b07519", 117274189),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformWindows,
|
||||
GF_BIG_DEMO | ADGF_DEMO | ADGF_DROPPLATFORM,
|
||||
GUIO1(GUIO_NONE)
|
||||
},
|
||||
|
||||
// Neverhood English demo version
|
||||
{
|
||||
"neverhood",
|
||||
"Demo",
|
||||
AD_ENTRY1s("nevdemo.blb", "05b735cfb1086892bec79b54dca5545b", 22564568),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformWindows,
|
||||
ADGF_DEMO | ADGF_DROPPLATFORM,
|
||||
GUIO1(GUIO_NONE)
|
||||
},
|
||||
|
||||
// Neverhood earlier English demo version
|
||||
{
|
||||
"neverhood",
|
||||
"Demo",
|
||||
AD_ENTRY1s("nevdemo.blb", "9cbc33bc8ebacacfc8071f3e26a9c85f", 22357020),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformWindows,
|
||||
ADGF_DEMO | ADGF_DROPPLATFORM,
|
||||
GUIO1(GUIO_NONE)
|
||||
},
|
||||
|
||||
// Neverhood lite English demo version
|
||||
{
|
||||
"neverhood",
|
||||
"Demo",
|
||||
AD_ENTRY1s("nevdemo.blb", "816741610771f6434a673b6821e88899", 11986100),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformWindows,
|
||||
ADGF_DEMO | ADGF_DROPPLATFORM,
|
||||
GUIO1(GUIO_NONE)
|
||||
},
|
||||
|
||||
// Neverhood Russian version. Dyadyushka Risech
|
||||
{
|
||||
"neverhood",
|
||||
"DR",
|
||||
AD_ENTRY1s("hd.blb", "787951bf094aad9962291e69a707bdde", 4248635),
|
||||
Common::RU_RUS,
|
||||
Common::kPlatformWindows,
|
||||
ADGF_DROPPLATFORM,
|
||||
GUIO1(GUIO_NONE)
|
||||
},
|
||||
|
||||
// Neverhood Russian version. Fargus
|
||||
{
|
||||
"neverhood",
|
||||
"Fargus",
|
||||
AD_ENTRY1s("hd.blb", "c87c69db423f560d3708e9de78751a7f", 4425816),
|
||||
Common::RU_RUS,
|
||||
Common::kPlatformWindows,
|
||||
ADGF_DROPPLATFORM,
|
||||
GUIO1(GUIO_NONE)
|
||||
},
|
||||
|
||||
// Alternative Neverhood Russian translation.
|
||||
{
|
||||
"neverhood",
|
||||
"Stream",
|
||||
AD_ENTRY1s("hd.blb", "1b6bfa33c5e9e7a7cc02964e9ea7a6f8", 4540208),
|
||||
Common::RU_RUS,
|
||||
Common::kPlatformWindows,
|
||||
ADGF_DROPPLATFORM,
|
||||
GUIO1(GUIO_NONE)
|
||||
},
|
||||
|
||||
// Neverhood Japanese version
|
||||
// Bugreport #11074
|
||||
{
|
||||
"neverhood",
|
||||
"",
|
||||
AD_ENTRY1s("hd.blb", "c791725bbbc23c0f8bf78eece4555565", 4308928),
|
||||
Common::JA_JPN,
|
||||
Common::kPlatformWindows,
|
||||
ADGF_DROPPLATFORM,
|
||||
GUIO1(GUIO_NONE)
|
||||
},
|
||||
|
||||
AD_TABLE_END_MARKER
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
|
||||
class NeverhoodMetaEngineDetection : public AdvancedMetaEngineDetection<ADGameDescription> {
|
||||
public:
|
||||
NeverhoodMetaEngineDetection() : AdvancedMetaEngineDetection(Neverhood::gameDescriptions, neverhoodGames) {
|
||||
_guiOptions = GUIO5(GUIO_NOMIDI, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_SKIP_HALL_OF_RECORDS,
|
||||
GAMEOPTION_SCALE_MAKING_OF_VIDEOS, GAMEOPTION_REPEAT_WILLIE_HINT);
|
||||
}
|
||||
|
||||
const char *getName() const override {
|
||||
return "neverhood";
|
||||
}
|
||||
|
||||
const char *getEngineName() const override {
|
||||
return "The Neverhood";
|
||||
}
|
||||
|
||||
const char *getOriginalCopyright() const override {
|
||||
return "The Neverhood (C) The Neverhood, Inc.";
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_PLUGIN_STATIC(NEVERHOOD_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, NeverhoodMetaEngineDetection);
|
||||
38
engines/neverhood/detection.h
Normal file
38
engines/neverhood/detection.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_DETECTION_H
|
||||
#define NEVERHOOD_DETECTION_H
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
enum NeverhoodGameFeatures {
|
||||
GF_BIG_DEMO = (1 << 0)
|
||||
};
|
||||
|
||||
#define GAMEOPTION_ORIGINAL_SAVELOAD GUIO_GAMEOPTIONS1
|
||||
#define GAMEOPTION_SKIP_HALL_OF_RECORDS GUIO_GAMEOPTIONS2
|
||||
#define GAMEOPTION_SCALE_MAKING_OF_VIDEOS GUIO_GAMEOPTIONS3
|
||||
#define GAMEOPTION_REPEAT_WILLIE_HINT GUIO_GAMEOPTIONS4
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif // NEVERHOOD_DETECTION_H
|
||||
170
engines/neverhood/dialogs.cpp
Normal file
170
engines/neverhood/dialogs.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/dialogs.h"
|
||||
|
||||
#include "gui/gui-manager.h"
|
||||
#include "gui/message.h"
|
||||
#include "gui/saveload.h"
|
||||
#include "gui/ThemeEval.h"
|
||||
#include "gui/widget.h"
|
||||
#include "gui/widgets/popup.h"
|
||||
|
||||
#include "common/system.h"
|
||||
#include "common/translation.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
NeverhoodOptionsWidget::NeverhoodOptionsWidget(GuiObject *boss, const Common::String &name, const Common::String &domain) :
|
||||
OptionsContainerWidget(boss, name, "NeverhoodGameOptionsDialog", domain),
|
||||
_originalSaveLoadCheckbox(nullptr),
|
||||
_skipHallOfRecordsCheckbox(nullptr),
|
||||
_scaleMakingOfVideosCheckbox(nullptr),
|
||||
_nhcPopUp(nullptr) {
|
||||
|
||||
_originalSaveLoadCheckbox = new GUI::CheckboxWidget(
|
||||
widgetsBoss(),
|
||||
"NeverhoodGameOptionsDialog.OriginalSaveLoad",
|
||||
_("Use original save/load screens"),
|
||||
_("Use the original save/load screens instead of the ScummVM ones"));
|
||||
|
||||
_skipHallOfRecordsCheckbox = new GUI::CheckboxWidget(
|
||||
widgetsBoss(),
|
||||
"NeverhoodGameOptionsDialog.SkipHallOfRecords", _("Skip the Hall of Records storyboard scenes"),
|
||||
_("Allows the player to skip past the Hall of Records storyboard scenes"));
|
||||
|
||||
_scaleMakingOfVideosCheckbox = new GUI::CheckboxWidget(
|
||||
widgetsBoss(),
|
||||
"NeverhoodGameOptionsDialog.ScaleMakingOfVideos", _("Scale the making of videos to full screen"),
|
||||
_("Scale the making of videos, so that they use the whole screen"));
|
||||
|
||||
_repeatWillieHint = new GUI::CheckboxWidget(
|
||||
widgetsBoss(),
|
||||
"NeverhoodGameOptionsDialog.RepeatWillieHint", _("Repeat useful Willie's hint"),
|
||||
_("Repeat actual useful hint by Willie"));
|
||||
|
||||
Common::FSDirectory dir(ConfMan.getPath("path", _domain));
|
||||
Common::Path extraPath(ConfMan.getPath("extrapath", _domain));
|
||||
Common::FSDirectory extraDir(extraPath);
|
||||
Common::Array<Common::FSDirectory *> langdirs = { &dir, dir.getSubDirectory("language") };
|
||||
if (!extraPath.empty()) {
|
||||
langdirs.push_back(&extraDir);
|
||||
langdirs.push_back(extraDir.getSubDirectory("language"));
|
||||
}
|
||||
_nhcFiles.push_back("");
|
||||
for (Common::Array<Common::FSDirectory *>::const_iterator langdir = langdirs.begin(); langdir != langdirs.end(); langdir++) {
|
||||
Common::ArchiveMemberList nhcFileList;
|
||||
if (!(*langdir))
|
||||
continue;
|
||||
(*langdir)->listMatchingMembers(nhcFileList, "*.nhc");
|
||||
|
||||
for (Common::ArchiveMemberList::iterator iter = nhcFileList.begin(); iter != nhcFileList.end(); ++iter) {
|
||||
Common::String nhcFileName = (*iter)->getName();
|
||||
nhcFileName.erase(nhcFileName.size() - 4); // remove .nhc extension
|
||||
_nhcFiles.push_back(nhcFileName);
|
||||
}
|
||||
}
|
||||
|
||||
if (_nhcFiles.size() > 1) {
|
||||
// I18N: NHC is a file extension
|
||||
GUI::StaticTextWidget *nhcCaption = new GUI::StaticTextWidget(widgetsBoss(), "NeverhoodGameOptionsDialog.NhcDesc", _("NHC replacement:"));
|
||||
nhcCaption->setAlign(Graphics::kTextAlignRight);
|
||||
|
||||
_nhcPopUp = new GUI::PopUpWidget(widgetsBoss(), "NeverhoodGameOptionsDialog.Nhc");
|
||||
|
||||
for (uint i = 0; i < _nhcFiles.size(); i++)
|
||||
_nhcPopUp->appendEntry(_nhcFiles[i].empty() ? _("<original>") : Common::U32String(_nhcFiles[i]), i);
|
||||
}
|
||||
}
|
||||
|
||||
NeverhoodOptionsWidget::~NeverhoodOptionsWidget() {
|
||||
}
|
||||
|
||||
void NeverhoodOptionsWidget::defineLayout(GUI::ThemeEval &layouts, const Common::String &layoutName, const Common::String &overlayedLayout) const {
|
||||
layouts.addDialog(layoutName, overlayedLayout)
|
||||
.addLayout(GUI::ThemeLayout::kLayoutVertical)
|
||||
.addPadding(0, 0, 0, 0)
|
||||
.addWidget("OriginalSaveLoad", "Checkbox")
|
||||
.addWidget("SkipHallOfRecords", "Checkbox")
|
||||
.addWidget("ScaleMakingOfVideos", "Checkbox")
|
||||
.addWidget("RepeatWillieHint", "Checkbox")
|
||||
.addLayout(GUI::ThemeLayout::kLayoutHorizontal)
|
||||
.addPadding(0, 0, 0, 0)
|
||||
.addWidget("NhcDesc", "OptionsLabel")
|
||||
.addWidget("Nhc", "PopUp")
|
||||
.closeLayout()
|
||||
.closeLayout()
|
||||
.closeDialog();
|
||||
}
|
||||
|
||||
void NeverhoodOptionsWidget::load() {
|
||||
if (_originalSaveLoadCheckbox) {
|
||||
_originalSaveLoadCheckbox->setState(ConfMan.getBool("originalsaveload", _domain));
|
||||
}
|
||||
|
||||
if (_skipHallOfRecordsCheckbox) {
|
||||
_skipHallOfRecordsCheckbox->setState(ConfMan.getBool("skiphallofrecordsscenes", _domain));
|
||||
}
|
||||
|
||||
if (_scaleMakingOfVideosCheckbox) {
|
||||
_scaleMakingOfVideosCheckbox->setState(ConfMan.getBool("scalemakingofvideos", _domain));
|
||||
}
|
||||
|
||||
if (_repeatWillieHint) {
|
||||
_repeatWillieHint->setState(ConfMan.getBool("repeatwilliehint", _domain));
|
||||
}
|
||||
|
||||
if (_nhcPopUp) {
|
||||
Common::String nhcFile(ConfMan.get("nhc_file", _domain));
|
||||
for (uint i = 0; i < _nhcFiles.size(); i++)
|
||||
if (_nhcFiles[i].equalsIgnoreCase(nhcFile))
|
||||
_nhcPopUp->setSelectedTag(i);
|
||||
}
|
||||
}
|
||||
|
||||
bool NeverhoodOptionsWidget::save() {
|
||||
if (_originalSaveLoadCheckbox) {
|
||||
ConfMan.setBool("originalsaveload", _originalSaveLoadCheckbox->getState(), _domain);
|
||||
}
|
||||
|
||||
if (_skipHallOfRecordsCheckbox) {
|
||||
ConfMan.setBool("skiphallofrecordsscenes", _skipHallOfRecordsCheckbox->getState(), _domain);
|
||||
}
|
||||
|
||||
if (_scaleMakingOfVideosCheckbox) {
|
||||
ConfMan.setBool("scalemakingofvideos", _scaleMakingOfVideosCheckbox->getState(), _domain);
|
||||
}
|
||||
|
||||
if (_repeatWillieHint) {
|
||||
ConfMan.setBool("repeatwilliehint", _repeatWillieHint->getState(), _domain);
|
||||
}
|
||||
|
||||
if (_nhcPopUp) {
|
||||
uint32 selectedNhcFile = _nhcPopUp->getSelectedTag();
|
||||
if (selectedNhcFile < _nhcFiles.size())
|
||||
ConfMan.set("nhc_file", _nhcFiles[selectedNhcFile], _domain);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
68
engines/neverhood/dialogs.h
Normal file
68
engines/neverhood/dialogs.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_DIALOGS_H
|
||||
#define NEVERHOOD_DIALOGS_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
|
||||
#include "common/events.h"
|
||||
#include "common/str.h"
|
||||
#include "common/ustr.h"
|
||||
|
||||
#include "engines/dialogs.h"
|
||||
|
||||
#include "gui/dialog.h"
|
||||
#include "gui/widget.h"
|
||||
|
||||
namespace GUI {
|
||||
class PopUpWidget;
|
||||
}
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class NeverhoodEngine;
|
||||
|
||||
class NeverhoodOptionsWidget : public GUI::OptionsContainerWidget {
|
||||
public:
|
||||
NeverhoodOptionsWidget(GuiObject *boss, const Common::String &name, const Common::String &domain);
|
||||
~NeverhoodOptionsWidget() override;
|
||||
|
||||
// OptionsContainerWidget API
|
||||
void load() override;
|
||||
bool save() override;
|
||||
|
||||
private:
|
||||
// OptionsContainerWidget API
|
||||
void defineLayout(GUI::ThemeEval &layouts, const Common::String &layoutName, const Common::String &overlayedLayout) const override;
|
||||
|
||||
GUI::CheckboxWidget *_originalSaveLoadCheckbox;
|
||||
GUI::CheckboxWidget *_skipHallOfRecordsCheckbox;
|
||||
GUI::CheckboxWidget *_scaleMakingOfVideosCheckbox;
|
||||
GUI::CheckboxWidget *_repeatWillieHint;
|
||||
|
||||
GUI::PopUpWidget *_nhcPopUp;
|
||||
Common::StringArray _nhcFiles;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif
|
||||
520
engines/neverhood/diskplayerscene.cpp
Normal file
520
engines/neverhood/diskplayerscene.cpp
Normal file
@@ -0,0 +1,520 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/diskplayerscene.h"
|
||||
#include "neverhood/mouse.h"
|
||||
#include "neverhood/smackerplayer.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kDiskplayerPaletteFileHashes[] = {
|
||||
0x03B78240,
|
||||
0x34B32B08,
|
||||
0x4F2569D4,
|
||||
0x07620590,
|
||||
0x38422401
|
||||
};
|
||||
|
||||
static const byte kDiskplayerInitArray[] = {
|
||||
2, 1, 4, 5, 3, 11, 8, 6, 7, 9, 10, 17, 16, 18, 19, 20, 15, 14, 13, 12
|
||||
};
|
||||
|
||||
static const uint32 kDiskplayerSmackerFileHashes[] = {
|
||||
0x010A2810,
|
||||
0x020A2810,
|
||||
0x040A2810,
|
||||
0x080A2810,
|
||||
0x100A2810,
|
||||
0x200A2810,
|
||||
0x400A2810,
|
||||
0x800A2810,
|
||||
0x000A2811,
|
||||
0x010C2810,
|
||||
0x020C2810,
|
||||
0x040C2810,
|
||||
0x080C2810,
|
||||
0x100C2810,
|
||||
0x200C2810,
|
||||
0x400C2810,
|
||||
0x800C2810,
|
||||
0x000C2811,
|
||||
0x000C2812,
|
||||
0x02002810,
|
||||
0x04002810
|
||||
};
|
||||
|
||||
static const uint32 kDiskplayerSlotFileHashes1[] = {
|
||||
0x81312280,
|
||||
0x01312281,
|
||||
0x01312282,
|
||||
0x01312284,
|
||||
0x01312288,
|
||||
0x01312290,
|
||||
0x013122A0,
|
||||
0x013122C0,
|
||||
0x01312200,
|
||||
0x82312280,
|
||||
0x02312281,
|
||||
0x02312282,
|
||||
0x02312284,
|
||||
0x02312288,
|
||||
0x02312290,
|
||||
0x023122A0,
|
||||
0x023122C0,
|
||||
0x02312200,
|
||||
0x02312380,
|
||||
0x04312281
|
||||
};
|
||||
|
||||
static const uint32 kDiskplayerSlotFileHashes2[] = {
|
||||
0x90443A00,
|
||||
0x90443A18,
|
||||
0x90443A28,
|
||||
0x90443A48,
|
||||
0x90443A88,
|
||||
0x90443B08,
|
||||
0x90443808,
|
||||
0x90443E08,
|
||||
0x90443208,
|
||||
0xA0443A00,
|
||||
0xA0443A18,
|
||||
0xA0443A28,
|
||||
0xA0443A48,
|
||||
0xA0443A88,
|
||||
0xA0443B08,
|
||||
0xA0443808,
|
||||
0xA0443E08,
|
||||
0xA0443208,
|
||||
0xA0442A08,
|
||||
0xC0443A18
|
||||
};
|
||||
|
||||
static const uint32 kDiskplayerSlotFileHashes3[] = {
|
||||
0x10357320,
|
||||
0x10557320,
|
||||
0x10957320,
|
||||
0x11157320,
|
||||
0x12157320,
|
||||
0x14157320,
|
||||
0x18157320,
|
||||
0x00157320,
|
||||
0x30157320,
|
||||
0x1035B320,
|
||||
0x1055B320,
|
||||
0x1095B320,
|
||||
0x1115B320,
|
||||
0x1215B320,
|
||||
0x1415B320,
|
||||
0x1815B320,
|
||||
0x0015B320,
|
||||
0x3015B320,
|
||||
0x5015B320,
|
||||
0x10543320
|
||||
};
|
||||
|
||||
static const uint32 kDiskplayerSlotFileHashes4[] = {
|
||||
0xDC8020E4,
|
||||
0xDC802164,
|
||||
0xDC802264,
|
||||
0xDC802464,
|
||||
0xDC802864,
|
||||
0xDC803064,
|
||||
0xDC800064,
|
||||
0xDC806064,
|
||||
0xDC80A064,
|
||||
0xDC8020E7,
|
||||
0xDC802167,
|
||||
0xDC802267,
|
||||
0xDC802467,
|
||||
0xDC802867,
|
||||
0xDC803067,
|
||||
0xDC800067,
|
||||
0xDC806067,
|
||||
0xDC80A067,
|
||||
0xDC812067,
|
||||
0xDC802161
|
||||
};
|
||||
|
||||
AsDiskplayerSceneKey::AsDiskplayerSceneKey(NeverhoodEngine *vm)
|
||||
: AnimatedSprite(vm, 1100) {
|
||||
|
||||
createSurface1(0x100B90B4, 1200);
|
||||
_x = 211;
|
||||
_y = 195;
|
||||
startAnimation(0x100B90B4, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
_needRefresh = true;
|
||||
updatePosition();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
uint32 AsDiskplayerSceneKey::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsDiskplayerSceneKey::stDropKey() {
|
||||
startAnimation(0x100B90B4, 0, -1);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsDiskplayerSceneKey::handleMessage);
|
||||
NextState(&AsDiskplayerSceneKey::stDropKeyDone);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
void AsDiskplayerSceneKey::stDropKeyDone() {
|
||||
stopAnimation();
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&Sprite::handleMessage);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
DiskplayerPlayButton::DiskplayerPlayButton(NeverhoodEngine *vm, DiskplayerScene *diskplayerScene)
|
||||
: StaticSprite(vm, 1400), _diskplayerScene(diskplayerScene), _isPlaying(false) {
|
||||
|
||||
loadSprite(0x24A4A664, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
|
||||
setVisible(false);
|
||||
loadSound(0, 0x44043000);
|
||||
loadSound(1, 0x44045000);
|
||||
SetMessageHandler(&DiskplayerPlayButton::handleMessage);
|
||||
}
|
||||
|
||||
uint32 DiskplayerPlayButton::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = 0;
|
||||
Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (!_diskplayerScene->getDropKey()) {
|
||||
if (_isPlaying) {
|
||||
sendMessage(_diskplayerScene, 0x2001, 0);
|
||||
release();
|
||||
} else {
|
||||
sendMessage(_diskplayerScene, 0x2000, 0);
|
||||
press();
|
||||
}
|
||||
}
|
||||
updatePosition();
|
||||
messageResult = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void DiskplayerPlayButton::press() {
|
||||
if (!_isPlaying) {
|
||||
setVisible(true);
|
||||
updatePosition();
|
||||
playSound(0);
|
||||
_isPlaying = true;
|
||||
}
|
||||
}
|
||||
|
||||
void DiskplayerPlayButton::release() {
|
||||
if (_isPlaying) {
|
||||
setVisible(false);
|
||||
updatePosition();
|
||||
playSound(1);
|
||||
_isPlaying = false;
|
||||
}
|
||||
}
|
||||
|
||||
DiskplayerSlot::DiskplayerSlot(NeverhoodEngine *vm, DiskplayerScene *diskplayerScene, int slotIndex, bool isAvailable)
|
||||
: Entity(vm, 0), _diskplayerScene(diskplayerScene), _isLocked(false), _isBlinking(false),
|
||||
_blinkCountdown(0), _initialBlinkCountdown(2), _inactiveSlot(nullptr), _appearSlot(nullptr), _activeSlot(nullptr) {
|
||||
|
||||
if (isAvailable && slotIndex < 20) {
|
||||
_inactiveSlot = _diskplayerScene->addSprite(new StaticSprite(_vm, kDiskplayerSlotFileHashes1[slotIndex], 1100));
|
||||
_appearSlot = _diskplayerScene->addSprite(new StaticSprite(_vm, kDiskplayerSlotFileHashes2[slotIndex], 1000));
|
||||
_activeSlot = _diskplayerScene->addSprite(new StaticSprite(_vm, kDiskplayerSlotFileHashes3[slotIndex], 1100));
|
||||
_inactiveSlot->setVisible(false);
|
||||
_appearSlot->setVisible(false);
|
||||
_activeSlot->setVisible(false);
|
||||
loadSound(0, 0x46210074);
|
||||
setSoundPan(0, slotIndex * 100 / 19);
|
||||
} else if (slotIndex != 20) {
|
||||
_activeSlot = _diskplayerScene->addSprite(new StaticSprite(_vm, kDiskplayerSlotFileHashes4[slotIndex], 1100));
|
||||
_activeSlot->setVisible(false);
|
||||
}
|
||||
SetUpdateHandler(&DiskplayerSlot::update);
|
||||
}
|
||||
|
||||
void DiskplayerSlot::update() {
|
||||
if (_blinkCountdown != 0 && (--_blinkCountdown == 0)) {
|
||||
if (_isBlinking) {
|
||||
if (_inactiveSlot)
|
||||
_inactiveSlot->setVisible(true);
|
||||
if (_activeSlot)
|
||||
_activeSlot->setVisible(false);
|
||||
_blinkCountdown = _initialBlinkCountdown / 2;
|
||||
} else {
|
||||
if (_inactiveSlot)
|
||||
_inactiveSlot->setVisible(false);
|
||||
if (_activeSlot)
|
||||
_activeSlot->setVisible(true);
|
||||
_blinkCountdown = _initialBlinkCountdown;
|
||||
}
|
||||
_isBlinking = !_isBlinking;
|
||||
}
|
||||
}
|
||||
|
||||
void DiskplayerSlot::appear() {
|
||||
if (_inactiveSlot)
|
||||
_inactiveSlot->setVisible(true);
|
||||
if (_appearSlot)
|
||||
_appearSlot->setVisible(true);
|
||||
if (_inactiveSlot)
|
||||
playSound(0);
|
||||
}
|
||||
|
||||
void DiskplayerSlot::play() {
|
||||
if (!_isLocked) {
|
||||
if (_inactiveSlot)
|
||||
_inactiveSlot->setVisible(false);
|
||||
if (_activeSlot)
|
||||
_activeSlot->setVisible(true);
|
||||
_isBlinking = true;
|
||||
_blinkCountdown = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void DiskplayerSlot::activate() {
|
||||
if (!_isLocked)
|
||||
_blinkCountdown = _initialBlinkCountdown;
|
||||
}
|
||||
|
||||
void DiskplayerSlot::stop() {
|
||||
if (!_isLocked) {
|
||||
if (_inactiveSlot)
|
||||
_inactiveSlot->setVisible(true);
|
||||
if (_activeSlot)
|
||||
_activeSlot->setVisible(false);
|
||||
_isBlinking = false;
|
||||
_blinkCountdown = 0;
|
||||
}
|
||||
}
|
||||
|
||||
DiskplayerScene::DiskplayerScene(NeverhoodEngine *vm, Module *parentModule, int paletteIndex)
|
||||
: Scene(vm, parentModule), _diskIndex(0), _appearCountdown(0), _tuneInCountdown(0),
|
||||
_hasAllDisks(false), _dropKey(false), _inputDisabled(true), _updateStatus(kUSStopped) {
|
||||
|
||||
int availableDisksCount = 0;
|
||||
|
||||
setBackground(0x8A000044);
|
||||
setPalette(kDiskplayerPaletteFileHashes[paletteIndex]);
|
||||
|
||||
_ssPlayButton = insertSprite<DiskplayerPlayButton>(this);
|
||||
addCollisionSprite(_ssPlayButton);
|
||||
|
||||
_asKey = insertSprite<AsDiskplayerSceneKey>();
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
_diskAvailable[i] = false;
|
||||
if (getSubVar(VA_IS_TAPE_INSERTED, i))
|
||||
availableDisksCount++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < availableDisksCount; i++)
|
||||
_diskAvailable[kDiskplayerInitArray[i] - 1] = true;
|
||||
|
||||
for (int slotIndex = 0; slotIndex < 20; slotIndex++) {
|
||||
_diskSlots[slotIndex] = new DiskplayerSlot(_vm, this, slotIndex, _diskAvailable[slotIndex]);
|
||||
addEntity(_diskSlots[slotIndex]);
|
||||
}
|
||||
|
||||
_hasAllDisks = availableDisksCount == 20;
|
||||
|
||||
if (_hasAllDisks && !getGlobalVar(V_HAS_FINAL_KEY))
|
||||
_dropKey = true;
|
||||
|
||||
_finalDiskSlot = new DiskplayerSlot(_vm, this, 20, false);
|
||||
addEntity(_finalDiskSlot);
|
||||
|
||||
insertPuzzleMouse(0x000408A8, 20, 620);
|
||||
showMouse(false);
|
||||
|
||||
_diskSmackerPlayer = addSmackerPlayer(new SmackerPlayer(_vm, this, 0x08288103, false, true));
|
||||
_diskSmackerPlayer->setDrawPos(154, 86);
|
||||
_vm->_screen->setSmackerDecoder(_diskSmackerPlayer->getSmackerDecoder());
|
||||
|
||||
_palette->usePalette();
|
||||
|
||||
SetMessageHandler(&DiskplayerScene::handleMessage);
|
||||
SetUpdateHandler(&DiskplayerScene::update);
|
||||
_appearCountdown = 6;
|
||||
|
||||
}
|
||||
|
||||
void DiskplayerScene::update() {
|
||||
Scene::update();
|
||||
|
||||
if (_updateStatus == kUSTuningIn && _diskSmackerPlayer->isDone()) {
|
||||
if (_diskAvailable[_diskIndex])
|
||||
playDisk();
|
||||
else
|
||||
playStatic();
|
||||
} else if (_updateStatus == kUSPlaying && _diskSmackerPlayer->isDone()) {
|
||||
_diskSlots[_diskIndex]->stop();
|
||||
_diskIndex++;
|
||||
if (_hasAllDisks) {
|
||||
if (_diskIndex != 20) {
|
||||
playDisk();
|
||||
} else if (_dropKey) {
|
||||
playDisk();
|
||||
_updateStatus = kUSPlayingFinal;
|
||||
} else {
|
||||
_diskIndex = 0;
|
||||
stop();
|
||||
}
|
||||
} else if (_diskIndex != 20) {
|
||||
tuneIn();
|
||||
} else {
|
||||
_diskIndex = 0;
|
||||
stop();
|
||||
}
|
||||
} else if (_updateStatus == kUSPlayingFinal) {
|
||||
if (_diskSmackerPlayer->getFrameNumber() == 133) {
|
||||
_asKey->stDropKey();
|
||||
setGlobalVar(V_HAS_FINAL_KEY, 1);
|
||||
} else if (_diskSmackerPlayer->isDone()) {
|
||||
for (int i = 0; i < 20; i++) {
|
||||
_diskSlots[i]->setLocked(false);
|
||||
_diskSlots[i]->stop();
|
||||
}
|
||||
_diskIndex = 0;
|
||||
stop();
|
||||
showMouse(true);
|
||||
_dropKey = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_appearCountdown != 0 && (--_appearCountdown == 0)) {
|
||||
_diskSlots[_diskIndex]->appear();
|
||||
if (_dropKey) {
|
||||
_diskSlots[_diskIndex]->activate();
|
||||
_diskSlots[_diskIndex]->setLocked(true);
|
||||
}
|
||||
_diskIndex++;
|
||||
while (!_diskAvailable[_diskIndex] && _diskIndex < 19)
|
||||
_diskIndex++;
|
||||
if (_diskIndex < 20) {
|
||||
_appearCountdown = 1;
|
||||
} else {
|
||||
_diskIndex = 0;
|
||||
_inputDisabled = false;
|
||||
if (_dropKey) {
|
||||
_ssPlayButton->press();
|
||||
_tuneInCountdown = 2;
|
||||
} else {
|
||||
showMouse(true);
|
||||
_diskSlots[_diskIndex]->activate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_tuneInCountdown != 0 && (--_tuneInCountdown == 0))
|
||||
playDisk();
|
||||
|
||||
}
|
||||
|
||||
uint32 DiskplayerScene::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
if (!_inputDisabled) {
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
|
||||
sendMessage(_parentModule, 0x1009, 0);
|
||||
} else if (!_dropKey &&
|
||||
param.asPoint().x > 38 && param.asPoint().x < 598 &&
|
||||
param.asPoint().y > 400 && param.asPoint().y < 460) {
|
||||
|
||||
_diskSlots[_diskIndex]->stop();
|
||||
_diskIndex = (param.asPoint().x - 38) / 28;
|
||||
_diskSlots[_diskIndex]->activate();
|
||||
if (_updateStatus == kUSPlaying) {
|
||||
if (_diskAvailable[_diskIndex])
|
||||
playDisk();
|
||||
else
|
||||
playStatic();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_CHEAT:
|
||||
if (param.asInteger() == 0x2C034A29 && !_dropKey && !_hasAllDisks) { // "itsshowtime"
|
||||
for (uint i = 0; i < 20; i++)
|
||||
setSubVar(VA_HAS_TAPE, i, 1);
|
||||
sendMessage(_parentModule, 0x1009, 0);
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
tuneIn();
|
||||
break;
|
||||
case 0x2001:
|
||||
stop();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DiskplayerScene::openSmacker(uint32 fileHash, bool keepLastFrame) {
|
||||
_diskSmackerPlayer->open(fileHash, keepLastFrame);
|
||||
_vm->_screen->setSmackerDecoder(_diskSmackerPlayer->getSmackerDecoder());
|
||||
_palette->usePalette();
|
||||
}
|
||||
|
||||
void DiskplayerScene::stop() {
|
||||
openSmacker(0x08288103, true);
|
||||
_ssPlayButton->release();
|
||||
_updateStatus = kUSStopped;
|
||||
_diskSlots[_diskIndex]->activate();
|
||||
}
|
||||
|
||||
void DiskplayerScene::tuneIn() {
|
||||
openSmacker(0x900001C1, false);
|
||||
_ssPlayButton->release();
|
||||
_updateStatus = kUSTuningIn;
|
||||
_diskSlots[_diskIndex]->activate();
|
||||
}
|
||||
|
||||
void DiskplayerScene::playDisk() {
|
||||
openSmacker(kDiskplayerSmackerFileHashes[_diskIndex], false);
|
||||
_updateStatus = kUSPlaying;
|
||||
_diskSlots[_diskIndex]->play();
|
||||
}
|
||||
|
||||
void DiskplayerScene::playStatic() {
|
||||
openSmacker(0x90000101, false);
|
||||
_ssPlayButton->release();
|
||||
_updateStatus = kUSPlaying;
|
||||
_diskSlots[_diskIndex]->activate();
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
110
engines/neverhood/diskplayerscene.h
Normal file
110
engines/neverhood/diskplayerscene.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_DISKPLAYERSCENE_H
|
||||
#define NEVERHOOD_DISKPLAYERSCENE_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/resourceman.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class DiskplayerScene;
|
||||
class SmackerPlayer;
|
||||
|
||||
class AsDiskplayerSceneKey : public AnimatedSprite {
|
||||
public:
|
||||
AsDiskplayerSceneKey(NeverhoodEngine *vm);
|
||||
void stDropKey();
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stDropKeyDone();
|
||||
};
|
||||
|
||||
class DiskplayerPlayButton : public StaticSprite {
|
||||
public:
|
||||
DiskplayerPlayButton(NeverhoodEngine *vm, DiskplayerScene *diskplayerScene);
|
||||
void press();
|
||||
void release();
|
||||
protected:
|
||||
DiskplayerScene *_diskplayerScene;
|
||||
bool _isPlaying;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class DiskplayerSlot : public Entity {
|
||||
public:
|
||||
DiskplayerSlot(NeverhoodEngine *vm, DiskplayerScene *diskplayerScene, int slotIndex, bool isAvailable);
|
||||
void activate();
|
||||
void stop();
|
||||
void appear();
|
||||
void play();
|
||||
void setLocked(bool isLocked) { _isLocked = isLocked; }
|
||||
protected:
|
||||
DiskplayerScene *_diskplayerScene;
|
||||
Sprite *_inactiveSlot;
|
||||
Sprite *_appearSlot;
|
||||
Sprite *_activeSlot;
|
||||
int _initialBlinkCountdown;
|
||||
int _blinkCountdown;
|
||||
bool _isLocked;
|
||||
bool _isBlinking;
|
||||
void update();
|
||||
};
|
||||
|
||||
enum {
|
||||
kUSStopped = 0,
|
||||
kUSTuningIn = 1,
|
||||
kUSPlaying = 2,
|
||||
kUSPlayingFinal = 3
|
||||
};
|
||||
|
||||
class DiskplayerScene : public Scene {
|
||||
public:
|
||||
DiskplayerScene(NeverhoodEngine *vm, Module *parentModule, int paletteIndex);
|
||||
bool getDropKey() const { return _dropKey; }
|
||||
protected:
|
||||
SmackerPlayer *_diskSmackerPlayer;
|
||||
DiskplayerPlayButton *_ssPlayButton;
|
||||
AsDiskplayerSceneKey *_asKey;
|
||||
DiskplayerSlot *_diskSlots[20];
|
||||
DiskplayerSlot *_finalDiskSlot;
|
||||
int _updateStatus;
|
||||
bool _diskAvailable[20];
|
||||
int _diskIndex;
|
||||
int _appearCountdown;
|
||||
int _tuneInCountdown;
|
||||
bool _hasAllDisks;
|
||||
bool _inputDisabled;
|
||||
bool _dropKey;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void openSmacker(uint32 fileHash, bool keepLastFrame);
|
||||
void stop();
|
||||
void tuneIn();
|
||||
void playDisk();
|
||||
void playStatic();
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_DISKPLAYERSCENE_H */
|
||||
158
engines/neverhood/entity.cpp
Normal file
158
engines/neverhood/entity.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/entity.h"
|
||||
#include "neverhood/sound.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
uint32 MessageParam::asInteger() const {
|
||||
assert(_type == mptInteger);
|
||||
return _integer;
|
||||
}
|
||||
|
||||
NPoint MessageParam::asPoint() const {
|
||||
assert(_type == mptInteger || _type == mptPoint);
|
||||
if (_type == mptInteger) {
|
||||
NPoint pt;
|
||||
pt.x = _integer & 0xFFFF;
|
||||
pt.y = (_integer >> 16) & 0xFFFF;
|
||||
return pt;
|
||||
}
|
||||
return _point;
|
||||
}
|
||||
|
||||
Entity *MessageParam::asEntity() const {
|
||||
assert(_type == mptEntity);
|
||||
return _entity;
|
||||
}
|
||||
|
||||
Entity::Entity(NeverhoodEngine *vm, int priority)
|
||||
: _vm(vm), _updateHandlerCb(nullptr), _messageHandlerCb(nullptr), _priority(priority), _soundResources(nullptr) {
|
||||
}
|
||||
|
||||
Entity::~Entity() {
|
||||
deleteSoundResources();
|
||||
}
|
||||
|
||||
void Entity::draw() {
|
||||
// Empty
|
||||
}
|
||||
|
||||
void Entity::handleUpdate() {
|
||||
debug(5, "handleUpdate() -> [%s]", _updateHandlerCbName.c_str());
|
||||
if (_updateHandlerCb)
|
||||
(this->*_updateHandlerCb)();
|
||||
}
|
||||
|
||||
uint32 Entity::receiveMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
debug(5, "receiveMessage(%04X) -> [%s]", messageNum, _messageHandlerCbName.c_str());
|
||||
return _messageHandlerCb ? (this->*_messageHandlerCb)(messageNum, param, sender) : 0;
|
||||
}
|
||||
|
||||
uint32 Entity::sendMessage(Entity *receiver, int messageNum, const MessageParam ¶m) {
|
||||
return receiver ? receiver->receiveMessage(messageNum, param, this) : 0;
|
||||
}
|
||||
|
||||
uint32 Entity::sendMessage(Entity *receiver, int messageNum, uint32 param) {
|
||||
return sendMessage(receiver, messageNum, MessageParam(param));
|
||||
}
|
||||
|
||||
uint32 Entity::sendPointMessage(Entity *receiver, int messageNum, const NPoint ¶m) {
|
||||
return sendMessage(receiver, messageNum, MessageParam(param));
|
||||
}
|
||||
|
||||
uint32 Entity::sendEntityMessage(Entity *receiver, int messageNum, Entity *param) {
|
||||
return sendMessage(receiver, messageNum, MessageParam((Entity*)param));
|
||||
}
|
||||
|
||||
uint32 Entity::getGlobalVar(uint32 nameHash) {
|
||||
return _vm->_gameVars->getGlobalVar(nameHash);
|
||||
}
|
||||
|
||||
void Entity::setGlobalVar(uint32 nameHash, uint32 value) {
|
||||
_vm->_gameVars->setGlobalVar(nameHash, value);
|
||||
}
|
||||
|
||||
uint32 Entity::getSubVar(uint32 nameHash, uint32 subNameHash) {
|
||||
return _vm->_gameVars->getSubVar(nameHash, subNameHash);
|
||||
}
|
||||
|
||||
void Entity::setSubVar(uint32 nameHash, uint32 subNameHash, uint32 value) {
|
||||
_vm->_gameVars->setSubVar(nameHash, subNameHash, value);
|
||||
}
|
||||
|
||||
void Entity::incGlobalVar(uint32 nameHash, int incrValue) {
|
||||
setGlobalVar(nameHash, getGlobalVar(nameHash) + incrValue);
|
||||
}
|
||||
|
||||
void Entity::incSubVar(uint32 nameHash, uint32 subNameHash, int incrValue) {
|
||||
setSubVar(nameHash, subNameHash, getSubVar(nameHash, subNameHash) + incrValue);
|
||||
}
|
||||
|
||||
SoundResource *Entity::getSoundResource(uint index) {
|
||||
assert(index < kMaxSoundResources);
|
||||
if (!_soundResources) {
|
||||
_soundResources = new SoundResource*[kMaxSoundResources];
|
||||
for (uint i = 0; i < kMaxSoundResources; ++i)
|
||||
_soundResources[i] = nullptr;
|
||||
}
|
||||
if (!_soundResources[index])
|
||||
_soundResources[index] = new SoundResource(_vm);
|
||||
return _soundResources[index];
|
||||
}
|
||||
|
||||
void Entity::loadSound(uint index, uint32 fileHash) {
|
||||
getSoundResource(index)->load(fileHash);
|
||||
}
|
||||
|
||||
void Entity::playSound(uint index, uint32 fileHash) {
|
||||
if (fileHash)
|
||||
getSoundResource(index)->play(fileHash);
|
||||
else
|
||||
getSoundResource(index)->play();
|
||||
}
|
||||
|
||||
void Entity::stopSound(uint index) {
|
||||
getSoundResource(index)->stop();
|
||||
}
|
||||
|
||||
bool Entity::isSoundPlaying(uint index) {
|
||||
return getSoundResource(index)->isPlaying();
|
||||
}
|
||||
|
||||
void Entity::setSoundVolume(uint index, int volume) {
|
||||
getSoundResource(index)->setVolume(volume);
|
||||
}
|
||||
|
||||
void Entity::setSoundPan(uint index, int pan) {
|
||||
getSoundResource(index)->setPan(pan);
|
||||
}
|
||||
|
||||
void Entity::deleteSoundResources() {
|
||||
if (_soundResources) {
|
||||
for (uint i = 0; i < kMaxSoundResources; ++i)
|
||||
delete _soundResources[i];
|
||||
delete[] _soundResources;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
119
engines/neverhood/entity.h
Normal file
119
engines/neverhood/entity.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_ENTITY_H
|
||||
#define NEVERHOOD_ENTITY_H
|
||||
|
||||
#include "common/str.h"
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/gamevars.h"
|
||||
#include "neverhood/graphics.h"
|
||||
#include "neverhood/sound.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Entity;
|
||||
class SoundResource;
|
||||
|
||||
enum MessageParamType {
|
||||
mptInteger,
|
||||
mptPoint,
|
||||
mptEntity
|
||||
};
|
||||
|
||||
struct MessageParam {
|
||||
public:
|
||||
MessageParam(uint32 value) : _type(mptInteger), _integer(value) {}
|
||||
MessageParam(NPoint value) : _type(mptPoint), _point(value) {}
|
||||
MessageParam(Entity *entity) : _type(mptEntity), _entity(entity) {}
|
||||
uint32 asInteger() const;
|
||||
NPoint asPoint() const;
|
||||
Entity *asEntity() const;
|
||||
protected:
|
||||
union {
|
||||
uint32 _integer;
|
||||
NPoint _point;
|
||||
Entity *_entity;
|
||||
};
|
||||
MessageParamType _type;
|
||||
};
|
||||
|
||||
// TODO: Disable heavy debug stuff in release mode
|
||||
|
||||
#define SetUpdateHandler(handler) \
|
||||
do { \
|
||||
_updateHandlerCb = static_cast <void (Entity::*)(void)> (handler); \
|
||||
debug(5, "SetUpdateHandler(" #handler ")"); \
|
||||
_updateHandlerCbName = #handler; \
|
||||
} while (0)
|
||||
|
||||
#define SetMessageHandler(handler) \
|
||||
do { \
|
||||
_messageHandlerCb = static_cast <uint32 (Entity::*)(int messageNum, const MessageParam ¶m, Entity *sender)> (handler); \
|
||||
debug(5, "SetMessageHandler(" #handler ")"); \
|
||||
_messageHandlerCbName = #handler; \
|
||||
} while (0)
|
||||
|
||||
const uint kMaxSoundResources = 16;
|
||||
|
||||
class Entity {
|
||||
public:
|
||||
Common::String _updateHandlerCbName;
|
||||
Common::String _messageHandlerCbName;
|
||||
Entity(NeverhoodEngine *vm, int priority);
|
||||
virtual ~Entity();
|
||||
virtual void draw();
|
||||
void handleUpdate();
|
||||
uint32 receiveMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
// NOTE: These were overloaded before for the various message parameter types
|
||||
// it caused some problems so each type gets its own sendMessage variant now
|
||||
uint32 sendMessage(Entity *receiver, int messageNum, const MessageParam ¶m);
|
||||
uint32 sendMessage(Entity *receiver, int messageNum, uint32 param);
|
||||
uint32 sendPointMessage(Entity *receiver, int messageNum, const NPoint ¶m);
|
||||
uint32 sendEntityMessage(Entity *receiver, int messageNum, Entity *param);
|
||||
// Shortcuts for game variable access
|
||||
uint32 getGlobalVar(uint32 nameHash);
|
||||
void setGlobalVar(uint32 nameHash, uint32 value);
|
||||
uint32 getSubVar(uint32 nameHash, uint32 subNameHash);
|
||||
void setSubVar(uint32 nameHash, uint32 subNameHash, uint32 value);
|
||||
void incGlobalVar(uint32 nameHash, int incrValue);
|
||||
void incSubVar(uint32 nameHash, uint32 subNameHash, int incrValue);
|
||||
int getPriority() const { return _priority; }
|
||||
bool hasMessageHandler() const { return _messageHandlerCb != nullptr; }
|
||||
protected:
|
||||
void (Entity::*_updateHandlerCb)();
|
||||
uint32 (Entity::*_messageHandlerCb)(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
NeverhoodEngine *_vm;
|
||||
int _priority;
|
||||
SoundResource **_soundResources;
|
||||
SoundResource *getSoundResource(uint index);
|
||||
void loadSound(uint index, uint32 fileHash);
|
||||
void playSound(uint index, uint32 fileHash = 0);
|
||||
void stopSound(uint index);
|
||||
bool isSoundPlaying(uint index);
|
||||
void setSoundVolume(uint index, int volume);
|
||||
void setSoundPan(uint index, int pan);
|
||||
void deleteSoundResources();
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_ENTITY_H */
|
||||
871
engines/neverhood/gamemodule.cpp
Normal file
871
engines/neverhood/gamemodule.cpp
Normal file
@@ -0,0 +1,871 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/gamemodule.h"
|
||||
|
||||
#include "neverhood/graphics.h"
|
||||
#include "neverhood/menumodule.h"
|
||||
#include "neverhood/modules/module1000.h"
|
||||
#include "neverhood/modules/module1100.h"
|
||||
#include "neverhood/modules/module1200.h"
|
||||
#include "neverhood/modules/module1300.h"
|
||||
#include "neverhood/modules/module1400.h"
|
||||
#include "neverhood/modules/module1500.h"
|
||||
#include "neverhood/modules/module1600.h"
|
||||
#include "neverhood/modules/module1700.h"
|
||||
#include "neverhood/modules/module1800.h"
|
||||
#include "neverhood/modules/module1900.h"
|
||||
#include "neverhood/modules/module2000.h"
|
||||
#include "neverhood/modules/module2100.h"
|
||||
#include "neverhood/modules/module2200.h"
|
||||
#include "neverhood/modules/module2300.h"
|
||||
#include "neverhood/modules/module2400.h"
|
||||
#include "neverhood/modules/module2500.h"
|
||||
#include "neverhood/modules/module2600.h"
|
||||
#include "neverhood/modules/module2700.h"
|
||||
#include "neverhood/modules/module2800.h"
|
||||
#include "neverhood/modules/module2900.h"
|
||||
#include "neverhood/modules/module3000.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kRadioMusicFileHashes[] = {
|
||||
0x82B22000,
|
||||
0x02B22004,
|
||||
0x42B22000,
|
||||
0x03322008,
|
||||
0x02B22001,
|
||||
0x02B22008,
|
||||
0x02B22020,
|
||||
0x03322001,
|
||||
0x03322002,
|
||||
0x03322004,
|
||||
0x03322040,
|
||||
0x02B22002,
|
||||
0x02B22010,
|
||||
0x03322010,
|
||||
0x02B22040,
|
||||
0x43322000,
|
||||
0x83322000,
|
||||
0x03322020
|
||||
};
|
||||
|
||||
enum {
|
||||
MENU_MODULE = 9999
|
||||
};
|
||||
|
||||
GameModule::GameModule(NeverhoodEngine *vm)
|
||||
: Module(vm, nullptr), _moduleNum(-1), _prevChildObject(nullptr), _prevModuleNum(-1),
|
||||
_restoreGameRequested(false), _restartGameRequested(false), _canRequestMainMenu(true),
|
||||
_mainMenuRequested(false) {
|
||||
|
||||
// Other initializations moved to actual engine class
|
||||
_vm->_soundMan->playSoundThree(0x002D0031, 0x08861079);
|
||||
SetMessageHandler(&GameModule::handleMessage);
|
||||
}
|
||||
|
||||
GameModule::~GameModule() {
|
||||
_vm->_soundMan->deleteSoundGroup(0x002D0031);
|
||||
delete _childObject;
|
||||
_childObject = nullptr;
|
||||
}
|
||||
|
||||
void GameModule::handleMouseMove(int16 x, int16 y) {
|
||||
if (_childObject) {
|
||||
NPoint mousePos;
|
||||
mousePos.x = x;
|
||||
mousePos.y = y;
|
||||
debug(2, "GameModule::handleMouseMove(%d, %d)", x, y);
|
||||
sendPointMessage(_childObject, NM_MOUSE_MOVE, mousePos);
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::handleMouseDown(int16 x, int16 y) {
|
||||
if (_childObject) {
|
||||
NPoint mousePos;
|
||||
mousePos.x = x;
|
||||
mousePos.y = y;
|
||||
debug(2, "GameModule::handleMouseDown(%d, %d)", x, y);
|
||||
sendPointMessage(_childObject, NM_MOUSE_CLICK, mousePos);
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::handleMouseUp(int16 x, int16 y) {
|
||||
if (_childObject) {
|
||||
NPoint mousePos;
|
||||
mousePos.x = x;
|
||||
mousePos.y = y;
|
||||
debug(2, "GameModule::handleMouseUp(%d, %d)", x, y);
|
||||
sendPointMessage(_childObject, NM_MOUSE_RELEASE, mousePos);
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::handleWheelUp() {
|
||||
if (_childObject) {
|
||||
sendMessage(_childObject, NM_MOUSE_WHEELUP, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::handleWheelDown() {
|
||||
if (_childObject) {
|
||||
sendMessage(_childObject, NM_MOUSE_WHEELDOWN, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::handleSpaceKey() {
|
||||
if (_childObject) {
|
||||
debug(2, "GameModule::handleSpaceKey()");
|
||||
sendMessage(_childObject, NM_KEYPRESS_SPACE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::handleAsciiKey(char key) {
|
||||
if (_childObject) {
|
||||
debug(2, "GameModule::handleAsciiKey()");
|
||||
sendMessage(_childObject, 0x000A, (uint32)key);
|
||||
}
|
||||
|
||||
if (key == '\n' || key == '\r') {
|
||||
if (!_currentCheat.empty() && _childObject) {
|
||||
uint32 cheatHash = calcHash(_currentCheat.c_str());
|
||||
debug(2, "GameModule: cheat=\"%s\" (0x%08x)", _currentCheat.c_str(), cheatHash);
|
||||
sendMessage(_childObject, NM_CHEAT, cheatHash);
|
||||
} else if (!_currentCheat.empty())
|
||||
debug(2, "GameModule: cheat=\"%s\" but no child", _currentCheat.c_str());
|
||||
_currentCheat.clear();
|
||||
} else if (key)
|
||||
_currentCheat += key;
|
||||
}
|
||||
|
||||
void GameModule::handleKeyDown(Common::CustomEventType action) {
|
||||
if (_childObject) {
|
||||
if (action == kActionPause || action == kActionQuit || action == kActionSkipFull)
|
||||
handleEscapeKey();
|
||||
else if (action == kActionSkipPartial)
|
||||
handleSpaceKey();
|
||||
debug(2, "GameModule::handleKeyDown()");
|
||||
sendMessage(_childObject, 0x000B, action);
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::handleEscapeKey() {
|
||||
if (_vm->isDemo())
|
||||
_vm->quitGame();
|
||||
else if (!_prevChildObject && _canRequestMainMenu)
|
||||
_mainMenuRequested = true;
|
||||
else if (_childObject)
|
||||
sendMessage(_childObject, NM_KEYPRESS_ESC, 0);
|
||||
}
|
||||
|
||||
void GameModule::initKeySlotsPuzzle() {
|
||||
if (!getSubVar(VA_IS_PUZZLE_INIT, 0x25400B10)) {
|
||||
NonRepeatingRandomNumbers keySlots(_vm->_rnd, 16);
|
||||
for (uint i = 0; i < 3; i++) {
|
||||
setSubVar(VA_GOOD_KEY_SLOT_NUMBERS, i, keySlots.getNumber());
|
||||
setSubVar(VA_CURR_KEY_SLOT_NUMBERS, i, keySlots.getNumber());
|
||||
}
|
||||
setSubVar(VA_IS_PUZZLE_INIT, 0x25400B10, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::initMemoryPuzzle() {
|
||||
if (!getSubVar(VA_IS_PUZZLE_INIT, 0xC8606803)) {
|
||||
NonRepeatingRandomNumbers diceIndices(_vm->_rnd, 3);
|
||||
NonRepeatingRandomNumbers availableTiles(_vm->_rnd, 48);
|
||||
NonRepeatingRandomNumbers tileSymbols(_vm->_rnd, 10);
|
||||
for (uint32 i = 0; i < 3; i++)
|
||||
setSubVar(VA_CURR_DICE_NUMBERS, i, 1);
|
||||
// Set special symbols
|
||||
// Symbol 5 is always one of the three special symbols
|
||||
setSubVar(VA_DICE_MEMORY_SYMBOLS, diceIndices.getNumber(), 5);
|
||||
tileSymbols.removeNumber(5);
|
||||
for (int i = 0; i < 2; i++)
|
||||
setSubVar(VA_DICE_MEMORY_SYMBOLS, diceIndices.getNumber(), tileSymbols.getNumber());
|
||||
// Insert special symbols tiles
|
||||
for (uint32 i = 0; i < 3; ++i) {
|
||||
int tileSymbolOccurrence = _vm->_rnd->getRandomNumber(4 - 1) * 2 + 2;
|
||||
setSubVar(VA_GOOD_DICE_NUMBERS, i, tileSymbolOccurrence);
|
||||
while (tileSymbolOccurrence--)
|
||||
setSubVar(VA_TILE_SYMBOLS, availableTiles.getNumber(), getSubVar(VA_DICE_MEMORY_SYMBOLS, i));
|
||||
}
|
||||
// Fill the remaining tiles
|
||||
uint32 tileSymbolIndex = 0;
|
||||
while (!availableTiles.empty()) {
|
||||
setSubVar(VA_TILE_SYMBOLS, availableTiles.getNumber(), tileSymbols[tileSymbolIndex]);
|
||||
setSubVar(VA_TILE_SYMBOLS, availableTiles.getNumber(), tileSymbols[tileSymbolIndex]);
|
||||
tileSymbolIndex++;
|
||||
if (tileSymbolIndex >= tileSymbols.size())
|
||||
tileSymbolIndex = 0;
|
||||
}
|
||||
setSubVar(VA_IS_PUZZLE_INIT, 0xC8606803, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::initWaterPipesPuzzle() {
|
||||
if (!getSubVar(VA_IS_PUZZLE_INIT, 0x40520234)) {
|
||||
setSubVar(VA_GOOD_WATER_PIPES_LEVEL, 0, 3);
|
||||
setSubVar(VA_GOOD_WATER_PIPES_LEVEL, 1, 1);
|
||||
setSubVar(VA_GOOD_WATER_PIPES_LEVEL, 2, 2);
|
||||
setSubVar(VA_GOOD_WATER_PIPES_LEVEL, 3, 0);
|
||||
setSubVar(VA_GOOD_WATER_PIPES_LEVEL, 4, 4);
|
||||
setSubVar(VA_IS_PUZZLE_INIT, 0x40520234, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::initRadioPuzzle() {
|
||||
if (!getSubVar(VA_IS_PUZZLE_INIT, 0x08C80800)) {
|
||||
int currMusicIndex = _vm->_rnd->getRandomNumber(5 - 1) + 3;
|
||||
setGlobalVar(V_GOOD_RADIO_MUSIC_INDEX, 5 * currMusicIndex);
|
||||
setGlobalVar(V_GOOD_RADIO_MUSIC_NAME, kRadioMusicFileHashes[currMusicIndex]);
|
||||
setGlobalVar(V_RADIO_ROOM_LEFT_DOOR, 1);
|
||||
setGlobalVar(V_RADIO_ROOM_RIGHT_DOOR, 0);
|
||||
setSubVar(VA_IS_PUZZLE_INIT, 0x08C80800, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::initTestTubes1Puzzle() {
|
||||
if (!getSubVar(VA_IS_PUZZLE_INIT, 0x20479010)) {
|
||||
for (uint i = 0; i < 3; i++)
|
||||
setSubVar(VA_GOOD_TEST_TUBES_LEVEL_1, i, _vm->_rnd->getRandomNumber(3 - 1) + 1);
|
||||
setSubVar(VA_IS_PUZZLE_INIT, 0x20479010, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::initTestTubes2Puzzle() {
|
||||
if (!getSubVar(VA_IS_PUZZLE_INIT, 0x66059818)) {
|
||||
for (uint i = 0; i < 3; i++)
|
||||
setSubVar(VA_GOOD_TEST_TUBES_LEVEL_2, i, _vm->_rnd->getRandomNumber(6 - 1) + 1);
|
||||
setSubVar(VA_IS_PUZZLE_INIT, 0x66059818, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::initCannonSymbolsPuzzle() {
|
||||
if (!getSubVar(VA_IS_PUZZLE_INIT, 0x8C9819C2)) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
setSubVar(VA_GOOD_CANNON_SYMBOLS_1, i, _vm->_rnd->getRandomNumber(12 - 1));
|
||||
setSubVar(VA_GOOD_CANNON_SYMBOLS_2, i, _vm->_rnd->getRandomNumber(12 - 1));
|
||||
}
|
||||
setSubVar(VA_IS_PUZZLE_INIT, 0x8C9819C2, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::initCodeSymbolsPuzzle() {
|
||||
if (!getSubVar(VA_IS_PUZZLE_INIT, 0x0CD09B50)) {
|
||||
for (int i = 0; i < 12; ++i)
|
||||
setSubVar(VA_CODE_SYMBOLS, i, i);
|
||||
for (int i = 0; i < 12; ++i) {
|
||||
uint32 index1 = _vm->_rnd->getRandomNumber(12 - 1);
|
||||
uint32 index2 = _vm->_rnd->getRandomNumber(12 - 1);
|
||||
uint32 temp = getSubVar(VA_CODE_SYMBOLS, index1);
|
||||
setSubVar(VA_CODE_SYMBOLS, index1, getSubVar(VA_CODE_SYMBOLS, index2));
|
||||
setSubVar(VA_CODE_SYMBOLS, index2, temp);
|
||||
}
|
||||
setGlobalVar(V_NOISY_SYMBOL_INDEX, _vm->_rnd->getRandomNumber(11 - 1) + 1);
|
||||
setSubVar(VA_IS_PUZZLE_INIT, 0x0CD09B50, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::initCubeSymbolsPuzzle() {
|
||||
if (!getSubVar(VA_IS_PUZZLE_INIT, 0x60400854)) {
|
||||
NonRepeatingRandomNumbers cubeSymbols(_vm->_rnd, 9);
|
||||
for (uint32 cubePosition = 0; cubePosition < 9; ++cubePosition)
|
||||
setSubVar(VA_CUBE_POSITIONS, cubePosition, (uint32)(cubeSymbols.getNumber() - 1));
|
||||
setSubVar(VA_IS_PUZZLE_INIT, 0x60400854, 1);
|
||||
}
|
||||
}
|
||||
|
||||
byte GameModule::parseCrystalColor(char colorLetter) {
|
||||
switch (colorLetter) {
|
||||
case 'B':
|
||||
return 4;
|
||||
case 'G':
|
||||
return 3;
|
||||
case 'O':
|
||||
return 1;
|
||||
case 'R':
|
||||
return 0;
|
||||
case 'V':
|
||||
return 5;
|
||||
case 'Y':
|
||||
return 2;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
void GameModule::initCrystalColorsPuzzle() {
|
||||
if (!getGlobalVar(V_CRYSTAL_COLORS_INIT)) {
|
||||
TextResource textResource(_vm);
|
||||
const char *textStart, *textEnd;
|
||||
textResource.load(0x46691611);
|
||||
textStart = textResource.getString(0, textEnd);
|
||||
for (uint index = 0; index < 5; index++) {
|
||||
char colorLetter = (byte)textStart[index];
|
||||
byte correctColorNum = parseCrystalColor(colorLetter), misalignedColorNum;
|
||||
do {
|
||||
misalignedColorNum = _vm->_rnd->getRandomNumber(6 - 1);
|
||||
} while (misalignedColorNum == correctColorNum);
|
||||
setSubVar(VA_GOOD_CRYSTAL_COLORS, index, correctColorNum);
|
||||
setSubVar(VA_CURR_CRYSTAL_COLORS, index, misalignedColorNum);
|
||||
}
|
||||
setGlobalVar(V_CRYSTAL_COLORS_INIT, 1);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GameModule::getCurrRadioMusicFileHash() {
|
||||
uint musicIndex = getGlobalVar(V_CURR_RADIO_MUSIC_INDEX);
|
||||
return (musicIndex % 5 != 0) ? 0 : kRadioMusicFileHashes[CLIP<uint>(musicIndex / 5, 0, 17)];
|
||||
}
|
||||
|
||||
|
||||
uint32 GameModule::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Module::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x0800:
|
||||
_canRequestMainMenu = true;
|
||||
break;
|
||||
case 0x1009:
|
||||
_moduleResult = param.asInteger();
|
||||
_done = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void GameModule::startup() {
|
||||
#if 1
|
||||
// Logos and intro video // Real game start
|
||||
createModule(1500, 0);
|
||||
#else
|
||||
// DEBUG>>>
|
||||
/*
|
||||
setGlobalVar(V_SEEN_MUSIC_BOX, 1);
|
||||
setGlobalVar(V_CREATURE_EXPLODED, 0);
|
||||
setGlobalVar(V_MATCH_STATUS, 0);
|
||||
setGlobalVar(V_PROJECTOR_LOCATION, 2);
|
||||
*/
|
||||
//setGlobalVar(V_ENTRANCE_OPEN, 0);
|
||||
//setGlobalVar(V_DOOR_SPIKES_OPEN, 1);
|
||||
//setGlobalVar(V_CREATURE_ANGRY, 1);
|
||||
setGlobalVar(V_RADIO_ENABLED, 1);
|
||||
//setGlobalVar(V_TNT_DUMMY_BUILT, 1);
|
||||
setGlobalVar(V_FLYTRAP_RING_DOOR, 1);
|
||||
setGlobalVar(V_TV_JOKE_TOLD, 1);
|
||||
/*
|
||||
// Give all disks
|
||||
for (int i = 0; i < 20; i++)
|
||||
setSubVar(VA_IS_TAPE_INSERTED, i, 1);
|
||||
*/
|
||||
setSubVar(VA_IS_KEY_INSERTED, 0, 1);
|
||||
setSubVar(VA_IS_KEY_INSERTED, 1, 1);
|
||||
setSubVar(VA_IS_KEY_INSERTED, 2, 1);
|
||||
for (uint32 index = 0; index < 9; index++)
|
||||
setSubVar(VA_CUBE_POSITIONS, index, 7 - index);
|
||||
setGlobalVar(V_WALL_BROKEN, 0);
|
||||
setGlobalVar(V_WORLDS_JOINED, 1);
|
||||
setGlobalVar(V_RADIO_MOVE_DISH_VIDEO, 0);
|
||||
// Enable all locations
|
||||
for (int i = 0; i < 6; i++)
|
||||
setSubVar(V_TELEPORTER_DEST_AVAILABLE, i, 1);
|
||||
//setGlobalVar(V_PROJECTOR_LOCATION, 4);
|
||||
setGlobalVar(V_KEYDOOR_UNLOCKED, 1);
|
||||
setGlobalVar(V_LIGHTS_ON, 1);
|
||||
setGlobalVar(V_WATER_RUNNING, 1);
|
||||
setGlobalVar(V_HAS_TEST_TUBE, 1);
|
||||
setSubVar(VA_CURR_WATER_PIPES_LEVEL, 0, 3);
|
||||
setSubVar(VA_CURR_WATER_PIPES_LEVEL, 1, 1);
|
||||
setSubVar(VA_CURR_WATER_PIPES_LEVEL, 2, 2);
|
||||
setSubVar(VA_CURR_WATER_PIPES_LEVEL, 3, 0);
|
||||
setSubVar(VA_CURR_WATER_PIPES_LEVEL, 4, 4);
|
||||
setGlobalVar(V_KLAYMEN_SMALL, 1);
|
||||
setGlobalVar(V_SHRINK_LIGHTS_ON, 0);
|
||||
// <<<DEBUG
|
||||
|
||||
#if 1
|
||||
_vm->gameState().which = 0;
|
||||
_vm->gameState().sceneNum = 0;
|
||||
createModule(2400, 0);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void GameModule::requestRestoreGame() {
|
||||
_restoreGameRequested = true;
|
||||
}
|
||||
|
||||
void GameModule::requestRestartGame(bool requestMainMenu) {
|
||||
_restartGameRequested = true;
|
||||
_mainMenuRequested = requestMainMenu;
|
||||
}
|
||||
|
||||
void GameModule::redrawPrevChildObject() {
|
||||
if (_prevChildObject) {
|
||||
_prevChildObject->draw();
|
||||
_vm->_screen->update();
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::checkRequests() {
|
||||
if (_restartGameRequested) {
|
||||
_restartGameRequested = false;
|
||||
_vm->_gameVars->clear();
|
||||
requestRestoreGame();
|
||||
}
|
||||
if (_restoreGameRequested) {
|
||||
_restoreGameRequested = false;
|
||||
_vm->_audioResourceMan->stopAllMusic();
|
||||
_vm->_audioResourceMan->stopAllSounds();
|
||||
_vm->_soundMan->stopAllMusic();
|
||||
_vm->_soundMan->stopAllSounds();
|
||||
// Reinsert turning sound because SoundMan::stopAllSounds() removes it
|
||||
_vm->_soundMan->playSoundThree(0x002D0031, 0x08861079);
|
||||
delete _childObject;
|
||||
delete _prevChildObject;
|
||||
_childObject = nullptr;
|
||||
_prevChildObject = nullptr;
|
||||
_prevModuleNum = 0;
|
||||
createModuleByHash(getGlobalVar(V_MODULE_NAME));
|
||||
}
|
||||
if (_mainMenuRequested)
|
||||
openMainMenu();
|
||||
}
|
||||
|
||||
void GameModule::createModule(int moduleNum, int which) {
|
||||
debug(1, "GameModule::createModule(%d, %d)", moduleNum, which);
|
||||
_moduleNum = moduleNum;
|
||||
|
||||
delete _childObject;
|
||||
|
||||
switch (_moduleNum) {
|
||||
case 1000:
|
||||
setGlobalVar(V_MODULE_NAME, 0x03294419);
|
||||
_childObject = new Module1000(_vm, this, which);
|
||||
break;
|
||||
case 1100:
|
||||
setGlobalVar(V_MODULE_NAME, 0x0002C818);
|
||||
_childObject = new Module1100(_vm, this, which);
|
||||
break;
|
||||
case 1200:
|
||||
setGlobalVar(V_MODULE_NAME, 0x00478311);
|
||||
_childObject = new Module1200(_vm, this, which);
|
||||
break;
|
||||
case 1300:
|
||||
setGlobalVar(V_MODULE_NAME, 0x0061C090);
|
||||
_childObject = new Module1300(_vm, this, which);
|
||||
break;
|
||||
case 1400:
|
||||
setGlobalVar(V_MODULE_NAME, 0x00AD0012);
|
||||
_childObject = new Module1400(_vm, this, which);
|
||||
break;
|
||||
case 1500:
|
||||
_canRequestMainMenu = false;
|
||||
setGlobalVar(V_MODULE_NAME, 0x00F10114);
|
||||
_childObject = new Module1500(_vm, this, which);
|
||||
break;
|
||||
case 1600:
|
||||
setGlobalVar(V_MODULE_NAME, 0x01A008D8);
|
||||
_childObject = new Module1600(_vm, this, which);
|
||||
break;
|
||||
case 1700:
|
||||
setGlobalVar(V_MODULE_NAME, 0x04212331);
|
||||
_childObject = new Module1700(_vm, this, which);
|
||||
break;
|
||||
case 1800:
|
||||
setGlobalVar(V_MODULE_NAME, 0x04A14718);
|
||||
_childObject = new Module1800(_vm, this, which);
|
||||
break;
|
||||
case 1900:
|
||||
setGlobalVar(V_MODULE_NAME, 0x04E1C09C);
|
||||
_childObject = new Module1900(_vm, this, which);
|
||||
break;
|
||||
case 2000:
|
||||
setGlobalVar(V_MODULE_NAME, 0x08250000);
|
||||
_childObject = new Module2000(_vm, this, which);
|
||||
break;
|
||||
case 2100:
|
||||
setGlobalVar(V_MODULE_NAME, 0x10A10C14);
|
||||
_childObject = new Module2100(_vm, this, which);
|
||||
break;
|
||||
case 2200:
|
||||
setGlobalVar(V_MODULE_NAME, 0x11391412);
|
||||
_childObject = new Module2200(_vm, this, which);
|
||||
break;
|
||||
case 2300:
|
||||
setGlobalVar(V_MODULE_NAME, 0x1A214010);
|
||||
_childObject = new Module2300(_vm, this, which);
|
||||
break;
|
||||
case 2400:
|
||||
setGlobalVar(V_MODULE_NAME, 0x202D1010);
|
||||
_childObject = new Module2400(_vm, this, which);
|
||||
break;
|
||||
case 2500:
|
||||
setGlobalVar(V_MODULE_NAME, 0x29220120);
|
||||
_childObject = new Module2500(_vm, this, which);
|
||||
break;
|
||||
case 2600:
|
||||
setGlobalVar(V_MODULE_NAME, 0x40271018);
|
||||
_childObject = new Module2600(_vm, this, which);
|
||||
break;
|
||||
case 2700:
|
||||
setGlobalVar(V_MODULE_NAME, 0x42212411);
|
||||
_childObject = new Module2700(_vm, this, which);
|
||||
break;
|
||||
case 2800:
|
||||
setGlobalVar(V_MODULE_NAME, 0x64210814);
|
||||
_childObject = new Module2800(_vm, this, which);
|
||||
break;
|
||||
case 2900:
|
||||
setGlobalVar(V_MODULE_NAME, 0x81100020);
|
||||
if (which >= 0)
|
||||
setGlobalVar(V_TELEPORTER_CURR_LOCATION, which);
|
||||
_childObject = new Module2900(_vm, this, which);
|
||||
break;
|
||||
case 3000:
|
||||
setGlobalVar(V_MODULE_NAME, 0x81293110);
|
||||
_childObject = new Module3000(_vm, this, which);
|
||||
break;
|
||||
case 9999:
|
||||
createDemoScene();
|
||||
break;
|
||||
default:
|
||||
error("GameModule::createModule() Could not create module %d", moduleNum);
|
||||
}
|
||||
SetUpdateHandler(&GameModule::updateModule);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void GameModule::createModuleByHash(uint32 nameHash) {
|
||||
debug(1, "GameModule::createModuleByHash(%08X)", nameHash);
|
||||
switch (nameHash) {
|
||||
case 0x03294419:
|
||||
createModule(1000, -1);
|
||||
break;
|
||||
case 0x0002C818:
|
||||
createModule(1100, -1);
|
||||
break;
|
||||
case 0x00478311:
|
||||
createModule(1200, -1);
|
||||
break;
|
||||
case 0x0061C090:
|
||||
createModule(1300, -1);
|
||||
break;
|
||||
case 0x00AD0012:
|
||||
createModule(1400, -1);
|
||||
break;
|
||||
case 0x00F10114:
|
||||
createModule(1500, -1);
|
||||
break;
|
||||
case 0x01A008D8:
|
||||
createModule(1600, -1);
|
||||
break;
|
||||
case 0x04212331:
|
||||
createModule(1700, -1);
|
||||
break;
|
||||
case 0x04A14718:
|
||||
createModule(1800, -1);
|
||||
break;
|
||||
case 0x04E1C09C:
|
||||
createModule(1900, -1);
|
||||
break;
|
||||
case 0x08250000:
|
||||
createModule(2000, -1);
|
||||
break;
|
||||
case 0x10A10C14:
|
||||
createModule(2100, -1);
|
||||
break;
|
||||
case 0x11391412:
|
||||
createModule(2200, -1);
|
||||
break;
|
||||
case 0x1A214010:
|
||||
createModule(2300, -1);
|
||||
break;
|
||||
case 0x202D1010:
|
||||
createModule(2400, -1);
|
||||
break;
|
||||
case 0x29220120:
|
||||
createModule(2500, -1);
|
||||
break;
|
||||
case 0x40271018:
|
||||
createModule(2600, -1);
|
||||
break;
|
||||
case 0x42212411:
|
||||
createModule(2700, -1);
|
||||
break;
|
||||
case 0x64210814:
|
||||
createModule(2800, -1);
|
||||
break;
|
||||
case 0x81100020:
|
||||
createModule(2900, -1);
|
||||
break;
|
||||
case 0x81293110:
|
||||
createModule(3000, -1);
|
||||
break;
|
||||
default:
|
||||
createModule(1000, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::updateModule() {
|
||||
if (!updateChild()) {
|
||||
switch (_moduleNum) {
|
||||
case 1000:
|
||||
createModule(2300, 0);
|
||||
break;
|
||||
case 1200:
|
||||
if (_moduleResult == 1)
|
||||
createModule(2600, 0);
|
||||
else
|
||||
createModule(2300, 2);
|
||||
break;
|
||||
case 1100:
|
||||
if (_moduleResult == 0)
|
||||
createModule(2900, 2);
|
||||
else {
|
||||
setGlobalVar(V_ENTRANCE_OPEN, 1);
|
||||
createModule(1300, 0);
|
||||
}
|
||||
break;
|
||||
case 1300:
|
||||
if (_moduleResult == 1) {
|
||||
// The game was successfully finished
|
||||
requestRestartGame(true);
|
||||
} else
|
||||
createModule(2900, 0);
|
||||
break;
|
||||
case 1400:
|
||||
createModule(1600, 1);
|
||||
break;
|
||||
case 1500:
|
||||
createModule(1000, 0);
|
||||
break;
|
||||
case 1600:
|
||||
if (_moduleResult == 1)
|
||||
createModule(1400, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createModule(1700, 0);
|
||||
else
|
||||
createModule(2100, 0);
|
||||
break;
|
||||
case 1700:
|
||||
if (_moduleResult == 1)
|
||||
createModule(2900, 3);
|
||||
else
|
||||
createModule(1600, 2);
|
||||
break;
|
||||
case 1800:
|
||||
if (_moduleResult == 1) {
|
||||
// Game over, Klaymen jumped into the hole
|
||||
requestRestartGame(true);
|
||||
} else if (_moduleResult == 2)
|
||||
createModule(2700, 0);
|
||||
else if (_moduleResult == 3)
|
||||
createModule(3000, 3);
|
||||
else
|
||||
createModule(2800, 0);
|
||||
break;
|
||||
case 1900:
|
||||
createModule(3000, 1);
|
||||
break;
|
||||
case 2000:
|
||||
createModule(2900, 4);
|
||||
break;
|
||||
case 2100:
|
||||
if (_moduleResult == 1)
|
||||
createModule(2900, 1);
|
||||
else
|
||||
createModule(1600, 0);
|
||||
break;
|
||||
case 2200:
|
||||
createModule(2300, 1);
|
||||
break;
|
||||
case 2300:
|
||||
debug(1, "module 23000 _moduleResult : %d", _moduleResult);
|
||||
if (_moduleResult == 2)
|
||||
createModule(1200, 0);
|
||||
else if (_moduleResult == 0)
|
||||
createModule(1000, 1);
|
||||
else if (_vm->isDemo())
|
||||
createModule(9999, -1);
|
||||
else if (_moduleResult == 1)
|
||||
createModule(2200, 0);
|
||||
else if (_moduleResult == 3)
|
||||
createModule(2400, 0);
|
||||
else if (_moduleResult == 4)
|
||||
createModule(3000, 0);
|
||||
break;
|
||||
case 2400:
|
||||
createModule(2300, 3);
|
||||
break;
|
||||
case 2500:
|
||||
createModule(2600, 1);
|
||||
break;
|
||||
case 2600:
|
||||
if (_moduleResult == 1) {
|
||||
if (_vm->isDemo())
|
||||
createModule(9999, -1);
|
||||
else
|
||||
createModule(2500, 0);
|
||||
} else
|
||||
createModule(1200, 1);
|
||||
break;
|
||||
case 2700:
|
||||
createModule(1800, 2);
|
||||
break;
|
||||
case 2800:
|
||||
if (_moduleResult == 1)
|
||||
createModule(2900, 5);
|
||||
else
|
||||
createModule(1800, 0);
|
||||
break;
|
||||
case 2900:
|
||||
if (_moduleResult != (uint32)-1) {
|
||||
switch (_moduleResult) {
|
||||
case 0:
|
||||
createModule(1300, 5);
|
||||
break;
|
||||
case 1:
|
||||
createModule(2100, 1);
|
||||
break;
|
||||
case 2:
|
||||
createModule(1100, 1);
|
||||
break;
|
||||
case 3:
|
||||
setSubVar(V_TELEPORTER_DEST_AVAILABLE, 2, 1);
|
||||
createModule(1700, 1);
|
||||
break;
|
||||
case 4:
|
||||
createModule(2000, 0);
|
||||
break;
|
||||
case 5:
|
||||
default:
|
||||
createModule(2800, 1);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (getGlobalVar(V_TELEPORTER_CURR_LOCATION)) {
|
||||
case 0:
|
||||
createModule(1300, 6);
|
||||
break;
|
||||
case 1:
|
||||
createModule(2100, 2);
|
||||
break;
|
||||
case 2:
|
||||
createModule(1100, 2);
|
||||
break;
|
||||
case 3:
|
||||
createModule(1700, 2);
|
||||
break;
|
||||
case 4:
|
||||
createModule(2000, 1);
|
||||
break;
|
||||
case 5:
|
||||
default:
|
||||
createModule(2800, 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
setGlobalVar(V_TELEPORTER_CURR_LOCATION, 0);
|
||||
break;
|
||||
case 3000:
|
||||
// NOTE _moduleResult 2 never used
|
||||
// NOTE Check if _moduleResult 4 is used
|
||||
if (_moduleResult == 1)
|
||||
createModule(1900, 0);
|
||||
else if (_moduleResult == 3)
|
||||
createModule(1800, 3);
|
||||
else if (_moduleResult == 4)
|
||||
createModule(3000, 0);
|
||||
else
|
||||
createModule(2300, 4);
|
||||
break;
|
||||
case 9999:
|
||||
createModuleByHash(getGlobalVar(V_MODULE_NAME));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::openMainMenu() {
|
||||
if (_childObject) {
|
||||
sendMessage(_childObject, NM_MOUSE_HIDE, 0);
|
||||
_childObject->draw();
|
||||
} else {
|
||||
// If there's no module, create one so there's something to return to
|
||||
createModule(1000, 0);
|
||||
}
|
||||
_vm->_screen->saveParams();
|
||||
_vm->_screen->update();
|
||||
_mainMenuRequested = false;
|
||||
createMenuModule();
|
||||
}
|
||||
|
||||
void GameModule::createMenuModule() {
|
||||
if (!_prevChildObject) {
|
||||
_prevChildObject = _childObject;
|
||||
_prevModuleNum = _moduleNum;
|
||||
_childObject = new MenuModule(_vm, this, 0);
|
||||
_childObject->handleUpdate();
|
||||
SetUpdateHandler(&GameModule::updateMenuModule);
|
||||
}
|
||||
}
|
||||
|
||||
void GameModule::updateMenuModule() {
|
||||
if (!updateChild()) {
|
||||
_vm->_screen->restoreParams();
|
||||
_childObject = _prevChildObject;
|
||||
sendMessage(_childObject, NM_MOUSE_SHOW, 0);
|
||||
_prevChildObject = nullptr;
|
||||
_moduleNum = _prevModuleNum;
|
||||
SetUpdateHandler(&GameModule::updateModule);
|
||||
}
|
||||
}
|
||||
|
||||
NonRepeatingRandomNumbers::NonRepeatingRandomNumbers(Common::RandomSource *rnd, int count)
|
||||
: _rnd(rnd) {
|
||||
for (int i = 0; i < count; i++)
|
||||
push_back(i);
|
||||
}
|
||||
|
||||
int NonRepeatingRandomNumbers::getNumber() {
|
||||
int number;
|
||||
if (!empty()) {
|
||||
uint index = _rnd->getRandomNumber(size() - 1);
|
||||
number = (*this)[index];
|
||||
remove_at(index);
|
||||
} else
|
||||
number = 0;
|
||||
return number;
|
||||
}
|
||||
|
||||
void NonRepeatingRandomNumbers::removeNumber(int number) {
|
||||
for (uint i = 0; i < size(); ++i)
|
||||
if ((*this)[i] == number) {
|
||||
remove_at(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
92
engines/neverhood/gamemodule.h
Normal file
92
engines/neverhood/gamemodule.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_GAMEMODULE_H
|
||||
#define NEVERHOOD_GAMEMODULE_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class GameModule : public Module {
|
||||
public:
|
||||
GameModule(NeverhoodEngine *vm);
|
||||
~GameModule() override;
|
||||
void startup();
|
||||
void requestRestoreGame();
|
||||
void requestRestartGame(bool requestMainMenu);
|
||||
void redrawPrevChildObject();
|
||||
void checkRequests();
|
||||
void handleMouseMove(int16 x, int16 y);
|
||||
void handleMouseDown(int16 x, int16 y);
|
||||
void handleMouseUp(int16 x, int16 y);
|
||||
void handleWheelUp();
|
||||
void handleWheelDown();
|
||||
void handleSpaceKey();
|
||||
void handleAsciiKey(char key);
|
||||
void handleKeyDown(Common::CustomEventType action);
|
||||
void handleEscapeKey();
|
||||
void initKeySlotsPuzzle();
|
||||
void initMemoryPuzzle();
|
||||
void initWaterPipesPuzzle();
|
||||
void initRadioPuzzle();
|
||||
void initTestTubes1Puzzle();
|
||||
void initTestTubes2Puzzle();
|
||||
void initCannonSymbolsPuzzle();
|
||||
void initCodeSymbolsPuzzle();
|
||||
void initCubeSymbolsPuzzle();
|
||||
void initCrystalColorsPuzzle();
|
||||
uint32 getCurrRadioMusicFileHash();
|
||||
int getCurrentModuleNum() { return _moduleNum; }
|
||||
int getPreviousModuleNum() { return _moduleNum; }
|
||||
|
||||
void createModule(int moduleNum, int which);
|
||||
static byte parseCrystalColor(char colorLetter);
|
||||
protected:
|
||||
int _moduleNum;
|
||||
Entity *_prevChildObject;
|
||||
int _prevModuleNum;
|
||||
bool _restoreGameRequested;
|
||||
bool _restartGameRequested;
|
||||
bool _canRequestMainMenu;
|
||||
bool _mainMenuRequested;
|
||||
Common::String _currentCheat;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void createModuleByHash(uint32 nameHash);
|
||||
void updateModule();
|
||||
void openMainMenu();
|
||||
void createMenuModule();
|
||||
void updateMenuModule();
|
||||
};
|
||||
|
||||
class NonRepeatingRandomNumbers : public Common::Array<int> {
|
||||
public:
|
||||
NonRepeatingRandomNumbers(Common::RandomSource *rnd, int count);
|
||||
int getNumber();
|
||||
void removeNumber(int number);
|
||||
protected:
|
||||
Common::RandomSource *_rnd;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULE_H */
|
||||
133
engines/neverhood/gamevars.cpp
Normal file
133
engines/neverhood/gamevars.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/console.h"
|
||||
#include "neverhood/gamevars.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
GameVars::GameVars() {
|
||||
addVar(0, 0);
|
||||
}
|
||||
|
||||
void GameVars::clear() {
|
||||
_vars.clear();
|
||||
addVar(0, 0);
|
||||
}
|
||||
|
||||
void GameVars::loadState(Common::InSaveFile *in) {
|
||||
uint varCount;
|
||||
_vars.clear();
|
||||
varCount = in->readUint32LE();
|
||||
for (uint i = 0; i < varCount; ++i) {
|
||||
GameVar var;
|
||||
var.nameHash = in->readUint32LE();
|
||||
var.value = in->readUint32LE();
|
||||
var.firstIndex = in->readUint16LE();
|
||||
var.nextIndex = in->readUint16LE();
|
||||
_vars.push_back(var);
|
||||
}
|
||||
}
|
||||
|
||||
void GameVars::saveState(Common::OutSaveFile *out) {
|
||||
out->writeUint32LE(_vars.size());
|
||||
for (uint i = 0; i < _vars.size(); ++i) {
|
||||
GameVar &var = _vars[i];
|
||||
out->writeUint32LE(var.nameHash);
|
||||
out->writeUint32LE(var.value);
|
||||
out->writeUint16LE(var.firstIndex);
|
||||
out->writeUint16LE(var.nextIndex);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GameVars::getGlobalVar(uint32 nameHash) {
|
||||
int16 varIndex = findSubVarIndex(0, nameHash);
|
||||
return varIndex != -1 ? _vars[varIndex].value : 0;
|
||||
}
|
||||
|
||||
void GameVars::setGlobalVar(uint32 nameHash, uint32 value) {
|
||||
_vars[getSubVarIndex(0, nameHash)].value = value;
|
||||
}
|
||||
|
||||
uint32 GameVars::getSubVar(uint32 nameHash, uint32 subNameHash) {
|
||||
uint32 value = 0;
|
||||
int16 varIndex = findSubVarIndex(0, nameHash);
|
||||
if (varIndex != -1) {
|
||||
int16 subVarIndex = findSubVarIndex(varIndex, subNameHash);
|
||||
if (subVarIndex != -1)
|
||||
value = _vars[subVarIndex].value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void GameVars::setSubVar(uint32 nameHash, uint32 subNameHash, uint32 value) {
|
||||
int16 varIndex = getSubVarIndex(0, nameHash);
|
||||
int16 subVarIndex = getSubVarIndex(varIndex, subNameHash);
|
||||
_vars[subVarIndex].value = value;
|
||||
}
|
||||
|
||||
int16 GameVars::addVar(uint32 nameHash, uint32 value) {
|
||||
GameVar gameVar;
|
||||
gameVar.nameHash = nameHash;
|
||||
gameVar.value = value;
|
||||
gameVar.firstIndex = -1;
|
||||
gameVar.nextIndex = -1;
|
||||
_vars.push_back(gameVar);
|
||||
return _vars.size() - 1;
|
||||
}
|
||||
|
||||
int16 GameVars::findSubVarIndex(int16 varIndex, uint32 subNameHash) {
|
||||
for (int16 nextIndex = _vars[varIndex].firstIndex; nextIndex != -1; nextIndex = _vars[nextIndex].nextIndex)
|
||||
if (_vars[nextIndex].nameHash == subNameHash)
|
||||
return nextIndex;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int16 GameVars::addSubVar(int16 varIndex, uint32 subNameHash, uint32 value) {
|
||||
int16 nextIndex = _vars[varIndex].firstIndex;
|
||||
int16 subVarIndex;
|
||||
if (nextIndex == -1) {
|
||||
subVarIndex = addVar(subNameHash, value);
|
||||
_vars[varIndex].firstIndex = subVarIndex;
|
||||
} else {
|
||||
while (_vars[nextIndex].nextIndex != -1)
|
||||
nextIndex = _vars[nextIndex].nextIndex;
|
||||
subVarIndex = addVar(subNameHash, value);
|
||||
_vars[nextIndex].nextIndex = subVarIndex;
|
||||
}
|
||||
return subVarIndex;
|
||||
}
|
||||
|
||||
int16 GameVars::getSubVarIndex(int16 varIndex, uint32 subNameHash) {
|
||||
int16 subVarIndex = findSubVarIndex(varIndex, subNameHash);
|
||||
if (subVarIndex == -1)
|
||||
subVarIndex = addSubVar(varIndex, subNameHash, 0);
|
||||
return subVarIndex;
|
||||
}
|
||||
|
||||
void GameVars::dumpVars(Console *con) {
|
||||
for (Common::Array<GameVar>::iterator it = _vars.begin(); it != _vars.end(); ++it) {
|
||||
GameVar gameVar = *it;
|
||||
con->debugPrintf("hash: %08X, var: %08X, first index: %3d, next index: %3d\n", gameVar.nameHash, gameVar.value, gameVar.firstIndex, gameVar.nextIndex);
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
194
engines/neverhood/gamevars.h
Normal file
194
engines/neverhood/gamevars.h
Normal file
@@ -0,0 +1,194 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_GAMEVARS_H
|
||||
#define NEVERHOOD_GAMEVARS_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/savefile.h"
|
||||
#include "neverhood/neverhood.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
enum : uint {
|
||||
// Misc
|
||||
V_MODULE_NAME = 0x91080831, // Currently active module name hash
|
||||
V_CURRENT_SCENE = 0x108A4870, // Current scene in the current module
|
||||
V_CURRENT_SCENE_WHICH = 0x82C80875,
|
||||
V_DEBUG = 0xA4014072, // Original debug-flag, can probably be removed
|
||||
V_SMACKER_CAN_ABORT = 0x06C02850, // Not set anywhere (yet), seems like a debug flag
|
||||
V_KEY3_LOCATION = 0x13382860, // Location of the third key
|
||||
V_TEXT_FLAG1 = 0x8440001F,
|
||||
V_TEXT_INDEX = 0x01830201,
|
||||
V_TEXT_COUNTING_INDEX1 = 0x29408F00,
|
||||
V_TEXT_COUNTING_INDEX2 = 0x8A140C21,
|
||||
V_TALK_COUNTING_INDEX = 0xA0808898,
|
||||
V_FRUIT_COUNTING_INDEX = 0x40040831,
|
||||
V_NOISY_SYMBOL_INDEX = 0x2414C2F2,
|
||||
V_COLUMN_BACK_NAME = 0x4CE79018,
|
||||
V_COLUMN_TEXT_NAME = 0xC8C28808,
|
||||
V_CLICKED_COLUMN_INDEX = 0x48A68852,
|
||||
V_CLICKED_COLUMN_ROW = 0x49C40058,
|
||||
// Klaymen
|
||||
V_KLAYMEN_SMALL = 0x1860C990, // Is Klaymen small?
|
||||
V_KLAYMEN_FRAMEINDEX = 0x18288913,
|
||||
V_KLAYMEN_IS_DELTA_X = 0xC0418A02,
|
||||
V_KLAYMEN_SAVED_X = 0x00D30138,
|
||||
V_CAR_DELTA_X = 0x21E60190,
|
||||
// Flags
|
||||
V_CRYSTAL_COLORS_INIT = 0xDE2EC914,
|
||||
V_TV_JOKE_TOLD = 0x92603A79,
|
||||
V_NOTES_DOOR_UNLOCKED = 0x0045D021,
|
||||
V_WATER_RUNNING = 0x4E0BE910,
|
||||
V_CREATURE_ANGRY = 0x0A310817, // After having played with the music box
|
||||
V_BEEN_SHRINKING_ROOM = 0x1C1B8A9A,
|
||||
V_BEEN_STATUE_ROOM = 0xCB45DE03,
|
||||
V_MOUSE_PUZZLE_SOLVED = 0x70A1189C,
|
||||
V_NOTES_PUZZLE_SOLVED = 0x86615030,
|
||||
V_TILE_PUZZLE_SOLVED = 0x404290D5,
|
||||
V_STAIRS_PUZZLE_SOLVED = 0xA9035F60,
|
||||
V_CODE_SYMBOLS_SOLVED = 0x2C531AF8,
|
||||
V_SPIKES_RETRACTED = 0x18890C91,
|
||||
V_LARGE_DOOR_NUMBER = 0x9A500914, // Number of the currently "large" door
|
||||
V_LIGHTS_ON = 0x4D080E54,
|
||||
V_SHRINK_LIGHTS_ON = 0x190A1D18, // Lights on in the room with the shrinking device
|
||||
V_STAIRS_DOWN_ONCE = 0x2050861A, // Stairs have been down once before
|
||||
V_STAIRS_DOWN = 0x09221A62,
|
||||
V_LADDER_DOWN = 0x0018CA22, // Is the ladder in the statue room down?
|
||||
V_LADDER_DOWN_ACTION = 0x00188211,
|
||||
V_WALL_BROKEN = 0x10938830,
|
||||
V_BOLT_DOOR_OPEN = 0x01BA1A52,
|
||||
V_BOLT_DOOR_UNLOCKED = 0x00040153,
|
||||
V_SEEN_SYMBOLS_NO_LIGHT = 0x81890D14,
|
||||
V_FELL_DOWN_HOLE = 0xE7498218,
|
||||
V_DOOR_PASSED = 0x2090590C, // Auto-closing door was passed
|
||||
V_ENTRANCE_OPEN = 0xD0A14D10, // Is the entrance to Module1300 open (after the robot got his teddy)
|
||||
V_WINDOW_OPEN = 0x03C698DA,
|
||||
V_DOOR_STATUS = 0x52371C95,
|
||||
V_DOOR_BUSTED = 0xD217189D,
|
||||
V_WORLDS_JOINED = 0x98109F12, // Are the worlds joined?
|
||||
V_KEYDOOR_UNLOCKED = 0x80455A41, // Is the keyboard-door unlocked?
|
||||
V_MOUSE_SUCKED_IN = 0x01023818, // Are mouse/cheese in Scene1308?
|
||||
V_BALLOON_POPPED = 0xAC00C0D0, // Has the balloon with the key been popped?
|
||||
V_TNT_DUMMY_BUILT = 0x000CF819, // Are all TNT parts on the dummy?
|
||||
V_TNT_DUMMY_FUSE_LIT = 0x20A0C516,
|
||||
V_RADIO_ENABLED = 0x4DE80AC0,
|
||||
V_SEEN_CREATURE_EXPLODE_VID = 0x2A02C07B,
|
||||
V_CREATURE_EXPLODED = 0x0A18CA33,
|
||||
V_UNUSED = 0x89C669AA, // Seems to be unused, confirmed by checking the exe for this constant value (still left in atm)
|
||||
// Radio
|
||||
V_RADIO_ROOM_LEFT_DOOR = 0x09880D40,
|
||||
V_RADIO_ROOM_RIGHT_DOOR = 0x08180ABC,
|
||||
V_CURR_RADIO_MUSIC_INDEX = 0x08CC0828,
|
||||
V_GOOD_RADIO_MUSIC_INDEX = 0x88880915,
|
||||
V_GOOD_RADIO_MUSIC_NAME = 0x89A82A15,
|
||||
V_RADIO_MOVE_DISH_VIDEO = 0x28D8C940,
|
||||
// Match
|
||||
V_MATCH_STATUS = 0x0112090A,
|
||||
// Venus fly trap
|
||||
V_FLYTRAP_RING_EATEN = 0x2B514304,
|
||||
V_FLYTRAP_RING_DOOR = 0x8306F218,
|
||||
V_FLYTRAP_RING_FENCE = 0x80101B1E,
|
||||
V_FLYTRAP_RING_BRIDGE = 0x13206309,
|
||||
V_FLYTRAP_POSITION_1 = 0x1B144052,
|
||||
V_FLYTRAP_POSITION_2 = 0x86341E88,
|
||||
// Navigation
|
||||
V_NAVIGATION_INDEX = 0x4200189E, // Navigation scene: Current navigation index
|
||||
// Cannon
|
||||
V_CANNON_RAISED = 0x000809C2, // Is the cannon raised?
|
||||
V_CANNON_TURNED = 0x9040018A, // Is the cannon turned?
|
||||
V_ROBOT_HIT = 0x0C0288F4, // Was the robot hit by the cannon?
|
||||
V_ROBOT_TARGET = 0x610210B7, // Is the robot at the cannon target position? (teddy)
|
||||
V_CANNON_SMACKER_NAME = 0xF0402B0A,
|
||||
V_CANNON_TARGET_STATUS = 0x20580A86,
|
||||
// Projector
|
||||
V_PROJECTOR_SLOT = 0x04A10F33, // Projector x slot index
|
||||
V_PROJECTOR_LOCATION = 0x04A105B3, // Projector scene location
|
||||
V_PROJECTOR_ACTIVE = 0x12A10DB3, // Is the projecor projecting?
|
||||
// Teleporter
|
||||
V_TELEPORTER_CURR_LOCATION = 0x0152899A,
|
||||
V_TELEPORTER_WHICH = 0x60826830,
|
||||
V_TELEPORTER_DEST_AVAILABLE = 0x2C145A98,
|
||||
// Inventory
|
||||
V_HAS_NEEDLE = 0x31C63C51, // Has Klaymen the needle?
|
||||
V_HAS_FINAL_KEY = 0xC0780812, // Has Klaymen the key from the diskplayer?
|
||||
V_HAS_TEST_TUBE = 0x45080C38,
|
||||
// Arrays
|
||||
// NOTE "GOOD" means the solution, "CURR" is the current setup of the puzzle variables
|
||||
VA_IS_PUZZLE_INIT = 0x40050052,
|
||||
VA_SMACKER_PLAYED = 0x00800410,
|
||||
VA_CURR_CRYSTAL_COLORS = 0xE11A1929,
|
||||
VA_GOOD_CRYSTAL_COLORS = 0xD4B2089C,
|
||||
VA_GOOD_TEST_TUBES_LEVEL_1 = 0x0C601058,
|
||||
VA_GOOD_TEST_TUBES_LEVEL_2 = 0x40005834,
|
||||
VA_CURR_CANNON_SYMBOLS = 0x00000914,
|
||||
VA_GOOD_CANNON_SYMBOLS_1 = 0x00504B86,
|
||||
VA_GOOD_CANNON_SYMBOLS_2 = 0x0A4C0A9A,
|
||||
VA_CURR_WATER_PIPES_LEVEL = 0x0800547C,
|
||||
VA_GOOD_WATER_PIPES_LEVEL = 0x90405038,
|
||||
VA_CURR_DICE_NUMBERS = 0x61084036,
|
||||
VA_GOOD_DICE_NUMBERS = 0x7500993A,
|
||||
VA_CURR_KEY_SLOT_NUMBERS = 0xA010B810,
|
||||
VA_GOOD_KEY_SLOT_NUMBERS = 0x0C10A000,
|
||||
VA_CUBE_POSITIONS = 0x484498D0,
|
||||
VA_CODE_SYMBOLS = 0x04909A50,
|
||||
VA_TILE_SYMBOLS = 0x0C65F80B,
|
||||
VA_IS_TILE_MATCH = 0xCCE0280F,
|
||||
VA_TNT_POSITIONS = 0x10055D14,
|
||||
VA_DICE_MEMORY_SYMBOLS = 0x13100631,
|
||||
VA_HAS_TAPE = 0x02038314,
|
||||
VA_IS_TAPE_INSERTED = 0x02720344,
|
||||
VA_HAS_KEY = 0x0090EA95,
|
||||
VA_IS_KEY_INSERTED = 0x08D0AB11,
|
||||
VA_LOCKS_DISABLED = 0x14800353,
|
||||
V_END_
|
||||
};
|
||||
|
||||
struct GameVar {
|
||||
uint32 nameHash;
|
||||
uint32 value;
|
||||
int16 firstIndex, nextIndex;
|
||||
};
|
||||
|
||||
class Console;
|
||||
|
||||
class GameVars {
|
||||
public:
|
||||
GameVars();
|
||||
void clear();
|
||||
void loadState(Common::InSaveFile *in);
|
||||
void saveState(Common::OutSaveFile *out);
|
||||
uint32 getGlobalVar(uint32 nameHash);
|
||||
void setGlobalVar(uint32 nameHash, uint32 value);
|
||||
uint32 getSubVar(uint32 nameHash, uint32 subNameHash);
|
||||
void setSubVar(uint32 nameHash, uint32 subNameHash, uint32 value);
|
||||
void dumpVars(Console *con);
|
||||
protected:
|
||||
Common::Array<GameVar> _vars;
|
||||
int16 addVar(uint32 nameHash, uint32 value);
|
||||
int16 findSubVarIndex(int16 varIndex, uint32 subNameHash);
|
||||
int16 addSubVar(int16 varIndex, uint32 subNameHash, uint32 value);
|
||||
int16 getSubVarIndex(int16 varIndex, uint32 subNameHash);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_GAMEVARS_H */
|
||||
358
engines/neverhood/graphics.cpp
Normal file
358
engines/neverhood/graphics.cpp
Normal file
@@ -0,0 +1,358 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/graphics.h"
|
||||
#include "neverhood/resource.h"
|
||||
#include "neverhood/screen.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
BaseSurface::BaseSurface(NeverhoodEngine *vm, int priority, int16 width, int16 height, Common::String name)
|
||||
: _vm(vm), _priority(priority), _visible(true), _transparent(true),
|
||||
_clipRects(nullptr), _clipRectsCount(0), _version(0), _name(name) {
|
||||
|
||||
_drawRect.x = 0;
|
||||
_drawRect.y = 0;
|
||||
_drawRect.width = width;
|
||||
_drawRect.height = height;
|
||||
_sysRect.x = 0;
|
||||
_sysRect.y = 0;
|
||||
_sysRect.width = (width + 3) & 0xFFFC; // align by 4 bytes
|
||||
_sysRect.height = height;
|
||||
_clipRect.x1 = 0;
|
||||
_clipRect.y1 = 0;
|
||||
_clipRect.x2 = 640;
|
||||
_clipRect.y2 = 480;
|
||||
_surface = new Graphics::Surface();
|
||||
_surface->create(_sysRect.width, _sysRect.height, Graphics::PixelFormat::createFormatCLUT8());
|
||||
}
|
||||
|
||||
BaseSurface::~BaseSurface() {
|
||||
_surface->free();
|
||||
delete _surface;
|
||||
}
|
||||
|
||||
void BaseSurface::draw() {
|
||||
if (_surface && _visible && _drawRect.width > 0 && _drawRect.height > 0) {
|
||||
if (_clipRects && _clipRectsCount) {
|
||||
_vm->_screen->drawSurfaceClipRects(_surface, _drawRect, _clipRects, _clipRectsCount, _transparent, _version);
|
||||
} else if (_sysRect.x == 0 && _sysRect.y == 0) {
|
||||
_vm->_screen->drawSurface2(_surface, _drawRect, _clipRect, _transparent, _version);
|
||||
} else {
|
||||
_vm->_screen->drawUnk(_surface, _drawRect, _sysRect, _clipRect, _transparent, _version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BaseSurface::clear() {
|
||||
_surface->fillRect(Common::Rect(0, 0, _surface->w, _surface->h), 0);
|
||||
++_version;
|
||||
}
|
||||
|
||||
void BaseSurface::drawSpriteResource(SpriteResource &spriteResource) {
|
||||
if (spriteResource.getDimensions().width <= _drawRect.width &&
|
||||
spriteResource.getDimensions().height <= _drawRect.height) {
|
||||
clear();
|
||||
spriteResource.draw(_surface, false, false);
|
||||
++_version;
|
||||
}
|
||||
}
|
||||
|
||||
void BaseSurface::drawSpriteResourceEx(SpriteResource &spriteResource, bool flipX, bool flipY, int16 width, int16 height) {
|
||||
if (spriteResource.getDimensions().width <= _sysRect.width &&
|
||||
spriteResource.getDimensions().height <= _sysRect.height) {
|
||||
if (width > 0 && width <= _sysRect.width)
|
||||
_drawRect.width = width;
|
||||
if (height > 0 && height <= _sysRect.height)
|
||||
_drawRect.height = height;
|
||||
if (_surface) {
|
||||
clear();
|
||||
spriteResource.draw(_surface, flipX, flipY);
|
||||
++_version;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BaseSurface::drawAnimResource(AnimResource &animResource, uint frameIndex, bool flipX, bool flipY, int16 width, int16 height) {
|
||||
if (width > 0 && width <= _sysRect.width)
|
||||
_drawRect.width = width;
|
||||
if (height > 0 && height <= _sysRect.height)
|
||||
_drawRect.height = height;
|
||||
if (_surface) {
|
||||
clear();
|
||||
if (frameIndex < animResource.getFrameCount()) {
|
||||
animResource.draw(frameIndex, _surface, flipX, flipY);
|
||||
++_version;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BaseSurface::drawMouseCursorResource(MouseCursorResource &mouseCursorResource, int frameNum) {
|
||||
if (frameNum < 3) {
|
||||
mouseCursorResource.draw(frameNum, _surface);
|
||||
++_version;
|
||||
}
|
||||
}
|
||||
|
||||
void BaseSurface::copyFrom(Graphics::Surface *sourceSurface, int16 x, int16 y, NDrawRect &sourceRect) {
|
||||
// Copy a rectangle from sourceSurface, 0 is the transparent color
|
||||
// Clipping is performed against the right/bottom border since x, y will always be >= 0
|
||||
|
||||
if (x + sourceRect.width > _surface->w)
|
||||
sourceRect.width = _surface->w - x - 1;
|
||||
|
||||
if (y + sourceRect.height > _surface->h)
|
||||
sourceRect.height = _surface->h - y - 1;
|
||||
|
||||
byte *source = (byte*)sourceSurface->getBasePtr(sourceRect.x, sourceRect.y);
|
||||
byte *dest = (byte*)_surface->getBasePtr(x, y);
|
||||
int height = sourceRect.height;
|
||||
while (height--) {
|
||||
for (int xc = 0; xc < sourceRect.width; xc++)
|
||||
if (source[xc] != 0)
|
||||
dest[xc] = source[xc];
|
||||
source += sourceSurface->pitch;
|
||||
dest += _surface->pitch;
|
||||
}
|
||||
++_version;
|
||||
}
|
||||
|
||||
// ShadowSurface
|
||||
|
||||
ShadowSurface::ShadowSurface(NeverhoodEngine *vm, int priority, int16 width, int16 height, const Common::SharedPtr<BaseSurface> &shadowSurface)
|
||||
: BaseSurface(vm, priority, width, height, "shadow"), _shadowSurface(shadowSurface) {
|
||||
// Empty
|
||||
}
|
||||
|
||||
void ShadowSurface::draw() {
|
||||
if (_surface && _visible && _drawRect.width > 0 && _drawRect.height > 0) {
|
||||
_vm->_screen->drawSurface2(_surface, _drawRect, _clipRect, _transparent, _version, _shadowSurface->getSurface());
|
||||
}
|
||||
}
|
||||
|
||||
// FontSurface
|
||||
|
||||
FontSurface::FontSurface(NeverhoodEngine *vm, NPointArray *tracking, uint charsPerRow, uint16 numRows, byte firstChar, uint16 charWidth, uint16 charHeight)
|
||||
: BaseSurface(vm, 0, charWidth * charsPerRow, charHeight * numRows + 4, "font"), _charsPerRow(charsPerRow), _numRows(numRows),
|
||||
_firstChar(firstChar), _charWidth(charWidth), _charHeight(charHeight), _tracking(nullptr) {
|
||||
|
||||
_tracking = new NPointArray();
|
||||
*_tracking = *tracking;
|
||||
|
||||
}
|
||||
|
||||
FontSurface::FontSurface(NeverhoodEngine *vm, uint32 fileHash, uint charsPerRow, uint16 numRows, byte firstChar, uint16 charWidth, uint16 charHeight)
|
||||
: BaseSurface(vm, 0, charWidth * charsPerRow, charHeight * numRows + 4, "font"), _charsPerRow(charsPerRow), _numRows(numRows),
|
||||
_firstChar(firstChar), _charWidth(charWidth), _charHeight(charHeight), _tracking(nullptr) {
|
||||
|
||||
SpriteResource fontSpriteResource(_vm);
|
||||
fontSpriteResource.load(fileHash, true);
|
||||
drawSpriteResourceEx(fontSpriteResource, false, false, 0, 0);
|
||||
}
|
||||
|
||||
FontSurface::~FontSurface() {
|
||||
delete _tracking;
|
||||
}
|
||||
|
||||
void FontSurface::drawChar(BaseSurface *destSurface, int16 x, int16 y, byte chr) {
|
||||
NDrawRect sourceRect;
|
||||
chr -= _firstChar;
|
||||
sourceRect.x = (chr % _charsPerRow) * _charWidth;
|
||||
sourceRect.y = (chr / _charsPerRow) * _charHeight;
|
||||
sourceRect.width = _charWidth;
|
||||
sourceRect.height = _charHeight;
|
||||
destSurface->copyFrom(_surface, x, y, sourceRect);
|
||||
}
|
||||
|
||||
void FontSurface::drawString(const Common::SharedPtr<BaseSurface> &destSurface, int16 x, int16 y, const byte *string, int stringLen) {
|
||||
BaseSurface *destSurfaceRaw = destSurface.get();
|
||||
|
||||
if (stringLen < 0)
|
||||
stringLen = strlen((const char*)string);
|
||||
|
||||
for (; stringLen > 0; --stringLen, ++string) {
|
||||
drawChar(destSurfaceRaw, x, y, *string);
|
||||
x += _tracking ? (*_tracking)[*string - _firstChar].x : _charWidth;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int16 FontSurface::getStringWidth(const byte *string, int stringLen) {
|
||||
return string ? stringLen * _charWidth : 0;
|
||||
}
|
||||
|
||||
FontSurface *FontSurface::createFontSurface(NeverhoodEngine *vm, uint32 fileHash) {
|
||||
FontSurface *fontSurface;
|
||||
DataResource fontData(vm);
|
||||
SpriteResource fontSprite(vm);
|
||||
fontData.load(calcHash("asRecFont"));
|
||||
uint16 numRows = fontData.getPoint(calcHash("meNumRows")).x;
|
||||
uint16 firstChar = fontData.getPoint(calcHash("meFirstChar")).x;
|
||||
uint16 charWidth = fontData.getPoint(calcHash("meCharWidth")).x;
|
||||
uint16 charHeight = fontData.getPoint(calcHash("meCharHeight")).x;
|
||||
NPointArray *tracking = fontData.getPointArray(calcHash("meTracking"));
|
||||
fontSprite.load(fileHash, true);
|
||||
fontSurface = new FontSurface(vm, tracking, 16, numRows, firstChar, charWidth, charHeight);
|
||||
fontSurface->drawSpriteResourceEx(fontSprite, false, false, 0, 0);
|
||||
return fontSurface;
|
||||
}
|
||||
|
||||
// Misc
|
||||
|
||||
enum BitmapFlags {
|
||||
BF_RLE = 1,
|
||||
BF_HAS_DIMENSIONS = 2,
|
||||
BF_HAS_POSITION = 4,
|
||||
BF_HAS_PALETTE = 8,
|
||||
BF_HAS_IMAGE = 16
|
||||
};
|
||||
|
||||
void parseBitmapResource(const byte *sprite, bool *rle, NDimensions *dimensions, NPoint *position, const byte **palette, const byte **pixels) {
|
||||
|
||||
uint16 flags;
|
||||
|
||||
flags = READ_LE_UINT16(sprite);
|
||||
sprite += 2;
|
||||
|
||||
if (rle)
|
||||
*rle = flags & BF_RLE;
|
||||
|
||||
if (flags & BF_HAS_DIMENSIONS) {
|
||||
if (dimensions) {
|
||||
dimensions->width = READ_LE_UINT16(sprite);
|
||||
dimensions->height = READ_LE_UINT16(sprite + 2);
|
||||
}
|
||||
sprite += 4;
|
||||
} else if (dimensions) {
|
||||
dimensions->width = 1;
|
||||
dimensions->height = 1;
|
||||
}
|
||||
|
||||
if (flags & BF_HAS_POSITION) {
|
||||
if (position) {
|
||||
position->x = READ_LE_UINT16(sprite);
|
||||
position->y = READ_LE_UINT16(sprite + 2);
|
||||
}
|
||||
sprite += 4;
|
||||
} else if (position) {
|
||||
position->x = 0;
|
||||
position->y = 0;
|
||||
}
|
||||
|
||||
if (flags & BF_HAS_PALETTE) {
|
||||
if (palette)
|
||||
*palette = sprite;
|
||||
sprite += 1024;
|
||||
} else if (palette)
|
||||
*palette = nullptr;
|
||||
|
||||
if (flags & BF_HAS_IMAGE) {
|
||||
if (pixels)
|
||||
*pixels = sprite;
|
||||
} else if (pixels)
|
||||
*pixels = nullptr;
|
||||
|
||||
}
|
||||
|
||||
void unpackSpriteRle(const byte *source, int width, int height, byte *dest, int destPitch, bool flipX, bool flipY, byte oldColor, byte newColor) {
|
||||
|
||||
const bool replaceColors = oldColor != newColor;
|
||||
|
||||
int16 rows, chunks;
|
||||
int16 skip, copy;
|
||||
|
||||
if (flipY) {
|
||||
dest += destPitch * (height - 1);
|
||||
destPitch = -destPitch;
|
||||
}
|
||||
|
||||
rows = READ_LE_UINT16(source);
|
||||
chunks = READ_LE_UINT16(source + 2);
|
||||
source += 4;
|
||||
|
||||
do {
|
||||
if (chunks == 0) {
|
||||
dest += rows * destPitch;
|
||||
} else {
|
||||
while (rows-- > 0) {
|
||||
uint16 rowChunks = chunks;
|
||||
while (rowChunks-- > 0) {
|
||||
skip = READ_LE_UINT16(source);
|
||||
copy = READ_LE_UINT16(source + 2);
|
||||
source += 4;
|
||||
if (!flipX) {
|
||||
memcpy(dest + skip, source, copy);
|
||||
} else {
|
||||
byte *flipDest = dest + width - skip - 1;
|
||||
for (int xc = 0; xc < copy; xc++) {
|
||||
*flipDest-- = source[xc];
|
||||
}
|
||||
}
|
||||
source += copy;
|
||||
}
|
||||
if (replaceColors)
|
||||
for (int xc = 0; xc < width; xc++)
|
||||
if (dest[xc] == oldColor)
|
||||
dest[xc] = newColor;
|
||||
dest += destPitch;
|
||||
}
|
||||
}
|
||||
rows = READ_LE_UINT16(source);
|
||||
chunks = READ_LE_UINT16(source + 2);
|
||||
source += 4;
|
||||
} while (rows > 0);
|
||||
|
||||
}
|
||||
|
||||
void unpackSpriteNormal(const byte *source, int width, int height, byte *dest, int destPitch, bool flipX, bool flipY) {
|
||||
|
||||
const int sourcePitch = (width + 3) & 0xFFFC;
|
||||
|
||||
if (flipY) {
|
||||
dest += destPitch * (height - 1);
|
||||
destPitch = -destPitch;
|
||||
}
|
||||
|
||||
if (!flipX) {
|
||||
while (height-- > 0) {
|
||||
memcpy(dest, source, width);
|
||||
source += sourcePitch;
|
||||
dest += destPitch;
|
||||
}
|
||||
} else {
|
||||
while (height-- > 0) {
|
||||
dest += width - 1;
|
||||
for (int xc = 0; xc < width; xc++)
|
||||
*dest-- = source[xc];
|
||||
source += sourcePitch;
|
||||
dest += destPitch;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int calcDistance(int16 x1, int16 y1, int16 x2, int16 y2) {
|
||||
const int16 deltaX = ABS(x1 - x2);
|
||||
const int16 deltaY = ABS(y1 - y2);
|
||||
return (int)sqrt((double)(deltaX * deltaX + deltaY * deltaY));
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
162
engines/neverhood/graphics.h
Normal file
162
engines/neverhood/graphics.h
Normal file
@@ -0,0 +1,162 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_GRAPHICS_H
|
||||
#define NEVERHOOD_GRAPHICS_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/file.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "neverhood/neverhood.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
struct NPoint {
|
||||
int16 x, y;
|
||||
};
|
||||
|
||||
typedef Common::Array<NPoint> NPointArray;
|
||||
|
||||
struct NDimensions {
|
||||
int16 width, height;
|
||||
};
|
||||
|
||||
struct NRect {
|
||||
int16 x1, y1, x2, y2;
|
||||
|
||||
static NRect make(int16 x01, int16 y01, int16 x02, int16 y02) {
|
||||
NRect r;
|
||||
r.set(x01, y01, x02, y02);
|
||||
return r;
|
||||
}
|
||||
|
||||
void set(int16 x01, int16 y01, int16 x02, int16 y02) {
|
||||
x1 = x01;
|
||||
y1 = y01;
|
||||
x2 = x02;
|
||||
y2 = y02;
|
||||
}
|
||||
|
||||
bool contains(int16 x, int16 y) const {
|
||||
return x >= x1 && x <= x2 && y >= y1 && y <= y2;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
typedef Common::Array<NRect> NRectArray;
|
||||
|
||||
// TODO: Use Common::Rect
|
||||
struct NDrawRect {
|
||||
int16 x, y, width, height;
|
||||
NDrawRect() : x(0), y(0), width(0), height(0) {}
|
||||
NDrawRect(int16 x0, int16 y0, int16 width0, int16 height0) : x(x0), y(y0), width(width0), height(height0) {}
|
||||
int16 x2() { return x + width; }
|
||||
int16 y2() { return y + height; }
|
||||
void set(int16 x0, int16 y0, int16 width0, int16 height0) {
|
||||
x = x0;
|
||||
y = y0;
|
||||
width = width0;
|
||||
height = height0;
|
||||
}
|
||||
};
|
||||
|
||||
class AnimResource;
|
||||
class SpriteResource;
|
||||
class MouseCursorResource;
|
||||
|
||||
class BaseSurface {
|
||||
public:
|
||||
BaseSurface(NeverhoodEngine *vm, int priority, int16 width, int16 height, Common::String name);
|
||||
virtual ~BaseSurface();
|
||||
virtual void draw();
|
||||
void clear();
|
||||
void drawSpriteResource(SpriteResource &spriteResource);
|
||||
void drawSpriteResourceEx(SpriteResource &spriteResource, bool flipX, bool flipY, int16 width, int16 height);
|
||||
void drawAnimResource(AnimResource &animResource, uint frameIndex, bool flipX, bool flipY, int16 width, int16 height);
|
||||
void drawMouseCursorResource(MouseCursorResource &mouseCursorResource, int frameNum);
|
||||
void copyFrom(Graphics::Surface *sourceSurface, int16 x, int16 y, NDrawRect &sourceRect);
|
||||
int getPriority() const { return _priority; }
|
||||
void setPriority(int priority) { _priority = priority; }
|
||||
NDrawRect& getDrawRect() { return _drawRect; }
|
||||
NDrawRect& getSysRect() { return _sysRect; }
|
||||
NRect& getClipRect() { return _clipRect; }
|
||||
void setClipRect(NRect clipRect) { _clipRect = clipRect; }
|
||||
void setClipRects(NRect *clipRects, uint clipRectsCount) { _clipRects = clipRects; _clipRectsCount = clipRectsCount; }
|
||||
void clearClipRects() { _clipRects = NULL; _clipRectsCount = 0; }
|
||||
bool getVisible() const { return _visible; }
|
||||
void setVisible(bool value) { _visible = value; }
|
||||
void setTransparent(bool value) { _transparent = value; }
|
||||
Graphics::Surface *getSurface() { return _surface; }
|
||||
const Common::String getName() const { return _name; }
|
||||
protected:
|
||||
NeverhoodEngine *_vm;
|
||||
int _priority;
|
||||
bool _visible;
|
||||
Common::String _name;
|
||||
Graphics::Surface *_surface;
|
||||
NDrawRect _drawRect;
|
||||
NDrawRect _sysRect;
|
||||
NRect _clipRect;
|
||||
NRect *_clipRects;
|
||||
uint _clipRectsCount;
|
||||
bool _transparent;
|
||||
// Version changes each time the pixels are touched in any way
|
||||
byte _version;
|
||||
};
|
||||
|
||||
class ShadowSurface : public BaseSurface {
|
||||
public:
|
||||
ShadowSurface(NeverhoodEngine *vm, int priority, int16 width, int16 height, const Common::SharedPtr<BaseSurface> &shadowSurface);
|
||||
void draw() override;
|
||||
protected:
|
||||
Common::SharedPtr<BaseSurface> _shadowSurface;
|
||||
};
|
||||
|
||||
class FontSurface : public BaseSurface {
|
||||
public:
|
||||
FontSurface(NeverhoodEngine *vm, NPointArray *tracking, uint charsPerRow, uint16 numRows, byte firstChar, uint16 charWidth, uint16 charHeight);
|
||||
FontSurface(NeverhoodEngine *vm, uint32 fileHash, uint charsPerRow, uint16 numRows, byte firstChar, uint16 charWidth, uint16 charHeight);
|
||||
~FontSurface() override;
|
||||
void drawChar(BaseSurface *destSurface, int16 x, int16 y, byte chr);
|
||||
void drawString(const Common::SharedPtr<BaseSurface> &destSurface, int16 x, int16 y, const byte *string, int stringLen = -1);
|
||||
int16 getStringWidth(const byte *string, int stringLen);
|
||||
uint16 getCharWidth() const { return _charWidth; }
|
||||
uint16 getCharHeight() const { return _charHeight; }
|
||||
static FontSurface *createFontSurface(NeverhoodEngine *vm, uint32 fileHash);
|
||||
protected:
|
||||
uint _charsPerRow;
|
||||
uint16 _numRows;
|
||||
byte _firstChar;
|
||||
uint16 _charWidth;
|
||||
uint16 _charHeight;
|
||||
NPointArray *_tracking;
|
||||
};
|
||||
|
||||
// Misc
|
||||
|
||||
void parseBitmapResource(const byte *sprite, bool *rle, NDimensions *dimensions, NPoint *position, const byte **palette, const byte **pixels);
|
||||
void unpackSpriteRle(const byte *source, int width, int height, byte *dest, int destPitch, bool flipX, bool flipY, byte oldColor = 0, byte newColor = 0);
|
||||
void unpackSpriteNormal(const byte *source, int width, int height, byte *dest, int destPitch, bool flipX, bool flipY);
|
||||
int calcDistance(int16 x1, int16 y1, int16 x2, int16 y2);
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_GRAPHICS_H */
|
||||
2769
engines/neverhood/klaymen.cpp
Normal file
2769
engines/neverhood/klaymen.cpp
Normal file
File diff suppressed because it is too large
Load Diff
373
engines/neverhood/klaymen.h
Normal file
373
engines/neverhood/klaymen.h
Normal file
@@ -0,0 +1,373 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_KLAYMEN_H
|
||||
#define NEVERHOOD_KLAYMEN_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/sprite.h"
|
||||
#include "neverhood/graphics.h"
|
||||
#include "neverhood/resource.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// TODO This code is horrible and weird and a lot of stuff needs renaming once a better name is found
|
||||
// TODO Also the methods should probably rearranged and be grouped together more consistently
|
||||
|
||||
class Scene;
|
||||
|
||||
const uint32 kKlaymenSpeedUpHash = 0x004A2148;
|
||||
|
||||
#include "common/pack-start.h" // START STRUCT PACKING
|
||||
|
||||
struct KlaymenIdleTableItem {
|
||||
int weight;
|
||||
uint idleAnimation;
|
||||
};
|
||||
|
||||
#include "common/pack-end.h" // END STRUCT PACKING
|
||||
|
||||
enum {
|
||||
kIdlePickEar,
|
||||
kIdleSpinHead,
|
||||
kIdleArms,
|
||||
kIdleChest,
|
||||
kIdleHeadOff,
|
||||
kIdleTeleporterHands,
|
||||
kIdleTeleporterHands2,
|
||||
kIdleWonderAbout
|
||||
};
|
||||
|
||||
class Klaymen : public AnimatedSprite {
|
||||
public:
|
||||
Klaymen(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRectArray *clipRects = NULL);
|
||||
|
||||
void update();
|
||||
|
||||
void startIdleAnimation(uint32 fileHash, AnimationCb callback);
|
||||
void upIdleAnimation();
|
||||
|
||||
// Idle animations - start
|
||||
void stIdlePickEar();
|
||||
void evIdlePickEarDone();
|
||||
void stIdleSpinHead();
|
||||
void stIdleArms();
|
||||
void evIdleArmsDone();
|
||||
void stIdleChest();
|
||||
void stIdleHeadOff();
|
||||
void stIdleWonderAbout();
|
||||
void stIdleTeleporterHands();
|
||||
void stIdleTeleporterHands2();
|
||||
|
||||
uint32 hmIdlePickEar(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmIdleSpinHead(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmIdleArms(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmIdleChest(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmIdleHeadOff(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
// Idle animations - end
|
||||
|
||||
void stTryStandIdle();
|
||||
void stStandAround();
|
||||
void upStandIdle();
|
||||
void stIdleBlink();
|
||||
|
||||
bool stStartAction(AnimationCb callback3);
|
||||
bool stStartActionFromIdle(AnimationCb callback);
|
||||
uint32 hmStartAction(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stSneak();
|
||||
uint32 hmSneaking(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suSneaking();
|
||||
void evSneakingDone();
|
||||
|
||||
void stStartWalking();
|
||||
void stStartWalkingExt();
|
||||
void stWalkingOpenDoor();
|
||||
void suWalkingOpenDoor();
|
||||
void stStepOver();
|
||||
uint32 hmStartWalking(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void evStartWalkingDone();
|
||||
|
||||
void stWalkingFirst();
|
||||
void stWalkingFirstExt();
|
||||
void stStartWalkingResume();
|
||||
void stUpdateWalkingFirst();
|
||||
uint32 hmWalking(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suWalkingFirst();
|
||||
|
||||
void stWalkToFrontNoStep();
|
||||
void stWalkToFront();
|
||||
void stTurnToFront();
|
||||
void stTurnToBack();
|
||||
uint32 hmWalkToFront(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stTurnToBackToUse();
|
||||
uint32 hmTurnToBackToUse(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stPickUpGeneric();
|
||||
void stPickUpNeedle();
|
||||
uint32 hmPickUpObject(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stPickUpTube();
|
||||
uint32 hmPickUpTube(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stTurnToUse();
|
||||
void stTurnToUseHalf();
|
||||
void stTurnAwayFromUse();
|
||||
void stReturnFromUse();
|
||||
void stTurnToUseExt();
|
||||
uint32 hmTurnToUse(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stLargeStep();
|
||||
uint32 hmLargeStep(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suLargeStep();
|
||||
void evLargeStepDone();
|
||||
|
||||
void stInsertKey();
|
||||
uint32 hmInsertKey(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stPeekWall();
|
||||
uint32 hmPeekWall(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stPeekWallReturn();
|
||||
uint32 hmPeekWallReturn(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stPeekWallBlink();
|
||||
void upPeekWallBlink();
|
||||
|
||||
void stPeekWall1();
|
||||
void stPeekWall2();
|
||||
|
||||
void stGrow();
|
||||
uint32 hmGrow(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stDrinkPotion();
|
||||
uint32 hmDrinkPotion(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stPullCord();
|
||||
void stReleaseCord();
|
||||
uint32 hmPullReleaseCord(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stUseTube();
|
||||
uint32 hmUseTube(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stUseLever();
|
||||
void stUseLeverRelease();
|
||||
void stReleaseLever();
|
||||
void stInteractLever();
|
||||
uint32 hmLever(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stLetGoOfLever();
|
||||
void evLeverReleasedEvent();
|
||||
|
||||
void stPressButton();
|
||||
void stPressFloorButton();
|
||||
void stPressButtonSide();
|
||||
uint32 hmPressButton(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stWonderAbout();
|
||||
void stWonderAboutHalf();
|
||||
void stWonderAboutAfter();
|
||||
|
||||
void stStandWonderAbout();
|
||||
|
||||
void stStartClimbLadderUp();
|
||||
void stStartClimbLadderDown();
|
||||
uint32 hmClimbLadderUpDown(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stContinueClimbLadderUp();
|
||||
|
||||
void stClimbLadderHalf();
|
||||
uint32 hmClimbLadderHalf(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stReleaseRing();
|
||||
|
||||
void stLandOnFeet();
|
||||
uint32 hmLandOnFeet(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stPullLeverDown();
|
||||
void stHoldLeverDown();
|
||||
|
||||
void stInsertDisk();
|
||||
uint32 hmInsertDisk(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stMoveObjectSkipTurnFaceObject();
|
||||
void stMoveObjectSkipTurn();
|
||||
void stMoveObjectFaceObject();
|
||||
uint32 hmMoveObjectTurn(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void evMoveObjectTurnDone();
|
||||
|
||||
void stJumpToGrab();
|
||||
void stJumpToGrabFall();
|
||||
uint32 hmJumpToGrab(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suJumpToGrab();
|
||||
|
||||
void stJumpToGrabRelease();
|
||||
uint32 hmJumpToGrabRelease(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stSitInTeleporter();
|
||||
uint32 hmSitInTeleporter(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stSitIdleTeleporter();
|
||||
void upSitIdleTeleporter();
|
||||
void stSitIdleTeleporterBlink();
|
||||
void stSitIdleTeleporterBlinkSecond();
|
||||
|
||||
void stTurnToUseInTeleporter();
|
||||
void stReturnFromUseInTeleporter();
|
||||
void stGetUpFromTeleporter();
|
||||
|
||||
void teleporterAppear(uint32 fileHash);
|
||||
void teleporterDisappear(uint32 fileHash);
|
||||
uint32 hmTeleporterAppearDisappear(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stFallSkipJump();
|
||||
void suFallSkipJump();
|
||||
|
||||
void stMoveObject();
|
||||
void stContinueMoveObject();
|
||||
uint32 hmMoveObject(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void upMoveObject();
|
||||
|
||||
void stStandIdleSmall();
|
||||
void stWonderAboutSmall();
|
||||
void stWonderAboutHalfSmall();
|
||||
void stWonderAboutAfterSmall();
|
||||
|
||||
void stWalkToFrontNoStepSmall();
|
||||
void stWalkToFrontSmall();
|
||||
void stWalkToFront2Small();
|
||||
void stTurnToBackHalfSmall();
|
||||
void stTurnToBackWalkSmall();
|
||||
void stTurnToBackSmall();
|
||||
uint32 hmWalkFrontBackSmall(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stFinishGrow();
|
||||
uint32 hmFinishGrow(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stStandIdleSpecial();
|
||||
uint32 hmStandIdleSpecial(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void stSpitOutFall0();
|
||||
void stSpitOutFall2();
|
||||
void suFallDown();
|
||||
void upSpitOutFall();
|
||||
|
||||
void stFalling();
|
||||
void stFallTouchdown();
|
||||
|
||||
void stPeekInside();
|
||||
void stPeekInsideReturn();
|
||||
void stPeekInsideBlink();
|
||||
void upPeekInsideBlink();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void stopWalking();
|
||||
|
||||
void suAction();
|
||||
void suUpdateDestX();
|
||||
void suWalkingTestExit();
|
||||
|
||||
uint32 hmLowLevel(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmLowLevelAnimation(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void setKlaymenIdleTable(const KlaymenIdleTableItem *table, uint tableCount);
|
||||
void setKlaymenIdleTable1();
|
||||
void setKlaymenIdleTable2();
|
||||
void setKlaymenIdleTable3();
|
||||
|
||||
void setSoundFlag(bool value) { _soundFlag = value; }
|
||||
|
||||
void stRidePlatform();
|
||||
void suRidePlatform();
|
||||
void stPullLever();
|
||||
void stLookLeverDown();
|
||||
void stWaitLeverDown();
|
||||
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
Sprite *_attachedSprite;
|
||||
int _ladderStatus;
|
||||
bool _isWalking;
|
||||
bool _isSneaking;
|
||||
bool _isLargeStep;
|
||||
bool _isMoveObjectRequested;
|
||||
bool _acceptInput;
|
||||
int16 _destX, _destY;
|
||||
int16 _idleCounter, _idleCounterMax;
|
||||
int16 _blinkCounter, _blinkCounterMax;
|
||||
int16 _tapesToInsert, _keysToInsert;
|
||||
bool _doYHitIncr;
|
||||
bool _isLeverDown;
|
||||
bool _isWalkingOpenDoorNotified;
|
||||
int _busyStatus;
|
||||
bool _actionStatusChanged;
|
||||
int _actionStatus;
|
||||
|
||||
const KlaymenIdleTableItem *_idleTable;
|
||||
uint _idleTableCount;
|
||||
int _idleTableTotalWeight;
|
||||
int _idleTableNum;
|
||||
|
||||
NPointArray *_pathPoints;
|
||||
bool _soundFlag;
|
||||
|
||||
int16 _spitOutCountdown;
|
||||
|
||||
bool _isSittingInTeleporter;
|
||||
|
||||
bool _potionFlag1;
|
||||
bool _potionFlag2;
|
||||
|
||||
int16 _platformDeltaY;
|
||||
|
||||
Sprite *_otherSprite;
|
||||
|
||||
int16 _walkResumeFrameIncr;
|
||||
|
||||
int _moveObjectCountdown;
|
||||
|
||||
virtual void xUpdate();
|
||||
virtual uint32 xHandleMessage(int messageNum, const MessageParam ¶m);
|
||||
|
||||
void startWalkToX(int16 x, bool walkExt);
|
||||
void startWalkToXExt(int16 x);
|
||||
void startWalkToXSmall(int16 x);
|
||||
void startSpecialWalkLeft(int16 x);
|
||||
void startSpecialWalkRight(int16 x);
|
||||
void startWalkToXDistance(int16 destX, int16 distance);
|
||||
void startWalkToAttachedSpriteXDistance(int16 distance);
|
||||
|
||||
void gotoNextStateExt();
|
||||
void beginAction();
|
||||
void endAction();
|
||||
|
||||
void stStartWalkingSmall();
|
||||
uint32 hmWalkingSmall(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void enterIdleAnimation(uint idleAnimation);
|
||||
void walkAlongPathPoints();
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_KLAYMEN_H */
|
||||
1293
engines/neverhood/menumodule.cpp
Normal file
1293
engines/neverhood/menumodule.cpp
Normal file
File diff suppressed because it is too large
Load Diff
267
engines/neverhood/menumodule.h
Normal file
267
engines/neverhood/menumodule.h
Normal file
@@ -0,0 +1,267 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MENUMODULE_H
|
||||
#define NEVERHOOD_MENUMODULE_H
|
||||
|
||||
#include "common/str.h"
|
||||
#include "common/str-array.h"
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
struct SavegameItem {
|
||||
int slotNum;
|
||||
Common::String description;
|
||||
};
|
||||
|
||||
typedef Common::Array<SavegameItem> SavegameList;
|
||||
|
||||
class MenuModule : public Module {
|
||||
public:
|
||||
MenuModule(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~MenuModule() override;
|
||||
void setLoadgameInfo(uint index);
|
||||
void setLoadgameSlot(int slot);
|
||||
void setSavegameInfo(const Common::String &description, uint index, bool newSavegame);
|
||||
void setDeletegameInfo(uint index);
|
||||
void refreshSaveGameList();
|
||||
protected:
|
||||
int _sceneNum;
|
||||
byte *_savedPaletteData;
|
||||
SavegameList *_savegameList;
|
||||
Common::String _savegameDescription;
|
||||
int _savegameSlot;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void createLoadGameMenu();
|
||||
void createSaveGameMenu();
|
||||
void createDeleteGameMenu();
|
||||
void handleLoadGameMenuAction(bool doLoad);
|
||||
void handleSaveGameMenuAction(bool doSave, bool doQuery);
|
||||
void handleDeleteGameMenuAction(bool doDelete);
|
||||
void loadSavegameList();
|
||||
};
|
||||
|
||||
class MenuButton : public StaticSprite {
|
||||
public:
|
||||
MenuButton(NeverhoodEngine *vm, Scene *parentScene, uint buttonIndex, uint32 fileHash, const NRect &collisionBounds);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _countdown;
|
||||
uint _buttonIndex;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class MainMenu : public Scene {
|
||||
public:
|
||||
MainMenu(NeverhoodEngine *vm, Module *parentModule);
|
||||
bool hasMakingOf() const;
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class CreditsScene : public Scene {
|
||||
public:
|
||||
CreditsScene(NeverhoodEngine *vm, Module *parentModule, bool canAbort);
|
||||
~CreditsScene() override;
|
||||
protected:
|
||||
int _screenIndex;
|
||||
int _countdown;
|
||||
MusicResource *_musicResource;
|
||||
uint32 _ticksTime;
|
||||
uint32 _ticksDuration;
|
||||
bool _canAbort;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Widget;
|
||||
class GameStateMenu;
|
||||
|
||||
class Widget : public StaticSprite {
|
||||
public:
|
||||
Widget(NeverhoodEngine *vm, int16 x, int16 y, GameStateMenu *parentScene,
|
||||
int baseObjectPriority, int baseSurfacePriority);
|
||||
virtual void onClick();
|
||||
virtual void setPosition(int16 x, int16 y);
|
||||
virtual void refreshPosition();
|
||||
virtual void initialize();
|
||||
virtual int16 getWidth();
|
||||
virtual int16 getHeight();
|
||||
virtual void enterWidget();
|
||||
virtual void exitWidget();
|
||||
protected:
|
||||
GameStateMenu *_parentScene;
|
||||
int _baseObjectPriority;
|
||||
int _baseSurfacePriority;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class TextLabelWidget : public Widget {
|
||||
public:
|
||||
TextLabelWidget(NeverhoodEngine *vm, int16 x, int16 y, GameStateMenu *parentScene,
|
||||
int baseObjectPriority, int baseSurfacePriority,
|
||||
const byte *string, int stringLen, const Common::SharedPtr<BaseSurface> &drawSurface, int16 tx, int16 ty, const Common::SharedPtr<FontSurface> &fontSurface);
|
||||
void initialize() override;
|
||||
int16 getWidth() override;
|
||||
int16 getHeight() override;
|
||||
void drawString(int maxStringLength);
|
||||
void clear();
|
||||
void setString(const byte *string, int stringLen);
|
||||
Common::SharedPtr<FontSurface> getFontSurface() const { return _fontSurface; }
|
||||
protected:
|
||||
Common::SharedPtr<BaseSurface> _drawSurface;
|
||||
int16 _tx, _ty;
|
||||
Common::SharedPtr<FontSurface> _fontSurface;
|
||||
const byte *_string;
|
||||
int _stringLen;
|
||||
};
|
||||
|
||||
class TextEditWidget : public Widget {
|
||||
public:
|
||||
TextEditWidget(NeverhoodEngine *vm, int16 x, int16 y, GameStateMenu *parentScene,
|
||||
int maxStringLength, const Common::SharedPtr<FontSurface> &fontSurface, uint32 fileHash, const NRect &rect);
|
||||
~TextEditWidget() override;
|
||||
void onClick() override;
|
||||
void initialize() override;
|
||||
void enterWidget() override;
|
||||
void exitWidget() override;
|
||||
void setCursor(uint32 cursorFileHash, int16 cursorWidth, int16 cursorHeight);
|
||||
void drawCursor();
|
||||
void updateString();
|
||||
Common::String& getString();
|
||||
void setString(const Common::String &string);
|
||||
void handleAsciiKey(char ch);
|
||||
void handleKeyDown(Common::KeyCode keyCode);
|
||||
void refresh();
|
||||
void setReadOnly(bool value) { _readOnly = value; }
|
||||
bool isReadOnly() const { return _readOnly; }
|
||||
bool isModified() const { return _modified; }
|
||||
protected:
|
||||
NRect _rect;
|
||||
uint32 _fileHash;
|
||||
int _maxVisibleChars;
|
||||
int _maxStringLength;
|
||||
int _cursorPos;
|
||||
int _cursorTicks;
|
||||
Common::String _entryString;
|
||||
Common::SharedPtr<FontSurface> _fontSurface;
|
||||
TextLabelWidget *_textLabelWidget;
|
||||
BaseSurface *_cursorSurface;
|
||||
uint32 _cursorFileHash;
|
||||
int16 _cursorWidth, _cursorHeight;
|
||||
bool _modified;
|
||||
bool _readOnly;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class SavegameListBox : public Widget {
|
||||
public:
|
||||
SavegameListBox(NeverhoodEngine *vm, int16 x, int16 y, GameStateMenu *parentScene,
|
||||
SavegameList *savegameList, const Common::SharedPtr<FontSurface> &fontSurface, uint32 bgFileHash, const NRect &rect);
|
||||
void onClick() override;
|
||||
void initialize() override;
|
||||
void buildItems();
|
||||
void drawItems();
|
||||
void refresh();
|
||||
void scrollUp();
|
||||
void scrollDown();
|
||||
void pageUp();
|
||||
void pageDown();
|
||||
uint getCurrIndex() const { return _currIndex; }
|
||||
protected:
|
||||
const NRect _rect;
|
||||
uint32 _bgFileHash;
|
||||
int _maxStringLength;
|
||||
Common::Array<TextLabelWidget*> _textLabelItems;
|
||||
int _firstVisibleItem;
|
||||
int _lastVisibleItem;
|
||||
SavegameList *_savegameList;
|
||||
Common::SharedPtr<FontSurface> _fontSurface;
|
||||
uint _currIndex;
|
||||
int _maxVisibleItemsCount;
|
||||
};
|
||||
|
||||
class GameStateMenu : public Scene {
|
||||
public:
|
||||
GameStateMenu(NeverhoodEngine *vm, Module *parentModule, SavegameList *savegameList,
|
||||
const uint32 *buttonFileHashes, const NRect *buttonCollisionBounds,
|
||||
uint32 backgroundFileHash, uint32 fontFileHash,
|
||||
uint32 mouseFileHash, const NRect *mouseRect,
|
||||
uint32 listBoxBackgroundFileHash, int16 listBoxX, int16 listBoxY, const NRect &listBoxRect,
|
||||
uint32 textEditBackgroundFileHash, uint32 textEditCursorFileHash, int16 textEditX, int16 textEditY, const NRect &textEditRect,
|
||||
uint32 textFileHash1, uint32 textFileHash2);
|
||||
NPoint getMousePos();
|
||||
virtual void setCurrWidget(Widget *newWidget);
|
||||
virtual Widget *getCurrWidget() { return _currWidget; }
|
||||
virtual void refreshDescriptionEdit();
|
||||
protected:
|
||||
Widget *_currWidget;
|
||||
SavegameList *_savegameList;
|
||||
Common::SharedPtr<FontSurface> _fontSurface;
|
||||
SavegameListBox *_listBox;
|
||||
TextEditWidget *_textEditWidget;
|
||||
Common::String _savegameDescription;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
virtual void performAction();
|
||||
int scummVMSaveLoadDialog(bool isSave, Common::String &saveDesc);
|
||||
};
|
||||
|
||||
class SaveGameMenu : public GameStateMenu {
|
||||
public:
|
||||
SaveGameMenu(NeverhoodEngine *vm, Module *parentModule, SavegameList *savegameList);
|
||||
protected:
|
||||
void performAction() override;
|
||||
};
|
||||
|
||||
class LoadGameMenu : public GameStateMenu {
|
||||
public:
|
||||
LoadGameMenu(NeverhoodEngine *vm, Module *parentModule, SavegameList *savegameList);
|
||||
protected:
|
||||
void performAction() override;
|
||||
};
|
||||
|
||||
class DeleteGameMenu : public GameStateMenu {
|
||||
public:
|
||||
DeleteGameMenu(NeverhoodEngine *vm, Module *parentModule, SavegameList *savegameList);
|
||||
protected:
|
||||
void performAction() override;
|
||||
};
|
||||
|
||||
class QueryOverwriteMenu : public Scene {
|
||||
public:
|
||||
QueryOverwriteMenu(NeverhoodEngine *vm, Module *parentModule, const Common::String &description);
|
||||
protected:
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void displayOverwriteStrings(const Common::String &description);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MENUMODULE_H */
|
||||
77
engines/neverhood/messages.h
Normal file
77
engines/neverhood/messages.h
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MESSAGES_H
|
||||
#define NEVERHOOD_MESSAGES_H
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
enum NeverhoodMessage {
|
||||
NM_MOUSE_MOVE = 0x0000,
|
||||
NM_MOUSE_CLICK = 0x0001,
|
||||
NM_MOUSE_RELEASE = 0x0002,
|
||||
NM_MOUSE_HIDE = 0x101D,
|
||||
NM_MOUSE_SHOW = 0x101E,
|
||||
NM_KEYPRESS_SPACE = 0x0009,
|
||||
NM_KEYPRESS_ESC = 0x000C,
|
||||
NM_CHEAT = 0x000D,
|
||||
NM_ANIMATION_START = 0x100D,
|
||||
NM_SCENE_LEAVE = 0x1019,
|
||||
NM_PRIORITY_CHANGE = 0x1022,
|
||||
NM_ANIMATION_UPDATE = 0x2000,
|
||||
NM_POSITION_CHANGE = 0x2002,
|
||||
NM_KLAYMEN_CLIMB_LADDER = 0x2005,
|
||||
NM_KLAYMEN_STOP_CLIMBING = 0x2006,
|
||||
|
||||
NM_CAR_MOVE_TO_PREV_POINT = 0x2007,
|
||||
NM_CAR_MOVE_TO_NEXT_POINT = 0x2008,
|
||||
NM_CAR_ENTER = 0x2009,
|
||||
NM_CAR_LEAVE = 0x200A,
|
||||
NM_CAR_TURN = 0x200E,
|
||||
NM_CAR_AT_HOME = 0x200F,
|
||||
|
||||
NM_ANIMATION_STOP = 0x3002,
|
||||
|
||||
NM_KLAYMEN_STAND_IDLE = 0x4004,
|
||||
NM_KLAYMEN_USE_OBJECT = 0x4806,
|
||||
NM_KLAYMEN_RAISE_LEVER = 0x4807,
|
||||
NM_KLAYMEN_OPEN_DOOR = 0x4808,
|
||||
NM_KLAYMEN_CLOSE_DOOR = 0x4809,
|
||||
NM_KLAYMEN_MOVE_OBJECT = 0x480A,
|
||||
NM_KLAYMEN_LOWER_LEVER = 0x480F,
|
||||
NM_KLAYMEN_PICKUP = 0x4812,
|
||||
NM_KLAYMEN_PRESS_BUTTON = 0x4816,
|
||||
NM_KLAYMEN_INSERT_DISK = 0x481A,
|
||||
NM_KLAYMEN_TURN_TO_USE = 0x481D,
|
||||
NM_KLAYMEN_RETURN_FROM_USE = 0x481E,
|
||||
NM_KLAYMEN_RELEASE_LEVER = 0x4827,
|
||||
|
||||
NM_MOVE_TO_BACK = 0x482A,
|
||||
NM_MOVE_TO_FRONT = 0x482B,
|
||||
|
||||
// New to ScummVM
|
||||
NM_MOUSE_WHEELUP = 0xF000,
|
||||
NM_MOUSE_WHEELDOWN = 0xF001
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MESSAGES_H */
|
||||
249
engines/neverhood/metaengine.cpp
Normal file
249
engines/neverhood/metaengine.cpp
Normal file
@@ -0,0 +1,249 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "base/plugins.h"
|
||||
|
||||
#include "engines/advancedDetector.h"
|
||||
#include "common/file.h"
|
||||
|
||||
#include "neverhood/dialogs.h"
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/detection.h"
|
||||
|
||||
#include "common/translation.h"
|
||||
|
||||
#include "backends/keymapper/action.h"
|
||||
#include "backends/keymapper/keymapper.h"
|
||||
#include "backends/keymapper/standard-actions.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
const char *NeverhoodEngine::getGameId() const {
|
||||
return _gameDescription->gameId;
|
||||
}
|
||||
|
||||
Common::Platform NeverhoodEngine::getPlatform() const {
|
||||
return _gameDescription->platform;
|
||||
}
|
||||
|
||||
Common::Language NeverhoodEngine::getLanguage() const {
|
||||
return _gameDescription->language;
|
||||
}
|
||||
|
||||
bool NeverhoodEngine::isDemo() const {
|
||||
return _gameDescription->flags & ADGF_DEMO;
|
||||
}
|
||||
|
||||
bool NeverhoodEngine::isBigDemo() const {
|
||||
return _gameDescription->flags & GF_BIG_DEMO;
|
||||
}
|
||||
|
||||
bool NeverhoodEngine::applyResourceFixes() const {
|
||||
return getLanguage() == Common::RU_RUS;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
class NeverhoodMetaEngine : public AdvancedMetaEngine<ADGameDescription> {
|
||||
public:
|
||||
const char *getName() const override {
|
||||
return "neverhood";
|
||||
}
|
||||
|
||||
GUI::OptionsContainerWidget *buildEngineOptionsWidget(GUI::GuiObject *boss, const Common::String &name, const Common::String &target) const override {
|
||||
return new Neverhood::NeverhoodOptionsWidget(boss, name, target);
|
||||
}
|
||||
|
||||
bool hasFeature(MetaEngineFeature f) const override;
|
||||
Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
|
||||
|
||||
SaveStateList listSaves(const char *target) const override;
|
||||
int getMaximumSaveSlot() const override;
|
||||
bool removeSaveState(const char *target, int slot) const override;
|
||||
SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const override;
|
||||
Common::KeymapArray initKeymaps(const char *target) const override;
|
||||
};
|
||||
|
||||
bool NeverhoodMetaEngine::hasFeature(MetaEngineFeature f) const {
|
||||
return
|
||||
(f == kSupportsListSaves) ||
|
||||
(f == kSupportsLoadingDuringStartup) ||
|
||||
(f == kSupportsDeleteSave) ||
|
||||
(f == kSavesSupportMetaInfo) ||
|
||||
(f == kSavesSupportThumbnail) ||
|
||||
(f == kSavesSupportCreationDate) ||
|
||||
(f == kSavesSupportPlayTime) ||
|
||||
(f == kSimpleSavesNames);
|
||||
}
|
||||
|
||||
bool Neverhood::NeverhoodEngine::hasFeature(EngineFeature f) const {
|
||||
return
|
||||
(f == kSupportsReturnToLauncher) ||
|
||||
(f == kSupportsLoadingDuringRuntime) ||
|
||||
(f == kSupportsSavingDuringRuntime);
|
||||
}
|
||||
|
||||
Common::Error NeverhoodMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
|
||||
*engine = new Neverhood::NeverhoodEngine(syst, desc);
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
SaveStateList NeverhoodMetaEngine::listSaves(const char *target) const {
|
||||
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
|
||||
Neverhood::NeverhoodEngine::SaveHeader header;
|
||||
Common::String pattern = target;
|
||||
pattern += ".###";
|
||||
|
||||
Common::StringArray filenames;
|
||||
filenames = saveFileMan->listSavefiles(pattern.c_str());
|
||||
|
||||
SaveStateList saveList;
|
||||
for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); file++) {
|
||||
// Obtain the last 3 digits of the filename, since they correspond to the save slot
|
||||
int slotNum = atoi(file->c_str() + file->size() - 3);
|
||||
if (slotNum >= 0 && slotNum <= 999) {
|
||||
Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
|
||||
if (in) {
|
||||
if (Neverhood::NeverhoodEngine::readSaveHeader(in, header) == Neverhood::NeverhoodEngine::kRSHENoError) {
|
||||
saveList.push_back(SaveStateDescriptor(this, slotNum, header.description));
|
||||
}
|
||||
delete in;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort saves based on slot number.
|
||||
Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator());
|
||||
return saveList;
|
||||
}
|
||||
|
||||
int NeverhoodMetaEngine::getMaximumSaveSlot() const {
|
||||
return 999;
|
||||
}
|
||||
|
||||
bool NeverhoodMetaEngine::removeSaveState(const char *target, int slot) const {
|
||||
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
|
||||
Common::String filename = Neverhood::NeverhoodEngine::getSavegameFilename(target, slot);
|
||||
return saveFileMan->removeSavefile(filename.c_str());
|
||||
}
|
||||
|
||||
SaveStateDescriptor NeverhoodMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
|
||||
Common::String filename = Neverhood::NeverhoodEngine::getSavegameFilename(target, slot);
|
||||
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename.c_str());
|
||||
|
||||
if (in) {
|
||||
Neverhood::NeverhoodEngine::SaveHeader header;
|
||||
Neverhood::NeverhoodEngine::kReadSaveHeaderError error;
|
||||
|
||||
error = Neverhood::NeverhoodEngine::readSaveHeader(in, header, false);
|
||||
delete in;
|
||||
|
||||
if (error == Neverhood::NeverhoodEngine::kRSHENoError) {
|
||||
SaveStateDescriptor desc(this, slot, header.description);
|
||||
|
||||
desc.setThumbnail(header.thumbnail);
|
||||
int day = (header.saveDate >> 24) & 0xFF;
|
||||
int month = (header.saveDate >> 16) & 0xFF;
|
||||
int year = header.saveDate & 0xFFFF;
|
||||
desc.setSaveDate(year, month, day);
|
||||
int hour = (header.saveTime >> 16) & 0xFF;
|
||||
int minutes = (header.saveTime >> 8) & 0xFF;
|
||||
desc.setSaveTime(hour, minutes);
|
||||
desc.setPlayTime(header.playTime * 1000);
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
|
||||
return SaveStateDescriptor();
|
||||
}
|
||||
|
||||
Common::KeymapArray NeverhoodMetaEngine::initKeymaps(const char *target) const {
|
||||
using namespace Common;
|
||||
using namespace Neverhood;
|
||||
|
||||
Common::String extra = ConfMan.get("extra", target);
|
||||
const bool isDemo = extra.contains("Demo");
|
||||
|
||||
Keymap *engineKeyMap = new Keymap(Keymap::kKeymapTypeGame, "neverhood-default", _("Default keymappings"));
|
||||
Keymap *gameKeymap = new Keymap(Keymap::kKeymapTypeGame, "game", _("Game keymappings"));
|
||||
Keymap *saveMenuKeymap = new Keymap(Keymap::kKeymapTypeGame, "save-management", _("Save file management menus keymappings"));
|
||||
Keymap *pauseKeymap = new Keymap(Keymap::kKeymapTypeGame, "pause", _("Pause menu keymappings"));
|
||||
|
||||
Action *act;
|
||||
|
||||
act = new Action(kStandardActionInteract, _("Move / Interact"));
|
||||
act->setLeftClickEvent();
|
||||
act->addDefaultInputMapping("MOUSE_LEFT");
|
||||
act->addDefaultInputMapping("MOUSE_RIGHT");
|
||||
act->addDefaultInputMapping("JOY_A");
|
||||
engineKeyMap->addAction(act);
|
||||
|
||||
if (isDemo) {
|
||||
act = new Action("QUIT", _("Quit"));
|
||||
act->setCustomEngineActionEvent(kActionQuit);
|
||||
act->addDefaultInputMapping("ESCAPE");
|
||||
act->addDefaultInputMapping("JOY_Y");
|
||||
pauseKeymap->addAction(act);
|
||||
} else {
|
||||
act = new Action("PAUSE", _("Pause / Exit menu"));
|
||||
act->setCustomEngineActionEvent(kActionPause);
|
||||
act->addDefaultInputMapping("ESCAPE");
|
||||
act->addDefaultInputMapping("JOY_Y");
|
||||
pauseKeymap->addAction(act);
|
||||
}
|
||||
|
||||
// I18N: (Game name: The Neverhood) The game has multiple cutscenes, and this action skips part of the scene.
|
||||
act = new Action("SKIP", _("Skip section of cutscene"));
|
||||
act->setCustomEngineActionEvent(kActionSkipPartial);
|
||||
act->addDefaultInputMapping("SPACE");
|
||||
act->addDefaultInputMapping("JOY_B");
|
||||
gameKeymap->addAction(act);
|
||||
|
||||
// I18N: (Game name: The Neverhood) The game has multiple cutscenes, and this action skips the entire scene.
|
||||
act = new Action("SKIPCREDITS", _("Skip entire scene (works only in some scenes)"));
|
||||
act->setCustomEngineActionEvent(kActionSkipFull);
|
||||
act->addDefaultInputMapping("ESCAPE");
|
||||
act->addDefaultInputMapping("JOY_X");
|
||||
gameKeymap->addAction(act);
|
||||
|
||||
// I18N: (Game name: The Neverhood) This action confirms the selected save or entered new save name in the save file management menus.
|
||||
act = new Action("Confirm", _("Confirm the selected save / new save name"));
|
||||
act->setCustomEngineActionEvent(kActionConfirm);
|
||||
act->addDefaultInputMapping("RETURN");
|
||||
act->addDefaultInputMapping("JOY_X");
|
||||
saveMenuKeymap->addAction(act);
|
||||
|
||||
KeymapArray keymaps(4);
|
||||
keymaps[0] = engineKeyMap;
|
||||
keymaps[1] = gameKeymap;
|
||||
keymaps[2] = pauseKeymap;
|
||||
keymaps[3] = saveMenuKeymap;
|
||||
|
||||
saveMenuKeymap->setEnabled(false);
|
||||
|
||||
return keymaps;
|
||||
}
|
||||
|
||||
#if PLUGIN_ENABLED_DYNAMIC(NEVERHOOD)
|
||||
REGISTER_PLUGIN_DYNAMIC(NEVERHOOD, PLUGIN_TYPE_ENGINE, NeverhoodMetaEngine);
|
||||
#else
|
||||
REGISTER_PLUGIN_STATIC(NEVERHOOD, PLUGIN_TYPE_ENGINE, NeverhoodMetaEngine);
|
||||
#endif
|
||||
158
engines/neverhood/microtiles.cpp
Normal file
158
engines/neverhood/microtiles.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/microtiles.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
MicroTileArray::MicroTileArray(int16 width, int16 height) {
|
||||
_tilesW = (width / TileSize) + ((width % TileSize) > 0 ? 1 : 0);
|
||||
_tilesH = (height / TileSize) + ((height % TileSize) > 0 ? 1 : 0);
|
||||
_tiles = new BoundingBox[_tilesW * _tilesH];
|
||||
clear();
|
||||
}
|
||||
|
||||
MicroTileArray::~MicroTileArray() {
|
||||
delete[] _tiles;
|
||||
}
|
||||
|
||||
void MicroTileArray::addRect(Common::Rect r) {
|
||||
|
||||
int ux0, uy0, ux1, uy1;
|
||||
int tx0, ty0, tx1, ty1;
|
||||
int ix0, iy0, ix1, iy1;
|
||||
|
||||
r.clip(Common::Rect(0, 0, 639, 479));
|
||||
|
||||
ux0 = r.left / TileSize;
|
||||
uy0 = r.top / TileSize;
|
||||
ux1 = r.right / TileSize;
|
||||
uy1 = r.bottom / TileSize;
|
||||
|
||||
tx0 = r.left % TileSize;
|
||||
ty0 = r.top % TileSize;
|
||||
tx1 = r.right % TileSize;
|
||||
ty1 = r.bottom % TileSize;
|
||||
|
||||
for (int yc = uy0; yc <= uy1; yc++) {
|
||||
for (int xc = ux0; xc <= ux1; xc++) {
|
||||
ix0 = (xc == ux0) ? tx0 : 0;
|
||||
ix1 = (xc == ux1) ? tx1 : TileSize - 1;
|
||||
iy0 = (yc == uy0) ? ty0 : 0;
|
||||
iy1 = (yc == uy1) ? ty1 : TileSize - 1;
|
||||
updateBoundingBox(_tiles[xc + yc * _tilesW], ix0, iy0, ix1, iy1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MicroTileArray::clear() {
|
||||
memset(_tiles, 0, _tilesW * _tilesH * sizeof(BoundingBox));
|
||||
}
|
||||
|
||||
byte MicroTileArray::TileX0(const BoundingBox &boundingBox) {
|
||||
return (boundingBox >> 24) & 0xFF;
|
||||
}
|
||||
|
||||
byte MicroTileArray::TileY0(const BoundingBox &boundingBox) {
|
||||
return (boundingBox >> 16) & 0xFF;
|
||||
}
|
||||
|
||||
byte MicroTileArray::TileX1(const BoundingBox &boundingBox) {
|
||||
return (boundingBox >> 8) & 0xFF;
|
||||
}
|
||||
|
||||
byte MicroTileArray::TileY1(const BoundingBox &boundingBox) {
|
||||
return boundingBox & 0xFF;
|
||||
}
|
||||
|
||||
bool MicroTileArray::isBoundingBoxEmpty(const BoundingBox &boundingBox) {
|
||||
return boundingBox == EmptyBoundingBox;
|
||||
}
|
||||
|
||||
bool MicroTileArray::isBoundingBoxFull(const BoundingBox &boundingBox) {
|
||||
return boundingBox == FullBoundingBox;
|
||||
}
|
||||
|
||||
void MicroTileArray::setBoundingBox(BoundingBox &boundingBox, byte x0, byte y0, byte x1, byte y1) {
|
||||
boundingBox = (x0 << 24) | (y0 << 16) | (x1 << 8) | y1;
|
||||
}
|
||||
|
||||
void MicroTileArray::updateBoundingBox(BoundingBox &boundingBox, byte x0, byte y0, byte x1, byte y1) {
|
||||
if (!isBoundingBoxEmpty(boundingBox)) {
|
||||
x0 = MIN(TileX0(boundingBox), x0);
|
||||
y0 = MIN(TileY0(boundingBox), y0);
|
||||
x1 = MAX(TileX1(boundingBox), x1);
|
||||
y1 = MAX(TileY1(boundingBox), y1);
|
||||
}
|
||||
setBoundingBox(boundingBox, x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
RectangleList *MicroTileArray::getRectangles() {
|
||||
|
||||
RectangleList *rects = new RectangleList();
|
||||
|
||||
int x, y;
|
||||
int x0, y0, x1, y1;
|
||||
int i = 0;
|
||||
|
||||
for (y = 0; y < _tilesH; ++y) {
|
||||
for (x = 0; x < _tilesW; ++x) {
|
||||
int finish = 0;
|
||||
BoundingBox boundingBox = _tiles[i];
|
||||
|
||||
if (isBoundingBoxEmpty(boundingBox)) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
x0 = (x * TileSize) + TileX0(boundingBox);
|
||||
y0 = (y * TileSize) + TileY0(boundingBox);
|
||||
y1 = (y * TileSize) + TileY1(boundingBox);
|
||||
|
||||
if (TileX1(boundingBox) == TileSize - 1 && x != _tilesW - 1) { // check if the tile continues
|
||||
while (!finish) {
|
||||
++x;
|
||||
++i;
|
||||
if (x == _tilesW || i >= _tilesW * _tilesH ||
|
||||
TileY0(_tiles[i]) != TileY0(boundingBox) ||
|
||||
TileY1(_tiles[i]) != TileY1(boundingBox) ||
|
||||
TileX0(_tiles[i]) != 0)
|
||||
{
|
||||
--x;
|
||||
--i;
|
||||
finish = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x1 = (x * TileSize) + TileX1(_tiles[i]);
|
||||
|
||||
rects->push_back(Common::Rect(x0, y0, x1 + 1, y1 + 1));
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
return rects;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
62
engines/neverhood/microtiles.h
Normal file
62
engines/neverhood/microtiles.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MICROTILES_H
|
||||
#define NEVERHOOD_MICROTILES_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/list.h"
|
||||
#include "common/util.h"
|
||||
#include "common/rect.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
typedef uint32 BoundingBox;
|
||||
|
||||
const BoundingBox FullBoundingBox = 0x00001F1F;
|
||||
const BoundingBox EmptyBoundingBox = 0x00000000;
|
||||
const int TileSize = 32;
|
||||
|
||||
typedef Common::List<Common::Rect> RectangleList;
|
||||
|
||||
class MicroTileArray {
|
||||
public:
|
||||
MicroTileArray(int16 width, int16 height);
|
||||
~MicroTileArray();
|
||||
void addRect(Common::Rect r);
|
||||
void clear();
|
||||
RectangleList *getRectangles();
|
||||
protected:
|
||||
BoundingBox *_tiles;
|
||||
int16 _tilesW, _tilesH;
|
||||
byte TileX0(const BoundingBox &boundingBox);
|
||||
byte TileY0(const BoundingBox &boundingBox);
|
||||
byte TileX1(const BoundingBox &boundingBox);
|
||||
byte TileY1(const BoundingBox &boundingBox);
|
||||
bool isBoundingBoxEmpty(const BoundingBox &boundingBox);
|
||||
bool isBoundingBoxFull(const BoundingBox &boundingBox);
|
||||
void setBoundingBox(BoundingBox &boundingBox, byte x0, byte y0, byte x1, byte y1);
|
||||
void updateBoundingBox(BoundingBox &boundingBox, byte x0, byte y0, byte x1, byte y1);
|
||||
};
|
||||
|
||||
} // namespace Neverhood
|
||||
|
||||
#endif // NEVERHOOD_MICROTILES_H
|
||||
72
engines/neverhood/module.h
Normal file
72
engines/neverhood/module.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// TODO: I couldn't come up with a better name than 'Module' so far
|
||||
|
||||
#ifndef NEVERHOOD_MODULE_H
|
||||
#define NEVERHOOD_MODULE_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/background.h"
|
||||
#include "neverhood/entity.h"
|
||||
#include "neverhood/graphics.h"
|
||||
#include "neverhood/mouse.h"
|
||||
#include "neverhood/palette.h"
|
||||
#include "neverhood/screen.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class NavigationScene;
|
||||
|
||||
enum SceneType {
|
||||
kSceneTypeNormal,
|
||||
kSceneTypeSmacker,
|
||||
kSceneTypeNavigation
|
||||
};
|
||||
|
||||
class Module : public Entity {
|
||||
public:
|
||||
Module(NeverhoodEngine *vm, Module *parentModule);
|
||||
~Module() override;
|
||||
void draw() override;
|
||||
SceneType getSceneType() { return _sceneType; }
|
||||
|
||||
Entity *_childObject;
|
||||
protected:
|
||||
Module *_parentModule;
|
||||
bool _done;
|
||||
uint32 _moduleResult;
|
||||
SceneType _sceneType;
|
||||
int _navigationAreaType;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
NavigationScene *navigationScene();
|
||||
void createNavigationScene(uint32 navigationListId, int navigationIndex, const byte *itemsTypes = NULL);
|
||||
void createSmackerScene(uint32 fileHash, bool doubleSurface, bool canSkip, bool canAbort);
|
||||
void createSmackerScene(const uint32 *fileHashList, bool doubleSurface, bool canSkip, bool canAbort);
|
||||
void createStaticScene(uint32 backgroundFileHash, uint32 cursorFileHash);
|
||||
void createDemoScene();
|
||||
bool updateChild();
|
||||
void leaveModule(uint32 result);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULE_H */
|
||||
83
engines/neverhood/module.mk
Normal file
83
engines/neverhood/module.mk
Normal file
@@ -0,0 +1,83 @@
|
||||
MODULE := engines/neverhood
|
||||
|
||||
MODULE_OBJS = \
|
||||
background.o \
|
||||
blbarchive.o \
|
||||
console.o \
|
||||
dialogs.o \
|
||||
diskplayerscene.o \
|
||||
entity.o \
|
||||
gamemodule.o \
|
||||
gamevars.o \
|
||||
graphics.o \
|
||||
klaymen.o \
|
||||
menumodule.o \
|
||||
metaengine.o \
|
||||
microtiles.o \
|
||||
module_scene.o \
|
||||
modules/module1000.o \
|
||||
modules/module1000_sprites.o \
|
||||
modules/module1100.o \
|
||||
modules/module1100_sprites.o \
|
||||
modules/module1200.o \
|
||||
modules/module1200_sprites.o \
|
||||
modules/module1300.o \
|
||||
modules/module1300_sprites.o \
|
||||
modules/module1400.o \
|
||||
modules/module1400_sprites.o \
|
||||
modules/module1500.o \
|
||||
modules/module1600.o \
|
||||
modules/module1600_sprites.o \
|
||||
modules/module1700.o \
|
||||
modules/module1700_sprites.o \
|
||||
modules/module1800.o \
|
||||
modules/module1900.o \
|
||||
modules/module1900_sprites.o \
|
||||
modules/module2000.o \
|
||||
modules/module2000_sprites.o \
|
||||
modules/module2100.o \
|
||||
modules/module2100_sprites.o \
|
||||
modules/module2200.o \
|
||||
modules/module2200_sprites.o \
|
||||
modules/module2300.o \
|
||||
modules/module2400.o \
|
||||
modules/module2400_sprites.o \
|
||||
modules/module2500.o \
|
||||
modules/module2500_sprites.o \
|
||||
modules/module2600.o \
|
||||
modules/module2600_sprites.o \
|
||||
modules/module2700.o \
|
||||
modules/module2700_sprites.o \
|
||||
modules/module2800.o \
|
||||
modules/module2800_sprites.o \
|
||||
modules/module2900.o \
|
||||
modules/module2900_sprites.o \
|
||||
modules/module3000.o \
|
||||
modules/module3000_sprites.o \
|
||||
mouse.o \
|
||||
navigationscene.o \
|
||||
neverhood.o \
|
||||
nhcarchive.o \
|
||||
palette.o \
|
||||
resource.o \
|
||||
resourceman.o \
|
||||
saveload.o \
|
||||
scene.o \
|
||||
screen.o \
|
||||
smackerscene.o \
|
||||
smackerplayer.o \
|
||||
sound.o \
|
||||
sprite.o \
|
||||
staticdata.o \
|
||||
subtitles.o
|
||||
|
||||
# This module can be built as a plugin
|
||||
ifeq ($(ENABLE_NEVERHOOD), DYNAMIC_PLUGIN)
|
||||
PLUGIN := 1
|
||||
endif
|
||||
|
||||
# Include common rules
|
||||
include $(srcdir)/rules.mk
|
||||
|
||||
# Detection objects
|
||||
DETECT_OBJS += $(MODULE)/detection.o
|
||||
122
engines/neverhood/module_scene.cpp
Normal file
122
engines/neverhood/module_scene.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/navigationscene.h"
|
||||
#include "neverhood/smackerscene.h"
|
||||
#include "neverhood/modules/module1000.h"
|
||||
#include "neverhood/modules/module1500.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
Module::Module(NeverhoodEngine *vm, Module *parentModule)
|
||||
: Entity(vm, 0), _parentModule(parentModule), _childObject(nullptr),
|
||||
_done(false), _sceneType(kSceneTypeNormal) {
|
||||
|
||||
SetMessageHandler(&Module::handleMessage);
|
||||
|
||||
}
|
||||
|
||||
Module::~Module() {
|
||||
delete _childObject;
|
||||
}
|
||||
|
||||
void Module::draw() {
|
||||
if (_childObject)
|
||||
_childObject->draw();
|
||||
}
|
||||
|
||||
uint32 Module::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
switch (messageNum) {
|
||||
case 0x0008:
|
||||
sendMessage(_parentModule, 0x0008, 0);
|
||||
return 0;
|
||||
case 0x1009:
|
||||
_moduleResult = param.asInteger();
|
||||
_done = true;
|
||||
return 0;
|
||||
case 0x100A:
|
||||
case 0x1023:
|
||||
case 0x1024:
|
||||
// Unused resource preloading messages
|
||||
return 0;
|
||||
default:
|
||||
if (_childObject && sender == _parentModule)
|
||||
return sender->sendMessage(_childObject, messageNum, param);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
NavigationScene *Module::navigationScene() {
|
||||
return (NavigationScene*)_childObject;
|
||||
}
|
||||
|
||||
void Module::createNavigationScene(uint32 navigationListId, int navigationIndex, const byte *itemsTypes) {
|
||||
_sceneType = kSceneTypeNavigation;
|
||||
_childObject = new NavigationScene(_vm, this, navigationListId, navigationIndex, itemsTypes);
|
||||
}
|
||||
|
||||
void Module::createSmackerScene(uint32 fileHash, bool doubleSurface, bool canSkip, bool canAbort) {
|
||||
_sceneType = kSceneTypeSmacker;
|
||||
SmackerScene *smackerScene = new SmackerScene(_vm, this, doubleSurface, canSkip, canAbort);
|
||||
smackerScene->setFileHash(fileHash);
|
||||
smackerScene->nextVideo();
|
||||
_childObject = smackerScene;
|
||||
}
|
||||
|
||||
void Module::createSmackerScene(const uint32 *fileHashList, bool doubleSurface, bool canSkip, bool canAbort) {
|
||||
_sceneType = kSceneTypeSmacker;
|
||||
SmackerScene *smackerScene = new SmackerScene(_vm, this, doubleSurface, canSkip, canAbort);
|
||||
smackerScene->setFileHashList(fileHashList);
|
||||
smackerScene->nextVideo();
|
||||
_childObject = smackerScene;
|
||||
}
|
||||
|
||||
void Module::createStaticScene(uint32 backgroundFileHash, uint32 cursorFileHash) {
|
||||
_childObject = new StaticScene(_vm, this, backgroundFileHash, cursorFileHash);
|
||||
}
|
||||
|
||||
void Module::createDemoScene() {
|
||||
_childObject = new Scene1501(_vm, this, 0x0009B624, 0, 288, 0);
|
||||
}
|
||||
|
||||
bool Module::updateChild() {
|
||||
if (_childObject) {
|
||||
_childObject->handleUpdate();
|
||||
if (_done) {
|
||||
_done = false;
|
||||
// Save the last area type if it's a NavigationScene for further processing
|
||||
if (_sceneType == kSceneTypeNavigation)
|
||||
_navigationAreaType = navigationScene()->getNavigationAreaType();
|
||||
delete _childObject;
|
||||
_childObject = nullptr;
|
||||
_sceneType = kSceneTypeNormal;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Module::leaveModule(uint32 result) {
|
||||
sendMessage(_parentModule, 0x1009, result);
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
794
engines/neverhood/modules/module1000.cpp
Normal file
794
engines/neverhood/modules/module1000.cpp
Normal file
@@ -0,0 +1,794 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1000.h"
|
||||
#include "neverhood/modules/module1000_sprites.h"
|
||||
|
||||
#include "common/config-manager.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
Module1000::Module1000(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
_musicFileHash = getGlobalVar(V_ENTRANCE_OPEN) ? 0x81106480 : 0x00103144;
|
||||
|
||||
_vm->_soundMan->addMusic(0x03294419, 0x061880C6);
|
||||
_vm->_soundMan->addMusic(0x03294419, _musicFileHash);
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else if (which == 0)
|
||||
createScene(0, 0);
|
||||
else if (which == 1)
|
||||
createScene(1, 1);
|
||||
|
||||
}
|
||||
|
||||
Module1000::~Module1000() {
|
||||
_vm->_soundMan->deleteMusicGroup(0x03294419);
|
||||
}
|
||||
|
||||
void Module1000::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module1000::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_vm->_soundMan->startMusic(0x061880C6, 0, 0);
|
||||
_childObject = new Scene1001(_vm, this, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
_vm->_soundMan->startMusic(0x061880C6, 0, 0);
|
||||
_childObject = new Scene1002(_vm, this, which);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
_vm->_soundMan->startMusic(0x061880C6, 0, 0);
|
||||
createStaticScene(0xC084110C, 0x41108C00);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
_vm->_soundMan->stopMusic(0x061880C6, 0, 2);
|
||||
_childObject = new Scene1004(_vm, this, which);
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
_vm->_soundMan->stopMusic(0x061880C6, 0, 0);
|
||||
_vm->_soundMan->startMusic(_musicFileHash, 0, 0);
|
||||
_childObject = new Scene1005(_vm, this, which);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module1000::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module1000::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 2)
|
||||
createScene(2, 0);
|
||||
else
|
||||
createScene(1, 0);
|
||||
break;
|
||||
case 1:
|
||||
if (_moduleResult == 1)
|
||||
leaveModule(0);
|
||||
else if (_moduleResult == 2) {
|
||||
if (_vm->isDemo() && !_vm->isBigDemo())
|
||||
// Demo version returns to the same scene
|
||||
createScene(1, 2);
|
||||
else
|
||||
createScene(3, 0);
|
||||
} else
|
||||
createScene(0, 1);
|
||||
break;
|
||||
case 2:
|
||||
createScene(0, 2);
|
||||
break;
|
||||
case 3:
|
||||
if (_moduleResult == 1)
|
||||
createScene(4, 0);
|
||||
else
|
||||
createScene(1, 2);
|
||||
break;
|
||||
case 4:
|
||||
_vm->_soundMan->stopMusic(_musicFileHash, 0, 1);
|
||||
createScene(3, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scene1001::Scene1001(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _asDoor(nullptr), _asWindow(nullptr) {
|
||||
|
||||
Sprite *tempSprite;
|
||||
|
||||
SetMessageHandler(&Scene1001::handleMessage);
|
||||
|
||||
setHitRects(0x004B4860);
|
||||
setBackground(0x4086520E);
|
||||
setPalette(0x4086520E);
|
||||
insertScreenMouse(0x6520A400);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
setRectList(0x004B49F0);
|
||||
insertKlaymen<KmScene1001>(200, 433);
|
||||
setMessageList(0x004B4888);
|
||||
} else if (which == 1) {
|
||||
// Klaymen entering from the right
|
||||
setRectList(0x004B49F0);
|
||||
insertKlaymen<KmScene1001>(640, 433);
|
||||
setMessageList(0x004B4898);
|
||||
} else if (which == 2) {
|
||||
// Klaymen returning from looking through the window
|
||||
setRectList(0x004B49F0);
|
||||
if (getGlobalVar(V_KLAYMEN_IS_DELTA_X)) {
|
||||
insertKlaymen<KmScene1001>(390, 433);
|
||||
_klaymen->setDoDeltaX(1);
|
||||
} else {
|
||||
insertKlaymen<KmScene1001>(300, 433);
|
||||
}
|
||||
setMessageList(0x004B4970);
|
||||
} else {
|
||||
// Klaymen sleeping
|
||||
setRectList(0x004B4A00);
|
||||
insertKlaymen<KmScene1001>(200, 433);
|
||||
setMessageList(0x004B4890);
|
||||
}
|
||||
|
||||
tempSprite = insertStaticSprite(0x2080A3A8, 1300);
|
||||
|
||||
_klaymen->setClipRect(0, 0, tempSprite->getDrawRect().x2(), 480);
|
||||
|
||||
if (!getGlobalVar(V_DOOR_BUSTED)) {
|
||||
_asDoor = insertSprite<AsScene1001Door>();
|
||||
_asDoor->setClipRect(0, 0, tempSprite->getDrawRect().x2(), 480);
|
||||
}
|
||||
|
||||
_asLever = insertSprite<AsScene1001Lever>(this, 150, 433, 1);
|
||||
|
||||
insertStaticSprite(0x809861A6, 950);
|
||||
insertStaticSprite(0x89C03848, 1100);
|
||||
|
||||
_ssButton = insertSprite<SsCommonButtonSprite>(this, 0x15288120, 100, 0);
|
||||
|
||||
if (!getGlobalVar(V_WINDOW_OPEN)) {
|
||||
tempSprite = insertStaticSprite(0x8C066150, 200);
|
||||
_asWindow = insertSprite<AsScene1001Window>();
|
||||
_asWindow->setClipRect(tempSprite->getDrawRect());
|
||||
}
|
||||
|
||||
_asHammer = insertSprite<AsScene1001Hammer>(_asDoor);
|
||||
|
||||
}
|
||||
|
||||
Scene1001::~Scene1001() {
|
||||
setGlobalVar(V_KLAYMEN_IS_DELTA_X, _klaymen->isDoDeltaX());
|
||||
}
|
||||
|
||||
uint32 Scene1001::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = 0;
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x00342624) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asLever);
|
||||
setMessageList2(0x004B4910);
|
||||
messageResult = 1;
|
||||
} else if (param.asInteger() == 0x21E64A00) {
|
||||
if (getGlobalVar(V_DOOR_BUSTED)) {
|
||||
setMessageList(0x004B48A8);
|
||||
} else {
|
||||
setMessageList(0x004B48C8);
|
||||
}
|
||||
messageResult = 1;
|
||||
} else if (param.asInteger() == 0x040424D0) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _ssButton);
|
||||
} else if (param.asInteger() == 0x80006358) {
|
||||
if (getGlobalVar(V_WINDOW_OPEN)) {
|
||||
setMessageList(0x004B4938);
|
||||
} else {
|
||||
setMessageList(0x004B4960);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
setRectList(0x004B49F0);
|
||||
break;
|
||||
case 0x480B:
|
||||
sendMessage(_asWindow, 0x2001, 0);
|
||||
break;
|
||||
case NM_KLAYMEN_LOWER_LEVER:
|
||||
sendMessage(_asHammer, 0x2000, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
Scene1002::Scene1002(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _isKlaymenFloor(false), _isClimbingLadder(false), _asKlaymenPeekHand(nullptr) {
|
||||
|
||||
NRect tempClipRect;
|
||||
Sprite *tempSprite;
|
||||
|
||||
SetUpdateHandler(&Scene1002::update);
|
||||
SetMessageHandler(&Scene1002::handleMessage);
|
||||
|
||||
setHitRects(0x004B4138);
|
||||
setBackground(0x12C23307);
|
||||
setPalette(0x12C23307);
|
||||
|
||||
insertStaticSprite(0x06149428, 1100);
|
||||
insertStaticSprite(0x312C8774, 1100);
|
||||
|
||||
_ssLadderArch = insertStaticSprite(0x152C1313, 1015);
|
||||
_ssLadderArchPart1 = insertStaticSprite(0x060000A0, 1200);
|
||||
_ssLadderArchPart2 = insertStaticSprite(0xB2A423B0, 1100);
|
||||
_ssLadderArchPart3 = insertStaticSprite(0x316E0772, 1100);
|
||||
|
||||
_ssCeiling = insertStaticSprite(0x316C4BB4, 1015);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
if (_vm->_gameState.which == 0) {
|
||||
// Klaymen on top
|
||||
insertKlaymen<KmScene1002>(90, 226);
|
||||
_asKlaymenLadderHands = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen);
|
||||
setMessageList(0x004B4270);
|
||||
_klaymen->setClipRect(31, 0, _ssLadderArchPart2->getDrawRect().x2(), _ssLadderArchPart3->getDrawRect().y2());
|
||||
_asKlaymenLadderHands->getSurface()->getClipRect() = _klaymen->getSurface()->getClipRect();
|
||||
_klaymen->setRepl(64, 0);
|
||||
} else {
|
||||
// Klaymen on the floor
|
||||
insertKlaymen<KmScene1002>(379, 435);
|
||||
_asKlaymenLadderHands = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen);
|
||||
setMessageList(0x004B4270);
|
||||
_klaymen->setClipRect(_ssLadderArch->getDrawRect().x, 0, _ssLadderArchPart2->getDrawRect().x2(), _ssLadderArchPart1->getDrawRect().y2());
|
||||
_asKlaymenLadderHands->setClipRect(_klaymen->getClipRect());
|
||||
}
|
||||
} else if (which == 1) {
|
||||
// Klaymen entering from the right
|
||||
insertKlaymen<KmScene1002>(650, 435);
|
||||
_asKlaymenLadderHands = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen);
|
||||
setMessageList(0x004B4478);
|
||||
_klaymen->setClipRect(_ssLadderArch->getDrawRect().x, 0, _ssLadderArchPart2->getDrawRect().x2(), _ssLadderArchPart1->getDrawRect().y2());
|
||||
_asKlaymenLadderHands->setClipRect(_klaymen->getClipRect());
|
||||
_vm->_gameState.which = 1;
|
||||
} else if (which == 2) {
|
||||
// Klaymen coming up the ladder
|
||||
insertKlaymen<KmScene1002>(68, 645);
|
||||
_asKlaymenLadderHands = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen);
|
||||
setMessageList(0x004B4298);
|
||||
_klaymen->setClipRect(_ssLadderArch->getDrawRect().x, 0, _ssLadderArchPart2->getDrawRect().x2(), _ssLadderArchPart1->getDrawRect().y2());
|
||||
_asKlaymenLadderHands->setClipRect(_klaymen->getClipRect());
|
||||
_vm->_gameState.which = 1;
|
||||
sendMessage(_klaymen, 0x4820, 0);
|
||||
} else {
|
||||
// Klaymen entering from the left, peeking
|
||||
insertKlaymen<KmScene1002>(90, 226);
|
||||
_asKlaymenLadderHands = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen);
|
||||
setMessageList(0x004B4470);
|
||||
_klaymen->setClipRect(31, 0, _ssLadderArchPart2->getDrawRect().x2(), _ssLadderArchPart3->getDrawRect().y2());
|
||||
_asKlaymenLadderHands->setClipRect(_klaymen->getClipRect());
|
||||
_asKlaymenPeekHand = insertSprite<AsScene1002KlaymenPeekHand>(this, _klaymen);
|
||||
_asKlaymenPeekHand->setClipRect(_klaymen->getClipRect());
|
||||
_klaymen->setRepl(64, 0);
|
||||
_vm->_gameState.which = 0;
|
||||
}
|
||||
|
||||
insertScreenMouse(0x23303124);
|
||||
|
||||
tempSprite = insertStaticSprite(0xB3242310, 825);
|
||||
tempClipRect.set(tempSprite->getDrawRect().x, tempSprite->getDrawRect().y,
|
||||
_ssLadderArchPart2->getDrawRect().x2(), _ssLadderArchPart2->getDrawRect().y2());
|
||||
|
||||
_asRing1 = insertSprite<AsScene1002Ring>(this, false, 258, 191, _ssCeiling->getDrawRect().y, false);
|
||||
_asRing2 = insertSprite<AsScene1002Ring>(this, false, 297, 189, _ssCeiling->getDrawRect().y, false);
|
||||
_asRing3 = insertSprite<AsScene1002Ring>(this, true, 370, 201, _ssCeiling->getDrawRect().y, getGlobalVar(V_FLYTRAP_RING_DOOR));
|
||||
_asRing4 = insertSprite<AsScene1002Ring>(this, false, 334, 191, _ssCeiling->getDrawRect().y, false);
|
||||
_asRing5 = insertSprite<AsScene1002Ring>(this, false, 425, 184, _ssCeiling->getDrawRect().y, false);
|
||||
|
||||
_asDoor = insertSprite<AsScene1002Door>(tempClipRect);
|
||||
tempSprite = insertSprite<AsScene1002BoxingGloveHitEffect>();
|
||||
_asDoorSpy = insertSprite<AsScene1002DoorSpy>(tempClipRect, this, _asDoor, tempSprite);
|
||||
_ssPressButton = insertSprite<SsCommonPressButton>(this, 0x00412692, 0x140B60BE, 800, 0);
|
||||
_asVenusFlyTrap = insertSprite<AsScene1002VenusFlyTrap>(this, _klaymen, false);
|
||||
addCollisionSprite(_asVenusFlyTrap);
|
||||
|
||||
sendEntityMessage(_klaymen, NM_CAR_MOVE_TO_PREV_POINT, _asVenusFlyTrap);
|
||||
|
||||
_asOutsideDoorBackground = insertSprite<AsScene1002OutsideDoorBackground>();
|
||||
|
||||
setRectList(0x004B43A0);
|
||||
|
||||
loadSound(1, 0x60755842);
|
||||
loadSound(2, 0x616D5821);
|
||||
|
||||
}
|
||||
|
||||
Scene1002::~Scene1002() {
|
||||
}
|
||||
|
||||
void Scene1002::update() {
|
||||
Scene::update();
|
||||
if (!_isKlaymenFloor && _klaymen->getY() > 230) {
|
||||
_klaymen->setClipRect(_ssLadderArch->getDrawRect().x, 0, _ssLadderArchPart2->getDrawRect().x2(), _ssLadderArchPart1->getDrawRect().y2());
|
||||
_asKlaymenLadderHands->setClipRect(_klaymen->getClipRect());
|
||||
deleteSprite(&_ssLadderArchPart3);
|
||||
_klaymen->clearRepl();
|
||||
_isKlaymenFloor = true;
|
||||
_vm->_gameState.which = 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Scene1002::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = 0;
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0xE6EE60E1) {
|
||||
if (getGlobalVar(V_FLYTRAP_RING_DOOR))
|
||||
setMessageList(0x004B4428);
|
||||
else
|
||||
setMessageList(0x004B4448);
|
||||
messageResult = 1;
|
||||
} else if (param.asInteger() == 0x4A845A00)
|
||||
sendEntityMessage(_klaymen, 0x1014, _asRing1);
|
||||
else if (param.asInteger() == 0x43807801)
|
||||
sendEntityMessage(_klaymen, 0x1014, _asRing2);
|
||||
else if (param.asInteger() == 0x46C26A01) {
|
||||
if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
|
||||
setMessageList(0x004B44B8);
|
||||
} else {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asRing3);
|
||||
if (_asVenusFlyTrap->getX() - 10 < 366 && _asVenusFlyTrap->getX() + 10 > 366) {
|
||||
setGlobalVar(V_FLYTRAP_RING_EATEN, 1);
|
||||
setMessageList(0x004B44A8);
|
||||
} else {
|
||||
setMessageList(0x004B44A0);
|
||||
}
|
||||
}
|
||||
messageResult = 1;
|
||||
} else if (param.asInteger() == 0x468C7B11)
|
||||
sendEntityMessage(_klaymen, 0x1014, _asRing4);
|
||||
else if (param.asInteger() == 0x42845B19)
|
||||
sendEntityMessage(_klaymen, 0x1014, _asRing5);
|
||||
else if (param.asInteger() == 0xC0A07458)
|
||||
sendEntityMessage(_klaymen, 0x1014, _ssPressButton);
|
||||
break;
|
||||
case 0x1024:
|
||||
sendMessage(_parentModule, 0x1024, param.asInteger());
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (_isClimbingLadder) {
|
||||
setMessageList2(0x004B43D0);
|
||||
} else {
|
||||
if (_klaymen->getY() > 420) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asVenusFlyTrap);
|
||||
setMessageList2(0x004B4480);
|
||||
} else if (_klaymen->getY() > 227) {
|
||||
setMessageList2(0x004B41E0);
|
||||
} else {
|
||||
setMessageList2(0x004B4148);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
_messageList = nullptr;
|
||||
break;
|
||||
case NM_KLAYMEN_CLIMB_LADDER:
|
||||
_isClimbingLadder = true;
|
||||
setRectList(0x004B4418);
|
||||
break;
|
||||
case NM_KLAYMEN_STOP_CLIMBING:
|
||||
_isClimbingLadder = false;
|
||||
setRectList(0x004B43A0);
|
||||
break;
|
||||
case NM_KLAYMEN_USE_OBJECT:
|
||||
if (sender == _asRing1) {
|
||||
setGlobalVar(V_RADIO_ENABLED, 0);
|
||||
playSound(0, 0x665198C0);
|
||||
} else if (sender == _asRing2) {
|
||||
setGlobalVar(V_RADIO_ENABLED, 0);
|
||||
playSound(0, 0xE2D389C0);
|
||||
} else if (sender == _asRing3) {
|
||||
setGlobalVar(V_RADIO_ENABLED, 0);
|
||||
playSound(1);
|
||||
sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
|
||||
sendMessage(_asOutsideDoorBackground, NM_KLAYMEN_OPEN_DOOR, 0);
|
||||
} else if (sender == _asRing4) {
|
||||
setGlobalVar(V_RADIO_ENABLED, 0);
|
||||
playSound(0, 0xE0558848);
|
||||
} else if (sender == _asRing5) {
|
||||
setGlobalVar(V_RADIO_ENABLED, 1);
|
||||
playSound(0, 0x44014282);
|
||||
}
|
||||
break;
|
||||
case NM_KLAYMEN_RAISE_LEVER:
|
||||
if (sender == _asRing3) {
|
||||
playSound(2);
|
||||
sendMessage(_asDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
|
||||
sendMessage(_asOutsideDoorBackground, NM_KLAYMEN_CLOSE_DOOR, 0);
|
||||
} else if (sender == _asVenusFlyTrap) {
|
||||
if (getGlobalVar(V_FLYTRAP_RING_DOOR)) {
|
||||
sendMessage(_asRing3, NM_KLAYMEN_RAISE_LEVER, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x480B:
|
||||
sendEntityMessage(_klaymen, 0x1014, _asDoorSpy);
|
||||
break;
|
||||
case NM_KLAYMEN_LOWER_LEVER:
|
||||
setGlobalVar(V_RADIO_ENABLED, 0);
|
||||
playSound(1);
|
||||
sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
|
||||
sendMessage(_asOutsideDoorBackground, NM_KLAYMEN_OPEN_DOOR, 0);
|
||||
break;
|
||||
case 0x8000:
|
||||
setSpriteSurfacePriority(_ssCeiling, 995);
|
||||
setSpriteSurfacePriority(_ssLadderArch, 995);
|
||||
break;
|
||||
case 0x8001:
|
||||
setSpriteSurfacePriority(_ssCeiling, 1015);
|
||||
setSpriteSurfacePriority(_ssLadderArch, 1015);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
Scene1004::Scene1004(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _paletteAreaStatus(-1) {
|
||||
|
||||
Sprite *tempSprite;
|
||||
|
||||
SetUpdateHandler(&Scene1004::update);
|
||||
SetMessageHandler(&Scene1004::handleMessage);
|
||||
|
||||
setBackground(0x50C03005);
|
||||
|
||||
if (getGlobalVar(V_ENTRANCE_OPEN)) {
|
||||
setPalette(0xA30BA329);
|
||||
_palette->addBasePalette(0xA30BA329, 0, 256, 0);
|
||||
} else {
|
||||
setPalette(0x50C03005);
|
||||
_palette->addBasePalette(0x50C03005, 0, 256, 0);
|
||||
}
|
||||
addEntity(_palette);
|
||||
|
||||
insertScreenMouse(0x03001504);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
setRectList(0x004B7C70);
|
||||
insertKlaymen<KmScene1004>(330, 327);
|
||||
setMessageList(0x004B7C18);
|
||||
} else if (which == 1) {
|
||||
// Klaymen returning from reading a note
|
||||
setRectList(0x004B7C70);
|
||||
insertKlaymen<KmScene1004>(330, 327);
|
||||
setMessageList(0x004B7C08);
|
||||
} else {
|
||||
// Klaymen coming down the ladder
|
||||
loadDataResource(0x01900A04);
|
||||
insertKlaymen<KmScene1004>(_dataResource.getPoint(0x80052A29).x, 27);
|
||||
setMessageList(0x004B7BF0);
|
||||
}
|
||||
|
||||
updatePaletteArea();
|
||||
|
||||
_asKlaymenLadderHands = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen);
|
||||
|
||||
insertStaticSprite(0x800034A0, 1100);
|
||||
insertStaticSprite(0x64402020, 1100);
|
||||
insertStaticSprite(0x3060222E, 1300);
|
||||
tempSprite = insertStaticSprite(0x0E002004, 1300);
|
||||
|
||||
_klaymen->setClipRect(0, tempSprite->getDrawRect().y, 640, 480);
|
||||
_asKlaymenLadderHands->setClipRect(_klaymen->getClipRect());
|
||||
|
||||
_asTrashCan = insertSprite<AsScene1004TrashCan>();
|
||||
|
||||
}
|
||||
|
||||
void Scene1004::update() {
|
||||
Scene::update();
|
||||
updatePaletteArea();
|
||||
}
|
||||
|
||||
uint32 Scene1004::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = 0;
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x926500A1) {
|
||||
setMessageList(0x004B7C20);
|
||||
messageResult = 1;
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
loadDataResource(0x01900A04);
|
||||
break;
|
||||
case 0x2001:
|
||||
setRectList(0x004B7C70);
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
sendMessage(_asTrashCan, NM_POSITION_CHANGE, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void Scene1004::updatePaletteArea() {
|
||||
if (_klaymen->getY() < 150) {
|
||||
if (_paletteAreaStatus != 0) {
|
||||
_paletteAreaStatus = 0;
|
||||
_palette->addBasePalette(0x406B0D10, 0, 64, 0);
|
||||
_palette->startFadeToPalette(12);
|
||||
}
|
||||
} else {
|
||||
if (_paletteAreaStatus != 1) {
|
||||
_paletteAreaStatus = 1;
|
||||
_palette->addBasePalette(0x24332243, 0, 64, 0);
|
||||
_palette->startFadeToPalette(12);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scene1005::Scene1005(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule) {
|
||||
|
||||
SetMessageHandler(&Scene1005::handleMessage);
|
||||
|
||||
if (getGlobalVar(V_ENTRANCE_OPEN)) {
|
||||
setBackground(0x2800E011);
|
||||
setPalette(0x2800E011);
|
||||
insertStaticSprite(0x492D5AD7, 100);
|
||||
insertPuzzleMouse(0x0E015288, 20, 620);
|
||||
} else {
|
||||
setBackground(0x8870A546);
|
||||
setPalette(0x8870A546);
|
||||
insertStaticSprite(0x40D1E0A9, 100);
|
||||
insertStaticSprite(0x149C00A6, 100);
|
||||
insertPuzzleMouse(0x0A54288F, 20, 620);
|
||||
}
|
||||
|
||||
drawTextToBackground();
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene1005::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
|
||||
leaveScene(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Scene1005::drawTextToBackground() {
|
||||
uint32 textIndex = getTextIndex();
|
||||
if (_vm->getLanguage() == Common::Language::JA_JPN) {
|
||||
static const struct {
|
||||
uint32 image_id;
|
||||
int x, y;
|
||||
} jp_images[] = {
|
||||
/* 1 */ { 0xB1048044, 205, 39 },
|
||||
/* 2 */ { 0x31048045, 201, 54 },
|
||||
/* 3 */ { 0x31048046, 193, 37 },
|
||||
/* 4 */ { 0x31048040, 192, 57 },
|
||||
/* 5 */ { 0x3104804C, 195, 43 },
|
||||
/* 6 */ { 0x31048054, 188, 32 },
|
||||
/* 7 */ { 0x31048064, 201, 52 },
|
||||
/* 8 */ { 0x31048004, 191, 51 },
|
||||
/* 9 */ { 0x310480C4, 197, 58 },
|
||||
/* 10 */ { 0xB2048044, 196, 65 },
|
||||
/* 11 */ { 0x32048045, 188, 53 },
|
||||
/* 12 */ { 0x32048046, 190, 71 },
|
||||
/* 13 */ { 0x32048040, 210, 45 },
|
||||
/* 14 */ { 0x3204804C, 199, 67 },
|
||||
/* 15 */ { 0x32048054, 214, 58 },
|
||||
/* 16 */ { 0x32048064, 201, 52 },
|
||||
/* 17 */ { 0x32048004, 205, 57 },
|
||||
/* 18 */ { 0x320480C4, 215, 65 },
|
||||
/* 19 */ { 0x32048144, 223, 85 },
|
||||
/* 20 */ { 0x34048045, 208, 82 },
|
||||
/* 21 */ { 0x34048046, 200, 66 },
|
||||
/* 22 */ { 0x34048040, 209, 76 },
|
||||
/* 23 */ { 0x3404804C, 211, 80 },
|
||||
/* 24 */ { 0x34048054, 211, 50 },
|
||||
/* 25 */ { 0x34048064, 224, 76 },
|
||||
/* 26 */ { 0x34048004, 209, 85 },
|
||||
/* 27 */ { 0x340480C4, 202, 61 },
|
||||
/* 28 */ { 0x34048144, 206, 79 },
|
||||
/* 29 */ { 0x34048244, 219, 71 },
|
||||
/* 30 */ { 0x38048046, 200, 87 },
|
||||
/* 31 */ { 0x38048040, 215, 85 },
|
||||
/* 32 */ { 0x3804804C, 209, 87 },
|
||||
/* 33 */ { 0x38048054, 201, 62 },
|
||||
/* 34 */ { 0x38048064, 213, 95 },
|
||||
/* 35 */ { 0x38048004, 204, 90 },
|
||||
/* 36 */ { 0x380480C4, 214, 77 },
|
||||
/* 37 */ { 0x38048144, 211, 96 },
|
||||
/* 38 */ { 0x38048244, 207, 91 },
|
||||
/* 39 */ { 0x38048444, 207, 71 },
|
||||
/* 40 */ { 0x20048040, 206, 68 },
|
||||
/* 41 */ { 0x2004804C, 201, 140 },
|
||||
/* 42 */ { 0x20048054, 218, 122 },
|
||||
/* 43 */ { 0x20048064, 219, 107 },
|
||||
/* 44 */ { 0x20048004, 214, 115 },
|
||||
/* 45 */ { 0x200480C4, 193, 142 },
|
||||
/* 46 */ { 0x20048144, 210, 130 },
|
||||
/* 47 */ { 0x20048244, 208, 110 },
|
||||
/* 48 */ { 0x20048444, 213, 112 },
|
||||
/* 49 */ { 0x20048844, 221, 112 },
|
||||
/* 50 */ { 0x1004804C, 207, 133 },
|
||||
/* 51 */ { 0x10048054, 209, 111 },
|
||||
};
|
||||
if (textIndex >= ARRAYSIZE(jp_images))
|
||||
textIndex = 0;
|
||||
addSprite(new StaticSprite(_vm, jp_images[textIndex].image_id, kSLFSetPosition, jp_images[textIndex].x, jp_images[textIndex].y));
|
||||
} else {
|
||||
TextResource textResource(_vm);
|
||||
const char *textStart, *textEnd;
|
||||
int16 x = 188, y = 36;
|
||||
FontSurface *fontSurface = FontSurface::createFontSurface(_vm, getGlobalVar(V_ENTRANCE_OPEN) ? 0x283CE401 : 0xC6604282);
|
||||
textResource.load(0x80283101);
|
||||
textStart = textResource.getString(textIndex, textEnd);
|
||||
if (_vm->shouldOffsetFontNhc()) {
|
||||
x += 15;
|
||||
y += 18;
|
||||
}
|
||||
while (textStart < textEnd) {
|
||||
fontSurface->drawString(_background->getSurface(), x, y, (const byte*)textStart);
|
||||
y += 36;
|
||||
textStart += strlen(textStart) + 1;
|
||||
}
|
||||
delete fontSurface;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Scene1005::getTextIndex() {
|
||||
uint32 textIndex;
|
||||
textIndex = getTextIndex1();
|
||||
if (getGlobalVar(V_ENTRANCE_OPEN)) {
|
||||
textIndex = getKloggsTextIndex();
|
||||
}
|
||||
if (getGlobalVar(V_TEXT_FLAG1) && getGlobalVar(V_TEXT_INDEX) == textIndex) {
|
||||
textIndex = getTextIndex3(textIndex);
|
||||
} else {
|
||||
setGlobalVar(V_TEXT_FLAG1, 1);
|
||||
setGlobalVar(V_TEXT_INDEX, textIndex);
|
||||
}
|
||||
return textIndex;
|
||||
}
|
||||
|
||||
uint32 Scene1005::getTextIndex1() {
|
||||
uint32 textIndex;
|
||||
if (getGlobalVar(V_WORLDS_JOINED)) {
|
||||
if (!getGlobalVar(V_DOOR_PASSED))
|
||||
textIndex = 18;
|
||||
else if (!getGlobalVar(V_ROBOT_TARGET))
|
||||
textIndex = 19;
|
||||
else if (getGlobalVar(V_ROBOT_HIT)) {
|
||||
if (!getGlobalVar(V_ENTRANCE_OPEN))
|
||||
textIndex = 23;
|
||||
else if (!getSubVar(VA_HAS_KEY, 0) && !getSubVar(VA_IS_KEY_INSERTED, 0))
|
||||
textIndex = 24;
|
||||
else if (!getGlobalVar(V_HAS_FINAL_KEY))
|
||||
textIndex = 26;
|
||||
else if (!getSubVar(VA_HAS_KEY, 1) && !getSubVar(VA_IS_KEY_INSERTED, 1))
|
||||
textIndex = 27;
|
||||
else if (!getGlobalVar(V_HAS_FINAL_KEY))
|
||||
textIndex = 28;
|
||||
else
|
||||
textIndex = 29;
|
||||
} else if (!getGlobalVar(V_FELL_DOWN_HOLE))
|
||||
textIndex = 20;
|
||||
else if (!getGlobalVar(V_SEEN_SYMBOLS_NO_LIGHT))
|
||||
textIndex = 21;
|
||||
else
|
||||
textIndex = 22;
|
||||
} else if (getGlobalVar(V_BOLT_DOOR_UNLOCKED)) {
|
||||
if (!getGlobalVar(V_WALL_BROKEN))
|
||||
textIndex = 12;
|
||||
else if (!getGlobalVar(V_STAIRS_DOWN_ONCE))
|
||||
textIndex = 13;
|
||||
else if (!getGlobalVar(V_RADIO_ENABLED))
|
||||
textIndex = 50;
|
||||
else if (!getGlobalVar(V_UNUSED))
|
||||
textIndex = 14;
|
||||
else if (!getGlobalVar(V_BEEN_SHRINKING_ROOM))
|
||||
textIndex = 15;
|
||||
else if (!getGlobalVar(V_BEEN_STATUE_ROOM))
|
||||
textIndex = 16;
|
||||
else
|
||||
textIndex = 17;
|
||||
} else if (!getGlobalVar(V_FLYTRAP_RING_EATEN)) {
|
||||
textIndex = 0;
|
||||
} else if (getGlobalVar(V_CREATURE_EXPLODED)) {
|
||||
if (!getGlobalVar(V_TILE_PUZZLE_SOLVED))
|
||||
textIndex = 4;
|
||||
else if (!getGlobalVar(V_HAS_TEST_TUBE))
|
||||
textIndex = 5;
|
||||
else if (!getSubVar(VA_LOCKS_DISABLED, 0x40119852))
|
||||
textIndex = 6;
|
||||
else if (!getGlobalVar(V_WATER_RUNNING))
|
||||
textIndex = 7;
|
||||
else if (!getGlobalVar(V_NOTES_PUZZLE_SOLVED))
|
||||
textIndex = 8;
|
||||
else if (!getSubVar(VA_LOCKS_DISABLED, 0x304008D2))
|
||||
textIndex = 9;
|
||||
else if (!getSubVar(VA_LOCKS_DISABLED, 0x01180951))
|
||||
textIndex = 10;
|
||||
else
|
||||
textIndex = 11;
|
||||
} else if (!getGlobalVar(V_CREATURE_ANGRY)) {
|
||||
textIndex = 1;
|
||||
} else if (getGlobalVar(V_TNT_DUMMY_BUILT)) {
|
||||
textIndex = 3;
|
||||
} else {
|
||||
textIndex = 2;
|
||||
}
|
||||
return textIndex;
|
||||
}
|
||||
|
||||
uint32 Scene1005::getKloggsTextIndex() {
|
||||
uint32 textIndex = getGlobalVar(V_TEXT_COUNTING_INDEX1);
|
||||
if (textIndex + 1 > 10) {
|
||||
textIndex = 0;
|
||||
}
|
||||
setGlobalVar(V_TEXT_COUNTING_INDEX1, textIndex + 1);
|
||||
return textIndex + 40;
|
||||
}
|
||||
|
||||
uint32 Scene1005::getTextIndex3(uint32 usefulHint) {
|
||||
uint32 textIndex = getGlobalVar(V_TEXT_COUNTING_INDEX2);
|
||||
if (textIndex + 1 > 10 && ConfMan.getBool("repeatwilliehint")) {
|
||||
setGlobalVar(V_TEXT_COUNTING_INDEX2, 0);
|
||||
return usefulHint;
|
||||
}
|
||||
if (textIndex + 1 > 10) {
|
||||
textIndex = 0;
|
||||
}
|
||||
setGlobalVar(V_TEXT_COUNTING_INDEX2, textIndex + 1);
|
||||
return textIndex + 30;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
109
engines/neverhood/modules/module1000.h
Normal file
109
engines/neverhood/modules/module1000.h
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1000_H
|
||||
#define NEVERHOOD_MODULES_MODULE1000_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module1000 : public Module {
|
||||
public:
|
||||
Module1000(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module1000() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
uint32 _musicFileHash;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class Scene1001 : public Scene {
|
||||
public:
|
||||
Scene1001(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene1001() override;
|
||||
protected:
|
||||
Sprite *_asHammer;
|
||||
Sprite *_asDoor;
|
||||
Sprite *_asWindow;
|
||||
Sprite *_asLever;
|
||||
Sprite *_ssButton;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1002 : public Scene {
|
||||
public:
|
||||
Scene1002(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene1002() override;
|
||||
protected:
|
||||
Sprite *_asRing1;
|
||||
Sprite *_asRing2;
|
||||
Sprite *_asRing3;
|
||||
Sprite *_asRing4;
|
||||
Sprite *_asRing5;
|
||||
Sprite *_asDoor;
|
||||
Sprite *_asDoorSpy;
|
||||
Sprite *_asVenusFlyTrap;
|
||||
Sprite *_ssLadderArch;
|
||||
Sprite *_ssLadderArchPart1;
|
||||
Sprite *_ssLadderArchPart2;
|
||||
Sprite *_ssLadderArchPart3;
|
||||
Sprite *_ssCeiling;
|
||||
Sprite *_asKlaymenLadderHands;
|
||||
Sprite *_asKlaymenPeekHand;
|
||||
Sprite *_asOutsideDoorBackground;
|
||||
Sprite *_ssPressButton;
|
||||
bool _isKlaymenFloor;
|
||||
bool _isClimbingLadder;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1004 : public Scene {
|
||||
public:
|
||||
Scene1004(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_asKlaymenLadderHands;
|
||||
Sprite *_asTrashCan;
|
||||
int _paletteAreaStatus;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void updatePaletteArea();
|
||||
};
|
||||
|
||||
class Scene1005 : public Scene {
|
||||
public:
|
||||
Scene1005(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void drawTextToBackground();
|
||||
uint32 getTextIndex();
|
||||
uint32 getTextIndex1();
|
||||
uint32 getKloggsTextIndex();
|
||||
uint32 getTextIndex3(uint32 usefulHint);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1000_H */
|
||||
1705
engines/neverhood/modules/module1000_sprites.cpp
Normal file
1705
engines/neverhood/modules/module1000_sprites.cpp
Normal file
File diff suppressed because it is too large
Load Diff
261
engines/neverhood/modules/module1000_sprites.h
Normal file
261
engines/neverhood/modules/module1000_sprites.h
Normal file
@@ -0,0 +1,261 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1000_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE1000_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class AsScene1001Door : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1001Door(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void hammerHitsDoor();
|
||||
void stShowIdleDoor();
|
||||
void stBustedDoorMove();
|
||||
void stBustedDoorGone();
|
||||
};
|
||||
|
||||
class AsScene1001Hammer : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1001Hammer(NeverhoodEngine *vm, Sprite *asDoor);
|
||||
protected:
|
||||
Sprite *_asDoor;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1001Window : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1001Window(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1001Lever : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1001Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int deltaXType);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class SsCommonButtonSprite : public StaticSprite {
|
||||
public:
|
||||
SsCommonButtonSprite(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, int surfacePriority, uint32 soundFileHash);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 _soundFileHash;
|
||||
int16 _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1002Ring : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1002Ring(NeverhoodEngine *vm, Scene *parentScene, bool isSpecial, int16 x, int16 y, int16 clipY1, bool isRingLow);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
bool _isSpecial;
|
||||
void update();
|
||||
uint32 hmRingIdle(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmRingPulled1(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmRingPulled2(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmRingHangingLow(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmRingReleased(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1002Door : public StaticSprite {
|
||||
public:
|
||||
AsScene1002Door(NeverhoodEngine *vm, NRect &clipRect);
|
||||
protected:
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suOpenDoor();
|
||||
void suCloseDoor();
|
||||
};
|
||||
|
||||
class AsScene1002BoxingGloveHitEffect : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1002BoxingGloveHitEffect(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1002DoorSpy : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1002DoorSpy(NeverhoodEngine *vm, NRect &clipRect, Scene *parentScene, Sprite *asDoor, Sprite *asScene1002BoxingGloveHitEffect);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
Sprite *_asDoor;
|
||||
Sprite *_asBoxingGloveHitEffect;
|
||||
NRect _clipRect;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmDoorSpyAnimation(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suDoorSpy();
|
||||
void stDoorSpyIdle();
|
||||
void stDoorSpyBoxingGlove();
|
||||
};
|
||||
|
||||
class SsCommonPressButton : public StaticSprite {
|
||||
public:
|
||||
SsCommonPressButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash);
|
||||
void setFileHashes(uint32 fileHash1, uint32 fileHash2);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 _soundFileHash;
|
||||
uint32 _fileHashes[2];
|
||||
int _status;
|
||||
int _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1002VenusFlyTrap : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1002VenusFlyTrap(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, bool isSecond);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
Sprite *_klaymen;
|
||||
int _countdown;
|
||||
bool _isSecond;
|
||||
void update();
|
||||
void upIdle();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmAnimationSimple(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmAnimationExt(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stWalkBack();
|
||||
void stWalk();
|
||||
void stRelease();
|
||||
void stGrabRing();
|
||||
void stRingGrabbed();
|
||||
void stKlaymenInside();
|
||||
void stIdle();
|
||||
void stKlaymenInsideMoving();
|
||||
void stSpitOutKlaymen();
|
||||
void swallowKlaymen();
|
||||
};
|
||||
|
||||
class AsScene1002OutsideDoorBackground : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1002OutsideDoorBackground(NeverhoodEngine *vm);
|
||||
protected:
|
||||
int _countdown;
|
||||
bool _isDoorClosed;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmAnimation(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stOpenDoor();
|
||||
void stCloseDoor();
|
||||
void stDoorClosed();
|
||||
};
|
||||
|
||||
class AsScene1002KlaymenLadderHands : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1002KlaymenLadderHands(NeverhoodEngine *vm, Klaymen *klaymen);
|
||||
protected:
|
||||
Klaymen *_klaymen;
|
||||
void update();
|
||||
};
|
||||
|
||||
class AsScene1002KlaymenPeekHand : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1002KlaymenPeekHand(NeverhoodEngine *vm, Scene *parentScene, Klaymen *klaymen);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
Klaymen *_klaymen;
|
||||
bool _isClipRectSaved;
|
||||
NRect _savedClipRect;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1004TrashCan : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1004TrashCan(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene1001 : public Klaymen {
|
||||
public:
|
||||
KmScene1001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void stWakeUp();
|
||||
void stSleeping();
|
||||
void stPullHammerLever();
|
||||
uint32 hmSleeping(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmPullHammerLever(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene1002 : public Klaymen {
|
||||
public:
|
||||
KmScene1002(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void stJumpToRing1();
|
||||
void stJumpToRing2();
|
||||
void stJumpToRing3();
|
||||
void stJumpToRing4();
|
||||
void setupJumpToRing();
|
||||
void stHangOnRing();
|
||||
void stHoldRing3();
|
||||
void stDropFromRing();
|
||||
void stJumpToRingVenusFlyTrap();
|
||||
void stJumpAndFall();
|
||||
void stMoveVenusFlyTrap();
|
||||
void stContinueMovingVenusFlyTrap();
|
||||
void evMoveVenusFlyTrapDone();
|
||||
void stPressDoorButton();
|
||||
void stHitByBoxingGlove();
|
||||
void evHitByBoxingGloveDone();
|
||||
|
||||
uint32 hmJumpToRing(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmJumpToRing3(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmHoldRing3(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmJumpToRingVenusFlyTrap(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmJumpAndFall(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmMoveVenusFlyTrap(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmFirstMoveVenusFlyTrap(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmPressDoorButton(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmHitByBoxingGlove(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
void xUpdate() override;
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene1004 : public Klaymen {
|
||||
public:
|
||||
KmScene1004(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void stReadNote();
|
||||
uint32 hmReadNote(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1000_SPRITES_H */
|
||||
543
engines/neverhood/modules/module1100.cpp
Normal file
543
engines/neverhood/modules/module1100.cpp
Normal file
@@ -0,0 +1,543 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/gamemodule.h"
|
||||
#include "neverhood/navigationscene.h"
|
||||
#include "neverhood/modules/module1100.h"
|
||||
#include "neverhood/modules/module1100_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kModule1100SoundList[] = {
|
||||
0x90805C50,
|
||||
0xB288D450,
|
||||
0x98C05840,
|
||||
0x98A01500,
|
||||
0xB4005E50,
|
||||
0x92025040,
|
||||
0x90035066,
|
||||
0x74E01054,
|
||||
0
|
||||
};
|
||||
|
||||
Module1100::Module1100(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
if (which < 0) {
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
} else if (which == 1) {
|
||||
createScene(8, 1);
|
||||
} else {
|
||||
createScene(8, 3);
|
||||
}
|
||||
|
||||
_vm->_soundMan->addSoundList(0x0002C818, kModule1100SoundList);
|
||||
_vm->_soundMan->setSoundListParams(kModule1100SoundList, true, 50, 600, 20, 250);
|
||||
_vm->_soundMan->setSoundParams(0x74E01054, false, 100, 200, 10, 20);
|
||||
_vm->_soundMan->setSoundVolume(0x74E01054, 60);
|
||||
_vm->_soundMan->playTwoSounds(0x0002C818, 0x41861371, 0x43A2507F, 0);
|
||||
|
||||
}
|
||||
|
||||
Module1100::~Module1100() {
|
||||
_vm->_soundMan->deleteGroup(0x0002C818);
|
||||
}
|
||||
|
||||
void Module1100::createScene(int sceneNum, int which) {
|
||||
static const uint32 kSmackerFileHashList06[] = {0x10880805, 0x1088081D, 0};
|
||||
static const uint32 kSmackerFileHashList07[] = {0x00290321, 0x01881000, 0};
|
||||
static const byte kNavigationTypes02[] = {1, 0, 4, 1};
|
||||
debug(1, "Module1100::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_countdown = 65;
|
||||
createNavigationScene(0x004B8430, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
_countdown = 50;
|
||||
createNavigationScene(0x004B8460, which);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
if (getGlobalVar(V_ROBOT_TARGET)) {
|
||||
createNavigationScene(0x004B84F0, which, kNavigationTypes02);
|
||||
} else {
|
||||
createNavigationScene(0x004B8490, which, kNavigationTypes02);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
if (getGlobalVar(V_ROBOT_TARGET)) {
|
||||
createNavigationScene(0x004B8580, which);
|
||||
} else {
|
||||
createNavigationScene(0x004B8550, which);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
_childObject = new Scene1105(_vm, this);
|
||||
break;
|
||||
case 5:
|
||||
_vm->gameState().sceneNum = 5;
|
||||
if (getGlobalVar(V_ROBOT_TARGET))
|
||||
createSmackerScene(0x04180001, true, false, false);
|
||||
else
|
||||
createSmackerScene(0x04180007, true, false, false);
|
||||
break;
|
||||
case 6:
|
||||
_vm->gameState().sceneNum = 6;
|
||||
_vm->_soundMan->deleteSoundGroup(0x0002C818);
|
||||
createSmackerScene(kSmackerFileHashList06, true, true, false);
|
||||
break;
|
||||
case 7:
|
||||
_vm->gameState().sceneNum = 7;
|
||||
_vm->_soundMan->setSoundParams(0x74E01054, false, 0, 0, 0, 0);
|
||||
createSmackerScene(kSmackerFileHashList07, true, true, false);
|
||||
break;
|
||||
case 8:
|
||||
_vm->gameState().sceneNum = 8;
|
||||
_childObject = new Scene1109(_vm, this, which);
|
||||
break;
|
||||
case 1002:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
_countdown = 40;
|
||||
_vm->_soundMan->setTwoSoundsPlayFlag(true);
|
||||
createSmackerScene(0x00012211, true, true, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module1100::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module1100::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_countdown = 0;
|
||||
_vm->_soundMan->setSoundVolume(0x48498E46, 65);
|
||||
_vm->_soundMan->setSoundVolume(0x50399F64, 65);
|
||||
if (_moduleResult == 0) {
|
||||
_vm->_soundMan->playTwoSounds(0x0002C818, 0x48498E46, 0x50399F64, 0);
|
||||
createScene(1, 0);
|
||||
} else if (_moduleResult == 1) {
|
||||
/* NOTE This fixes a bug in the original where the "tunnel" footstep
|
||||
sounds are played instead of the correct footsteps. */
|
||||
_vm->_soundMan->playTwoSounds(0x0002C818, 0x41861371, 0x43A2507F, 0);
|
||||
createScene(8, 0);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
_countdown = 0;
|
||||
_vm->_soundMan->playTwoSounds(0x0002C818, 0x41861371, 0x43A2507F, 0);
|
||||
if (getGlobalVar(V_ROBOT_HIT)) {
|
||||
if (_moduleResult == 0)
|
||||
createScene(6, -1);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(0, 1);
|
||||
} else {
|
||||
if (_moduleResult == 0)
|
||||
createScene(2, 0);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(0, 1);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
_vm->_soundMan->setSoundParams(0x74E01054, false, 0, 0, 0, 0);
|
||||
if (_navigationAreaType == 3)
|
||||
createScene(7, -1);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(3, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(1002, -1);
|
||||
break;
|
||||
case 3:
|
||||
if (_moduleResult == 0)
|
||||
createScene(4, 0);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(2, 3);
|
||||
break;
|
||||
case 4:
|
||||
if (_moduleResult == 0)
|
||||
createScene(3, 0);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(5, -1);
|
||||
break;
|
||||
case 5:
|
||||
_vm->_soundMan->setTwoSoundsPlayFlag(false);
|
||||
if (getGlobalVar(V_ROBOT_TARGET))
|
||||
createScene(3, 0);
|
||||
else
|
||||
createScene(4, 0);
|
||||
break;
|
||||
case 6:
|
||||
_vm->_soundMan->setTwoSoundsPlayFlag(false);
|
||||
leaveModule(1);
|
||||
break;
|
||||
case 7:
|
||||
_vm->_soundMan->setTwoSoundsPlayFlag(false);
|
||||
createScene(2, 2);
|
||||
break;
|
||||
case 8:
|
||||
if (_moduleResult == 0)
|
||||
createScene(0, 0);
|
||||
else if (_moduleResult == 1)
|
||||
leaveModule(0);
|
||||
break;
|
||||
case 1002:
|
||||
_vm->_soundMan->setTwoSoundsPlayFlag(false);
|
||||
_countdown = 0;
|
||||
_vm->_soundMan->playTwoSounds(0x0002C818, 0x48498E46, 0x50399F64, 0);
|
||||
createScene(1, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (navigationScene()->isWalkingForward() && _countdown != 0 && (--_countdown == 0)) {
|
||||
_vm->_soundMan->playTwoSounds(0x0002C818, 0x48498E46, 0x50399F64, 0);
|
||||
_vm->_soundMan->setSoundVolume(0x48498E46, 65);
|
||||
_vm->_soundMan->setSoundVolume(0x50399F64, 65);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (navigationScene()->isWalkingForward() && _countdown != 0 && (--_countdown == 0))
|
||||
_vm->_soundMan->playTwoSounds(0x0002C818, 0x41861371, 0x43A2507F, 0);
|
||||
break;
|
||||
case 2:
|
||||
_vm->_soundMan->setSoundParams(0x74E01054, !navigationScene()->isWalkingForward(), 0, 0, 0, 0);
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 1002:
|
||||
if (_countdown != 0 && (--_countdown == 0)) {
|
||||
_vm->_soundMan->playTwoSounds(0x0002C818, 0x48498E46, 0x50399F64, 0);
|
||||
_vm->_soundMan->setSoundVolume(0x48498E46, 65);
|
||||
_vm->_soundMan->setSoundVolume(0x50399F64, 65);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const uint32 kScene1105BackgroundFileHashes[] = {
|
||||
0x20018662,
|
||||
0x20014202,
|
||||
0x20012202,
|
||||
0x20010002 // CHECKME: This used ??
|
||||
};
|
||||
|
||||
static const uint32 kScene1105FileHashes[] = {
|
||||
0x00028006,
|
||||
0x0100A425,
|
||||
0x63090415,
|
||||
0x082100C4,
|
||||
0x0068C607,
|
||||
0x00018344,
|
||||
0x442090E4,
|
||||
0x0400E004,
|
||||
0x5020A054,
|
||||
0xB14A891E
|
||||
};
|
||||
|
||||
Scene1105::Scene1105(NeverhoodEngine *vm, Module *parentModule)
|
||||
: Scene(vm, parentModule), _countdown(0), _isPanelOpen(false), _isActionButtonClicked(false), _doMoveTeddy(false),
|
||||
_isClosePanelDone(false), _leaveResult(0), _backgroundIndex(0) {
|
||||
|
||||
Sprite *ssOpenButton;
|
||||
|
||||
_vm->gameModule()->initMemoryPuzzle();
|
||||
|
||||
SetUpdateHandler(&Scene1105::update);
|
||||
SetMessageHandler(&Scene1105::handleMessage);
|
||||
|
||||
setBackground(0x20010002);
|
||||
setPalette(0x20010002);
|
||||
|
||||
_asTeddyBear = insertSprite<AsScene1105TeddyBear>(this);
|
||||
ssOpenButton = insertSprite<SsScene1105OpenButton>(this);
|
||||
addCollisionSprite(ssOpenButton);
|
||||
insertPuzzleMouse(0x10006208, 20, 620);
|
||||
|
||||
loadSound(0, 0x48442057);
|
||||
loadSound(1, 0xC025014F);
|
||||
loadSound(2, 0x68E25540);
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene1105::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = 0;
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
|
||||
if (!_isActionButtonClicked && _backgroundIndex == 0) {
|
||||
if (_isPanelOpen) {
|
||||
_isPanelOpen = false;
|
||||
_backgroundIndex = 15;
|
||||
SetUpdateHandler(&Scene1105::upClosePanel);
|
||||
} else
|
||||
_isClosePanelDone = true;
|
||||
_leaveResult = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x2001:
|
||||
showMouse(false);
|
||||
_backgroundIndex = 24;
|
||||
SetUpdateHandler(&Scene1105::upOpenPanel);
|
||||
break;
|
||||
case 0x2003:
|
||||
_backgroundIndex = 24;
|
||||
_leaveResult = 1;
|
||||
SetUpdateHandler(&Scene1105::upClosePanel);
|
||||
break;
|
||||
case NM_KLAYMEN_RAISE_LEVER:
|
||||
if (sender == _ssActionButton) {
|
||||
if (getSubVar(VA_GOOD_DICE_NUMBERS, 0) == getSubVar(VA_CURR_DICE_NUMBERS, 0) &&
|
||||
getSubVar(VA_GOOD_DICE_NUMBERS, 1) == getSubVar(VA_CURR_DICE_NUMBERS, 1) &&
|
||||
getSubVar(VA_GOOD_DICE_NUMBERS, 2) == getSubVar(VA_CURR_DICE_NUMBERS, 2)) {
|
||||
setGlobalVar(V_ROBOT_TARGET, 1);
|
||||
playSound(2);
|
||||
_doMoveTeddy = true;
|
||||
} else {
|
||||
sendMessage(_asTeddyBear, NM_POSITION_CHANGE, 0);
|
||||
}
|
||||
showMouse(false);
|
||||
_isActionButtonClicked = true;
|
||||
}
|
||||
break;
|
||||
case 0x4826:
|
||||
if (_isPanelOpen) {
|
||||
if (sender == _ssActionButton) {
|
||||
sendMessage(_ssActionButton, 0x480B, 0);
|
||||
_isPanelOpen = false;
|
||||
} else if (!getGlobalVar(V_ROBOT_TARGET)) {
|
||||
if (sender == _ssSymbol1UpButton) {
|
||||
if (getSubVar(VA_CURR_DICE_NUMBERS, 0) < 9) {
|
||||
incSubVar(VA_CURR_DICE_NUMBERS, 0, +1);
|
||||
sendMessage(_ssSymbol1UpButton, 0x480B, 0);
|
||||
sendMessage(_ssSymbolDice[0], 0x2000, 0);
|
||||
}
|
||||
} else if (sender == _ssSymbol1DownButton) {
|
||||
if (getSubVar(VA_CURR_DICE_NUMBERS, 0) > 1) {
|
||||
incSubVar(VA_CURR_DICE_NUMBERS, 0, -1);
|
||||
sendMessage(_ssSymbol1DownButton, 0x480B, 0);
|
||||
sendMessage(_ssSymbolDice[0], 0x2000, 0);
|
||||
}
|
||||
} else if (sender == _ssSymbol2UpButton) {
|
||||
if (getSubVar(VA_CURR_DICE_NUMBERS, 1) < 9) {
|
||||
incSubVar(VA_CURR_DICE_NUMBERS, 1, +1);
|
||||
sendMessage(_ssSymbol2UpButton, 0x480B, 0);
|
||||
sendMessage(_ssSymbolDice[1], 0x2000, 0);
|
||||
}
|
||||
} else if (sender == _ssSymbol2DownButton) {
|
||||
if (getSubVar(VA_CURR_DICE_NUMBERS, 1) > 1) {
|
||||
incSubVar(VA_CURR_DICE_NUMBERS, 1, -1);
|
||||
sendMessage(_ssSymbol2DownButton, 0x480B, 0);
|
||||
sendMessage(_ssSymbolDice[1], 0x2000, 0);
|
||||
}
|
||||
} else if (sender == _ssSymbol3UpButton) {
|
||||
if (getSubVar(VA_CURR_DICE_NUMBERS, 2) < 9) {
|
||||
incSubVar(VA_CURR_DICE_NUMBERS, 2, +1);
|
||||
sendMessage(_ssSymbol3UpButton, 0x480B, 0);
|
||||
sendMessage(_ssSymbolDice[2], 0x2000, 0);
|
||||
}
|
||||
} else if (sender == _ssSymbol3DownButton) {
|
||||
if (getSubVar(VA_CURR_DICE_NUMBERS, 2) > 1) {
|
||||
incSubVar(VA_CURR_DICE_NUMBERS, 2, -1);
|
||||
sendMessage(_ssSymbol3DownButton, 0x480B, 0);
|
||||
sendMessage(_ssSymbolDice[2], 0x2000, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void Scene1105::createObjects() {
|
||||
_ssSymbols[0] = insertSprite<SsScene1105Symbol>(kScene1105FileHashes[getSubVar(VA_DICE_MEMORY_SYMBOLS, 0)], 161, 304);
|
||||
_ssSymbols[1] = insertSprite<SsScene1105Symbol>(kScene1105FileHashes[getSubVar(VA_DICE_MEMORY_SYMBOLS, 1)], 294, 304);
|
||||
_ssSymbols[2] = insertSprite<SsScene1105Symbol>(kScene1105FileHashes[getSubVar(VA_DICE_MEMORY_SYMBOLS, 2)], 440, 304);
|
||||
|
||||
_ssSymbolDice[0] = insertSprite<SsScene1105SymbolDie>(0, 206, 304);
|
||||
_ssSymbolDice[1] = insertSprite<SsScene1105SymbolDie>(1, 339, 304);
|
||||
_ssSymbolDice[2] = insertSprite<SsScene1105SymbolDie>(2, 485, 304);
|
||||
|
||||
_ssSymbol1UpButton = insertSprite<SsScene1105Button>(this, 0x08002860, NRect::make(146, 362, 192, 403));
|
||||
addCollisionSprite(_ssSymbol1UpButton);
|
||||
_ssSymbol1DownButton = insertSprite<SsScene1105Button>(this, 0x42012460, NRect::make(147, 404, 191, 442));
|
||||
addCollisionSprite(_ssSymbol1DownButton);
|
||||
_ssSymbol2UpButton = insertSprite<SsScene1105Button>(this, 0x100030A0, NRect::make(308, 361, 355, 402));
|
||||
addCollisionSprite(_ssSymbol2UpButton);
|
||||
_ssSymbol2DownButton = insertSprite<SsScene1105Button>(this, 0x840228A0, NRect::make(306, 406, 352, 445));
|
||||
addCollisionSprite(_ssSymbol2DownButton);
|
||||
_ssSymbol3UpButton = insertSprite<SsScene1105Button>(this, 0x20000120, NRect::make(476, 358, 509, 394));
|
||||
addCollisionSprite(_ssSymbol3UpButton);
|
||||
_ssSymbol3DownButton = insertSprite<SsScene1105Button>(this, 0x08043121, NRect::make(463, 401, 508, 438));
|
||||
addCollisionSprite(_ssSymbol3DownButton);
|
||||
_ssActionButton = insertSprite<SsScene1105Button>(this, 0x8248AD35, NRect::make(280, 170, 354, 245));
|
||||
addCollisionSprite(_ssActionButton);
|
||||
|
||||
_isPanelOpen = true;
|
||||
|
||||
_asTeddyBear->show();
|
||||
|
||||
insertPuzzleMouse(0x18666208, 20, 620);
|
||||
|
||||
}
|
||||
|
||||
void Scene1105::upOpenPanel() {
|
||||
Scene::update();
|
||||
if (_backgroundIndex != 0) {
|
||||
_backgroundIndex--;
|
||||
if (_backgroundIndex < 6 && _backgroundIndex % 2 == 0) {
|
||||
uint32 backgroundFileHash = kScene1105BackgroundFileHashes[_backgroundIndex / 2];
|
||||
changeBackground(backgroundFileHash);
|
||||
_palette->addPalette(backgroundFileHash, 0, 256, 0);
|
||||
}
|
||||
if (_backgroundIndex == 10)
|
||||
playSound(0);
|
||||
if (_backgroundIndex == 0) {
|
||||
SetUpdateHandler(&Scene1105::update);
|
||||
_countdown = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Scene1105::upClosePanel() {
|
||||
Scene::update();
|
||||
if (_backgroundIndex != 0) {
|
||||
_backgroundIndex--;
|
||||
if (_backgroundIndex == 14) {
|
||||
showMouse(false);
|
||||
_ssSymbols[0]->hide();
|
||||
_ssSymbols[1]->hide();
|
||||
_ssSymbols[2]->hide();
|
||||
_ssSymbolDice[0]->hide();
|
||||
_ssSymbolDice[1]->hide();
|
||||
_ssSymbolDice[2]->hide();
|
||||
}
|
||||
if (_backgroundIndex < 6 && _backgroundIndex % 2 == 0) {
|
||||
uint32 backgroundFileHash = kScene1105BackgroundFileHashes[3 - _backgroundIndex / 2]; // CHECKME
|
||||
if (_backgroundIndex == 4) {
|
||||
playSound(1);
|
||||
_asTeddyBear->hide();
|
||||
}
|
||||
changeBackground(backgroundFileHash);
|
||||
_palette->addPalette(backgroundFileHash, 0, 256, 0);
|
||||
}
|
||||
if (_backgroundIndex == 0) {
|
||||
SetUpdateHandler(&Scene1105::update);
|
||||
_isClosePanelDone = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Scene1105::update() {
|
||||
Scene::update();
|
||||
if (_countdown != 0 && (--_countdown == 0))
|
||||
createObjects();
|
||||
if (_isClosePanelDone && !isSoundPlaying(1))
|
||||
leaveScene(_leaveResult);
|
||||
if (_doMoveTeddy && !isSoundPlaying(2)) {
|
||||
sendMessage(_asTeddyBear, NM_POSITION_CHANGE, 0);
|
||||
_doMoveTeddy = false;
|
||||
}
|
||||
}
|
||||
|
||||
Scene1109::Scene1109(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule) {
|
||||
|
||||
SetMessageHandler(&Scene1109::handleMessage);
|
||||
|
||||
setBackground(0x8449E02F);
|
||||
setPalette(0x8449E02F);
|
||||
insertScreenMouse(0x9E02B84C);
|
||||
|
||||
_sprite1 = insertStaticSprite(0x600CEF01, 1100);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene1109>(140, 436);
|
||||
setMessageList(0x004B6260);
|
||||
sendMessage(this, 0x2000, 0);
|
||||
} else if (which == 1) {
|
||||
// Klaymen teleporting in
|
||||
insertKlaymen<KmScene1109>(450, 436);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B6268, false);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
} else if (which == 2) {
|
||||
// Klaymen teleporting out
|
||||
insertKlaymen<KmScene1109>(450, 436);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B6318, false);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
} else if (which == 3) {
|
||||
// Klaymen returning from teleporter console
|
||||
insertKlaymen<KmScene1109>(450, 436);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B6278, false);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
} else {
|
||||
// Klaymen entering from the left
|
||||
insertKlaymen<KmScene1109>(0, 436);
|
||||
setMessageList(0x004B6258);
|
||||
sendMessage(this, 0x2000, 0);
|
||||
}
|
||||
|
||||
_klaymen->setClipRect(0, 0, _sprite1->getDrawRect().x2(), 480);
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene1109::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (param.asInteger()) {
|
||||
setRectList(0x004B63A8);
|
||||
_klaymen->setKlaymenIdleTable3();
|
||||
} else {
|
||||
setRectList(0x004B6398);
|
||||
_klaymen->setKlaymenIdleTable1();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
84
engines/neverhood/modules/module1100.h
Normal file
84
engines/neverhood/modules/module1100.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1100_H
|
||||
#define NEVERHOOD_MODULES_MODULE1100_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module1100 : public Module {
|
||||
public:
|
||||
Module1100(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module1100() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
int _countdown;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class AsScene1105TeddyBear;
|
||||
class SsScene1105Symbol;
|
||||
class SsScene1105SymbolDie;
|
||||
|
||||
class Scene1105 : public Scene {
|
||||
public:
|
||||
Scene1105(NeverhoodEngine *vm, Module *parentModule);
|
||||
protected:
|
||||
int _countdown;
|
||||
int _backgroundIndex;
|
||||
bool _isPanelOpen;
|
||||
bool _isActionButtonClicked;
|
||||
bool _doMoveTeddy;
|
||||
bool _isClosePanelDone;
|
||||
int _leaveResult;
|
||||
AsScene1105TeddyBear *_asTeddyBear;
|
||||
SsScene1105Symbol *_ssSymbols[3];
|
||||
SsScene1105SymbolDie *_ssSymbolDice[3];
|
||||
Sprite *_ssSymbol1UpButton;
|
||||
Sprite *_ssSymbol1DownButton;
|
||||
Sprite *_ssSymbol2UpButton;
|
||||
Sprite *_ssSymbol2DownButton;
|
||||
Sprite *_ssSymbol3UpButton;
|
||||
Sprite *_ssSymbol3DownButton;
|
||||
Sprite *_ssActionButton;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void createObjects();
|
||||
void upOpenPanel();
|
||||
void upClosePanel();
|
||||
void update();
|
||||
};
|
||||
|
||||
class Scene1109 : public Scene {
|
||||
public:
|
||||
Scene1109(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_sprite1;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1100_H */
|
||||
274
engines/neverhood/modules/module1100_sprites.cpp
Normal file
274
engines/neverhood/modules/module1100_sprites.cpp
Normal file
@@ -0,0 +1,274 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1100_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kSsScene1105SymbolDieFileHashes[] = {
|
||||
0,
|
||||
0x90898414,
|
||||
0x91098414,
|
||||
0x92098414,
|
||||
0x94098414,
|
||||
0x98098414,
|
||||
0x80098414,
|
||||
0xB0098414,
|
||||
0xD0098414,
|
||||
0x10098414
|
||||
};
|
||||
|
||||
SsScene1105Button::SsScene1105Button(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, NRect &collisionBounds)
|
||||
: StaticSprite(vm, fileHash, 200), _parentScene(parentScene), _countdown(0) {
|
||||
|
||||
_collisionBounds = collisionBounds;
|
||||
SetMessageHandler(&SsScene1105Button::handleMessage);
|
||||
SetUpdateHandler(&SsScene1105Button::update);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
void SsScene1105Button::update() {
|
||||
if (_countdown != 0 && (--_countdown == 0)) {
|
||||
sendMessage(_parentScene, NM_KLAYMEN_RAISE_LEVER, 0);
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SsScene1105Button::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (_countdown == 0) {
|
||||
sendMessage(_parentScene, 0x4826, 0);
|
||||
messageResult = 1;
|
||||
}
|
||||
break;
|
||||
case 0x480B:
|
||||
_countdown = 8;
|
||||
setVisible(true);
|
||||
playSound(0, 0x44141000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
SsScene1105Symbol::SsScene1105Symbol(NeverhoodEngine *vm, uint32 fileHash, int16 x, int16 y)
|
||||
: StaticSprite(vm, 0) {
|
||||
|
||||
loadSprite(fileHash, kSLFCenteredDrawOffset | kSLFSetPosition, 200, x, y);
|
||||
}
|
||||
|
||||
void SsScene1105Symbol::hide() {
|
||||
setVisible(false);
|
||||
_needRefresh = true;
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
SsScene1105SymbolDie::SsScene1105SymbolDie(NeverhoodEngine *vm, uint dieIndex, int16 x, int16 y)
|
||||
: StaticSprite(vm, 1100), _dieIndex(dieIndex) {
|
||||
|
||||
_x = x;
|
||||
_y = y;
|
||||
createSurface(200, 50, 50);
|
||||
loadSymbolSprite();
|
||||
SetMessageHandler(&SsScene1105SymbolDie::handleMessage);
|
||||
}
|
||||
|
||||
uint32 SsScene1105SymbolDie::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
loadSymbolSprite();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void SsScene1105SymbolDie::loadSymbolSprite() {
|
||||
loadSprite(kSsScene1105SymbolDieFileHashes[getSubVar(VA_CURR_DICE_NUMBERS, _dieIndex)], kSLFCenteredDrawOffset);
|
||||
}
|
||||
|
||||
void SsScene1105SymbolDie::hide() {
|
||||
setVisible(false);
|
||||
_needRefresh = true;
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
AsScene1105TeddyBear::AsScene1105TeddyBear(NeverhoodEngine *vm, Scene *parentScene)
|
||||
: AnimatedSprite(vm, 1100), _parentScene(parentScene) {
|
||||
|
||||
createSurface(100, 556, 328);
|
||||
_x = 320;
|
||||
_y = 240;
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1105TeddyBear::handleMessage);
|
||||
startAnimation(0x65084002, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
setVisible(false);
|
||||
_needRefresh = true;
|
||||
updatePosition();
|
||||
loadSound(0, 0xCE840261);
|
||||
loadSound(1, 0xCCA41A62);
|
||||
}
|
||||
|
||||
uint32 AsScene1105TeddyBear::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_POSITION_CHANGE:
|
||||
if (getGlobalVar(V_ROBOT_TARGET)) {
|
||||
startAnimation(0x6B0C0432, 0, -1);
|
||||
playSound(0);
|
||||
} else {
|
||||
startAnimation(0x65084002, 0, -1);
|
||||
playSound(1);
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
sendMessage(_parentScene, 0x2003, 0);
|
||||
stopAnimation();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1105TeddyBear::show() {
|
||||
setVisible(true);
|
||||
_needRefresh = true;
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
void AsScene1105TeddyBear::hide() {
|
||||
setVisible(false);
|
||||
_needRefresh = true;
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
SsScene1105OpenButton::SsScene1105OpenButton(NeverhoodEngine *vm, Scene *parentScene)
|
||||
: StaticSprite(vm, 900), _parentScene(parentScene), _countdown(0), _isClicked(false) {
|
||||
|
||||
loadSprite(0x8228A46C, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
|
||||
setVisible(false);
|
||||
loadSound(0, 0x44045140);
|
||||
SetUpdateHandler(&SsScene1105OpenButton::update);
|
||||
SetMessageHandler(&SsScene1105OpenButton::handleMessage);
|
||||
}
|
||||
|
||||
void SsScene1105OpenButton::update() {
|
||||
updatePosition();
|
||||
if (_countdown != 0 && (--_countdown == 0)) {
|
||||
setVisible(false);
|
||||
sendMessage(_parentScene, 0x2001, 0);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SsScene1105OpenButton::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = 0;
|
||||
Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (_countdown == 0 && !_isClicked) {
|
||||
playSound(0);
|
||||
setVisible(true);
|
||||
_isClicked = true;
|
||||
_countdown = 4;
|
||||
}
|
||||
messageResult = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
KmScene1109::KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene1109::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isSittingInTeleporter = param.asInteger() != 0;
|
||||
messageResult = 1;
|
||||
break;
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stSitIdleTeleporter);
|
||||
else
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x4804:
|
||||
if (param.asInteger() != 0) {
|
||||
_destX = param.asInteger();
|
||||
GotoState(&Klaymen::stWalkingFirst);
|
||||
} else
|
||||
GotoState(&Klaymen::stPeekWall);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stTurnToUseInTeleporter);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stReturnFromUseInTeleporter);
|
||||
break;
|
||||
case 0x4834:
|
||||
GotoState(&Klaymen::stStepOver);
|
||||
break;
|
||||
case 0x4835:
|
||||
sendMessage(_parentScene, 0x2000, 1);
|
||||
_isSittingInTeleporter = true;
|
||||
GotoState(&Klaymen::stSitInTeleporter);
|
||||
break;
|
||||
case 0x4836:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_isSittingInTeleporter = false;
|
||||
GotoState(&Klaymen::stGetUpFromTeleporter);
|
||||
break;
|
||||
case 0x483D:
|
||||
teleporterAppear(0x2C2A4A1C);
|
||||
break;
|
||||
case 0x483E:
|
||||
teleporterDisappear(0x3C2E4245);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
87
engines/neverhood/modules/module1100_sprites.h
Normal file
87
engines/neverhood/modules/module1100_sprites.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1100_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE1100_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class SsScene1105Button : public StaticSprite {
|
||||
public:
|
||||
SsScene1105Button(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash, NRect &collisionBounds);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class SsScene1105Symbol : public StaticSprite {
|
||||
public:
|
||||
SsScene1105Symbol(NeverhoodEngine *vm, uint32 fileHash, int16 x, int16 y);
|
||||
void hide();
|
||||
};
|
||||
|
||||
class SsScene1105SymbolDie : public StaticSprite {
|
||||
public:
|
||||
SsScene1105SymbolDie(NeverhoodEngine *vm, uint dieIndex, int16 x, int16 y);
|
||||
void hide();
|
||||
protected:
|
||||
uint _dieIndex;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void loadSymbolSprite();
|
||||
};
|
||||
|
||||
class AsScene1105TeddyBear : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1105TeddyBear(NeverhoodEngine *vm, Scene *parentScene);
|
||||
void show();
|
||||
void hide();
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class SsScene1105OpenButton : public StaticSprite {
|
||||
public:
|
||||
SsScene1105OpenButton(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _countdown;
|
||||
bool _isClicked;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene1109 : public Klaymen {
|
||||
public:
|
||||
KmScene1109(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1100_SPRITES_H */
|
||||
471
engines/neverhood/modules/module1200.cpp
Normal file
471
engines/neverhood/modules/module1200.cpp
Normal file
@@ -0,0 +1,471 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1200.h"
|
||||
#include "neverhood/modules/module1200_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
Module1200::Module1200(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
SetMessageHandler(&Module1200::handleMessage);
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else if (which == 1)
|
||||
createScene(0, 2);
|
||||
else
|
||||
createScene(0, 0);
|
||||
|
||||
_vm->_soundMan->addMusic(0x00478311, 0x62222CAE);
|
||||
_vm->_soundMan->startMusic(0x62222CAE, 0, 0);
|
||||
}
|
||||
|
||||
Module1200::~Module1200() {
|
||||
_vm->_soundMan->deleteMusicGroup(0x00478311);
|
||||
}
|
||||
|
||||
void Module1200::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module1200::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_childObject = new Scene1201(_vm, this, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
_childObject = new Scene1202(_vm, this);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
_vm->_soundMan->stopMusic(0x62222CAE, 0, 0);
|
||||
createSmackerScene(0x31890001, true, true, false);
|
||||
setGlobalVar(V_SEEN_CREATURE_EXPLODE_VID, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module1200::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module1200::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1)
|
||||
createScene(1, 0);
|
||||
else if (_moduleResult == 2) {
|
||||
if (getGlobalVar(V_CREATURE_EXPLODED) && !getGlobalVar(V_SEEN_CREATURE_EXPLODE_VID))
|
||||
createScene(2, -1);
|
||||
else
|
||||
leaveModule(1);
|
||||
} else
|
||||
leaveModule(0);
|
||||
break;
|
||||
case 1:
|
||||
createScene(0, 1);
|
||||
break;
|
||||
case 2:
|
||||
_vm->_soundMan->startMusic(0x62222CAE, 0, 0);
|
||||
createScene(0, 3);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const uint32 kScene1201InitArray[] = {
|
||||
1, 0, 2, 4, 5, 3, 6, 7, 8, 10, 9, 11, 13, 14, 12, 16, 17, 15
|
||||
};
|
||||
|
||||
Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _creatureExploded(false), _asMatch(nullptr), _asTntMan(nullptr),
|
||||
_asCreature(nullptr), _asTntManRope(nullptr), _asLeftDoor(nullptr), _asRightDoor(nullptr), _asTape(nullptr) {
|
||||
|
||||
int16 topY1, topY2, topY3, topY4;
|
||||
int16 x1, x2;
|
||||
Sprite *tempSprite;
|
||||
|
||||
SetUpdateHandler(&Scene1201::update);
|
||||
SetMessageHandler(&Scene1201::handleMessage);
|
||||
|
||||
setHitRects(0x004AEBD0);
|
||||
|
||||
if (!getSubVar(VA_IS_PUZZLE_INIT, 0xE8058B52)) {
|
||||
setSubVar(VA_IS_PUZZLE_INIT, 0xE8058B52, 1);
|
||||
for (uint32 index = 0; index < 18; index++)
|
||||
setSubVar(VA_TNT_POSITIONS, index, kScene1201InitArray[index]);
|
||||
}
|
||||
|
||||
insertScreenMouse(0x9A2C0409);
|
||||
|
||||
_asTape = insertSprite<AsScene1201Tape>(this, 3, 1100, 243, 340, 0x9148A011);
|
||||
addCollisionSprite(_asTape);
|
||||
|
||||
tempSprite = insertStaticSprite(0x03C82530, 100);
|
||||
topY1 = tempSprite->getY() + tempSprite->getDrawRect().height;
|
||||
|
||||
tempSprite = insertStaticSprite(0x88182069, 200);
|
||||
topY2 = tempSprite->getY() + tempSprite->getDrawRect().height;
|
||||
|
||||
tempSprite = insertStaticSprite(0x476014E0, 300);
|
||||
topY3 = tempSprite->getY() + tempSprite->getDrawRect().height;
|
||||
|
||||
tempSprite = insertStaticSprite(0x04063110, 500);
|
||||
topY4 = tempSprite->getY() + 1;
|
||||
|
||||
_asTntManRope = insertSprite<AsScene1201TntManRope>(getGlobalVar(V_TNT_DUMMY_BUILT) && which != 1);
|
||||
_asTntManRope->setClipRect(0, topY4, 640, 480);
|
||||
|
||||
insertStaticSprite(0x400B04B0, 1200);
|
||||
|
||||
tempSprite = insertStaticSprite(0x40295462, 1200);
|
||||
x1 = tempSprite->getX();
|
||||
|
||||
tempSprite = insertStaticSprite(0xA29223FA, 1200);
|
||||
x2 = tempSprite->getX() + tempSprite->getDrawRect().width;
|
||||
|
||||
_asKlaymenHead = insertSprite<AsScene1201KlaymenHead>();
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene1201>(364, 333);
|
||||
setMessageList(0x004AEC08);
|
||||
} else if (which == 3) {
|
||||
// Klaymen standing after the weasel exploded
|
||||
insertKlaymen<KmScene1201>(400, 329);
|
||||
setMessageList(0x004AEC08);
|
||||
} else if (which == 2) {
|
||||
// Klaymen entering from the right
|
||||
if (getGlobalVar(V_CREATURE_ANGRY) && !getGlobalVar(V_CREATURE_EXPLODED)) {
|
||||
insertKlaymen<KmScene1201>(374, 333);
|
||||
setMessageList(0x004AEC08);
|
||||
} else {
|
||||
insertKlaymen<KmScene1201>(640, 329);
|
||||
setMessageList(0x004AEC20);
|
||||
}
|
||||
} else if (which == 1) {
|
||||
// Klaymen returning from the TNT console
|
||||
if (getGlobalVar(V_KLAYMEN_IS_DELTA_X)) {
|
||||
insertKlaymen<KmScene1201>(364, 333);
|
||||
_klaymen->setDoDeltaX(1);
|
||||
} else {
|
||||
insertKlaymen<KmScene1201>(246, 333);
|
||||
}
|
||||
setMessageList(0x004AEC30);
|
||||
} else {
|
||||
// Klaymen entering from the left
|
||||
insertKlaymen<KmScene1201>(0, 336);
|
||||
setMessageList(0x004AEC10);
|
||||
}
|
||||
|
||||
_klaymen->setClipRect(x1, 0, x2, 480);
|
||||
_klaymen->setRepl(64, 0);
|
||||
|
||||
if (getGlobalVar(V_CREATURE_ANGRY) && !getGlobalVar(V_CREATURE_EXPLODED)) {
|
||||
setBackground(0x4019A2C4);
|
||||
setPalette(0x4019A2C4);
|
||||
_asRightDoor = nullptr;
|
||||
} else {
|
||||
setBackground(0x40206EC5);
|
||||
setPalette(0x40206EC5);
|
||||
_asRightDoor = insertSprite<AsScene1201RightDoor>(_klaymen, which == 2);
|
||||
}
|
||||
|
||||
if (getGlobalVar(V_TNT_DUMMY_BUILT)) {
|
||||
insertStaticSprite(0x10002ED8, 500);
|
||||
if (!getGlobalVar(V_CREATURE_EXPLODED)) {
|
||||
_asTntMan = insertSprite<AsScene1201TntMan>(this, _asTntManRope, which == 1);
|
||||
_asTntMan->setClipRect(x1, 0, x2, 480);
|
||||
_asTntMan->setRepl(64, 0);
|
||||
addCollisionSprite(_asTntMan);
|
||||
tempSprite = insertSprite<AsScene1201TntManFlame>(_asTntMan);
|
||||
tempSprite->setClipRect(x1, 0, x2, 480);
|
||||
}
|
||||
|
||||
uint32 tntIndex = 1;
|
||||
while (tntIndex < 18) {
|
||||
uint32 elemIndex = getSubVar(VA_TNT_POSITIONS, tntIndex);
|
||||
int16 clipY2;
|
||||
if (kScene1201PointArray[elemIndex].y < 175)
|
||||
clipY2 = topY1;
|
||||
else if (kScene1201PointArray[elemIndex].y < 230)
|
||||
clipY2 = topY2;
|
||||
else
|
||||
clipY2 = topY3;
|
||||
insertSprite<SsScene1201Tnt>(tntIndex, getSubVar(VA_TNT_POSITIONS, tntIndex), clipY2);
|
||||
elemIndex = getSubVar(VA_TNT_POSITIONS, tntIndex + 1);
|
||||
if (kScene1201PointArray[elemIndex].y < 175)
|
||||
clipY2 = topY1;
|
||||
else if (kScene1201PointArray[elemIndex].y < 230)
|
||||
clipY2 = topY2;
|
||||
else
|
||||
clipY2 = topY3;
|
||||
insertSprite<SsScene1201Tnt>(tntIndex + 1, getSubVar(VA_TNT_POSITIONS, tntIndex + 1), clipY2);
|
||||
tntIndex += 3;
|
||||
}
|
||||
|
||||
if (getGlobalVar(V_CREATURE_ANGRY) && !getGlobalVar(V_CREATURE_EXPLODED)) {
|
||||
setRectList(0x004AEE58);
|
||||
} else {
|
||||
setRectList(0x004AEDC8);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
insertStaticSprite(0x8E8A1981, 900);
|
||||
|
||||
uint32 tntIndex = 0;
|
||||
while (tntIndex < 18) {
|
||||
uint32 elemIndex = getSubVar(VA_TNT_POSITIONS, tntIndex);
|
||||
int16 clipY2;
|
||||
if (kScene1201PointArray[elemIndex].x < 300) {
|
||||
clipY2 = 480;
|
||||
} else {
|
||||
if (kScene1201PointArray[elemIndex].y < 175)
|
||||
clipY2 = topY1;
|
||||
else if (kScene1201PointArray[elemIndex].y < 230)
|
||||
clipY2 = topY2;
|
||||
else
|
||||
clipY2 = topY3;
|
||||
}
|
||||
insertSprite<SsScene1201Tnt>(tntIndex, getSubVar(VA_TNT_POSITIONS, tntIndex), clipY2);
|
||||
tntIndex++;
|
||||
}
|
||||
|
||||
if (getGlobalVar(V_CREATURE_ANGRY) && !getGlobalVar(V_CREATURE_EXPLODED))
|
||||
setRectList(0x004AEE18);
|
||||
else
|
||||
setRectList(0x004AED88);
|
||||
|
||||
}
|
||||
|
||||
tempSprite = insertStaticSprite(0x63D400BC, 900);
|
||||
|
||||
_asLeftDoor = insertSprite<AsScene1201LeftDoor>(_klaymen);
|
||||
_asLeftDoor->setClipRect(x1, tempSprite->getDrawRect().y, tempSprite->getDrawRect().x2(), 480);
|
||||
|
||||
if (getGlobalVar(V_CREATURE_ANGRY) && getGlobalVar(V_MATCH_STATUS) == 0)
|
||||
setGlobalVar(V_MATCH_STATUS, 1);
|
||||
|
||||
_asMatch = nullptr;
|
||||
|
||||
if (getGlobalVar(V_MATCH_STATUS) < 3) {
|
||||
_asMatch = insertSprite<AsScene1201Match>(this);
|
||||
addCollisionSprite(_asMatch);
|
||||
}
|
||||
|
||||
if (getGlobalVar(V_CREATURE_ANGRY) && getGlobalVar(V_CREATURE_EXPLODED) == 0) {
|
||||
_asCreature = insertSprite<AsScene1201Creature>(this, _klaymen);
|
||||
_asCreature->setClipRect(x1, 0, x2, 480);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Scene1201::~Scene1201() {
|
||||
if (_creatureExploded)
|
||||
setGlobalVar(V_CREATURE_EXPLODED, 1);
|
||||
setGlobalVar(V_KLAYMEN_IS_DELTA_X, _klaymen->isDoDeltaX() ? 1 : 0);
|
||||
}
|
||||
|
||||
void Scene1201::update() {
|
||||
Scene::update();
|
||||
if (_asMatch && getGlobalVar(V_MATCH_STATUS) == 3)
|
||||
deleteSprite(&_asMatch);
|
||||
}
|
||||
|
||||
uint32 Scene1201::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x07053000) {
|
||||
_creatureExploded = true;
|
||||
sendMessage(_asCreature, 0x2004, 0);
|
||||
} else if (param.asInteger() == 0x140E5744)
|
||||
sendMessage(_asCreature, NM_KLAYMEN_CLIMB_LADDER, 0);
|
||||
else if (param.asInteger() == 0x40253C40) {
|
||||
_canAcceptInput = false;
|
||||
sendMessage(_asCreature, NM_KLAYMEN_STOP_CLIMBING, 0);
|
||||
} else if (param.asInteger() == 0x090EB048) {
|
||||
if (_klaymen->getX() < 572)
|
||||
setMessageList2(0x004AEC90);
|
||||
else
|
||||
setMessageList2(0x004AEC20);
|
||||
}
|
||||
break;
|
||||
case 0x2001:
|
||||
if (getGlobalVar(V_MATCH_STATUS) == 0)
|
||||
setMessageList2(0x004AECB0);
|
||||
else {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asMatch);
|
||||
setMessageList2(0x004AECC0);
|
||||
}
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
if (getGlobalVar(V_TNT_DUMMY_FUSE_LIT)) {
|
||||
// Move the TNT dummy if the fuse is burning
|
||||
sendEntityMessage(_klaymen, 0x1014, _asTntMan);
|
||||
setMessageList2(0x004AECF0, false);
|
||||
} else if (getGlobalVar(V_MATCH_STATUS) == 3) {
|
||||
// Light the TNT dummy if we have the match
|
||||
sendEntityMessage(_klaymen, 0x1014, _asTntMan);
|
||||
if (_klaymen->getX() > _asTntMan->getX())
|
||||
setMessageList(0x004AECD0);
|
||||
else
|
||||
setMessageList(0x004AECE0);
|
||||
}
|
||||
break;
|
||||
case 0x4814:
|
||||
cancelMessageList();
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asTape) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asTape);
|
||||
setMessageList(0x004AED38);
|
||||
}
|
||||
break;
|
||||
case 0x4829:
|
||||
sendMessage(_asRightDoor, 0x4829, 0);
|
||||
break;
|
||||
case 0x8000:
|
||||
sendMessage(_asKlaymenHead, NM_KLAYMEN_STOP_CLIMBING, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
static const uint32 kScene1202Table[] = {
|
||||
1, 2, 0, 4, 5, 3, 7, 8, 6, 10, 11, 9, 13, 14, 12, 16, 17, 15
|
||||
};
|
||||
|
||||
Scene1202::Scene1202(NeverhoodEngine *vm, Module *parentModule)
|
||||
: Scene(vm, parentModule), _paletteResource(vm),
|
||||
_soundToggle(true), _isPuzzleSolved(false), _counter(0), _clickedIndex(-1) {
|
||||
|
||||
SetMessageHandler(&Scene1202::handleMessage);
|
||||
SetUpdateHandler(&Scene1202::update);
|
||||
|
||||
setBackground(0x60210ED5);
|
||||
setPalette(0x60210ED5);
|
||||
addEntity(_palette);
|
||||
|
||||
_paletteResource.load(0x60250EB5);
|
||||
_paletteResource.copyPalette(_paletteData);
|
||||
|
||||
insertPuzzleMouse(0x10ED160A, 20, 620);
|
||||
|
||||
for (int tntIndex = 0; tntIndex < 18; tntIndex++) {
|
||||
_asTntItems[tntIndex] = insertSprite<AsScene1202TntItem>(this, tntIndex);
|
||||
addCollisionSprite(_asTntItems[tntIndex]);
|
||||
}
|
||||
|
||||
insertStaticSprite(0x8E8419C1, 1100);
|
||||
|
||||
if (getGlobalVar(V_TNT_DUMMY_BUILT))
|
||||
SetMessageHandler(&Scene1202::hmSolved);
|
||||
|
||||
playSound(0, 0x40106542);
|
||||
loadSound(1, 0x40005446);
|
||||
loadSound(2, 0x40005446); // Same sound as slot 1
|
||||
loadSound(3, 0x68E25540);
|
||||
|
||||
}
|
||||
|
||||
Scene1202::~Scene1202() {
|
||||
if (isSolved())
|
||||
setGlobalVar(V_TNT_DUMMY_BUILT, 1);
|
||||
}
|
||||
|
||||
void Scene1202::update() {
|
||||
Scene::update();
|
||||
if (_isPuzzleSolved) {
|
||||
if (!isSoundPlaying(3))
|
||||
leaveScene(0);
|
||||
} else if (_counter == 0 && isSolved()) {
|
||||
_clickedIndex = 0;
|
||||
SetMessageHandler(&Scene1202::hmSolved);
|
||||
setGlobalVar(V_TNT_DUMMY_BUILT, 1);
|
||||
_palette->copyToBasePalette(_paletteData);
|
||||
_palette->startFadeToPalette(24);
|
||||
playSound(3);
|
||||
_isPuzzleSolved = true;
|
||||
} else if (_clickedIndex >= 0 && _counter == 0) {
|
||||
// Swap TNT positions
|
||||
int destIndex = kScene1202Table[_clickedIndex];
|
||||
sendMessage(_asTntItems[_clickedIndex], 0x2001, getSubVar(VA_TNT_POSITIONS, destIndex));
|
||||
sendMessage(_asTntItems[destIndex], 0x2001, getSubVar(VA_TNT_POSITIONS, _clickedIndex));
|
||||
int temp = getSubVar(VA_TNT_POSITIONS, destIndex);
|
||||
setSubVar(VA_TNT_POSITIONS, destIndex, getSubVar(VA_TNT_POSITIONS, _clickedIndex));
|
||||
setSubVar(VA_TNT_POSITIONS, _clickedIndex, temp);
|
||||
_counter = 2;
|
||||
_clickedIndex = -1;
|
||||
playSound(_soundToggle ? 1 : 2);
|
||||
_soundToggle = !_soundToggle;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Scene1202::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = 0;
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && !_isPuzzleSolved)
|
||||
leaveScene(0);
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_clickedIndex = (int)param.asInteger();
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
_counter--;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 Scene1202::hmSolved(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
|
||||
leaveScene(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Scene1202::isSolved() {
|
||||
return
|
||||
getSubVar(VA_TNT_POSITIONS, 0) == 0 && getSubVar(VA_TNT_POSITIONS, 3) == 3 &&
|
||||
getSubVar(VA_TNT_POSITIONS, 6) == 6 && getSubVar(VA_TNT_POSITIONS, 9) == 9 &&
|
||||
getSubVar(VA_TNT_POSITIONS, 12) == 12 && getSubVar(VA_TNT_POSITIONS, 15) == 15;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
81
engines/neverhood/modules/module1200.h
Normal file
81
engines/neverhood/modules/module1200.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1200_H
|
||||
#define NEVERHOOD_MODULES_MODULE1200_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module1200 : public Module {
|
||||
public:
|
||||
Module1200(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module1200() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class AsScene1201TntMan;
|
||||
|
||||
class Scene1201 : public Scene {
|
||||
public:
|
||||
Scene1201(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene1201() override;
|
||||
protected:
|
||||
Sprite *_asMatch;
|
||||
AsScene1201TntMan *_asTntMan;
|
||||
Sprite *_asCreature;
|
||||
Sprite *_asTntManRope;
|
||||
Sprite *_asLeftDoor;
|
||||
Sprite *_asRightDoor;
|
||||
Sprite *_asTape;
|
||||
Sprite *_asKlaymenHead;
|
||||
bool _creatureExploded;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1202 : public Scene {
|
||||
public:
|
||||
Scene1202(NeverhoodEngine *vm, Module *parentModule);
|
||||
~Scene1202() override;
|
||||
protected:
|
||||
PaletteResource _paletteResource;
|
||||
Sprite *_asTntItems[18];
|
||||
int _counter;
|
||||
int _clickedIndex;
|
||||
byte _paletteData[1024];
|
||||
bool _isPuzzleSolved;
|
||||
bool _soundToggle;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmSolved(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
bool isSolved();
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1200_H */
|
||||
847
engines/neverhood/modules/module1200_sprites.cpp
Normal file
847
engines/neverhood/modules/module1200_sprites.cpp
Normal file
@@ -0,0 +1,847 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1200_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kScene1201TntFileHashList1[] = {
|
||||
0x2098212D, 0x1600437E, 0x1600437E,
|
||||
0x00A840E3, 0x1A1830F6, 0x1A1830F6,
|
||||
0x00212062, 0x384010B6, 0x384010B6,
|
||||
0x07A01080, 0xD80C2837, 0xD80C2837,
|
||||
0x03A22092, 0xD8802CB6, 0xD8802CB6,
|
||||
0x03A93831, 0xDA460476, 0xDA460476
|
||||
};
|
||||
|
||||
static const uint32 kScene1201TntFileHashList2[] = {
|
||||
0x3040C676, 0x10914448, 0x10914448,
|
||||
0x3448A066, 0x1288C049, 0x1288C049,
|
||||
0x78C0E026, 0x3098D05A, 0x3098D05A,
|
||||
0x304890E6, 0x1284E048, 0x1284E048,
|
||||
0xB140A1E6, 0x5088A068, 0x5088A068,
|
||||
0x74C4C866, 0x3192C059, 0x3192C059
|
||||
};
|
||||
|
||||
SsScene1201Tnt::SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2)
|
||||
: StaticSprite(vm, 900) {
|
||||
|
||||
int16 x = kScene1201PointArray[pointIndex].x;
|
||||
int16 y = kScene1201PointArray[pointIndex].y;
|
||||
if (x < 300)
|
||||
loadSprite(kScene1201TntFileHashList1[elemIndex], kSLFDefDrawOffset | kSLFDefPosition, 50);
|
||||
else
|
||||
loadSprite(kScene1201TntFileHashList2[elemIndex], kSLFCenteredDrawOffset | kSLFSetPosition, 50, x, y - 20);
|
||||
setClipRect(0, 0, 640, clipY2);
|
||||
}
|
||||
|
||||
AsScene1201Tape::AsScene1201Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 nameHash, int surfacePriority, int16 x, int16 y, uint32 fileHash)
|
||||
: AnimatedSprite(vm, fileHash, surfacePriority, x, y), _parentScene(parentScene), _nameHash(nameHash) {
|
||||
|
||||
if (!getSubVar(VA_HAS_TAPE, _nameHash) && !getSubVar(VA_IS_TAPE_INSERTED, _nameHash)) {
|
||||
SetMessageHandler(&AsScene1201Tape::handleMessage);
|
||||
} else {
|
||||
setVisible(false);
|
||||
SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 AsScene1201Tape::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
sendMessage(_parentScene, 0x4826, 0);
|
||||
messageResult = 1;
|
||||
break;
|
||||
case NM_KLAYMEN_USE_OBJECT:
|
||||
setSubVar(VA_HAS_TAPE, _nameHash, 1);
|
||||
setVisible(false);
|
||||
SetMessageHandler(nullptr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene1201TntManRope::AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging)
|
||||
: AnimatedSprite(vm, 1200) {
|
||||
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1201TntManRope::handleMessage);
|
||||
createSurface(10, 34, 149);
|
||||
_x = 202;
|
||||
_y = -32;
|
||||
if (isDummyHanging) {
|
||||
startAnimation(0x928F0C10, 15, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
} else {
|
||||
startAnimation(0x928F0C10, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 AsScene1201TntManRope::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x02060018)
|
||||
playSound(0, 0x47900E06);
|
||||
break;
|
||||
case NM_KLAYMEN_STOP_CLIMBING:
|
||||
startAnimation(0x928F0C10, 1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene1201RightDoor::AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen)
|
||||
: AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown(0) {
|
||||
|
||||
createSurface1(0xD088AC30, 100);
|
||||
_x = 320;
|
||||
_y = 240;
|
||||
SetUpdateHandler(&AsScene1201RightDoor::update);
|
||||
SetMessageHandler(&AsScene1201RightDoor::handleMessage);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
if (isOpen) {
|
||||
startAnimation(0xD088AC30, -1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
_countdown = 25;
|
||||
} else {
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1201RightDoor::update() {
|
||||
if (_countdown != 0 && (--_countdown == 0))
|
||||
stCloseDoor();
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
uint32 AsScene1201RightDoor::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
case 0x4829:
|
||||
stOpenDoor();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1201RightDoor::stOpenDoor() {
|
||||
startAnimation(0xD088AC30, 0, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
setVisible(true);
|
||||
playSound(0, calcHash("fxDoorOpen20"));
|
||||
}
|
||||
|
||||
void AsScene1201RightDoor::stCloseDoor() {
|
||||
startAnimation(0xD088AC30, -1, -1);
|
||||
_playBackwards = true;
|
||||
setVisible(true);
|
||||
playSound(0, calcHash("fxDoorClose20"));
|
||||
NextState(&AsScene1201RightDoor::stCloseDoorDone);
|
||||
}
|
||||
|
||||
void AsScene1201RightDoor::stCloseDoorDone() {
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
AsScene1201KlaymenHead::AsScene1201KlaymenHead(NeverhoodEngine *vm)
|
||||
: AnimatedSprite(vm, 1200) {
|
||||
|
||||
createSurface(1200, 69, 98);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1201KlaymenHead::handleMessage);
|
||||
SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
uint32 AsScene1201KlaymenHead::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_KLAYMEN_STOP_CLIMBING:
|
||||
_x = 436;
|
||||
_y = 339;
|
||||
startAnimation(0xA060C599, 0, -1);
|
||||
setVisible(true);
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene1201TntMan::AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *asTntManRope, bool isComingDown)
|
||||
: AnimatedSprite(vm, 1100), _parentScene(parentScene), _asTntManRope(asTntManRope),
|
||||
_isMoving(false) {
|
||||
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1201TntMan::handleMessage);
|
||||
createSurface(990, 106, 181);
|
||||
_x = 201;
|
||||
if (isComingDown) {
|
||||
_y = 297;
|
||||
stComingDown();
|
||||
} else {
|
||||
_y = 334;
|
||||
stStanding();
|
||||
}
|
||||
}
|
||||
|
||||
AsScene1201TntMan::~AsScene1201TntMan() {
|
||||
_vm->_soundMan->deleteSoundGroup(0x01D00560);
|
||||
}
|
||||
|
||||
uint32 AsScene1201TntMan::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x092870C0)
|
||||
sendMessage(_asTntManRope, NM_KLAYMEN_STOP_CLIMBING, 0);
|
||||
else if (param.asInteger() == 0x11CA0144)
|
||||
playSound(0, 0x51800A04);
|
||||
break;
|
||||
case 0x1011:
|
||||
sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
|
||||
messageResult = 1;
|
||||
break;
|
||||
case 0x480B:
|
||||
if (!_isMoving) {
|
||||
_sprite = (Sprite*)sender;
|
||||
stMoving();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
|
||||
}
|
||||
|
||||
uint32 AsScene1201TntMan::hmComingDown(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = AsScene1201TntMan::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1201TntMan::suMoving() {
|
||||
_x = _sprite->getX() + 100;
|
||||
}
|
||||
|
||||
void AsScene1201TntMan::stStanding() {
|
||||
startAnimation(0x654913D0, 0, -1);
|
||||
SetMessageHandler(&AsScene1201TntMan::handleMessage);
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
|
||||
void AsScene1201TntMan::stComingDown() {
|
||||
startAnimation(0x356803D0, 0, -1);
|
||||
SetMessageHandler(&AsScene1201TntMan::hmComingDown);
|
||||
SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
|
||||
NextState(&AsScene1201TntMan::stStanding);
|
||||
}
|
||||
|
||||
void AsScene1201TntMan::stMoving() {
|
||||
_vm->_soundMan->addSound(0x01D00560, 0x4B044624);
|
||||
_vm->_soundMan->playSoundLooping(0x4B044624);
|
||||
_isMoving = true;
|
||||
startAnimation(0x85084190, 0, -1);
|
||||
SetMessageHandler(&AsScene1201TntMan::handleMessage);
|
||||
SetSpriteUpdate(&AsScene1201TntMan::suMoving);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
}
|
||||
|
||||
AsScene1201TntManFlame::AsScene1201TntManFlame(NeverhoodEngine *vm, Sprite *asTntMan)
|
||||
: AnimatedSprite(vm, 1200), _asTntMan(asTntMan) {
|
||||
|
||||
createSurface1(0x828C0411, 995);
|
||||
SetUpdateHandler(&AsScene1201TntManFlame::update);
|
||||
SetMessageHandler(&Sprite::handleMessage);
|
||||
SetSpriteUpdate(&AsScene1201TntManFlame::suUpdate);
|
||||
startAnimation(0x828C0411, 0, -1);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
AsScene1201TntManFlame::~AsScene1201TntManFlame() {
|
||||
_vm->_soundMan->deleteSoundGroup(0x041080A4);
|
||||
}
|
||||
|
||||
void AsScene1201TntManFlame::update() {
|
||||
AnimatedSprite::update();
|
||||
if (getGlobalVar(V_TNT_DUMMY_FUSE_LIT)) {
|
||||
setVisible(true);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
_vm->_soundMan->addSound(0x041080A4, 0x460A1050);
|
||||
_vm->_soundMan->playSoundLooping(0x460A1050);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1201TntManFlame::suUpdate() {
|
||||
_x = _asTntMan->getX() - 18;
|
||||
_y = _asTntMan->getY() - 158;
|
||||
}
|
||||
|
||||
AsScene1201Match::AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene)
|
||||
: AnimatedSprite(vm, 1100), _parentScene(parentScene), _countdown(0) {
|
||||
|
||||
createSurface(1100, 57, 60);
|
||||
SetUpdateHandler(&AsScene1201Match::update);
|
||||
SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
|
||||
SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
|
||||
switch (getGlobalVar(V_MATCH_STATUS)) {
|
||||
case 0:
|
||||
_x = 521;
|
||||
_y = 112;
|
||||
_status = 0;
|
||||
stIdleOnDoorFrame();
|
||||
break;
|
||||
case 1:
|
||||
_x = 521;
|
||||
_y = 112;
|
||||
_status = 2;
|
||||
stOnDoorFrameAboutToMove();
|
||||
loadSound(0, 0xD00230CD);
|
||||
break;
|
||||
case 2:
|
||||
setDoDeltaX(1);
|
||||
_x = 403;
|
||||
_y = 337;
|
||||
_status = 0;
|
||||
stIdleOnFloor();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1201Match::update() {
|
||||
if (_countdown != 0 && (--_countdown == 0))
|
||||
gotoNextState();
|
||||
updateAnim();
|
||||
handleSpriteUpdate();
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
uint32 AsScene1201Match::hmOnDoorFrameAboutToMove(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x86668011)
|
||||
playSound(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 AsScene1201Match::hmOnDoorFrameMoving(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 AsScene1201Match::hmIdle(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = hmOnDoorFrameAboutToMove(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
sendMessage(_parentScene, 0x2001, 0);
|
||||
messageResult = 1;
|
||||
break;
|
||||
case NM_KLAYMEN_USE_OBJECT:
|
||||
setVisible(false);
|
||||
setGlobalVar(V_MATCH_STATUS, 3);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1201Match::stOnDoorFrameMoving() {
|
||||
startAnimation(0x00842374, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Match::hmOnDoorFrameMoving);
|
||||
if (_status == 0) {
|
||||
NextState(&AsScene1201Match::stFallingFromDoorFrame);
|
||||
} else {
|
||||
NextState(&AsScene1201Match::stOnDoorFrameAboutToMove);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1201Match::stFallingFromDoorFrame() {
|
||||
setGlobalVar(V_MATCH_STATUS, 2);
|
||||
_x -= 199;
|
||||
_y += 119;
|
||||
startAnimation(0x018D0240, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Match::hmOnDoorFrameMoving);
|
||||
NextState(&AsScene1201Match::stIdleOnFloor);
|
||||
}
|
||||
|
||||
void AsScene1201Match::stOnDoorFrameAboutToMove() {
|
||||
startAnimation(0x00842374, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Match::hmOnDoorFrameAboutToMove);
|
||||
_newStickFrameIndex = 0;
|
||||
if (_status != 0) {
|
||||
_countdown = 36;
|
||||
_status--;
|
||||
NextState(&AsScene1201Match::stOnDoorFrameMoving);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1201Match::stIdleOnDoorFrame() {
|
||||
startAnimation(0x00842374, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Match::hmIdle);
|
||||
_newStickFrameIndex = 0;
|
||||
}
|
||||
|
||||
void AsScene1201Match::stIdleOnFloor() {
|
||||
setDoDeltaX(1);
|
||||
_x = 403;
|
||||
_y = 337;
|
||||
startAnimation(0x00842374, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Match::hmIdle);
|
||||
_newStickFrameIndex = 0;
|
||||
}
|
||||
|
||||
AsScene1201Creature::AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen)
|
||||
: AnimatedSprite(vm, 900), _parentScene(parentScene), _klaymen(klaymen), _klaymenTooClose(false) {
|
||||
|
||||
// NOTE: _countdown2 and _countdown3 were unused/without effect and thus removed
|
||||
|
||||
createSurface(1100, 203, 199);
|
||||
SetUpdateHandler(&AsScene1201Creature::update);
|
||||
SetMessageHandler(&AsScene1201Creature::hmWaiting);
|
||||
_x = 540;
|
||||
_y = 320;
|
||||
stWaiting();
|
||||
}
|
||||
|
||||
void AsScene1201Creature::update() {
|
||||
bool oldKlaymenTooClose = _klaymenTooClose;
|
||||
_klaymenTooClose = _klaymen->getX() >= 385;
|
||||
if (_klaymenTooClose != oldKlaymenTooClose)
|
||||
stWaiting();
|
||||
if (_countdown != 0 && (--_countdown == 0))
|
||||
gotoNextState();
|
||||
updateAnim();
|
||||
handleSpriteUpdate();
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
uint32 AsScene1201Creature::hmWaiting(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x02060018)
|
||||
playSound(0, 0xCD298116);
|
||||
break;
|
||||
case 0x2004:
|
||||
GotoState(&AsScene1201Creature::stStartReachForTntDummy);
|
||||
break;
|
||||
case NM_KLAYMEN_STOP_CLIMBING:
|
||||
GotoState(&AsScene1201Creature::stPincerSnapKlaymen);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 AsScene1201Creature::hmPincerSnap(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = hmWaiting(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 AsScene1201Creature::hmPincerSnapKlaymen(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x02060018) {
|
||||
playSound(0, 0xCD298116);
|
||||
sendMessage(_parentScene, 0x4814, 0);
|
||||
sendMessage(_klaymen, 0x4814, 0);
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1201Creature::stWaiting() {
|
||||
startAnimation(0x08081513, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Creature::hmWaiting);
|
||||
NextState(&AsScene1201Creature::stPincerSnap);
|
||||
_countdown = 36;
|
||||
}
|
||||
|
||||
void AsScene1201Creature::stPincerSnap() {
|
||||
if (!_klaymenTooClose) {
|
||||
startAnimation(0xCA287133, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Creature::hmPincerSnap);
|
||||
NextState(&AsScene1201Creature::stWaiting);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1201Creature::stStartReachForTntDummy() {
|
||||
startAnimation(0x08081513, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Creature::hmWaiting);
|
||||
NextState(&AsScene1201Creature::stReachForTntDummy);
|
||||
_countdown = 48;
|
||||
}
|
||||
|
||||
void AsScene1201Creature::stReachForTntDummy() {
|
||||
startAnimation(0x5A201453, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Creature::hmWaiting);
|
||||
_countdown = 0;
|
||||
}
|
||||
|
||||
void AsScene1201Creature::stPincerSnapKlaymen() {
|
||||
startAnimation(0xCA287133, 0, -1);
|
||||
SetMessageHandler(&AsScene1201Creature::hmPincerSnapKlaymen);
|
||||
NextState(&AsScene1201Creature::stWaiting);
|
||||
_countdown = 0;
|
||||
}
|
||||
|
||||
AsScene1201LeftDoor::AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klaymen)
|
||||
: AnimatedSprite(vm, 1100), _klaymen(klaymen) {
|
||||
|
||||
_x = 320;
|
||||
_y = 240;
|
||||
createSurface(800, 55, 199);
|
||||
if (_klaymen->getX() < 100) {
|
||||
startAnimation(0x508A111B, 0, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
playSound(0, calcHash("fxDoorOpen03"));
|
||||
} else {
|
||||
startAnimation(0x508A111B, -1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
}
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1201LeftDoor::handleMessage);
|
||||
}
|
||||
|
||||
uint32 AsScene1201LeftDoor::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_KLAYMEN_CLOSE_DOOR:
|
||||
stCloseDoor();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1201LeftDoor::stCloseDoor() {
|
||||
startAnimation(0x508A111B, -1, -1);
|
||||
_playBackwards = true;
|
||||
_newStickFrameIndex = 0;
|
||||
}
|
||||
|
||||
static const NPoint kScene1202Points[] = {
|
||||
{203, 140}, {316, 212}, {277, 264},
|
||||
{176, 196}, {275, 159}, {366, 212},
|
||||
{230, 195}, {412, 212}, {368, 263},
|
||||
{204, 192}, {365, 164}, {316, 262},
|
||||
{191, 255}, {280, 213}, {406, 266},
|
||||
{214, 254}, {316, 158}, {402, 161}
|
||||
};
|
||||
|
||||
static const uint32 kScene1202FileHashes[] = {
|
||||
0x1AC00B8, 0x1AC14B8, 0x1AC14B8,
|
||||
0x1AC30B8, 0x1AC14B8, 0x1AC14B8,
|
||||
0x1AC00B8, 0x1AC14B8, 0x1AC14B8,
|
||||
0x1AC90B8, 0x1AC18B8, 0x1AC18B8,
|
||||
0x1AC30B8, 0x1AC14B8, 0x1AC14B8,
|
||||
0x1AC50B8, 0x1AC14B8, 0x1AC14B8
|
||||
};
|
||||
|
||||
AsScene1202TntItem::AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int itemIndex)
|
||||
: AnimatedSprite(vm, 900), _parentScene(parentScene), _itemIndex(itemIndex) {
|
||||
|
||||
int positionIndex;
|
||||
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1202TntItem::hmShowIdle);
|
||||
positionIndex = getSubVar(VA_TNT_POSITIONS, _itemIndex);
|
||||
createSurface(900, 37, 67);
|
||||
_x = kScene1202Points[positionIndex].x;
|
||||
_y = kScene1202Points[positionIndex].y;
|
||||
stShowIdle();
|
||||
}
|
||||
|
||||
uint32 AsScene1202TntItem::hmShowIdle(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
sendMessage(_parentScene, 0x2000, _itemIndex);
|
||||
messageResult = 1;
|
||||
break;
|
||||
case 0x2001:
|
||||
_newPosition = (int)param.asInteger();
|
||||
stChangePositionFadeOut();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 AsScene1202TntItem::hmChangePosition(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1202TntItem::stShowIdle() {
|
||||
startAnimation(kScene1202FileHashes[_itemIndex], 0, -1);
|
||||
SetMessageHandler(&AsScene1202TntItem::hmShowIdle);
|
||||
_newStickFrameIndex = 0;
|
||||
}
|
||||
|
||||
void AsScene1202TntItem::stChangePositionFadeOut() {
|
||||
startAnimation(kScene1202FileHashes[_itemIndex], 0, -1);
|
||||
SetMessageHandler(&AsScene1202TntItem::hmChangePosition);
|
||||
NextState(&AsScene1202TntItem::stChangePositionFadeIn);
|
||||
}
|
||||
|
||||
void AsScene1202TntItem::stChangePositionFadeIn() {
|
||||
_x = kScene1202Points[_newPosition].x;
|
||||
_y = kScene1202Points[_newPosition].y;
|
||||
startAnimation(kScene1202FileHashes[_itemIndex], 6, -1);
|
||||
_playBackwards = true;
|
||||
SetMessageHandler(&AsScene1202TntItem::hmChangePosition);
|
||||
NextState(&AsScene1202TntItem::stChangePositionDone);
|
||||
}
|
||||
|
||||
void AsScene1202TntItem::stChangePositionDone() {
|
||||
sendMessage(_parentScene, NM_POSITION_CHANGE, _itemIndex);
|
||||
stShowIdle();
|
||||
}
|
||||
|
||||
static const KlaymenIdleTableItem klaymenIdleTable1201[] = {
|
||||
{1, kIdleSpinHead},
|
||||
{1, kIdleChest},
|
||||
{1, kIdleHeadOff},
|
||||
};
|
||||
|
||||
KmScene1201::KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
setKlaymenIdleTable(klaymenIdleTable1201, ARRAYSIZE(klaymenIdleTable1201));
|
||||
_doYHitIncr = true;
|
||||
}
|
||||
|
||||
uint32 KmScene1201::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
switch (messageNum) {
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case NM_KLAYMEN_MOVE_OBJECT:
|
||||
GotoState(&Klaymen::stMoveObject);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case 0x4813:
|
||||
GotoState(&KmScene1201::stFetchMatch);
|
||||
break;
|
||||
case 0x4814:
|
||||
GotoState(&KmScene1201::stTumbleHeadless);
|
||||
break;
|
||||
case 0x4815:
|
||||
GotoState(&KmScene1201::stCloseEyes);
|
||||
break;
|
||||
case NM_KLAYMEN_PRESS_BUTTON:
|
||||
if (param.asInteger() == 0)
|
||||
GotoState(&Klaymen::stPressButtonSide);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
GotoState(&Klaymen::stTurnToUse);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
GotoState(&Klaymen::stReturnFromUse);
|
||||
break;
|
||||
case 0x481F:
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
break;
|
||||
case 0x482D:
|
||||
setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void KmScene1201::stTumbleHeadless() {
|
||||
if (!stStartActionFromIdle(AnimationCallback(&KmScene1201::stTumbleHeadless))) {
|
||||
_busyStatus = 1;
|
||||
_acceptInput = false;
|
||||
setDoDeltaX(0);
|
||||
startAnimation(0x2821C590, 0, -1);
|
||||
SetUpdateHandler(&Klaymen::update);
|
||||
SetMessageHandler(&KmScene1201::hmTumbleHeadless);
|
||||
SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
|
||||
NextState(&Klaymen::stTryStandIdle);
|
||||
sendMessage(_parentScene, 0x8000, 0);
|
||||
playSound(0, 0x62E0A356);
|
||||
}
|
||||
}
|
||||
|
||||
void KmScene1201::stCloseEyes() {
|
||||
if (!stStartActionFromIdle(AnimationCallback(&KmScene1201::stCloseEyes))) {
|
||||
_busyStatus = 1;
|
||||
_acceptInput = false;
|
||||
startAnimation(0x5420E254, 0, -1);
|
||||
SetUpdateHandler(&Klaymen::update);
|
||||
SetMessageHandler(&Klaymen::hmLowLevel);
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 KmScene1201::hmMatch(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x51281850) {
|
||||
setGlobalVar(V_TNT_DUMMY_FUSE_LIT, 1);
|
||||
} else if (param.asInteger() == 0x43000538) {
|
||||
playSound(0, 0x21043059);
|
||||
} else if (param.asInteger() == 0x02B20220) {
|
||||
playSound(0, 0xC5408620);
|
||||
} else if (param.asInteger() == 0x0A720138) {
|
||||
playSound(0, 0xD4C08010);
|
||||
} else if (param.asInteger() == 0xB613A180) {
|
||||
playSound(0, 0x44051000);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void KmScene1201::stFetchMatch() {
|
||||
if (!stStartAction(AnimationCallback(&KmScene1201::stFetchMatch))) {
|
||||
_busyStatus = 0;
|
||||
_acceptInput = false;
|
||||
setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
|
||||
startAnimation(0x9CAA0218, 0, -1);
|
||||
SetUpdateHandler(&Klaymen::update);
|
||||
SetMessageHandler(&KmScene1201::hmMatch);
|
||||
SetSpriteUpdate(nullptr);
|
||||
NextState(&KmScene1201::stLightMatch);
|
||||
}
|
||||
}
|
||||
|
||||
void KmScene1201::stLightMatch() {
|
||||
_busyStatus = 1;
|
||||
_acceptInput = false;
|
||||
setDoDeltaX(_attachedSprite->getX() < _x ? 1 : 0);
|
||||
startAnimation(0x1222A513, 0, -1);
|
||||
SetUpdateHandler(&Klaymen::update);
|
||||
SetMessageHandler(&KmScene1201::hmMatch);
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
|
||||
uint32 KmScene1201::hmTumbleHeadless(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x000F0082) {
|
||||
playSound(0, 0x74E2810F);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
186
engines/neverhood/modules/module1200_sprites.h
Normal file
186
engines/neverhood/modules/module1200_sprites.h
Normal file
@@ -0,0 +1,186 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1200_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE1200_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Used for both the scene sprites and the scene itself (for clipping)
|
||||
static const NPoint kScene1201PointArray[] = {
|
||||
{218, 193}, {410, 225}, {368, 277},
|
||||
{194, 227}, {366, 174}, {458, 224},
|
||||
{242, 228}, {512, 228}, {458, 277},
|
||||
{217, 233}, {458, 173}, {410, 276},
|
||||
{203, 280}, {371, 226}, {508, 279},
|
||||
{230, 273}, {410, 171}, {493, 174}
|
||||
};
|
||||
|
||||
class AsScene1201Tape : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1201Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 nameHash, int surfacePriority, int16 x, int16 y, uint32 fileHash);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 _nameHash;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1201TntManRope : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1201TntManRope(NeverhoodEngine *vm, bool isDummyHanging);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1201RightDoor : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen);
|
||||
protected:
|
||||
Sprite *_klaymen;
|
||||
int _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stOpenDoor();
|
||||
void stCloseDoor();
|
||||
void stCloseDoorDone();
|
||||
};
|
||||
|
||||
class AsScene1201KlaymenHead : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1201KlaymenHead(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1201TntMan : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *asTntManRope, bool isDown);
|
||||
~AsScene1201TntMan() override;
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
Sprite *_asTntManRope;
|
||||
Sprite *_sprite;
|
||||
bool _isMoving;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmComingDown(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suMoving();
|
||||
void stStanding();
|
||||
void stComingDown();
|
||||
void stMoving();
|
||||
};
|
||||
|
||||
class AsScene1201TntManFlame : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1201TntManFlame(NeverhoodEngine *vm, Sprite *asTntMan);
|
||||
~AsScene1201TntManFlame() override;
|
||||
protected:
|
||||
Sprite *_asTntMan;
|
||||
void update();
|
||||
void suUpdate();
|
||||
};
|
||||
|
||||
class AsScene1201Match : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _countdown;
|
||||
int _status;
|
||||
void update();
|
||||
uint32 hmOnDoorFrameAboutToMove(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmOnDoorFrameMoving(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmIdle(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stOnDoorFrameMoving();
|
||||
void stFallingFromDoorFrame();
|
||||
void stOnDoorFrameAboutToMove();
|
||||
void stIdleOnDoorFrame();
|
||||
void stIdleOnFloor();
|
||||
};
|
||||
|
||||
class AsScene1201Creature : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
Sprite *_klaymen;
|
||||
int _countdown;
|
||||
bool _klaymenTooClose;
|
||||
void update();
|
||||
uint32 hmWaiting(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmPincerSnap(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmPincerSnapKlaymen(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stWaiting();
|
||||
void stPincerSnap();
|
||||
void stStartReachForTntDummy();
|
||||
void stReachForTntDummy();
|
||||
void stPincerSnapKlaymen();
|
||||
};
|
||||
|
||||
class AsScene1201LeftDoor : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klaymen);
|
||||
protected:
|
||||
Sprite *_klaymen;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stCloseDoor();
|
||||
};
|
||||
|
||||
class SsScene1201Tnt : public StaticSprite {
|
||||
public:
|
||||
SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 pointIndex, int16 clipY2);
|
||||
};
|
||||
|
||||
class AsScene1202TntItem : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int index);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _itemIndex, _newPosition;
|
||||
uint32 hmShowIdle(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmChangePosition(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stShowIdle();
|
||||
void stChangePositionFadeOut();
|
||||
void stChangePositionFadeIn();
|
||||
void stChangePositionDone();
|
||||
};
|
||||
|
||||
class KmScene1201 : public Klaymen {
|
||||
public:
|
||||
KmScene1201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void stCloseEyes();
|
||||
void stTumbleHeadless();
|
||||
void stFetchMatch();
|
||||
void stLightMatch();
|
||||
|
||||
uint32 hmTumbleHeadless(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmMatch(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1200_SPRITES_H */
|
||||
1258
engines/neverhood/modules/module1300.cpp
Normal file
1258
engines/neverhood/modules/module1300.cpp
Normal file
File diff suppressed because it is too large
Load Diff
166
engines/neverhood/modules/module1300.h
Normal file
166
engines/neverhood/modules/module1300.h
Normal file
@@ -0,0 +1,166 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1300_H
|
||||
#define NEVERHOOD_MODULES_MODULE1300_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class SmackerPlayer;
|
||||
|
||||
class Module1300 : public Module {
|
||||
public:
|
||||
Module1300(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module1300() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
uint32 _musicFileHash;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class Scene1302 : public Scene {
|
||||
public:
|
||||
Scene1302(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_asVenusFlyTrap;
|
||||
Sprite *_asBridge;
|
||||
Sprite *_ssFence;
|
||||
Sprite *_asRing1;
|
||||
Sprite *_asRing2;
|
||||
Sprite *_asRing3;
|
||||
Sprite *_asRing4;
|
||||
Sprite *_asRing5;
|
||||
Sprite *_class595;
|
||||
Sprite *_sprite1;
|
||||
Sprite *_sprite2;
|
||||
Sprite *_sprite3;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1303 : public Scene {
|
||||
public:
|
||||
Scene1303(NeverhoodEngine *vm, Module *parentModule);
|
||||
protected:
|
||||
Sprite *_sprite1;
|
||||
Sprite *_asBalloon;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1304 : public Scene {
|
||||
public:
|
||||
Scene1304(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_sprite1;
|
||||
Sprite *_asKey;
|
||||
Sprite *_asNeedle;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1305 : public Scene {
|
||||
public:
|
||||
Scene1305(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1306 : public Scene {
|
||||
public:
|
||||
Scene1306(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene1306() override;
|
||||
protected:
|
||||
Sprite *_ssButton;
|
||||
Sprite *_asTape;
|
||||
AnimatedSprite *_asElevatorDoor;
|
||||
Sprite *_asElevator;
|
||||
Sprite *_sprite1;
|
||||
Sprite *_asKey;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 handleMessage416EB0(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1307 : public Scene {
|
||||
public:
|
||||
Scene1307(NeverhoodEngine *vm, Module *parentModule);
|
||||
protected:
|
||||
NPointArray *_keyHolePoints;
|
||||
NRect _keyHoleRects[16];
|
||||
NRect _clipRects[4];
|
||||
Sprite *_asKeys[3];
|
||||
int _countdown;
|
||||
Sprite *_asCurrKey;
|
||||
bool _isInsertingKey;
|
||||
bool _doLeaveScene;
|
||||
bool _isPuzzleSolved;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1308 : public Scene {
|
||||
public:
|
||||
Scene1308(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_asTape;
|
||||
Sprite *_asJaggyDoor;
|
||||
Sprite *_asLightWallSymbols;
|
||||
Sprite *_ssNumber1;
|
||||
Sprite *_ssNumber2;
|
||||
Sprite *_ssNumber3;
|
||||
AnimatedSprite *_asProjector;
|
||||
Sprite *_sprite1;
|
||||
Sprite *_sprite2;
|
||||
Sprite *_sprite3;
|
||||
Sprite *_sprite4;
|
||||
Sprite *_sprite5;
|
||||
bool _isProjecting;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1317 : public Scene {
|
||||
public:
|
||||
Scene1317(NeverhoodEngine *vm, Module *parentModule);
|
||||
protected:
|
||||
SmackerPlayer *_smackerPlayer;
|
||||
bool _klaymenBlinks;
|
||||
int _klaymenBlinkCountdown;
|
||||
int _decisionCountdown;
|
||||
uint32 _smackerFileHash;
|
||||
bool _keepLastSmackerFrame;
|
||||
void update();
|
||||
void upChooseKing();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmChooseKing(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmHoborgAsKing(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmEndMovie(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stChooseKing();
|
||||
void stNoDecisionYet();
|
||||
void stHoborgAsKing();
|
||||
void stKlaymenAsKing();
|
||||
void stEndMovie();
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1300_H */
|
||||
966
engines/neverhood/modules/module1300_sprites.cpp
Normal file
966
engines/neverhood/modules/module1300_sprites.cpp
Normal file
@@ -0,0 +1,966 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1300_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
AsScene1302Bridge::AsScene1302Bridge(NeverhoodEngine *vm, Scene *parentScene)
|
||||
: AnimatedSprite(vm, 1100), _parentScene(parentScene) {
|
||||
|
||||
_x = 320;
|
||||
_y = 240;
|
||||
createSurface1(0x88148150, 500);
|
||||
if (!getGlobalVar(V_FLYTRAP_RING_BRIDGE)) {
|
||||
startAnimation(0x88148150, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
} else {
|
||||
startAnimation(0x88148150, -1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
}
|
||||
loadSound(0, 0x68895082);
|
||||
loadSound(1, 0x689BD0C1);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1302Bridge::handleMessage);
|
||||
}
|
||||
|
||||
uint32 AsScene1302Bridge::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
case NM_KLAYMEN_OPEN_DOOR:
|
||||
stLowerBridge();
|
||||
break;
|
||||
case NM_KLAYMEN_CLOSE_DOOR:
|
||||
stRaiseBridge();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1302Bridge::stLowerBridge() {
|
||||
startAnimation(0x88148150, 0, -1);
|
||||
playSound(1);
|
||||
NextState(&AsScene1302Bridge::cbLowerBridgeEvent);
|
||||
}
|
||||
|
||||
void AsScene1302Bridge::stRaiseBridge() {
|
||||
startAnimation(0x88148150, 7, -1);
|
||||
_playBackwards = true;
|
||||
_newStickFrameIndex = 0;
|
||||
playSound(0);
|
||||
}
|
||||
|
||||
void AsScene1302Bridge::cbLowerBridgeEvent() {
|
||||
sendMessage(_parentScene, 0x2032, 0);
|
||||
startAnimation(0x88148150, -1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
}
|
||||
|
||||
SsScene1302Fence::SsScene1302Fence(NeverhoodEngine *vm)
|
||||
: StaticSprite(vm, 0x11122122, 200) {
|
||||
|
||||
_firstY = _y;
|
||||
if (getGlobalVar(V_FLYTRAP_RING_FENCE))
|
||||
_y += 152;
|
||||
loadSound(0, 0x7A00400C);
|
||||
loadSound(1, 0x78184098);
|
||||
SetUpdateHandler(&SsScene1302Fence::update);
|
||||
SetMessageHandler(&SsScene1302Fence::handleMessage);
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
|
||||
void SsScene1302Fence::update() {
|
||||
handleSpriteUpdate();
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
uint32 SsScene1302Fence::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_KLAYMEN_OPEN_DOOR:
|
||||
playSound(0);
|
||||
SetMessageHandler(nullptr);
|
||||
SetSpriteUpdate(&SsScene1302Fence::suMoveDown);
|
||||
break;
|
||||
case NM_KLAYMEN_CLOSE_DOOR:
|
||||
playSound(1);
|
||||
SetMessageHandler(nullptr);
|
||||
SetSpriteUpdate(&SsScene1302Fence::suMoveUp);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void SsScene1302Fence::suMoveDown() {
|
||||
if (_y < _firstY + 152)
|
||||
_y += 8;
|
||||
else {
|
||||
SetMessageHandler(&SsScene1302Fence::handleMessage);
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void SsScene1302Fence::suMoveUp() {
|
||||
if (_y > _firstY)
|
||||
_y -= 8;
|
||||
else {
|
||||
SetMessageHandler(&SsScene1302Fence::handleMessage);
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
AsScene1303Balloon::AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene)
|
||||
: AnimatedSprite(vm, 1100), _parentScene(parentScene) {
|
||||
|
||||
createSurface(200, 128, 315);
|
||||
_x = 289;
|
||||
_y = 390;
|
||||
startAnimation(0x800278D2, 0, -1);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1303Balloon::handleMessage);
|
||||
SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
|
||||
}
|
||||
|
||||
uint32 AsScene1303Balloon::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
sendMessage(_parentScene, 0x4826, 0);
|
||||
messageResult = 1;
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
stPopBalloon();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 AsScene1303Balloon::hmBalloonPopped(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x020B0003)
|
||||
playSound(0, 0x742B0055);
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
playSound(0, 0x470007EE);
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
SetMessageHandler(nullptr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1303Balloon::stPopBalloon() {
|
||||
startAnimation(0xAC004CD0, 0, -1);
|
||||
SetMessageHandler(&AsScene1303Balloon::hmBalloonPopped);
|
||||
}
|
||||
|
||||
AsScene1304Needle::AsScene1304Needle(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, int16 x, int16 y)
|
||||
: AnimatedSprite(vm, 0x548E9411, surfacePriority, x, y), _parentScene(parentScene) {
|
||||
|
||||
// NOTE: Skipped check if Klaymen already has the needle since that's done in the scene itself
|
||||
SetMessageHandler(&AsScene1304Needle::handleMessage);
|
||||
}
|
||||
|
||||
uint32 AsScene1304Needle::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
sendMessage(_parentScene, 0x4826, 0);
|
||||
messageResult = 1;
|
||||
break;
|
||||
case NM_KLAYMEN_USE_OBJECT:
|
||||
setGlobalVar(V_HAS_NEEDLE, 1);
|
||||
setVisible(false);
|
||||
SetMessageHandler(nullptr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene1306Elevator::AsScene1306Elevator(NeverhoodEngine *vm, Scene *parentScene, AnimatedSprite *asElevatorDoor)
|
||||
: AnimatedSprite(vm, 1100), _parentScene(parentScene), _asElevatorDoor(asElevatorDoor), _isUp(false), _isDown(true),
|
||||
_countdown(0) {
|
||||
|
||||
_x = 320;
|
||||
_y = 240;
|
||||
createSurface1(0x043B0270, 100);
|
||||
startAnimation(0x043B0270, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
loadSound(0, 0x1C100E83);
|
||||
loadSound(1, 0x1C08CEC5);
|
||||
loadSound(2, 0x5D011E87);
|
||||
SetMessageHandler(&AsScene1306Elevator::handleMessage);
|
||||
}
|
||||
|
||||
void AsScene1306Elevator::update() {
|
||||
if (_isUp && _countdown != 0 && (--_countdown == 0))
|
||||
stGoingDown();
|
||||
AnimatedSprite::update();
|
||||
if (_currFrameIndex == 7 && _asElevatorDoor->getVisible()) {
|
||||
playSound(1);
|
||||
_asElevatorDoor->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1306Elevator::upGoingDown() {
|
||||
AnimatedSprite::update();
|
||||
if (_currFrameIndex == 5)
|
||||
_asElevatorDoor->setVisible(true);
|
||||
}
|
||||
|
||||
uint32 AsScene1306Elevator::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x2001:
|
||||
if (_isUp)
|
||||
_countdown = 144;
|
||||
messageResult = _isUp ? 1 : 0;
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
case NM_KLAYMEN_OPEN_DOOR:
|
||||
if (_isDown)
|
||||
stGoingUp();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1306Elevator::stGoingUp() {
|
||||
setVisible(true);
|
||||
_isDown = false;
|
||||
startAnimation(0x043B0270, 0, -1);
|
||||
playSound(0);
|
||||
SetUpdateHandler(&AsScene1306Elevator::update);
|
||||
NextState(&AsScene1306Elevator::cbGoingUpEvent);
|
||||
}
|
||||
|
||||
void AsScene1306Elevator::cbGoingUpEvent() {
|
||||
sendMessage(_parentScene, NM_KLAYMEN_OPEN_DOOR, 0);
|
||||
_isUp = true;
|
||||
_countdown = 144;
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
SetUpdateHandler(&AsScene1306Elevator::update);
|
||||
}
|
||||
|
||||
void AsScene1306Elevator::stGoingDown() {
|
||||
_isUp = false;
|
||||
setVisible(true);
|
||||
startAnimation(0x043B0270, -1, -1);
|
||||
_playBackwards = true;
|
||||
playSound(1);
|
||||
SetUpdateHandler(&AsScene1306Elevator::upGoingDown);
|
||||
NextState(&AsScene1306Elevator::cbGoingDownEvent);
|
||||
}
|
||||
|
||||
void AsScene1306Elevator::cbGoingDownEvent() {
|
||||
_isDown = true;
|
||||
sendMessage(_parentScene, NM_KLAYMEN_CLOSE_DOOR, 0);
|
||||
stopAnimation();
|
||||
SetUpdateHandler(&AsScene1306Elevator::update);
|
||||
}
|
||||
|
||||
static const uint32 kAsScene1307KeyResourceList1[] = {
|
||||
0x0438069C, 0x45B0023C, 0x05700217
|
||||
};
|
||||
|
||||
static const uint32 kAsScene1307KeyResourceList2[] = {
|
||||
0x04441334, 0x061433F0, 0x06019390
|
||||
};
|
||||
|
||||
static const uint32 kAsScene1307KeyResourceList3[] = {
|
||||
0x11A80030, 0x178812B1, 0x1488121C
|
||||
};
|
||||
|
||||
static const uint32 *kAsScene1307KeyResourceLists[] = {
|
||||
kAsScene1307KeyResourceList1,
|
||||
kAsScene1307KeyResourceList2,
|
||||
kAsScene1307KeyResourceList3
|
||||
};
|
||||
|
||||
static const int kAsScene1307KeySurfacePriorities[] = {
|
||||
700, 500, 300, 100
|
||||
};
|
||||
|
||||
const uint kAsScene1307KeyPointsCount = 12;
|
||||
|
||||
static const NPoint kAsScene1307KeyPoints[] = {
|
||||
{-2, 0}, {-5, 0}, { 5, 0},
|
||||
{12, 0}, {17, 0}, {25, 0},
|
||||
{16, -2}, {10, -6}, { 0, -7},
|
||||
{-7, -3}, {-3, 4}, { 2, 2}
|
||||
};
|
||||
|
||||
const uint kAsScene1307KeyFrameIndicesCount = 20;
|
||||
|
||||
static const int16 kAsScene1307KeyFrameIndices[] = {
|
||||
1, 4, 8, 11, 15, 16, 17, 17, 17, 16,
|
||||
15, 14, 12, 10, 9, 7, 5, 3, 2, 1
|
||||
};
|
||||
|
||||
const int kAsScene1307KeyDivValue = 200;
|
||||
const int16 kAsScene1307KeyXDelta = 70;
|
||||
const int16 kAsScene1307KeyYDelta = -12;
|
||||
|
||||
AsScene1307Key::AsScene1307Key(NeverhoodEngine *vm, Scene *parentScene, uint keyIndex, NRect *clipRects)
|
||||
: AnimatedSprite(vm, 1100), _parentScene(parentScene), _keyIndex(keyIndex), _clipRects(clipRects),
|
||||
_isClickable(true) {
|
||||
|
||||
NPoint pt;
|
||||
const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
|
||||
|
||||
_dataResource.load(0x22102142);
|
||||
_pointList = _dataResource.getPointArray(0xAC849240);
|
||||
pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
|
||||
_x = pt.x;
|
||||
_y = pt.y;
|
||||
createSurface(kAsScene1307KeySurfacePriorities[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4], 190, 148);
|
||||
startAnimation(fileHashes[0], 0, -1);
|
||||
loadSound(0, 0xDC4A1280);
|
||||
loadSound(1, 0xCC021233);
|
||||
loadSound(2, 0xC4C23844);
|
||||
loadSound(3, 0xC4523208);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1307Key::handleMessage);
|
||||
}
|
||||
|
||||
uint32 AsScene1307Key::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (_isClickable) {
|
||||
sendMessage(_parentScene, 0x4826, 0);
|
||||
stRemoveKey();
|
||||
messageResult = 1;
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isClickable = param.asInteger() != 0;
|
||||
break;
|
||||
case 0x2001:
|
||||
setSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex, param.asInteger());
|
||||
stMoveKey();
|
||||
break;
|
||||
case 0x2003:
|
||||
playSound(3);
|
||||
stUnlock();
|
||||
break;
|
||||
case 0x2004:
|
||||
playSound(2);
|
||||
stInsert();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1307Key::suRemoveKey() {
|
||||
if (_pointIndex < kAsScene1307KeyPointsCount) {
|
||||
_x += kAsScene1307KeyPoints[_pointIndex].x;
|
||||
_y += kAsScene1307KeyPoints[_pointIndex].y;
|
||||
updateBounds();
|
||||
_pointIndex++;
|
||||
} else {
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1307Key::suInsertKey() {
|
||||
if (_pointIndex < kAsScene1307KeyPointsCount) {
|
||||
_x -= kAsScene1307KeyPoints[kAsScene1307KeyPointsCount - _pointIndex - 1].x;
|
||||
_y -= kAsScene1307KeyPoints[kAsScene1307KeyPointsCount - _pointIndex - 1].y;
|
||||
updateBounds();
|
||||
_pointIndex++;
|
||||
if (_pointIndex == 7)
|
||||
playSound(0);
|
||||
} else {
|
||||
SetSpriteUpdate(nullptr);
|
||||
sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1307Key::suMoveKey() {
|
||||
if (_pointIndex < kAsScene1307KeyFrameIndicesCount) {
|
||||
_frameIndex += kAsScene1307KeyFrameIndices[_pointIndex];
|
||||
_x = _prevX + (_deltaX * _frameIndex) / kAsScene1307KeyDivValue;
|
||||
_y = _prevY + (_deltaY * _frameIndex) / kAsScene1307KeyDivValue;
|
||||
updateBounds();
|
||||
_pointIndex++;
|
||||
} else {
|
||||
NPoint pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
|
||||
_x = pt.x + kAsScene1307KeyXDelta;
|
||||
_y = pt.y + kAsScene1307KeyYDelta;
|
||||
stInsertKey();
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1307Key::stRemoveKey() {
|
||||
const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
|
||||
_pointIndex = 0;
|
||||
startAnimation(fileHashes[0], 0, -1);
|
||||
playSound(1);
|
||||
SetSpriteUpdate(&AsScene1307Key::suRemoveKey);
|
||||
}
|
||||
|
||||
void AsScene1307Key::stInsertKey() {
|
||||
_pointIndex = 0;
|
||||
sendMessage(_parentScene, NM_PRIORITY_CHANGE, kAsScene1307KeySurfacePriorities[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4]);
|
||||
setClipRect(_clipRects[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex) % 4]);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
SetSpriteUpdate(&AsScene1307Key::suInsertKey);
|
||||
}
|
||||
|
||||
void AsScene1307Key::stMoveKey() {
|
||||
NPoint pt = (*_pointList)[getSubVar(VA_CURR_KEY_SLOT_NUMBERS, _keyIndex)];
|
||||
int16 newX = pt.x + kAsScene1307KeyXDelta;
|
||||
int16 newY = pt.y + kAsScene1307KeyYDelta;
|
||||
sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1000);
|
||||
setClipRect(0, 0, 640, 480);
|
||||
_prevX = _x;
|
||||
_prevY = _y;
|
||||
if (newX == _x && newY == _y) {
|
||||
stInsertKey();
|
||||
} else {
|
||||
const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
|
||||
_pointIndex = 0;
|
||||
_frameIndex = 0;
|
||||
_deltaX = newX - _x;
|
||||
_deltaY = newY - _y;
|
||||
startAnimation(fileHashes[0], 0, -1);
|
||||
SetSpriteUpdate(&AsScene1307Key::suMoveKey);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1307Key::stUnlock() {
|
||||
const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
|
||||
startAnimation(fileHashes[1], 0, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
}
|
||||
|
||||
void AsScene1307Key::stInsert() {
|
||||
const uint32 *fileHashes = kAsScene1307KeyResourceLists[_keyIndex];
|
||||
startAnimation(fileHashes[2], 0, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
}
|
||||
|
||||
AsScene1308JaggyDoor::AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene)
|
||||
: AnimatedSprite(vm, 0xBA0AE050, 1100, 320, 240), _parentScene(parentScene) {
|
||||
|
||||
setVisible(false);
|
||||
stopAnimation();
|
||||
SetMessageHandler(&AsScene1308JaggyDoor::handleMessage);
|
||||
}
|
||||
|
||||
uint32 AsScene1308JaggyDoor::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
case NM_KLAYMEN_OPEN_DOOR:
|
||||
stOpenDoor();
|
||||
break;
|
||||
case NM_KLAYMEN_CLOSE_DOOR:
|
||||
stCloseDoor();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1308JaggyDoor::stOpenDoor() {
|
||||
startAnimation(0xBA0AE050, 0, -1);
|
||||
setVisible(true);
|
||||
playSound(0, calcHash("fxDoorOpen38"));
|
||||
NextState(&AsScene1308JaggyDoor::stOpenDoorDone);
|
||||
}
|
||||
|
||||
void AsScene1308JaggyDoor::stOpenDoorDone() {
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
void AsScene1308JaggyDoor::stCloseDoor() {
|
||||
startAnimation(0xBA0AE050, -1, -1);
|
||||
_playBackwards = true;
|
||||
setVisible(true);
|
||||
playSound(0, calcHash("fxDoorClose38"));
|
||||
NextState(&AsScene1308JaggyDoor::stCloseDoorDone);
|
||||
}
|
||||
|
||||
void AsScene1308JaggyDoor::stCloseDoorDone() {
|
||||
sendMessage(_parentScene, 0x2001, 0);
|
||||
stopAnimation();
|
||||
}
|
||||
|
||||
AsScene1308KeyboardDoor::AsScene1308KeyboardDoor(NeverhoodEngine *vm, Scene *parentScene)
|
||||
: AnimatedSprite(vm, 0xA08A0851, 1100, 320, 240), _parentScene(parentScene) {
|
||||
|
||||
playSound(0, 0x51456049);
|
||||
SetMessageHandler(&AsScene1308KeyboardDoor::handleMessage);
|
||||
NextState(&AsScene1308KeyboardDoor::stFallingKeys);
|
||||
}
|
||||
|
||||
uint32 AsScene1308KeyboardDoor::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1308KeyboardDoor::stFallingKeys() {
|
||||
startAnimation(0x6238B191, 0, -1);
|
||||
_x = 580;
|
||||
_y = 383;
|
||||
NextState(&AsScene1308KeyboardDoor::stFallingKeysDone);
|
||||
}
|
||||
|
||||
void AsScene1308KeyboardDoor::stFallingKeysDone() {
|
||||
sendMessage(_parentScene, 0x2004, 0);
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
AsScene1308LightWallSymbols::AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene)
|
||||
: AnimatedSprite(vm, 0x80180A10, 100, 320, 240), _parentScene(parentScene) {
|
||||
|
||||
setVisible(false);
|
||||
stopAnimation();
|
||||
Entity::_priority = 1200;
|
||||
SetMessageHandler(&AsScene1308LightWallSymbols::handleMessage);
|
||||
}
|
||||
|
||||
uint32 AsScene1308LightWallSymbols::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_POSITION_CHANGE:
|
||||
stFadeIn();
|
||||
break;
|
||||
case 0x2003:
|
||||
stFadeOut();
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1308LightWallSymbols::stFadeIn() {
|
||||
startAnimation(0x80180A10, 0, -1);
|
||||
setVisible(true);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
}
|
||||
|
||||
void AsScene1308LightWallSymbols::stFadeOut() {
|
||||
startAnimation(0x80180A10, -1, -1);
|
||||
_playBackwards = true;
|
||||
NextState(&AsScene1308LightWallSymbols::stFadeOutDone);
|
||||
}
|
||||
|
||||
void AsScene1308LightWallSymbols::stFadeOutDone() {
|
||||
sendMessage(_parentScene, 0x2003, 0);
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
SsScene1308Number::SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index)
|
||||
: StaticSprite(vm, fileHash, 100) {
|
||||
|
||||
setVisible(false);
|
||||
_x = _spriteResource.getPosition().x + index * 20;
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
AsScene1308Mouse::AsScene1308Mouse(NeverhoodEngine *vm)
|
||||
: AnimatedSprite(vm, 1100) {
|
||||
|
||||
_x = 286;
|
||||
_y = 429;
|
||||
createSurface1(0xA282C472, 100);
|
||||
startAnimation(0xA282C472, 0, -1);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1308Mouse::handleMessage);
|
||||
}
|
||||
|
||||
uint32 AsScene1308Mouse::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x66382026)
|
||||
playSound(0, 0x0CD84468);
|
||||
else if (param.asInteger() == 0x6E28061C)
|
||||
playSound(0, 0x78C8402C);
|
||||
else if (param.asInteger() == 0x462F0410)
|
||||
playSound(0, 0x60984E28);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
KmScene1303::KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene1303::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
switch (messageNum) {
|
||||
case 0x4804:
|
||||
GotoState(&Klaymen::stPeekWall1);
|
||||
break;
|
||||
case 0x483B:
|
||||
GotoState(&Klaymen::stPeekWallReturn);
|
||||
break;
|
||||
case 0x483C:
|
||||
GotoState(&Klaymen::stPeekWall2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
KmScene1304::KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene1304::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
switch (messageNum) {
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPickUpNeedle);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPickUpTube);
|
||||
else
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case 0x481F:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stTurnAwayFromUse);
|
||||
else if (param.asInteger() == 0)
|
||||
GotoState(&Klaymen::stTurnToUseHalf);
|
||||
else
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
KmScene1305::KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene1305::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
switch (messageNum) {
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x4804:
|
||||
GotoState(&KmScene1305::stCrashDown);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void KmScene1305::stCrashDown() {
|
||||
playSound(0, 0x41648271);
|
||||
_busyStatus = 1;
|
||||
_acceptInput = false;
|
||||
startAnimationByHash(0x000BAB02, 0x88003000, 0);
|
||||
SetUpdateHandler(&Klaymen::update);
|
||||
SetSpriteUpdate(nullptr);
|
||||
SetMessageHandler(&Klaymen::hmLowLevelAnimation);
|
||||
NextState(&KmScene1305::stCrashDownFinished);
|
||||
}
|
||||
|
||||
void KmScene1305::stCrashDownFinished() {
|
||||
setDoDeltaX(2);
|
||||
stTryStandIdle();
|
||||
}
|
||||
|
||||
KmScene1306::KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene1306::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isSittingInTeleporter = param.asInteger() != 0;
|
||||
messageResult = 1;
|
||||
break;
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stSitIdleTeleporter);
|
||||
else
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPickUpNeedle);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPickUpTube);
|
||||
else
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case NM_KLAYMEN_PRESS_BUTTON:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPressButton);
|
||||
else if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPressFloorButton);
|
||||
else
|
||||
GotoState(&Klaymen::stPressButtonSide);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case NM_KLAYMEN_INSERT_DISK:
|
||||
GotoState(&Klaymen::stInsertDisk);
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stTurnToUseInTeleporter);
|
||||
else
|
||||
GotoState(&Klaymen::stTurnToUse);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stReturnFromUseInTeleporter);
|
||||
else
|
||||
GotoState(&Klaymen::stReturnFromUse);
|
||||
break;
|
||||
case 0x481F:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stWonderAboutAfter);
|
||||
else if (param.asInteger() == 0)
|
||||
GotoState(&Klaymen::stWonderAboutHalf);
|
||||
else if (param.asInteger() == 4)
|
||||
GotoState(&Klaymen::stTurnAwayFromUse);
|
||||
else if (param.asInteger() == 3)
|
||||
GotoState(&Klaymen::stTurnToUseHalf);
|
||||
else
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
break;
|
||||
case 0x482D:
|
||||
setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x482E:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stWalkToFrontNoStep);
|
||||
else
|
||||
GotoState(&Klaymen::stWalkToFront);
|
||||
break;
|
||||
case 0x482F:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stTurnToFront);
|
||||
else
|
||||
GotoState(&Klaymen::stTurnToBack);
|
||||
break;
|
||||
case 0x4834:
|
||||
GotoState(&Klaymen::stStepOver);
|
||||
break;
|
||||
case 0x4835:
|
||||
sendMessage(_parentScene, 0x2000, 1);
|
||||
_isSittingInTeleporter = true;
|
||||
GotoState(&Klaymen::stSitInTeleporter);
|
||||
break;
|
||||
case 0x4836:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_isSittingInTeleporter = false;
|
||||
GotoState(&Klaymen::stGetUpFromTeleporter);
|
||||
break;
|
||||
case 0x483D:
|
||||
teleporterAppear(0xEE084A04);
|
||||
break;
|
||||
case 0x483E:
|
||||
teleporterDisappear(0xB86A4274);
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
KmScene1308::KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene1308::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
switch (messageNum) {
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case NM_KLAYMEN_MOVE_OBJECT:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stMoveObjectSkipTurnFaceObject);
|
||||
else
|
||||
GotoState(&Klaymen::stMoveObjectFaceObject);
|
||||
break;
|
||||
case 0x480D:
|
||||
GotoState(&Klaymen::stUseLever);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPickUpNeedle);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPickUpTube);
|
||||
else
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case NM_KLAYMEN_INSERT_DISK:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stInsertKey);
|
||||
else
|
||||
GotoState(&Klaymen::stInsertDisk);
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
GotoState(&Klaymen::stTurnToUse);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
GotoState(&Klaymen::stReturnFromUse);
|
||||
break;
|
||||
case NM_KLAYMEN_RELEASE_LEVER:
|
||||
GotoState(&Klaymen::stReleaseLever);
|
||||
break;
|
||||
case 0x4834:
|
||||
GotoState(&Klaymen::stStepOver);
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
198
engines/neverhood/modules/module1300_sprites.h
Normal file
198
engines/neverhood/modules/module1300_sprites.h
Normal file
@@ -0,0 +1,198 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1300_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE1300_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class AsScene1302Bridge : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1302Bridge(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stLowerBridge();
|
||||
void stRaiseBridge();
|
||||
void cbLowerBridgeEvent();
|
||||
};
|
||||
|
||||
class SsScene1302Fence : public StaticSprite {
|
||||
public:
|
||||
SsScene1302Fence(NeverhoodEngine *vm);
|
||||
protected:
|
||||
int16 _firstY;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suMoveDown();
|
||||
void suMoveUp();
|
||||
};
|
||||
|
||||
class AsScene1303Balloon : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1303Balloon(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmBalloonPopped(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stPopBalloon();
|
||||
};
|
||||
|
||||
class AsScene1304Needle : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1304Needle(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, int16 x, int16 y);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene1306Elevator : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1306Elevator(NeverhoodEngine *vm, Scene *parentScene, AnimatedSprite *asElevatorDoor);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
AnimatedSprite *_asElevatorDoor;
|
||||
bool _isUp;
|
||||
bool _isDown;
|
||||
int _countdown;
|
||||
void update();
|
||||
void upGoingDown();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stGoingUp();
|
||||
void cbGoingUpEvent();
|
||||
void stGoingDown();
|
||||
void cbGoingDownEvent();
|
||||
};
|
||||
|
||||
class AsScene1307Key : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1307Key(NeverhoodEngine *vm, Scene *parentScene, uint keyIndex, NRect *clipRects);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
NPointArray *_pointList;
|
||||
uint _pointIndex;
|
||||
int _frameIndex;
|
||||
uint _keyIndex;
|
||||
NRect *_clipRects;
|
||||
bool _isClickable;
|
||||
int16 _prevX, _prevY;
|
||||
int16 _deltaX, _deltaY;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suRemoveKey();
|
||||
void suInsertKey();
|
||||
void suMoveKey();
|
||||
void stRemoveKey();
|
||||
void stInsertKey();
|
||||
void stMoveKey();
|
||||
void stUnlock();
|
||||
void stInsert();
|
||||
};
|
||||
|
||||
class AsScene1308JaggyDoor : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1308JaggyDoor(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stOpenDoor();
|
||||
void stOpenDoorDone();
|
||||
void stCloseDoor();
|
||||
void stCloseDoorDone();
|
||||
};
|
||||
|
||||
class AsScene1308KeyboardDoor : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1308KeyboardDoor(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stFallingKeys();
|
||||
void stFallingKeysDone();
|
||||
};
|
||||
|
||||
class AsScene1308LightWallSymbols : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1308LightWallSymbols(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stFadeIn();
|
||||
void stFadeOut();
|
||||
void stFadeOutDone();
|
||||
};
|
||||
|
||||
class SsScene1308Number : public StaticSprite {
|
||||
public:
|
||||
SsScene1308Number(NeverhoodEngine *vm, uint32 fileHash, int index);
|
||||
};
|
||||
|
||||
class AsScene1308Mouse : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1308Mouse(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene1303 : public Klaymen {
|
||||
public:
|
||||
KmScene1303(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene1304 : public Klaymen {
|
||||
public:
|
||||
KmScene1304(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene1305 : public Klaymen {
|
||||
public:
|
||||
KmScene1305(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void stCrashDown();
|
||||
void stCrashDownFinished();
|
||||
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene1306 : public Klaymen {
|
||||
public:
|
||||
KmScene1306(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene1308 : public Klaymen {
|
||||
public:
|
||||
KmScene1308(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1300_SPRITES_H */
|
||||
771
engines/neverhood/modules/module1400.cpp
Normal file
771
engines/neverhood/modules/module1400.cpp
Normal file
@@ -0,0 +1,771 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/diskplayerscene.h"
|
||||
#include "neverhood/gamemodule.h"
|
||||
#include "neverhood/modules/module1000_sprites.h"
|
||||
#include "neverhood/modules/module1200_sprites.h"
|
||||
#include "neverhood/modules/module1400.h"
|
||||
#include "neverhood/modules/module1400_sprites.h"
|
||||
#include "neverhood/modules/module2100_sprites.h"
|
||||
#include "neverhood/modules/module2200_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
Module1400::Module1400(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
_vm->_soundMan->addMusic(0x00AD0012, 0x06333232);
|
||||
_vm->_soundMan->addMusic(0x00AD0012, 0x624A220E);
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else
|
||||
createScene(0, 0);
|
||||
|
||||
}
|
||||
|
||||
Module1400::~Module1400() {
|
||||
_vm->_soundMan->deleteMusicGroup(0x00AD0012);
|
||||
}
|
||||
|
||||
void Module1400::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module1400::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_vm->_soundMan->startMusic(0x06333232, 0, 2);
|
||||
_childObject = new Scene1401(_vm, this, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
_vm->_soundMan->stopMusic(0x06333232, 0, 2);
|
||||
_vm->_soundMan->stopMusic(0x624A220E, 0, 2);
|
||||
_childObject = new Scene1402(_vm, this, which);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
_vm->_soundMan->stopMusic(0x06333232, 0, 2);
|
||||
_vm->_soundMan->startMusic(0x624A220E, 0, 2);
|
||||
_childObject = new Scene1403(_vm, this, which);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
_vm->_soundMan->startMusic(0x06333232, 0, 2);
|
||||
_childObject = new Scene1404(_vm, this, which);
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
_vm->_soundMan->startMusic(0x06333232, 0, 2);
|
||||
_childObject = new Scene1405(_vm, this);
|
||||
break;
|
||||
case 5:
|
||||
_vm->gameState().sceneNum = 5;
|
||||
_vm->_soundMan->stopMusic(0x06333232, 0, 2);
|
||||
_childObject = new DiskplayerScene(_vm, this, 2);
|
||||
break;
|
||||
case 6:
|
||||
_vm->gameState().sceneNum = 6;
|
||||
_vm->_soundMan->stopMusic(0x06333232, 0, 2);
|
||||
_childObject = new Scene1407(_vm, this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module1400::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module1400::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1)
|
||||
createScene(1, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(3, 0);
|
||||
else
|
||||
leaveModule(0);
|
||||
break;
|
||||
case 1:
|
||||
if (_moduleResult == 1)
|
||||
createScene(2, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(6, -1);
|
||||
else
|
||||
createScene(0, 1);
|
||||
break;
|
||||
case 2:
|
||||
createScene(1, 1);
|
||||
break;
|
||||
case 3:
|
||||
if (_moduleResult == 1)
|
||||
createScene(4, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(5, -1);
|
||||
else
|
||||
createScene(0, 2);
|
||||
break;
|
||||
case 4:
|
||||
createScene(3, 1);
|
||||
break;
|
||||
case 5:
|
||||
createScene(3, 2);
|
||||
break;
|
||||
case 6:
|
||||
createScene(1, 2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scene1401::Scene1401(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _projectorBorderFlag(false), _ssFloorButton(nullptr), _asProjector(nullptr),
|
||||
_asPipe(nullptr), _asMouse(nullptr), _asCheese(nullptr), _asBackDoor(nullptr),
|
||||
_sprite1(nullptr), _sprite2(nullptr), _sprite3(nullptr), _ssButton(nullptr) {
|
||||
|
||||
SetMessageHandler(&Scene1401::handleMessage);
|
||||
SetUpdateHandler(&Scene1401::update);
|
||||
|
||||
setRectList(0x004B6758);
|
||||
setBackground(0x08221FA5);
|
||||
setPalette(0x08221FA5);
|
||||
insertScreenMouse(0x21FA108A);
|
||||
|
||||
_ssFloorButton = insertSprite<SsCommonFloorButton>(this, 0x980F3124, 0x12192892, 100, 0);
|
||||
_asPipe = insertSprite<AsScene1401Pipe>();
|
||||
|
||||
if (!getGlobalVar(V_MOUSE_SUCKED_IN)) {
|
||||
_asMouse = insertSprite<AsScene1401Mouse>();
|
||||
_asCheese = insertSprite<AsScene1401Cheese>();
|
||||
}
|
||||
|
||||
_sprite3 = insertStaticSprite(0xA82BA811, 1100);
|
||||
insertStaticSprite(0x0A116C60, 1100);
|
||||
_ssButton = insertSprite<SsCommonButtonSprite>(this, 0xB84B1100, 100, 0);
|
||||
_sprite1 = insertStaticSprite(0x38EA100C, 1005);
|
||||
_sprite2 = insertStaticSprite(0x98D0223C, 1200);
|
||||
_sprite2->setVisible(false);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene1401>(380, 447);
|
||||
setMessageList(0x004B65C8);
|
||||
_sprite1->setVisible(false);
|
||||
} else if (which == 1) {
|
||||
// Klaymen entering from the left
|
||||
insertKlaymen<KmScene1401>(0, 447);
|
||||
setMessageList(0x004B65D0);
|
||||
_sprite1->setVisible(false);
|
||||
} else if (which == 2) {
|
||||
// Klaymen entering from the right
|
||||
insertKlaymen<KmScene1401>(660, 447);
|
||||
setMessageList(0x004B65D8);
|
||||
_sprite1->setVisible(false);
|
||||
} else {
|
||||
// Klaymen entering from the back
|
||||
insertKlaymen<KmScene1401>(290, 413);
|
||||
setMessageList(0x004B65E8);
|
||||
_sprite1->setVisible(false);
|
||||
}
|
||||
|
||||
if (getGlobalVar(V_PROJECTOR_LOCATION) == 2) {
|
||||
_asProjector = insertSprite<AsCommonProjector>(this, _klaymen, _asPipe);
|
||||
addCollisionSprite(_asProjector);
|
||||
if (getGlobalVar(V_PROJECTOR_SLOT) == 6) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
_klaymen->setX(_asProjector->getX() + 100);
|
||||
_klaymen->updateBounds();
|
||||
setMessageList(0x004B6670);
|
||||
} else if (getGlobalVar(V_PROJECTOR_SLOT) == 0) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
_klaymen->setX(_asProjector->getX() - 100);
|
||||
_klaymen->updateBounds();
|
||||
setMessageList(0x004B6670);
|
||||
}
|
||||
_asProjector->setClipRect(_sprite3->getDrawRect().x, _sprite2->getDrawRect().y, 640, 480);
|
||||
}
|
||||
|
||||
_klaymen->setClipRect(_sprite3->getDrawRect().x, 0, 640, 480);
|
||||
|
||||
if (which == 0 && _asProjector)
|
||||
sendMessage(_asProjector, NM_MOVE_TO_FRONT, 0);
|
||||
|
||||
_asBackDoor = insertSprite<AsScene1401BackDoor>(_klaymen, which == 0);
|
||||
|
||||
}
|
||||
|
||||
void Scene1401::update() {
|
||||
Scene::update();
|
||||
if (_asProjector && !_projectorBorderFlag && _asProjector->getY() < 360) {
|
||||
_sprite2->setVisible(true);
|
||||
_projectorBorderFlag = true;
|
||||
} else
|
||||
_sprite2->setVisible(false);
|
||||
}
|
||||
|
||||
uint32 Scene1401::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x02144CB1)
|
||||
sendEntityMessage(_klaymen, 0x1014, _ssFloorButton);
|
||||
else if (param.asInteger() == 0x402064D8)
|
||||
sendEntityMessage(_klaymen, 0x1014, _ssButton);
|
||||
else if (param.asInteger() == 0x01C66840) {
|
||||
if (sendMessage(_asBackDoor, 0x2001, 0) != 0)
|
||||
setMessageList(0x004B6690);
|
||||
else
|
||||
setMessageList(0x004B66B0);
|
||||
}
|
||||
break;
|
||||
case NM_SCENE_LEAVE:
|
||||
if (param.asInteger() != 0)
|
||||
leaveScene(2);
|
||||
else
|
||||
leaveScene(1);
|
||||
break;
|
||||
case 0x480B:
|
||||
if (sender == _ssFloorButton) {
|
||||
sendMessage(_asPipe, 0x2000, 0);
|
||||
if (!getGlobalVar(V_MOUSE_SUCKED_IN)) {
|
||||
sendMessage(_asMouse, 0x4839, 0);
|
||||
sendMessage(_asCheese, 0x4839, 0);
|
||||
setGlobalVar(V_MOUSE_SUCKED_IN, 1);
|
||||
}
|
||||
if (_asProjector && _asProjector->getX() > 404 && _asProjector->getX() < 504)
|
||||
sendMessage(_asProjector , 0x4839, 0);
|
||||
} else if (sender == _ssButton)
|
||||
sendMessage(_asBackDoor, NM_KLAYMEN_OPEN_DOOR, 0);
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asProjector) {
|
||||
if (sendMessage(_asProjector, 0x480C, _klaymen->getX() > _asProjector->getX() ? 1 : 0) != 0) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
setMessageList2(0x004B6658);
|
||||
} else
|
||||
setMessageList2(0x004B65F0);
|
||||
}
|
||||
break;
|
||||
case NM_MOVE_TO_BACK:
|
||||
_sprite1->setVisible(true);
|
||||
if (_asProjector)
|
||||
sendMessage(_asProjector, NM_MOVE_TO_FRONT, 0);
|
||||
break;
|
||||
case NM_MOVE_TO_FRONT:
|
||||
_sprite1->setVisible(false);
|
||||
if (_asProjector)
|
||||
sendMessage(_asProjector, NM_MOVE_TO_BACK, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Scene1402::Scene1402(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _isShaking(false), _asPuzzleBox(nullptr), _asProjector(nullptr) {
|
||||
|
||||
SetMessageHandler(&Scene1402::handleMessage);
|
||||
|
||||
_vm->_screen->setYOffset(0);
|
||||
|
||||
setBackground(0x231482F0);
|
||||
setBackgroundY(-10);
|
||||
setPalette(0x231482F0);
|
||||
_palette->addPalette(0x91D3A391, 0, 64, 0);
|
||||
insertScreenMouse(0x482F4239);
|
||||
|
||||
_ssBridgePart1 = insertSprite<SsScene1402BridgePart>(0x15402D64, 1100);
|
||||
_ssBridgePart2 = insertSprite<SsScene1402BridgePart>(0x10A02120, 1100);
|
||||
_ssBridgePart3 = insertSprite<SsScene1402BridgePart>(0x60882BE0, 1100);
|
||||
|
||||
if (getGlobalVar(V_MOUSE_PUZZLE_SOLVED))
|
||||
setRectList(0x004B0C48);
|
||||
else
|
||||
setRectList(0x004B0C98);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene1402>(377, 391);
|
||||
setMessageList(0x004B0B48);
|
||||
if (!getGlobalVar(V_MOUSE_PUZZLE_SOLVED))
|
||||
_asPuzzleBox = insertSprite<AsScene1402PuzzleBox>(this, 0);
|
||||
} else if (which == 1) {
|
||||
// Klaymen entering from the left
|
||||
insertKlaymen<KmScene1402>(42, 391);
|
||||
setMessageList(0x004B0B50);
|
||||
} else if (which == 2) {
|
||||
// Klaymen returning from the puzzle box
|
||||
insertKlaymen<KmScene1402>(377, 391);
|
||||
setMessageList(0x004B0B60);
|
||||
_klaymen->setDoDeltaX(1);
|
||||
if (getGlobalVar(V_MOUSE_PUZZLE_SOLVED)) {
|
||||
_asPuzzleBox = insertSprite<AsScene1402PuzzleBox>(this, 1);
|
||||
clearRectList();
|
||||
showMouse(false);
|
||||
startShaking();
|
||||
} else
|
||||
_asPuzzleBox = insertSprite<AsScene1402PuzzleBox>(this, 0);
|
||||
} else {
|
||||
// Klaymen entering from the right
|
||||
insertKlaymen<KmScene1402>(513, 391);
|
||||
setMessageList(0x004B0B58);
|
||||
if (!getGlobalVar(V_MOUSE_PUZZLE_SOLVED)) {
|
||||
_asPuzzleBox = insertSprite<AsScene1402PuzzleBox>(this, 2);
|
||||
startShaking();
|
||||
}
|
||||
}
|
||||
|
||||
if (_asPuzzleBox)
|
||||
_asPuzzleBox->setClipRect(0, 0, 640, _ssBridgePart3->getDrawRect().y2());
|
||||
|
||||
if (getGlobalVar(V_PROJECTOR_LOCATION) == 1) {
|
||||
_asProjector = insertSprite<AsCommonProjector>(this, _klaymen, (Sprite*)nullptr);
|
||||
addCollisionSprite(_asProjector);
|
||||
if (getGlobalVar(V_PROJECTOR_SLOT) == 4) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
_klaymen->setX(_asProjector->getX() + 100);
|
||||
_klaymen->updateBounds();
|
||||
setMessageList(0x004B0BD0);
|
||||
} else if (getGlobalVar(V_PROJECTOR_SLOT) == 0) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
_klaymen->setX(_asProjector->getX() - 100);
|
||||
_klaymen->updateBounds();
|
||||
setMessageList(0x004B0BD0);
|
||||
}
|
||||
_asProjector->setClipRect(_ssBridgePart1->getDrawRect().x, 0, _ssBridgePart2->getDrawRect().x, _ssBridgePart3->getDrawRect().y2());
|
||||
}
|
||||
|
||||
_klaymen->setClipRect(_ssBridgePart1->getDrawRect().x, 0, _ssBridgePart2->getDrawRect().x2(), _ssBridgePart3->getDrawRect().y2());
|
||||
|
||||
}
|
||||
|
||||
void Scene1402::upShaking() {
|
||||
if (_isShaking) {
|
||||
setBackgroundY(_vm->_rnd->getRandomNumber(10 - 1) - 10);
|
||||
_vm->_screen->setYOffset(-10 - getBackgroundY());
|
||||
} else {
|
||||
setBackgroundY(-10);
|
||||
_vm->_screen->setYOffset(0);
|
||||
SetUpdateHandler(&Scene::update);
|
||||
}
|
||||
Scene::update();
|
||||
if (_asPuzzleBox)
|
||||
_asPuzzleBox->setClipRect(0, 0, 640, _ssBridgePart3->getDrawRect().y2());
|
||||
_klaymen->setClipRect(_ssBridgePart1->getDrawRect().x, 0, _ssBridgePart2->getDrawRect().x2(), _ssBridgePart3->getDrawRect().y2());
|
||||
}
|
||||
|
||||
uint32 Scene1402::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x00F43389) {
|
||||
if (getGlobalVar(V_MOUSE_PUZZLE_SOLVED))
|
||||
leaveScene(0);
|
||||
else {
|
||||
clearRectList();
|
||||
_klaymen->setVisible(false);
|
||||
showMouse(false);
|
||||
sendMessage(_asPuzzleBox, NM_POSITION_CHANGE, 0);
|
||||
startShaking();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_SCENE_LEAVE:
|
||||
if (param.asInteger())
|
||||
leaveScene(0);
|
||||
else
|
||||
leaveScene(1);
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
stopShaking();
|
||||
showMouse(true);
|
||||
setRectList(0x004B0C48);
|
||||
break;
|
||||
case 0x2001:
|
||||
stopShaking();
|
||||
leaveScene(0);
|
||||
break;
|
||||
case 0x2003:
|
||||
stopShaking();
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asProjector) {
|
||||
if (sendMessage(_asProjector, 0x480C, _klaymen->getX() > _asProjector->getX() ? 1 : 0) != 0) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
setMessageList2(0x004B0BB8);
|
||||
} else
|
||||
setMessageList2(0x004B0B68);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Scene1402::startShaking() {
|
||||
_isShaking = true;
|
||||
SetUpdateHandler(&Scene1402::upShaking);
|
||||
}
|
||||
|
||||
void Scene1402::stopShaking() {
|
||||
_isShaking = false;
|
||||
}
|
||||
|
||||
Scene1407::Scene1407(NeverhoodEngine *vm, Module *parentModule)
|
||||
: Scene(vm, parentModule), _puzzleSolvedCountdown(0), _resetButtonCountdown(0) {
|
||||
|
||||
SetMessageHandler(&Scene1407::handleMessage);
|
||||
SetUpdateHandler(&Scene1407::update);
|
||||
|
||||
setBackground(0x00442225);
|
||||
setPalette(0x00442225);
|
||||
insertPuzzleMouse(0x4222100C, 20, 620);
|
||||
|
||||
_asMouse = insertSprite<AsScene1407Mouse>(this);
|
||||
_ssResetButton = insertStaticSprite(0x12006600, 100);
|
||||
_ssResetButton->setVisible(false);
|
||||
|
||||
}
|
||||
|
||||
void Scene1407::update() {
|
||||
Scene::update();
|
||||
if (_puzzleSolvedCountdown != 0 && (--_puzzleSolvedCountdown == 0))
|
||||
leaveScene(1);
|
||||
else if (_resetButtonCountdown != 0 && (--_resetButtonCountdown == 0))
|
||||
_ssResetButton->setVisible(false);
|
||||
}
|
||||
|
||||
uint32 Scene1407::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if (_puzzleSolvedCountdown == 0) {
|
||||
if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
|
||||
// Exit scene
|
||||
leaveScene(0);
|
||||
} else if (param.asPoint().x >= 75 && param.asPoint().x <= 104 &&
|
||||
param.asPoint().y >= 62 && param.asPoint().y <= 90) {
|
||||
// The reset button was clicked
|
||||
sendMessage(_asMouse, 0x2001, 0);
|
||||
_ssResetButton->setVisible(true);
|
||||
playSound(0, 0x44045000);
|
||||
_resetButtonCountdown = 12;
|
||||
} else {
|
||||
// Handle the mouse
|
||||
sendMessage(_asMouse, messageNum, param);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
// The mouse got the cheese (nomnom)
|
||||
setGlobalVar(V_MOUSE_PUZZLE_SOLVED, 1);
|
||||
playSound(0, 0x68E25540);
|
||||
showMouse(false);
|
||||
_puzzleSolvedCountdown = 72;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Scene1403::Scene1403(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _asProjector(nullptr), _isProjecting(false) {
|
||||
|
||||
SetMessageHandler(&Scene1403::handleMessage);
|
||||
|
||||
setRectList(0x004B1FF8);
|
||||
setBackground(0x2110A234);
|
||||
setPalette(0x2110A234);
|
||||
insertScreenMouse(0x0A230219);
|
||||
|
||||
_sprite1 = insertStaticSprite(0x01102A33, 100);
|
||||
_sprite1->setVisible(false);
|
||||
_sprite2 = insertStaticSprite(0x04442520, 995);
|
||||
_sprite3 = insertStaticSprite(0x08742271, 995);
|
||||
_asTape1 = insertSprite<AsScene1201Tape>(this, 12, 1100, 201, 468, 0x9148A011);
|
||||
addCollisionSprite(_asTape1);
|
||||
_asTape1->setRepl(64, 0);
|
||||
_asTape2 = insertSprite<AsScene1201Tape>(this, 16, 1100, 498, 468, 0x9048A093);
|
||||
addCollisionSprite(_asTape2);
|
||||
_asTape2->setRepl(64, 0);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene1403>(380, 463);
|
||||
setMessageList(0x004B1F18);
|
||||
} else {
|
||||
// Klaymen entering from the right
|
||||
insertKlaymen<KmScene1403>(640, 463);
|
||||
setMessageList(0x004B1F20);
|
||||
}
|
||||
_klaymen->setRepl(64, 0);
|
||||
|
||||
if (getGlobalVar(V_PROJECTOR_LOCATION) == 0) {
|
||||
_asProjector = insertSprite<AsCommonProjector>(this, _klaymen, (Sprite*)nullptr);
|
||||
addCollisionSprite(_asProjector);
|
||||
if (getGlobalVar(V_PROJECTOR_SLOT) == 4) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
_klaymen->setX(_asProjector->getX() + 100);
|
||||
_klaymen->updateBounds();
|
||||
setMessageList(0x004B1F70);
|
||||
}
|
||||
_asProjector->setClipRect(0, 0, 640, _sprite2->getDrawRect().y2());
|
||||
_asProjector->setRepl(64, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene1403::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x88C11390) {
|
||||
setRectList(0x004B2008);
|
||||
_isProjecting = true;
|
||||
} else if (param.asInteger() == 0x08821382) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
setRectList(0x004B1FF8);
|
||||
_isProjecting = false;
|
||||
}
|
||||
break;
|
||||
case NM_SCENE_LEAVE:
|
||||
leaveScene(0);
|
||||
break;
|
||||
case NM_PRIORITY_CHANGE:
|
||||
if (sender == _asProjector) {
|
||||
if (param.asInteger() >= 1000)
|
||||
setSurfacePriority(_sprite3->getSurface(), 1100);
|
||||
else
|
||||
setSurfacePriority(_sprite3->getSurface(), 995);
|
||||
}
|
||||
break;
|
||||
case NM_KLAYMEN_RAISE_LEVER:
|
||||
_sprite1->setVisible(false);
|
||||
break;
|
||||
case NM_KLAYMEN_LOWER_LEVER:
|
||||
_sprite1->setVisible(true);
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asProjector) {
|
||||
if (_isProjecting)
|
||||
setMessageList2(0x004B1FA8);
|
||||
else if (param.asInteger() == 1) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
setMessageList2(0x004B1F88);
|
||||
} else if (sendMessage(_asProjector, 0x480C, _klaymen->getX() > _asProjector->getX() ? 1 : 0) != 0) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
setMessageList2(0x004B1F58);
|
||||
} else
|
||||
setMessageList2(0x004B1F28);
|
||||
} else if (sender == _asTape1 || sender == _asTape2) {
|
||||
if (_isProjecting)
|
||||
setMessageList2(0x004B1FA8);
|
||||
else if (_messageListStatus != 2) {
|
||||
sendEntityMessage(_klaymen, 0x1014, sender);
|
||||
setMessageList2(0x004B1FB8);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Scene1404::Scene1404(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _asProjector(nullptr), _asKey(nullptr) {
|
||||
|
||||
if (getGlobalVar(V_HAS_FINAL_KEY) && getGlobalVar(V_KEY3_LOCATION) == 0)
|
||||
setGlobalVar(V_KEY3_LOCATION, 5);
|
||||
|
||||
SetMessageHandler(&Scene1404::handleMessage);
|
||||
|
||||
setRectList(0x004B8D80);
|
||||
setBackground(0xAC0B006F);
|
||||
setPalette(0xAC0B006F);
|
||||
_palette->addPalette(0x00801510, 0, 65, 0);
|
||||
insertScreenMouse(0xB006BAC8);
|
||||
|
||||
if (getGlobalVar(V_KEY3_LOCATION) == 5) {
|
||||
_asKey = insertSprite<AsCommonKey>(this, 2, 1100, 267, 411);
|
||||
addCollisionSprite(_asKey);
|
||||
}
|
||||
|
||||
_sprite1 = insertStaticSprite(0x1900A1F8, 1100);
|
||||
_asTape = insertSprite<AsScene1201Tape>(this, 14, 1100, 281, 411, 0x9148A011);
|
||||
addCollisionSprite(_asTape);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene1404>(376, 406);
|
||||
setMessageList(0x004B8C28);
|
||||
} else if (which == 1) {
|
||||
// Klaymen returning from the tiles puzzle
|
||||
insertKlaymen<KmScene1404>(376, 406);
|
||||
setMessageList(0x004B8C30);
|
||||
} else if (which == 2) {
|
||||
// Klaymen returning from the diskplayer
|
||||
if (getGlobalVar(V_KLAYMEN_IS_DELTA_X)) {
|
||||
insertKlaymen<KmScene1404>(347, 406);
|
||||
_klaymen->setDoDeltaX(1);
|
||||
} else {
|
||||
insertKlaymen<KmScene1404>(187, 406);
|
||||
}
|
||||
setMessageList(0x004B8D28);
|
||||
} else {
|
||||
// Klaymen entering from the left
|
||||
insertKlaymen<KmScene1404>(30, 406);
|
||||
setMessageList(0x004B8C38);
|
||||
}
|
||||
|
||||
if (getGlobalVar(V_PROJECTOR_LOCATION) == 3) {
|
||||
_asProjector = insertSprite<AsCommonProjector>(this, _klaymen, (Sprite*)nullptr);
|
||||
addCollisionSprite(_asProjector);
|
||||
if (getGlobalVar(V_PROJECTOR_SLOT) == 0) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
_klaymen->setX(_asProjector->getX() - 100);
|
||||
_klaymen->updateBounds();
|
||||
setMessageList(0x004B8CB8);
|
||||
}
|
||||
_asProjector->setClipRect(_sprite1->getDrawRect().x, 0, 640, 480);
|
||||
}
|
||||
|
||||
_klaymen->setClipRect(_sprite1->getDrawRect().x, 0, 640, 480);
|
||||
|
||||
}
|
||||
|
||||
Scene1404::~Scene1404() {
|
||||
setGlobalVar(V_KLAYMEN_IS_DELTA_X, _klaymen->isDoDeltaX() ? 1 : 0);
|
||||
}
|
||||
|
||||
uint32 Scene1404::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x410650C2) {
|
||||
if (_asProjector && _asProjector->getX() == 220)
|
||||
setMessageList(0x004B8C40);
|
||||
else
|
||||
setMessageList(0x004B8CE8);
|
||||
}
|
||||
break;
|
||||
case NM_SCENE_LEAVE:
|
||||
leaveScene(0);
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asProjector) {
|
||||
if (sendMessage(_asProjector, 0x480C, _klaymen->getX() > _asProjector->getX() ? 1 : 0) != 0) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asProjector);
|
||||
setMessageList2(0x004B8CA0);
|
||||
} else
|
||||
setMessageList2(0x004B8C40);
|
||||
} else if (sender == _asTape && _messageListStatus != 2) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asTape);
|
||||
setMessageList(0x004B8CD0);
|
||||
} else if (sender == _asKey && _messageListStatus != 2) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asKey);
|
||||
setMessageList(0x004B8D18);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Scene1405::Scene1405(NeverhoodEngine *vm, Module *parentModule)
|
||||
: Scene(vm, parentModule), _selectFirstTile(true), _tilesLeft(48), _countdown(0) {
|
||||
|
||||
_vm->gameModule()->initMemoryPuzzle();
|
||||
|
||||
SetUpdateHandler(&Scene1405::update);
|
||||
SetMessageHandler(&Scene1405::handleMessage);
|
||||
|
||||
setBackground(0x0C0C007D);
|
||||
setPalette(0x0C0C007D);
|
||||
insertPuzzleMouse(0xC00790C8, 20, 620);
|
||||
|
||||
for (uint32 tileIndex = 0; tileIndex < 48; tileIndex++) {
|
||||
_tiles[tileIndex] = insertSprite<AsScene1405Tile>(this, tileIndex);
|
||||
addCollisionSprite(_tiles[tileIndex]);
|
||||
if (getSubVar(VA_IS_TILE_MATCH, tileIndex))
|
||||
_tilesLeft--;
|
||||
}
|
||||
|
||||
loadSound(0, 0x68E25540);
|
||||
}
|
||||
|
||||
void Scene1405::update() {
|
||||
Scene::update();
|
||||
// Check if the player chose a wrong tile, in which case the whole grid gets reset
|
||||
if (_countdown != 0 && (--_countdown == 0)) {
|
||||
_tilesLeft = 48;
|
||||
_tiles[_firstTileIndex]->hide(true);
|
||||
_tiles[_secondTileIndex]->hide(false);
|
||||
for (uint32 i = 0; i < 48; i++) {
|
||||
if (getSubVar(VA_IS_TILE_MATCH, i)) {
|
||||
_tiles[i]->hide(false);
|
||||
setSubVar(VA_IS_TILE_MATCH, i, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Scene1405::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
|
||||
leaveScene(0);
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (_selectFirstTile) {
|
||||
_firstTileIndex = param.asInteger();
|
||||
_selectFirstTile = false;
|
||||
} else {
|
||||
_secondTileIndex = param.asInteger();
|
||||
if (_firstTileIndex != _secondTileIndex) {
|
||||
_selectFirstTile = true;
|
||||
if (getSubVar(VA_TILE_SYMBOLS, _secondTileIndex) == getSubVar(VA_TILE_SYMBOLS, _firstTileIndex)) {
|
||||
setSubVar(VA_IS_TILE_MATCH, _firstTileIndex, 1);
|
||||
setSubVar(VA_IS_TILE_MATCH, _secondTileIndex, 1);
|
||||
_tilesLeft -= 2;
|
||||
if (_tilesLeft == 0)
|
||||
playSound(0);
|
||||
} else
|
||||
_countdown = 10;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
135
engines/neverhood/modules/module1400.h
Normal file
135
engines/neverhood/modules/module1400.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1400_H
|
||||
#define NEVERHOOD_MODULES_MODULE1400_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module1400 : public Module {
|
||||
public:
|
||||
Module1400(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module1400() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class AsCommonProjector;
|
||||
class AsScene1201Tape;
|
||||
class AsScene1405Tile;
|
||||
|
||||
class Scene1401 : public Scene {
|
||||
public:
|
||||
Scene1401(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
bool _projectorBorderFlag;
|
||||
Sprite *_ssFloorButton;
|
||||
AsCommonProjector *_asProjector;
|
||||
Sprite *_asPipe;
|
||||
Sprite *_asMouse;
|
||||
Sprite *_asCheese;
|
||||
Sprite *_asBackDoor;
|
||||
Sprite *_sprite1;
|
||||
Sprite *_sprite2;
|
||||
Sprite *_sprite3;
|
||||
Sprite *_ssButton;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1402 : public Scene {
|
||||
public:
|
||||
Scene1402(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_ssBridgePart1;
|
||||
Sprite *_ssBridgePart2;
|
||||
Sprite *_ssBridgePart3;
|
||||
Sprite *_asPuzzleBox;
|
||||
AsCommonProjector *_asProjector;
|
||||
bool _isShaking;
|
||||
void upShaking();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void startShaking();
|
||||
void stopShaking();
|
||||
};
|
||||
|
||||
class Scene1407 : public Scene {
|
||||
public:
|
||||
Scene1407(NeverhoodEngine *vm, Module *parentModule);
|
||||
protected:
|
||||
Sprite *_asMouse;
|
||||
Sprite *_ssResetButton;
|
||||
int _puzzleSolvedCountdown;
|
||||
int _resetButtonCountdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1403 : public Scene {
|
||||
public:
|
||||
Scene1403(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_sprite1;
|
||||
Sprite *_sprite2;
|
||||
Sprite *_sprite3;
|
||||
AsScene1201Tape *_asTape1;
|
||||
AsScene1201Tape *_asTape2;
|
||||
AsCommonProjector *_asProjector;
|
||||
bool _isProjecting;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1404 : public Scene {
|
||||
public:
|
||||
Scene1404(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene1404() override;
|
||||
protected:
|
||||
Sprite *_sprite1;
|
||||
Sprite *_asTape;
|
||||
AsCommonProjector *_asProjector;
|
||||
Sprite *_asKey;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene1405 : public Scene {
|
||||
public:
|
||||
Scene1405(NeverhoodEngine *vm, Module *parentModule);
|
||||
int getCountdown() const { return _countdown; }
|
||||
protected:
|
||||
bool _selectFirstTile;
|
||||
int _firstTileIndex;
|
||||
int _secondTileIndex;
|
||||
int _tilesLeft;
|
||||
int _countdown;
|
||||
AsScene1405Tile *_tiles[48];
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1400_H */
|
||||
1159
engines/neverhood/modules/module1400_sprites.cpp
Normal file
1159
engines/neverhood/modules/module1400_sprites.cpp
Normal file
File diff suppressed because it is too large
Load Diff
197
engines/neverhood/modules/module1400_sprites.h
Normal file
197
engines/neverhood/modules/module1400_sprites.h
Normal file
@@ -0,0 +1,197 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1400_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE1400_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class AsScene1401Pipe : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1401Pipe(NeverhoodEngine *vm);
|
||||
~AsScene1401Pipe() override;
|
||||
protected:
|
||||
int _countdown1;
|
||||
int _countdown2;
|
||||
void update();
|
||||
void upSuckInProjector();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmSuckInProjector(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stStartSucking();
|
||||
void stDoneSucking();
|
||||
void stSuckInProjector();
|
||||
};
|
||||
|
||||
class AsScene1401Mouse : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1401Mouse(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suSuckedIn();
|
||||
void stSuckedIn();
|
||||
};
|
||||
|
||||
class AsScene1401Cheese : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1401Cheese(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suSuckedIn();
|
||||
void stSuckedIn();
|
||||
};
|
||||
|
||||
class AsScene1401BackDoor : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1401BackDoor(NeverhoodEngine *vm, Sprite *klaymen, bool isOpen);
|
||||
protected:
|
||||
Sprite *_klaymen;
|
||||
int _countdown;
|
||||
bool _isOpen;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stOpenDoor();
|
||||
void stCloseDoor();
|
||||
void stCloseDoorDone();
|
||||
};
|
||||
|
||||
struct AsCommonProjectorItem {
|
||||
NPoint point;
|
||||
int8 maxSlotCount;
|
||||
int8 lockSlotIndex;
|
||||
int8 index1;
|
||||
int8 leftBorderLeaves;
|
||||
int8 rightBorderLeaves;
|
||||
};
|
||||
|
||||
class AsCommonProjector : public AnimatedSprite {
|
||||
public:
|
||||
AsCommonProjector(NeverhoodEngine *vm, Scene *parentScene, Sprite *klaymen, Sprite *asPipe);
|
||||
~AsCommonProjector() override;
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
Sprite *_klaymen;
|
||||
Sprite *_asPipe;
|
||||
const AsCommonProjectorItem *_asProjectorItem;
|
||||
int16 _beforeMoveX;
|
||||
bool _lockedInSlot;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmLockedInSlot(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmAnimation(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suMoving();
|
||||
void moveProjector();
|
||||
void stSuckedIn();
|
||||
void stIdle();
|
||||
void stMoving();
|
||||
void stStartLockedInSlot();
|
||||
void stStayLockedInSlot();
|
||||
void stStartProjecting();
|
||||
void stLockedInSlot();
|
||||
void stStopProjecting();
|
||||
void stTurnToFront();
|
||||
void stStartSuckedIn();
|
||||
};
|
||||
|
||||
class SsScene1402BridgePart : public StaticSprite {
|
||||
public:
|
||||
SsScene1402BridgePart(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority);
|
||||
};
|
||||
|
||||
class AsScene1402PuzzleBox : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1402PuzzleBox(NeverhoodEngine *vm, Scene *parentScene, int status);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stMoveUpDone();
|
||||
void stMoveDownDone();
|
||||
void stMoveDownSolvedDone();
|
||||
};
|
||||
|
||||
class AsScene1407Mouse : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1407Mouse(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int16 _walkDestX;
|
||||
int16 _currSectionIndex;
|
||||
int16 _nextHoleIndex;
|
||||
int _countdown;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suWalkTo();
|
||||
void upGoThroughHole();
|
||||
void stIdleLookAtGoodHole();
|
||||
void stWalkToDest();
|
||||
void stWalkToHole();
|
||||
void stGoThroughHole();
|
||||
void stArriveAtHole();
|
||||
};
|
||||
|
||||
class Scene1405;
|
||||
|
||||
class AsScene1405Tile : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1405Tile(NeverhoodEngine *vm, Scene1405 *parentScene, uint32 tileIndex);
|
||||
void show();
|
||||
void hide(bool playClickSound);
|
||||
protected:
|
||||
Scene1405 *_parentScene;
|
||||
bool _isShowing;
|
||||
uint32 _tileIndex;
|
||||
int _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene1401 : public Klaymen {
|
||||
public:
|
||||
KmScene1401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene1402 : public Klaymen {
|
||||
public:
|
||||
KmScene1402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene1403 : public Klaymen {
|
||||
public:
|
||||
KmScene1403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene1404 : public Klaymen {
|
||||
public:
|
||||
KmScene1404(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1400_SPRITES_H */
|
||||
137
engines/neverhood/modules/module1500.cpp
Normal file
137
engines/neverhood/modules/module1500.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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1500.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
Module1500::Module1500(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else
|
||||
createScene(3, -1);
|
||||
|
||||
}
|
||||
|
||||
void Module1500::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module1500::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_childObject = new Scene1501(_vm, this, 0x8420221D, 0xA61024C4, 150, 48);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
_childObject = new Scene1501(_vm, this, 0x30050A0A, 0x58B45E58, 110, 48);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
sendMessage(_parentModule, 0x0800, 0);
|
||||
createSmackerScene(0x001A0005, true, true, true);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
_childObject = new Scene1501(_vm, this, 0x0CA04202, 0, 110, 48);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module1500::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module1500::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
createScene(1, -1);
|
||||
break;
|
||||
case 1:
|
||||
createScene(2, -1);
|
||||
break;
|
||||
case 3:
|
||||
createScene(0, -1);
|
||||
break;
|
||||
default:
|
||||
leaveModule(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scene1501
|
||||
|
||||
Scene1501::Scene1501(NeverhoodEngine *vm, Module *parentModule, uint32 backgroundFileHash, uint32 soundFileHash, int countdown2, int countdown3)
|
||||
: Scene(vm, parentModule), _countdown3(countdown3), _countdown2(countdown2), _countdown1(0), _skip(false) {
|
||||
|
||||
SetUpdateHandler(&Scene1501::update);
|
||||
SetMessageHandler(&Scene1501::handleMessage);
|
||||
|
||||
setBackground(backgroundFileHash);
|
||||
setPalette();
|
||||
addEntity(_palette);
|
||||
_palette->addBasePalette(backgroundFileHash, 0, 256, 0);
|
||||
_palette->startFadeToPalette(12);
|
||||
|
||||
if (soundFileHash != 0)
|
||||
playSound(0, soundFileHash);
|
||||
|
||||
}
|
||||
|
||||
void Scene1501::update() {
|
||||
Scene::update();
|
||||
if (_countdown1 != 0) {
|
||||
_countdown1--;
|
||||
if (_countdown1 == 0 || _skip) {
|
||||
_vm->_screen->clear();
|
||||
leaveScene(0);
|
||||
}
|
||||
} else if ((_countdown2 != 0 && (--_countdown2 == 0)) || (_countdown2 == 0 && !isSoundPlaying(0)) || _skip) {
|
||||
_countdown1 = 12;
|
||||
_palette->startFadeToBlack(11);
|
||||
}
|
||||
|
||||
if (_countdown3 != 0)
|
||||
_countdown3--;
|
||||
|
||||
if (_countdown3 == 0 && _skip && _countdown1 == 0) {
|
||||
_countdown1 = 12;
|
||||
_palette->startFadeToBlack(11);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene1501::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_KEYPRESS_SPACE:
|
||||
_skip = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
57
engines/neverhood/modules/module1500.h
Normal file
57
engines/neverhood/modules/module1500.h
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// TODO: I couldn't come up with a better name than 'Module' so far
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1500_H
|
||||
#define NEVERHOOD_MODULES_MODULE1500_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
#include "neverhood/smackerscene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module1500 : public Module {
|
||||
public:
|
||||
Module1500(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
int _sceneNum;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class Scene1501 : public Scene {
|
||||
public:
|
||||
Scene1501(NeverhoodEngine *vm, Module *parentModule, uint32 backgroundFileHash, uint32 soundFileHash, int countdown2, int countdown3);
|
||||
protected:
|
||||
int _countdown1;
|
||||
int _countdown2;
|
||||
int _countdown3;
|
||||
bool _skip;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1500_H */
|
||||
609
engines/neverhood/modules/module1600.cpp
Normal file
609
engines/neverhood/modules/module1600.cpp
Normal file
@@ -0,0 +1,609 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/gamemodule.h"
|
||||
#include "neverhood/modules/module1200_sprites.h"
|
||||
#include "neverhood/modules/module1600.h"
|
||||
#include "neverhood/modules/module1600_sprites.h"
|
||||
#include "neverhood/modules/module2200_sprites.h"
|
||||
#include "neverhood/modules/module3000_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kModule1600SoundList[] = {
|
||||
0x90805C50, 0x90804450, 0xB4005E60,
|
||||
0x91835066, 0x90E14440, 0
|
||||
};
|
||||
|
||||
Module1600::Module1600(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else if (which == 1)
|
||||
createScene(4, 1);
|
||||
else if (which == 2)
|
||||
createScene(5, 0);
|
||||
else if (which == 3)
|
||||
createScene(6, 1);
|
||||
else if (which == 4)
|
||||
createScene(1, 0);
|
||||
else
|
||||
createScene(0, 0);
|
||||
|
||||
_vm->_soundMan->addSoundList(0x1A008D8, kModule1600SoundList);
|
||||
_vm->_soundMan->setSoundListParams(kModule1600SoundList, true, 50, 600, 5, 150);
|
||||
_vm->_soundMan->playTwoSounds(0x1A008D8, 0x41861371, 0x43A2507F, 0);
|
||||
|
||||
}
|
||||
|
||||
Module1600::~Module1600() {
|
||||
_vm->_soundMan->deleteGroup(0x1A008D8);
|
||||
}
|
||||
|
||||
void Module1600::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module1600::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
createNavigationScene(0x004B39D0, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
createNavigationScene(0x004B3A30, which);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
createNavigationScene(0x004B3A60, which);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
createNavigationScene(0x004B3A90, which);
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
createNavigationScene(0x004B3B20, which);
|
||||
break;
|
||||
case 5:
|
||||
_vm->gameState().sceneNum = 5;
|
||||
createNavigationScene(0x004B3B50, which);
|
||||
break;
|
||||
case 6:
|
||||
_vm->gameState().sceneNum = 6;
|
||||
createNavigationScene(0x004B3B80, which);
|
||||
break;
|
||||
case 7:
|
||||
_vm->gameState().sceneNum = 7;
|
||||
_childObject = new Scene1608(_vm, this, which);
|
||||
break;
|
||||
case 8:
|
||||
_vm->gameState().sceneNum = 8;
|
||||
_childObject = new Scene1609(_vm, this);
|
||||
break;
|
||||
case 1001:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
if (getGlobalVar(V_TALK_COUNTING_INDEX) == 1)
|
||||
createSmackerScene(0x80050200, true, true, false);
|
||||
else if (getGlobalVar(V_TALK_COUNTING_INDEX) == 2)
|
||||
createSmackerScene(0x80090200, true, true, false);
|
||||
else
|
||||
createSmackerScene(0x80000200, true, true, false);
|
||||
if (getGlobalVar(V_TALK_COUNTING_INDEX) >= 2)
|
||||
setGlobalVar(V_TALK_COUNTING_INDEX, 0);
|
||||
else
|
||||
incGlobalVar(V_TALK_COUNTING_INDEX, +1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module1600::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module1600::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 0)
|
||||
createScene(2, 0);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(1, 0);
|
||||
else if (_moduleResult == 2)
|
||||
leaveModule(4);
|
||||
break;
|
||||
case 1:
|
||||
if (_moduleResult == 0)
|
||||
createScene(1001, -1);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(0, 3);
|
||||
break;
|
||||
case 2:
|
||||
if (_moduleResult == 0)
|
||||
createScene(3, 0);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(0, 2);
|
||||
break;
|
||||
case 3:
|
||||
if (_moduleResult == 0)
|
||||
createScene(5, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(6, 0);
|
||||
else if (_moduleResult == 3)
|
||||
createScene(2, 1);
|
||||
else if (_moduleResult == 4)
|
||||
createScene(4, 0);
|
||||
break;
|
||||
case 4:
|
||||
if (_moduleResult == 0)
|
||||
leaveModule(1);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(3, 1);
|
||||
break;
|
||||
case 5:
|
||||
if (_moduleResult == 0)
|
||||
leaveModule(2);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(3, 3);
|
||||
break;
|
||||
case 6:
|
||||
if (_moduleResult == 0)
|
||||
createScene(8, -1);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(3, 5);
|
||||
break;
|
||||
case 7:
|
||||
createScene(6, 1);
|
||||
break;
|
||||
case 8:
|
||||
if (_moduleResult == 0)
|
||||
createScene(6, 0);
|
||||
else
|
||||
createScene(7, 0);
|
||||
break;
|
||||
case 1001:
|
||||
createScene(1, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scene1608::Scene1608(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _asCar(nullptr), _countdown1(0) {
|
||||
|
||||
setGlobalVar(V_CAR_DELTA_X, 1);
|
||||
|
||||
SetMessageHandler(&Scene1608::hmLowerFloor);
|
||||
|
||||
_asKey = insertSprite<AsCommonKey>(this, 1, 1100, 198, 220);
|
||||
addCollisionSprite(_asKey);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
if (_vm->gameState().which == 1)
|
||||
// Klaymen is in the car
|
||||
which = 1;
|
||||
else {
|
||||
// Klaymen is standing around
|
||||
setRectList(0x004B47D0);
|
||||
insertKlaymen<KmScene1608>(380, 438);
|
||||
_kmScene1608 = _klaymen;
|
||||
_klaymenInCar = false;
|
||||
_sprite1 = insertStaticSprite(0x7D0404E8, 1100);
|
||||
setMessageList(0x004B46A8);
|
||||
setBackground(0x10080E01);
|
||||
setPalette(0x10080E01);
|
||||
_asTape = insertSprite<AsScene1201Tape>(this, 13, 1100, 412, 443, 0x9148A011);
|
||||
addCollisionSprite(_asTape);
|
||||
_klaymen->setClipRect(_sprite1->getDrawRect().x, 0, 640, 480);
|
||||
SetUpdateHandler(&Scene1608::upLowerFloor);
|
||||
insertScreenMouse(0x80E05108);
|
||||
insertStaticSprite(0x4B18F868, 1200);
|
||||
}
|
||||
} else if (which == 0) {
|
||||
// Klaymen entering from the left
|
||||
playSound(0, calcHash("fxDoorOpen23"));
|
||||
_vm->gameState().which = 0;
|
||||
setRectList(0x004B47D0);
|
||||
insertKlaymen<KmScene1608>(0, 438);
|
||||
_kmScene1608 = _klaymen;
|
||||
_klaymenInCar = false;
|
||||
setMessageList(0x004B46B0);
|
||||
setBackground(0x10080E01);
|
||||
setPalette(0x10080E01);
|
||||
_asTape = insertSprite<AsScene1201Tape>(this, 13, 1100, 412, 443, 0x9148A011);
|
||||
addCollisionSprite(_asTape);
|
||||
insertScreenMouse(0x80E05108);
|
||||
_sprite1 = insertStaticSprite(0x7D0404E8, 1100);
|
||||
_klaymen->setClipRect(_sprite1->getDrawRect().x, 0, 640, 480);
|
||||
SetUpdateHandler(&Scene1608::upLowerFloor);
|
||||
insertStaticSprite(0x4B18F868, 1200);
|
||||
} else if (which == 2) {
|
||||
// Klaymen returning from looking through the upper window
|
||||
_vm->gameState().which = 1;
|
||||
_dataResource.load(0x003C0492);
|
||||
_roomPathPoints = _dataResource.getPointArray(calcHash("meArchroArchRoomPath"));
|
||||
setBackground(0x98001604);
|
||||
setPalette(0x98001604);
|
||||
_palette->addPalette("paPodRed", 65, 31, 65);
|
||||
insertScreenMouse(0x01600988);
|
||||
_sprite2 = insertStaticSprite(0x491F38A8, 1100);
|
||||
_asCar = createSprite<AsCommonCar>(this, 375, 227); // Create but don't add to the sprite list yet
|
||||
_asIdleCarLower = insertSprite<AsCommonIdleCarLower>(375, 227);
|
||||
_asIdleCarFull = insertSprite<AsCommonIdleCarFull>(375, 227);
|
||||
_asCar->setVisible(false);
|
||||
if (getGlobalVar(V_KLAYMEN_IS_DELTA_X)) {
|
||||
insertKlaymen<KmScene1608>(373, 220);
|
||||
_klaymen->setDoDeltaX(1);
|
||||
} else
|
||||
insertKlaymen<KmScene1608>(283, 220);
|
||||
_kmScene1608 = _klaymen;
|
||||
setMessageList(0x004B47A8);
|
||||
SetMessageHandler(&Scene1608::hmUpperFloor);
|
||||
SetUpdateHandler(&Scene1608::upUpperFloor);
|
||||
_asCar->setPathPoints(_roomPathPoints);
|
||||
sendMessage(_asCar, NM_POSITION_CHANGE, _roomPathPoints->size() - 1);
|
||||
_sprite3 = insertStaticSprite(0xB47026B0, 1100);
|
||||
_clipRect1.set(_sprite3->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2());
|
||||
_clipRect3.set(_sprite2->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2());
|
||||
_clipRect2 = _clipRect1;
|
||||
_clipRect2.y2 = 215;
|
||||
_klaymen->setClipRect(_clipRect1);
|
||||
_asCar->setClipRect(_clipRect1);
|
||||
_asIdleCarLower->setClipRect(_clipRect1);
|
||||
_asIdleCarFull->setClipRect(_clipRect1);
|
||||
_asTape = insertSprite<AsScene1201Tape>(this, 13, 1100, 412, 443, 0x9148A011);
|
||||
addCollisionSprite(_asTape);
|
||||
insertSprite<AsCommonCarConnector>(_asCar)->setClipRect(_clipRect1);
|
||||
_klaymenInCar = false;
|
||||
_carClipFlag = false;
|
||||
_carStatus = 0;
|
||||
setRectList(0x004B4810);
|
||||
}
|
||||
|
||||
// NOTE: Not in the else because 'which' is set to 1 in the true branch
|
||||
if (which == 1) {
|
||||
// Klaymen riding the car
|
||||
_vm->gameState().which = 1;
|
||||
_dataResource.load(0x003C0492);
|
||||
_roomPathPoints = _dataResource.getPointArray(calcHash("meArchroArchRoomPath"));
|
||||
setBackground(0x98001604);
|
||||
setPalette(0x98001604);
|
||||
_palette->addPalette("paPodRed", 65, 31, 65);
|
||||
insertScreenMouse(0x01600988);
|
||||
_asCar = insertSprite<AsCommonCar>(this, 375, 227);
|
||||
_asIdleCarLower = insertSprite<AsCommonIdleCarLower>(375, 227);
|
||||
_asIdleCarFull = insertSprite<AsCommonIdleCarFull>(375, 227);
|
||||
_sprite2 = insertStaticSprite(0x491F38A8, 1100);
|
||||
_kmScene1608 = createSprite<KmScene1608>(this, 439, 220);
|
||||
sendMessage(_kmScene1608, 0x2032, 1);
|
||||
_kmScene1608->setDoDeltaX(1);
|
||||
SetMessageHandler(&Scene1608::hmRidingCar);
|
||||
SetUpdateHandler(&Scene1608::upRidingCar);
|
||||
_asIdleCarLower->setVisible(false);
|
||||
_asIdleCarFull->setVisible(false);
|
||||
_asCar->setPathPoints(_roomPathPoints);
|
||||
sendMessage(_asCar, NM_POSITION_CHANGE, 0);
|
||||
sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 90);
|
||||
_sprite3 = insertStaticSprite(0xB47026B0, 1100);
|
||||
_clipRect1.set(_sprite3->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2());
|
||||
_clipRect3.set(_sprite2->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2());
|
||||
_clipRect2 = _clipRect1;
|
||||
_clipRect2.y2 = 215;
|
||||
_kmScene1608->setClipRect(_clipRect1);
|
||||
_asCar->setClipRect(_clipRect3);
|
||||
_asIdleCarLower->setClipRect(_clipRect1);
|
||||
_asIdleCarFull->setClipRect(_clipRect1);
|
||||
_asTape = insertSprite<AsScene1201Tape>(this, 13, 1100, 412, 443, 0x9148A011);
|
||||
// ... addCollisionSprite(_asTape);
|
||||
insertSprite<AsCommonCarConnector>(_asCar)->setClipRect(_clipRect1);
|
||||
_klaymenInCar = true;
|
||||
_carClipFlag = true;
|
||||
_carStatus = 0;
|
||||
}
|
||||
|
||||
_palette->addPalette("paKlayRed", 0, 64, 0);
|
||||
|
||||
}
|
||||
|
||||
Scene1608::~Scene1608() {
|
||||
setGlobalVar(V_KLAYMEN_IS_DELTA_X, _kmScene1608->isDoDeltaX() ? 1 : 0);
|
||||
if (_klaymenInCar)
|
||||
delete _kmScene1608;
|
||||
else
|
||||
delete _asCar;
|
||||
}
|
||||
|
||||
void Scene1608::upLowerFloor() {
|
||||
Scene::update();
|
||||
if (_countdown1 != 0 && (--_countdown1 == 0))
|
||||
leaveScene(0);
|
||||
}
|
||||
|
||||
void Scene1608::upUpperFloor() {
|
||||
Scene::update();
|
||||
if (_carStatus == 1) {
|
||||
removeSurface(_klaymen->getSurface());
|
||||
removeEntity(_klaymen);
|
||||
addSprite(_asCar);
|
||||
_klaymenInCar = true;
|
||||
clearRectList();
|
||||
SetUpdateHandler(&Scene1608::upCarAtHome);
|
||||
SetMessageHandler(&Scene1608::hmCarAtHome);
|
||||
_asIdleCarLower->setVisible(false);
|
||||
_asIdleCarFull->setVisible(false);
|
||||
_asCar->setVisible(true);
|
||||
sendMessage(_asCar, NM_CAR_ENTER, 0);
|
||||
_asCar->handleUpdate();
|
||||
_klaymen = nullptr;
|
||||
_carStatus = 0;
|
||||
}
|
||||
updateKlaymenCliprect();
|
||||
}
|
||||
|
||||
void Scene1608::upCarAtHome() {
|
||||
Scene::update();
|
||||
if (_mouseClicked) {
|
||||
if (_mouseClickPos.x <= 329 && _asCar->getX() == 375 && _asCar->getY() == 227) {
|
||||
sendMessage(_asCar, NM_CAR_LEAVE, 0);
|
||||
SetUpdateHandler(&Scene1608::upGettingOutOfCar);
|
||||
} else {
|
||||
sendPointMessage(_asCar, 0x2004, _mouseClickPos);
|
||||
SetMessageHandler(&Scene1608::hmRidingCar);
|
||||
SetUpdateHandler(&Scene1608::upRidingCar);
|
||||
}
|
||||
_mouseClicked = false;
|
||||
}
|
||||
updateKlaymenCliprect();
|
||||
}
|
||||
|
||||
void Scene1608::upGettingOutOfCar() {
|
||||
Scene::update();
|
||||
if (_carStatus == 2) {
|
||||
_klaymen = _kmScene1608;
|
||||
removeSurface(_asCar->getSurface());
|
||||
removeEntity(_asCar);
|
||||
addSprite(_klaymen);
|
||||
_klaymenInCar = false;
|
||||
SetMessageHandler(&Scene1608::hmUpperFloor);
|
||||
SetUpdateHandler(&Scene1608::upUpperFloor);
|
||||
setRectList(0x004B4810);
|
||||
_asIdleCarLower->setVisible(true);
|
||||
_asIdleCarFull->setVisible(true);
|
||||
_asCar->setVisible(false);
|
||||
setMessageList(0x004B4748);
|
||||
processMessageList();
|
||||
_klaymen->handleUpdate();
|
||||
_carStatus = 0;
|
||||
}
|
||||
updateKlaymenCliprect();
|
||||
}
|
||||
|
||||
void Scene1608::upRidingCar() {
|
||||
Scene::update();
|
||||
if (_mouseClicked) {
|
||||
sendPointMessage(_asCar, 0x2004, _mouseClickPos);
|
||||
_mouseClicked = false;
|
||||
}
|
||||
if (_asCar->getY() < 330) {
|
||||
if (_carClipFlag) {
|
||||
_carClipFlag = false;
|
||||
_asCar->setClipRect(_clipRect1);
|
||||
if (!_asCar->isDoDeltaX())
|
||||
sendMessage(_asCar, NM_CAR_TURN, 0);
|
||||
}
|
||||
} else if (!_carClipFlag) {
|
||||
_carClipFlag = true;
|
||||
_asCar->setClipRect(_clipRect3);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Scene1608::hmLowerFloor(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x20250B1A) {
|
||||
clearRectList();
|
||||
_klaymen->setVisible(false);
|
||||
showMouse(false);
|
||||
_sprite1->setVisible(false);
|
||||
playSound(0, calcHash("fxDoorClose23"));
|
||||
_countdown1 = 28;
|
||||
}
|
||||
break;
|
||||
case 0x200D:
|
||||
sendMessage(_parentModule, 0x200D, 0);
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asTape) {
|
||||
sendEntityMessage(_kmScene1608, 0x1014, _asTape);
|
||||
setMessageList(0x004B4770);
|
||||
} else if (sender == _asKey)
|
||||
setMessageList(0x004B46C8);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 Scene1608::hmUpperFloor(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x60842040)
|
||||
_carStatus = 1;
|
||||
break;
|
||||
case 0x200D:
|
||||
sendMessage(_parentModule, 0x200D, 0);
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asKey) {
|
||||
sendEntityMessage(_kmScene1608, 0x1014, _asKey);
|
||||
setMessageList(0x004B4760);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 Scene1608::hmRidingCar(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_KLAYMEN_CLIMB_LADDER:
|
||||
leaveScene(1);
|
||||
break;
|
||||
case NM_KLAYMEN_STOP_CLIMBING:
|
||||
SetMessageHandler(&Scene1608::hmCarAtHome);
|
||||
SetUpdateHandler(&Scene1608::upCarAtHome);
|
||||
sendMessage(_asCar, NM_CAR_AT_HOME, 1);
|
||||
break;
|
||||
case 0x200D:
|
||||
sendMessage(_parentModule, 0x200D, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 Scene1608::hmCarAtHome(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_CAR_LEAVE:
|
||||
_carStatus = 2;
|
||||
break;
|
||||
case 0x200D:
|
||||
sendMessage(_parentModule, 0x200D, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Scene1608::updateKlaymenCliprect() {
|
||||
if (_kmScene1608->getX() <= 375)
|
||||
_kmScene1608->setClipRect(_clipRect1);
|
||||
else
|
||||
_kmScene1608->setClipRect(_clipRect2);
|
||||
}
|
||||
|
||||
Scene1609::Scene1609(NeverhoodEngine *vm, Module *parentModule)
|
||||
: Scene(vm, parentModule), _countdown1(1), _currentSymbolIndex(0), _symbolPosition(0), _changeCurrentSymbol(true), _isSolved(false) {
|
||||
|
||||
_vm->gameModule()->initCodeSymbolsPuzzle();
|
||||
_noisySymbolIndex = getGlobalVar(V_NOISY_SYMBOL_INDEX);
|
||||
|
||||
SetMessageHandler(&Scene1609::handleMessage);
|
||||
SetUpdateHandler(&Scene1609::update);
|
||||
|
||||
setBackground(0x92124A14);
|
||||
setPalette(0x92124A14);
|
||||
insertPuzzleMouse(0x24A10929, 20, 620);
|
||||
|
||||
for (int symbolPosition = 0; symbolPosition < 12; symbolPosition++)
|
||||
_asSymbols[symbolPosition] = insertSprite<AsScene3011Symbol>(symbolPosition, false);
|
||||
|
||||
_ssButton = insertSprite<SsScene3011Button>(this, true);
|
||||
addCollisionSprite(_ssButton);
|
||||
loadSound(0, 0x68E25540);
|
||||
|
||||
}
|
||||
|
||||
void Scene1609::update() {
|
||||
if (!_isSolved && _countdown1 != 0 && (--_countdown1 == 0)) {
|
||||
if (_changeCurrentSymbol) {
|
||||
_currentSymbolIndex++;
|
||||
if (_currentSymbolIndex >= 12)
|
||||
_currentSymbolIndex = 0;
|
||||
_asSymbols[_symbolPosition]->change(_currentSymbolIndex + 12, _currentSymbolIndex == (int)getSubVar(VA_CODE_SYMBOLS, _noisySymbolIndex));
|
||||
_changeCurrentSymbol = false;
|
||||
_countdown1 = 36;
|
||||
} else {
|
||||
_asSymbols[_symbolPosition]->hide();
|
||||
_changeCurrentSymbol = true;
|
||||
_countdown1 = 12;
|
||||
}
|
||||
}
|
||||
if (_isSolved && !isSoundPlaying(0))
|
||||
leaveScene(1);
|
||||
Scene::update();
|
||||
}
|
||||
|
||||
uint32 Scene1609::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
|
||||
leaveScene(0);
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (!_isSolved) {
|
||||
if (_changeCurrentSymbol)
|
||||
_asSymbols[_symbolPosition]->change(_currentSymbolIndex + 12, false);
|
||||
_asSymbols[_symbolPosition]->stopSymbolSound();
|
||||
_symbolPosition++;
|
||||
if (_symbolPosition >= 12) {
|
||||
if (testVars()) {
|
||||
playSound(0);
|
||||
setGlobalVar(V_CODE_SYMBOLS_SOLVED, 1);
|
||||
_isSolved = true;
|
||||
} else {
|
||||
_symbolPosition = 0;
|
||||
for (int i = 0; i < 12; i++)
|
||||
_asSymbols[i]->hide();
|
||||
}
|
||||
}
|
||||
_changeCurrentSymbol = true;
|
||||
_countdown1 = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Scene1609::testVars() {
|
||||
int cmpSymbolIndex = 0;
|
||||
|
||||
// Find the position of the first symbol
|
||||
while ((int)getSubVar(VA_CODE_SYMBOLS, cmpSymbolIndex) != _asSymbols[0]->getSymbolIndex())
|
||||
cmpSymbolIndex++;
|
||||
|
||||
// Check if the entered symbols match
|
||||
for (int enteredSymbolIndex = 0; enteredSymbolIndex < 12; enteredSymbolIndex++) {
|
||||
if ((int)getSubVar(VA_CODE_SYMBOLS, cmpSymbolIndex) != _asSymbols[enteredSymbolIndex]->getSymbolIndex())
|
||||
return false;
|
||||
cmpSymbolIndex++;
|
||||
if (cmpSymbolIndex >= 12)
|
||||
cmpSymbolIndex = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
99
engines/neverhood/modules/module1600.h
Normal file
99
engines/neverhood/modules/module1600.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1600_H
|
||||
#define NEVERHOOD_MODULES_MODULE1600_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module1600 : public Module {
|
||||
public:
|
||||
Module1600(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module1600() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class AsCommonCar;
|
||||
|
||||
class Scene1608 : public Scene {
|
||||
public:
|
||||
Scene1608(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene1608() override;
|
||||
protected:
|
||||
AsCommonCar *_asCar;
|
||||
Sprite *_asKey;
|
||||
Sprite *_asIdleCarLower;
|
||||
Sprite *_asIdleCarFull;
|
||||
Sprite *_sprite1;
|
||||
Sprite *_sprite2;
|
||||
Sprite *_sprite3;
|
||||
Sprite *_asTape;
|
||||
Klaymen *_kmScene1608;
|
||||
NRect _clipRect1;
|
||||
NRect _clipRect2;
|
||||
NRect _clipRect3;
|
||||
int _carStatus;
|
||||
bool _carClipFlag;
|
||||
bool _klaymenInCar;
|
||||
int _countdown1;
|
||||
NPointArray *_roomPathPoints;
|
||||
void upLowerFloor();
|
||||
void upUpperFloor();
|
||||
void upCarAtHome();
|
||||
void upGettingOutOfCar();
|
||||
void upRidingCar();
|
||||
uint32 hmLowerFloor(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmUpperFloor(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmRidingCar(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmCarAtHome(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void updateKlaymenCliprect();
|
||||
};
|
||||
|
||||
class AsScene3011Symbol;
|
||||
|
||||
class Scene1609 : public Scene {
|
||||
friend class Console;
|
||||
public:
|
||||
Scene1609(NeverhoodEngine *vm, Module *parentModule);
|
||||
protected:
|
||||
Sprite *_ssButton;
|
||||
AsScene3011Symbol *_asSymbols[12];
|
||||
int _currentSymbolIndex;
|
||||
int _noisySymbolIndex;
|
||||
int _symbolPosition;
|
||||
int _countdown1;
|
||||
bool _changeCurrentSymbol;
|
||||
bool _isSolved;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
bool testVars();
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1600_H */
|
||||
944
engines/neverhood/modules/module1600_sprites.cpp
Normal file
944
engines/neverhood/modules/module1600_sprites.cpp
Normal file
@@ -0,0 +1,944 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1600_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
AsCommonCar::AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: AnimatedSprite(vm, 1000), _parentScene(parentScene) {
|
||||
|
||||
createSurface(200, 556, 328);
|
||||
_x = x;
|
||||
_y = y;
|
||||
_destX = x;
|
||||
_destY = y;
|
||||
|
||||
_inMainArea = false;
|
||||
_exitDirection = 0;
|
||||
_currPointIndex = 0;
|
||||
_hasAgainDestPoint = false;
|
||||
_stepError = 0;
|
||||
_hasAgainDestPointIndex = false;
|
||||
_steps = 0;
|
||||
_isBraking = false;
|
||||
_yMoveTotalSteps = 0;
|
||||
_isBusy = false;
|
||||
_isIdle = false;
|
||||
_isMoving = true;
|
||||
_rectFlag = false;
|
||||
_newDeltaXType = -1;
|
||||
_soundCounter = 0;
|
||||
_pathPoints = nullptr;
|
||||
_currMoveDirection = 0;
|
||||
_newMoveDirection = 0;
|
||||
|
||||
startAnimation(0xD4220027, 0, -1);
|
||||
setDoDeltaX(getGlobalVar(V_CAR_DELTA_X));
|
||||
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::handleMessage);
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
|
||||
AsCommonCar::~AsCommonCar() {
|
||||
if (_finalizeStateCb == AnimationCallback(&AsCommonCar::evTurnCarDone))
|
||||
setGlobalVar(V_CAR_DELTA_X, !getGlobalVar(V_CAR_DELTA_X));
|
||||
}
|
||||
|
||||
void AsCommonCar::setPathPoints(NPointArray *pathPoints) {
|
||||
_pathPoints = pathPoints;
|
||||
}
|
||||
|
||||
void AsCommonCar::update() {
|
||||
if (_newDeltaXType >= 0) {
|
||||
setDoDeltaX(_newDeltaXType);
|
||||
_newDeltaXType = -1;
|
||||
}
|
||||
AnimatedSprite::update();
|
||||
if (_hasAgainDestPoint && _yMoveTotalSteps == 0 && !_isBusy) {
|
||||
_hasAgainDestPoint = false;
|
||||
_hasAgainDestPointIndex = false;
|
||||
sendPointMessage(this, 0x2004, _againDestPoint);
|
||||
} else if (_hasAgainDestPointIndex && _yMoveTotalSteps == 0 && !_isBusy) {
|
||||
_hasAgainDestPointIndex = false;
|
||||
sendMessage(this, 0x2003, _againDestPointIndex);
|
||||
}
|
||||
updateMovement();
|
||||
updateSound();
|
||||
}
|
||||
|
||||
void AsCommonCar::upIdle() {
|
||||
update();
|
||||
if (++_idleCounter >= _idleCounterMax)
|
||||
stIdleBlink();
|
||||
updateSound();
|
||||
}
|
||||
|
||||
uint32 AsCommonCar::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_SCENE_LEAVE:
|
||||
SetSpriteUpdate(nullptr);
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
// Set the current position without moving
|
||||
_currPointIndex = param.asInteger();
|
||||
_stepError = 0;
|
||||
_x = pathPoint(_currPointIndex).x;
|
||||
_y = pathPoint(_currPointIndex).y;
|
||||
break;
|
||||
case 0x2003:
|
||||
// Move to a point by its index
|
||||
{
|
||||
int newPointIndex = param.asInteger();
|
||||
if (_yMoveTotalSteps <= 0 && !_isBusy) {
|
||||
_destX = pathPoint(newPointIndex).x;
|
||||
_destY = pathPoint(newPointIndex).y;
|
||||
if (_currPointIndex < newPointIndex) {
|
||||
moveToNextPoint();
|
||||
} else if (_currPointIndex == newPointIndex && _stepError == 0) {
|
||||
if (_currPointIndex == 0) {
|
||||
_yMoveTotalSteps = 0;
|
||||
sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
|
||||
} else if (_currPointIndex == (int)_pathPoints->size()) {
|
||||
_yMoveTotalSteps = 0;
|
||||
sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 0);
|
||||
}
|
||||
} else {
|
||||
moveToPrevPoint();
|
||||
}
|
||||
} else {
|
||||
_hasAgainDestPointIndex = true;
|
||||
_againDestPointIndex = newPointIndex;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x2004:
|
||||
// Move to the point closest to the parameter point
|
||||
{
|
||||
int minMatchIndex = -1;
|
||||
int minMatchDistance, distance;
|
||||
NPoint pt = param.asPoint();
|
||||
if (_yMoveTotalSteps <= 0 && !_isBusy) {
|
||||
// Check if we're already exiting (or something)
|
||||
if ((pt.x <= 20 && _exitDirection == 1) ||
|
||||
(pt.x >= 620 && _exitDirection == 3) ||
|
||||
(pt.y <= 20 && _exitDirection == 2) ||
|
||||
(pt.y >= 460 && _exitDirection == 4))
|
||||
break;
|
||||
_destX = pt.x;
|
||||
_destY = pt.y;
|
||||
minMatchDistance = calcDistance(_destX, _destY, _x, _y) + 1;
|
||||
for (int i = _currPointIndex + 1; i < (int)_pathPoints->size(); i++) {
|
||||
distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
|
||||
if (distance >= minMatchDistance)
|
||||
break;
|
||||
minMatchDistance = distance;
|
||||
minMatchIndex = i;
|
||||
}
|
||||
for (int i = _currPointIndex; i >= 0; i--) {
|
||||
distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
|
||||
if (distance >= minMatchDistance)
|
||||
break;
|
||||
minMatchDistance = distance;
|
||||
minMatchIndex = i;
|
||||
}
|
||||
if (minMatchIndex == -1) {
|
||||
if (_currPointIndex == 0)
|
||||
moveToPrevPoint();
|
||||
else
|
||||
SetSpriteUpdate(nullptr);
|
||||
} else {
|
||||
if (minMatchIndex > _currPointIndex)
|
||||
moveToNextPoint();
|
||||
else
|
||||
moveToPrevPoint();
|
||||
}
|
||||
} else {
|
||||
_hasAgainDestPoint = true;
|
||||
_againDestPoint = pt;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_CAR_MOVE_TO_PREV_POINT:
|
||||
_yMoveTotalSteps = param.asInteger();
|
||||
_steps = 0;
|
||||
_isBraking = false;
|
||||
_lastDistance = 640;
|
||||
SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
|
||||
break;
|
||||
case NM_CAR_MOVE_TO_NEXT_POINT:
|
||||
_yMoveTotalSteps = param.asInteger();
|
||||
_steps = 0;
|
||||
_isBraking = false;
|
||||
_lastDistance = 640;
|
||||
SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
|
||||
break;
|
||||
case NM_CAR_ENTER:
|
||||
stEnterCar();
|
||||
break;
|
||||
case NM_CAR_LEAVE:
|
||||
stLeaveCar();
|
||||
break;
|
||||
case NM_CAR_TURN:
|
||||
stTurnCar();
|
||||
break;
|
||||
case NM_CAR_AT_HOME:
|
||||
stCarAtHome();
|
||||
_newDeltaXType = param.asInteger();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 AsCommonCar::hmAnimation(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = AsCommonCar::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (_isBusy && param.asInteger() == 0x025424A2)
|
||||
gotoNextState();
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 AsCommonCar::hmLeaveCar(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
switch (messageNum) {
|
||||
case NM_CAR_ENTER:
|
||||
stEnterCar();
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
sendMessage(_parentScene, NM_CAR_LEAVE, 0);
|
||||
SetMessageHandler(&AsCommonCar::handleMessage);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AsCommonCar::stCarAtHome() {
|
||||
bool doDeltaX = _doDeltaX;
|
||||
SetSpriteUpdate(nullptr);
|
||||
_hasAgainDestPoint = false;
|
||||
_hasAgainDestPointIndex = false;
|
||||
_isBraking = false;
|
||||
_isBusy = false;
|
||||
_isIdle = false;
|
||||
_isMoving = false;
|
||||
_rectFlag = false;
|
||||
NextState(&AsCommonCar::stLeanForwardIdle);
|
||||
startAnimation(0x35698F78, 0, -1);
|
||||
setDoDeltaX(doDeltaX ? 1 : 0);
|
||||
_currMoveDirection = 0;
|
||||
_newMoveDirection = 0;
|
||||
_steps = 0;
|
||||
_idleCounter = 0;
|
||||
_idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
|
||||
SetUpdateHandler(&AsCommonCar::upIdle);
|
||||
SetMessageHandler(&AsCommonCar::handleMessage);
|
||||
FinalizeState(&AsCommonCar::evIdleDone);
|
||||
}
|
||||
|
||||
void AsCommonCar::updateTurnMovement() {
|
||||
if (_turnMoveStatus == 1) {
|
||||
_lastDistance = 640;
|
||||
_isIdle = false;
|
||||
_isBraking = false;
|
||||
SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
|
||||
} else if (_turnMoveStatus == 2) {
|
||||
_lastDistance = 640;
|
||||
_isIdle = false;
|
||||
_isBraking = false;
|
||||
SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
|
||||
}
|
||||
}
|
||||
|
||||
void AsCommonCar::updateMovement() {
|
||||
if (_isBraking && !_isIdle && !_isBusy) {
|
||||
gotoNextState();
|
||||
_isMoving = false;
|
||||
_isIdle = true;
|
||||
startAnimation(0x192ADD30, 0, -1);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
NextState(&AsCommonCar::stLeanForwardIdle);
|
||||
} else if (!_isBraking && _steps && _isIdle) {
|
||||
gotoNextState();
|
||||
_isIdle = false;
|
||||
startAnimation(0x9966B138, 0, -1);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
NextState(&AsCommonCar::stUpdateMoveDirection);
|
||||
} else if (_newMoveDirection != _currMoveDirection && _isMoving && !_isBusy) {
|
||||
gotoNextState();
|
||||
_currMoveDirection = _newMoveDirection;
|
||||
stUpdateMoveDirection();
|
||||
}
|
||||
}
|
||||
|
||||
void AsCommonCar::stEnterCar() {
|
||||
startAnimation(0xA86A9538, 0, -1);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
NextState(&AsCommonCar::stLeanForwardIdle);
|
||||
}
|
||||
|
||||
void AsCommonCar::stLeaveCar() {
|
||||
startAnimation(0xA86A9538, -1, -1);
|
||||
_playBackwards = true;
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmLeaveCar);
|
||||
}
|
||||
|
||||
void AsCommonCar::stLeanForwardIdle() {
|
||||
startAnimation(0x35698F78, 0, -1);
|
||||
_currMoveDirection = 0;
|
||||
_newMoveDirection = 0;
|
||||
_steps = 0;
|
||||
_idleCounter = 0;
|
||||
_idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
|
||||
SetUpdateHandler(&AsCommonCar::upIdle);
|
||||
SetMessageHandler(&AsCommonCar::handleMessage);
|
||||
FinalizeState(&AsCommonCar::evIdleDone);
|
||||
}
|
||||
|
||||
void AsCommonCar::evIdleDone() {
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
}
|
||||
|
||||
void AsCommonCar::stIdleBlink() {
|
||||
startAnimation(0xB579A77C, 0, -1);
|
||||
_idleCounter = 0;
|
||||
_idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
NextState(&AsCommonCar::stLeanForwardIdle);
|
||||
}
|
||||
|
||||
void AsCommonCar::stUpdateMoveDirection() {
|
||||
_isMoving = true;
|
||||
if (_currMoveDirection == 1)
|
||||
startAnimation(0xD4AA03A4, 0, -1);
|
||||
else if (_currMoveDirection == 3)
|
||||
startAnimation(0xD00A1364, 0, -1);
|
||||
else if ((_currMoveDirection == 2 && _doDeltaX) || (_currMoveDirection == 4 && !_doDeltaX))
|
||||
stTurnCar();
|
||||
else
|
||||
startAnimation(0xD4220027, 0, -1);
|
||||
setGlobalVar(V_CAR_DELTA_X, _doDeltaX ? 1 : 0);
|
||||
}
|
||||
|
||||
void AsCommonCar::moveToNextPoint() {
|
||||
if (_currPointIndex >= (int)_pathPoints->size() - 1) {
|
||||
_yMoveTotalSteps = 0;
|
||||
sendMessage(this, NM_SCENE_LEAVE, 0);
|
||||
sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 0);
|
||||
} else {
|
||||
NPoint nextPt = pathPoint(_currPointIndex + 1);
|
||||
NPoint currPt = pathPoint(_currPointIndex);
|
||||
if (ABS(nextPt.y - currPt.y) <= ABS(nextPt.x - currPt.x) &&
|
||||
((_currMoveDirection == 2 && nextPt.x < currPt.x) ||
|
||||
(_currMoveDirection == 4 && nextPt.x >= currPt.x))) {
|
||||
if (_currMoveDirection == 2)
|
||||
_currMoveDirection = 4;
|
||||
else if (_currMoveDirection == 4)
|
||||
_currMoveDirection = 2;
|
||||
if (_isIdle)
|
||||
stTurnCarMoveToNextPoint();
|
||||
else
|
||||
stBrakeMoveToNextPoint();
|
||||
} else {
|
||||
if (_steps == 0) {
|
||||
gotoNextState();
|
||||
_isIdle = false;
|
||||
startAnimation(0x9966B138, 0, -1);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
NextState(&AsCommonCar::stUpdateMoveDirection);
|
||||
}
|
||||
_isBraking = false;
|
||||
SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
|
||||
_lastDistance = 640;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AsCommonCar::stBrakeMoveToNextPoint() {
|
||||
gotoNextState();
|
||||
_isBusy = true;
|
||||
_isBraking = true;
|
||||
startAnimation(0x192ADD30, 0, -1);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
NextState(&AsCommonCar::stTurnCarMoveToNextPoint);
|
||||
}
|
||||
|
||||
void AsCommonCar::stTurnCar() {
|
||||
// Turn to left/right #1
|
||||
gotoNextState();
|
||||
_isBusy = true;
|
||||
startAnimation(0xF46A0324, 0, -1);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
FinalizeState(&AsCommonCar::evTurnCarDone);
|
||||
_turnMoveStatus = 0;
|
||||
updateTurnMovement();
|
||||
}
|
||||
|
||||
void AsCommonCar::stTurnCarMoveToNextPoint() {
|
||||
// Turn to left/right #2
|
||||
gotoNextState();
|
||||
_isBusy = true;
|
||||
startAnimation(0xF46A0324, 0, -1);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
FinalizeState(&AsCommonCar::evTurnCarDone);
|
||||
_turnMoveStatus = 1;
|
||||
updateTurnMovement();
|
||||
}
|
||||
|
||||
void AsCommonCar::stTurnCarMoveToPrevPoint() {
|
||||
// Turn to left/right #3
|
||||
FinalizeState(nullptr);
|
||||
_isBusy = true;
|
||||
startAnimation(0xF46A0324, 0, -1);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
FinalizeState(&AsCommonCar::evTurnCarDone);
|
||||
_turnMoveStatus = 2;
|
||||
updateTurnMovement();
|
||||
}
|
||||
|
||||
void AsCommonCar::moveToPrevPoint() {
|
||||
if (_currPointIndex == 0 && _stepError == 0) {
|
||||
_yMoveTotalSteps = 0;
|
||||
sendMessage(this, NM_SCENE_LEAVE, 0);
|
||||
sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
|
||||
} else {
|
||||
NPoint prevPt;
|
||||
NPoint currPt;
|
||||
if (_stepError == 0) {
|
||||
prevPt = pathPoint(_currPointIndex - 1);
|
||||
currPt = pathPoint(_currPointIndex);
|
||||
} else {
|
||||
prevPt = pathPoint(_currPointIndex);
|
||||
currPt = pathPoint(_currPointIndex + 1);
|
||||
}
|
||||
if (ABS(prevPt.y - currPt.y) <= ABS(prevPt.x - currPt.x) &&
|
||||
((_currMoveDirection == 2 && prevPt.x < currPt.x) ||
|
||||
(_currMoveDirection == 4 && prevPt.x >= currPt.x))) {
|
||||
if (_currMoveDirection == 2)
|
||||
_currMoveDirection = 4;
|
||||
else if (_currMoveDirection == 4)
|
||||
_currMoveDirection = 2;
|
||||
if (_isIdle)
|
||||
stTurnCarMoveToPrevPoint();
|
||||
else
|
||||
stBrakeMoveToPrevPoint();
|
||||
} else {
|
||||
if (_steps == 0) {
|
||||
gotoNextState();
|
||||
_isIdle = false;
|
||||
startAnimation(0x9966B138, 0, -1);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
NextState(&AsCommonCar::stUpdateMoveDirection);
|
||||
}
|
||||
_isBraking = false;
|
||||
SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
|
||||
_lastDistance = 640;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AsCommonCar::stBrakeMoveToPrevPoint() {
|
||||
FinalizeState(nullptr);
|
||||
_isBusy = true;
|
||||
_isBraking = true;
|
||||
startAnimation(0x192ADD30, 0, -1);
|
||||
SetUpdateHandler(&AsCommonCar::update);
|
||||
SetMessageHandler(&AsCommonCar::hmAnimation);
|
||||
NextState(&AsCommonCar::stTurnCarMoveToPrevPoint);
|
||||
}
|
||||
|
||||
void AsCommonCar::evTurnCarDone() {
|
||||
_isBusy = false;
|
||||
setDoDeltaX(2);
|
||||
_newMoveDirection = 0;
|
||||
stUpdateMoveDirection();
|
||||
}
|
||||
|
||||
void AsCommonCar::suMoveToNextPoint() {
|
||||
int16 newX = _x, newY = _y;
|
||||
|
||||
if (_currPointIndex >= (int)_pathPoints->size()) {
|
||||
_yMoveTotalSteps = 0;
|
||||
sendMessage(this, NM_SCENE_LEAVE, 0);
|
||||
sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_isBraking) {
|
||||
if (_steps <= 0) {
|
||||
sendMessage(this, NM_SCENE_LEAVE, 0);
|
||||
return;
|
||||
} else
|
||||
_steps--;
|
||||
} else if (_steps < 11)
|
||||
_steps++;
|
||||
|
||||
bool firstTime = true;
|
||||
_ySteps = _steps;
|
||||
int stepsCtr = _steps;
|
||||
|
||||
while (stepsCtr > 0) {
|
||||
NPoint pt1;
|
||||
NPoint pt2 = pathPoint(_currPointIndex);
|
||||
if (_currPointIndex + 1 >= (int)_pathPoints->size())
|
||||
pt1 = pathPoint(0);
|
||||
else
|
||||
pt1 = pathPoint(_currPointIndex + 1);
|
||||
int16 deltaX = ABS(pt1.x - pt2.x);
|
||||
int16 deltaY = ABS(pt1.y - pt2.y);
|
||||
if (deltaX >= deltaY) {
|
||||
_newMoveDirection = 2;
|
||||
if (pt1.x < pt2.x)
|
||||
_newMoveDirection = 4;
|
||||
if (stepsCtr + _stepError >= deltaX) {
|
||||
stepsCtr -= deltaX;
|
||||
stepsCtr += _stepError;
|
||||
_stepError = 0;
|
||||
_currPointIndex++;
|
||||
if (_currPointIndex == (int)_pathPoints->size() - 1)
|
||||
stepsCtr = 0;
|
||||
newX = pathPoint(_currPointIndex).x;
|
||||
newY = pathPoint(_currPointIndex).y;
|
||||
} else {
|
||||
_stepError += stepsCtr;
|
||||
if (pt1.x >= pt2.x)
|
||||
newX += stepsCtr;
|
||||
else
|
||||
newX -= stepsCtr;
|
||||
if (pt1.y >= pt2.y)
|
||||
newY = pt2.y + (deltaY * _stepError) / deltaX;
|
||||
else
|
||||
newY = pt2.y - (deltaY * _stepError) / deltaX;
|
||||
stepsCtr = 0;
|
||||
}
|
||||
} else {
|
||||
_newMoveDirection = 3;
|
||||
if (pt1.y < pt2.y)
|
||||
_newMoveDirection = 1;
|
||||
if (firstTime) {
|
||||
if (pt1.y >= pt2.y)
|
||||
stepsCtr += 7;
|
||||
else {
|
||||
stepsCtr -= 4;
|
||||
if (stepsCtr < 0)
|
||||
stepsCtr = 0;
|
||||
}
|
||||
_ySteps = stepsCtr;
|
||||
}
|
||||
if (stepsCtr + _stepError >= deltaY) {
|
||||
stepsCtr -= deltaY;
|
||||
stepsCtr += _stepError;
|
||||
_stepError = 0;
|
||||
_currPointIndex++;
|
||||
if (_currPointIndex == (int)_pathPoints->size() - 1)
|
||||
stepsCtr = 0;
|
||||
newX = pathPoint(_currPointIndex).x;
|
||||
newY = pathPoint(_currPointIndex).y;
|
||||
} else {
|
||||
_stepError += stepsCtr;
|
||||
if (pt1.x >= pt2.x)
|
||||
newX = pt2.x + (deltaX * _stepError) / deltaY;
|
||||
else
|
||||
newX = pt2.x - (deltaX * _stepError) / deltaY;
|
||||
if (pt1.y >= pt2.y)
|
||||
newY += stepsCtr;
|
||||
else
|
||||
newY -= stepsCtr;
|
||||
stepsCtr = 0;
|
||||
}
|
||||
}
|
||||
firstTime = false;
|
||||
}
|
||||
|
||||
if (_yMoveTotalSteps != 0) {
|
||||
_x = newX;
|
||||
_y = newY;
|
||||
_yMoveTotalSteps -= _ySteps;
|
||||
if (_yMoveTotalSteps <= 0) {
|
||||
_isBraking = true;
|
||||
_yMoveTotalSteps = 0;
|
||||
}
|
||||
} else {
|
||||
int distance = calcDistance(_destX, _destY, _x, _y);
|
||||
_x = newX;
|
||||
_y = newY;
|
||||
if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
|
||||
_exitDirection = 0;
|
||||
_inMainArea = true;
|
||||
} else if (_inMainArea) {
|
||||
_destX = pathPoint(_pathPoints->size() - 1).x;
|
||||
_destY = pathPoint(_pathPoints->size() - 1).y;
|
||||
_inMainArea = false;
|
||||
if (_x <= 20)
|
||||
_exitDirection = 1;
|
||||
else if (_x >= 620)
|
||||
_exitDirection = 3;
|
||||
else if (_y <= 20)
|
||||
_exitDirection = 2;
|
||||
else if (_y >= 460)
|
||||
_exitDirection = 4;
|
||||
if (_exitDirection != 0 && _isBraking) {
|
||||
_isBraking = false;
|
||||
_steps = 11;
|
||||
}
|
||||
}
|
||||
if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
|
||||
(_exitDirection == 0 && _lastDistance + 20 < distance))
|
||||
_isBraking = true;
|
||||
if (distance < _lastDistance)
|
||||
_lastDistance = distance;
|
||||
if (_currPointIndex == (int)_pathPoints->size() - 1) {
|
||||
_isBraking = true;
|
||||
_yMoveTotalSteps = 0;
|
||||
sendMessage(this, NM_SCENE_LEAVE, 0);
|
||||
sendMessage(_parentScene, NM_KLAYMEN_STOP_CLIMBING, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AsCommonCar::suMoveToPrevPoint() {
|
||||
int16 newX = _x, newY = _y;
|
||||
|
||||
if (_currPointIndex == 0 && _stepError == 0) {
|
||||
_yMoveTotalSteps = 0;
|
||||
sendMessage(this, NM_SCENE_LEAVE, 0);
|
||||
sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_isBraking) {
|
||||
if (_steps <= 0) {
|
||||
sendMessage(this, NM_SCENE_LEAVE, 0);
|
||||
return;
|
||||
} else
|
||||
_steps--;
|
||||
} else if (_steps < 11)
|
||||
_steps++;
|
||||
|
||||
bool firstTime = true;
|
||||
_ySteps = _steps;
|
||||
int stepsCtr = _steps;
|
||||
|
||||
while (stepsCtr > 0) {
|
||||
if (_stepError == 0)
|
||||
_currPointIndex--;
|
||||
NPoint pt1;
|
||||
NPoint pt2 = pathPoint(_currPointIndex);
|
||||
if (_currPointIndex + 1 >= (int)_pathPoints->size())
|
||||
pt1 = pathPoint(0);
|
||||
else
|
||||
pt1 = pathPoint(_currPointIndex + 1);
|
||||
int16 deltaX = ABS(pt1.x - pt2.x);
|
||||
int16 deltaY = ABS(pt1.y - pt2.y);
|
||||
if (deltaX >= deltaY) {
|
||||
_newMoveDirection = 4;
|
||||
if (pt1.x < pt2.x)
|
||||
_newMoveDirection = 2;
|
||||
if (_stepError == 0)
|
||||
_stepError = deltaX;
|
||||
if (stepsCtr > _stepError) {
|
||||
stepsCtr -= _stepError;
|
||||
_stepError = 0;
|
||||
if (_currPointIndex == 0)
|
||||
stepsCtr = 0;
|
||||
newX = pathPoint(_currPointIndex).x;
|
||||
newY = pathPoint(_currPointIndex).y;
|
||||
} else {
|
||||
_stepError -= stepsCtr;
|
||||
if (pt1.x >= pt2.x)
|
||||
newX -= stepsCtr;
|
||||
else
|
||||
newX += stepsCtr;
|
||||
if (pt1.y >= pt2.y)
|
||||
newY = pt2.y + (deltaY * _stepError) / deltaX;
|
||||
else
|
||||
newY = pt2.y - (deltaY * _stepError) / deltaX;
|
||||
stepsCtr = 0;
|
||||
}
|
||||
} else {
|
||||
_newMoveDirection = 1;
|
||||
if (pt1.y < pt2.y)
|
||||
_newMoveDirection = 3;
|
||||
if (firstTime) {
|
||||
if (pt1.y >= pt2.y) {
|
||||
stepsCtr -= 4;
|
||||
if (stepsCtr < 0)
|
||||
stepsCtr = 0;
|
||||
} else {
|
||||
stepsCtr += 7;
|
||||
}
|
||||
_ySteps = stepsCtr;
|
||||
}
|
||||
if (_stepError == 0)
|
||||
_stepError = deltaY;
|
||||
if (stepsCtr > _stepError) {
|
||||
stepsCtr -= _stepError;
|
||||
_stepError = 0;
|
||||
if (_currPointIndex == 0)
|
||||
stepsCtr = 0;
|
||||
newX = pathPoint(_currPointIndex).x;
|
||||
newY = pathPoint(_currPointIndex).y;
|
||||
} else {
|
||||
_stepError -= stepsCtr;
|
||||
if (pt1.x >= pt2.x)
|
||||
newX = pt2.x + (deltaX * _stepError) / deltaY;
|
||||
else
|
||||
newX = pt2.x - (deltaX * _stepError) / deltaY;
|
||||
if (pt1.y >= pt2.y)
|
||||
newY -= stepsCtr;
|
||||
else
|
||||
newY += stepsCtr;
|
||||
stepsCtr = 0;
|
||||
}
|
||||
}
|
||||
firstTime = false;
|
||||
}
|
||||
|
||||
if (_yMoveTotalSteps != 0) {
|
||||
_x = newX;
|
||||
_y = newY;
|
||||
_yMoveTotalSteps -= _ySteps;
|
||||
if (_yMoveTotalSteps <= 0) {
|
||||
_isBraking = true;
|
||||
_yMoveTotalSteps = 0;
|
||||
}
|
||||
} else {
|
||||
int distance = calcDistance(_destX, _destY, _x, _y);
|
||||
_x = newX;
|
||||
_y = newY;
|
||||
if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
|
||||
_exitDirection = 0;
|
||||
_inMainArea = true;
|
||||
} else if (_inMainArea) {
|
||||
_destX = pathPoint(0).x;
|
||||
_destY = pathPoint(0).y;
|
||||
_inMainArea = false;
|
||||
if (_x <= 20)
|
||||
_exitDirection = 1;
|
||||
else if (_x >= 620)
|
||||
_exitDirection = 3;
|
||||
else if (_y <= 20)
|
||||
_exitDirection = 2;
|
||||
else if (_y >= 460)
|
||||
_exitDirection = 4;
|
||||
if (_exitDirection != 0 && _isBraking) {
|
||||
_isBraking = false;
|
||||
_steps = 11;
|
||||
}
|
||||
}
|
||||
if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
|
||||
(_exitDirection == 0 && _lastDistance + 20 < distance))
|
||||
_isBraking = true;
|
||||
if (distance < _lastDistance)
|
||||
_lastDistance = distance;
|
||||
if (_currPointIndex == 0 && _stepError == 0) {
|
||||
_isBraking = true;
|
||||
_yMoveTotalSteps = 0;
|
||||
sendMessage(this, NM_SCENE_LEAVE, 0);
|
||||
sendMessage(_parentScene, NM_KLAYMEN_CLIMB_LADDER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AsCommonCar::updateSound() {
|
||||
int maxSoundCounter = 0;
|
||||
_soundCounter++;
|
||||
if (_steps != 0 && !_isIdle) {
|
||||
if (_currMoveDirection == 1)
|
||||
maxSoundCounter = 18 - _steps;
|
||||
else if (_currMoveDirection == 3) {
|
||||
maxSoundCounter = 5 - _steps;
|
||||
if (maxSoundCounter < 1)
|
||||
maxSoundCounter = 1;
|
||||
} else
|
||||
maxSoundCounter = 14 - _steps;
|
||||
} else
|
||||
maxSoundCounter = 21;
|
||||
if (_soundCounter >= maxSoundCounter) {
|
||||
sendMessage(_parentScene, 0x200D, 0);
|
||||
_soundCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
AsCommonIdleCarLower::AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y)
|
||||
: AnimatedSprite(vm, 0x1209E09F, 1100, x, y) {
|
||||
|
||||
setDoDeltaX(1);
|
||||
startAnimation(0x1209E09F, 1, -1);
|
||||
_newStickFrameIndex = 1;
|
||||
}
|
||||
|
||||
AsCommonIdleCarFull::AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y)
|
||||
: AnimatedSprite(vm, 0x1209E09F, 100, x, y) {
|
||||
|
||||
setDoDeltaX(1);
|
||||
_newStickFrameIndex = 0;
|
||||
}
|
||||
|
||||
AsCommonCarConnector::AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar)
|
||||
: AnimatedSprite(vm, 1100), _asCar(asCar) {
|
||||
|
||||
createSurface1(0x60281C10, 150);
|
||||
startAnimation(0x60281C10, -1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
SetUpdateHandler(&AsCommonCarConnector::update);
|
||||
}
|
||||
|
||||
void AsCommonCarConnector::update() {
|
||||
_x = _asCar->getX();
|
||||
_y = _asCar->getY();
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
void Tracks::findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
|
||||
DataResource &dataResource) {
|
||||
const uint trackCount = size();
|
||||
minMatchTrackIndex = -1;
|
||||
minMatchDistance = 640;
|
||||
for (uint trackIndex = 0; trackIndex < trackCount; trackIndex++) {
|
||||
NPointArray *pointList = dataResource.getPointArray((*this)[trackIndex]->trackPointsName);
|
||||
for (uint pointIndex = 0; pointIndex < pointList->size(); pointIndex++) {
|
||||
NPoint testPt = (*pointList)[pointIndex];
|
||||
int distance = calcDistance(testPt.x, testPt.y, pt.x, pt.y);
|
||||
if (distance < minMatchDistance) {
|
||||
minMatchTrackIndex = trackIndex;
|
||||
minMatchDistance = distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KmScene1608::KmScene1608(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene1608::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case 0x2032:
|
||||
_isSittingInTeleporter = param.asInteger() != 0;
|
||||
messageResult = 1;
|
||||
break;
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stSitIdleTeleporter);
|
||||
else
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPickUpNeedle);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPickUpTube);
|
||||
else
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stTurnToUseInTeleporter);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stReturnFromUseInTeleporter);
|
||||
break;
|
||||
case 0x481F:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stWonderAboutAfter);
|
||||
else if (param.asInteger() == 0)
|
||||
GotoState(&Klaymen::stWonderAboutHalf);
|
||||
else if (param.asInteger() == 4)
|
||||
GotoState(&Klaymen::stTurnAwayFromUse);
|
||||
else if (param.asInteger() == 3)
|
||||
GotoState(&Klaymen::stTurnToUseHalf);
|
||||
else
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
break;
|
||||
case 0x482D:
|
||||
setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x4834:
|
||||
GotoState(&Klaymen::stStepOver);
|
||||
break;
|
||||
case 0x4835:
|
||||
sendMessage(_parentScene, 0x2032, 1);
|
||||
_isSittingInTeleporter = true;
|
||||
GotoState(&Klaymen::stSitInTeleporter);
|
||||
break;
|
||||
case 0x4836:
|
||||
sendMessage(_parentScene, 0x2032, 0);
|
||||
_isSittingInTeleporter = false;
|
||||
GotoState(&Klaymen::stGetUpFromTeleporter);
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
125
engines/neverhood/modules/module1600_sprites.h
Normal file
125
engines/neverhood/modules/module1600_sprites.h
Normal file
@@ -0,0 +1,125 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1600_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE1600_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class AsCommonCar : public AnimatedSprite {
|
||||
public:
|
||||
AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
~AsCommonCar() override;
|
||||
void setPathPoints(NPointArray *pathPoints);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
NPointArray *_pathPoints;
|
||||
int _newMoveDirection;
|
||||
int _currMoveDirection;
|
||||
int _exitDirection;
|
||||
int _currPointIndex;
|
||||
bool _hasAgainDestPoint;
|
||||
NPoint _againDestPoint;
|
||||
bool _hasAgainDestPointIndex;
|
||||
int _againDestPointIndex;
|
||||
bool _inMainArea;
|
||||
bool _isBraking;
|
||||
bool _isBusy;
|
||||
bool _isIdle;
|
||||
bool _isMoving;
|
||||
bool _rectFlag;
|
||||
int _idleCounter;
|
||||
int _idleCounterMax;
|
||||
int _steps;
|
||||
int _stepError;
|
||||
int _lastDistance;
|
||||
int _yMoveTotalSteps;
|
||||
int _ySteps;
|
||||
int _newDeltaXType;
|
||||
int _soundCounter;
|
||||
int _turnMoveStatus;
|
||||
int16 _destX, _destY;
|
||||
NPoint pathPoint(uint index) { return (*_pathPoints)[index]; }
|
||||
void update();
|
||||
void upIdle();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmAnimation(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmLeaveCar(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stCarAtHome();
|
||||
void updateTurnMovement();
|
||||
void updateMovement();
|
||||
void stEnterCar();
|
||||
void stLeaveCar();
|
||||
void stLeanForwardIdle();
|
||||
void evIdleDone();
|
||||
void stIdleBlink();
|
||||
void stUpdateMoveDirection();
|
||||
void stTurnCar();
|
||||
void moveToNextPoint();
|
||||
void stBrakeMoveToNextPoint();
|
||||
void stTurnCarMoveToNextPoint();
|
||||
void moveToPrevPoint();
|
||||
void stBrakeMoveToPrevPoint();
|
||||
void stTurnCarMoveToPrevPoint();
|
||||
void evTurnCarDone();
|
||||
void suMoveToNextPoint();
|
||||
void suMoveToPrevPoint();
|
||||
void updateSound();
|
||||
};
|
||||
|
||||
class AsCommonIdleCarLower : public AnimatedSprite {
|
||||
public:
|
||||
AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y);
|
||||
};
|
||||
|
||||
class AsCommonIdleCarFull : public AnimatedSprite {
|
||||
public:
|
||||
AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y);
|
||||
};
|
||||
|
||||
class AsCommonCarConnector : public AnimatedSprite {
|
||||
public:
|
||||
AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar);
|
||||
protected:
|
||||
AsCommonCar *_asCar;
|
||||
void update();
|
||||
};
|
||||
|
||||
class Tracks : public Common::Array<TrackInfo*> {
|
||||
public:
|
||||
void findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
|
||||
DataResource &dataResource);
|
||||
};
|
||||
|
||||
class KmScene1608 : public Klaymen {
|
||||
public:
|
||||
KmScene1608(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1600_SPRITES_H */
|
||||
242
engines/neverhood/modules/module1700.cpp
Normal file
242
engines/neverhood/modules/module1700.cpp
Normal file
@@ -0,0 +1,242 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/gamemodule.h"
|
||||
#include "neverhood/modules/module1700.h"
|
||||
#include "neverhood/modules/module1700_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kModule1700SoundList[] = {
|
||||
0xB288D450,
|
||||
0x90804450,
|
||||
0x99801500,
|
||||
0xB288D455,
|
||||
0x93825040,
|
||||
0
|
||||
};
|
||||
|
||||
Module1700::Module1700(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
_vm->_soundMan->addMusic(0x04212331, 0x31114225);
|
||||
_vm->_soundMan->addSoundList(0x04212331, kModule1700SoundList);
|
||||
_vm->_soundMan->setSoundListParams(kModule1700SoundList, true, 50, 600, 5, 150);
|
||||
_vm->_soundMan->playTwoSounds(0x04212331, 0x41861371, 0x43A2507F, 0);
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else if (which == 0)
|
||||
createScene(0, -1);
|
||||
else if (which == 1)
|
||||
createScene(4, 1);
|
||||
else
|
||||
createScene(4, 3);
|
||||
|
||||
}
|
||||
|
||||
Module1700::~Module1700() {
|
||||
_vm->_soundMan->deleteGroup(0x04212331);
|
||||
}
|
||||
|
||||
void Module1700::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module1700::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_vm->_soundMan->setSoundListParams(kModule1700SoundList, false, 0, 0, 0, 0);
|
||||
createSmackerScene(0x3028A005, true, true, false);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
createNavigationScene(0x004AE8B8, which);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
createNavigationScene(0x004AE8E8, which);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
_vm->_soundMan->setSoundListParams(kModule1700SoundList, false, 0, 0, 0, 0);
|
||||
createSmackerScene(0x01190041, true, true, false);
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
_vm->_soundMan->setSoundListParams(kModule1700SoundList, false, 0, 0, 0, 0);
|
||||
_vm->_soundMan->startMusic(0x31114225, 0, 2);
|
||||
_childObject = new Scene1705(_vm, this, which);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module1700::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module1700::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->_soundMan->setSoundListParams(kModule1700SoundList, true, 0, 0, 0, 0);
|
||||
createScene(1, 0);
|
||||
break;
|
||||
case 1:
|
||||
if (_moduleResult == 0)
|
||||
createScene(2, 0);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(1, 1);
|
||||
break;
|
||||
case 2:
|
||||
if (_moduleResult == 0)
|
||||
createScene(3, -1);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(1, 1);
|
||||
else if (_moduleResult == 2) {
|
||||
if (!isSoundPlaying(0)) {
|
||||
setSoundVolume(0, 60);
|
||||
playSound(0, 0x58B45E58);
|
||||
}
|
||||
createScene(2, 2);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
createScene(4, 0);
|
||||
break;
|
||||
case 4:
|
||||
leaveModule(1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const uint32 kScene1705FileHashes[] = {
|
||||
0x910EA801, 0x920EA801, 0x940EA801,
|
||||
0x980EA801, 0x800EA801, 0xB00EA801,
|
||||
0xD00EA801, 0x100EA801, 0x900EA800,
|
||||
0xD10EA801, 0x110EA801, 0x910EA800
|
||||
};
|
||||
|
||||
Scene1705::Scene1705(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _paletteArea(1) {
|
||||
|
||||
Sprite *tempSprite;
|
||||
|
||||
setGlobalVar(V_FELL_DOWN_HOLE, 1);
|
||||
_vm->gameModule()->initCannonSymbolsPuzzle();
|
||||
|
||||
SetMessageHandler(&Scene1705::handleMessage);
|
||||
SetUpdateHandler(&Scene1705::update);
|
||||
|
||||
setHitRects(0x004B69D8);
|
||||
setBackground(0x03118226);
|
||||
setPalette(0x03118226);
|
||||
_palette->addBasePalette(0x91D3A391, 0, 64, 0);
|
||||
_palette->copyBasePalette(0, 256, 0);
|
||||
addEntity(_palette);
|
||||
insertScreenMouse(0x18222039);
|
||||
|
||||
insertSprite<SsScene1705WallSymbol>(kScene1705FileHashes[getSubVar(VA_GOOD_CANNON_SYMBOLS_2, 0)], 0);
|
||||
insertSprite<SsScene1705WallSymbol>(kScene1705FileHashes[getSubVar(VA_GOOD_CANNON_SYMBOLS_2, 1)], 1);
|
||||
insertSprite<SsScene1705WallSymbol>(kScene1705FileHashes[getSubVar(VA_GOOD_CANNON_SYMBOLS_2, 2)], 2);
|
||||
_sprite = insertStaticSprite(0x31313A22, 1100);
|
||||
_ssTape = insertSprite<SsScene1705Tape>(this, 15, 1100, 238, 439, 0x02363852);
|
||||
addCollisionSprite(_ssTape);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene1705>(231, 434);
|
||||
setMessageList(0x004B69E8);
|
||||
sendMessage(this, 0x2000, 0);
|
||||
_klaymen->setClipRect(0, 0, _sprite->getDrawRect().x2(), 480);
|
||||
} else if (which == 1) {
|
||||
// Klaymen teleporting in
|
||||
insertKlaymen<KmScene1705>(431, 434);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B6A08, false);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
_klaymen->setClipRect(0, 0, _sprite->getDrawRect().x2(), 480);
|
||||
} else if (which == 2) {
|
||||
// Klaymen teleporting out
|
||||
insertKlaymen<KmScene1705>(431, 434);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B6AA0, false);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
_klaymen->setClipRect(0, 0, _sprite->getDrawRect().x2(), 480);
|
||||
} else if (which == 3) {
|
||||
// Klaymen returning from teleporter console
|
||||
insertKlaymen<KmScene1705>(431, 434);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B6A18, false);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
_klaymen->setClipRect(0, 0, _sprite->getDrawRect().x2(), 480);
|
||||
} else {
|
||||
// Klaymen falling through the hole
|
||||
insertKlaymen<KmScene1705>(231, 74);
|
||||
sendMessage(_klaymen, 0x2000, 0);
|
||||
setMessageList(0x004B69F0);
|
||||
sendMessage(this, 0x2000, 0);
|
||||
tempSprite = insertStaticSprite(0x30303822, 1100);
|
||||
_klaymen->setClipRect(0, tempSprite->getDrawRect().y, _sprite->getDrawRect().x2(), 480);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Scene1705::update() {
|
||||
Scene::update();
|
||||
if (_klaymen->getX() < 224 && _paletteArea != 0) {
|
||||
_palette->addBasePalette(0xF2210C15, 0, 64, 0);
|
||||
_palette->startFadeToPalette(12);
|
||||
_paletteArea = 0;
|
||||
} else if (_klaymen->getX() >= 224 && _paletteArea == 0) {
|
||||
_palette->addBasePalette(0x91D3A391, 0, 64, 0);
|
||||
_palette->startFadeToPalette(12);
|
||||
_paletteArea = 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Scene1705::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (param.asInteger()) {
|
||||
setRectList(0x004B6B40);
|
||||
_klaymen->setKlaymenIdleTable3();
|
||||
} else {
|
||||
setRectList(0x004B6B30);
|
||||
_klaymen->setKlaymenIdleTable1();
|
||||
}
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _ssTape && _klaymen->getX() <= 318) {
|
||||
sendEntityMessage(_klaymen, 0x1014, sender);
|
||||
setMessageList(0x004B6AC0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
54
engines/neverhood/modules/module1700.h
Normal file
54
engines/neverhood/modules/module1700.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1700_H
|
||||
#define NEVERHOOD_MODULES_MODULE1700_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module1700 : public Module {
|
||||
public:
|
||||
Module1700(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module1700() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class Scene1705 : public Scene {
|
||||
public:
|
||||
Scene1705(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_sprite;
|
||||
Sprite *_ssTape;
|
||||
int _paletteArea;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1700_H */
|
||||
159
engines/neverhood/modules/module1700_sprites.cpp
Normal file
159
engines/neverhood/modules/module1700_sprites.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1700_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
SsScene1705WallSymbol::SsScene1705WallSymbol(NeverhoodEngine *vm, uint32 fileHash, int symbolIndex)
|
||||
: StaticSprite(vm, fileHash, 100) {
|
||||
|
||||
_x = _spriteResource.getPosition().x + symbolIndex * 30;
|
||||
_y = _spriteResource.getPosition().y + 160;
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
SsScene1705Tape::SsScene1705Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 tapeIndex, int surfacePriority, int16 x, int16 y, uint32 fileHash)
|
||||
: StaticSprite(vm, fileHash, surfacePriority, x - 24, y - 4), _parentScene(parentScene), _tapeIndex(tapeIndex) {
|
||||
|
||||
if (!getSubVar(VA_HAS_TAPE, _tapeIndex) && !getSubVar(VA_IS_TAPE_INSERTED, _tapeIndex)) {
|
||||
SetMessageHandler(&SsScene1705Tape::handleMessage);
|
||||
} else {
|
||||
setVisible(false);
|
||||
SetMessageHandler(nullptr);
|
||||
}
|
||||
_collisionBoundsOffset = _drawOffset;
|
||||
_collisionBoundsOffset.x -= 4;
|
||||
_collisionBoundsOffset.y -= 8;
|
||||
_collisionBoundsOffset.width += 8;
|
||||
_collisionBoundsOffset.height += 16;
|
||||
Sprite::updateBounds();
|
||||
}
|
||||
|
||||
uint32 SsScene1705Tape::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
sendMessage(_parentScene, 0x4826, 0);
|
||||
messageResult = 1;
|
||||
break;
|
||||
case NM_KLAYMEN_USE_OBJECT:
|
||||
setSubVar(VA_HAS_TAPE, _tapeIndex, 1);
|
||||
setVisible(false);
|
||||
SetMessageHandler(nullptr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
KmScene1705::KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isSittingInTeleporter = param.asInteger() != 0;
|
||||
messageResult = 1;
|
||||
break;
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stSitIdleTeleporter);
|
||||
else
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x4803:
|
||||
GotoState(&Klaymen::stFallSkipJump);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPickUpNeedle);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPickUpTube);
|
||||
else
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
if (_isSittingInTeleporter) {
|
||||
GotoState(&Klaymen::stTurnToUseInTeleporter);
|
||||
}
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stReturnFromUseInTeleporter);
|
||||
break;
|
||||
case 0x481F:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stWonderAboutAfter);
|
||||
else if (param.asInteger() == 0)
|
||||
GotoState(&Klaymen::stWonderAboutHalf);
|
||||
else if (param.asInteger() == 4)
|
||||
GotoState(&Klaymen::stTurnAwayFromUse);
|
||||
else if (param.asInteger() == 3)
|
||||
GotoState(&Klaymen::stTurnToUseHalf);
|
||||
else
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
break;
|
||||
case 0x4834:
|
||||
GotoState(&Klaymen::stStepOver);
|
||||
break;
|
||||
case 0x4835:
|
||||
sendMessage(_parentScene, 0x2000, 1);
|
||||
_isSittingInTeleporter = true;
|
||||
GotoState(&Klaymen::stSitInTeleporter);
|
||||
break;
|
||||
case 0x4836:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_isSittingInTeleporter = false;
|
||||
GotoState(&Klaymen::stGetUpFromTeleporter);
|
||||
break;
|
||||
case 0x483D:
|
||||
teleporterAppear(0x5E0A4905);
|
||||
break;
|
||||
case 0x483E:
|
||||
teleporterDisappear(0xD86E4477);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
54
engines/neverhood/modules/module1700_sprites.h
Normal file
54
engines/neverhood/modules/module1700_sprites.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1700_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE1700_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class SsScene1705WallSymbol : public StaticSprite {
|
||||
public:
|
||||
SsScene1705WallSymbol(NeverhoodEngine *vm, uint32 fileHash, int symbolIndex);
|
||||
};
|
||||
|
||||
class SsScene1705Tape : public StaticSprite {
|
||||
public:
|
||||
SsScene1705Tape(NeverhoodEngine *vm, Scene *parentScene, uint32 tapeIndex, int surfacePriority, int16 x, int16 y, uint32 fileHash);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 _tapeIndex;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene1705 : public Klaymen {
|
||||
public:
|
||||
KmScene1705(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1700_SPRITES_H */
|
||||
187
engines/neverhood/modules/module1800.cpp
Normal file
187
engines/neverhood/modules/module1800.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/diskplayerscene.h"
|
||||
#include "neverhood/menumodule.h"
|
||||
#include "neverhood/navigationscene.h"
|
||||
#include "neverhood/modules/module1800.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kModule1800SoundList[] = {
|
||||
0x16805548,
|
||||
0x16805048,
|
||||
0xD0E14441,
|
||||
0x90E090C2,
|
||||
0x90E1D0C2,
|
||||
0x90E2D0C2,
|
||||
0
|
||||
};
|
||||
|
||||
Module1800::Module1800(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
_vm->_soundMan->addSoundList(0x04A14718, kModule1800SoundList);
|
||||
_vm->_soundMan->setSoundListParams(kModule1800SoundList, true, 50, 600, 10, 150);
|
||||
_vm->_soundMan->playTwoSounds(0x04A14718, 0x8A382B55, 0x0C242F1D, 0);
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else if (which == 2)
|
||||
createScene(5, 0);
|
||||
else if (which == 3)
|
||||
createScene(0, 0);
|
||||
else
|
||||
createScene(3, 1);
|
||||
|
||||
}
|
||||
|
||||
Module1800::~Module1800() {
|
||||
_vm->_soundMan->deleteGroup(0x04A14718);
|
||||
}
|
||||
|
||||
void Module1800::createScene(int sceneNum, int which) {
|
||||
static const byte kNavigationTypes00[] = {1, 0, 2, 0};
|
||||
static const byte kNavigationTypes01[] = {5};
|
||||
debug(1, "Module1800::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
createNavigationScene(0x004AFD38, which, kNavigationTypes00);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
createNavigationScene(0x004AFD98, which, kNavigationTypes01);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
createSmackerScene(0x006C0085, true, true, false);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
createNavigationScene(0x004AFDB0, which);
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
createNavigationScene(0x004AFDE0, which);
|
||||
break;
|
||||
case 5:
|
||||
_vm->gameState().sceneNum = 5;
|
||||
createNavigationScene(0x004AFE40, which);
|
||||
break;
|
||||
case 6:
|
||||
_vm->gameState().sceneNum = 6;
|
||||
_vm->_soundMan->deleteGroup(0x04A14718);
|
||||
createSmackerScene(0x08D84010, true, true, false);
|
||||
break;
|
||||
case 7:
|
||||
_vm->gameState().sceneNum = 7;
|
||||
_vm->_soundMan->setSoundListParams(kModule1800SoundList, false, 0, 0, 0, 0);
|
||||
createSmackerScene(0x0168B121, true, true, false);
|
||||
break;
|
||||
case 8:
|
||||
_vm->gameState().sceneNum = 8;
|
||||
_childObject = new CreditsScene(_vm, this, false);
|
||||
break;
|
||||
case 1009:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
// NOTE: Newly introduced sceneNum 1009 (was duplicate 3 with own update handler)
|
||||
createSmackerScene(0x0A840C01, true, true, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module1800::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module1800::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1)
|
||||
createScene(4, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(1, -1);
|
||||
else if (_moduleResult == 3)
|
||||
createScene(3, 0);
|
||||
break;
|
||||
case 1:
|
||||
if (_navigationAreaType == 3)
|
||||
createScene(7, -1);
|
||||
else
|
||||
createScene(2, -1);
|
||||
break;
|
||||
case 2:
|
||||
createScene(0, 2);
|
||||
break;
|
||||
case 3:
|
||||
if (_moduleResult == 0)
|
||||
createScene(1009, -1);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(0, 1);
|
||||
break;
|
||||
case 4:
|
||||
if (_moduleResult == 0)
|
||||
createScene(6, -1);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(5, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(0, 3);
|
||||
else if (_moduleResult == 3)
|
||||
createScene(4, 3);
|
||||
break;
|
||||
case 5:
|
||||
if (_moduleResult == 0)
|
||||
leaveModule(2);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(4, 3);
|
||||
break;
|
||||
case 6:
|
||||
createScene(8, -1);
|
||||
break;
|
||||
case 7:
|
||||
leaveModule(3);
|
||||
break;
|
||||
case 8:
|
||||
// NOTE: After Klaymen jumped into the hole and died...
|
||||
leaveModule(1);
|
||||
break;
|
||||
case 1009:
|
||||
leaveModule(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (navigationScene()->isWalkingForward() && navigationScene()->getNavigationIndex() == 2)
|
||||
_vm->_soundMan->setTwoSoundsPlayFlag(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
45
engines/neverhood/modules/module1800.h
Normal file
45
engines/neverhood/modules/module1800.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1800_H
|
||||
#define NEVERHOOD_MODULES_MODULE1800_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Module1800
|
||||
|
||||
class Module1800 : public Module {
|
||||
public:
|
||||
Module1800(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module1800() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1800_H */
|
||||
264
engines/neverhood/modules/module1900.cpp
Normal file
264
engines/neverhood/modules/module1900.cpp
Normal file
@@ -0,0 +1,264 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1900.h"
|
||||
#include "neverhood/modules/module1900_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kModule1900SoundList[] = {
|
||||
0xB4005E60,
|
||||
0x91835066,
|
||||
0x90E14440,
|
||||
0
|
||||
};
|
||||
|
||||
Module1900::Module1900(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
// NOTE: The original has a Scene1908 here as well but it's not used here but in another module...
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else
|
||||
createScene(0, 0);
|
||||
|
||||
_vm->_soundMan->addSoundList(0x04E1C09C, kModule1900SoundList);
|
||||
_vm->_soundMan->setSoundListParams(kModule1900SoundList, true, 50, 600, 5, 150);
|
||||
|
||||
}
|
||||
|
||||
Module1900::~Module1900() {
|
||||
_vm->_soundMan->deleteGroup(0x04E1C09C);
|
||||
}
|
||||
|
||||
void Module1900::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module1900::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_childObject = new Scene1901(_vm, this, which);
|
||||
break;
|
||||
case 6:
|
||||
_vm->gameState().sceneNum = 6;
|
||||
_childObject = new Scene1907(_vm, this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module1900::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module1900::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1)
|
||||
createScene(6, 0);
|
||||
else
|
||||
leaveModule(0);
|
||||
break;
|
||||
case 6:
|
||||
createScene(0, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scene1901::Scene1901(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule) {
|
||||
|
||||
Sprite *tempSprite;
|
||||
|
||||
setRectList(0x004B34C8);
|
||||
|
||||
setBackground(0x01303227);
|
||||
setPalette(0x01303227);
|
||||
insertScreenMouse(0x0322301B);
|
||||
|
||||
insertStaticSprite(0x42213133, 1100);
|
||||
|
||||
if (!getGlobalVar(V_STAIRS_PUZZLE_SOLVED))
|
||||
insertStaticSprite(0x40A40168, 100);
|
||||
else if (getGlobalVar(V_STAIRS_DOWN)) {
|
||||
insertStaticSprite(0x124404C4, 100);
|
||||
setGlobalVar(V_STAIRS_DOWN_ONCE, 1);
|
||||
} else
|
||||
insertStaticSprite(0x02840064, 100);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene1901>(120, 380);
|
||||
setMessageList(0x004B3408);
|
||||
} else if (which == 1) {
|
||||
// Klaymen returning from the puzzle
|
||||
insertKlaymen<KmScene1901>(372, 380);
|
||||
setMessageList(0x004B3410);
|
||||
} else {
|
||||
// Klaymen entering from the left
|
||||
insertKlaymen<KmScene1901>(0, 380);
|
||||
setMessageList(0x004B3400);
|
||||
}
|
||||
|
||||
tempSprite = insertStaticSprite(0x4830A402, 1100);
|
||||
_klaymen->setClipRect(tempSprite->getDrawRect().x, 0, 640, 480);
|
||||
|
||||
}
|
||||
|
||||
Scene1907::Scene1907(NeverhoodEngine *vm, Module *parentModule)
|
||||
: Scene(vm, parentModule), _currMovingSymbolIndex(0), _pluggedInCount(0),
|
||||
_moveDownCountdown(0), _moveUpCountdown(0), _countdown3(0), _hasPlugInFailed(false) {
|
||||
|
||||
setBackground(0x20628E05);
|
||||
setPalette(0x20628E05);
|
||||
|
||||
for (int i = 0; i < 9; i++)
|
||||
_positionFree[i] = true;
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
_asSymbols[i] = insertSprite<AsScene1907Symbol>(this, i, getRandomPositionIndex());
|
||||
addCollisionSprite(_asSymbols[i]);
|
||||
}
|
||||
|
||||
_ssUpDownButton = insertSprite<SsScene1907UpDownButton>(this, _asSymbols[8]);
|
||||
addCollisionSprite(_ssUpDownButton);
|
||||
|
||||
_asWaterHint = insertSprite<AsScene1907WaterHint>();
|
||||
|
||||
insertPuzzleMouse(0x28E0120E, 20, 620);
|
||||
|
||||
SetMessageHandler(&Scene1907::handleMessage);
|
||||
SetUpdateHandler(&Scene1907::update);
|
||||
|
||||
if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED))
|
||||
_pluggedInCount = 9;
|
||||
|
||||
loadSound(0, 0x72004A10);
|
||||
loadSound(1, 0x22082A12);
|
||||
loadSound(2, 0x21100A10);
|
||||
loadSound(3, 0x68E25540);
|
||||
|
||||
}
|
||||
|
||||
void Scene1907::update() {
|
||||
Scene::update();
|
||||
|
||||
if (_hasPlugInFailed) {
|
||||
int fallOffDelay = 0;
|
||||
_hasPlugInFailed = false;
|
||||
for (int i = 0; i < 9; i++) {
|
||||
AsScene1907Symbol *asSymbol = _asSymbols[8 - i];
|
||||
if (asSymbol->isPluggedIn()) {
|
||||
asSymbol->fallOff(getRandomPositionIndex(), fallOffDelay);
|
||||
fallOffDelay += _vm->_rnd->getRandomNumber(10 - 1) + 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_moveDownCountdown != 0 && (--_moveDownCountdown == 0)) {
|
||||
_asSymbols[_currMovingSymbolIndex]->moveDown();
|
||||
if (_currMovingSymbolIndex > 0) {
|
||||
_moveDownCountdown = 2;
|
||||
_currMovingSymbolIndex--;
|
||||
}
|
||||
}
|
||||
|
||||
if (_moveUpCountdown != 0 && (--_moveUpCountdown == 0)) {
|
||||
_moveDownCountdown = 0;
|
||||
for (int i = 0; i < 9; i++)
|
||||
_asSymbols[i]->moveUp();
|
||||
}
|
||||
|
||||
if (_countdown3 != 0 && (--_countdown3 == 0)) {
|
||||
_asWaterHint->show();
|
||||
_moveUpCountdown = 4;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene1907::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) &&
|
||||
!_hasPlugInFailed && _moveDownCountdown == 0 && _moveUpCountdown == 0 && _countdown3 == 0) {
|
||||
leaveScene(0);
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (getGlobalVar(V_STAIRS_DOWN)) {
|
||||
playSound(0);
|
||||
for (int i = 0; i < 9; i++)
|
||||
_asSymbols[i]->moveUp();
|
||||
_ssUpDownButton->setToUpPosition();
|
||||
setGlobalVar(V_STAIRS_DOWN, 0);
|
||||
} else {
|
||||
if (!getGlobalVar(V_WALL_BROKEN)) {
|
||||
playSound(2);
|
||||
_countdown3 = 5;
|
||||
} else {
|
||||
playSound(1);
|
||||
_ssUpDownButton->setToDownPosition();
|
||||
setGlobalVar(V_STAIRS_DOWN, 1);
|
||||
}
|
||||
_moveDownCountdown = 1;
|
||||
_currMovingSymbolIndex = 8;
|
||||
}
|
||||
break;
|
||||
case 0x2001:
|
||||
playSound(3);
|
||||
setGlobalVar(V_STAIRS_PUZZLE_SOLVED, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Scene1907::plugInFailed() {
|
||||
_pluggedInCount = 0;
|
||||
_hasPlugInFailed = true;
|
||||
}
|
||||
|
||||
int Scene1907::getRandomPositionIndex() {
|
||||
bool found = false;
|
||||
int index = 0;
|
||||
// Check if any position is free
|
||||
for (int i = 0; i < 9; i++)
|
||||
if (_positionFree[i])
|
||||
found = true;
|
||||
if (found) {
|
||||
// Get a random free position
|
||||
found = false;
|
||||
while (!found) {
|
||||
index = _vm->_rnd->getRandomNumber(9 - 1);
|
||||
if (_positionFree[index])
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
75
engines/neverhood/modules/module1900.h
Normal file
75
engines/neverhood/modules/module1900.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1900_H
|
||||
#define NEVERHOOD_MODULES_MODULE1900_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module1900 : public Module {
|
||||
public:
|
||||
Module1900(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module1900() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class Scene1901 : public Scene {
|
||||
public:
|
||||
Scene1901(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
};
|
||||
|
||||
class AsScene1907Symbol;
|
||||
class SsScene1907UpDownButton;
|
||||
class AsScene1907WaterHint;
|
||||
|
||||
class Scene1907 : public Scene {
|
||||
public:
|
||||
Scene1907(NeverhoodEngine *vm, Module *parentModule);
|
||||
void plugInFailed();
|
||||
void setPositionFree(int index, bool value) { _positionFree[index] = value; }
|
||||
int getNextPosition() { return _pluggedInCount++; }
|
||||
protected:
|
||||
AsScene1907Symbol *_asSymbols[9];
|
||||
SsScene1907UpDownButton *_ssUpDownButton;
|
||||
AsScene1907WaterHint *_asWaterHint;
|
||||
int _currMovingSymbolIndex;
|
||||
int _pluggedInCount;
|
||||
int _moveDownCountdown;
|
||||
int _moveUpCountdown;
|
||||
int _countdown3;
|
||||
bool _hasPlugInFailed;
|
||||
bool _positionFree[9];
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
int getRandomPositionIndex();
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1900_H */
|
||||
466
engines/neverhood/modules/module1900_sprites.cpp
Normal file
466
engines/neverhood/modules/module1900_sprites.cpp
Normal file
@@ -0,0 +1,466 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1900.h"
|
||||
#include "neverhood/modules/module1900_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const NPoint kAsScene1907SymbolGroundPositions[] = {
|
||||
{160, 310}, { 90, 340}, {210, 335},
|
||||
{210, 380}, {310, 340}, {290, 400},
|
||||
{400, 375}, {370, 435}, {475, 415}
|
||||
};
|
||||
|
||||
static const NPoint kAsScene1907SymbolPluggedInPositions[] = {
|
||||
{275, 125}, {244, 125}, {238, 131},
|
||||
{221, 135}, {199, 136}, {168, 149},
|
||||
{145, 152}, {123, 154}, {103, 157}
|
||||
};
|
||||
|
||||
static const NPoint kAsScene1907SymbolGroundHitPositions[] = {
|
||||
{275, 299}, {244, 299}, {238, 305},
|
||||
{221, 309}, {199, 310}, {168, 323},
|
||||
{145, 326}, {123, 328}, {103, 331}
|
||||
};
|
||||
|
||||
static const NPoint kAsScene1907SymbolPluggedInDownPositions[] = {
|
||||
{275, 136}, {244, 156}, {238, 183},
|
||||
{221, 207}, {199, 228}, {168, 262},
|
||||
{145, 285}, {123, 307}, {103, 331}
|
||||
};
|
||||
|
||||
static const uint32 kAsScene1907SymbolFileHashes[] = {
|
||||
0x006A1034, 0x006A1010, 0x006A1814,
|
||||
0x006A1016, 0x006A0014, 0x002A1014,
|
||||
0x00EA1014, 0x206A1014, 0x046A1414
|
||||
};
|
||||
|
||||
bool AsScene1907Symbol::_plugInFailed = false;
|
||||
int AsScene1907Symbol::_plugInTryCount = 0;
|
||||
|
||||
AsScene1907Symbol::AsScene1907Symbol(NeverhoodEngine *vm, Scene1907 *parentScene, int elementIndex, int positionIndex)
|
||||
: AnimatedSprite(vm, 1000 - positionIndex), _parentScene(parentScene), _elementIndex(elementIndex), _isMoving(false) {
|
||||
|
||||
_plugInFailed = false;
|
||||
_plugInTryCount = 0;
|
||||
|
||||
if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
|
||||
_isPluggedIn = true;
|
||||
_currPositionIndex = elementIndex;
|
||||
if (!getGlobalVar(V_STAIRS_DOWN)) {
|
||||
_x = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].x;
|
||||
_y = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].y;
|
||||
} else {
|
||||
_x = kAsScene1907SymbolPluggedInDownPositions[_currPositionIndex].x;
|
||||
_y = kAsScene1907SymbolPluggedInDownPositions[_currPositionIndex].y;
|
||||
}
|
||||
createSurface1(kAsScene1907SymbolFileHashes[_elementIndex], 1000 + _currPositionIndex);
|
||||
startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
} else {
|
||||
_isPluggedIn = false;
|
||||
_currPositionIndex = positionIndex;
|
||||
loadSound(0, 0x74231924);
|
||||
loadSound(1, 0x36691914);
|
||||
loadSound(2, 0x5421D806);
|
||||
_parentScene->setPositionFree(_currPositionIndex, false);
|
||||
_x = kAsScene1907SymbolGroundPositions[_currPositionIndex].x;
|
||||
_y = kAsScene1907SymbolGroundPositions[_currPositionIndex].y;
|
||||
createSurface1(kAsScene1907SymbolFileHashes[_elementIndex], 1000 + _currPositionIndex);
|
||||
startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
}
|
||||
_collisionBoundsOffset.set(0, 0, 80, 80);
|
||||
Sprite::updateBounds();
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1907Symbol::handleMessage);
|
||||
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::update() {
|
||||
updateAnim();
|
||||
handleSpriteUpdate();
|
||||
updatePosition();
|
||||
if (_plugInFailed && _plugInTryCount == 0)
|
||||
_plugInFailed = false;
|
||||
}
|
||||
|
||||
uint32 AsScene1907Symbol::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (!_isPluggedIn && !_plugInFailed) {
|
||||
tryToPlugIn();
|
||||
messageResult = 1;
|
||||
} else
|
||||
messageResult = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 AsScene1907Symbol::hmTryToPlugIn(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::suTryToPlugIn() {
|
||||
_currStep++;
|
||||
_x -= _deltaX;
|
||||
_y -= _deltaY;
|
||||
if (_currStep == 16) {
|
||||
_x -= _smallDeltaX;
|
||||
_y -= _smallDeltaY;
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::suFallOff() {
|
||||
if (_fallOffDelay != 0) {
|
||||
_fallOffDelay--;
|
||||
} else {
|
||||
_y += _yAccel;
|
||||
_yAccel += 8;
|
||||
if (_y >= kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y) {
|
||||
_y = kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y;
|
||||
stFallOffHitGround();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::suFallOffHitGround() {
|
||||
|
||||
if (_x == _someX - _xBreak)
|
||||
_x -= _smallDeltaX;
|
||||
else
|
||||
_x -= _deltaX;
|
||||
|
||||
if (_y == kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y) {
|
||||
_y -= _someY;
|
||||
}
|
||||
|
||||
if (_currStep < 8) {
|
||||
_y -= _yAccel;
|
||||
_yAccel -= 4;
|
||||
if (_yAccel < 0)
|
||||
_yAccel = 0;
|
||||
} else if (_currStep < 15) {
|
||||
_y += _yAccel;
|
||||
_yAccel += 4;
|
||||
} else {
|
||||
_y = kAsScene1907SymbolGroundPositions[_newPositionIndex].y;
|
||||
cbFallOffHitGroundEvent();
|
||||
}
|
||||
|
||||
_currStep++;
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::suMoveDown() {
|
||||
_y += _yIncr;
|
||||
if (_yIncr < 11)
|
||||
_yIncr++;
|
||||
if (_y >= kAsScene1907SymbolPluggedInDownPositions[_elementIndex].y) {
|
||||
_y = kAsScene1907SymbolPluggedInDownPositions[_elementIndex].y;
|
||||
_isMoving = false;
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::suMoveUp() {
|
||||
_y -= _yIncr;
|
||||
if (getGlobalVar(V_WALL_BROKEN)) {
|
||||
if (_y - (9 + (_elementIndex > 5 ? 31 : 0)) < kAsScene1907SymbolPluggedInPositions[_elementIndex].y)
|
||||
_yIncr--;
|
||||
else
|
||||
_yIncr++;
|
||||
} else
|
||||
_yIncr = 2;
|
||||
if (_yIncr > 9)
|
||||
_yIncr = 9;
|
||||
else if (_yIncr < 1)
|
||||
_yIncr = 1;
|
||||
if (_y < kAsScene1907SymbolPluggedInPositions[_elementIndex].y) {
|
||||
_y = kAsScene1907SymbolPluggedInPositions[_elementIndex].y;
|
||||
_isMoving = false;
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::tryToPlugIn() {
|
||||
_isPluggedIn = true;
|
||||
_plugInTryCount++;
|
||||
_newPositionIndex = _parentScene->getNextPosition();
|
||||
_parentScene->setPositionFree(_currPositionIndex, true);
|
||||
sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1100 + _newPositionIndex);
|
||||
startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
|
||||
SetUpdateHandler(&AsScene1907Symbol::update);
|
||||
SetMessageHandler(&AsScene1907Symbol::hmTryToPlugIn);
|
||||
SetSpriteUpdate(&AsScene1907Symbol::suTryToPlugIn);
|
||||
_currStep = 0;
|
||||
_deltaX = (_x - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].x) / 16;
|
||||
_smallDeltaX = _x - _deltaX * 16 - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].x;
|
||||
_deltaY = (_y - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].y) / 16;
|
||||
_smallDeltaY = _y - _deltaY * 16 - kAsScene1907SymbolPluggedInPositions[_newPositionIndex].y;
|
||||
if (_elementIndex == _newPositionIndex) {
|
||||
NextState(&AsScene1907Symbol::stPlugIn);
|
||||
} else {
|
||||
_plugInFailed = true;
|
||||
NextState(&AsScene1907Symbol::stPlugInFail);
|
||||
}
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::fallOff(int newPositionIndex, int fallOffDelay) {
|
||||
_isPluggedIn = false;
|
||||
_newPositionIndex = newPositionIndex;
|
||||
_fallOffDelay = fallOffDelay;
|
||||
_parentScene->setPositionFree(_newPositionIndex, false);
|
||||
_x = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].x;
|
||||
_y = kAsScene1907SymbolPluggedInPositions[_currPositionIndex].y;
|
||||
_someX = _x;
|
||||
_someY = _y;
|
||||
startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, 0);
|
||||
_playBackwards = true;
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
_currStep = 0;
|
||||
_yAccel = 1;
|
||||
SetUpdateHandler(&AsScene1907Symbol::update);
|
||||
SetMessageHandler(&AsScene1907Symbol::handleMessage);
|
||||
SetSpriteUpdate(&AsScene1907Symbol::suFallOff);
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::stFallOffHitGround() {
|
||||
playSound(1);
|
||||
sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1000 + _newPositionIndex);
|
||||
Entity::_priority = 1000 - _newPositionIndex;
|
||||
_parentScene->removeCollisionSprite(this);
|
||||
_parentScene->addCollisionSprite(this);
|
||||
SetSpriteUpdate(&AsScene1907Symbol::suFallOffHitGround);
|
||||
NextState(&AsScene1907Symbol::cbFallOffHitGroundEvent);
|
||||
_newStickFrameIndex = 0;
|
||||
_currStep = 0;
|
||||
_yAccel = 30;
|
||||
_deltaX = (_x - kAsScene1907SymbolGroundPositions[_newPositionIndex].x) / 15;
|
||||
_xBreak = _deltaX * 15;
|
||||
_smallDeltaX = _x - kAsScene1907SymbolGroundPositions[_newPositionIndex].x - _xBreak;
|
||||
_someY = 0;
|
||||
if (kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y > kAsScene1907SymbolGroundPositions[_newPositionIndex].y)
|
||||
_someY = kAsScene1907SymbolGroundHitPositions[_currPositionIndex].y - kAsScene1907SymbolGroundPositions[_newPositionIndex].y;
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::cbFallOffHitGroundEvent() {
|
||||
_currPositionIndex = _newPositionIndex;
|
||||
if (_plugInTryCount > 0)
|
||||
_plugInTryCount--;
|
||||
startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene1907Symbol::handleMessage);
|
||||
SetSpriteUpdate(nullptr);
|
||||
updateBounds();
|
||||
playSound(2);
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::stPlugIn() {
|
||||
playSound(0);
|
||||
_currPositionIndex = _newPositionIndex;
|
||||
stopAnimation();
|
||||
SetMessageHandler(&AsScene1907Symbol::handleMessage);
|
||||
SetSpriteUpdate(nullptr);
|
||||
if (_elementIndex == 8)
|
||||
sendMessage(_parentScene, 0x2001, 0);
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::stPlugInFail() {
|
||||
_currPositionIndex = _newPositionIndex;
|
||||
stopAnimation();
|
||||
_parentScene->plugInFailed();
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::moveUp() {
|
||||
startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
|
||||
stopAnimation();
|
||||
SetMessageHandler(&AsScene1907Symbol::handleMessage);
|
||||
SetSpriteUpdate(&AsScene1907Symbol::suMoveUp);
|
||||
_yIncr = 1;
|
||||
_isMoving = true;
|
||||
}
|
||||
|
||||
void AsScene1907Symbol::moveDown() {
|
||||
startAnimation(kAsScene1907SymbolFileHashes[_elementIndex], -1, -1);
|
||||
stopAnimation();
|
||||
SetMessageHandler(&AsScene1907Symbol::handleMessage);
|
||||
SetSpriteUpdate(&AsScene1907Symbol::suMoveDown);
|
||||
_yIncr = 4;
|
||||
_isMoving = true;
|
||||
}
|
||||
|
||||
SsScene1907UpDownButton::SsScene1907UpDownButton(NeverhoodEngine *vm, Scene1907 *parentScene, AsScene1907Symbol *asScene1907Symbol)
|
||||
: StaticSprite(vm, 1400), _parentScene(parentScene), _asScene1907Symbol(asScene1907Symbol),
|
||||
_countdown1(0) {
|
||||
|
||||
loadSprite(0x64516424, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 1400);
|
||||
setVisible(false);
|
||||
loadSound(0, 0x44061000);
|
||||
SetUpdateHandler(&SsScene1907UpDownButton::update);
|
||||
SetMessageHandler(&SsScene1907UpDownButton::handleMessage);
|
||||
if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
|
||||
if (getGlobalVar(V_STAIRS_DOWN))
|
||||
setToDownPosition();
|
||||
else
|
||||
setToUpPosition();
|
||||
}
|
||||
}
|
||||
|
||||
void SsScene1907UpDownButton::update() {
|
||||
updatePosition();
|
||||
if (_countdown1 != 0 && (--_countdown1 == 0)) {
|
||||
setVisible(false);
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SsScene1907UpDownButton::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (_countdown1 == 0 && !_asScene1907Symbol->isMoving() && getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) {
|
||||
setVisible(true);
|
||||
_countdown1 = 4;
|
||||
updatePosition();
|
||||
playSound(0);
|
||||
}
|
||||
messageResult = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void SsScene1907UpDownButton::setToUpPosition() {
|
||||
_y = _spriteResource.getPosition().y;
|
||||
updateBounds();
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
void SsScene1907UpDownButton::setToDownPosition() {
|
||||
_y = _spriteResource.getPosition().y + 174;
|
||||
updateBounds();
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
AsScene1907WaterHint::AsScene1907WaterHint(NeverhoodEngine *vm)
|
||||
: AnimatedSprite(vm, 1400) {
|
||||
|
||||
createSurface1(0x110A1061, 1500);
|
||||
_x = 320;
|
||||
_y = 240;
|
||||
startAnimation(0x110A1061, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
setVisible(false);
|
||||
_needRefresh = true;
|
||||
AnimatedSprite::updatePosition();
|
||||
SetUpdateHandler(&AsScene1907WaterHint::update);
|
||||
SetMessageHandler(&Sprite::handleMessage);
|
||||
}
|
||||
|
||||
void AsScene1907WaterHint::update() {
|
||||
updateAnim();
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
uint32 AsScene1907WaterHint::hmShowing(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene1907WaterHint::show() {
|
||||
setVisible(true);
|
||||
startAnimation(0x110A1061, 0, -1);
|
||||
SetMessageHandler(&AsScene1907WaterHint::hmShowing);
|
||||
NextState(&AsScene1907WaterHint::hide);
|
||||
}
|
||||
|
||||
void AsScene1907WaterHint::hide() {
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
SetMessageHandler(&Sprite::handleMessage);
|
||||
}
|
||||
|
||||
KmScene1901::KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene1901::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
switch (messageNum) {
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
GotoState(&Klaymen::stTurnToUse);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
GotoState(&Klaymen::stReturnFromUse);
|
||||
break;
|
||||
case 0x482D:
|
||||
setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
106
engines/neverhood/modules/module1900_sprites.h
Normal file
106
engines/neverhood/modules/module1900_sprites.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE1900_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE1900_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Scene1907;
|
||||
|
||||
class AsScene1907Symbol : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1907Symbol(NeverhoodEngine *vm, Scene1907 *parentScene, int elementIndex, int positionIndex);
|
||||
void moveUp();
|
||||
void moveDown();
|
||||
void fallOff(int newPositionIndex, int fallOffDelay);
|
||||
bool isPluggedIn() { return _isPluggedIn; }
|
||||
bool isMoving() { return _isMoving; }
|
||||
protected:
|
||||
Scene1907 *_parentScene;
|
||||
int _elementIndex;
|
||||
int _currPositionIndex;
|
||||
int _newPositionIndex;
|
||||
bool _isPluggedIn;
|
||||
bool _isMoving;
|
||||
int _someX, _someY;
|
||||
int _xBreak;
|
||||
int _currStep;
|
||||
int _yAccel;
|
||||
int _yIncr;
|
||||
int _fallOffDelay;
|
||||
int _deltaX, _smallDeltaX;
|
||||
int _deltaY, _smallDeltaY;
|
||||
// Dumb, change if possible
|
||||
static bool _plugInFailed;
|
||||
static int _plugInTryCount;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmTryToPlugIn(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suTryToPlugIn();
|
||||
void suFallOff();
|
||||
void suFallOffHitGround();
|
||||
void suMoveDown();
|
||||
void suMoveUp();
|
||||
void tryToPlugIn();
|
||||
void stFallOffHitGround();
|
||||
void cbFallOffHitGroundEvent();
|
||||
void stPlugIn();
|
||||
void stPlugInFail();
|
||||
};
|
||||
|
||||
class AsScene1907WaterHint : public AnimatedSprite {
|
||||
public:
|
||||
AsScene1907WaterHint(NeverhoodEngine *vm);
|
||||
void show();
|
||||
protected:
|
||||
void update();
|
||||
uint32 hmShowing(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void hide();
|
||||
};
|
||||
|
||||
class SsScene1907UpDownButton : public StaticSprite {
|
||||
public:
|
||||
SsScene1907UpDownButton(NeverhoodEngine *vm, Scene1907 *parentScene, AsScene1907Symbol *asScene1907Symbol);
|
||||
void setToUpPosition();
|
||||
void setToDownPosition();
|
||||
protected:
|
||||
Scene1907 *_parentScene;
|
||||
AsScene1907Symbol *_asScene1907Symbol;
|
||||
int _countdown1;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene1901 : public Klaymen {
|
||||
public:
|
||||
KmScene1901(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE1900_SPRITES_H */
|
||||
165
engines/neverhood/modules/module2000.cpp
Normal file
165
engines/neverhood/modules/module2000.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module2000.h"
|
||||
#include "neverhood/modules/module2000_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
Module2000::Module2000(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else if (which == 0)
|
||||
createScene(0, 1);
|
||||
else if (which == 1)
|
||||
createScene(0, 3);
|
||||
|
||||
}
|
||||
|
||||
Module2000::~Module2000() {
|
||||
_vm->_soundMan->deleteGroup(0x81293110);
|
||||
}
|
||||
|
||||
void Module2000::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module2000::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_childObject = new Scene2001(_vm, this, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
createNavigationScene(getGlobalVar(V_WORLDS_JOINED) ? 0x004B7B48 : 0x004B7B00, which);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
setGlobalVar(V_WORLDS_JOINED, 1);
|
||||
setSubVar(V_TELEPORTER_DEST_AVAILABLE, 1, 1);
|
||||
createSmackerScene(0x204B2031, true, true, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module2000::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module2000::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1)
|
||||
leaveModule(0);
|
||||
else
|
||||
createScene(1, 0);
|
||||
break;
|
||||
case 1:
|
||||
if (_moduleResult == 0) {
|
||||
if (getGlobalVar(V_WORLDS_JOINED))
|
||||
createScene(1, 0);
|
||||
else
|
||||
createScene(2, -1);
|
||||
} else if (_moduleResult == 1)
|
||||
createScene(1, 1);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(0, 0);
|
||||
break;
|
||||
case 2:
|
||||
createScene(1, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scene2001
|
||||
|
||||
Scene2001::Scene2001(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule) {
|
||||
|
||||
Sprite *tempSprite;
|
||||
|
||||
SetMessageHandler(&Scene2001::handleMessage);
|
||||
|
||||
setBackground(0xA6417244);
|
||||
setPalette(0xA6417244);
|
||||
insertScreenMouse(0x17240A6C);
|
||||
|
||||
tempSprite = insertStaticSprite(0x0D641724, 1100);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene2001>(300, 345);
|
||||
setMessageList(0x004B3538);
|
||||
sendMessage(this, 0x2000, 0);
|
||||
} else if (which == 1) {
|
||||
// Klaymen teleporting in
|
||||
insertKlaymen<KmScene2001>(116, 345);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B3540, false);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
} else if (which == 2) {
|
||||
// Klaymen teleporting out
|
||||
insertKlaymen<KmScene2001>(116, 345);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B35F0, false);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
} else if (which == 3) {
|
||||
// Klaymen returning from teleporter console
|
||||
insertKlaymen<KmScene2001>(116, 345);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B3550, false);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
} else {
|
||||
// Klaymen standing around
|
||||
insertKlaymen<KmScene2001>(390, 345);
|
||||
setMessageList(0x004B3530);
|
||||
sendMessage(this, 0x2000, 0);
|
||||
_klaymen->setDoDeltaX(1);
|
||||
}
|
||||
|
||||
_klaymen->setClipRect(tempSprite->getDrawRect().x, 0, 640, 480);
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene2001::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (param.asInteger()) {
|
||||
setRectList(0x004B3680);
|
||||
_klaymen->setKlaymenIdleTable3();
|
||||
} else {
|
||||
setRectList(0x004B3670);
|
||||
_klaymen->setKlaymenIdleTable1();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
51
engines/neverhood/modules/module2000.h
Normal file
51
engines/neverhood/modules/module2000.h
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2000_H
|
||||
#define NEVERHOOD_MODULES_MODULE2000_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module2000 : public Module {
|
||||
public:
|
||||
Module2000(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module2000() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class Scene2001 : public Scene {
|
||||
public:
|
||||
Scene2001(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2000_H */
|
||||
93
engines/neverhood/modules/module2000_sprites.cpp
Normal file
93
engines/neverhood/modules/module2000_sprites.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module2000_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
KmScene2001::KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene2001::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isSittingInTeleporter = param.asInteger() != 0;
|
||||
messageResult = 1;
|
||||
break;
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stSitIdleTeleporter);
|
||||
else
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x4804:
|
||||
if (param.asInteger() != 0) {
|
||||
_destX = param.asInteger();
|
||||
GotoState(&Klaymen::stWalkingFirst);
|
||||
} else
|
||||
GotoState(&Klaymen::stPeekWall);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stTurnToUseInTeleporter);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stReturnFromUseInTeleporter);
|
||||
break;
|
||||
case 0x4834:
|
||||
GotoState(&Klaymen::stStepOver);
|
||||
break;
|
||||
case 0x4835:
|
||||
sendMessage(_parentScene, 0x2000, 1);
|
||||
_isSittingInTeleporter = true;
|
||||
GotoState(&Klaymen::stSitInTeleporter);
|
||||
break;
|
||||
case 0x4836:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_isSittingInTeleporter = false;
|
||||
GotoState(&Klaymen::stGetUpFromTeleporter);
|
||||
break;
|
||||
case 0x483D:
|
||||
teleporterAppear(0xBE68CC54);
|
||||
break;
|
||||
case 0x483E:
|
||||
teleporterDisappear(0x18AB4ED4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
40
engines/neverhood/modules/module2000_sprites.h
Normal file
40
engines/neverhood/modules/module2000_sprites.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2000_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE2000_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class KmScene2001 : public Klaymen {
|
||||
public:
|
||||
KmScene2001(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2000_SPRITES_H */
|
||||
223
engines/neverhood/modules/module2100.cpp
Normal file
223
engines/neverhood/modules/module2100.cpp
Normal file
@@ -0,0 +1,223 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1200_sprites.h"
|
||||
#include "neverhood/modules/module2100.h"
|
||||
#include "neverhood/modules/module2100_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
Module2100::Module2100(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
_vm->_soundMan->addMusic(0x10A10C14, 0x11482B95);
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else if (which == 1)
|
||||
createScene(0, 0);
|
||||
else if (which == 2)
|
||||
createScene(0, 3);
|
||||
else
|
||||
createScene(0, 1);
|
||||
|
||||
}
|
||||
|
||||
Module2100::~Module2100() {
|
||||
_vm->_soundMan->deleteMusicGroup(0x10A10C14);
|
||||
}
|
||||
|
||||
void Module2100::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module2100::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_vm->_soundMan->startMusic(0x11482B95, 0, 1);
|
||||
_childObject = new Scene2101(_vm, this, which);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module2100::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module2100::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1) {
|
||||
setGlobalVar(V_DOOR_PASSED, 1);
|
||||
leaveModule(0);
|
||||
} else {
|
||||
leaveModule(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scene2101::Scene2101(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule) {
|
||||
|
||||
Sprite *tempSprite;
|
||||
|
||||
SetMessageHandler(&Scene2101::handleMessage);
|
||||
SetUpdateHandler(&Scene2101::update);
|
||||
|
||||
setBackground(0x44242305);
|
||||
setPalette(0x44242305);
|
||||
insertScreenMouse(0x4230144A);
|
||||
|
||||
insertStaticSprite(0x00502330, 1100);
|
||||
tempSprite = insertStaticSprite(0x78492010, 1100);
|
||||
_ssFloorButton = insertSprite<SsCommonFloorButton>(this, 0x72427010, 0x32423010, 200, 0);
|
||||
_asTape1 = insertSprite<AsScene1201Tape>(this, 18, 1100, 412, 443, 0x9148A011);
|
||||
addCollisionSprite(_asTape1);
|
||||
_asTape2 = insertSprite<AsScene1201Tape>(this, 11, 1100, 441, 443, 0x9048A093);
|
||||
addCollisionSprite(_asTape2);
|
||||
|
||||
if (which < 0) {
|
||||
insertKlaymen<KmScene2101>(380, 438);
|
||||
setMessageList(0x004B8E48);
|
||||
sendMessage(this, 0x2000, 0);
|
||||
_asDoor = insertSprite<AsScene2101Door>(false);
|
||||
_doorStatus = 1;
|
||||
_countdown1 = 0;
|
||||
} else if (which == 1) {
|
||||
// Klaymen entering from the right
|
||||
insertKlaymen<KmScene2101>(640, 438);
|
||||
setMessageList(0x004B8E50);
|
||||
sendMessage(this, 0x2000, 0);
|
||||
_asDoor = insertSprite<AsScene2101Door>(true);
|
||||
_doorStatus = 2;
|
||||
_countdown1 = 48;
|
||||
} else if (which == 2) {
|
||||
// Klaymen teleporting out
|
||||
insertKlaymen<KmScene2101>(115, 438);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B8F58);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
_asDoor = insertSprite<AsScene2101Door>(false);
|
||||
_doorStatus = 1;
|
||||
_countdown1 = 0;
|
||||
} else if (which == 3) {
|
||||
// Klaymen returning from the teleporter console
|
||||
insertKlaymen<KmScene2101>(115, 438);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B8EB0);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
_asDoor = insertSprite<AsScene2101Door>(false);
|
||||
_doorStatus = 1;
|
||||
_countdown1 = 0;
|
||||
} else {
|
||||
// Klaymen teleporting in
|
||||
insertKlaymen<KmScene2101>(115, 438);
|
||||
sendMessage(_klaymen, 0x2000, 1);
|
||||
setMessageList(0x004B8EA0);
|
||||
sendMessage(this, 0x2000, 1);
|
||||
_asDoor = insertSprite<AsScene2101Door>(false);
|
||||
_doorStatus = 1;
|
||||
_countdown1 = 0;
|
||||
}
|
||||
|
||||
_asHitByDoorEffect = insertSprite<AsScene2101HitByDoorEffect>(_klaymen);
|
||||
_klaymen->setClipRect(0, 0, tempSprite->getDrawRect().x2(), 480);
|
||||
|
||||
}
|
||||
|
||||
void Scene2101::update() {
|
||||
if (_countdown1 != 0) {
|
||||
if (_doorStatus == 2) {
|
||||
if (--_countdown1 == 0) {
|
||||
sendMessage(_asDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
|
||||
_doorStatus = 1;
|
||||
}
|
||||
} else {
|
||||
if (_klaymen->getX() > 575)
|
||||
_canAcceptInput = false;
|
||||
if (--_countdown1 == 0) {
|
||||
if (_klaymen->getX() < 480) {
|
||||
sendMessage(_asDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
|
||||
_doorStatus = 1;
|
||||
} else if (_klaymen->getX() >= 480 && _klaymen->getX() <= 575) {
|
||||
_klaymen->setDoDeltaX(0);
|
||||
setMessageList2(0x004B8F48);
|
||||
sendMessage(_asDoor, NM_KLAYMEN_CLOSE_DOOR, 0);
|
||||
sendMessage(_asHitByDoorEffect, 0x2001, 0);
|
||||
_doorStatus = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (_doorStatus == 1 && _messageValue >= 0 && _klaymen->getX() > 470 && !isMessageList2(0x004B8F48))
|
||||
setMessageList2(0x004B8F50);
|
||||
Scene::update();
|
||||
}
|
||||
|
||||
uint32 Scene2101::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x02144CB1)
|
||||
sendEntityMessage(_klaymen, 0x1014, _ssFloorButton);
|
||||
else if (param.asInteger() == 0x21E64A00) {
|
||||
if (_doorStatus == 0)
|
||||
setMessageList(0x004B8E80);
|
||||
else
|
||||
setMessageList(0x004B8EC8);
|
||||
} else if (param.asInteger() == 0x41442820)
|
||||
cancelMessageList();
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (param.asInteger() != 0) {
|
||||
setRectList(0x004B9008);
|
||||
_klaymen->setKlaymenIdleTable3();
|
||||
} else {
|
||||
setRectList(0x004B8FF8);
|
||||
_klaymen->setKlaymenIdleTable1();
|
||||
}
|
||||
break;
|
||||
case 0x480B:
|
||||
if (sender == _ssFloorButton && _doorStatus == 1) {
|
||||
sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
|
||||
_doorStatus = 0;
|
||||
_countdown1 = 90;
|
||||
}
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asTape1 || sender == _asTape2) {
|
||||
if (_klaymen->getX() >= 228 && _klaymen->getX() <= 500) {
|
||||
sendEntityMessage(_klaymen, 0x1014, sender);
|
||||
setMessageList(0x004B8F78);
|
||||
} else if (_klaymen->getX() < 228)
|
||||
setMessageList2(0x004B8F00);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
59
engines/neverhood/modules/module2100.h
Normal file
59
engines/neverhood/modules/module2100.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2100_H
|
||||
#define NEVERHOOD_MODULES_MODULE2100_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module2100 : public Module {
|
||||
public:
|
||||
Module2100(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module2100() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class Scene2101 : public Scene {
|
||||
public:
|
||||
Scene2101(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_ssFloorButton;
|
||||
Sprite *_asTape1;
|
||||
Sprite *_asTape2;
|
||||
Sprite *_asDoor;
|
||||
Sprite *_asHitByDoorEffect;
|
||||
int _countdown1;
|
||||
int _doorStatus;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2100_H */
|
||||
269
engines/neverhood/modules/module2100_sprites.cpp
Normal file
269
engines/neverhood/modules/module2100_sprites.cpp
Normal file
@@ -0,0 +1,269 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module2100_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
AsScene2101Door::AsScene2101Door(NeverhoodEngine *vm, bool isOpen)
|
||||
: AnimatedSprite(vm, 1100) {
|
||||
|
||||
createSurface(100, 328, 347);
|
||||
_x = 320;
|
||||
_y = 240;
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene2101Door::handleMessage);
|
||||
if (isOpen) {
|
||||
startAnimation(0x0C202B9C, -1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
} else
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
uint32 AsScene2101Door::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
case NM_KLAYMEN_OPEN_DOOR:
|
||||
stOpenDoor();
|
||||
break;
|
||||
case NM_KLAYMEN_CLOSE_DOOR:
|
||||
stCloseDoor();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene2101Door::stOpenDoor() {
|
||||
startAnimation(0x0C202B9C, 0, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
setVisible(true);
|
||||
playSound(0, calcHash("fxDoorOpen32"));
|
||||
}
|
||||
|
||||
void AsScene2101Door::stCloseDoor() {
|
||||
startAnimation(0xC222A8D4, 0, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
setVisible(true);
|
||||
playSound(0, calcHash("fxDoorClose32"));
|
||||
NextState(&AsScene2101Door::stCloseDoorDone);
|
||||
}
|
||||
|
||||
void AsScene2101Door::stCloseDoorDone() {
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
AsScene2101HitByDoorEffect::AsScene2101HitByDoorEffect(NeverhoodEngine *vm, Sprite *klaymen)
|
||||
: AnimatedSprite(vm, 1400), _klaymen(klaymen) {
|
||||
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene2101HitByDoorEffect::handleMessage);
|
||||
createSurface(1200, 88, 165);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
uint32 AsScene2101HitByDoorEffect::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x2001:
|
||||
_x = _klaymen->getX();
|
||||
_y = _klaymen->getY() - 132;
|
||||
startAnimation(0x0422255A, 0, -1);
|
||||
setVisible(true);
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
SsCommonFloorButton::SsCommonFloorButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash)
|
||||
: StaticSprite(vm, 1100), _parentScene(parentScene), _countdown(0),
|
||||
_fileHash1(fileHash1), _fileHash2(fileHash2), _soundFileHash(soundFileHash) {
|
||||
|
||||
SetUpdateHandler(&SsCommonFloorButton::update);
|
||||
SetMessageHandler(&SsCommonFloorButton::handleMessage);
|
||||
if (_soundFileHash == 0)
|
||||
_soundFileHash = 0x44141000;
|
||||
createSurface(1010, 61, 30);
|
||||
if (_fileHash1)
|
||||
loadSprite(_fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
|
||||
else
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
void SsCommonFloorButton::update() {
|
||||
if (_countdown != 0 && (--_countdown == 0)) {
|
||||
sendMessage(_parentScene, NM_PRIORITY_CHANGE, 1010);
|
||||
if (_fileHash1)
|
||||
loadSprite(_fileHash1, kSLFDefDrawOffset | kSLFDefPosition);
|
||||
else
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SsCommonFloorButton::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x480B:
|
||||
sendMessage(_parentScene, 0x480B, 0);
|
||||
setVisible(true);
|
||||
sendMessage(_parentScene, NM_PRIORITY_CHANGE, 990);
|
||||
loadSprite(_fileHash2, kSLFDefDrawOffset | kSLFDefPosition);
|
||||
_countdown = 16;
|
||||
playSound(0, _soundFileHash);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
KmScene2101::KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene2101::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isSittingInTeleporter = param.asInteger() != 0;
|
||||
messageResult = 1;
|
||||
break;
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stSitIdleTeleporter);
|
||||
else
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x4811:
|
||||
GotoState(&KmScene2101::stHitByDoor);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPickUpNeedle);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPickUpTube);
|
||||
else
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case NM_KLAYMEN_PRESS_BUTTON:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPressButton);
|
||||
else if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPressFloorButton);
|
||||
else
|
||||
GotoState(&Klaymen::stPressButtonSide);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stTurnToUseInTeleporter);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stReturnFromUseInTeleporter);
|
||||
break;
|
||||
case 0x4834:
|
||||
GotoState(&Klaymen::stStepOver);
|
||||
break;
|
||||
case 0x4835:
|
||||
sendMessage(_parentScene, 0x2000, 1);
|
||||
_isSittingInTeleporter = true;
|
||||
GotoState(&Klaymen::stSitInTeleporter);
|
||||
break;
|
||||
case 0x4836:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_isSittingInTeleporter = false;
|
||||
GotoState(&Klaymen::stGetUpFromTeleporter);
|
||||
break;
|
||||
case 0x483D:
|
||||
teleporterAppear(0xFF290E30);
|
||||
break;
|
||||
case 0x483E:
|
||||
teleporterDisappear(0x9A28CA1C);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 KmScene2101::hmHitByDoor(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = hmLowLevelAnimation(messageNum, param, sender);
|
||||
int16 speedUpFrameIndex;
|
||||
switch (messageNum) {
|
||||
case 0x1008:
|
||||
speedUpFrameIndex = getFrameIndex(kKlaymenSpeedUpHash);
|
||||
if (_currFrameIndex < speedUpFrameIndex) {
|
||||
startAnimation(0x35AA8059, speedUpFrameIndex, -1);
|
||||
_y = 438;
|
||||
}
|
||||
messageResult = 0;
|
||||
break;
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x1A1A0785) {
|
||||
playSound(0, 0x40F0A342);
|
||||
} else if (param.asInteger() == 0x60428026) {
|
||||
playSound(0, 0x40608A59);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void KmScene2101::stHitByDoor() {
|
||||
_busyStatus = 1;
|
||||
_acceptInput = false;
|
||||
startAnimation(0x35AA8059, 0, -1);
|
||||
SetUpdateHandler(&Klaymen::update);
|
||||
SetMessageHandler(&KmScene2101::hmHitByDoor);
|
||||
SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
|
||||
playSound(0, 0x402E82D4);
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
74
engines/neverhood/modules/module2100_sprites.h
Normal file
74
engines/neverhood/modules/module2100_sprites.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2100_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE2100_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class AsScene2101Door : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2101Door(NeverhoodEngine *vm, bool isOpen);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stOpenDoor();
|
||||
void stCloseDoor();
|
||||
void stCloseDoorDone();
|
||||
};
|
||||
|
||||
class AsScene2101HitByDoorEffect : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2101HitByDoorEffect(NeverhoodEngine *vm, Sprite *klaymen);
|
||||
protected:
|
||||
Sprite *_klaymen;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class SsCommonFloorButton : public StaticSprite {
|
||||
public:
|
||||
SsCommonFloorButton(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int surfacePriority, uint32 soundFileHash);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 _soundFileHash;
|
||||
uint32 _fileHash1, _fileHash2;
|
||||
int16 _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene2101 : public Klaymen {
|
||||
public:
|
||||
KmScene2101(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
|
||||
void stHitByDoor();
|
||||
uint32 hmHitByDoor(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2100_SPRITES_H */
|
||||
1771
engines/neverhood/modules/module2200.cpp
Normal file
1771
engines/neverhood/modules/module2200.cpp
Normal file
File diff suppressed because it is too large
Load Diff
201
engines/neverhood/modules/module2200.h
Normal file
201
engines/neverhood/modules/module2200.h
Normal file
@@ -0,0 +1,201 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2200_H
|
||||
#define NEVERHOOD_MODULES_MODULE2200_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
#include "neverhood/modules/module1000.h"
|
||||
#include "neverhood/graphics.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module2200 : public Module {
|
||||
public:
|
||||
Module2200(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module2200() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
void createHallOfRecordsScene(int which, uint32 hallOfRecordsInfoId);
|
||||
bool shouldSkipHall();
|
||||
};
|
||||
|
||||
class Scene2201 : public Scene {
|
||||
public:
|
||||
Scene2201(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2201() override;
|
||||
protected:
|
||||
NRect _clipRects[2];
|
||||
Sprite *_ssDoorLight;
|
||||
Sprite *_asDoor;
|
||||
Sprite *_ssDoorButton;
|
||||
Sprite *_asTape;
|
||||
bool _isSoundPlaying;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2202 : public Scene {
|
||||
public:
|
||||
Scene2202(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2202() override;
|
||||
protected:
|
||||
Sprite *_ssMovingCube;
|
||||
Sprite *_ssDoneMovingCube;
|
||||
bool _isCubeMoving;
|
||||
int16 _movingCubePosition;
|
||||
int _surfacePriority;
|
||||
bool _leaveScene;
|
||||
bool _isSolved;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
int16 getFreeCubePosition(int16 index);
|
||||
bool testIsSolved();
|
||||
};
|
||||
|
||||
class Scene2203 : public Scene {
|
||||
public:
|
||||
Scene2203(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2203() override;
|
||||
protected:
|
||||
Sprite *_asLeftDoor;
|
||||
Sprite *_asRightDoor;
|
||||
Sprite *_ssSmallLeftDoor;
|
||||
Sprite *_ssSmallRightDoor;
|
||||
Sprite *_asTape;
|
||||
Sprite *_asKey;
|
||||
NRect _leftDoorClipRect;
|
||||
NRect _rightDoorClipRect;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class SsCommonPressButton;
|
||||
|
||||
class Scene2205 : public Scene {
|
||||
public:
|
||||
Scene2205(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
SsCommonPressButton *_ssLightSwitch;
|
||||
Sprite *_ssDoorFrame;
|
||||
bool _isKlaymenInLight;
|
||||
bool _isLightOn;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2206 : public Scene {
|
||||
public:
|
||||
Scene2206(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2206() override;
|
||||
protected:
|
||||
Sprite *_sprite1;
|
||||
Sprite *_sprite2;
|
||||
Sprite *_sprite3;
|
||||
Sprite *_asDoorSpikes;
|
||||
Sprite *_ssButton;
|
||||
Sprite *_asPlatform;
|
||||
Sprite *_ssTestTube;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void klaymenInFrontSpikes();
|
||||
void klaymenBehindSpikes();
|
||||
void readClickedColumn();
|
||||
};
|
||||
|
||||
class Scene2207 : public Scene {
|
||||
public:
|
||||
Scene2207(NeverhoodEngine *vm, Module *parentModule);
|
||||
protected:
|
||||
Sprite *_asElevator;
|
||||
Sprite *_ssMaskPart1;
|
||||
Sprite *_ssMaskPart2;
|
||||
Sprite *_ssMaskPart3;
|
||||
Sprite *_asTape;
|
||||
Sprite *_asLever;
|
||||
Sprite *_asWallRobotAnimation;
|
||||
Sprite *_asWallCannonAnimation;
|
||||
Sprite *_ssButton;
|
||||
int _elevatorSurfacePriority;
|
||||
bool _klaymenAtElevator;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 handleMessage2(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2208 : public Scene {
|
||||
public:
|
||||
Scene2208(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2208() override;
|
||||
protected:
|
||||
FontSurface *_fontSurface;
|
||||
BaseSurface *_backgroundSurface;
|
||||
BaseSurface *_topBackgroundSurface;
|
||||
BaseSurface *_bottomBackgroundSurface;
|
||||
TextResource _textResource;
|
||||
int16 _backgroundScrollY;
|
||||
int16 _newRowIndex;
|
||||
int16 _currRowIndex;
|
||||
int16 _rowScrollY;
|
||||
int16 _maxRowIndex;
|
||||
int16 _visibleRowsCount;
|
||||
Common::Array<const char*> _strings;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void drawRow(int16 rowIndex);
|
||||
};
|
||||
|
||||
class Scene2242 : public Scene {
|
||||
public:
|
||||
Scene2242(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2242() override;
|
||||
protected:
|
||||
Sprite *_asTape;
|
||||
bool _isKlaymenInLight;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void readClickedColumn();
|
||||
};
|
||||
|
||||
class HallOfRecordsScene : public Scene {
|
||||
public:
|
||||
HallOfRecordsScene(NeverhoodEngine *vm, Module *parentModule, int which, uint32 hallOfRecordsInfoId);
|
||||
~HallOfRecordsScene() override;
|
||||
protected:
|
||||
HallOfRecordsInfo *_hallOfRecordsInfo;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void readClickedColumn();
|
||||
};
|
||||
|
||||
class Scene2247 : public Scene {
|
||||
public:
|
||||
Scene2247(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2247() override;
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void readClickedColumn();
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2200_H */
|
||||
1471
engines/neverhood/modules/module2200_sprites.cpp
Normal file
1471
engines/neverhood/modules/module2200_sprites.cpp
Normal file
File diff suppressed because it is too large
Load Diff
274
engines/neverhood/modules/module2200_sprites.h
Normal file
274
engines/neverhood/modules/module2200_sprites.h
Normal file
@@ -0,0 +1,274 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2200_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE2200_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
#include "neverhood/graphics.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const NPoint kSsScene2201PuzzleCubePoints[] = {
|
||||
{305, 305}, {321, 305}, {336, 305}, {305, 319},
|
||||
{321, 319}, {336, 319}, {305, 332}, {321, 332},
|
||||
{336, 333}
|
||||
};
|
||||
|
||||
static const uint32 kSsScene2201PuzzleCubeFileHashes[] = {
|
||||
0x88134A44, 0xAA124340, 0xB8124602, 0xA902464C,
|
||||
0x890A4244, 0xA8124642, 0xB812C204, 0x381A4A4C
|
||||
};
|
||||
|
||||
class AsScene2201CeilingFan : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2201CeilingFan(NeverhoodEngine *vm);
|
||||
};
|
||||
|
||||
class AsScene2201Door : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2201Door(NeverhoodEngine *vm, Klaymen *klaymen, Sprite *ssDoorLight, bool isOpen);
|
||||
protected:
|
||||
Klaymen *_klaymen;
|
||||
Sprite *_ssDoorLight;
|
||||
bool _isOpen;
|
||||
int _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stOpenDoor();
|
||||
void stCloseDoor();
|
||||
};
|
||||
|
||||
class SsScene2201PuzzleCube : public StaticSprite {
|
||||
public:
|
||||
SsScene2201PuzzleCube(NeverhoodEngine *vm, uint32 positionIndex, uint32 cubeIndex);
|
||||
};
|
||||
|
||||
class SsScene2202PuzzleCube : public StaticSprite {
|
||||
public:
|
||||
SsScene2202PuzzleCube(NeverhoodEngine *vm, Scene *parentScene, int16 cubePosition, int16 cubeSymbol);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int16 _cubeSymbol;
|
||||
int16 _cubePosition;
|
||||
int16 _newX, _newY;
|
||||
int16 _xDelta, _yDelta;
|
||||
int16 _xIncr;
|
||||
int16 _yIncr;
|
||||
int16 _errValue;
|
||||
int16 _counter;
|
||||
int16 _xFlagPos;
|
||||
bool _counterDirection;
|
||||
bool _isMoving;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suMoveCubeX();
|
||||
void suMoveCubeY();
|
||||
void moveCube(int16 newCubePosition);
|
||||
void stopMoving();
|
||||
};
|
||||
|
||||
class AsCommonKey : public AnimatedSprite {
|
||||
public:
|
||||
AsCommonKey(NeverhoodEngine *vm, Scene *parentScene, int keyIndex, int surfacePriority, int16 x, int16 y);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _keyIndex;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2203Door : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2203Door(NeverhoodEngine *vm, Scene *parentScene, uint doorIndex);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
Sprite *_otherDoor;
|
||||
uint _doorIndex;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void openDoor();
|
||||
void closeDoor();
|
||||
};
|
||||
|
||||
class SsScene2205DoorFrame : public StaticSprite {
|
||||
public:
|
||||
SsScene2205DoorFrame(NeverhoodEngine *vm);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2206DoorSpikes : public StaticSprite {
|
||||
public:
|
||||
AsScene2206DoorSpikes(NeverhoodEngine *vm, uint32 fileHash);
|
||||
protected:
|
||||
int _deltaIndex;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suOpen();
|
||||
void suClose();
|
||||
};
|
||||
|
||||
class AsScene2206Platform : public StaticSprite {
|
||||
public:
|
||||
AsScene2206Platform(NeverhoodEngine *vm, uint32 fileHash);
|
||||
protected:
|
||||
int16 _yDelta;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suMoveDown();
|
||||
};
|
||||
|
||||
class SsScene2206TestTube : public StaticSprite {
|
||||
public:
|
||||
SsScene2206TestTube(NeverhoodEngine *vm, Scene *parentScene, int surfacePriority, uint32 fileHash);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2207Elevator : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2207Elevator(NeverhoodEngine *vm, Scene *parentScene);
|
||||
~AsScene2207Elevator() override;
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
NPointArray *_pointArray;
|
||||
int16 _pointIndex;
|
||||
int16 _destPointIndex, _destPointIndexDelta;
|
||||
bool _isMoving;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void suSetPosition();
|
||||
void moveToY(int16 y);
|
||||
};
|
||||
|
||||
class AsScene2207Lever : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2207Lever(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, int doDeltaX);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stLeverDown();
|
||||
void stLeverDownEvent();
|
||||
void stLeverUp();
|
||||
void stLeverUpEvent();
|
||||
};
|
||||
|
||||
class AsScene2207WallRobotAnimation : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2207WallRobotAnimation(NeverhoodEngine *vm, Scene *parentScene);
|
||||
~AsScene2207WallRobotAnimation() override;
|
||||
protected:
|
||||
bool _idle;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stStartAnimation();
|
||||
void stStopAnimation();
|
||||
void cbStopAnimation();
|
||||
};
|
||||
|
||||
class AsScene2207WallCannonAnimation : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2207WallCannonAnimation(NeverhoodEngine *vm);
|
||||
protected:
|
||||
bool _idle;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stStartAnimation();
|
||||
void stStopAnimation();
|
||||
void cbStopAnimation();
|
||||
};
|
||||
|
||||
class SsScene2207Symbol : public StaticSprite {
|
||||
public:
|
||||
SsScene2207Symbol(NeverhoodEngine *vm, uint32 fileHash, int index);
|
||||
};
|
||||
|
||||
class KmScene2201 : public Klaymen {
|
||||
public:
|
||||
KmScene2201(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2203 : public Klaymen {
|
||||
public:
|
||||
KmScene2203(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void stClayDoorOpen();
|
||||
uint32 hmClayDoorOpen(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2205 : public Klaymen {
|
||||
public:
|
||||
KmScene2205(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void xUpdate() override;
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2206 : public Klaymen {
|
||||
public:
|
||||
KmScene2206(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
~KmScene2206() override;
|
||||
protected:
|
||||
void stRidePlatformDown();
|
||||
void suRidePlatformDown();
|
||||
|
||||
void xUpdate() override;
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2207 : public Klaymen {
|
||||
public:
|
||||
KmScene2207(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2242 : public Klaymen {
|
||||
public:
|
||||
KmScene2242(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void xUpdate() override;
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmHallOfRecords : public Klaymen {
|
||||
public:
|
||||
KmHallOfRecords(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void xUpdate() override;
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2247 : public Klaymen {
|
||||
public:
|
||||
KmScene2247(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
void xUpdate() override;
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2200_SPRITES_H */
|
||||
191
engines/neverhood/modules/module2300.cpp
Normal file
191
engines/neverhood/modules/module2300.cpp
Normal file
@@ -0,0 +1,191 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/navigationscene.h"
|
||||
#include "neverhood/modules/module2300.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kModule2300SoundList[] = {
|
||||
0x90805C50, 0x90804450, 0xB4005E60, 0x91835066,
|
||||
0x90E14440, 0x90F0D1C3, 0
|
||||
};
|
||||
|
||||
Module2300::Module2300(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule), _waterfallSoundVolume(0) {
|
||||
|
||||
_vm->_soundMan->addSoundList(0x1A214010, kModule2300SoundList);
|
||||
_vm->_soundMan->setSoundListParams(kModule2300SoundList, true, 50, 600, 10, 150);
|
||||
|
||||
_isWaterfallRunning = getGlobalVar(V_WALL_BROKEN) != 1;
|
||||
|
||||
if (_isWaterfallRunning) {
|
||||
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 0);
|
||||
_vm->_soundMan->playSoundLooping(0x90F0D1C3);
|
||||
} else {
|
||||
_vm->_soundMan->setSoundParams(0x90F0D1C3, false, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
_vm->_soundMan->playTwoSounds(0x1A214010, 0x48498E46, 0x50399F64, 0);
|
||||
_vm->_soundMan->playTwoSounds(0x1A214010, 0x41861371, 0x43A2507F, 0);
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else if (which == 1)
|
||||
createScene(2, 0);
|
||||
else if (which == 2)
|
||||
createScene(3, 0);
|
||||
else if (which == 3)
|
||||
createScene(4, -1);
|
||||
else if (which == 4)
|
||||
createScene(1, 3);
|
||||
else
|
||||
createScene(0, 1);
|
||||
|
||||
}
|
||||
|
||||
Module2300::~Module2300() {
|
||||
_vm->_soundMan->deleteGroup(0x1A214010);
|
||||
}
|
||||
|
||||
void Module2300::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module2300::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
createNavigationScene(0x004B67B8, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
createNavigationScene(0x004B67E8, which);
|
||||
if (_isWaterfallRunning) {
|
||||
_waterfallSoundVolume = 15;
|
||||
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 15);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
createNavigationScene(0x004B6878, which);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
if (getGlobalVar(V_WALL_BROKEN))
|
||||
createNavigationScene(0x004B68F0, which);
|
||||
else {
|
||||
_vm->_soundMan->setSoundVolume(0x90F0D1C3, _waterfallSoundVolume);
|
||||
createNavigationScene(0x004B68A8, which);
|
||||
if (_isWaterfallRunning) {
|
||||
_waterfallSoundVolume = 87;
|
||||
_vm->_soundMan->setSoundVolume(0x90F0D1C3, 87);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
_vm->_soundMan->setTwoSoundsPlayFlag(true);
|
||||
createSmackerScene(0x20080A0B, true, true, false);
|
||||
break;
|
||||
case 9999:
|
||||
createDemoScene();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module2300::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module2300::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1)
|
||||
createScene(1, 4);
|
||||
else
|
||||
leaveModule(0);
|
||||
break;
|
||||
case 1:
|
||||
if (_moduleResult == 1)
|
||||
createScene(0, 0);
|
||||
else if (_vm->isDemo() && !(_vm->isBigDemo() && _moduleResult == 4))
|
||||
createScene(9999, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(2, 1);
|
||||
else if (_moduleResult == 3)
|
||||
createScene(1, 3);
|
||||
else if (_moduleResult == 4)
|
||||
createScene(3, 1);
|
||||
else if (_moduleResult == 5)
|
||||
leaveModule(3);
|
||||
else
|
||||
leaveModule(4);
|
||||
break;
|
||||
case 2:
|
||||
if (_moduleResult == 1)
|
||||
leaveModule(1);
|
||||
else
|
||||
createScene(1, 5);
|
||||
break;
|
||||
case 3:
|
||||
if (_moduleResult == 1)
|
||||
leaveModule(2);
|
||||
else
|
||||
createScene(1, 1);
|
||||
break;
|
||||
case 4:
|
||||
_vm->_soundMan->setTwoSoundsPlayFlag(false);
|
||||
createScene(1, 2);
|
||||
break;
|
||||
case 9999:
|
||||
createScene(1, -1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (_sceneNum) {
|
||||
case 1:
|
||||
if (_isWaterfallRunning && navigationScene()->isWalkingForward() && navigationScene()->getNavigationIndex() == 4 &&
|
||||
navigationScene()->getFrameNumber() % 2) {
|
||||
_waterfallSoundVolume++;
|
||||
_vm->_soundMan->setSoundVolume(0x90F0D1C3, _waterfallSoundVolume);
|
||||
}
|
||||
if (navigationScene()->isWalkingForward() && navigationScene()->getNavigationIndex() == 0 &&
|
||||
navigationScene()->getFrameNumber() == 50) {
|
||||
_vm->_soundMan->playTwoSounds(0x1A214010, 0x48498E46, 0x50399F64, 0);
|
||||
_vm->_soundMan->setSoundVolume(0x48498E46, 70);
|
||||
_vm->_soundMan->setSoundVolume(0x50399F64, 70);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (_isWaterfallRunning && navigationScene()->isWalkingForward() && navigationScene()->getFrameNumber() % 2) {
|
||||
_waterfallSoundVolume--;
|
||||
_vm->_soundMan->setSoundVolume(0x90F0D1C3, _waterfallSoundVolume);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
47
engines/neverhood/modules/module2300.h
Normal file
47
engines/neverhood/modules/module2300.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2300_H
|
||||
#define NEVERHOOD_MODULES_MODULE2300_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Module2300
|
||||
|
||||
class Module2300 : public Module {
|
||||
public:
|
||||
Module2300(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module2300() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
int _waterfallSoundVolume;
|
||||
bool _isWaterfallRunning;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2300_H */
|
||||
675
engines/neverhood/modules/module2400.cpp
Normal file
675
engines/neverhood/modules/module2400.cpp
Normal file
@@ -0,0 +1,675 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1000_sprites.h"
|
||||
#include "neverhood/modules/module1200_sprites.h"
|
||||
#include "neverhood/modules/module2400.h"
|
||||
#include "neverhood/modules/module2100_sprites.h"
|
||||
#include "neverhood/modules/module2200_sprites.h"
|
||||
#include "neverhood/modules/module2400_sprites.h"
|
||||
#include "neverhood/modules/module2800_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
Module2400::Module2400(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
_vm->_soundMan->addMusic(0x202D1010, 0xB110382D);
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else
|
||||
createScene(0, 0);
|
||||
|
||||
}
|
||||
|
||||
Module2400::~Module2400() {
|
||||
_vm->_soundMan->deleteMusicGroup(0x202D1010);
|
||||
}
|
||||
|
||||
void Module2400::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module2400::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_vm->_soundMan->stopMusic(0xB110382D, 0, 0);
|
||||
_childObject = new Scene2401(_vm, this, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
_vm->_soundMan->startMusic(0xB110382D, 0, 2);
|
||||
_childObject = new Scene2402(_vm, this, which);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
_vm->_soundMan->startMusic(0xB110382D, 0, 0);
|
||||
_childObject = new Scene2403(_vm, this, which);
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
_vm->_soundMan->stopMusic(0xB110382D, 0, 2);
|
||||
_childObject = new DiskplayerScene(_vm, this, 0);
|
||||
break;
|
||||
case 5:
|
||||
_vm->gameState().sceneNum = 5;
|
||||
_vm->_soundMan->startMusic(0xB110382D, 0, 2);
|
||||
_childObject = new Scene2406(_vm, this, which);
|
||||
break;
|
||||
case 6:
|
||||
_vm->gameState().sceneNum = 6;
|
||||
_vm->_soundMan->stopMusic(0xB110382D, 0, 2);
|
||||
createSmackerScene(0x20D80001, true, true, false);
|
||||
break;
|
||||
case 7:
|
||||
_vm->gameState().sceneNum = 7;
|
||||
createStaticScene(0x81523218, 0x2321C81D);
|
||||
break;
|
||||
case 8:
|
||||
_vm->gameState().sceneNum = 8;
|
||||
createStaticScene(0x08100210, 0x00214089);
|
||||
break;
|
||||
case 9:
|
||||
_vm->gameState().sceneNum = 9;
|
||||
createStaticScene(0x8C020505, 0x205018C8);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module2400::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module2400::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1)
|
||||
createScene(1, 0);
|
||||
else
|
||||
leaveModule(0);
|
||||
break;
|
||||
case 1:
|
||||
if (_moduleResult == 1)
|
||||
createScene(5, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(7, -1);
|
||||
else
|
||||
createScene(0, 1);
|
||||
break;
|
||||
case 2:
|
||||
if (_moduleResult == 1)
|
||||
createScene(9, -1);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(6, -1);
|
||||
else
|
||||
createScene(5, 1);
|
||||
break;
|
||||
case 4:
|
||||
createScene(5, 2);
|
||||
break;
|
||||
case 5:
|
||||
if (_moduleResult == 1)
|
||||
createScene(2, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(4, 0);
|
||||
else if (_moduleResult == 3)
|
||||
createScene(8, -1);
|
||||
else
|
||||
createScene(1, 1);
|
||||
break;
|
||||
case 6:
|
||||
createScene(2, 2);
|
||||
break;
|
||||
case 7:
|
||||
createScene(1, 2);
|
||||
break;
|
||||
case 8:
|
||||
createScene(5, 3);
|
||||
break;
|
||||
case 9:
|
||||
createScene(2, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const NPoint kScene2401Points[] = {
|
||||
{384, 389}, {406, 389}, {429, 389},
|
||||
{453, 389}, {477, 389}
|
||||
};
|
||||
|
||||
static const uint32 kScene2401FileHashes1[] = {
|
||||
0x02842920, 0x02882920, 0x02902920,
|
||||
0x02A02920, 0x02C02920, 0x02002920,
|
||||
0x03802920, 0x00802920, 0x06802920,
|
||||
0x03842920
|
||||
};
|
||||
|
||||
static const uint32 kScene2401FileHashes2[] = {
|
||||
0xD0910020, 0xD0910038, 0xD0910008,
|
||||
0xD0910068, 0xD09100A8, 0
|
||||
};
|
||||
|
||||
static const NRect kScene2401Rects[] = {
|
||||
{ 369, 331, 394, 389 },
|
||||
{ 395, 331, 419, 389 },
|
||||
{ 420, 331, 441, 389 },
|
||||
{ 442, 331, 464, 389 },
|
||||
{ 465, 331, 491, 389 }
|
||||
};
|
||||
|
||||
Scene2401::Scene2401(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _countdown1(0), _countdown2(0), _unkFlag(false),
|
||||
_soundToggle(false), _asWaterSpitIndex(0) {
|
||||
|
||||
_vm->gameModule()->initWaterPipesPuzzle();
|
||||
|
||||
SetMessageHandler(&Scene2401::handleMessage);
|
||||
SetUpdateHandler(&Scene2401::update);
|
||||
|
||||
setRectList(0x004B3140);
|
||||
setBackground(0x8C030206);
|
||||
setPalette(0x8C030206);
|
||||
addEntity(_palette);
|
||||
_palette->addBasePalette(0x8C030206, 0, 256, 0);
|
||||
_palette->addPalette(0x91D3A391, 0, 65, 0);
|
||||
insertScreenMouse(0x302028C8);
|
||||
|
||||
_sprite1 = insertStaticSprite(0x2E068A23, 200);
|
||||
insertStaticSprite(0x401410A6, 200);
|
||||
_asFlowingWater = insertSprite<AsScene2401FlowingWater>();
|
||||
insertStaticSprite(0x90C0A4B4, 200);
|
||||
_ssButton = insertSprite<SsCommonButtonSprite>(this, 0x0092916A, 100, 0);
|
||||
_ssFloorButton = insertSprite<SsCommonFloorButton>(this, 0x28001120, 0x00911068, 100, 0);
|
||||
|
||||
for (uint i = 0; i < 5; i++)
|
||||
_asWaterFlushing[i] = insertSprite<AsScene2401WaterFlushing>(kScene2401Points[i].x, kScene2401Points[i].y);
|
||||
|
||||
for (uint i = 0; i < 10; i++) {
|
||||
_ssWaterPipes[i] = insertStaticSprite(kScene2401FileHashes1[i], 300);
|
||||
_ssWaterPipes[i]->setVisible(false);
|
||||
}
|
||||
|
||||
_asWaterSpit[0] = insertSprite<AsScene2401WaterSpit>();
|
||||
_asWaterSpit[1] = insertSprite<AsScene2401WaterSpit>();
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene2401>(200, 447);
|
||||
setMessageList(0x004B2F70);
|
||||
_asDoor = insertSprite<AsScene2401Door>(false);
|
||||
} else if (which == 1) {
|
||||
// Klaymen entering from the back
|
||||
insertKlaymen<KmScene2401>(280, 413);
|
||||
setMessageList(0x004B2F80);
|
||||
_palette->addBasePalette(0xB103B604, 0, 65, 0);
|
||||
_palette->addPalette(0xB103B604, 0, 65, 0);
|
||||
_asDoor = insertSprite<AsScene2401Door>(true);
|
||||
} else {
|
||||
// Klaymen entering from the left
|
||||
insertKlaymen<KmScene2401>(-20, 447);
|
||||
setMessageList(0x004B2F78);
|
||||
_asDoor = insertSprite<AsScene2401Door>(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Scene2401::update() {
|
||||
|
||||
if (_countdown1 != 0 && (--_countdown1) == 0) {
|
||||
if (_pipeStatus > 0 && _pipeStatus <= 10)
|
||||
_ssWaterPipes[_pipeStatus - 1]->setVisible(false);
|
||||
if (_pipeStatus >= 10) {
|
||||
bool puzzleSolved = true, waterInside = false;
|
||||
for (uint pipeIndex = 0; pipeIndex < 5; pipeIndex++) {
|
||||
if (getSubVar(VA_CURR_WATER_PIPES_LEVEL, pipeIndex) != getSubVar(VA_GOOD_WATER_PIPES_LEVEL, pipeIndex))
|
||||
puzzleSolved = false;
|
||||
if (getSubVar(VA_CURR_WATER_PIPES_LEVEL, pipeIndex) != 0)
|
||||
waterInside = true;
|
||||
}
|
||||
if (puzzleSolved) {
|
||||
setGlobalVar(V_NOTES_DOOR_UNLOCKED, 1);
|
||||
setGlobalVar(V_NOTES_PUZZLE_SOLVED, 1);
|
||||
sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
|
||||
} else if (waterInside) {
|
||||
playPipeSound(0xD0431020);
|
||||
for (uint i = 0; i < 5; i++) {
|
||||
sendMessage(_asWaterFlushing[i], NM_POSITION_CHANGE, getSubVar(VA_CURR_WATER_PIPES_LEVEL, i));
|
||||
setSubVar(VA_CURR_WATER_PIPES_LEVEL, i, 0);
|
||||
}
|
||||
}
|
||||
} else if (_pipeStatus >= 5) {
|
||||
_ssWaterPipes[_pipeStatus]->setVisible(true);
|
||||
_countdown1 = 8;
|
||||
playPipeSound(kScene2401FileHashes2[getSubVar(VA_CURR_WATER_PIPES_LEVEL, _pipeStatus - 5)]);
|
||||
} else {
|
||||
_ssWaterPipes[_pipeStatus]->setVisible(true);
|
||||
_countdown1 = _pipeStatus == 4 ? 16 : 8;
|
||||
playPipeSound(kScene2401FileHashes2[getSubVar(VA_GOOD_WATER_PIPES_LEVEL, _pipeStatus)]);
|
||||
}
|
||||
_pipeStatus++;
|
||||
}
|
||||
|
||||
if (_countdown2 != 0 && (--_countdown2) == 0)
|
||||
sendMessage(_asFlowingWater, 0x2003, 0);
|
||||
|
||||
Scene::update();
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene2401::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x402064D8)
|
||||
sendEntityMessage(_klaymen, 0x1014, _ssButton);
|
||||
else if (param.asInteger() == 0x02144CB1)
|
||||
sendEntityMessage(_klaymen, 0x1014, _ssFloorButton);
|
||||
else if (param.asInteger() == 0x11C40840) {
|
||||
if (getGlobalVar(V_NOTES_DOOR_UNLOCKED) && sendMessage(_asDoor, 0x2004, 0))
|
||||
setMessageList(0x004B3090);
|
||||
else
|
||||
setMessageList(0x004B30B0);
|
||||
} else if (param.asInteger() == 0x412722C0) {
|
||||
if (_countdown2 > 0 && getGlobalVar(V_HAS_TEST_TUBE)) {
|
||||
_countdown2 = 144;
|
||||
setMessageList(0x004B3020);
|
||||
} else
|
||||
setMessageList(0x004B3050);
|
||||
} else if (param.asInteger() == 0x21142050) {
|
||||
if (_unkFlag && _countdown1 == 0 && !getGlobalVar(V_NOTES_PUZZLE_SOLVED))
|
||||
setMessageList(0x004B2FA8);
|
||||
else
|
||||
setMessageList(0x004B2FC8);
|
||||
} else if (param.asInteger() == 0x87441031)
|
||||
setSurfacePriority(_sprite1->getSurface(), 1100);
|
||||
else if (param.asInteger() == 0x80C40322) {
|
||||
setSurfacePriority(_sprite1->getSurface(), 200);
|
||||
cancelMessageList();
|
||||
_unkFlag = true;
|
||||
} else if (param.asInteger() == 0x09C4B40A && _countdown2 > 12)
|
||||
_countdown2 = 12;
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
messageResult = 0;
|
||||
for (uint32 i = 0; i < 5; i++)
|
||||
if (kScene2401Rects[i].contains(_mouseClickPos.x, _mouseClickPos.y)) {
|
||||
messageResult = i;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x2001:
|
||||
sendMessage(_asWaterSpit[_asWaterSpitIndex], 0x2000, param.asInteger());
|
||||
_asWaterSpitIndex = (_asWaterSpitIndex + 1) & 1;
|
||||
incSubVar(VA_CURR_WATER_PIPES_LEVEL, param.asInteger(), 1);
|
||||
if (getSubVar(VA_CURR_WATER_PIPES_LEVEL, param.asInteger()) >= 5)
|
||||
setSubVar(VA_CURR_WATER_PIPES_LEVEL, param.asInteger(), 4);
|
||||
break;
|
||||
case 0x480B:
|
||||
if (sender == _ssButton) {
|
||||
_pipeStatus = 0;
|
||||
_countdown1 = 8;
|
||||
} else if (sender == _ssFloorButton && getGlobalVar(V_WATER_RUNNING)) {
|
||||
_countdown2 = 144;
|
||||
sendMessage(_asFlowingWater, NM_POSITION_CHANGE, 0);
|
||||
playSound(0, 0xE1130324);
|
||||
}
|
||||
break;
|
||||
case NM_MOVE_TO_BACK:
|
||||
_palette->addBasePalette(0xB103B604, 0, 65, 0);
|
||||
_palette->startFadeToPalette(12);
|
||||
break;
|
||||
case NM_MOVE_TO_FRONT:
|
||||
_palette->addBasePalette(0x91D3A391, 0, 65, 0);
|
||||
_palette->startFadeToPalette(12);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void Scene2401::playPipeSound(uint32 fileHash) {
|
||||
playSound(_soundToggle ? 0 : 1, fileHash);
|
||||
_soundToggle = !_soundToggle;
|
||||
}
|
||||
|
||||
static const uint32 kScene2402FileHashes[] = {
|
||||
0xD0910020, 0xD0910038, 0xD0910008,
|
||||
0xD0910068, 0xD09100A8
|
||||
};
|
||||
|
||||
Scene2402::Scene2402(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _countdown(0), _soundToggle(false) {
|
||||
|
||||
Sprite *tempSprite;
|
||||
|
||||
SetMessageHandler(&Scene2402::handleMessage);
|
||||
SetUpdateHandler(&Scene2402::update);
|
||||
|
||||
setRectList(0x004AF900);
|
||||
setBackground(0x81660220);
|
||||
setPalette(0x81660220);
|
||||
insertScreenMouse(0x6022481E);
|
||||
_asTape = insertSprite<AsScene1201Tape>(this, 9, 1100, 286, 409, 0x9148A011);
|
||||
addCollisionSprite(_asTape);
|
||||
_ssButton = insertSprite<SsCommonButtonSprite>(this, 0x15288120, 100, 0);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene2402>(198, 404);
|
||||
setMessageList(0x004AF7C8);
|
||||
} else if (which == 1) {
|
||||
// Klaymen entering from the right
|
||||
insertKlaymen<KmScene2402>(660, 404);
|
||||
setMessageList(0x004AF7D8);
|
||||
} else if (which == 2) {
|
||||
// Klaymen returning from looking through the window
|
||||
insertKlaymen<KmScene2402>(409, 404);
|
||||
_klaymen->setDoDeltaX(getGlobalVar(V_KLAYMEN_IS_DELTA_X) ? 1 : 0);
|
||||
setMessageList(0x004AF888);
|
||||
} else {
|
||||
// Klaymen entering from the left
|
||||
insertKlaymen<KmScene2402>(0, 404);
|
||||
setMessageList(0x004AF7D0);
|
||||
}
|
||||
|
||||
tempSprite = insertStaticSprite(0x081A60A8, 1100);
|
||||
_ssDoorFrame = (StaticSprite*)insertStaticSprite(0x406C0AE0, 1100);
|
||||
_klaymen->setClipRect(_ssDoorFrame->getDrawRect().x, 0, 639, tempSprite->getDrawRect().y2());
|
||||
_asDoor = insertSprite<AsScene2402Door>(this, which == 0);
|
||||
insertSprite<AsScene2402TV>(_klaymen);
|
||||
insertStaticSprite(0x3A01A020, 200);
|
||||
|
||||
}
|
||||
|
||||
Scene2402::~Scene2402() {
|
||||
setGlobalVar(V_KLAYMEN_IS_DELTA_X, _klaymen->isDoDeltaX() ? 1 : 0);
|
||||
}
|
||||
|
||||
void Scene2402::update() {
|
||||
if (_countdown != 0 && (--_countdown) == 0) {
|
||||
if (_pipeStatus >= 10) {
|
||||
sendMessage(_asDoor, NM_KLAYMEN_OPEN_DOOR, 0);
|
||||
_ssDoorFrame->loadSprite(0x00B415E0, kSLFDefDrawOffset | kSLFDefPosition);
|
||||
} else if (_pipeStatus >= 5) {
|
||||
_countdown = 8;
|
||||
playPipeSound(kScene2402FileHashes[getSubVar(VA_CURR_WATER_PIPES_LEVEL, _pipeStatus - 5)]);
|
||||
} else {
|
||||
_countdown = _pipeStatus == 4 ? 16 : 8;
|
||||
playPipeSound(kScene2402FileHashes[getSubVar(VA_GOOD_WATER_PIPES_LEVEL, _pipeStatus)]);
|
||||
}
|
||||
_pipeStatus++;
|
||||
}
|
||||
Scene::update();
|
||||
}
|
||||
|
||||
uint32 Scene2402::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x402064D8)
|
||||
sendEntityMessage(_klaymen, 0x1014, _ssButton);
|
||||
else if (param.asInteger() == 0x01C66840) {
|
||||
if (sendMessage(_asDoor, 0x2000, 0))
|
||||
setMessageList(0x004AF800);
|
||||
else
|
||||
setMessageList(0x004AF818);
|
||||
}
|
||||
break;
|
||||
case 0x2001:
|
||||
_ssDoorFrame->loadSprite(0x406C0AE0, kSLFDefDrawOffset | kSLFDefPosition);
|
||||
break;
|
||||
case 0x480B:
|
||||
if (sender == _ssButton) {
|
||||
_pipeStatus = 0;
|
||||
_countdown = 8;
|
||||
}
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asTape) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asTape);
|
||||
setMessageList(0x004AF890);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void Scene2402::playPipeSound(uint32 fileHash) {
|
||||
playSound(_soundToggle ? 0 : 1, fileHash);
|
||||
_soundToggle = !_soundToggle;
|
||||
}
|
||||
|
||||
Scene2403::Scene2403(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule) {
|
||||
|
||||
Sprite *tempSprite1, *tempSprite2, *tempSprite3;
|
||||
|
||||
SetMessageHandler(&Scene2403::handleMessage);
|
||||
setBackground(0x0C05060C);
|
||||
setPalette(0x0C05060C);
|
||||
_palette->addPalette(0x414364B0, 0, 65, 0);
|
||||
insertScreenMouse(0x506080C8);
|
||||
_asTape = insertSprite<AsScene1201Tape>(this, 2, 1100, 480, 454, 0x9148A011);
|
||||
addCollisionSprite(_asTape);
|
||||
_asLightCord = insertSprite<AsScene2803LightCord>(this, 0xA1095A10, 0x836D3813, 368, 200);
|
||||
_asLightCord->setClipRect(0, 25, 640, 480);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
_isClimbingLadder = false;
|
||||
insertKlaymen<KmScene2403>(220, 449);
|
||||
setMessageList(0x004B5C98);
|
||||
setRectList(0x004B5E18);
|
||||
} else if (which == 1) {
|
||||
// Klaymen returning from looking through the window
|
||||
_isClimbingLadder = false;
|
||||
insertKlaymen<KmScene2403>(433, 449);
|
||||
setMessageList(0x004B5D70);
|
||||
setRectList(0x004B5E18);
|
||||
} else if (which == 2) {
|
||||
// Klaymen standing around after the critter video
|
||||
_isClimbingLadder = false;
|
||||
insertKlaymen<KmScene2403>(440, 449);
|
||||
_klaymen->setDoDeltaX(1);
|
||||
setMessageList(0x004B5C98);
|
||||
setRectList(0x004B5E18);
|
||||
} else {
|
||||
// Klaymen coming up from ladder
|
||||
_isClimbingLadder = true;
|
||||
insertKlaymen<KmScene2403>(122, 599);
|
||||
setMessageList(0x004B5CA0);
|
||||
setRectList(0x004B5E28);
|
||||
}
|
||||
|
||||
_ssButton = insertSprite<SsCommonButtonSprite>(this, 0x3130B0EB, 100, 0);
|
||||
tempSprite1 = insertStaticSprite(0x20C24220, 1100);
|
||||
tempSprite2 = insertStaticSprite(0x03080900, 1300);
|
||||
tempSprite3 = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen);
|
||||
tempSprite3->setClipRect(tempSprite1->getDrawRect().x, 0, 640, tempSprite2->getDrawRect().y2());
|
||||
_klaymen->setClipRect(tempSprite1->getDrawRect().x, 0, 640, tempSprite2->getDrawRect().y2());
|
||||
loadSound(1, calcHash("fxFogHornSoft"));
|
||||
}
|
||||
|
||||
uint32 Scene2403::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x040424D0)
|
||||
sendEntityMessage(_klaymen, 0x1014, _ssButton);
|
||||
else if (param.asInteger() == 0x180CE614)
|
||||
sendEntityMessage(_klaymen, 0x1014, _asLightCord);
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isClimbingLadder = true;
|
||||
setRectList(0x004B5E28);
|
||||
break;
|
||||
case 0x2001:
|
||||
_isClimbingLadder = false;
|
||||
setRectList(0x004B5E18);
|
||||
break;
|
||||
case 0x480B:
|
||||
if (sender == _ssButton) {
|
||||
if (getSubVar(VA_LOCKS_DISABLED, 0x304008D2)) {
|
||||
setSubVar(VA_LOCKS_DISABLED, 0x304008D2, 0);
|
||||
playSound(0, calcHash("fx3LocksDisable"));
|
||||
} else {
|
||||
setSubVar(VA_LOCKS_DISABLED, 0x304008D2, 1);
|
||||
playSound(1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_KLAYMEN_LOWER_LEVER:
|
||||
if (sender == _asLightCord)
|
||||
leaveScene(2);
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asTape && !_isClimbingLadder) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asTape);
|
||||
setMessageList(0x004B5D98);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
Scene2406::Scene2406(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule) {
|
||||
|
||||
Sprite *tempSprite1, *tempSprite2;
|
||||
|
||||
if (getGlobalVar(V_HAS_FINAL_KEY) && getGlobalVar(V_KEY3_LOCATION) == 0)
|
||||
setGlobalVar(V_KEY3_LOCATION, 2);
|
||||
|
||||
SetMessageHandler(&Scene2406::handleMessage);
|
||||
|
||||
setRectList(0x004B78C8);
|
||||
insertScreenMouse(0xB03001A8);
|
||||
|
||||
if (getGlobalVar(V_KEY3_LOCATION) == 2) {
|
||||
_asKey = insertSprite<AsCommonKey>(this, 2, 1100, 560, 409);
|
||||
addCollisionSprite(_asKey);
|
||||
}
|
||||
|
||||
_asTape = insertSprite<AsScene1201Tape>(this, 5, 1100, 456, 409, 0x9148A011);
|
||||
addCollisionSprite(_asTape);
|
||||
tempSprite2 = insertStaticSprite(0x19625293, 1100);
|
||||
_clipRects[0].x1 = 0;
|
||||
_clipRects[0].y1 = 0;
|
||||
_clipRects[0].x2 = tempSprite2->getDrawRect().x2();
|
||||
_clipRects[0].y2 = 480;
|
||||
|
||||
if (getGlobalVar(V_SPIKES_RETRACTED)) {
|
||||
setBackground(0x1A0B0304);
|
||||
setPalette(0x1A0B0304);
|
||||
tempSprite1 = insertStaticSprite(0x32923922, 1100);
|
||||
} else {
|
||||
setBackground(0x0A038595);
|
||||
setPalette(0x0A038595);
|
||||
tempSprite1 = insertStaticSprite(0x1712112A, 1100);
|
||||
}
|
||||
|
||||
tempSprite2 = insertStaticSprite(0x22300924, 1300);
|
||||
_clipRects[1].x1 = tempSprite1->getDrawRect().x;
|
||||
_clipRects[1].y1 = tempSprite2->getDrawRect().y;
|
||||
_clipRects[1].x2 = 640;
|
||||
_clipRects[1].y2 = 480;
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
_isClimbingLadder = false;
|
||||
insertKlaymen<KmScene2406>(307, 404, _clipRects, 2);
|
||||
setMessageList(0x004B76C8);
|
||||
setRectList(0x004B78C8);
|
||||
} else if (which == 1) {
|
||||
// Klaymen coming down the ladder
|
||||
_isClimbingLadder = true;
|
||||
insertKlaymen<KmScene2406>(253, -16, _clipRects, 2);
|
||||
setMessageList(0x004B76D8);
|
||||
setRectList(0x004B78D8);
|
||||
} else if (which == 2) {
|
||||
// Klaymen returning from the diskplayer
|
||||
_isClimbingLadder = false;
|
||||
insertKlaymen<KmScene2406>(480, 404, _clipRects, 2);
|
||||
setMessageList(0x004B77C0);
|
||||
setRectList(0x004B78C8);
|
||||
} else if (which == 3) {
|
||||
// Klaymen returning from looking through the window
|
||||
_isClimbingLadder = false;
|
||||
insertKlaymen<KmScene2406>(387, 404, _clipRects, 2);
|
||||
setMessageList(0x004B7810);
|
||||
setRectList(0x004B78C8);
|
||||
} else {
|
||||
// Klaymen entering from the left
|
||||
_isClimbingLadder = false;
|
||||
insertKlaymen<KmScene2406>(0, 404, _clipRects, 2);
|
||||
setMessageList(0x004B76D0);
|
||||
setRectList(0x004B78C8);
|
||||
}
|
||||
|
||||
tempSprite2 = insertSprite<AsScene1002KlaymenLadderHands>(_klaymen);
|
||||
tempSprite2->setClipRect(_clipRects[1]);
|
||||
|
||||
}
|
||||
|
||||
uint32 Scene2406::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x41062804) {
|
||||
if (getGlobalVar(V_SPIKES_RETRACTED))
|
||||
setMessageList(0x004B7758);
|
||||
else
|
||||
setMessageList(0x004B7738);
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isClimbingLadder = true;
|
||||
setRectList(0x004B78D8);
|
||||
break;
|
||||
case 0x2001:
|
||||
_isClimbingLadder = false;
|
||||
setRectList(0x004B78C8);
|
||||
break;
|
||||
case 0x4826:
|
||||
if (sender == _asTape && !_isClimbingLadder) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asTape);
|
||||
setMessageList(0x004B77C8);
|
||||
} else if (sender == _asKey && !_isClimbingLadder) {
|
||||
sendEntityMessage(_klaymen, 0x1014, _asKey);
|
||||
setMessageList(0x004B77D8);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
111
engines/neverhood/modules/module2400.h
Normal file
111
engines/neverhood/modules/module2400.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2400_H
|
||||
#define NEVERHOOD_MODULES_MODULE2400_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
#include "neverhood/gamemodule.h"
|
||||
#include "neverhood/diskplayerscene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Module2400
|
||||
|
||||
class Module2400 : public Module {
|
||||
public:
|
||||
Module2400(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module2400() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2401 : public Scene {
|
||||
public:
|
||||
Scene2401(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_sprite1;
|
||||
Sprite *_asFlowingWater;
|
||||
Sprite *_ssButton;
|
||||
Sprite *_ssFloorButton;
|
||||
Sprite *_asWaterSpit[2];
|
||||
Sprite *_ssWaterPipes[10];
|
||||
Sprite *_asWaterFlushing[5];
|
||||
Sprite *_asDoor;
|
||||
bool _soundToggle;
|
||||
bool _unkFlag;
|
||||
int _countdown1;
|
||||
int _countdown2;
|
||||
int _pipeStatus;
|
||||
int _asWaterSpitIndex;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void playPipeSound(uint32 fileHash);
|
||||
};
|
||||
|
||||
class Scene2402 : public Scene {
|
||||
public:
|
||||
Scene2402(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2402() override;
|
||||
protected:
|
||||
Sprite *_asDoor;
|
||||
Sprite *_ssButton;
|
||||
Sprite *_asTape;
|
||||
StaticSprite *_ssDoorFrame;
|
||||
int _pipeStatus;
|
||||
int _countdown;
|
||||
bool _soundToggle;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void playPipeSound(uint32 fileHash);
|
||||
};
|
||||
|
||||
class Scene2403 : public Scene {
|
||||
public:
|
||||
Scene2403(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_ssButton;
|
||||
Sprite *_asTape;
|
||||
Sprite *_asKey;
|
||||
Sprite *_asLightCord;
|
||||
bool _isClimbingLadder;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2406 : public Scene {
|
||||
public:
|
||||
Scene2406(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
Sprite *_asTape;
|
||||
Sprite *_asKey;
|
||||
NRect _clipRects[2];
|
||||
bool _isClimbingLadder;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2400_H */
|
||||
762
engines/neverhood/modules/module2400_sprites.cpp
Normal file
762
engines/neverhood/modules/module2400_sprites.cpp
Normal file
@@ -0,0 +1,762 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module2400_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kAsScene2401WaterSpitFileHashes2[] = {
|
||||
0x5C044690, 0x5C644690, 0x5CA44690,
|
||||
0x5D244690, 0x5E244690
|
||||
};
|
||||
|
||||
static const uint32 kAsScene2401WaterSpitFileHashes1[] = {
|
||||
0xF4418408, 0xF4418808, 0xF4419008,
|
||||
0xF441A008, 0xCD4F8411
|
||||
};
|
||||
|
||||
AsScene2401WaterSpit::AsScene2401WaterSpit(NeverhoodEngine *vm)
|
||||
: AnimatedSprite(vm, 1200) {
|
||||
|
||||
_x = 240;
|
||||
_y = 447;
|
||||
createSurface(100, 146, 74);
|
||||
setVisible(false);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene2401WaterSpit::handleMessage);
|
||||
SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
|
||||
}
|
||||
|
||||
uint32 AsScene2401WaterSpit::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x120A0013)
|
||||
playSound(0, kAsScene2401WaterSpitFileHashes1[_soundIndex]);
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_x = 240;
|
||||
_y = 447;
|
||||
_soundIndex = getSubVar(VA_CURR_WATER_PIPES_LEVEL, param.asInteger());
|
||||
startAnimation(kAsScene2401WaterSpitFileHashes2[param.asInteger()], 0, -1);
|
||||
setVisible(true);
|
||||
playSound(0, 0x48640244);
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene2401FlowingWater::AsScene2401FlowingWater(NeverhoodEngine *vm)
|
||||
: AnimatedSprite(vm, 1200), _isWaterFlowing(false) {
|
||||
|
||||
_x = 88;
|
||||
_y = 421;
|
||||
createSurface1(0x10203116, 100);
|
||||
setVisible(false);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene2401FlowingWater::handleMessage);
|
||||
}
|
||||
|
||||
AsScene2401FlowingWater::~AsScene2401FlowingWater() {
|
||||
_vm->_soundMan->deleteSoundGroup(0x40F11C09);
|
||||
}
|
||||
|
||||
uint32 AsScene2401FlowingWater::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (_isWaterFlowing && param.asInteger() == 0x02421405)
|
||||
startAnimationByHash(0x10203116, 0x01084280, 0);
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
if (!_isWaterFlowing) {
|
||||
_vm->_soundMan->addSound(0x40F11C09, 0x980C1420);
|
||||
_vm->_soundMan->playSoundLooping(0x980C1420);
|
||||
startAnimation(0x10203116, 0, -1);
|
||||
setVisible(true);
|
||||
_isWaterFlowing = true;
|
||||
}
|
||||
break;
|
||||
case 0x2003:
|
||||
_vm->_soundMan->deleteSound(0x980C1420);
|
||||
_isWaterFlowing = false;
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene2401WaterFlushing::AsScene2401WaterFlushing(NeverhoodEngine *vm, int16 x, int16 y)
|
||||
: AnimatedSprite(vm, 1200), _countdown(0), _flushLoopCount(0) {
|
||||
|
||||
_x = x;
|
||||
_y = y;
|
||||
createSurface1(0xB8596884, 100);
|
||||
setVisible(false);
|
||||
SetUpdateHandler(&AsScene2401WaterFlushing::update);
|
||||
SetMessageHandler(&AsScene2401WaterFlushing::handleMessage);
|
||||
}
|
||||
|
||||
void AsScene2401WaterFlushing::update() {
|
||||
if (_countdown != 0 && (--_countdown) == 0) {
|
||||
setDoDeltaX(_vm->_rnd->getRandomNumber(1));
|
||||
startAnimation(0xB8596884, 0, -1);
|
||||
setVisible(true);
|
||||
}
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
uint32 AsScene2401WaterFlushing::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (_flushLoopCount > 0 && param.asInteger() == 0x02421405) {
|
||||
startAnimationByHash(0xB8596884, 0x01084280, 0);
|
||||
_flushLoopCount--;
|
||||
}
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
if (param.asInteger() > 0) {
|
||||
_flushLoopCount = param.asInteger() - 1;
|
||||
_countdown = _vm->_rnd->getRandomNumber(3) + 1;
|
||||
}
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene2401Door::AsScene2401Door(NeverhoodEngine *vm, bool isOpen)
|
||||
: AnimatedSprite(vm, 1100), _countdown(0), _isOpen(isOpen) {
|
||||
|
||||
_x = 320;
|
||||
_y = 240;
|
||||
createSurface1(0x44687810, 100);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
if (_isOpen) {
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
_countdown = 48;
|
||||
} else {
|
||||
startAnimation(0x44687810, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
}
|
||||
SetUpdateHandler(&AsScene2401Door::update);
|
||||
SetMessageHandler(&AsScene2401Door::handleMessage);
|
||||
}
|
||||
|
||||
void AsScene2401Door::update() {
|
||||
if (_isOpen && _countdown != 0 && (--_countdown) == 0) {
|
||||
_isOpen = false;
|
||||
setVisible(true);
|
||||
startAnimation(0x44687810, -1, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
_playBackwards = true;
|
||||
playSound(0, calcHash("fxDoorClose38"));
|
||||
}
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
uint32 AsScene2401Door::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x2004:
|
||||
if (_isOpen)
|
||||
_countdown = 168;
|
||||
messageResult = _isOpen ? 1 : 0;
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
case NM_KLAYMEN_OPEN_DOOR:
|
||||
if (!_isOpen) {
|
||||
_countdown = 168;
|
||||
_isOpen = true;
|
||||
setVisible(true);
|
||||
startAnimation(0x44687810, 0, -1);
|
||||
playSound(0, calcHash("fxDoorOpen38"));
|
||||
NextState(&AsScene2401Door::stDoorOpenFinished);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene2401Door::stDoorOpenFinished() {
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
AsScene2402Door::AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool isOpen)
|
||||
: AnimatedSprite(vm, 1100), _parentScene(parentScene), _isOpen(isOpen), _countdown(0) {
|
||||
|
||||
_x = 320;
|
||||
_y = 240;
|
||||
createSurface1(0x80495831, 100);
|
||||
if (_isOpen) {
|
||||
startAnimation(0x80495831, -1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
_countdown = 48;
|
||||
} else {
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
}
|
||||
SetUpdateHandler(&AsScene2402Door::update);
|
||||
SetMessageHandler(&AsScene2402Door::handleMessage);
|
||||
}
|
||||
|
||||
void AsScene2402Door::update() {
|
||||
if (_isOpen && _countdown != 0 && (--_countdown) == 0) {
|
||||
_isOpen = false;
|
||||
setVisible(true);
|
||||
startAnimation(0x80495831, -1, -1);
|
||||
_playBackwards = true;
|
||||
playSound(0, calcHash("fxDoorClose38"));
|
||||
NextState(&AsScene2402Door::stDoorClosingFinished);
|
||||
}
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
uint32 AsScene2402Door::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
if (_isOpen)
|
||||
_countdown = 144;
|
||||
messageResult = _isOpen ? 1 : 0;
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
case NM_KLAYMEN_OPEN_DOOR:
|
||||
_countdown = 144;
|
||||
_isOpen = true;
|
||||
setVisible(true);
|
||||
startAnimation(0x80495831, 0, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
playSound(0, calcHash("fxDoorOpen38"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void AsScene2402Door::stDoorClosingFinished() {
|
||||
sendMessage(_parentScene, 0x2001, 0);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
AsScene2402TV::AsScene2402TV(NeverhoodEngine *vm, Klaymen *klaymen)
|
||||
: AnimatedSprite(vm, 1100), _klaymen(klaymen), _countdown1(0), _countdown2(0) {
|
||||
|
||||
_x = 260;
|
||||
_y = 210;
|
||||
createSurface(100, 127, 90);
|
||||
setDoDeltaX(1);
|
||||
SetMessageHandler(&Sprite::handleMessage);
|
||||
if (!getGlobalVar(V_TV_JOKE_TOLD)) {
|
||||
loadSound(0, 0x58208810);
|
||||
_countdown1 = 48;
|
||||
startAnimation(0x4919397A, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
SetUpdateHandler(&AsScene2402TV::upWait);
|
||||
} else {
|
||||
int16 frameIndex;
|
||||
if (_klaymen->getX() > 320)
|
||||
_currFrameIndex = 29;
|
||||
frameIndex = CLIP<int16>((_klaymen->getX() - _x + 150) / 10, 0, 29);
|
||||
startAnimation(0x050A0103, frameIndex, -1);
|
||||
_newStickFrameIndex = frameIndex;
|
||||
_countdown1 = 0;
|
||||
SetUpdateHandler(&AsScene2402TV::upFocusKlaymen);
|
||||
}
|
||||
}
|
||||
|
||||
AsScene2402TV::~AsScene2402TV() {
|
||||
_vm->_soundMan->deleteSoundGroup(0x01520123);
|
||||
}
|
||||
|
||||
void AsScene2402TV::upWait() {
|
||||
if (_countdown1 != 0 && (--_countdown1) == 0) {
|
||||
startAnimation(0x4919397A, 0, -1);
|
||||
SetMessageHandler(&AsScene2402TV::hmJoke);
|
||||
NextState(&AsScene2402TV::stJokeFinished);
|
||||
}
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
void AsScene2402TV::upFocusKlaymen() {
|
||||
int16 frameIndex = CLIP<int16>((_klaymen->getX() - _x + 150) / 10, 0, 29);
|
||||
if (frameIndex != _currFrameIndex) {
|
||||
if (frameIndex > _currFrameIndex)
|
||||
_currFrameIndex++;
|
||||
else if (frameIndex < _currFrameIndex)
|
||||
_currFrameIndex--;
|
||||
startAnimation(0x050A0103, _currFrameIndex, -1);
|
||||
_newStickFrameIndex = _currFrameIndex;
|
||||
if (_countdown2 == 0) {
|
||||
_vm->_soundMan->addSound(0x01520123, 0xC42D4528);
|
||||
_vm->_soundMan->playSoundLooping(0xC42D4528);
|
||||
}
|
||||
_countdown2 = 5;
|
||||
} else if (_countdown2 != 0 && (--_countdown2 == 0))
|
||||
_vm->_soundMan->deleteSound(0xC42D4528);
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
void AsScene2402TV::stJokeFinished() {
|
||||
setGlobalVar(V_TV_JOKE_TOLD, 1);
|
||||
startAnimation(0x050A0103, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
SetUpdateHandler(&AsScene2402TV::upFocusKlaymen);
|
||||
}
|
||||
|
||||
uint32 AsScene2402TV::hmJoke(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x431EA0B0)
|
||||
playSound(0);
|
||||
break;
|
||||
case NM_ANIMATION_STOP:
|
||||
gotoNextState();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
KmScene2401::KmScene2401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y),
|
||||
_canSpitPipe(false), _contSpitPipe(false), _readyToSpit(false),
|
||||
_spitPipeIndex(0), _spitDestPipeIndex(0), _spitContDestPipeIndex(0) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene2401::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case NM_KLAYMEN_PRESS_BUTTON:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPressButton);
|
||||
else if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPressFloorButton);
|
||||
else
|
||||
GotoState(&Klaymen::stPressButtonSide);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case 0x481F:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stTurnAwayFromUse);
|
||||
else if (param.asInteger() == 0)
|
||||
GotoState(&Klaymen::stTurnToUseHalf);
|
||||
else
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
break;
|
||||
case 0x482D:
|
||||
setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x482E:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stWalkToFrontNoStep);
|
||||
else
|
||||
GotoState(&Klaymen::stWalkToFront);
|
||||
break;
|
||||
case 0x482F:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stTurnToFront);
|
||||
else
|
||||
GotoState(&Klaymen::stTurnToBack);
|
||||
break;
|
||||
case 0x4832:
|
||||
GotoState(&Klaymen::stUseTube);
|
||||
break;
|
||||
case 0x4833:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
else {
|
||||
_spitPipeIndex = sendMessage(_parentScene, 0x2000, 0);
|
||||
GotoState(&KmScene2401::stTrySpitIntoPipe);
|
||||
}
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 KmScene2401::hmSpit(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Klaymen::hmLowLevelAnimation(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x16401CA6) {
|
||||
_canSpitPipe = true;
|
||||
if (_contSpitPipe)
|
||||
spitIntoPipe();
|
||||
} else if (param.asInteger() == 0xC11C0008) {
|
||||
_canSpitPipe = false;
|
||||
_acceptInput = false;
|
||||
_readyToSpit = false;
|
||||
} else if (param.asInteger() == 0x018A0001) {
|
||||
sendMessage(_parentScene, 0x2001, _spitDestPipeIndex);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void KmScene2401::stTrySpitIntoPipe() {
|
||||
if (_readyToSpit) {
|
||||
_contSpitPipe = true;
|
||||
_spitContDestPipeIndex = _spitPipeIndex;
|
||||
if (_canSpitPipe)
|
||||
spitIntoPipe();
|
||||
} else if (!stStartAction(AnimationCallback(&KmScene2401::stTrySpitIntoPipe))) {
|
||||
_busyStatus = 2;
|
||||
_acceptInput = true;
|
||||
_spitDestPipeIndex = _spitPipeIndex;
|
||||
_readyToSpit = true;
|
||||
_canSpitPipe = false;
|
||||
_contSpitPipe = false;
|
||||
startAnimation(0x1808B150, 0, -1);
|
||||
SetUpdateHandler(&Klaymen::update);
|
||||
SetMessageHandler(&KmScene2401::hmSpit);
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void KmScene2401::spitIntoPipe() {
|
||||
_contSpitPipe = false;
|
||||
_spitDestPipeIndex = _spitContDestPipeIndex;
|
||||
_canSpitPipe = false;
|
||||
_acceptInput = false;
|
||||
startAnimation(0x1B08B553, 0, -1);
|
||||
SetUpdateHandler(&Klaymen::update);
|
||||
SetMessageHandler(&KmScene2401::hmSpit);
|
||||
SetSpriteUpdate(nullptr);
|
||||
NextState(&KmScene2401::stContSpitIntoPipe);
|
||||
}
|
||||
|
||||
void KmScene2401::stContSpitIntoPipe() {
|
||||
_canSpitPipe = true;
|
||||
_acceptInput = true;
|
||||
startAnimationByHash(0x1808B150, 0x16401CA6, 0);
|
||||
SetUpdateHandler(&Klaymen::update);
|
||||
SetMessageHandler(&KmScene2401::hmSpit);
|
||||
SetSpriteUpdate(nullptr);
|
||||
}
|
||||
|
||||
KmScene2402::KmScene2402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene2402::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
if (!getGlobalVar(V_TV_JOKE_TOLD))
|
||||
GotoState(&Klaymen::stStandWonderAbout);
|
||||
else
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x4804:
|
||||
if (param.asInteger() != 0) {
|
||||
_destX = param.asInteger();
|
||||
GotoState(&Klaymen::stWalkingFirst);
|
||||
} else
|
||||
GotoState(&Klaymen::stPeekWall);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case NM_KLAYMEN_PRESS_BUTTON:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPressButton);
|
||||
else if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPressFloorButton);
|
||||
else
|
||||
GotoState(&Klaymen::stPressButtonSide);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case 0x481F:
|
||||
if (param.asInteger() == 0)
|
||||
GotoState(&Klaymen::stWonderAboutHalf);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stWonderAboutAfter);
|
||||
else if (param.asInteger() == 3)
|
||||
GotoState(&Klaymen::stTurnToUseHalf);
|
||||
else if (param.asInteger() == 4)
|
||||
GotoState(&Klaymen::stTurnAwayFromUse);
|
||||
else
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
KmScene2403::KmScene2403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene2403::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x480D:
|
||||
GotoState(&Klaymen::stPullCord);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case NM_KLAYMEN_PRESS_BUTTON:
|
||||
if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPressButton);
|
||||
else if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPressFloorButton);
|
||||
else
|
||||
GotoState(&Klaymen::stPressButtonSide);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case 0x481F:
|
||||
if (param.asInteger() == 0)
|
||||
GotoState(&Klaymen::stWonderAboutHalf);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stWonderAboutAfter);
|
||||
else if (param.asInteger() == 3)
|
||||
GotoState(&Klaymen::stTurnToUseHalf);
|
||||
else if (param.asInteger() == 4)
|
||||
GotoState(&Klaymen::stTurnAwayFromUse);
|
||||
else
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
break;
|
||||
case 0x4820:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
GotoState(&Klaymen::stContinueClimbLadderUp);
|
||||
break;
|
||||
case 0x4821:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_destY = param.asInteger();
|
||||
GotoState(&Klaymen::stStartClimbLadderDown);
|
||||
break;
|
||||
case 0x4822:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_destY = param.asInteger();
|
||||
GotoState(&Klaymen::stStartClimbLadderUp);
|
||||
break;
|
||||
case 0x4823:
|
||||
sendMessage(_parentScene, 0x2001, 0);
|
||||
GotoState(&Klaymen::stClimbLadderHalf);
|
||||
break;
|
||||
case 0x482D:
|
||||
setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
KmScene2406::KmScene2406(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
_surface->setClipRects(clipRects, clipRectsCount);
|
||||
}
|
||||
|
||||
uint32 KmScene2406::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x4804:
|
||||
if (param.asInteger() != 0) {
|
||||
_destX = param.asInteger();
|
||||
GotoState(&Klaymen::stWalkingFirst);
|
||||
} else
|
||||
GotoState(&Klaymen::stPeekWall);
|
||||
break;
|
||||
case NM_KLAYMEN_PICKUP:
|
||||
if (param.asInteger() == 2)
|
||||
GotoState(&Klaymen::stPickUpNeedle);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stPickUpTube);
|
||||
else
|
||||
GotoState(&Klaymen::stPickUpGeneric);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case NM_KLAYMEN_INSERT_DISK:
|
||||
GotoState(&Klaymen::stInsertDisk);
|
||||
break;
|
||||
case 0x481B:
|
||||
if (param.asPoint().y != 0)
|
||||
startWalkToXDistance(param.asPoint().y, param.asPoint().x);
|
||||
else
|
||||
startWalkToAttachedSpriteXDistance(param.asPoint().x);
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
GotoState(&Klaymen::stTurnToUse);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
GotoState(&Klaymen::stReturnFromUse);
|
||||
break;
|
||||
case 0x481F:
|
||||
if (param.asInteger() == 0)
|
||||
GotoState(&Klaymen::stWonderAboutHalf);
|
||||
else if (param.asInteger() == 1)
|
||||
GotoState(&Klaymen::stWonderAboutAfter);
|
||||
else if (param.asInteger() == 3)
|
||||
GotoState(&Klaymen::stTurnToUseHalf);
|
||||
else if (param.asInteger() == 4)
|
||||
GotoState(&Klaymen::stTurnAwayFromUse);
|
||||
else
|
||||
GotoState(&Klaymen::stWonderAbout);
|
||||
break;
|
||||
case 0x4820:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
GotoState(&Klaymen::stContinueClimbLadderUp);
|
||||
break;
|
||||
case 0x4821:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_destY = param.asInteger();
|
||||
GotoState(&Klaymen::stStartClimbLadderDown);
|
||||
break;
|
||||
case 0x4822:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_destY = param.asInteger();
|
||||
GotoState(&Klaymen::stStartClimbLadderUp);
|
||||
break;
|
||||
case 0x4823:
|
||||
sendMessage(_parentScene, 0x2001, 0);
|
||||
GotoState(&Klaymen::stClimbLadderHalf);
|
||||
break;
|
||||
case 0x483F:
|
||||
startSpecialWalkRight(param.asInteger());
|
||||
break;
|
||||
case 0x4840:
|
||||
startSpecialWalkLeft(param.asInteger());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
138
engines/neverhood/modules/module2400_sprites.h
Normal file
138
engines/neverhood/modules/module2400_sprites.h
Normal file
@@ -0,0 +1,138 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2400_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE2400_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
#include "neverhood/gamemodule.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class AsScene2401WaterSpit : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2401WaterSpit(NeverhoodEngine *vm);
|
||||
protected:
|
||||
int _soundIndex;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2401FlowingWater : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2401FlowingWater(NeverhoodEngine *vm);
|
||||
~AsScene2401FlowingWater() override;
|
||||
protected:
|
||||
bool _isWaterFlowing;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2401WaterFlushing : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2401WaterFlushing(NeverhoodEngine *vm, int16 x, int16 y);
|
||||
protected:
|
||||
int _countdown;
|
||||
int _flushLoopCount;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2401Door : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2401Door(NeverhoodEngine *vm, bool isOpen);
|
||||
protected:
|
||||
int _countdown;
|
||||
bool _isOpen;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stDoorOpenFinished();
|
||||
};
|
||||
|
||||
class AsScene2402Door : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool isOpen);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _countdown;
|
||||
bool _isOpen;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void stDoorClosingFinished();
|
||||
};
|
||||
|
||||
class AsScene2402TV : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2402TV(NeverhoodEngine *vm, Klaymen *klaymen);
|
||||
~AsScene2402TV() override;
|
||||
protected:
|
||||
Klaymen *_klaymen;
|
||||
int _countdown1;
|
||||
int _countdown2;
|
||||
void upWait();
|
||||
void upFocusKlaymen();
|
||||
void stJokeFinished();
|
||||
uint32 hmJoke(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene2401 : public Klaymen {
|
||||
public:
|
||||
KmScene2401(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
bool _canSpitPipe;
|
||||
bool _contSpitPipe;
|
||||
bool _readyToSpit;
|
||||
uint32 _spitPipeIndex;
|
||||
uint32 _spitDestPipeIndex;
|
||||
uint32 _spitContDestPipeIndex;
|
||||
|
||||
void spitIntoPipe();
|
||||
void stTrySpitIntoPipe();
|
||||
void stContSpitIntoPipe();
|
||||
uint32 hmSpit(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2402 : public Klaymen {
|
||||
public:
|
||||
KmScene2402(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2403 : public Klaymen {
|
||||
public:
|
||||
KmScene2403(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
class KmScene2406 : public Klaymen {
|
||||
public:
|
||||
KmScene2406(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y, NRect *clipRects, int clipRectsCount);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2400_SPRITES_H */
|
||||
515
engines/neverhood/modules/module2500.cpp
Normal file
515
engines/neverhood/modules/module2500.cpp
Normal file
@@ -0,0 +1,515 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module1600.h" // for Scene1608
|
||||
#include "neverhood/modules/module1600_sprites.h"
|
||||
#include "neverhood/modules/module2500.h"
|
||||
#include "neverhood/modules/module2500_sprites.h"
|
||||
#include "neverhood/modules/module2700.h" // for Scene2704
|
||||
#include "neverhood/modules/module2700_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kScene2505StaticSprites[] = {
|
||||
0x4000A226, 0
|
||||
};
|
||||
|
||||
static const NRect kScene2505ClipRect = { 0, 0, 564, 480 };
|
||||
|
||||
static const uint32 kScene2506StaticSprites[] = {
|
||||
0x4027AF02, 0
|
||||
};
|
||||
|
||||
static const NRect kScene2506ClipRect = { 0, 0, 640, 441 };
|
||||
|
||||
static const uint32 kScene2508StaticSprites1[] = {
|
||||
0x2F08E610, 0xD844E6A0, 0
|
||||
};
|
||||
|
||||
static const NRect kScene2508ClipRect1 = { 0, 0, 594, 448 };
|
||||
|
||||
static const uint32 kScene2508StaticSprites2[] = {
|
||||
0x2F08E610, 0
|
||||
};
|
||||
|
||||
static const NRect kScene2508ClipRect2 = { 0, 0, 594, 448 };
|
||||
|
||||
Module2500::Module2500(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule), _soundIndex(0) {
|
||||
|
||||
_vm->_soundMan->addMusic(0x29220120, 0x05343184);
|
||||
_vm->_soundMan->startMusic(0x05343184, 0, 0);
|
||||
SetMessageHandler(&Module2500::handleMessage);
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, _vm->gameState().which);
|
||||
else
|
||||
createScene(0, 0);
|
||||
|
||||
loadSound(0, 0x00880CCC);
|
||||
loadSound(1, 0x00880CC0);
|
||||
loadSound(2, 0x00880CCC);
|
||||
loadSound(3, 0x00880CC0);
|
||||
|
||||
}
|
||||
|
||||
Module2500::~Module2500() {
|
||||
_vm->_soundMan->deleteMusicGroup(0x29220120);
|
||||
}
|
||||
|
||||
void Module2500::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module2500::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
_childObject = new Scene2501(_vm, this, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
_vm->gameState().which = which;
|
||||
createScene2704(which, 0x004B01B8, 220);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
_vm->gameState().which = which;
|
||||
if (getGlobalVar(V_WORLDS_JOINED))
|
||||
createScene2704(which, 0x004B01E0, 150);
|
||||
else
|
||||
createScene2704(which, 0x004B0208, 150);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
_childObject = new Scene2504(_vm, this, which);
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
_vm->gameState().which = which;
|
||||
createScene2704(which, 0x004B0230, 150, kScene2505StaticSprites, &kScene2505ClipRect);
|
||||
break;
|
||||
case 5:
|
||||
setGlobalVar(V_CAR_DELTA_X, 1);
|
||||
_vm->gameState().sceneNum = 5;
|
||||
_vm->gameState().which = which;
|
||||
createScene2704(which, 0x004B0268, 150, kScene2506StaticSprites, &kScene2506ClipRect);
|
||||
break;
|
||||
case 6:
|
||||
_vm->gameState().sceneNum = 6;
|
||||
_vm->gameState().which = which;
|
||||
createScene2704(which, 0x004B02A0, 150);
|
||||
break;
|
||||
case 7:
|
||||
_vm->gameState().sceneNum = 7;
|
||||
_vm->gameState().which = which;
|
||||
if (getGlobalVar(V_ENTRANCE_OPEN))
|
||||
createScene2704(which, 0x004B02C8, 150, kScene2508StaticSprites1, &kScene2508ClipRect1);
|
||||
else
|
||||
createScene2704(which, 0x004B02C8, 150, kScene2508StaticSprites2, &kScene2508ClipRect2);
|
||||
break;
|
||||
case 8:
|
||||
_vm->gameState().sceneNum = 8;
|
||||
_childObject = new Scene1608(_vm, this, which);
|
||||
break;
|
||||
case 9:
|
||||
_vm->gameState().sceneNum = 9;
|
||||
if (getGlobalVar(V_ENTRANCE_OPEN))
|
||||
createStaticScene(0xC62A0645, 0xA0641C6A);
|
||||
else
|
||||
createStaticScene(0x7A343546, 0x435427AB);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module2500::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module2500::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1)
|
||||
createScene(2, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(1, 0);
|
||||
else
|
||||
leaveModule(0);
|
||||
break;
|
||||
case 1:
|
||||
if (_moduleResult == 1)
|
||||
createScene(3, -1);
|
||||
else
|
||||
createScene(0, 2);
|
||||
break;
|
||||
case 2:
|
||||
if (_moduleResult == 1)
|
||||
createScene(4, 0);
|
||||
else
|
||||
createScene(0, 1);
|
||||
break;
|
||||
case 3:
|
||||
createScene(1, 1);
|
||||
break;
|
||||
case 4:
|
||||
if (_moduleResult == 1)
|
||||
createScene(5, 0);
|
||||
else
|
||||
createScene(2, 1);
|
||||
break;
|
||||
case 5:
|
||||
if (_moduleResult == 1)
|
||||
createScene(6, 0);
|
||||
else
|
||||
createScene(4, 1);
|
||||
break;
|
||||
case 6:
|
||||
if (_moduleResult == 1)
|
||||
createScene(7, 0);
|
||||
else
|
||||
createScene(5, 1);
|
||||
break;
|
||||
case 7:
|
||||
if (_moduleResult == 1)
|
||||
createScene(8, 1);
|
||||
else
|
||||
createScene(6, 1);
|
||||
break;
|
||||
case 8:
|
||||
if (_moduleResult == 2)
|
||||
createScene(9, -1);
|
||||
else
|
||||
createScene(7, 1);
|
||||
break;
|
||||
case 9:
|
||||
createScene(8, 2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Module2500::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Module::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x200D:
|
||||
playSound(_soundIndex);
|
||||
_soundIndex++;
|
||||
if (_soundIndex >= 4)
|
||||
_soundIndex = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void Module2500::createScene2704(int which, uint32 sceneInfoId, int16 value, const uint32 *staticSprites, const NRect *clipRect) {
|
||||
_childObject = new Scene2704(_vm, this, which, sceneInfoId, value, staticSprites, clipRect);
|
||||
}
|
||||
|
||||
Scene2501::Scene2501(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule) {
|
||||
|
||||
_tracks.push_back(_vm->_staticData->getTrackInfo(0x004B2628));
|
||||
_tracks.push_back(_vm->_staticData->getTrackInfo(0x004B264C));
|
||||
_tracks.push_back(_vm->_staticData->getTrackInfo(0x004B2670));
|
||||
|
||||
setGlobalVar(V_CAR_DELTA_X, 1);
|
||||
SetUpdateHandler(&Scene2501::update);
|
||||
setBackground(0x1B8E8115);
|
||||
setPalette(0x1B8E8115);
|
||||
_palette->addPalette(0x00128842, 65, 31, 65);
|
||||
_palette->addPalette("paKlayRed", 0, 64, 0);
|
||||
insertScreenMouse(0xE81111B0);
|
||||
|
||||
_ssTrackShadowBackground = createSprite<SsCommonTrackShadowBackground>(0x99BE9015); // Don't add this to the sprite list
|
||||
addEntity(_ssTrackShadowBackground);
|
||||
_asCar = createSprite<AsCommonCar>(this, 211, 400); // Create but don't add to the sprite list yet
|
||||
_asIdleCarLower = insertSprite<AsCommonIdleCarLower>(211, 400);
|
||||
_asIdleCarFull = insertSprite<AsCommonIdleCarFull>(211, 400);
|
||||
insertStaticSprite(0xC42AC521, 1500);
|
||||
|
||||
if (which < 0) {
|
||||
// Restoring game
|
||||
insertKlaymen<KmScene2501>(162, 393);
|
||||
_kmScene2501 = _klaymen;
|
||||
_klaymenInCar = false;
|
||||
setMessageList(0x004B2538);
|
||||
setRectList(0x004B2608);
|
||||
SetMessageHandler(&Scene2501::handleMessage);
|
||||
SetUpdateHandler(&Scene2501::update);
|
||||
sendMessage(_asCar, NM_CAR_ENTER, 0);
|
||||
_asCar->setVisible(false);
|
||||
_currTrackIndex = 0;
|
||||
} else if (which == 1 || which == 2) {
|
||||
// 1: Klaymen entering riding the car on the left track
|
||||
// 2: Klaymen entering riding the car on the bottom track
|
||||
addSprite(_asCar);
|
||||
_kmScene2501 = (Klaymen*)new KmScene2501(_vm, this, 275, 393);
|
||||
_klaymenInCar = true;
|
||||
sendMessage(_kmScene2501, 0x2000, 1);
|
||||
_kmScene2501->setDoDeltaX(1);
|
||||
SetMessageHandler(&Scene2501::hmRidingCar);
|
||||
SetUpdateHandler(&Scene2501::upRidingCar);
|
||||
_asIdleCarLower->setVisible(false);
|
||||
_asIdleCarFull->setVisible(false);
|
||||
_currTrackIndex = which;
|
||||
} else {
|
||||
// Klaymen entering the car
|
||||
insertKlaymen<KmScene2501>(162, 393);
|
||||
_kmScene2501 = _klaymen;
|
||||
_klaymenInCar = false;
|
||||
setMessageList(0x004B2538);
|
||||
setRectList(0x004B2608);
|
||||
SetMessageHandler(&Scene2501::handleMessage);
|
||||
SetUpdateHandler(&Scene2501::update);
|
||||
sendMessage(_asCar, NM_CAR_ENTER, 0);
|
||||
_asCar->setVisible(false);
|
||||
_currTrackIndex = 0;
|
||||
}
|
||||
|
||||
_asCarShadow = insertSprite<AsCommonCarShadow>(_asCar, _ssTrackShadowBackground->getSurface(), 4);
|
||||
_asCarTrackShadow = insertSprite<AsCommonCarTrackShadow>(_asCar, _ssTrackShadowBackground->getSurface(), 4);
|
||||
_asCarConnectorShadow = insertSprite<AsCommonCarConnectorShadow>(_asCar, _ssTrackShadowBackground->getSurface(), 4);
|
||||
insertSprite<AsCommonCarConnector>(_asCar);
|
||||
|
||||
_newTrackIndex = -1;
|
||||
_dataResource.load(calcHash("Ashooded"));
|
||||
|
||||
_trackPoints = _dataResource.getPointArray(_tracks[_currTrackIndex]->trackPointsName);
|
||||
_asCar->setPathPoints(_trackPoints);
|
||||
|
||||
if (which >= 0 && _tracks[_currTrackIndex]->which2 == which) {
|
||||
NPoint testPoint = (*_trackPoints)[_trackPoints->size() - 1];
|
||||
sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
|
||||
if (testPoint.x < 0 || testPoint.x >= 640 || testPoint.y < 0 || testPoint.y >= 480)
|
||||
sendMessage(_asCar, NM_CAR_MOVE_TO_PREV_POINT, 150);
|
||||
} else {
|
||||
NPoint testPoint = (*_trackPoints)[0];
|
||||
sendMessage(_asCar, NM_POSITION_CHANGE, 0);
|
||||
if (testPoint.x < 0 || testPoint.x >= 640 || testPoint.y < 0 || testPoint.y >= 480)
|
||||
sendMessage(_asCar, NM_CAR_MOVE_TO_NEXT_POINT, 150);
|
||||
}
|
||||
|
||||
_carStatus = 0;
|
||||
|
||||
}
|
||||
|
||||
Scene2501::~Scene2501() {
|
||||
// Free sprites not currently in the sprite list
|
||||
if (_klaymenInCar)
|
||||
delete _kmScene2501;
|
||||
else
|
||||
delete _asCar;
|
||||
}
|
||||
|
||||
void Scene2501::update() {
|
||||
Scene::update();
|
||||
if (_carStatus == 1) {
|
||||
removeSprite(_klaymen);
|
||||
addSprite(_asCar);
|
||||
clearRectList();
|
||||
_klaymenInCar = true;
|
||||
SetMessageHandler(&Scene2501::hmCarAtHome);
|
||||
SetUpdateHandler(&Scene2501::upCarAtHome);
|
||||
_asIdleCarLower->setVisible(false);
|
||||
_asIdleCarFull->setVisible(false);
|
||||
_asCar->setVisible(true);
|
||||
sendMessage(_asCar, NM_CAR_ENTER, 0);
|
||||
_asCar->handleUpdate();
|
||||
_klaymen = nullptr;
|
||||
_carStatus = 0;
|
||||
}
|
||||
updateKlaymenClipRect();
|
||||
}
|
||||
|
||||
void Scene2501::upCarAtHome() {
|
||||
Scene::update();
|
||||
if (_mouseClicked) {
|
||||
if (_mouseClickPos.x <= 210 && _asCar->getX() == 211 && _asCar->getY() == 400) {
|
||||
sendMessage(_asCar, NM_CAR_LEAVE, 0);
|
||||
SetUpdateHandler(&Scene2501::upGettingOutOfCar);
|
||||
} else {
|
||||
moveCarToPoint(_mouseClickPos);
|
||||
SetMessageHandler(&Scene2501::hmRidingCar);
|
||||
SetUpdateHandler(&Scene2501::upRidingCar);
|
||||
}
|
||||
_mouseClicked = false;
|
||||
}
|
||||
updateKlaymenClipRect();
|
||||
}
|
||||
|
||||
void Scene2501::upGettingOutOfCar() {
|
||||
Scene::update();
|
||||
if (_carStatus == 2) {
|
||||
_klaymen = _kmScene2501;
|
||||
removeSprite(_asCar);
|
||||
addSprite(_klaymen);
|
||||
_klaymenInCar = false;
|
||||
SetMessageHandler(&Scene2501::handleMessage);
|
||||
SetUpdateHandler(&Scene2501::update);
|
||||
setRectList(0x004B2608);
|
||||
_asIdleCarLower->setVisible(true);
|
||||
_asIdleCarFull->setVisible(true);
|
||||
_asCar->setVisible(false);
|
||||
setMessageList(0x004B2570);
|
||||
processMessageList();
|
||||
_klaymen->handleUpdate();
|
||||
_carStatus = 0;
|
||||
}
|
||||
updateKlaymenClipRect();
|
||||
}
|
||||
|
||||
void Scene2501::upRidingCar() {
|
||||
Scene::update();
|
||||
if (_mouseClicked) {
|
||||
moveCarToPoint(_mouseClickPos);
|
||||
_mouseClicked = false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Scene2501::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_START:
|
||||
if (param.asInteger() == 0x60842040)
|
||||
_carStatus = 1;
|
||||
break;
|
||||
case 0x200D:
|
||||
sendMessage(_parentModule, 0x200D, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 Scene2501::hmRidingCar(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_KLAYMEN_CLIMB_LADDER:
|
||||
if (_tracks[_currTrackIndex]->which1 < 0 && _newTrackIndex >= 0)
|
||||
changeTrack();
|
||||
else if (_tracks[_currTrackIndex]->which1 == 0) {
|
||||
SetMessageHandler(&Scene2501::hmCarAtHome);
|
||||
SetUpdateHandler(&Scene2501::upCarAtHome);
|
||||
sendMessage(_asCar, NM_CAR_AT_HOME, 1);
|
||||
} else if (_tracks[_currTrackIndex]->which1 > 0)
|
||||
leaveScene(_tracks[_currTrackIndex]->which1);
|
||||
break;
|
||||
case NM_KLAYMEN_STOP_CLIMBING:
|
||||
if (_tracks[_currTrackIndex]->which2 < 0 && _newTrackIndex >= 0)
|
||||
changeTrack();
|
||||
else if (_tracks[_currTrackIndex]->which2 == 0) {
|
||||
SetMessageHandler(&Scene2501::hmCarAtHome);
|
||||
SetUpdateHandler(&Scene2501::upCarAtHome);
|
||||
sendMessage(_asCar, NM_CAR_AT_HOME, 1);
|
||||
} else if (_tracks[_currTrackIndex]->which2 > 0)
|
||||
leaveScene(_tracks[_currTrackIndex]->which2);
|
||||
break;
|
||||
case 0x200D:
|
||||
sendMessage(_parentModule, 0x200D, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
uint32 Scene2501::hmCarAtHome(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_CAR_LEAVE:
|
||||
_carStatus = 2;
|
||||
break;
|
||||
case 0x200D:
|
||||
sendMessage(_parentModule, 0x200D, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
void Scene2501::moveCarToPoint(NPoint &pt) {
|
||||
int minMatchTrackIndex, minMatchDistance;
|
||||
_tracks.findTrackPoint(pt, minMatchTrackIndex, minMatchDistance, _dataResource);
|
||||
if (minMatchTrackIndex >= 0 && minMatchTrackIndex != _currTrackIndex) {
|
||||
_newTrackIndex = minMatchTrackIndex;
|
||||
_clickPoint = pt;
|
||||
if (_currTrackIndex == 0)
|
||||
sendMessage(_asCar, 0x2003, _trackPoints->size() - 1);
|
||||
else
|
||||
sendMessage(_asCar, 0x2003, 0);
|
||||
} else {
|
||||
_newTrackIndex = -1;
|
||||
sendMessage(_asCar, 0x2004, pt);
|
||||
}
|
||||
}
|
||||
|
||||
void Scene2501::changeTrack() {
|
||||
_currTrackIndex = _newTrackIndex;
|
||||
_trackPoints = _dataResource.getPointArray(_tracks[_currTrackIndex]->trackPointsName);
|
||||
_asCar->setPathPoints(_trackPoints);
|
||||
if (_currTrackIndex == 0)
|
||||
sendMessage(_asCar, NM_POSITION_CHANGE, _trackPoints->size() - 1);
|
||||
else
|
||||
sendMessage(_asCar, NM_POSITION_CHANGE, 0);
|
||||
sendPointMessage(_asCar, 0x2004, _clickPoint);
|
||||
_newTrackIndex = -1;
|
||||
}
|
||||
|
||||
void Scene2501::updateKlaymenClipRect() {
|
||||
if (_kmScene2501->getX() <= 211)
|
||||
_kmScene2501->setClipRect(0, 0, 640, 480);
|
||||
else
|
||||
_kmScene2501->setClipRect(0, 0, 640, 388);
|
||||
}
|
||||
|
||||
Scene2504::Scene2504(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule) {
|
||||
|
||||
Sprite *ssButton;
|
||||
|
||||
setBackground(0x90791B80);
|
||||
setPalette(0x90791B80);
|
||||
ssButton = insertSprite<SsScene2504Button>();
|
||||
addCollisionSprite(ssButton);
|
||||
insertPuzzleMouse(0x91B8490F, 20, 620);
|
||||
SetMessageHandler(&Scene2504::handleMessage);
|
||||
SetUpdateHandler(&Scene::update);
|
||||
}
|
||||
|
||||
uint32 Scene2504::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if (param.asPoint().x <= 20 || param.asPoint().x >= 620)
|
||||
leaveScene(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
88
engines/neverhood/modules/module2500.h
Normal file
88
engines/neverhood/modules/module2500.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2500_H
|
||||
#define NEVERHOOD_MODULES_MODULE2500_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
#include "neverhood/modules/module1600_sprites.h" // for Tracks
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class Module2500 : public Module {
|
||||
public:
|
||||
Module2500(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module2500() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
int _soundIndex;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void createScene2704(int which, uint32 sceneInfoId, int16 value, const uint32 *staticSprites = NULL, const NRect *clipRect = NULL);
|
||||
};
|
||||
|
||||
class AsCommonCar;
|
||||
|
||||
class Scene2501 : public Scene {
|
||||
public:
|
||||
Scene2501(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Scene2501() override;
|
||||
protected:
|
||||
AsCommonCar *_asCar;
|
||||
Sprite *_ssTrackShadowBackground;
|
||||
Sprite *_asCarShadow;
|
||||
Sprite *_asCarConnectorShadow;
|
||||
Sprite *_asCarTrackShadow;
|
||||
Sprite *_asIdleCarLower;
|
||||
Sprite *_asIdleCarFull;
|
||||
Klaymen *_kmScene2501;
|
||||
Tracks _tracks;
|
||||
NPointArray *_trackPoints;
|
||||
int _currTrackIndex;
|
||||
NPoint _clickPoint;
|
||||
int _newTrackIndex;
|
||||
int _carStatus;
|
||||
bool _klaymenInCar;
|
||||
void update();
|
||||
void upCarAtHome();
|
||||
void upGettingOutOfCar();
|
||||
void upRidingCar();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmRidingCar(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmCarAtHome(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void moveCarToPoint(NPoint &pt);
|
||||
void changeTrack();
|
||||
void updateKlaymenClipRect();
|
||||
};
|
||||
|
||||
class Scene2504 : public Scene {
|
||||
public:
|
||||
Scene2504(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2500_H */
|
||||
130
engines/neverhood/modules/module2500_sprites.cpp
Normal file
130
engines/neverhood/modules/module2500_sprites.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module2500_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
SsScene2504Button::SsScene2504Button(NeverhoodEngine *vm)
|
||||
: StaticSprite(vm, 1400), _countdown(0), _isSoundPlaying(false) {
|
||||
|
||||
loadSprite(0x070220D9, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
|
||||
setVisible(false);
|
||||
loadSound(0, 0x4600204C);
|
||||
loadSound(1, 0x408C0034);
|
||||
loadSound(2, 0x44043000);
|
||||
loadSound(3, 0x44045000);
|
||||
SetMessageHandler(&SsScene2504Button::handleMessage);
|
||||
SetUpdateHandler(&SsScene2504Button::update);
|
||||
}
|
||||
|
||||
void SsScene2504Button::update() {
|
||||
updatePosition();
|
||||
if (_isSoundPlaying && !isSoundPlaying(0) && !isSoundPlaying(1)) {
|
||||
playSound(3);
|
||||
setVisible(false);
|
||||
_isSoundPlaying = false;
|
||||
}
|
||||
if (_countdown != 0 && (--_countdown) == 0) {
|
||||
if (getSubVar(VA_LOCKS_DISABLED, 0x01180951))
|
||||
playSound(0);
|
||||
else
|
||||
playSound(1);
|
||||
_isSoundPlaying = true;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SsScene2504Button::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (_countdown == 0 && !_isSoundPlaying) {
|
||||
setVisible(true);
|
||||
_countdown = 2;
|
||||
if (getSubVar(VA_LOCKS_DISABLED, 0x01180951))
|
||||
setSubVar(VA_LOCKS_DISABLED, 0x01180951, 0);
|
||||
else
|
||||
setSubVar(VA_LOCKS_DISABLED, 0x01180951, 1);
|
||||
playSound(2);
|
||||
}
|
||||
messageResult = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
KmScene2501::KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene2501::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
uint32 messageResult = 0;
|
||||
switch (messageNum) {
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isSittingInTeleporter = param.asInteger() != 0;
|
||||
messageResult = 1;
|
||||
break;
|
||||
case 0x4001:
|
||||
case 0x4800:
|
||||
startWalkToX(param.asPoint().x, false);
|
||||
break;
|
||||
case NM_KLAYMEN_STAND_IDLE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stSitIdleTeleporter);
|
||||
else
|
||||
GotoState(&Klaymen::stTryStandIdle);
|
||||
break;
|
||||
case 0x4817:
|
||||
setDoDeltaX(param.asInteger());
|
||||
gotoNextStateExt();
|
||||
break;
|
||||
case NM_KLAYMEN_TURN_TO_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stTurnToUseInTeleporter);
|
||||
break;
|
||||
case NM_KLAYMEN_RETURN_FROM_USE:
|
||||
if (_isSittingInTeleporter)
|
||||
GotoState(&Klaymen::stReturnFromUseInTeleporter);
|
||||
break;
|
||||
case 0x4834:
|
||||
GotoState(&Klaymen::stStepOver);
|
||||
break;
|
||||
case 0x4835:
|
||||
sendMessage(_parentScene, 0x2000, 1);
|
||||
_isSittingInTeleporter = true;
|
||||
GotoState(&Klaymen::stSitInTeleporter);
|
||||
break;
|
||||
case 0x4836:
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
_isSittingInTeleporter = false;
|
||||
GotoState(&Klaymen::stGetUpFromTeleporter);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
50
engines/neverhood/modules/module2500_sprites.h
Normal file
50
engines/neverhood/modules/module2500_sprites.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2500_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE2500_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class SsScene2504Button : public StaticSprite {
|
||||
public:
|
||||
SsScene2504Button(NeverhoodEngine *vm);
|
||||
protected:
|
||||
int _countdown;
|
||||
bool _isSoundPlaying;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class KmScene2501 : public Klaymen {
|
||||
public:
|
||||
KmScene2501(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2500_SPRITES_H */
|
||||
266
engines/neverhood/modules/module2600.cpp
Normal file
266
engines/neverhood/modules/module2600.cpp
Normal file
@@ -0,0 +1,266 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module2600.h"
|
||||
#include "neverhood/modules/module2600_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const uint32 kModule2600SoundList[] = {
|
||||
0xB288D450,
|
||||
0x90804450,
|
||||
0x99801500,
|
||||
0xB288D455,
|
||||
0x93825040,
|
||||
0
|
||||
};
|
||||
|
||||
Module2600::Module2600(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Module(vm, parentModule) {
|
||||
|
||||
if (which < 0)
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
else if (which == 1)
|
||||
createScene(4, 1);
|
||||
else
|
||||
createScene(0, 1);
|
||||
|
||||
_vm->_soundMan->addSoundList(0x40271018, kModule2600SoundList);
|
||||
_vm->_soundMan->setSoundListParams(kModule2600SoundList, true, 50, 600, 5, 150);
|
||||
_vm->_soundMan->playTwoSounds(0x40271018, 0x41861371, 0x43A2507F, 0);
|
||||
|
||||
}
|
||||
|
||||
Module2600::~Module2600() {
|
||||
_vm->_soundMan->deleteGroup(0x40271018);
|
||||
}
|
||||
|
||||
void Module2600::createScene(int sceneNum, int which) {
|
||||
debug(1, "Module2600::createScene(%d, %d)", sceneNum, which);
|
||||
_sceneNum = sceneNum;
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
_vm->gameState().sceneNum = 0;
|
||||
createNavigationScene(0x004B8608, which);
|
||||
break;
|
||||
case 1:
|
||||
_vm->gameState().sceneNum = 1;
|
||||
createNavigationScene(0x004B8638, which);
|
||||
break;
|
||||
case 2:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
createNavigationScene(0x004B86C8, which);
|
||||
break;
|
||||
case 3:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
if (getGlobalVar(V_CREATURE_ANGRY))
|
||||
createNavigationScene(0x004B8758, which);
|
||||
else
|
||||
createNavigationScene(0x004B86F8, which);
|
||||
break;
|
||||
case 4:
|
||||
_vm->gameState().sceneNum = 4;
|
||||
createNavigationScene(0x004B87B8, which);
|
||||
break;
|
||||
case 6:
|
||||
_vm->gameState().sceneNum = 6;
|
||||
createNavigationScene(0x004B8698, which);
|
||||
break;
|
||||
case 7:
|
||||
_vm->gameState().sceneNum = 7;
|
||||
_vm->_soundMan->deleteGroup(0x40271018);
|
||||
createSmackerScene(0x30090001, true, true, false);
|
||||
break;
|
||||
case 8:
|
||||
_vm->gameState().sceneNum = 8;
|
||||
_childObject = new Scene2609(_vm, this, which);
|
||||
break;
|
||||
case 1002:
|
||||
_vm->gameState().sceneNum = 2;
|
||||
if (getGlobalVar(V_FRUIT_COUNTING_INDEX) == 1)
|
||||
createSmackerScene(0x018C0404, true, true, false);
|
||||
else if (getGlobalVar(V_FRUIT_COUNTING_INDEX) == 2)
|
||||
createSmackerScene(0x018C0407, true, true, false);
|
||||
else
|
||||
createSmackerScene(0x818C0405, true, true, false);
|
||||
if (getGlobalVar(V_FRUIT_COUNTING_INDEX) >= 2)
|
||||
setGlobalVar(V_FRUIT_COUNTING_INDEX, 0);
|
||||
else
|
||||
incGlobalVar(V_FRUIT_COUNTING_INDEX, +1);
|
||||
break;
|
||||
case 1003:
|
||||
_vm->gameState().sceneNum = 3;
|
||||
createSmackerScene(0x001C0007, true, true, false);
|
||||
break;
|
||||
case 1006:
|
||||
_vm->gameState().sceneNum = 6;
|
||||
if (getGlobalVar(V_WATER_RUNNING))
|
||||
createSmackerScene(0x049A1181, true, true, false);
|
||||
else
|
||||
createSmackerScene(0x04981181, true, true, false);
|
||||
break;
|
||||
case 1008:
|
||||
_vm->gameState().sceneNum = 8;
|
||||
if (getGlobalVar(V_WATER_RUNNING))
|
||||
createSmackerScene(0x42B80941, true, true, false);
|
||||
else
|
||||
createSmackerScene(0x42980941, true, true, false);
|
||||
break;
|
||||
case 9999:
|
||||
createDemoScene();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetUpdateHandler(&Module2600::updateScene);
|
||||
_childObject->handleUpdate();
|
||||
}
|
||||
|
||||
void Module2600::updateScene() {
|
||||
if (!updateChild()) {
|
||||
switch (_sceneNum) {
|
||||
case 0:
|
||||
if (_moduleResult == 1)
|
||||
createScene(1, 3);
|
||||
else
|
||||
leaveModule(0);
|
||||
break;
|
||||
case 1:
|
||||
if (_moduleResult == 0)
|
||||
createScene(6, 0);
|
||||
else if (_moduleResult == 1)
|
||||
createScene(0, 0);
|
||||
else if (_moduleResult == 2)
|
||||
createScene(2, 1);
|
||||
else if (_moduleResult == 3)
|
||||
createScene(3, 0);
|
||||
break;
|
||||
case 2:
|
||||
if (_moduleResult == 0)
|
||||
createScene(1, 0);
|
||||
else if (_moduleResult == 1) {
|
||||
if (_vm->isDemo())
|
||||
createScene(9999, -1);
|
||||
else
|
||||
createScene(1002, -1);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (_moduleResult == 0) {
|
||||
if (getGlobalVar(V_CREATURE_ANGRY))
|
||||
createScene(4, 0);
|
||||
else
|
||||
createScene(1003, -1);
|
||||
} else if (_moduleResult == 2)
|
||||
createScene(1, 1);
|
||||
else if (_moduleResult == 3) {
|
||||
if (getGlobalVar(V_CREATURE_ANGRY))
|
||||
createScene(4, 0);
|
||||
else {
|
||||
setGlobalVar(V_CREATURE_ANGRY, 1);
|
||||
createScene(7, -1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (_moduleResult == 0)
|
||||
leaveModule(1);
|
||||
else
|
||||
createScene(3, 1);
|
||||
break;
|
||||
case 6:
|
||||
if (_moduleResult == 0) {
|
||||
if (_vm->isDemo())
|
||||
createScene(9999, -1);
|
||||
else
|
||||
createScene(1006, -1);
|
||||
}
|
||||
else if (_moduleResult == 1)
|
||||
createScene(1, 2);
|
||||
break;
|
||||
case 7:
|
||||
leaveModule(0);
|
||||
break;
|
||||
case 8:
|
||||
createScene(1008, -1);
|
||||
break;
|
||||
case 1002:
|
||||
createScene(2, 1);
|
||||
break;
|
||||
case 1003:
|
||||
createScene(3, 0);
|
||||
break;
|
||||
case 1006:
|
||||
createScene(8, -1);
|
||||
break;
|
||||
case 1008:
|
||||
createScene(6, 0);
|
||||
break;
|
||||
case 9999:
|
||||
createScene(_vm->gameState().sceneNum, -1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scene2609::Scene2609(NeverhoodEngine *vm, Module *parentModule, int which)
|
||||
: Scene(vm, parentModule), _isBusy(false) {
|
||||
|
||||
SetUpdateHandler(&Scene::update);
|
||||
SetMessageHandler(&Scene2609::handleMessage);
|
||||
|
||||
setBackground(0x51409A16);
|
||||
setPalette(0x51409A16);
|
||||
_asWater = insertSprite<AsScene2609Water>();
|
||||
_ssButton = insertSprite<SsScene2609Button>(this);
|
||||
addCollisionSprite(_ssButton);
|
||||
insertPuzzleMouse(0x09A1251C, 20, 620);
|
||||
insertStaticSprite(0x02138002, 1200);
|
||||
insertStaticSprite(0x825E2827, 1200);
|
||||
}
|
||||
|
||||
uint32 Scene2609::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
Scene::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case NM_MOUSE_CLICK:
|
||||
if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && !_isBusy)
|
||||
leaveScene(0);
|
||||
break;
|
||||
case NM_ANIMATION_UPDATE:
|
||||
_isBusy = true;
|
||||
break;
|
||||
case 0x2001:
|
||||
_isBusy = false;
|
||||
sendMessage(_asWater, 0x2001, 0);
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
_isBusy = false;
|
||||
sendMessage(_asWater, NM_POSITION_CHANGE, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
55
engines/neverhood/modules/module2600.h
Normal file
55
engines/neverhood/modules/module2600.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2600_H
|
||||
#define NEVERHOOD_MODULES_MODULE2600_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Module2600
|
||||
|
||||
class Module2600 : public Module {
|
||||
public:
|
||||
Module2600(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module2600() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
};
|
||||
|
||||
class Scene2609 : public Scene {
|
||||
public:
|
||||
Scene2609(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
bool _isBusy;
|
||||
Sprite *_asWater;
|
||||
Sprite *_ssButton;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2600_H */
|
||||
118
engines/neverhood/modules/module2600_sprites.cpp
Normal file
118
engines/neverhood/modules/module2600_sprites.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module2600_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
SsScene2609Button::SsScene2609Button(NeverhoodEngine *vm, Scene *parentScene)
|
||||
: StaticSprite(vm, 1400), _parentScene(parentScene), _countdown(0) {
|
||||
|
||||
SetUpdateHandler(&SsScene2609Button::update);
|
||||
SetMessageHandler(&SsScene2609Button::handleMessage);
|
||||
|
||||
loadSprite(0x825A6923, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400);
|
||||
if (!getGlobalVar(V_WATER_RUNNING))
|
||||
setVisible(false);
|
||||
loadSound(0, 0x10267160);
|
||||
loadSound(1, 0x7027FD64);
|
||||
loadSound(2, 0x44043000);
|
||||
loadSound(3, 0x44045000);
|
||||
}
|
||||
|
||||
void SsScene2609Button::update() {
|
||||
updatePosition();
|
||||
if (_countdown != 0 && (--_countdown == 0)) {
|
||||
if (getGlobalVar(V_WATER_RUNNING)) {
|
||||
setGlobalVar(V_WATER_RUNNING, 0);
|
||||
sendMessage(_parentScene, 0x2001, 0);
|
||||
} else {
|
||||
setGlobalVar(V_WATER_RUNNING, 1);
|
||||
sendMessage(_parentScene, NM_POSITION_CHANGE, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 SsScene2609Button::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x1011:
|
||||
if (_countdown == 0) {
|
||||
sendMessage(_parentScene, 0x2000, 0);
|
||||
if (getGlobalVar(V_WATER_RUNNING)) {
|
||||
setVisible(false);
|
||||
playSound(3);
|
||||
playSound(1);
|
||||
_countdown = 12;
|
||||
} else {
|
||||
setVisible(true);
|
||||
playSound(2);
|
||||
playSound(0);
|
||||
_countdown = 96;
|
||||
}
|
||||
}
|
||||
messageResult = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
AsScene2609Water::AsScene2609Water(NeverhoodEngine *vm)
|
||||
: AnimatedSprite(vm, 1000) {
|
||||
|
||||
_x = 240;
|
||||
_y = 420;
|
||||
setDoDeltaX(1);
|
||||
createSurface1(0x9C210C90, 1200);
|
||||
setClipRect(260, 260, 400, 368);
|
||||
_vm->_soundMan->addSound(0x08526C36, 0xDC2769B0);
|
||||
SetUpdateHandler(&AnimatedSprite::update);
|
||||
SetMessageHandler(&AsScene2609Water::handleMessage);
|
||||
if (getGlobalVar(V_WATER_RUNNING))
|
||||
sendMessage(this, NM_POSITION_CHANGE, 0);
|
||||
}
|
||||
|
||||
AsScene2609Water::~AsScene2609Water() {
|
||||
_vm->_soundMan->deleteSoundGroup(0x08526C36);
|
||||
}
|
||||
|
||||
uint32 AsScene2609Water::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) {
|
||||
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
|
||||
switch (messageNum) {
|
||||
case 0x2001:
|
||||
stopAnimation();
|
||||
setVisible(false);
|
||||
_vm->_soundMan->stopSound(0xDC2769B0);
|
||||
break;
|
||||
case NM_POSITION_CHANGE:
|
||||
startAnimation(0x9C210C90, 0, -1);
|
||||
setVisible(true);
|
||||
_vm->_soundMan->playSoundLooping(0xDC2769B0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return messageResult;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
53
engines/neverhood/modules/module2600_sprites.h
Normal file
53
engines/neverhood/modules/module2600_sprites.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2600_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE2600_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Module2600
|
||||
|
||||
class SsScene2609Button : public StaticSprite {
|
||||
public:
|
||||
SsScene2609Button(NeverhoodEngine *vm, Scene *parentScene);
|
||||
protected:
|
||||
Scene *_parentScene;
|
||||
int _countdown;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class AsScene2609Water : public AnimatedSprite {
|
||||
public:
|
||||
AsScene2609Water(NeverhoodEngine *vm);
|
||||
~AsScene2609Water() override;
|
||||
protected:
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2600_SPRITES_H */
|
||||
1155
engines/neverhood/modules/module2700.cpp
Normal file
1155
engines/neverhood/modules/module2700.cpp
Normal file
File diff suppressed because it is too large
Load Diff
150
engines/neverhood/modules/module2700.h
Normal file
150
engines/neverhood/modules/module2700.h
Normal file
@@ -0,0 +1,150 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2700_H
|
||||
#define NEVERHOOD_MODULES_MODULE2700_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
#include "neverhood/modules/module1600_sprites.h" // for Tracks
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
// Module2700
|
||||
|
||||
class Module2700 : public Module {
|
||||
public:
|
||||
Module2700(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
~Module2700() override;
|
||||
protected:
|
||||
int _sceneNum;
|
||||
int _soundIndex;
|
||||
bool _radioMusicInitialized;
|
||||
uint32 _scene2711StaticSprites[6];
|
||||
uint32 _musicFileHash;
|
||||
void createScene(int sceneNum, int which);
|
||||
void updateScene();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void createScene2703(int which, uint32 trackInfoId);
|
||||
void createScene2704(int which, uint32 trackInfoId, int16 value, const uint32 *staticSprites = NULL, const NRect *clipRect = NULL);
|
||||
};
|
||||
|
||||
class AsCommonCar;
|
||||
|
||||
class Scene2701 : public Scene {
|
||||
public:
|
||||
Scene2701(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
AsCommonCar *_asCar;
|
||||
Sprite *_ssTrackShadowBackground;
|
||||
Sprite *_asCarShadow;
|
||||
Sprite *_asCarTrackShadow;
|
||||
Sprite *_asCarConnectorShadow;
|
||||
Sprite *_asCarConnector;
|
||||
int _which1, _which2;
|
||||
NPointArray *_trackPoints;
|
||||
uint32 hmRidingCar(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
uint32 hmCarAtHome(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2702 : public Scene {
|
||||
public:
|
||||
Scene2702(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
AsCommonCar *_asCar;
|
||||
Sprite *_ssTrackShadowBackground;
|
||||
Sprite *_asCarShadow;
|
||||
Sprite *_asCarTrackShadow;
|
||||
Sprite *_asCarConnectorShadow;
|
||||
NPoint _newTrackDest;
|
||||
bool _isInLight;
|
||||
int _currTrackIndex, _newTrackIndex;
|
||||
bool _isUpperTrack;
|
||||
Tracks _tracks;
|
||||
NPointArray *_trackPoints;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void moveCarToPoint(NPoint pt);
|
||||
void changeTrack();
|
||||
};
|
||||
|
||||
class Scene2703 : public Scene {
|
||||
public:
|
||||
Scene2703(NeverhoodEngine *vm, Module *parentModule, int which, uint32 trackInfoId);
|
||||
protected:
|
||||
AsCommonCar *_asCar;
|
||||
Sprite *_ssTrackShadowBackground;
|
||||
Sprite *_asCarShadow;
|
||||
Sprite *_asCarConnector;
|
||||
Sprite *_asCarTrackShadow;
|
||||
Sprite *_asCarConnectorShadow;
|
||||
int _palStatus;
|
||||
int _which1, _which2;
|
||||
NPointArray *_trackPoints;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2704 : public Scene {
|
||||
public:
|
||||
Scene2704(NeverhoodEngine *vm, Module *parentModule, int which, uint32 trackInfoId, int16 value,
|
||||
const uint32 *staticSprites = NULL, const NRect *clipRect = NULL);
|
||||
protected:
|
||||
AsCommonCar *_asCar;
|
||||
Sprite *_ssTrackShadowBackground;
|
||||
Sprite *_asCarShadow;
|
||||
Sprite *_asCarConnector;
|
||||
Sprite *_asCarTrackShadow;
|
||||
Sprite *_asCarConnectorShadow;
|
||||
int _which1, _which2;
|
||||
NPointArray *_trackPoints;
|
||||
void update();
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
};
|
||||
|
||||
class Scene2706 : public Scene {
|
||||
public:
|
||||
Scene2706(NeverhoodEngine *vm, Module *parentModule, int which);
|
||||
protected:
|
||||
AsCommonCar *_asCar;
|
||||
Sprite *_ssTrackShadowBackground;
|
||||
Sprite *_asCarShadow;
|
||||
Sprite *_asCarConnector;
|
||||
Sprite *_asCarTrackShadow;
|
||||
Sprite *_asCarConnectorShadow;
|
||||
NPoint _newTrackDest;
|
||||
int _currTrackIndex, _newTrackIndex;
|
||||
Tracks _tracks;
|
||||
NPointArray *_trackPoints;
|
||||
uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);
|
||||
void moveCarToPoint(NPoint pt);
|
||||
void changeTrack();
|
||||
};
|
||||
|
||||
class Scene2732 : public Scene {
|
||||
public:
|
||||
Scene2732(NeverhoodEngine *vm, Module *parentModule);
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2700_H */
|
||||
123
engines/neverhood/modules/module2700_sprites.cpp
Normal file
123
engines/neverhood/modules/module2700_sprites.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "neverhood/modules/module2700_sprites.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
static const NPoint kCarShadowOffsets[] = {
|
||||
{-63, 3}, {-48, 40}, {-33, 58},
|
||||
{ 0, 65}, { 40, 53}, { 56, 27},
|
||||
{ 63, 0}, {-30, 26}, { 0, 30},
|
||||
{ 26, 25}
|
||||
};
|
||||
|
||||
SsCommonTrackShadowBackground::SsCommonTrackShadowBackground(NeverhoodEngine *vm, uint32 fileHash)
|
||||
: StaticSprite(vm, 0) {
|
||||
|
||||
loadSprite(fileHash, kSLFDefDrawOffset | kSLFDefPosition, 0);
|
||||
}
|
||||
|
||||
AsCommonCarShadow::AsCommonCarShadow(NeverhoodEngine *vm, AnimatedSprite *asCar, const Common::SharedPtr<BaseSurface> &shadowSurface, uint index)
|
||||
: AnimatedSprite(vm, 1100), _asCar(asCar), _index(index), _animFileHash(0) {
|
||||
|
||||
SetUpdateHandler(&AsCommonCarShadow::update);
|
||||
createShadowSurface(shadowSurface, 211, 147, 100);
|
||||
updateShadow();
|
||||
}
|
||||
|
||||
void AsCommonCarShadow::update() {
|
||||
updateShadow();
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
void AsCommonCarShadow::updateShadow() {
|
||||
if (_asCar->getFrameIndex() != _currFrameIndex || _asCar->getCurrAnimFileHash() != _animFileHash) {
|
||||
uint32 fileHash = _asCar->getCurrAnimFileHash();
|
||||
if (fileHash == 0x35698F78 || fileHash == 0x192ADD30 || fileHash == 0x9C220DA4 ||
|
||||
fileHash == 0x9966B138 || fileHash == 0xB579A77C || fileHash == 0xA86A9538 ||
|
||||
fileHash == 0xD4220027 || fileHash == 0xD00A1364 || fileHash == 0xD4AA03A4 ||
|
||||
fileHash == 0xF46A0324) {
|
||||
startAnimation(fileHash, _asCar->getFrameIndex(), -1);
|
||||
_newStickFrameIndex = _asCar->getFrameIndex();
|
||||
}
|
||||
_animFileHash = fileHash;
|
||||
}
|
||||
_x = _asCar->getX() + kCarShadowOffsets[_index].x;
|
||||
_y = _asCar->getY() + kCarShadowOffsets[_index].y;
|
||||
if (!_asCar->getVisible()) {
|
||||
startAnimation(0x1209E09F, 0, -1);
|
||||
_newStickFrameIndex = 0;
|
||||
}
|
||||
setDoDeltaX(_asCar->isDoDeltaX() ? 1 : 0);
|
||||
}
|
||||
|
||||
AsCommonCarConnectorShadow::AsCommonCarConnectorShadow(NeverhoodEngine *vm, Sprite *asCar, const Common::SharedPtr<BaseSurface> &shadowSurface, uint index)
|
||||
: AnimatedSprite(vm, 1100), _asCar(asCar), _index(index) {
|
||||
|
||||
SetUpdateHandler(&AsCommonCarConnectorShadow::update);
|
||||
createShadowSurface1(shadowSurface, 0x60281C10, 150);
|
||||
startAnimation(0x60281C10, -1, -1);
|
||||
_newStickFrameIndex = STICK_LAST_FRAME;
|
||||
}
|
||||
|
||||
void AsCommonCarConnectorShadow::update() {
|
||||
_x = _asCar->getX() + kCarShadowOffsets[_index].x;
|
||||
_y = _asCar->getY() + kCarShadowOffsets[_index].y;
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
AsCommonCarTrackShadow::AsCommonCarTrackShadow(NeverhoodEngine *vm, Sprite *asCar, const Common::SharedPtr<BaseSurface> &shadowSurface, int16 frameIndex)
|
||||
: AnimatedSprite(vm, 1100), _asCar(asCar) {
|
||||
|
||||
SetUpdateHandler(&AsCommonCarTrackShadow::update);
|
||||
createShadowSurface1(shadowSurface, 0x0759129C, 100);
|
||||
startAnimation(0x0759129C, frameIndex, -1);
|
||||
_newStickFrameIndex = frameIndex;
|
||||
}
|
||||
|
||||
void AsCommonCarTrackShadow::update() {
|
||||
_x = _asCar->getX();
|
||||
_y = _asCar->getY();
|
||||
AnimatedSprite::update();
|
||||
}
|
||||
|
||||
KmScene2732::KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
|
||||
: Klaymen(vm, parentScene, x, y) {
|
||||
|
||||
// Empty
|
||||
}
|
||||
|
||||
uint32 KmScene2732::xHandleMessage(int messageNum, const MessageParam ¶m) {
|
||||
switch (messageNum) {
|
||||
case 0x4804:
|
||||
GotoState(&Klaymen::stPeekInside);
|
||||
break;
|
||||
case 0x483C:
|
||||
GotoState(&Klaymen::stPeekInsideReturn);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Neverhood
|
||||
73
engines/neverhood/modules/module2700_sprites.h
Normal file
73
engines/neverhood/modules/module2700_sprites.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NEVERHOOD_MODULES_MODULE2700_SPRITES_H
|
||||
#define NEVERHOOD_MODULES_MODULE2700_SPRITES_H
|
||||
|
||||
#include "neverhood/neverhood.h"
|
||||
#include "neverhood/module.h"
|
||||
#include "neverhood/scene.h"
|
||||
|
||||
namespace Neverhood {
|
||||
|
||||
class SsCommonTrackShadowBackground : public StaticSprite {
|
||||
public:
|
||||
SsCommonTrackShadowBackground(NeverhoodEngine *vm, uint32 fileHash);
|
||||
};
|
||||
|
||||
class AsCommonCarShadow : public AnimatedSprite {
|
||||
public:
|
||||
AsCommonCarShadow(NeverhoodEngine *vm, AnimatedSprite *asCar, const Common::SharedPtr<BaseSurface> &shadowSurface, uint index);
|
||||
protected:
|
||||
uint _index;
|
||||
AnimatedSprite *_asCar;
|
||||
uint32 _animFileHash;
|
||||
void update();
|
||||
void updateShadow();
|
||||
};
|
||||
|
||||
class AsCommonCarConnectorShadow : public AnimatedSprite {
|
||||
public:
|
||||
AsCommonCarConnectorShadow(NeverhoodEngine *vm, Sprite *asCar, const Common::SharedPtr<BaseSurface> &shadowSurface, uint index);
|
||||
protected:
|
||||
uint _index;
|
||||
Sprite *_asCar;
|
||||
void update();
|
||||
};
|
||||
|
||||
class AsCommonCarTrackShadow : public AnimatedSprite {
|
||||
public:
|
||||
AsCommonCarTrackShadow(NeverhoodEngine *vm, Sprite *asCar, const Common::SharedPtr<BaseSurface> &shadowSurface, int16 frameIndex);
|
||||
protected:
|
||||
Sprite *_asCar;
|
||||
void update();
|
||||
};
|
||||
|
||||
class KmScene2732 : public Klaymen {
|
||||
public:
|
||||
KmScene2732(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
|
||||
protected:
|
||||
uint32 xHandleMessage(int messageNum, const MessageParam ¶m) override;
|
||||
};
|
||||
|
||||
} // End of namespace Neverhood
|
||||
|
||||
#endif /* NEVERHOOD_MODULES_MODULE2700_SPRITES_H */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user