aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/neverhood/collisionman.h2
-rw-r--r--engines/neverhood/entity.h33
-rw-r--r--engines/neverhood/gamemodule.cpp6
-rw-r--r--engines/neverhood/klayman.cpp419
-rw-r--r--engines/neverhood/klayman.h32
-rw-r--r--engines/neverhood/module.cpp8
-rw-r--r--engines/neverhood/module1000.cpp174
-rw-r--r--engines/neverhood/module1000.h9
-rw-r--r--engines/neverhood/neverhood.cpp2
-rw-r--r--engines/neverhood/resource.cpp20
-rw-r--r--engines/neverhood/resource.h6
-rw-r--r--engines/neverhood/scene.cpp204
-rw-r--r--engines/neverhood/scene.h19
-rw-r--r--engines/neverhood/sprite.cpp30
-rw-r--r--engines/neverhood/sprite.h6
15 files changed, 770 insertions, 200 deletions
diff --git a/engines/neverhood/collisionman.h b/engines/neverhood/collisionman.h
index 426dca0c95..155859923b 100644
--- a/engines/neverhood/collisionman.h
+++ b/engines/neverhood/collisionman.h
@@ -42,6 +42,8 @@ public:
void clearSprites();
void save();
void restore();
+ uint getSpriteCount() const { return _sprites.size(); }
+ Sprite *getSprite(uint index) const { return _sprites[index]; }
protected:
NeverhoodEngine *_vm;
HitRectList *_hitRects;
diff --git a/engines/neverhood/entity.h b/engines/neverhood/entity.h
index 64c1181089..29bf6be988 100644
--- a/engines/neverhood/entity.h
+++ b/engines/neverhood/entity.h
@@ -30,16 +30,43 @@ namespace Neverhood {
class Entity;
+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 {
+ assert(_type == mptInteger);
+ return _integer;
+ }
+ NPoint asPoint() const {
+ assert(_type == mptInteger || _type == mptPoint);
+ if (_type == mptInteger) {
+ NPoint pt;
+ pt.x = (_integer >> 16) & 0xFFFF;
+ pt.y = _integer & 0xFFFF;
+ return pt;
+ }
+ return _point;
+ }
+ Entity *asEntity() const {
+ assert(_type == mptEntity);
+ return _entity;
+ }
+protected:
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; }
+ MessageParamType _type;
// TODO: Constructors for the param types...
};
diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp
index c63131dcf3..47fff17cda 100644
--- a/engines/neverhood/gamemodule.cpp
+++ b/engines/neverhood/gamemodule.cpp
@@ -78,17 +78,17 @@ uint32 GameModule::handleMessage(int messageNum, const MessageParam &param, Enti
_field24 = -1;
_field26 = -1;
_field28 = -1;
- _field20 = param._integer;
+ _field20 = param.asInteger();
_done = true;
return messageResult;
case 0x100A:
- _field24 = (int16)param._integer;
+ _field24 = (int16)param.asInteger();
return messageResult;
case 0x101F:
_field2C = true;
return messageResult;
case 0x1023:
- _field26 = (int16)param._integer;
+ _field26 = (int16)param.asInteger();
return messageResult;
}
return messageResult;
diff --git a/engines/neverhood/klayman.cpp b/engines/neverhood/klayman.cpp
index 7a775bcf12..eca8e02df4 100644
--- a/engines/neverhood/klayman.cpp
+++ b/engines/neverhood/klayman.cpp
@@ -21,7 +21,9 @@
*/
#include "neverhood/klayman.h"
+#include "neverhood/collisionman.h"
#include "neverhood/resourceman.h"
+#include "neverhood/staticdata.h"
namespace Neverhood {
@@ -52,7 +54,7 @@ Klayman::Klayman(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y, int
_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) {
+ _flagFA(false), _statusE0(0), _field114(0), _resourceHandle(-1), _soundFlag(false) {
// TODO
createSurface(surfacePriority, 320, 200);
@@ -74,13 +76,13 @@ uint32 Klayman::xHandleMessage(int messageNum, const MessageParam &param) {
switch (messageNum) {
case 0x4001:
case 0x4800:
- sub41C930(param._point.x, false);
+ sub41C930(param.asPoint().x, false);
break;
case 0x4004:
- // TODO AnimatedSprite_setCallback2(AnimationCallback(&sub41FC80));
+ setCallback2(AnimationCallback(&Klayman::sub41FC80));
break;
case 0x4818:
- // TODO sub41C930(_rectResource.getRectangle1(param._integer).x, false);
+ // TODO sub41C930(_rectResource.getRectangle1(param.asInteger()).x, false);
break;
}
return 0;
@@ -124,19 +126,15 @@ void Klayman::sub41FD40() {
SetMessageHandler(&Klayman::handleMessage41EB10);
SetSpriteCallback(NULL);
SetAnimationCallback3(&Klayman::sub41FCF0);
- // TODO AnimatedSprite_setCallback1(AnimationCallback(&Klayman::sub41FD90));
+ setCallback1(AnimationCallback(&Klayman::sub41FD90));
}
uint32 Klayman::handleMessage41EB10(int messageNum, const MessageParam &param, 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
+ if (param.asInteger() == 0x04DBC02C) {
+ _soundResource1.play(0x44528AA1);
}
break;
}
@@ -165,12 +163,8 @@ uint32 Klayman::handleMessage41E980(int messageNum, const MessageParam &param, E
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
+ if (param.asInteger() == 0x808A0008) {
+ _soundResource1.play(0xD948A340);
}
break;
}
@@ -189,7 +183,7 @@ void Klayman::sub41FE00() {
SetMessageHandler(&Klayman::handleMessage41E9E0);
SetSpriteCallback(NULL);
SetAnimationCallback3(&Klayman::sub41FCF0);
- // TODO AnimatedSprite_setCallback1(AnimationCallback(&Klayman::sub41FE50));
+ setCallback1(AnimationCallback(&Klayman::sub41FE50));
}
void Klayman::sub41FE50() {
@@ -200,24 +194,12 @@ uint32 Klayman::handleMessage41E9E0(int messageNum, const MessageParam &param, E
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
+ if (param.asInteger() == 0x5A0F0104) {
+ _soundResource1.play(0x7970A100);
+ } else if (param.asInteger() == 0x9A9A0109) {
+ _soundResource1.play(0xD170CF04);
+ } else if (param.asInteger() == 0x989A2169) {
+ _soundResource1.play(0xD073CF14);
}
break;
}
@@ -242,12 +224,8 @@ uint32 Klayman::handleMessage41EF80(int messageNum, const MessageParam &param, E
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
+ if (param.asInteger() == 0x0D2A0288) {
+ _soundResource1.play(0xD192A368);
}
break;
}
@@ -272,30 +250,14 @@ uint32 Klayman::handleMessage41EFE0(int messageNum, const MessageParam &param, E
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
+ if (param.asInteger() == 0xC006000C) {
+ _soundResource1.play(0x9D406340);
+ } else if (param.asInteger() == 0x2E4A2940) {
+ _soundResource1.play(0x53A4A1D4);
+ } else if (param.asInteger() == 0xAA0A0860) {
+ _soundResource1.play(0x5BE0A3C6);
+ } else if (param.asInteger() == 0xC0180260) {
+ _soundResource1.play(0x5D418366);
}
break;
}
@@ -405,6 +367,7 @@ void Klayman::update41D0F0() {
}
uint32 Klayman::handleMessage41D360(int messageNum, const MessageParam &param, Entity *sender) {
+ debug("Klayman::handleMessage41D360(%04X)", messageNum);
Sprite::handleMessage(messageNum, param, sender);
uint32 messageResult = xHandleMessage(messageNum, param);
switch (messageNum) {
@@ -412,7 +375,7 @@ uint32 Klayman::handleMessage41D360(int messageNum, const MessageParam &param, E
messageResult = _flagE5;
break;
case 0x1014:
- _attachedSprite = param._entity;
+ _attachedSprite = param.asEntity();
break;
case 0x1019:
sub41C7B0();
@@ -424,13 +387,13 @@ uint32 Klayman::handleMessage41D360(int messageNum, const MessageParam &param, E
sub41C790();
break;
case 0x481C:
- _status = param._integer;
+ _status = param.asInteger();
_flagFA = true;
messageResult = 1;
break;
case 0x482C:
- if (param._integer != 0) {
- // TODO _rectResource.getRectangle2(param._integer, &_field118, &_field114,);
+ if (param.asInteger() != 0) {
+ // TODO _rectResource.getRectangle2(param.asInteger(), &_field118, &_field114,);
} else {
// TODO _field114 = 0;
}
@@ -440,9 +403,9 @@ uint32 Klayman::handleMessage41D360(int messageNum, const MessageParam &param, E
}
void Klayman::sub41FF00() {
- setFileHash(0x5900C41E, 0, -1);
_status2 = 1;
_flagE5 = true;
+ setFileHash(0x5900C41E, 0, -1);
SetUpdateHandler(&Klayman::update);
SetMessageHandler(&Klayman::handleMessage41D480);
SetSpriteCallback(NULL);
@@ -472,18 +435,10 @@ uint32 Klayman::handleMessage41F140(int messageNum, const MessageParam &param, E
uint32 messageResult = handleMessage41D480(messageNum, param, sender);
switch (messageNum) {
case 0x100D:
- if (param._integer == 0x271AA210) {
-#if 0
- _soundResource1.set(0x4924AAC4);
- _soundResource1.load();
- _soundResource1.play(false);
-#endif
- } else if (param._integer == 0x2B22AA81) {
-#if 0
- _soundResource1.set(0x0A2AA8E0);
- _soundResource1.load();
- _soundResource1.play(false);
-#endif
+ if (param.asInteger() == 0x271AA210) {
+ _soundResource1.play(0x4924AAC4);
+ } else if (param.asInteger() == 0x2B22AA81) {
+ _soundResource1.play(0x0A2AA8E0);
}
break;
}
@@ -492,33 +447,323 @@ uint32 Klayman::handleMessage41F140(int messageNum, const MessageParam &param, E
void Klayman::sub41C930(int16 x, bool flag) {
+ debug("Klayman::sub41C930(%d, %d)", x, flag);
int16 xdiff = ABS(x - _x);
if (xdiff == 0) {
_x4 = x;
if (_flagE1 || _flagE2 || _flagE3) {
- // TODO AnimatedSprite_setCallback2(NULL);
+ setCallback2(NULL);
sub41C7B0();
}
} else if (xdiff <= 36 && !_flagE1 && !_flagE2 && !_flagE3) {
_x4 = x;
- // TODO AnimatedSprite_setCallback2(NULL);
+ setCallback2(NULL);
sub41C7B0();
} else if (xdiff <= 42 && _status != 3) {
if (_flagE2 && ((!_doDeltaX && x - _x > 0) || (_doDeltaX && x - _x < 0)) && ABS(_x4 - _x) > xdiff) {
_x4 = x;
} else {
_x4 = x;
- // TODO AnimatedSprite_setCallback2(AnimationCallback(&Klayman::sub41FB40));
+ setCallback2(AnimationCallback(&Klayman::sub41FB40));
}
} else if (_flagE1 && ((!_doDeltaX && x - _x > 0) || (_doDeltaX && x - _x < 0))) {
_x4 = x;
} else if (flag) {
_x4 = x;
+ debug("#### 1");
// TODO AnimatedSprite_setCallback2(AnimationCallback(&Klayman::sub421550));
} else {
_x4 = x;
- // TODO AnimatedSprite_setCallback2(AnimationCallback(&Klayman::sub41F950));
+ setCallback2(AnimationCallback(&Klayman::sub41F950));
+ }
+}
+
+void Klayman::sub4211F0() {
+ _status2 = 1;
+ _flagE5 = false;
+ setFileHash(0x527AC970, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41D480);
+ SetSpriteCallback(NULL);
+}
+
+void Klayman::sub4211B0() {
+ _status2 = 0;
+ _flagE5 = true;
+ setFileHash(0x5A38C110, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41E920);
+ SetSpriteCallback(NULL);
+}
+
+uint32 Klayman::handleMessage41E920(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage41D360(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x03060012) {
+ _soundResource1.play(0xC0238244);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+bool Klayman::sub41CEB0(AnimationCb callback3) {
+ if (_status2 == 1) {
+ _status2 = 2;
+ _flagE5 = false;
+ setFileHash(0x5C7080D4, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41F140);
+ SetSpriteCallback(&Klayman::spriteUpdate41F250);
+ SetAnimationCallback3(callback3);
+ return true;
+ } else {
+ _x = _x4;
+ return false;
+ }
+}
+
+void Klayman::spriteUpdate41F250() {
+ debug("Klayman::spriteUpdate41F250()");
+}
+
+void Klayman::spriteUpdate41F5F0() {
+ debug("Klayman::spriteUpdate41F5F0()");
+}
+
+void Klayman::sub41FB40() {
+ _status2 = 1;
+ _flagE2 = true;
+ _flagE5 = true;
+ setDoDeltaX(_x4 < _x);
+ setFileHash(0x5C48C506, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41DD80);
+ SetSpriteCallback(&Klayman::spriteUpdate41F5F0);
+ setCallback1(AnimationCallback(&Klayman::sub41FBB0));
+}
+
+void Klayman::sub41FBB0() {
+ _flagE2 = false;
+}
+
+uint32 Klayman::handleMessage41DD80(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage41D360(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x32180101) {
+ _soundResource1.play(0x4924AAC4);
+ } else if (param.asInteger() == 0x0A2A9098) {
+ _soundResource1.play(0x0A2AA8E0);
+ } else if (param.asInteger() == 0x32188010) {
+ if (_soundFlag) {
+ _soundResource1.play(0x48498E46);
+ } else {
+ _soundResource1.play(0x405002D8);
+ }
+ } else if (param.asInteger() == 0x02A2909C) {
+ if (_soundFlag) {
+ _soundResource1.play(0x50399F64);
+ } else {
+ _soundResource1.play(0x0460E2FA);
+ }
+ }
+ break;
+ case 0x3002:
+ _x = _x4;
+ sub41C7B0();
+ break;
}
+ return messageResult;
+}
+
+void Klayman::sub41CD70(int16 x) {
+ if (x > _x) {
+ if (ABS(x - _x) <= 105) {
+ debug("// TODO sub41CAC0(x);");
+ // TODO sub41CAC0(x);
+ } else {
+ sub41C930(x, false);
+ }
+ } else if (x == _x) {
+ _x4 = x;
+ setCallback2(NULL);
+ sub41C7B0();
+ } else {
+ sub41C930(x, false);
+ }
+}
+
+void Klayman::sub41F950() {
+ if (!sub41CF10(AnimationCallback(&Klayman::sub41F950))) {
+ _status2 = 0;
+ _flagE1 = true;
+ _flagE5 = true;
+ setDoDeltaX(_x4 < _x);
+ setFileHash(0x242C0198, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41EC70);
+ SetSpriteCallback(&Klayman::spriteUpdate41F320);
+ setCallback1(AnimationCallback(&Klayman::sub41FB30));
+ SetAnimationCallback3(&Klayman::sub41F9E0);
+ }
+}
+
+void Klayman::sub41FB30() {
+ _flagE1 = false;
+}
+
+uint32 Klayman::handleMessage41EC70(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage41D360(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x32180101) {
+ if (_soundFlag) {
+ _soundResource1.play(0x48498E46);
+ } else {
+ _soundResource1.play(0x405002D8);
+ }
+ } else if (param.asInteger() == 0x0A2A9098) {
+ if (_soundFlag) {
+ _soundResource1.play(0x50399F64);
+ } else {
+ _soundResource1.play(0x0460E2FA);
+ }
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void Klayman::sub41F9E0() {
+ _status2 = 0;
+ _flagE1 = true;
+ _flagE5 = true;
+ setFileHash(0x1A249001, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41EB70);
+ SetSpriteCallback(&Klayman::spriteUpdate41F300);
+ setCallback1(AnimationCallback(&Klayman::sub41FB30));
+ SetAnimationCallback3(&Klayman::sub41FA40);
+}
+
+void Klayman::spriteUpdate41F300() {
+ SetSpriteCallback(&Klayman::spriteUpdate41F320);
+ _deltaX = 0;
+}
+
+uint32 Klayman::handleMessage41EB70(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage41D360(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x32180101) {
+ if (_soundFlag) {
+ _soundResource1.play(0x48498E46);
+ } else {
+ _soundResource1.play(0x405002D8);
+ }
+ } else if (param.asInteger() == 0x0A2A9098) {
+ if (_soundFlag) {
+ _soundResource1.play(0x50399F64);
+ } else {
+ _soundResource1.play(0x0460E2FA);
+ }
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void Klayman::sub41FA40() {
+ if (_status == 2) {
+ sub41C7B0();
+ } else if (_status == 3) {
+ debug("// TODO sub420F20();");
+ // TODO sub420F20();
+ } else {
+ _flagE2 = true;
+ if (ABS(_x4 - _x) <= 42 && _frameIndex >= 5 && _frameIndex <= 11) {
+ if (_status == 0) {
+ _status2 = 1;
+ setFileHash(0xF234EE31, 0, -1);
+ } else {
+ _status2 = 2;
+ setFileHash(0xF135CC21, 0, -1);
+ }
+ } else if (ABS(_x4 - _x) <= 10 && (_frameIndex >= 12 || _frameIndex <= 4)) {
+ if (_status == 0) {
+ _status2 = 1;
+ setFileHash(0x8604A152, 0, -1);
+ } else {
+ _status2 = 2;
+ setFileHash(0xA246A132, 0, -1);
+ }
+ }
+ _flagE5 = true;
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41DD80);
+ SetSpriteCallback(&Klayman::spriteUpdate41F5F0);
+ setCallback1(AnimationCallback(&Klayman::sub41FBB0));
+ }
+}
+
+void Klayman::spriteUpdate41F320() {
+ int16 xdiff = ABS(_x4 - _x);
+ int16 xdelta = _x4 - _x;
+
+ if (xdelta > _deltaX)
+ xdelta = _deltaX;
+ else if (xdelta < _deltaX)
+ xdelta = -_deltaX;
+
+ _deltaX = 0;
+
+ if (xdiff == 0) {
+ sendMessage(0x1019, 0, this);
+ } else if (_status != 2 && _status != 3 && xdiff <= 42 && _frameIndex >= 5 && _frameIndex <= 11) {
+ sendMessage(0x1019, 0, this);
+ } else if (_status != 2 && _status != 3 && xdiff <= 10 && (_frameIndex >= 12 || _frameIndex <= 4)) {
+ sendMessage(0x1019, 0, this);
+ } else if (_status == 3 && xdiff < 30) {
+ sendMessage(0x1019, 0, this);
+ } else if (_status == 3 && xdiff < 150 && _frameIndex >= 6) {
+ sendMessage(0x1019, 0, this);
+ } else {
+ HitRect *hitRectPrev = _vm->_collisionMan->findHitRectAtPos(_x, _y);
+ _x += xdelta;
+ if (_field114) {
+ debug("_field114");
+ // TODO KlaymanSprite_sub_41CF70
+ } else {
+ HitRect *hitRectNext = _vm->_collisionMan->findHitRectAtPos(_x, _y);
+ if (hitRectNext->type == 0x5002) {
+ _y = MAX<int16>(hitRectNext->rect.y1, hitRectNext->rect.y2 - (hitRectNext->rect.x2 - _x) / 2);
+ } else if (hitRectNext->type == 0x5003) {
+ _y = MAX<int16>(hitRectNext->rect.y1, hitRectNext->rect.y2 - (_x - hitRectNext->rect.x1) / 2);
+ } else if (hitRectPrev->type == 0x5002) {
+ if (xdelta > 0) {
+ _y = hitRectPrev->rect.y2;
+ } else {
+ _y = hitRectPrev->rect.y1;
+ }
+ } else if (hitRectPrev->type == 0x5003) {
+ if (xdelta < 0) {
+ _y = hitRectPrev->rect.y2;
+ } else {
+ _y = hitRectPrev->rect.y1;
+ }
+ } else if (_flagF6 && xdelta != 0) {
+ if (hitRectNext->type == 0x5000) {
+ _y++;
+ } else if (hitRectNext->type == 0x5001 && _y > hitRectNext->rect.y1) {
+ _y--;
+ }
+ }
+ }
+ processDelta();
+ }
+
}
} // End of namespace Neverhood
diff --git a/engines/neverhood/klayman.h b/engines/neverhood/klayman.h
index 69f9a34dc6..50a12ae6a4 100644
--- a/engines/neverhood/klayman.h
+++ b/engines/neverhood/klayman.h
@@ -41,13 +41,21 @@ struct KlaymanTableItem {
class Klayman : public AnimatedSprite {
public:
- Klayman(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y, int surfacePriority, int objectPriority);
+ Klayman(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y, int surfacePriority = 1000, int objectPriority = 1000);
+
+ void update();
void sub41FD30();
void sub41FDA0();
void sub41FDF0();
void sub41FE60();
void sub41FEB0();
+ void sub41FC80();
+ void sub4211F0();
+ void sub4211B0();
+
+ void spriteUpdate41F250();
+ void spriteUpdate41F5F0();
protected:
Entity *_parentScene;
@@ -74,15 +82,14 @@ protected:
const KlaymanTableItem *_table;
int _tableCount;
int _tableMaxValue;
+ uint32 _field114;
/*
- 00000114 field114 dd ?
00000118 field118 dw ?
*/
bool _soundFlag;
int _resourceHandle;
virtual void xUpdate();
virtual uint32 xHandleMessage(int messageNum, const MessageParam &param);
- void update();
void setKlaymanTable(const KlaymanTableItem *table, int tableCount);
void setKlaymanTable1();
@@ -114,7 +121,6 @@ protected:
void sub41C770();
void sub41C790();
- void sub41FC80();
void update41D0F0();
uint32 handleMessage41D360(int messageNum, const MessageParam &param, Entity *sender);
@@ -126,6 +132,24 @@ protected:
uint32 handleMessage41F140(int messageNum, const MessageParam &param, Entity *sender);
void sub41C930(int16 x, bool flag);
+
+ uint32 handleMessage41E920(int messageNum, const MessageParam &param, Entity *sender);
+
+ bool sub41CEB0(AnimationCb callback3);
+
+ void sub41FB40();
+ void sub41FBB0();
+ uint32 handleMessage41DD80(int messageNum, const MessageParam &param, Entity *sender);
+ void sub41CD70(int16 x);
+ void sub41F950();
+ void sub41FB30();
+ uint32 handleMessage41EC70(int messageNum, const MessageParam &param, Entity *sender);
+ void sub41F9E0();
+ void spriteUpdate41F300();
+ uint32 handleMessage41EB70(int messageNum, const MessageParam &param, Entity *sender);
+ void sub41FA40();
+
+ void spriteUpdate41F320();
};
diff --git a/engines/neverhood/module.cpp b/engines/neverhood/module.cpp
index c46aa79ea2..03109c0c86 100644
--- a/engines/neverhood/module.cpp
+++ b/engines/neverhood/module.cpp
@@ -52,17 +52,17 @@ uint32 Module::handleMessage(int messageNum, const MessageParam &param, Entity *
_field24 = -1;
_field26 = -1;
_field28 = -1;
- _field20 = param._integer;
+ _field20 = param.asInteger();
_done = true;
return 0;
case 0x100A:
- _field24 = (int16)param._integer;
+ _field24 = (int16)param.asInteger();
return 0;
case 0x1023:
- _field26 = (int16)param._integer;
+ _field26 = (int16)param.asInteger();
return 0;
case 0x1024:
- _field28 = (int16)param._integer;
+ _field28 = (int16)param.asInteger();
return 0;
default:
if (_childObject && sender == _parentModule)
diff --git a/engines/neverhood/module1000.cpp b/engines/neverhood/module1000.cpp
index 858062084f..eea0d99567 100644
--- a/engines/neverhood/module1000.cpp
+++ b/engines/neverhood/module1000.cpp
@@ -132,6 +132,74 @@ void Module1000::updateScene1005() {
// Scene1001
+KmScene1001::KmScene1001(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y)
+ : Klayman(vm, parentScene, x, y, 1000, 1000) {
+}
+
+uint32 KmScene1001::xHandleMessage(int messageNum, const MessageParam &param) {
+ debug("KmScene1001::xHandleMessage() messageNum = %04X", messageNum);
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ sub41C930(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ setCallback2(AnimationCallback(&Klayman::sub41FC80));
+ break;
+ case 0x4804:
+ if (param.asInteger() == 2) {
+ setCallback2(AnimationCallback(&Klayman::sub4211B0));
+ }
+ break;
+ case 0x480D:
+ debug("########### A");
+ // TODO setCallback2(AnimationCallback(&Klayman::sub44FA50));
+ break;
+ case 0x4812:
+ debug("########### B");
+ // TODO setCallback2(AnimationCallback(&Klayman::sub41FF80));
+ break;
+
+ case 0x4836:
+ if (param.asInteger() == 1) {
+ _parentScene->sendMessage(0x2002, 0, this);
+ setCallback2(AnimationCallback(&Klayman::sub4211F0));
+ }
+ break;
+
+ case 0x4840:
+ sub41CD70(param.asInteger());
+ break;
+ }
+
+ // TODO
+
+ return 0;
+}
+
+void KmScene1001::sub44FA50() {
+ if (!sub41CEB0(AnimationCallback(&KmScene1001::sub44FA50))) {
+ _status2 = 2;
+ _flagE5 = false;
+ setFileHash(0x00648953, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&KmScene1001::handleMessage44FA00);
+ SetSpriteCallback(&AnimatedSprite::updateDeltaXY);
+ }
+}
+
+uint32 KmScene1001::handleMessage44FA00(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Klayman::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x4AB28209) {
+ _attachedSprite->sendMessage(0x480F, 0, this);
+ }
+ break;
+ }
+ return messageResult;
+}
+
AsScene1001Door::AsScene1001Door(NeverhoodEngine *vm)
: AnimatedSprite(vm, 1100), _soundResource1(vm), _soundResource2(vm) {
@@ -165,18 +233,12 @@ void AsScene1001Door::handleMessage2000h() {
switch (_vm->getGlobalVar(0x52371C95)) {
case 0:
case 1:
-#if 0
- _soundResource1.set(0x65482F03);
- _soundResource1.load();
- _soundResource1.play(false);
-#endif
+ _soundResource1.play(0x65482F03);
setFileHash(0x624C0498, 1, 3);
SetAnimationCallback3(&AsScene1001Door::callback1);
break;
case 2:
-#if 0
- _soundResource2.play(false);
-#endif
+ _soundResource2.play();
setFileHash(0x624C0498, 6, 6);
SetAnimationCallback3(&AsScene1001Door::callback2);
break;
@@ -216,9 +278,7 @@ void AsScene1001Door::callback2() {
}
void AsScene1001Door::callback3() {
-#if 0
- _soundResource1.play(false);
-#endif
+ _soundResource1.play();
setFileHash1();
_surface->setVisible(false);
}
@@ -239,25 +299,17 @@ uint32 AsScene1001Hammer::handleMessage(int messageNum, const MessageParam &para
Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
case 0x100D:
- if (param._integer == 0x00352100) {
+ if (param.asInteger() == 0x00352100) {
if (_asDoor) {
_asDoor->sendMessage(0x2000, 0, this);
}
- } else if (param._integer == 0x0A1A0109) {
-#if 0
- _soundResource.set(0x66410886);
- _soundResource.load();
- _soundResource.play(false);
-#endif
+ } else if (param.asInteger() == 0x0A1A0109) {
+ _soundResource.play(0x66410886);
}
break;
case 0x2000:
setFileHash(0x022C90D4, 1, -1);
-#if 0
- _soundResource.set(0xE741020A);
- _soundResource.load();
- _soundResource.play(false);
-#endif
+ _soundResource.play(0xE741020A);
_newHashListIndex = -2;
break;
}
@@ -280,12 +332,8 @@ uint32 AsScene1001Window::handleMessage(int messageNum, const MessageParam &para
Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
case 0x100D:
- if (param._integer == 0x0E0A1410) {
-#if 0
- _soundResource.set(0x60803F10);
- _soundResource.load();
- _soundResource.play(false);
-#endif
+ if (param.asInteger() == 0x0E0A1410) {
+ _soundResource.play(0x60803F10);
}
break;
case 0x2001:
@@ -317,17 +365,14 @@ uint32 AsScene1001Lever::handleMessage(int messageNum, const MessageParam &param
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
case 0x100D:
- if (param._integer == 0x00C0C444) {
+ if (param.asInteger() == 0x00C0C444) {
_parentScene->sendMessage(0x480F, 0, this);
- } else if (param._integer == 0xC41A02C0) {
-#if 0
- _soundResource.set(0x40581882);
- _soundResource.load();
- _soundResource.play(false);
-#endif
+ } else if (param.asInteger() == 0xC41A02C0) {
+ _soundResource.play(0x40581882);
}
break;
case 0x1011:
+ debug("Click lever");
_parentScene->sendMessage(0x4826, 0, this);
messageResult = 1;
break;
@@ -371,11 +416,7 @@ uint32 SsCommonButtonSprite::handleMessage(int messageNum, const MessageParam &p
_parentScene->sendMessage(0x480B, 0, this);
_surface->setVisible(true);
_countdown = 8;
-#if 0
- _soundResource.set(_soundFileHash);
- _soundResource.load();
- _soundResource.play(false);
-#endif
+ _soundResource.play(_soundFileHash);
break;
}
return messageResult;
@@ -386,8 +427,6 @@ Scene1001::Scene1001(NeverhoodEngine *vm, Module *parentModule, int which)
_name = "Scene1001";
- // TODO: Implement Sprite classes
-
Sprite *staticSprite1;
SetMessageHandler(&Scene1001::handleMessage);
@@ -400,46 +439,37 @@ Scene1001::Scene1001(NeverhoodEngine *vm, Module *parentModule, int which)
// TODO Mouse
- //DEBUG so he's here at least
- _klayman = new Klayman(_vm, this, 200, 433, 1000, 1000);
- addSprite(_klayman);
-
-#if 0
- // TODO: Player sprites...
if (which < 0) {
setRectList(0x004B49F0);
- _klayman = new Class572(_vm, this, 200, 433, 1000, 1000);
+ _klayman = new KmScene1001(_vm, this, 200, 433);
setMessageList(0x004B4888);
} else if (which == 1) {
setRectList(0x004B49F0);
- _klayman = new Class572(_vm, this, 640, 433, 1000, 1000);
+ _klayman = new KmScene1001(_vm, this, 640, 433);
setMessageList(0x004B4898);
} else if (which == 2) {
setRectList(0x004B49F0);
if (_vm->getGlobalVar(0xC0418A02)) {
- _klayman = new Class572(_vm, this, 390, 433, 1000, 1000);
+ _klayman = new KmScene1001(_vm, this, 390, 433);
_klayman->setDoDeltaX(1);
} else {
- _klayman = new Class572(_vm, this, 300, 433, 1000, 1000);
+ _klayman = new KmScene1001(_vm, this, 300, 433);
}
setMessageList(0x004B4970);
} else {
setRectList(0x004B4A00);
- _klayman = new Class572(_vm, this, 200, 433, 1000, 1000);
+ _klayman = new KmScene1001(_vm, this, 200, 433);
setMessageList(0x004B4890);
}
addSprite(_klayman);
-#endif
staticSprite1 = addSprite(new StaticSprite(_vm, 0x2080A3A8, 1300));
-#if 0
// TODO: This sucks somehow, find a better way
_klayman->getSurface()->getClipRect().x1 = 0;
_klayman->getSurface()->getClipRect().y1 = 0;
_klayman->getSurface()->getClipRect().x2 = staticSprite1->getSurface()->getDrawRect().x + staticSprite1->getSurface()->getDrawRect().width;
_klayman->getSurface()->getClipRect().y2 = 480;
-#endif
if (_vm->getGlobalVar(0xD217189D) == 0) {
_asDoor = addSprite(new AsScene1001Door(_vm));
@@ -478,45 +508,47 @@ Scene1001::~Scene1001() {
}
uint32 Scene1001::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ debug("Scene1001::handleMessage(%04X)", messageNum);
uint32 messageResult = 0;
Scene::handleMessage(messageNum, param, sender);
switch (messageNum) {
case 0x0001:
- if (param._point.x == 0 && _vm->getGlobalVar(0xA4014072)) {
+ if (param.asPoint().x == 0 && _vm->getGlobalVar(0xA4014072)) {
_parentModule->sendMessage(0x1009, 0, this);
}
break;
case 0x000D:
- if (param._integer == 0x188B2105) {
+ if (param.asInteger() == 0x188B2105) {
_parentModule->sendMessage(0x1009, 0, this);
messageResult = 1;
}
break;
case 0x100D:
- if (param._integer == 0x00342624) {
- // TODO _klayman->sendMessage(0x1014, _asLever, this);
- // TODO setMessageList2(0x004B4910, true, false);
+ if (param.asInteger() == 0x00342624) {
+ _klayman->sendMessage(0x1014, _asLever, this);
+ setMessageList2(0x004B4910);
messageResult = 1;
- } else if (param._integer == 0x21E64A00) {
+ } else if (param.asInteger() == 0x21E64A00) {
if (_vm->getGlobalVar(0xD217189D)) {
- // TODO setMessageList(0x004B48A8, true, false);
+ setMessageList(0x004B48A8);
messageResult = 1;
} else {
- // TODO setMessageList(0x004B48C8, true, false);
+ setMessageList(0x004B48C8);
messageResult = 1;
}
- } else if (param._integer == 0x040424D0) {
- // TODO _klayman->sendMessage(0x1014, _ssButton, this);
- } else if (param._integer == 0x80006358) {
+ } else if (param.asInteger() == 0x040424D0) {
+ _klayman->sendMessage(0x1014, _ssButton, this);
+ } else if (param.asInteger() == 0x80006358) {
if (_vm->getGlobalVar(0x03C698DA)) {
- // TODO setMessageList(0x004B4938, true, false);
+ setMessageList(0x004B4938);
} else {
- // TODO setMessageList(0x004B4960, true, false);
+ setMessageList(0x004B4960);
}
}
break;
case 0x2002:
- // TODO setRectList(0x004B49F0);
+ debug("########## setRectList(0x004B49F0);");
+ setRectList(0x004B49F0);
break;
case 0x480B:
if (_asWindow) {
diff --git a/engines/neverhood/module1000.h b/engines/neverhood/module1000.h
index 21be948c41..d74a0e189d 100644
--- a/engines/neverhood/module1000.h
+++ b/engines/neverhood/module1000.h
@@ -55,6 +55,15 @@ protected:
// Scene1001
+class KmScene1001 : public Klayman {
+public:
+ KmScene1001(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+ void sub44FA50();
+ uint32 handleMessage44FA00(int messageNum, const MessageParam &param, Entity *sender);
+};
+
class AsScene1001Door : public AnimatedSprite {
public:
AsScene1001Door(NeverhoodEngine *vm);
diff --git a/engines/neverhood/neverhood.cpp b/engines/neverhood/neverhood.cpp
index 73e7c5fcd6..0e3e0a33ea 100644
--- a/engines/neverhood/neverhood.cpp
+++ b/engines/neverhood/neverhood.cpp
@@ -78,6 +78,8 @@ Common::Error NeverhoodEngine::run() {
_res->addArchive("s.blb");
_res->addArchive("t.blb");
+ CursorMan.showMouse(true);
+
#if 0
BlbArchive *blb = new BlbArchive();
blb->open("m.blb");
diff --git a/engines/neverhood/resource.cpp b/engines/neverhood/resource.cpp
index 5fc167c050..e3a29c573d 100644
--- a/engines/neverhood/resource.cpp
+++ b/engines/neverhood/resource.cpp
@@ -198,7 +198,7 @@ bool AnimResource::load(uint32 fileHash) {
animList = resourceData + 12;
for (animListIndex = 0; animListIndex < animListCount; animListIndex++) {
- debug("hash: %08X", READ_LE_UINT32(animList));
+ debug(8, "hash: %08X", READ_LE_UINT32(animList));
if (READ_LE_UINT32(animList) == fileHash)
break;
animList += 8;
@@ -218,7 +218,7 @@ bool AnimResource::load(uint32 fileHash) {
frameCount = READ_LE_UINT16(animList + 4);
frameListStartOfs = READ_LE_UINT16(animList + 6);
- debug("frameCount = %d; frameListStartOfs = %04X; animInfoStartOfs = %04X", frameCount, frameListStartOfs, animInfoStartOfs);
+ debug(8, "frameCount = %d; frameListStartOfs = %04X; animInfoStartOfs = %04X", frameCount, frameListStartOfs, animInfoStartOfs);
frameList = resourceData + animInfoStartOfs + frameListStartOfs;
@@ -241,7 +241,7 @@ bool AnimResource::load(uint32 fileHash) {
frameInfo.deltaRect.height = READ_LE_UINT16(frameList + 24);
frameInfo.field_1A = READ_LE_UINT16(frameList + 26);
frameInfo.spriteDataOffs = READ_LE_UINT32(frameList + 28);
- debug("frameHash = %08X; counter = %d; rect = (%d,%d,%d,%d); deltaX = %d; deltaY = %d; deltaRect = (%d,%d,%d,%d); field_1A = %04X; spriteDataOffs = %08X",
+ debug(8, "frameHash = %08X; counter = %d; rect = (%d,%d,%d,%d); deltaX = %d; deltaY = %d; deltaRect = (%d,%d,%d,%d); field_1A = %04X; spriteDataOffs = %08X",
frameInfo.frameHash, frameInfo.counter,
frameInfo.rect.x, frameInfo.rect.y, frameInfo.rect.width, frameInfo.rect.height,
frameInfo.deltaX, frameInfo.deltaY,
@@ -299,4 +299,18 @@ int16 AnimResource::getFrameIndex(uint32 frameHash) {
return -1;
}
+SoundResource::SoundResource(NeverhoodEngine *vm)
+ : _vm(vm) {
+}
+
+bool SoundResource::isPlaying() {
+ return false;
+}
+
+void SoundResource::play(uint32 fileHash, bool looping) {
+}
+
+void SoundResource::play() {
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/resource.h b/engines/neverhood/resource.h
index 969f46d3e7..7540956954 100644
--- a/engines/neverhood/resource.h
+++ b/engines/neverhood/resource.h
@@ -103,8 +103,10 @@ protected:
class SoundResource {
public:
- SoundResource(NeverhoodEngine *vm) : _vm(vm) {}
- bool isPlaying() const { return false; }
+ SoundResource(NeverhoodEngine *vm);
+ bool isPlaying();
+ void play(uint32 fileHash, bool looping = false);
+ void play();
protected:
NeverhoodEngine *_vm;
};
diff --git a/engines/neverhood/scene.cpp b/engines/neverhood/scene.cpp
index 9b7b35d419..9d7d550c2d 100644
--- a/engines/neverhood/scene.cpp
+++ b/engines/neverhood/scene.cpp
@@ -31,11 +31,11 @@ Scene::Scene(NeverhoodEngine *vm, Module *parentModule, bool clearHitRects)
_messageListFlag1 = false;
_systemCallbackFlag = false;
_messageList = NULL;
- // TODO _rectType = 0;
+ _rectType = 0;
_mouseClickPos.x = 0;
_mouseClickPos.y = 0;
_mouseClicked = false;
- // TODO _rectList = NULL;
+ _rectList = NULL;
// TODO _someRects = NULL;
_klayman = NULL;
// TODO _mouseSprite = NULL;
@@ -191,27 +191,24 @@ void Scene::update() {
_smkFileHash = 0;
} else {
if (_mouseClicked) {
- //** ALL TODO
-#if 0
if (_klayman) {
// TODO: Merge later
if (_klayman->hasMessageHandler() &&
_klayman->sendMessage(0x1008, 0, this) != 0 &&
_messageListFlag &&
- queryPositionClass400(_mouseClickPos.x, _mouseClickPos.y)) {
+ queryPositionSprite(_mouseClickPos.x, _mouseClickPos.y)) {
_mouseClicked = false;
} else if (_klayman->hasMessageHandler() &&
_klayman->sendMessage(0x1008, 0, this) != 0 &&
_messageListFlag) {
_mouseClicked = !queryPositionRectList(_mouseClickPos.x, _mouseClickPos.y);
}
- } else if (queryPositionClass400(_mouseClickPos.x, _mouseClickPos.y)) {
+ } else if (queryPositionSprite(_mouseClickPos.x, _mouseClickPos.y)) {
_mouseClicked = false;
}
-#endif
}
-
- // TODO runMessageList();
+
+ runMessageList();
// Update all entities
for (Common::Array<Entity*>::iterator iter = _entities.begin(); iter != _entities.end(); iter++)
@@ -228,12 +225,13 @@ uint32 Scene::handleMessage(int messageNum, const MessageParam &param, Entity *s
#if 0
if (_mouseSprite && _mouseSprite->hasMessageHandler())
_mouseSprite->sendMessage(0x4002, param, this);
- queryPositionSomeRects(param._point.x, param._point.y);
+ queryPositionSomeRects(param.asPoint().x, param.asPoint().y);
#endif
break;
case 1: // mouse clicked
+ debug("mouse clicked");
_mouseClicked = true;
- _mouseClickPos = param._point;
+ _mouseClickPos = param.asPoint();
break;
/* ORIGINAL DEBUG
case 3:
@@ -259,7 +257,7 @@ uint32 Scene::handleMessage(int messageNum, const MessageParam &param, Entity *s
if (_messageListIndex == _messageListCount)
_klayman->sendMessage(0x4004, 0, this);
else {
- // TODO runMessageList();
+ runMessageList();
}
}
break;
@@ -287,7 +285,7 @@ uint32 Scene::handleMessage(int messageNum, const MessageParam &param, Entity *s
#endif
break;
case 0x1022:
- setSurfacePriority(((Sprite*)sender)->getSurface(), param._integer);
+ setSurfacePriority(((Sprite*)sender)->getSurface(), param.asInteger());
break;
}
return 0;
@@ -311,9 +309,187 @@ void Scene::smackerUpdate() {
}
uint32 Scene::smackerHandleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- if (messageNum == 0x3002)
+ switch (messageNum) {
+ case 0x3002:
_smackerDone = true;
+ break;
+ }
return 0;
}
+bool Scene::queryPositionSprite(int16 mouseX, int16 mouseY) {
+ debug("Scene::queryPositionSprite(%d, %d)", mouseX, mouseY);
+ for (uint i = 0; i < _vm->_collisionMan->getSpriteCount(); i++) {
+ Sprite *sprite = _vm->_collisionMan->getSprite(i);
+ if (sprite->hasMessageHandler() && sprite->isPointInside(mouseX, mouseY) &&
+ sprite->sendPointMessage(0x1011, _mouseClickPos, this) != 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Scene::queryPositionRectList(int16 mouseX, int16 mouseY) {
+ if (_rectType == 1) {
+ RectList &rectList = *_rectList;
+ int16 klaymanX = _klayman->getX();
+ int16 klaymanY = _klayman->getY();
+ for (uint i = 0; i < rectList.size(); i++) {
+ debug("(%d, %d) ? (%d, %d, %d, %d)", klaymanX, klaymanY, rectList[i].rect.x1, rectList[i].rect.y1, rectList[i].rect.x2, rectList[i].rect.y2);
+ if (klaymanX >= rectList[i].rect.x1 && klaymanX <= rectList[i].rect.x2 &&
+ klaymanY >= rectList[i].rect.y1 && klaymanY <= rectList[i].rect.y2) {
+ for (uint j = 0; j < rectList[i].subRects.size(); j++) {
+ debug(" (%d, %d) ? (%d, %d, %d, %d)", mouseX, mouseY, rectList[i].subRects[j].rect.x1, rectList[i].subRects[j].rect.y1, rectList[i].subRects[j].rect.x2, rectList[i].subRects[j].rect.y2);
+ if (mouseX >= rectList[i].subRects[j].rect.x1 && mouseX <= rectList[i].subRects[j].rect.x2 &&
+ mouseY >= rectList[i].subRects[j].rect.y1 && mouseY <= rectList[i].subRects[j].rect.y2) {
+ debug("Scene::queryPositionRectList() -> %08X", rectList[i].subRects[j].messageListId);
+ return setMessageList2(rectList[i].subRects[j].messageListId);
+ }
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+void Scene::setMessageList(uint32 id, bool messageListFlag, bool systemCallbackFlag) {
+ setMessageList(_vm->_staticData->getMessageList(id), messageListFlag, systemCallbackFlag);
+}
+
+void Scene::setMessageList(MessageList *messageList, bool messageListFlag, bool systemCallbackFlag) {
+ _messageList = messageList;
+ _messageListCount = _messageList ? _messageList->size() : 0;
+ _messageListIndex = 0;
+ _messageListFlag1 = false;
+ _messageListFlag = messageListFlag;
+ _systemCallbackFlag = systemCallbackFlag;
+ _messageListStatus = 1;
+ _klayman->sendMessage(0x101C, 0, this);
+}
+
+bool Scene::setMessageList2(uint32 id, bool messageListFlag, bool systemCallbackFlag) {
+ return setMessageList2(_vm->_staticData->getMessageList(id), messageListFlag, systemCallbackFlag);
+}
+
+bool Scene::setMessageList2(MessageList *messageList, bool messageListFlag, bool systemCallbackFlag) {
+ bool result = false;
+
+ debug("Scene::setMessageList2(%p)", (void*)messageList);
+
+ if (_messageListStatus == 1) {
+ if (messageList != _messageList2) {
+ if (_messageValue >= 0) {
+ _parentModule->sendMessage(0x1023, _messageValue, this);
+ _messageValue = -1;
+ }
+ _messageList2 = messageList;
+ setMessageList(messageList, messageListFlag, systemCallbackFlag);
+ result = true;
+ }
+ } else if (_messageListStatus == 2) {
+ if (messageList == _messageList2) {
+ if (_messageValue >= 0) {
+ _parentModule->sendMessage(0x1023, _messageValue, this);
+ _messageValue = -1;
+ }
+ _messageList2 = messageList;
+ setMessageList(messageList, messageListFlag, systemCallbackFlag);
+ result = true;
+ }
+ } else {
+ if (_messageValue >= 0) {
+ _parentModule->sendMessage(0x1023, _messageValue, this);
+ _messageValue = -1;
+ }
+ _messageList2 = messageList;
+ setMessageList(messageList, messageListFlag, systemCallbackFlag);
+ }
+ return result;
+}
+
+void Scene::runMessageList() {
+
+ //debug("_messageListFlag2 = %d", _messageListFlag2);
+
+ if (_messageListFlag2)
+ return;
+
+ _messageListFlag2 = true;
+
+ if (_messageListFlag1) {
+ _messageListFlag2 = false;
+ return;
+ }
+
+ if (!_messageList) {
+ _messageList2 = NULL;
+ _messageListStatus = 0;
+ }
+
+ if (_messageList && _klayman) {
+
+ while (_messageList && _messageListIndex < _messageListCount && !_messageListFlag1) {
+ int messageNum = (*_messageList)[_messageListIndex].messageNum;
+ uint32 messageParam = (*_messageList)[_messageListIndex].messageValue;
+
+ debug("$$$$$$$$$$$ Scene::runMessageList() %04X, %08X", messageNum, messageParam);
+
+ _messageListIndex++;
+ if (_messageListIndex == _messageListCount) {
+ _klayman->sendMessage(0x1021, 0, this);
+ }
+ if (_systemCallbackFlag) {
+ // TODO messageNum = systemConvertMessageCb(messageNum);
+ }
+ if (messageNum != 0x4003) {
+ if (messageNum == 0x1009 || messageNum == 0x1024) {
+ _parentModule->sendMessage(messageNum, messageParam, this);
+ } else if (messageNum == 0x100A) {
+ _messageValue = messageParam;
+ _parentModule->sendMessage(messageNum, messageParam, this);
+ } else if (messageNum == 0x4001) {
+ _messageListFlag1 = true;
+ _klayman->sendPointMessage(0x4001, _mouseClickPos, this);
+ } else if (messageNum == 0x100D) {
+ if (this->hasMessageHandler() && this->sendMessage(0x100D, messageParam, this) != 0)
+ continue;
+ } else if (messageNum == 0x101A) {
+ _messageListStatus = 0;
+ } else if (messageNum == 0x101B) {
+ _messageListStatus = 2;
+ } else if (messageNum == 0x1020) {
+ _messageListFlag = false;
+ } else if (messageNum >= 0x2000 && messageNum <= 0x2FFF) {
+ if (this->hasMessageHandler() && this->sendMessage(messageNum, messageParam, this) != 0) {
+ _messageListFlag2 = false;
+ return;
+ }
+ } else {
+ _messageListFlag1 = true;
+ if (_klayman->hasMessageHandler() && _klayman->sendMessage(messageNum, messageParam, this) != 0) {
+ _messageListFlag1 = false;
+ }
+ }
+ }
+ if (_messageListIndex == _messageListCount) {
+ _messageListFlag = true;
+ _messageList = NULL;
+ }
+ }
+ }
+
+ _messageListFlag2 = false;
+
+}
+
+void Scene::setRectList(uint32 id) {
+ setRectList(_vm->_staticData->getRectList(id));
+}
+
+void Scene::setRectList(RectList *rectList) {
+ _rectList = rectList;
+ _rectType = 1;
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/scene.h b/engines/neverhood/scene.h
index 4928d20ae2..34f3c1e759 100644
--- a/engines/neverhood/scene.h
+++ b/engines/neverhood/scene.h
@@ -56,15 +56,15 @@ protected:
Common::Array<BaseSurface*> _surfaces;
bool _systemCallbackFlag;
MessageList *_messageList;
- int _messageListIndex;
- int _messageListCount;
+ uint _messageListCount;
+ uint _messageListIndex;
bool _messageListFlag1;
NPoint _mouseClickPos;
bool _mouseClicked;
// TODO RectResource _rectResource;
- // TODO 00000080 rectList dd ?
- // TODO 00000084 rectType dw ?
- // TODO 00000086 rectListCount dw ?
+ RectList *_rectList;
+ int _rectType;
+ // rectListCount
// TODO 00000088 someRects dd ?
// TODO 0000008C someRectsCount dw ?
// TODO 0000008E field_8E dw ?
@@ -93,6 +93,15 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
void smackerUpdate();
uint32 smackerHandleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ bool queryPositionSprite(int16 mouseX, int16 mouseY);
+ bool queryPositionRectList(int16 mouseX, int16 mouseY);
+ void setMessageList(uint32 id, bool messageListFlag = true, bool systemCallbackFlag = false);
+ void setMessageList(MessageList *messageList, bool messageListFlag = true, bool systemCallbackFlag = false);
+ bool setMessageList2(uint32 id, bool messageListFlag = true, bool systemCallbackFlag = false);
+ bool setMessageList2(MessageList *messageList, bool messageListFlag = true, bool systemCallbackFlag = false);
+ void runMessageList();
+ void setRectList(uint32 id);
+ void setRectList(RectList *rectList);
};
} // End of namespace Neverhood
diff --git a/engines/neverhood/sprite.cpp b/engines/neverhood/sprite.cpp
index ce21527384..d9257502a0 100644
--- a/engines/neverhood/sprite.cpp
+++ b/engines/neverhood/sprite.cpp
@@ -384,7 +384,7 @@ void AnimatedSprite::updateFrameIndex() {
}
void AnimatedSprite::updateFrameInfo() {
- debug("AnimatedSprite::updateFrameInfo()");
+ debug(8, "AnimatedSprite::updateFrameInfo()");
const AnimFrameInfo &frameInfo = _animResource.getFrameInfo(_frameIndex);
@@ -452,20 +452,44 @@ void AnimatedSprite::setFileHash3(uint32 fileHash2, uint32 fileHash6, uint32 fil
_hashListIndex = -1;
}
+void AnimatedSprite::setCallback1(AnimationCb callback1) {
+ if (_callback1Cb) {
+ (this->*_callback1Cb)();
+ }
+ SetAnimationCallback1(callback1);
+}
+
+void AnimatedSprite::setCallback2(AnimationCb callback2) {
+
+ if (_callback1Cb) {
+ // _callback1Cb has to be cleared before it's called
+ AnimationCb cb = _callback1Cb;
+ _callback1Cb = NULL;
+ (this->*cb)();
+ }
+
+ // TODO _callbackList = NULL;
+ _callback3Cb = NULL;
+ _callback2Cb = callback2;
+
+ if (_callback2Cb) {
+ (this->*_callback2Cb)();
+ }
+
+}
+
void AnimatedSprite::removeCallbacks() {
if (_callback1Cb) {
// _callback1Cb has to be cleared before it's called
AnimationCb cb = _callback1Cb;
_callback1Cb = NULL;
- debug("Fire _callback1Cb");
(this->*cb)();
}
if (_callback3Cb) {
_callback2Cb = _callback3Cb;
_callback3Cb = NULL;
- debug("Fire _callback3Cb");
(this->*_callback2Cb)();
#if 0 // TODO
} else if (_callbackList) {
diff --git a/engines/neverhood/sprite.h b/engines/neverhood/sprite.h
index b3809a845e..160bfe1a7f 100644
--- a/engines/neverhood/sprite.h
+++ b/engines/neverhood/sprite.h
@@ -45,6 +45,8 @@ public:
void setDoDeltaX(int type);
void setDoDeltaY(int type);
bool isPointInside(int16 x, int16 y);
+ int16 getX() const { return _x; }
+ int16 getY() const { return _y; }
protected:
void (Sprite::*_spriteUpdateCb)();
int16 (Sprite::*_filterXCb)(int16);
@@ -98,6 +100,7 @@ public:
AnimatedSprite(NeverhoodEngine *vm, int objectPriority);
AnimatedSprite(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority, int16 x, int16 y);
void update();
+ void updateDeltaXY();
protected:
typedef void (AnimatedSprite::*AnimationCb)();
AnimResource _animResource;
@@ -129,7 +132,6 @@ protected:
AnimationCb _callback2Cb;
AnimationCb _callback3Cb;
void init();
- void updateDeltaXY();
void updateAnim();
void updatePosition();
void updateFrameIndex();
@@ -139,6 +141,8 @@ protected:
void setFileHash1();
void setFileHash2(uint32 fileHash, uint32 fileHash6, uint32 fileHash5);
void setFileHash3(uint32 fileHash2, uint32 fileHash6, uint32 fileHash5);
+ void setCallback1(AnimationCb callback1);
+ void setCallback2(AnimationCb callback2);
int16 getHashListIndex(uint32 fileHash) { return 0; } // TODO !!!
void removeCallbacks();
};