aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/neverhood/entity.h4
-rw-r--r--engines/neverhood/graphics.cpp15
-rw-r--r--engines/neverhood/graphics.h4
-rw-r--r--engines/neverhood/module1000.cpp146
-rw-r--r--engines/neverhood/module1000.h22
-rw-r--r--engines/neverhood/neverhood.cpp4
-rw-r--r--engines/neverhood/neverhood.h1
-rw-r--r--engines/neverhood/resource.cpp9
-rw-r--r--engines/neverhood/resource.h1
-rw-r--r--engines/neverhood/screen.cpp2
-rw-r--r--engines/neverhood/sprite.cpp61
-rw-r--r--engines/neverhood/sprite.h16
12 files changed, 255 insertions, 30 deletions
diff --git a/engines/neverhood/entity.h b/engines/neverhood/entity.h
index bbe67a187c..18b9cba793 100644
--- a/engines/neverhood/entity.h
+++ b/engines/neverhood/entity.h
@@ -44,14 +44,16 @@ struct MessageParam {
class Entity {
public:
+ Common::String _name; // Entity name for debugging purposes
Entity(NeverhoodEngine *vm, int priority)
- : _vm(vm), _updateHandlerCb(NULL), _messageHandlerCb(NULL), _priority(priority) {
+ : _vm(vm), _updateHandlerCb(NULL), _messageHandlerCb(NULL), _priority(priority), _name("Entity") {
}
virtual ~Entity() {
}
virtual void draw() {
}
void handleUpdate() {
+ //debug("Entity(%s).handleUpdate", _name.c_str());
if (_updateHandlerCb)
(this->*_updateHandlerCb)();
}
diff --git a/engines/neverhood/graphics.cpp b/engines/neverhood/graphics.cpp
index 3d21e8e7de..b6d883c168 100644
--- a/engines/neverhood/graphics.cpp
+++ b/engines/neverhood/graphics.cpp
@@ -51,7 +51,7 @@ BaseSurface::~BaseSurface() {
}
void BaseSurface::draw() {
- debug("BaseSurface::draw()");
+ debug(8, "BaseSurface::draw()");
if (_surface && _visible && _drawRect.width > 0 && _drawRect.height > 0) {
// TODO: _sysRect alternate drawing code (is that used?)
_vm->_screen->drawSurface2(_surface, _drawRect, _clipRect);
@@ -88,6 +88,19 @@ void BaseSurface::drawSpriteResourceEx(SpriteResource &spriteResource, bool flip
}
}
+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, (byte*)_surface->pixels, _surface->pitch, flipX, flipY);
+ }
+ }
+}
+
// Misc
void parseBitmapResource(byte *sprite, bool *rle, NDimensions *dimensions, NPoint *position, byte **palette, byte **pixels) {
diff --git a/engines/neverhood/graphics.h b/engines/neverhood/graphics.h
index ce2be1a592..bf8333c1f5 100644
--- a/engines/neverhood/graphics.h
+++ b/engines/neverhood/graphics.h
@@ -50,6 +50,7 @@ struct NDrawRect {
NDrawRect(int16 x0, int16 y0, int16 width0, int16 height0) : x(x0), y(y0), width(width0), height(height0) {}
};
+class AnimResource;
class SpriteResource;
// NOTE: "Restore" methods aren't need in the reimplementation as they're DirectDraw-specific
@@ -63,12 +64,15 @@ public:
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);
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; }
+ bool getVisible() const { return _visible; }
+ void setVisible(bool value) { _visible = value; }
protected:
NeverhoodEngine *_vm;
int _priority;
diff --git a/engines/neverhood/module1000.cpp b/engines/neverhood/module1000.cpp
index 248769ecf5..162618ec0b 100644
--- a/engines/neverhood/module1000.cpp
+++ b/engines/neverhood/module1000.cpp
@@ -86,6 +86,36 @@ void Module1000::createScene1005(int which) {
}
void Module1000::updateScene1001() {
+ _childObject->handleUpdate();
+
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (_field20 == 2) {
+ // TODO createScene1003();
+ // TODO _childObject->handleUpdate();
+ } else {
+ // TODO createScene1002();
+ // TODO _childObject->handleUpdate();
+ }
+ }
+
+ if (_field24 >= 0) {
+ if (_field24 == 2) {
+ // TODO ResourceTable_multiLoad(&_resourceTable2, &_resourceTable1, &_resourceTable3);
+ _field24 = -1;
+ } else {
+ // TODO ResourceTable_multiLoad(&_resourceTable3, &_resourceTable1);
+ _field24 = -1;
+ }
+ }
+
+ if (_field26 >= 0) {
+ // TODO ResourceTable_multiLoad(&_resourceTable1, &_resourceTable2, &_resourceTable3);
+ _field26 = -1;
+ }
+
}
void Module1000::updateScene1002() {
@@ -101,10 +131,121 @@ void Module1000::updateScene1005() {
}
// Scene1001
+
+Class509::Class509(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100), _soundResource1(vm), _soundResource2(vm) {
+
+ _name = "Class509";
+
+ createSurface(800, 137, 242);
+
+ _x = 726;
+ _y = 440;
+
+ callback1();
+
+#if 0
+ _soundResource2.set(0xED403E03);
+ _soundResource2.load();
+ _soundResource2.createSoundBuffer();
+#endif
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&Class509::handleMessage);
+
+}
+
+uint32 Class509::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ handleMessage2000h();
+ break;
+ case 0x3002:
+ removeCallbacks();
+ break;
+ }
+ return 0;
+}
+
+void Class509::handleMessage2000h() {
+
+ switch (_vm->getGlobalVar(0x52371C95)) {
+ case 0:
+#if 0
+ _soundResource1.set(0x65482F03);
+ _soundResource1.load();
+ _soundResource1.play(false);
+#endif
+ setFileHash(0x624C0498, 1, 3);
+ SetAnimationCallback3(&Class509::callback1);
+ break;
+ case 1:
+#if 0
+ _soundResource1.set(0x65482F03);
+ _soundResource1.load();
+ _soundResource1.play(false);
+#endif
+ setFileHash(0x624C0498, 1, 3);
+ SetAnimationCallback3(&Class509::callback1);
+ break;
+ case 2:
+#if 0
+ _soundResource2.play(false);
+#endif
+ setFileHash(0x624C0498, 6, 6);
+ SetAnimationCallback3(&Class509::callback2);
+ break;
+ default:
+ // Nothing
+ break;
+ }
+
+ _vm->incGlobalVar(0x52371C95, 1);
+
+}
+
+void Class509::callback1() {
+ switch (_vm->getGlobalVar(0x52371C95)) {
+ case 1:
+ setFileHash(0x624C0498, 4, -1);
+ _newHashListIndex = 4;
+ break;
+ case 2:
+ setFileHash(0x624C0498, 1, -1);
+ _newHashListIndex = 1;
+ break;
+ case 3:
+ setFileHash1();
+ _surface->setVisible(false);
+ break;
+ default:
+ setFileHash(0x624C0498, 0, -1);
+ _newHashListIndex = 0;
+ break;
+ }
+}
+
+void Class509::callback2() {
+ _vm->setGlobalVar(0xD217189D, 1);
+ setFileHash(0x624C0498, 6, 6);
+ SetAnimationCallback3(&Class509::callback3);
+ _x = 30;
+}
+
+void Class509::callback3() {
+#if 0
+ _soundResource1.play(false);
+#endif
+ setFileHash1();
+ _surface->setVisible(false);
+}
Scene1001::Scene1001(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule, true), _fieldE4(-1), _fieldE6(-1) {
+ _name = "Scene1001";
+
// TODO: Implement Sprite classes
Sprite *staticSprite1;
@@ -154,6 +295,7 @@ Scene1001::Scene1001(NeverhoodEngine *vm, Module *parentModule, int which)
_playerSprite->getSurface()->getClipRect().y1 = 0;
_playerSprite->getSurface()->getClipRect().x2 = staticSprite1->getSurface()->getDrawRect().x + staticSprite1->getSurface()->getDrawRect().width;
_playerSprite->getSurface()->getClipRect().y2 = 480;
+#endif
if (_vm->getGlobalVar(0xD217189D) == 0) {
_class509 = addSprite(new Class509(_vm));
@@ -165,6 +307,7 @@ Scene1001::Scene1001(NeverhoodEngine *vm, Module *parentModule, int which)
_class509 = NULL;
}
+#if 0
_class511 = addSprite(new Class511(_vm, this, 150, 433, 1));
#endif
@@ -194,9 +337,6 @@ Scene1001::Scene1001(NeverhoodEngine *vm, Module *parentModule, int which)
}
-void Scene1001::update() {
-}
-
uint32 Scene1001::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
return 0;
}
diff --git a/engines/neverhood/module1000.h b/engines/neverhood/module1000.h
index 935a8be020..4e7b2922a3 100644
--- a/engines/neverhood/module1000.h
+++ b/engines/neverhood/module1000.h
@@ -29,6 +29,8 @@
namespace Neverhood {
+// Module1000
+
class Module1000 : public Module {
public:
Module1000(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -51,18 +53,32 @@ protected:
void updateScene1005();
};
+// Scene1001
+
+class Class509 : public AnimatedSprite {
+public:
+ Class509(NeverhoodEngine *vm);
+protected:
+ SoundResource _soundResource1;
+ SoundResource _soundResource2;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void handleMessage2000h();
+ void callback1();
+ void callback2();
+ void callback3();
+};
+
class Scene1001 : public Scene {
public:
Scene1001(NeverhoodEngine *vm, Module *parentModule, int which);
protected:
- Sprite *_class511;
Sprite *_class508;
Sprite *_class509;
- Sprite *_class608;
Sprite *_class510;
+ Sprite *_class511;
+ Sprite *_class608;
int16 _fieldE4;
int16 _fieldE6;
- void update();
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
diff --git a/engines/neverhood/neverhood.cpp b/engines/neverhood/neverhood.cpp
index 8b74b6620e..1ba2c98860 100644
--- a/engines/neverhood/neverhood.cpp
+++ b/engines/neverhood/neverhood.cpp
@@ -203,6 +203,10 @@ void NeverhoodEngine::setGlobalVar(uint32 nameHash, uint32 value) {
// TODO
}
+void NeverhoodEngine::incGlobalVar(uint32 nameHash, int incrValue) {
+ setGlobalVar(nameHash, getGlobalVar(nameHash) - incrValue);
+}
+
uint32 NeverhoodEngine::getSubVar(uint32 nameHash, uint32 subNameHash) {
// TODO
return 0;
diff --git a/engines/neverhood/neverhood.h b/engines/neverhood/neverhood.h
index 4a07d6a1be..952a99d768 100644
--- a/engines/neverhood/neverhood.h
+++ b/engines/neverhood/neverhood.h
@@ -116,6 +116,7 @@ public:
GameState& gameState() { return _gameState; }
uint32 getGlobalVar(uint32 nameHash);
void setGlobalVar(uint32 nameHash, uint32 value);
+ void incGlobalVar(uint32 nameHash, int incrValue);
uint32 getSubVar(uint32 nameHash, uint32 subNameHash);
void setSubVar(uint32 nameHash, uint32 subNameHash, uint32 value);
diff --git a/engines/neverhood/resource.cpp b/engines/neverhood/resource.cpp
index c122ca2e5e..5fc167c050 100644
--- a/engines/neverhood/resource.cpp
+++ b/engines/neverhood/resource.cpp
@@ -153,6 +153,15 @@ AnimResource::~AnimResource() {
unloadInternal();
}
+void AnimResource::draw(uint frameIndex, byte *dest, int destPitch, bool flipX, bool flipY) {
+ const AnimFrameInfo frameInfo = _frames[frameIndex];
+ _currSpriteData = _spriteData + frameInfo.spriteDataOffs;
+ _width = frameInfo.rect.width;
+ _height = frameInfo.rect.height;
+ // TODO: Repl stuff
+ unpackSpriteRle(_currSpriteData, _width, _height, dest, destPitch, flipX, flipY);
+}
+
bool AnimResource::load(uint32 fileHash) {
debug("AnimResource::load(%08X)", fileHash);
diff --git a/engines/neverhood/resource.h b/engines/neverhood/resource.h
index 4199fe73e4..969f46d3e7 100644
--- a/engines/neverhood/resource.h
+++ b/engines/neverhood/resource.h
@@ -75,6 +75,7 @@ class AnimResource {
public:
AnimResource(NeverhoodEngine *vm);
~AnimResource();
+ void draw(uint frameIndex, byte *dest, int destPitch, bool flipX, bool flipY);
bool load(uint32 fileHash);
void unload();
void clear();
diff --git a/engines/neverhood/screen.cpp b/engines/neverhood/screen.cpp
index 68f611050d..77e8c02693 100644
--- a/engines/neverhood/screen.cpp
+++ b/engines/neverhood/screen.cpp
@@ -125,7 +125,7 @@ void Screen::drawSurface2(const Graphics::Surface *surface, NDrawRect &drawRect,
ddRect.y1 = 0;
}
- debug("draw: x = %d; y = %d; (%d, %d, %d, %d)", destX, destY, ddRect.x1, ddRect.y1, ddRect.x2, ddRect.y2);
+ debug(8, "draw: x = %d; y = %d; (%d, %d, %d, %d)", destX, destY, ddRect.x1, ddRect.y1, ddRect.x2, ddRect.y2);
const byte *source = (const byte*)surface->getBasePtr(ddRect.x1, ddRect.y1);
byte *dest = (byte*)_backScreen->getBasePtr(destX, destY);
diff --git a/engines/neverhood/sprite.cpp b/engines/neverhood/sprite.cpp
index 0f44110cdd..1239a301d0 100644
--- a/engines/neverhood/sprite.cpp
+++ b/engines/neverhood/sprite.cpp
@@ -29,9 +29,10 @@ namespace Neverhood {
Sprite::Sprite(NeverhoodEngine *vm, int objectPriority)
: Entity(vm, objectPriority), _x(0), _y(0),
_spriteUpdateCb(NULL), _filterXCb(NULL), _filterYCb(NULL),
- _doDeltaX(false), _doDeltaY(false), _needRedraw(false),
+ _doDeltaX(false), _doDeltaY(false), _needRefresh(false),
_flags(0) {
+ _name = "Sprite";
SetMessageHandler(&Sprite::handleMessage);
}
@@ -88,12 +89,15 @@ void Sprite::createSurface(int surfacePriority, int16 width, int16 height) {
StaticSprite::StaticSprite(NeverhoodEngine *vm, int objectPriority)
: Sprite(vm, objectPriority), _spriteResource(vm) {
-
+
+ _name = "StaticSprite";
+
}
StaticSprite::StaticSprite(NeverhoodEngine *vm, const char *filename, int surfacePriority, int16 x, int16 y, int16 width, int16 height)
: Sprite(vm, 0), _spriteResource(vm) {
+ _name = "StaticSprite";
// TODO init(calcHash(filename), surfacePriority, x, y, width, height);
}
@@ -101,6 +105,7 @@ StaticSprite::StaticSprite(NeverhoodEngine *vm, const char *filename, int surfac
StaticSprite::StaticSprite(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority, int16 x, int16 y, int16 width, int16 height)
: Sprite(vm, 0), _spriteResource(vm) {
+ _name = "StaticSprite";
init(fileHash, surfacePriority, x, y, width, height);
}
@@ -127,7 +132,7 @@ void StaticSprite::init(uint32 fileHash, int surfacePriority, int16 x, int16 y,
_drawRect.width = width;
_drawRect.width = height;
- _needRedraw = true;
+ _needRefresh = true;
update();
@@ -150,9 +155,9 @@ void StaticSprite::update() {
_surface->getDrawRect().y = filterY(_y + _drawRect.y);
}
- if (_needRedraw) {
+ if (_needRefresh) {
_surface->drawSpriteResourceEx(_spriteResource, _doDeltaX, _doDeltaY, _drawRect.width, _drawRect.height);
- _needRedraw = false;
+ _needRefresh = false;
}
}
@@ -173,7 +178,7 @@ void StaticSprite::load(uint32 fileHash, bool dimensions, bool position) {
_y = _spriteResource.getPosition().y;
}
- _needRedraw = true;
+ _needRefresh = true;
}
@@ -198,6 +203,7 @@ AnimatedSprite::AnimatedSprite(NeverhoodEngine *vm, uint32 fileHash, int surface
}
void AnimatedSprite::init() {
+ _name = "AnimatedSprite";
_counter = 0;
_fileHash1 = 0;
_deltaX = 0;
@@ -205,18 +211,18 @@ void AnimatedSprite::init() {
_fileHash2 = 0;
// TODO _callbackList = 0;
_frameIndex3 = 0;
- // TODO _callback3 = 0;
_frameIndex = 0;
_hashListIndex = -1;
- // TODO _callback2 = 0;
+ _callback1Cb = NULL;
+ _callback2Cb = NULL;
+ _callback3Cb = NULL;
_newHashListIndex = -1;
- // TODO _callback1 = 0;
_fileHash4 = 0;
_flag = false;
_replOldByte = 0;
_replNewByte = 0;
// TODO _animResource.replEnabled = 0;
- _playBackwards = 0;
+ _playBackwards = false;
}
void AnimatedSprite::update() {
@@ -265,7 +271,6 @@ void AnimatedSprite::updateAnim() {
// TODO _animResource.loadInternal(calcHash("sqDefault"));
_fileHash3 = 0;
}
- // loc_43831D
if (_replNewByte != _replOldByte) {
// TODO _animResource.setRepl(_replOldByte, _replNewByte);
}
@@ -349,10 +354,9 @@ void AnimatedSprite::updatePosition() {
_surface->getDrawRect().y = filterY(_y + _drawRect.y);
}
- if (_needRedraw) {
- debug("TODO: drawAnimResource");
- // TODO _surface->drawAnimResource(_animResource, _frameIndex, _doDeltaX, _doDeltaY, _drawRect.width, _drawRect.height);
- _needRedraw = false;
+ if (_needRefresh) {
+ _surface->drawAnimResource(_animResource, _frameIndex, _doDeltaX, _doDeltaY, _drawRect.width, _drawRect.height);
+ _needRefresh = false;
}
}
@@ -380,6 +384,7 @@ void AnimatedSprite::updateFrameIndex() {
}
void AnimatedSprite::updateFrameInfo() {
+ debug("AnimatedSprite::updateFrameInfo()");
const AnimFrameInfo &frameInfo = _animResource.getFrameInfo(_frameIndex);
@@ -392,7 +397,7 @@ void AnimatedSprite::updateFrameInfo() {
processDelta();
- _needRedraw = true;
+ _needRefresh = true;
if (frameInfo.frameHash != 0) {
sendMessage(0x100D, frameInfo.frameHash, this);
@@ -409,6 +414,7 @@ void AnimatedSprite::createSurface1(uint32 fileHash, int surfacePriority) {
}
void AnimatedSprite::setFileHash(uint32 fileHash, int16 frameIndex3, int16 frameIndex4) {
+ debug("AnimatedSprite::setFileHash(%08X, %d, %d)", fileHash, frameIndex3, frameIndex4);
_fileHash1 = fileHash;
_frameIndex3 = frameIndex3;
_frameIndex4 = frameIndex4;
@@ -446,6 +452,29 @@ void AnimatedSprite::setFileHash3(uint32 fileHash2, uint32 fileHash6, uint32 fil
_hashListIndex = -1;
}
+void AnimatedSprite::removeCallbacks() {
+
+ if (_callback1Cb) {
+ // _callback1Cb has to be cleared before it's called
+ AnimationCallback 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) {
+ removeCallbackList();
+#endif
+ } else {
+ _callback2Cb = NULL;
+ }
+
+}
} // End of namespace Neverhood
diff --git a/engines/neverhood/sprite.h b/engines/neverhood/sprite.h
index 5d013a85e4..71067fa9ec 100644
--- a/engines/neverhood/sprite.h
+++ b/engines/neverhood/sprite.h
@@ -52,7 +52,7 @@ protected:
BaseSurface *_surface;
int16 _x, _y;
bool _doDeltaX, _doDeltaY;
- bool _needRedraw;
+ bool _needRefresh;
//0000002B field_2B db ?
//0000002C field2C dd ? // unused
NDrawRect _drawRect;
@@ -88,11 +88,17 @@ protected:
void update();
};
+#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)
+
class AnimatedSprite : public Sprite {
public:
AnimatedSprite(NeverhoodEngine *vm, int objectPriority);
AnimatedSprite(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority, int16 x, int16 y);
+ void update();
protected:
+ typedef void (AnimatedSprite::*AnimationCallback)();
AnimResource _animResource;
uint32 _fileHash1;
uint32 _fileHash2;
@@ -117,12 +123,11 @@ protected:
callbackListIndex dw ?
callbackListCount dw ?
callbackList dd ?
- callback3 dd ?
- callback2 dd ?
- callback1 dd ?
*/
+ AnimationCallback _callback1Cb;
+ AnimationCallback _callback2Cb;
+ AnimationCallback _callback3Cb;
void init();
- void update();
void updateDeltaXY();
void updateAnim();
void updatePosition();
@@ -134,6 +139,7 @@ protected:
void setFileHash2(uint32 fileHash, uint32 fileHash6, uint32 fileHash5);
void setFileHash3(uint32 fileHash2, uint32 fileHash6, uint32 fileHash5);
int16 getHashListIndex(uint32 fileHash) { return 0; } // TODO !!!
+ void removeCallbacks();
};
} // End of namespace Neverhood