diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/neverhood/entity.h | 12 | ||||
-rw-r--r-- | engines/neverhood/klayman.cpp | 457 | ||||
-rw-r--r-- | engines/neverhood/klayman.h | 132 | ||||
-rw-r--r-- | engines/neverhood/module.mk | 1 | ||||
-rw-r--r-- | engines/neverhood/module1000.cpp | 4 | ||||
-rw-r--r-- | engines/neverhood/module1000.h | 1 | ||||
-rw-r--r-- | engines/neverhood/sprite.cpp | 2 | ||||
-rw-r--r-- | engines/neverhood/sprite.h | 11 |
8 files changed, 612 insertions, 8 deletions
diff --git a/engines/neverhood/entity.h b/engines/neverhood/entity.h index 18b9cba793..317672c7fe 100644 --- a/engines/neverhood/entity.h +++ b/engines/neverhood/entity.h @@ -28,14 +28,18 @@ namespace Neverhood { +class Entity; + struct MessageParam { union { uint32 _integer; NPoint _point; + Entity *_entity; // TODO: Other types... }; MessageParam(uint32 value) { _integer = value; } MessageParam(NPoint value) { _point = value; } + MessageParam(Entity *entity) { _entity = entity; } // TODO: Constructors for the param types... }; @@ -61,13 +65,17 @@ public: uint32 sendMessage(int messageNum, const MessageParam ¶m, Entity *sender) { return _messageHandlerCb ? (this->*_messageHandlerCb)(messageNum, param, sender) : 0; } - // Overloaded for various message parameter types + // 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(int messageNum, uint32 param, Entity *sender) { return sendMessage(messageNum, MessageParam(param), sender); } - uint32 sendMessage(int messageNum, NPoint param, Entity *sender) { + uint32 sendPointMessage(int messageNum, NPoint param, Entity *sender) { return sendMessage(messageNum, MessageParam(param), sender); } + uint32 sendEntityMessage(int messageNum, Entity *param, Entity *sender) { + return sendMessage(messageNum, MessageParam((Entity*)param), sender); + } int getPriority() const { return _priority; } protected: void (Entity::*_updateHandlerCb)(); diff --git a/engines/neverhood/klayman.cpp b/engines/neverhood/klayman.cpp new file mode 100644 index 0000000000..49c60932c1 --- /dev/null +++ b/engines/neverhood/klayman.cpp @@ -0,0 +1,457 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "neverhood/klayman.h" +#include "neverhood/resourceman.h" + +namespace Neverhood { + +static const KlaymanTableItem klaymanTable1[] = { + {1, &Klayman::sub41FD30}, + {1, &Klayman::sub41FDA0}, + {1, &Klayman::sub41FDF0}, + {1, &Klayman::sub41FE60}, + {1, &Klayman::sub41FEB0} +}; + +static const KlaymanTableItem klaymanTable2[] = { + {1, &Klayman::sub41FD30}, + {1, &Klayman::sub41FDA0}, + {1, &Klayman::sub41FE60}, + {1, &Klayman::sub41FEB0} +}; + +#if 0 +static const KlaymanTableItem klaymanTable3[] = { + {1, &Klayman::sub421430}, + {1, &Klayman::sub421480} +}; +#endif + +Klayman::Klayman(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y, int surfacePriority, int objectPriority) + : AnimatedSprite(vm, objectPriority), _soundResource1(vm), _soundResource2(vm), + _counterMax(0), _counter(0), _flagE4(false), _counter3Max(0), _flagF8(false), _counter1(0), + _counter2(0), /*_field118(0), */_status2(0), _flagE5(true), _attachedSprite(NULL), _flagE1(false), + _status(1), _parentScene(parentScene), _flagE2(false), _flagE3(false), _flagF6(false), _flagF7(false), + _flagFA(false), _statusE0(0) /*, _field114(0)*/, _resourceHandle(-1), _soundFlag(false) { + + // TODO + createSurface(surfacePriority, 320, 200); + _x = x; + _y = y; + _x4 = x; + _y4 = y; + _flags = 2; + setKlaymanTable1(); + sub41FC80(); + SetUpdateHandler(&Klayman::update); +} + +void Klayman::xUpdate() { +} + +uint32 Klayman::xHandleMessage(int messageNum, const MessageParam ¶m) { + return 0; +} + +void Klayman::update() { +} + +void Klayman::setKlaymanTable(const KlaymanTableItem *table, int tableCount) { + _table = table; + _tableCount = tableCount; + _tableMaxValue = 0; + for (int i = 0; i < tableCount; i++) { + _tableMaxValue += table[i].value; + } +} + +void Klayman::setKlaymanTable1() { + setKlaymanTable(klaymanTable1, ARRAYSIZE(klaymanTable1)); +} + +void Klayman::setKlaymanTable2() { + setKlaymanTable(klaymanTable2, ARRAYSIZE(klaymanTable2)); +} + +void Klayman::setKlaymanTable3() { + // TODO setKlaymanTable(klaymanTable3, ARRAYSIZE(klaymanTable3)); +} + +void Klayman::sub41FD30() { + sub41D320(0x5B20C814, AnimationCallback(&Klayman::sub41FD40)); +} + +void Klayman::sub41FD40() { + _status2 = 1; + _flagE5 = true; + setFileHash(0x5B20C814, 0, -1); + SetUpdateHandler(&Klayman::update); + SetMessageHandler(&Klayman::handleMessage41EB10); + SetSpriteCallback(NULL); + SetAnimationCallback3(&Klayman::sub41FCF0); + // TODO AnimatedSprite_setCallback1(AnimationCallback(&Klayman::sub41FD90)); +} + +uint32 Klayman::handleMessage41EB10(int messageNum, const MessageParam ¶m, Entity *sender) { + uint32 messageResult = handleMessage41D480(messageNum, param, sender); + switch (messageNum) { + case 0x100D: + if (param._integer == 0x04DBC02C) { +#if 0 + _soundResource1.set(0x44528AA1); + _soundResource1.load(); + _soundResource1.play(false); +#endif + } + break; + } + return messageResult; +} + +void Klayman::sub41FD90() { + // TODO _soundResource1.stop(0); +} + +void Klayman::sub41FDA0() { + sub41D320(0xD122C137, AnimationCallback(&Klayman::sub41FDB0)); +} + +void Klayman::sub41FDB0() { + _status2 = 1; + _flagE5 = true; + setFileHash(0xD122C137, 0, -1); + SetUpdateHandler(&Klayman::update); + SetMessageHandler(&Klayman::handleMessage41E980); + SetSpriteCallback(NULL); + SetAnimationCallback3(&Klayman::sub41FCF0); +} + +uint32 Klayman::handleMessage41E980(int messageNum, const MessageParam ¶m, Entity *sender) { + uint32 messageResult = handleMessage41D480(messageNum, param, sender); + switch (messageNum) { + case 0x100D: + if (param._integer == 0x808A0008) { +#if 0 + _soundResource1.set(0xD948A340); + _soundResource1.load(); + _soundResource1.play(false); +#endif + } + break; + } + return messageResult; +} + +void Klayman::sub41FDF0() { + sub41D320(0x543CD054, AnimationCallback(&Klayman::sub41FE00)); +} + +void Klayman::sub41FE00() { + _status2 = 1; + _flagE5 = true; + setFileHash(0x543CD054, 0, -1); + SetUpdateHandler(&Klayman::update); + SetMessageHandler(&Klayman::handleMessage41E9E0); + SetSpriteCallback(NULL); + SetAnimationCallback3(&Klayman::sub41FCF0); + // TODO AnimatedSprite_setCallback1(AnimationCallback(&Klayman::sub41FE50)); +} + +void Klayman::sub41FE50() { + // TODO _soundResource1.stop(0); +} + +uint32 Klayman::handleMessage41E9E0(int messageNum, const MessageParam ¶m, Entity *sender) { + uint32 messageResult = handleMessage41D480(messageNum, param, sender); + switch (messageNum) { + case 0x100D: + if (param._integer == 0x5A0F0104) { +#if 0 + _soundResource1.set(0x7970A100); + _soundResource1.load(); + _soundResource1.play(false); +#endif + } else if (param._integer == 0x9A9A0109) { +#if 0 + _soundResource1.set(0xD170CF04); + _soundResource1.load(); + _soundResource1.play(false); +#endif + } else if (param._integer == 0x989A2169) { +#if 0 + _soundResource1.set(0xD073CF14); + _soundResource1.load(); + _soundResource1.play(false); +#endif + } + break; + } + return messageResult; +} + +void Klayman::sub41FE60() { + sub41D320(0x40A0C034, AnimationCallback(&Klayman::sub41FE70)); +} + +void Klayman::sub41FE70() { + _status2 = 1; + _flagE5 = true; + setFileHash(0x40A0C034, 0, -1); + SetUpdateHandler(&Klayman::update); + SetMessageHandler(&Klayman::handleMessage41EF80); + SetSpriteCallback(NULL); + SetAnimationCallback3(&Klayman::sub41FCF0); +} + +uint32 Klayman::handleMessage41EF80(int messageNum, const MessageParam ¶m, Entity *sender) { + uint32 messageResult = handleMessage41D480(messageNum, param, sender); + switch (messageNum) { + case 0x100D: + if (param._integer == 0x0D2A0288) { +#if 0 + _soundResource1.set(0xD192A368); + _soundResource1.load(); + _soundResource1.play(false); +#endif + } + break; + } + return messageResult; +} + +void Klayman::sub41FEB0() { + sub41D320(0x5120E137, AnimationCallback(&Klayman::sub41FEC0)); +} + +void Klayman::sub41FEC0() { + _status2 = 1; + _flagE5 = true; + setFileHash(0x5120E137, 0, -1); + SetUpdateHandler(&Klayman::update); + SetMessageHandler(&Klayman::handleMessage41EFE0); + SetSpriteCallback(NULL); + SetAnimationCallback3(&Klayman::sub41FCF0); +} + +uint32 Klayman::handleMessage41EFE0(int messageNum, const MessageParam ¶m, Entity *sender) { + uint32 messageResult = handleMessage41D480(messageNum, param, sender); + switch (messageNum) { + case 0x100D: + if (param._integer == 0xC006000C) { +#if 0 + _soundResource1.set(0x9D406340); + _soundResource1.load(); + _soundResource1.play(false); +#endif + } else if (param._integer == 0x2E4A2940) { +#if 0 + _soundResource1.set(0x53A4A1D4); + _soundResource1.load(); + _soundResource1.play(false); +#endif + } else if (param._integer == 0xAA0A0860) { +#if 0 + _soundResource1.set(0x5BE0A3C6); + _soundResource1.load(); + _soundResource1.play(false); +#endif + } else if (param._integer == 0xC0180260) { +#if 0 + _soundResource1.set(0x5D418366); + _soundResource1.load(); + _soundResource1.play(false); +#endif + } + break; + } + return messageResult; +} + +///////////////////////////////////////////////////////////////// + +void Klayman::sub41D320(uint32 fileHash, AnimationCb callback) { + _resourceHandle = _vm->_res->useResource(fileHash); + if (_resourceHandle != -1) { + // TODO _vm->_res->moveToFront(_resourceHandle); + SetAnimationCallback3(callback); + SetUpdateHandler(&Klayman::update41D2B0); + } +} + +void Klayman::update41D2B0() { + // TODO Check if this odd stuff is needed or just some cache optimization + if (_vm->_res->isResourceDataValid(_resourceHandle)) { + sub41C7B0(); + // TODO _vm->_res->moveToBack(_resourceHandle); + _vm->_res->unuseResource(_resourceHandle); + _resourceHandle = -1; + } else { + // TODO _vm->_res->moveToFront(_resourceHandle); + } + update(); +} + +bool Klayman::sub41CF10(AnimationCb callback) { + if (_status2 != 2) + return false; + _status2 = 1; + setFileHash(0x9A7020B8, 0, -1); + SetUpdateHandler(&Klayman::update); + SetMessageHandler(&Klayman::handleMessage41F140); + SetSpriteCallback(NULL); + SetAnimationCallback3(callback); + _flagE5 = false; + return true; +} + +void Klayman::sub41C7B0() { + if (_callback1Cb) { + (this->*_callback1Cb)(); + _callback1Cb = NULL; + } + if (_callback3Cb) { + AnimationCb cb = _callback3Cb; + _callback3Cb = NULL; + (this->*cb)(); +#if 0 // TODO + } else if (_callbackList) { + removeCallbackList(); +#endif + } else { + _parentScene->sendMessage(0x1006, 0, this); + } +} + +void Klayman::sub41C770() { + _flagFA = false; + _status = 1; +} + +void Klayman::sub41C790() { + if (_flagFA) + _status = 0; +} + +void Klayman::sub41FC80() { + if (!sub41CF10(AnimationCallback(&Klayman::sub41FC80))) { + setFileHash(0x5420E254, 0, -1); + _counter = 0; + _counter3 = 0; + _counter3Max = _vm->_rnd->getRandomNumber(64) + 24; + SetUpdateHandler(&Klayman::update41D0F0); + SetMessageHandler(&Klayman::handleMessage41D360); + SetSpriteCallback(NULL); + } +} + +void Klayman::update41D0F0() { + update(); + _counter++; + if (_counter >= 720) { + _counter = 0; + if (_table) { + int randomValue = _vm->_rnd->getRandomNumber(_tableMaxValue); + for (int i = 0; i < _tableCount; i++) { + if (randomValue < _table[_tableCount].value) { + (this->*(_table[_tableCount].callback))(); + break; + } + randomValue -= _table[_tableCount].value; + } + } + } else { + _counter3++; + if (_counter3 >= _counter3Max) { + _counter3 = 0; + _counter3Max = _vm->_rnd->getRandomNumber(64) + 24; + sub41FF00(); + } + } +} + +uint32 Klayman::handleMessage41D360(int messageNum, const MessageParam ¶m, Entity *sender) { + Sprite::handleMessage(messageNum, param, sender); + uint32 messageResult = xHandleMessage(messageNum, param); + switch (messageNum) { + case 0x1008: + messageResult = _flagE5; + break; + case 0x1014: + _attachedSprite = param._entity; + break; + case 0x1019: + sub41C7B0(); + break; + case 0x101C: + sub41C770(); + break; + case 0x1021: + sub41C790(); + break; + case 0x481C: + _status = param._integer; + _flagFA = true; + messageResult = 1; + break; + case 0x482C: + if (param._integer != 0) { + // TODO _rectResource.getRectangle2(param._integer, &_field118, &_field114,); + } else { + // TODO _field114 = 0; + } + break; + } + return messageResult; +} + +void Klayman::sub41FF00() { + setFileHash(0x5900C41E, 0, -1); + _status2 = 1; + _flagE5 = true; + SetUpdateHandler(&Klayman::update); + SetMessageHandler(&Klayman::handleMessage41D480); + SetSpriteCallback(NULL); + SetAnimationCallback3(&Klayman::sub41FCF0); +} + +uint32 Klayman::handleMessage41D480(int messageNum, const MessageParam ¶m, Entity *sender) { + uint32 messageResult = handleMessage41D360(messageNum, param, sender); + switch (messageNum) { + case 0x3002: + sub41C7B0(); + break; + } + return messageResult; +} + +void Klayman::sub41FCF0() { + _status2 = 1; + _flagE5 = true; + setFileHash(0x5420E254, 0, -1); + SetUpdateHandler(&Klayman::update41D0F0); + SetMessageHandler(&Klayman::handleMessage41D360); + SetSpriteCallback(NULL); +} + + +} // End of namespace Neverhood diff --git a/engines/neverhood/klayman.h b/engines/neverhood/klayman.h new file mode 100644 index 0000000000..d953f5565f --- /dev/null +++ b/engines/neverhood/klayman.h @@ -0,0 +1,132 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef NEVERHOOD_KLAYMAN_H +#define NEVERHOOD_KLAYMAN_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 + +class Klayman; + +struct KlaymanTableItem { + int value; + void (Klayman::*callback)(); +}; + +class Klayman : public AnimatedSprite { +public: + Klayman(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y, int surfacePriority, int objectPriority); + + void sub41FD30(); + void sub41FDA0(); + void sub41FDF0(); + void sub41FE60(); + void sub41FEB0(); + +protected: + Entity *_parentScene; + Entity *_attachedSprite; + int _statusE0; + bool _flagE1; + bool _flagE2; + bool _flagE3; + bool _flagE4; + bool _flagE5; + int16 _x4, _y4; + int16 _counter, _counterMax; + int16 _counter3, _counter3Max; + int16 _counter1; + int16 _counter2; + bool _flagF6; + bool _flagF7; + bool _flagF8; + int _status2; + bool _flagFA; + SoundResource _soundResource1; + SoundResource _soundResource2; + int _status; + const KlaymanTableItem *_table; + int _tableCount; + int _tableMaxValue; + /* + 00000114 field114 dd ? + 00000118 field118 dw ? + */ + bool _soundFlag; + int _resourceHandle; + virtual void xUpdate(); + virtual uint32 xHandleMessage(int messageNum, const MessageParam ¶m); + void update(); + + void setKlaymanTable(const KlaymanTableItem *table, int tableCount); + void setKlaymanTable1(); + void setKlaymanTable2(); + void setKlaymanTable3(); + + void sub41FD40(); + void sub41FD90(); + uint32 handleMessage41EB10(int messageNum, const MessageParam ¶m, Entity *sender); + + void sub41FDB0(); + uint32 handleMessage41E980(int messageNum, const MessageParam ¶m, Entity *sender); + + void sub41FE00(); + void sub41FE50(); + uint32 handleMessage41E9E0(int messageNum, const MessageParam ¶m, Entity *sender); + + void sub41FE70(); + uint32 handleMessage41EF80(int messageNum, const MessageParam ¶m, Entity *sender); + + void sub41FEC0(); + uint32 handleMessage41EFE0(int messageNum, const MessageParam ¶m, Entity *sender); + + void sub41D320(uint32 fileHash, AnimationCb callback); + void update41D2B0(); + + bool sub41CF10(AnimationCb callback); + void sub41C7B0(); + void sub41C770(); + void sub41C790(); + + void sub41FC80(); + void update41D0F0(); + uint32 handleMessage41D360(int messageNum, const MessageParam ¶m, Entity *sender); + + void sub41FF00(); + uint32 handleMessage41D480(int messageNum, const MessageParam ¶m, Entity *sender); + + void sub41FCF0(); + + uint32 handleMessage41F140(int messageNum, const MessageParam ¶m, Entity *sender); + +}; + +} // End of namespace Neverhood + +#endif /* NEVERHOOD_KLAYMAN_H */ diff --git a/engines/neverhood/module.mk b/engines/neverhood/module.mk index f139268c36..2058db9e3e 100644 --- a/engines/neverhood/module.mk +++ b/engines/neverhood/module.mk @@ -8,6 +8,7 @@ MODULE_OBJS = \ entity.o \ gamemodule.o \ graphics.o \ + klayman.o \ module.o \ module1000.o \ module1500.o \ diff --git a/engines/neverhood/module1000.cpp b/engines/neverhood/module1000.cpp index d5b7b03481..7ee1090cb8 100644 --- a/engines/neverhood/module1000.cpp +++ b/engines/neverhood/module1000.cpp @@ -469,6 +469,10 @@ Scene1001::Scene1001(NeverhoodEngine *vm, Module *parentModule, int which) } +Scene1001::~Scene1001() { + // TODO _vm->setGlobalVar(0xC0418A02, _playerSprite->_doDeltaX); +} + uint32 Scene1001::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { uint32 messageResult = 0; Scene::handleMessage(messageNum, param, sender); diff --git a/engines/neverhood/module1000.h b/engines/neverhood/module1000.h index 82c2feab13..21be948c41 100644 --- a/engines/neverhood/module1000.h +++ b/engines/neverhood/module1000.h @@ -109,6 +109,7 @@ protected: class Scene1001 : public Scene { public: Scene1001(NeverhoodEngine *vm, Module *parentModule, int which); + virtual ~Scene1001(); protected: Sprite *_asHammer; Sprite *_asDoor; diff --git a/engines/neverhood/sprite.cpp b/engines/neverhood/sprite.cpp index 1239a301d0..ce21527384 100644 --- a/engines/neverhood/sprite.cpp +++ b/engines/neverhood/sprite.cpp @@ -456,7 +456,7 @@ void AnimatedSprite::removeCallbacks() { if (_callback1Cb) { // _callback1Cb has to be cleared before it's called - AnimationCallback cb = _callback1Cb; + AnimationCb cb = _callback1Cb; _callback1Cb = NULL; debug("Fire _callback1Cb"); (this->*cb)(); diff --git a/engines/neverhood/sprite.h b/engines/neverhood/sprite.h index 71067fa9ec..b3809a845e 100644 --- a/engines/neverhood/sprite.h +++ b/engines/neverhood/sprite.h @@ -30,7 +30,7 @@ namespace Neverhood { -#define SetSpriteCallback(callback) _spriteCallbackCb = static_cast <void (Sprite::*)(void)> (callback) +#define SetSpriteCallback(callback) _spriteUpdateCb = static_cast <void (Sprite::*)(void)> (callback) #define SetFilterX(callback) _filterXCb = static_cast <int16 (Sprite::*)(int16)> (callback) #define SetFilterY(callback) _filterYCb = static_cast <int16 (Sprite::*)(int16)> (callback) @@ -91,6 +91,7 @@ protected: #define SetAnimationCallback1(callback) _callback1Cb = static_cast <void (AnimatedSprite::*)(void)> (callback) #define SetAnimationCallback2(callback) _callback2Cb = static_cast <void (AnimatedSprite::*)(void)> (callback) #define SetAnimationCallback3(callback) _callback3Cb = static_cast <void (AnimatedSprite::*)(void)> (callback) +#define AnimationCallback(callback) static_cast <void (AnimatedSprite::*)()> (callback) class AnimatedSprite : public Sprite { public: @@ -98,7 +99,7 @@ public: AnimatedSprite(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority, int16 x, int16 y); void update(); protected: - typedef void (AnimatedSprite::*AnimationCallback)(); + typedef void (AnimatedSprite::*AnimationCb)(); AnimResource _animResource; uint32 _fileHash1; uint32 _fileHash2; @@ -124,9 +125,9 @@ protected: callbackListCount dw ? callbackList dd ? */ - AnimationCallback _callback1Cb; - AnimationCallback _callback2Cb; - AnimationCallback _callback3Cb; + AnimationCb _callback1Cb; + AnimationCb _callback2Cb; + AnimationCb _callback3Cb; void init(); void updateDeltaXY(); void updateAnim(); |