From d1d1596fd136783a7bc4db9264ba1627b8511355 Mon Sep 17 00:00:00 2001 From: johndoe123 Date: Fri, 14 Sep 2012 22:38:31 +0000 Subject: NEVERHOOD: Add support for shadow sprites, used only for the shadow of the car/vehicle thing --- engines/neverhood/gamemodule.cpp | 4 +- engines/neverhood/graphics.cpp | 13 ++++ engines/neverhood/graphics.h | 8 +++ engines/neverhood/module2500.cpp | 6 +- engines/neverhood/module2500.h | 6 +- engines/neverhood/module2700.cpp | 133 ++++++++++++++++++++++++++++++++------- engines/neverhood/module2700.h | 32 ++++++++++ engines/neverhood/screen.cpp | 25 ++++++-- engines/neverhood/screen.h | 7 ++- engines/neverhood/sprite.cpp | 13 +++- engines/neverhood/sprite.h | 3 + 11 files changed, 208 insertions(+), 42 deletions(-) diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp index 19bdc65fa1..6245cc807e 100644 --- a/engines/neverhood/gamemodule.cpp +++ b/engines/neverhood/gamemodule.cpp @@ -339,7 +339,7 @@ void GameModule::startup() { _vm->gameState().sceneNum = 8; createModule(2600, -1); #endif -#if 0 +#if 1 _vm->gameState().which = 0; _vm->gameState().sceneNum = 1; createModule(2700, -1); @@ -353,7 +353,7 @@ void GameModule::startup() { _vm->gameState().sceneNum = 0; createModule(2500, -1); #endif -#if 1 +#if 0 _vm->gameState().sceneNum = 2; createModule(2400, -1); #endif diff --git a/engines/neverhood/graphics.cpp b/engines/neverhood/graphics.cpp index 5bb9424f57..a58cdcb4b9 100644 --- a/engines/neverhood/graphics.cpp +++ b/engines/neverhood/graphics.cpp @@ -131,6 +131,19 @@ void BaseSurface::copyFrom(Graphics::Surface *sourceSurface, int16 x, int16 y, N } } +// ShadowSurface + +ShadowSurface::ShadowSurface(NeverhoodEngine *vm, int priority, int16 width, int16 height, BaseSurface *shadowSurface) + : BaseSurface(vm, priority, width, height), _shadowSurface(shadowSurface) { + // Empty +} + +void ShadowSurface::draw() { + if (_surface && _visible && _drawRect.width > 0 && _drawRect.height > 0) { + _vm->_screen->drawSurface2(_surface, _drawRect, _clipRect, _transparent, _shadowSurface->getSurface()); + } +} + // FontSurface FontSurface::FontSurface(NeverhoodEngine *vm, NPointArray *tracking, uint16 numRows, byte firstChar, uint16 charWidth, uint16 charHeight) diff --git a/engines/neverhood/graphics.h b/engines/neverhood/graphics.h index 7725e73289..5e91bdb8c6 100644 --- a/engines/neverhood/graphics.h +++ b/engines/neverhood/graphics.h @@ -116,6 +116,14 @@ protected: bool _transparent; }; +class ShadowSurface : public BaseSurface { +public: + ShadowSurface(NeverhoodEngine *vm, int priority, int16 width, int16 height, BaseSurface *shadowSurface); + virtual void draw(); +protected: + BaseSurface *_shadowSurface; +}; + class FontSurface : public BaseSurface { public: FontSurface(NeverhoodEngine *vm, NPointArray *tracking, uint16 numRows, byte firstChar, uint16 charWidth, uint16 charHeight); diff --git a/engines/neverhood/module2500.cpp b/engines/neverhood/module2500.cpp index 3cb2379489..84b98af08a 100644 --- a/engines/neverhood/module2500.cpp +++ b/engines/neverhood/module2500.cpp @@ -303,9 +303,9 @@ Scene2501::Scene2501(NeverhoodEngine *vm, Module *parentModule, int which) _currTrackIndex = 0; } - // TODO _class517 = insertSprite(_class521, _class437->getSurface(), 4); - // TODO _class520 = insertSprite(_class521, _class437->getSurface(), 4); - // TODO _class519 = insertSprite(_class521, _class437->getSurface(), 4); + _class517 = insertSprite(_class521, _class437->getSurface(), 4); + _class520 = insertSprite(_class521, _class437->getSurface(), 4); + _class519 = insertSprite(_class521, _class437->getSurface(), 4); insertSprite(_class521); _pointListsCount = 3; diff --git a/engines/neverhood/module2500.h b/engines/neverhood/module2500.h index c3c046e960..756c75efde 100644 --- a/engines/neverhood/module2500.h +++ b/engines/neverhood/module2500.h @@ -67,9 +67,9 @@ public: protected: Class521 *_class521; Sprite *_class437; - // TODO Sprite *_class517; - // TODO Sprite *_class519; - // TODO Sprite *_class520; + Sprite *_class517; + Sprite *_class519; + Sprite *_class520; Sprite *_class541; Sprite *_class542; Klayman *_kmScene2501; diff --git a/engines/neverhood/module2700.cpp b/engines/neverhood/module2700.cpp index 862b832654..71ce229956 100644 --- a/engines/neverhood/module2700.cpp +++ b/engines/neverhood/module2700.cpp @@ -512,6 +512,19 @@ void Module2700::createScene2704(int which, uint32 sceneInfoId, int16 value, con _childObject = new Scene2704(_vm, this, which, sceneInfoId, value, staticSprites, clipRect); } +static const NPoint kClass517Points[] = { + {-63, 3}, + {-48, 40}, + {-33, 58}, + { 0, 65}, + { 40, 53}, + { 56, 27}, + { 63, 0}, + {-30, 26}, + { 0, 30}, + { 26, 25} +}; + Class437::Class437(NeverhoodEngine *vm, uint32 fileHash) : StaticSprite(vm, 0) { @@ -524,6 +537,70 @@ Class437::Class437(NeverhoodEngine *vm, uint32 fileHash) StaticSprite::update(); } +Class517::Class517(NeverhoodEngine *vm, AnimatedSprite *class521, BaseSurface *shadowSurface, uint index) + : AnimatedSprite(vm, 1100), _class521(class521), _index(index), _animFileHash(0) { + + SetUpdateHandler(&Class517::update); + createShadowSurface(shadowSurface, 320, 240, 100); // TODO Use actual dimensions from resource + updateShadow(); +} + +void Class517::update() { + updateShadow(); + AnimatedSprite::update(); +} + +void Class517::updateShadow() { + if (_class521->getFrameIndex() != _currFrameIndex || _class521->getCurrAnimFileHash() != _animFileHash) { + uint32 fileHash = _class521->getCurrAnimFileHash(); + if (fileHash == 0x35698F78 || fileHash == 0x192ADD30 || fileHash == 0x9C220DA4 || + fileHash == 0x9966B138 || fileHash == 0xB579A77C || fileHash == 0xA86A9538 || + fileHash == 0xD4220027 || fileHash == 0xD00A1364 || fileHash == 0xD4AA03A4 || + fileHash == 0xF46A0324) { + startAnimation(fileHash, _class521->getFrameIndex(), -1); + _newStickFrameIndex = _class521->getFrameIndex(); + } + _animFileHash = fileHash; + } + _x = _class521->getX() + kClass517Points[_index].x; + _y = _class521->getY() + kClass517Points[_index].y; + if (!_class521->getVisible()) { + startAnimation(0x1209E09F, 0, -1); + _newStickFrameIndex = 0; + } + setDoDeltaX(_class521->isDoDeltaX() ? 1 : 0); +} + +Class519::Class519(NeverhoodEngine *vm, Sprite *class521, BaseSurface *shadowSurface, uint index) + : AnimatedSprite(vm, 1100), _class521(class521), _index(index) { + + SetUpdateHandler(&Class519::update); + createShadowSurface1(shadowSurface, 0x60281C10, 150); + startAnimation(0x60281C10, -1, -1); + _newStickFrameIndex = -2; +} + +void Class519::update() { + _x = _class521->getX() + kClass517Points[_index].x; + _y = _class521->getY() + kClass517Points[_index].y; + AnimatedSprite::update(); +} + +Class520::Class520(NeverhoodEngine *vm, Sprite *class521, BaseSurface *shadowSurface, int16 frameIndex) + : AnimatedSprite(vm, 1100), _class521(class521) { + + SetUpdateHandler(&Class520::update); + createShadowSurface1(shadowSurface, 0x0759129C, 100); + startAnimation(0x0759129C, frameIndex, -1); + _newStickFrameIndex = frameIndex; +} + +void Class520::update() { + _x = _class521->getX(); + _y = _class521->getY(); + AnimatedSprite::update(); +} + Scene2701::Scene2701(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule, true) { @@ -546,17 +623,20 @@ Scene2701::Scene2701(NeverhoodEngine *vm, Module *parentModule, int which) clipRect.set(0, 0, 640, _sprite1->getDrawRect().x2()); if (sceneInfo->class437Filename) { - _class437 = insertSprite(sceneInfo->class437Filename); + + _class437 = createSprite(sceneInfo->class437Filename); + addEntity(_class437); + _class521 = insertSprite(this, 320, 240); -//TODO _class517 = insertSprite(_class521, _class437->getSurface(), 4); -//TODO _class520 = insertSprite(_class521, _class437->getSurface(), 4); -//TODO _class519 = insertSprite(_class521, _class437->getSurface(), 4); + _class517 = insertSprite(_class521, _class437->getSurface(), 4); + _class520 = insertSprite(_class521, _class437->getSurface(), 4); + _class519 = insertSprite(_class521, _class437->getSurface(), 4); } else { _class437 = NULL; _class521 = insertSprite(this, 320, 240); } -//TODO _class518 = insertSprite(_class521); + _class518 = insertSprite(_class521); _which1 = sceneInfo->which1; _which2 = sceneInfo->which2; @@ -578,7 +658,7 @@ Scene2701::Scene2701(NeverhoodEngine *vm, Module *parentModule, int which) } _class521->setClipRect(clipRect); - // TODO _class518->setClipRect(clipRect); + _class518->setClipRect(clipRect); if (which == 1) { SetMessageHandler(&Scene2701::handleMessage42F500); @@ -654,12 +734,14 @@ Scene2702::Scene2702(NeverhoodEngine *vm, Module *parentModule, int which) insertMouse433(0x08B04180); - _class437 = insertSprite(0x12002035); + _class437 = createSprite(0x12002035); + addEntity(_class437); + _class521 = insertSprite(this, 320, 240); - //TODO _class517 = insertSprite(_class521, _class437->getSurface(), 4); - //TODO insertSprite(_class521); - //TODO _class520 = insertSprite(_class521, _class437->getSurface(), 4); - //TODO _class519 = insertSprite(_class521, _class437->getSurface(), 4); + _class517 = insertSprite(_class521, _class437->getSurface(), 4); + insertSprite(_class521); + _class520 = insertSprite(_class521, _class437->getSurface(), 4); + _class519 = insertSprite(_class521, _class437->getSurface(), 4); _dataResource.load(0x04310014); @@ -828,18 +910,21 @@ Scene2704::Scene2704(NeverhoodEngine *vm, Module *parentModule, int which, uint3 insertMouse433(sceneInfo->mouseCursorFilename); if (sceneInfo->class437Filename) { - _class437 = insertSprite(sceneInfo->class437Filename); + + _class437 = createSprite(sceneInfo->class437Filename); + addEntity(_class437); + _class521 = insertSprite(this, 320, 240); -//TODO _class517 = insertSprite(_class521, _class437->getSurface(), 4); -//TODO _class520 = insertSprite(_class521, _class437->getSurface(), 4); -//TODO _class519 = insertSprite(_class521, _class437->getSurface(), 4); + _class517 = insertSprite(_class521, _class437->getSurface(), 4); + _class520 = insertSprite(_class521, _class437->getSurface(), 4); + _class519 = insertSprite(_class521, _class437->getSurface(), 4); } else { _class437 = NULL; -//TODO _class517 = NULL; + _class517 = NULL; _class521 = insertSprite(this, 320, 240); } -//TODO _class518 = insertSprite(_class521); + _class518 = insertSprite(_class521); _which1 = sceneInfo->which1; _which2 = sceneInfo->which2; @@ -871,7 +956,6 @@ Scene2704::Scene2704(NeverhoodEngine *vm, Module *parentModule, int which, uint3 if (clipRect) { _class521->getClipRect() = *clipRect; -#if 0 if (_class517) _class517->getClipRect() = *clipRect; if (_class520) @@ -880,7 +964,6 @@ Scene2704::Scene2704(NeverhoodEngine *vm, Module *parentModule, int which, uint3 _class519->getClipRect() = *clipRect; if (_class518) _class518->getClipRect() = *clipRect; -#endif } } @@ -932,12 +1015,14 @@ Scene2706::Scene2706(NeverhoodEngine *vm, Module *parentModule, int which) insertMouse433(0x08B8C180); - _class437 = insertSprite(0x18808B88); + _class437 = createSprite(0x18808B88); + addEntity(_class437); + _class521 = insertSprite(this, 320, 240); -//TODO _class517 = insertSprite(_class521, _class437->getSurface(), 4); -//TODO _class518 = insertSprite(_class521); -//TODO _class520 = insertSprite(_class521, _class437->getSurface(), 4); -//TODO _class519 = insertSprite(_class521, _class437->getSurface(), 4); + _class517 = insertSprite(_class521, _class437->getSurface(), 4); + _class518 = insertSprite(_class521); + _class520 = insertSprite(_class521, _class437->getSurface(), 4); + _class519 = insertSprite(_class521, _class437->getSurface(), 4); _dataResource.load(0x06000162); diff --git a/engines/neverhood/module2700.h b/engines/neverhood/module2700.h index f1ef3f5727..bed9a7d829 100644 --- a/engines/neverhood/module2700.h +++ b/engines/neverhood/module2700.h @@ -58,6 +58,34 @@ public: Class437(NeverhoodEngine *vm, uint32 fileHash); }; +class Class517 : public AnimatedSprite { +public: + Class517(NeverhoodEngine *vm, AnimatedSprite *class521, BaseSurface *shadowSurface, uint index); +protected: + uint _index; + AnimatedSprite *_class521; + uint32 _animFileHash; + void update(); + void updateShadow(); +}; + +class Class519 : public AnimatedSprite { +public: + Class519(NeverhoodEngine *vm, Sprite *class521, BaseSurface *shadowSurface, uint index); +protected: + uint _index; + Sprite *_class521; + void update(); +}; + +class Class520 : public AnimatedSprite { +public: + Class520(NeverhoodEngine *vm, Sprite *class521, BaseSurface *shadowSurface, int16 frameIndex); +protected: + Sprite *_class521; + void update(); +}; + class Scene2701 : public Scene { public: Scene2701(NeverhoodEngine *vm, Module *parentModule, int which); @@ -104,6 +132,10 @@ public: protected: Class521 *_class521; Sprite *_class437; + Sprite *_class517; + Sprite *_class518; + Sprite *_class520; + Sprite *_class519; int _which1, _which2; NPointArray *_trackPoints; NRectArray *_rectList; diff --git a/engines/neverhood/screen.cpp b/engines/neverhood/screen.cpp index 351e51a3e9..dfc5358c5b 100644 --- a/engines/neverhood/screen.cpp +++ b/engines/neverhood/screen.cpp @@ -36,6 +36,7 @@ Screen::Screen(NeverhoodEngine *vm) } Screen::~Screen() { + _backScreen->free(); delete _backScreen; } @@ -94,16 +95,17 @@ void Screen::clear() { memset(_backScreen->pixels, 0, _backScreen->pitch * _backScreen->h); } -void Screen::drawSurface2(const Graphics::Surface *surface, NDrawRect &drawRect, NRect &clipRect, bool transparent) { +void Screen::drawSurface2(const Graphics::Surface *surface, NDrawRect &drawRect, NRect &clipRect, bool transparent, + const Graphics::Surface *shadowSurface) { int16 destX, destY; NRect ddRect; - + if (drawRect.x + drawRect.width >= clipRect.x2) ddRect.x2 = clipRect.x2 - drawRect.x; else ddRect.x2 = drawRect.width; - + if (drawRect.x < clipRect.x1) { destX = clipRect.x1; ddRect.x1 = clipRect.x1 - drawRect.x; @@ -127,7 +129,7 @@ void Screen::drawSurface2(const Graphics::Surface *surface, NDrawRect &drawRect, //debug(2, "draw: x = %d; y = %d; (%d, %d, %d, %d)", destX, destY, ddRect.x1, ddRect.y1, ddRect.x2, ddRect.y2); - blit(surface, destX, destY, ddRect, transparent); + blit(surface, destX, destY, ddRect, transparent, shadowSurface); // Useful for debugging //_backScreen->frameRect(Common::Rect(clipRect.x1, clipRect.y1, clipRect.x2, clipRect.y2), 250); @@ -171,7 +173,8 @@ void Screen::drawSurface3(const Graphics::Surface *surface, int16 x, int16 y, ND } -void Screen::blit(const Graphics::Surface *surface, int16 destX, int16 destY, NRect &ddRect, bool transparent) { +void Screen::blit(const Graphics::Surface *surface, int16 destX, int16 destY, NRect &ddRect, bool transparent, + const Graphics::Surface *shadowSurface) { const byte *source = (const byte*)surface->getBasePtr(ddRect.x1, ddRect.y1); byte *dest = (byte*)_backScreen->getBasePtr(destX, destY); @@ -181,7 +184,17 @@ void Screen::blit(const Graphics::Surface *surface, int16 destX, int16 destY, NR if (width <= 0 || height <= 0) return; - if (!transparent) { + if (shadowSurface) { + const byte *shadowSource = (const byte*)shadowSurface->getBasePtr(destX, destY); + while (height--) { + for (int xc = 0; xc < width; xc++) + if (source[xc] != 0) + dest[xc] = shadowSource[xc]; + source += surface->pitch; + shadowSource += shadowSurface->pitch; + dest += _backScreen->pitch; + } + } else if (!transparent) { while (height--) { memcpy(dest, source, width); source += surface->pitch; diff --git a/engines/neverhood/screen.h b/engines/neverhood/screen.h index e813e63f20..07be04cf32 100644 --- a/engines/neverhood/screen.h +++ b/engines/neverhood/screen.h @@ -42,9 +42,12 @@ public: void testPalette(byte *paletteData); void updatePalette(); void clear(); - void drawSurface2(const Graphics::Surface *surface, NDrawRect &drawRect, NRect &clipRect, bool transparent); + void drawSurface2(const Graphics::Surface *surface, NDrawRect &drawRect, NRect &clipRect, bool transparent, + const Graphics::Surface *shadowSurface = NULL); void drawSurface3(const Graphics::Surface *surface, int16 x, int16 y, NDrawRect &drawRect, NRect &clipRect, bool transparent); - void blit(const Graphics::Surface *surface, int16 destX, int16 destY, NRect &ddRect, bool transparent); + void drawShadowSurface(const Graphics::Surface *surface, const Graphics::Surface *shadowSurface, int16 x, int16 y, NDrawRect &drawRect, NRect &clipRect); + void blit(const Graphics::Surface *surface, int16 destX, int16 destY, NRect &ddRect, bool transparent, + const Graphics::Surface *shadowSurface = NULL); void drawDoubleSurface2(const Graphics::Surface *surface, NDrawRect &drawRect); void drawUnk(const Graphics::Surface *surface, NDrawRect &drawRect, NDrawRect &sysRect, NRect &clipRect, bool transparent); protected: diff --git a/engines/neverhood/sprite.cpp b/engines/neverhood/sprite.cpp index b68434b493..66f1178a52 100644 --- a/engines/neverhood/sprite.cpp +++ b/engines/neverhood/sprite.cpp @@ -28,7 +28,7 @@ namespace Neverhood { Sprite::Sprite(NeverhoodEngine *vm, int objectPriority) : Entity(vm, objectPriority), _x(0), _y(0), _spriteUpdateCb(NULL), _filterXCb(NULL), _filterYCb(NULL), - _dataResource(vm), _doDeltaX(false), _doDeltaY(false), _needRefresh(false), _flags(0) { + _dataResource(vm), _doDeltaX(false), _doDeltaY(false), _needRefresh(false), _flags(0), _surface(NULL) { _name = "Sprite"; SetMessageHandler(&Sprite::handleMessage); @@ -438,6 +438,15 @@ void AnimatedSprite::createSurface1(uint32 fileHash, int surfacePriority) { _surface = new BaseSurface(_vm, surfacePriority, dimensions.width, dimensions.height); } +void AnimatedSprite::createShadowSurface1(BaseSurface *shadowSurface, uint32 fileHash, int surfacePriority) { + NDimensions dimensions = _animResource.loadSpriteDimensions(fileHash); + _surface = new ShadowSurface(_vm, surfacePriority, dimensions.width, dimensions.height, shadowSurface); +} + +void AnimatedSprite::createShadowSurface(BaseSurface *shadowSurface, int16 width, int16 height, int surfacePriority) { + _surface = new ShadowSurface(_vm, surfacePriority, width, height, shadowSurface); +} + void AnimatedSprite::startAnimation(uint32 fileHash, int16 plFirstFrameIndex, int16 plLastFrameIndex) { debug(2, "AnimatedSprite::startAnimation(%08X, %d, %d)", fileHash, plFirstFrameIndex, plLastFrameIndex); _newAnimFileHash = fileHash; @@ -506,7 +515,7 @@ void AnimatedSprite::gotoNextState() { if (_nextStateCb) { _currStateCb = _nextStateCb; _nextStateCb = NULL; - debug("Fire _nextStateCb '%s'", _nextStateCbName.c_str()); + //debug("Fire _nextStateCb '%s'", _nextStateCbName.c_str()); (this->*_currStateCb)(); #if 0 // TODO } else if (_callbackList) { diff --git a/engines/neverhood/sprite.h b/engines/neverhood/sprite.h index bc7c0a5247..d34704d7bf 100644 --- a/engines/neverhood/sprite.h +++ b/engines/neverhood/sprite.h @@ -58,6 +58,7 @@ public: uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); void loadDataResource(uint32 fileHash); int16 defFilterY(int16 y); + bool getVisible() const { return _surface->getVisible(); } void setVisible(bool value) { _surface->setVisible(value); } NDrawRect& getDrawRect() { return _surface->getDrawRect(); } // Some shortcuts to set the clipRect @@ -157,6 +158,8 @@ protected: void updateFrameIndex(); void updateFrameInfo(); void createSurface1(uint32 fileHash, int surfacePriority); + void createShadowSurface1(BaseSurface *shadowSurface, uint32 fileHash, int surfacePriority); + void createShadowSurface(BaseSurface *shadowSurface, int16 width, int16 height, int surfacePriority); void stopAnimation(); void startAnimationByHash(uint32 fileHash, uint32 plFirstFrameHash, uint32 plLastFrameHash); void nextAnimationByHash(uint32 fileHash2, uint32 plFirstFrameHash, uint32 plLastFrameHash); -- cgit v1.2.3