diff options
-rw-r--r-- | engines/neverhood/entity.h | 7 | ||||
-rw-r--r-- | engines/neverhood/gamemodule.cpp | 2 | ||||
-rw-r--r-- | engines/neverhood/graphics.cpp | 18 | ||||
-rw-r--r-- | engines/neverhood/graphics.h | 22 | ||||
-rw-r--r-- | engines/neverhood/module.mk | 4 | ||||
-rw-r--r-- | engines/neverhood/neverhood.cpp | 2 | ||||
-rw-r--r-- | engines/neverhood/resource.cpp | 2 | ||||
-rw-r--r-- | engines/neverhood/resource.h | 5 | ||||
-rw-r--r-- | engines/neverhood/scene.cpp | 307 | ||||
-rw-r--r-- | engines/neverhood/scene.h | 100 | ||||
-rw-r--r-- | engines/neverhood/sprite.cpp | 179 | ||||
-rw-r--r-- | engines/neverhood/sprite.h | 90 |
12 files changed, 708 insertions, 30 deletions
diff --git a/engines/neverhood/entity.h b/engines/neverhood/entity.h index fe5d07e585..bbe67a187c 100644 --- a/engines/neverhood/entity.h +++ b/engines/neverhood/entity.h @@ -24,15 +24,18 @@ #define NEVERHOOD_ENTITY_H #include "neverhood/neverhood.h" +#include "neverhood/graphics.h" namespace Neverhood { struct MessageParam { union { uint32 _integer; + NPoint _point; // TODO: Other types... }; MessageParam(uint32 value) { _integer = value; } + MessageParam(NPoint value) { _point = value; } // TODO: Constructors for the param types... }; @@ -60,6 +63,10 @@ public: uint32 sendMessage(int messageNum, uint32 param, Entity *sender) { return sendMessage(messageNum, MessageParam(param), sender); } + uint32 sendMessage(int messageNum, NPoint param, Entity *sender) { + return sendMessage(messageNum, MessageParam(param), sender); + } + int getPriority() const { return _priority; } protected: void (Entity::*_updateHandlerCb)(); uint32 (Entity::*_messageHandlerCb)(int messageNum, const MessageParam ¶m, Entity *sender); diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp index 887ff3d37a..09046cfa3e 100644 --- a/engines/neverhood/gamemodule.cpp +++ b/engines/neverhood/gamemodule.cpp @@ -29,7 +29,7 @@ GameModule::GameModule(NeverhoodEngine *vm) // Other initializations moved to actual engine class - // TODO .text:0048AD96 + // TODO // TODO Sound1ChList_sub_407F70(0x2D0031, 0x8861079); diff --git a/engines/neverhood/graphics.cpp b/engines/neverhood/graphics.cpp index 315c62dbec..d7c1064948 100644 --- a/engines/neverhood/graphics.cpp +++ b/engines/neverhood/graphics.cpp @@ -61,8 +61,8 @@ void BaseSurface::clear() { } void BaseSurface::drawSpriteResource(SpriteResource &spriteResource) { - if (spriteResource.dimensions().width <= _drawRect.width && - spriteResource.dimensions().height <= _drawRect.height) { + if (spriteResource.getDimensions().width <= _drawRect.width && + spriteResource.getDimensions().height <= _drawRect.height) { clear(); spriteResource.draw((byte*)_surface->pixels, _surface->pitch, false, false); } @@ -70,7 +70,7 @@ void BaseSurface::drawSpriteResource(SpriteResource &spriteResource) { // Misc -void parseBitmapResource(byte *sprite, bool *rle, NDimensions *dimensions, NUnknown *unknown, byte **palette, byte **pixels) { +void parseBitmapResource(byte *sprite, bool *rle, NDimensions *dimensions, NPoint *position, byte **palette, byte **pixels) { uint16 flags; @@ -92,14 +92,14 @@ void parseBitmapResource(byte *sprite, bool *rle, NDimensions *dimensions, NUnkn } if (flags & 4) { - if (unknown) { - unknown->unk1 = READ_LE_UINT16(sprite); - unknown->unk2 = READ_LE_UINT16(sprite + 2); + if (position) { + position->x = READ_LE_UINT16(sprite); + position->y = READ_LE_UINT16(sprite + 2); } sprite += 4; - } else if (unknown) { - unknown->unk1 = 0; - unknown->unk2 = 0; + } else if (position) { + position->x = 0; + position->y = 0; } if (flags & 8) { diff --git a/engines/neverhood/graphics.h b/engines/neverhood/graphics.h index 27ef6cdee6..68ff84dc25 100644 --- a/engines/neverhood/graphics.h +++ b/engines/neverhood/graphics.h @@ -30,12 +30,12 @@ namespace Neverhood { -struct NDimensions { - int16 width, height; +struct NPoint { + int16 x, y; }; -struct NUnknown { - int16 unk1, unk2; +struct NDimensions { + int16 width, height; }; struct NRect { @@ -60,6 +60,8 @@ public: virtual void addDirtyRect(); void clear(); void drawSpriteResource(SpriteResource &spriteResource); + int getPriority() const { return _priority; } + void setPriority(int priority) { _priority = priority; } protected: NeverhoodEngine *_vm; int _priority; @@ -70,19 +72,9 @@ protected: NRect _clipRect; }; -/* -class Palette { -public: - Palette(); - ~Palette(); -protected: - -}; -*/ - // Misc -void parseBitmapResource(byte *sprite, bool *rle, NDimensions *dimensions, NUnknown *unknown, byte **palette, byte **pixels); +void parseBitmapResource(byte *sprite, bool *rle, NDimensions *dimensions, NPoint *position, byte **palette, byte **pixels); void unpackSpriteRle(byte *source, int width, int height, byte *dest, int destPitch, bool flipX, bool flipY); void unpackSpriteNormal(byte *source, int width, int height, byte *dest, int destPitch, bool flipX, bool flipY); diff --git a/engines/neverhood/module.mk b/engines/neverhood/module.mk index 97ad70e654..709538e565 100644 --- a/engines/neverhood/module.mk +++ b/engines/neverhood/module.mk @@ -11,7 +11,9 @@ MODULE_OBJS = \ neverhood.o \ palette.o \ resource.o \ - resourceman.o + resourceman.o \ + scene.o \ + sprite.o # This module can be built as a plugin ifdef BUILD_PLUGINS diff --git a/engines/neverhood/neverhood.cpp b/engines/neverhood/neverhood.cpp index f7bf0327d4..d4418cb8cd 100644 --- a/engines/neverhood/neverhood.cpp +++ b/engines/neverhood/neverhood.cpp @@ -117,7 +117,7 @@ Common::Error NeverhoodEngine::run() { SpriteResource r(this); BaseSurface *surf = new BaseSurface(this, 0, 640, 480); r.load(0x0CA04202); - debug("r: width = %d; height = %d", r.dimensions().width, r.dimensions().height); + debug("r: width = %d; height = %d", r.getDimensions().width, r.getDimensions().height); surf->drawSpriteResource(r); delete surf; } diff --git a/engines/neverhood/resource.cpp b/engines/neverhood/resource.cpp index 2dd919c087..4dcbd838fe 100644 --- a/engines/neverhood/resource.cpp +++ b/engines/neverhood/resource.cpp @@ -66,7 +66,7 @@ bool SpriteResource::load2(uint32 fileHash) { if (_resourceHandle != -1) { if (_vm->_res->getResourceType(_resourceHandle) == 2) { byte *spriteData = _vm->_res->loadResource(_resourceHandle, true); - parseBitmapResource(spriteData, &_rle, &_dimensions, &_unknown, NULL, &_pixels); + parseBitmapResource(spriteData, &_rle, &_dimensions, &_position, NULL, &_pixels); } else { _vm->_res->unuseResource(_resourceHandle); _resourceHandle = -1; diff --git a/engines/neverhood/resource.h b/engines/neverhood/resource.h index 7f699c54df..5a30d1292d 100644 --- a/engines/neverhood/resource.h +++ b/engines/neverhood/resource.h @@ -36,12 +36,13 @@ public: bool load(uint32 fileHash); bool load2(uint32 fileHash); void unload(); - const NDimensions& dimensions() { return _dimensions; }; + const NDimensions& getDimensions() { return _dimensions; } + const NPoint& getPosition() { return _position; } protected: NeverhoodEngine *_vm; int _resourceHandle; NDimensions _dimensions; - NUnknown _unknown; + NPoint _position; byte *_pixels; bool _rle; }; diff --git a/engines/neverhood/scene.cpp b/engines/neverhood/scene.cpp new file mode 100644 index 0000000000..ccdae3a287 --- /dev/null +++ b/engines/neverhood/scene.cpp @@ -0,0 +1,307 @@ +/* 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/scene.h" + +namespace Neverhood { + +Scene::Scene(NeverhoodEngine *vm, Module *parentModule, bool clearHitRects) + : Entity(vm, 0), _parentModule(parentModule) { + + _messageListFlag1 = false; + _systemCallbackFlag = false; + _messageList = NULL; + // TODO _rectType = 0; + _mouseClickPos.x = 0; + _mouseClickPos.y = 0; + _mouseClicked = false; + // TODO _rectList = NULL; + // TODO _someRects = NULL; + // TODO _playerSprite = NULL; + // TODO _mouseSprite = NULL; + _palette = NULL; + // TODO _class300 = NULL; + // TODO _field_8E = -1; + if (clearHitRects) { + // TODO g_Class700->setHitRects(NULL, 0); + // TODO g_Class700->clear(); + } + // TODO g_screen->setFps(24); + // TODO g_screen->hSmack = NULL; + // TODO g_screen->field_24 = 0; + // TODO g_screen->field_26 = 0; + // TODO g_screen->resetDirtyRects(); + _messageListFlag = true; + _surfaceFlag = false; + _messageList2 = NULL; + // TODO _smackerPlayer = NULL; + _smkFileHash = 0; + _messageListFlag2 = false; + _messageValue = -1; + + SetUpdateHandler(&Scene::update); + SetMessageHandler(&Scene::handleMessage); +} + +Scene::~Scene() { + + if (_palette) { + removeEntity(_palette); + delete _palette; + } + + // Delete all entities + for (Common::Array<Entity*>::iterator iter = _entities.begin(); iter != _entities.end(); iter++) + delete *iter; + + // Don't delete surfaces since they always belong to an entity + +} + +void Scene::draw() { + //**ALL TODO +#if 0 + if (_smackerPlayer) { + if (_surfaceFlag) { + g_screen->resetDirtyRects(); + g_screen->copyDirtyRects(); + g_screen->addDirtyRects(); + } + _smackerPlayer->_surface->draw(); + } else { + if (_surfaceFlag) { + g_screen->copyDirtyRects(); + for (Common::Array<BaseSurface*>::iterator iter = _surfaces.begin(); iter != _surfaces.end(); iter++) + (*iter)->addDirtyRect(); + g_screen->addDirtyRects(); + } + for (Common::Array<BaseSurface*>::iterator iter = _surfaces.begin(); iter != _surfaces.end(); iter++) + (*iter)->draw(); + } +#endif +} + +void Scene::addEntity(Entity *entity) { + int index = 0, insertIndex = -1; + for (Common::Array<Entity*>::iterator iter = _entities.begin(); iter != _entities.end(); iter++) { + if ((*iter)->getPriority() > entity->getPriority()) { + insertIndex = index; + break; + } + index++; + } + if (insertIndex >= 0) + _entities.insert_at(insertIndex, entity); + else + _entities.push_back(entity); +} + +bool Scene::removeEntity(Entity *entity) { + for (uint index = 0; index < _entities.size(); index++) { + if (_entities[index] == entity) { + _entities.remove_at(index); + return true; + } + } + return false; +} + +void Scene::addSurface(BaseSurface *surface) { + int index = 0, insertIndex = -1; + for (Common::Array<BaseSurface*>::iterator iter = _surfaces.begin(); iter != _surfaces.end(); iter++) { + if ((*iter)->getPriority() > surface->getPriority()) { + insertIndex = index; + break; + } + index++; + } + if (insertIndex >= 0) + _surfaces.insert_at(insertIndex, surface); + else + _surfaces.push_back(surface); +} + +bool Scene::removeSurface(BaseSurface *surface) { + for (uint index = 0; index < _surfaces.size(); index++) { + if (_surfaces[index] == surface) { + _surfaces.remove_at(index); + return true; + } + } + return false; +} + +Sprite *Scene::addSprite(Sprite *sprite) { + addEntity(sprite); + addSurface(sprite->getSurface()); + return sprite; +} + +void Scene::setSurfacePriority(BaseSurface *surface, int priority) { + surface->setPriority(priority); + if (removeSurface(surface)) + addSurface(surface); +} + +void Scene::deleteSprite(Sprite **sprite) { + // TODO g_Class700->removeSprite(*sprite); + removeSurface((*sprite)->getSurface()); + removeEntity(*sprite); + delete *sprite; + *sprite = NULL; +} + +void Scene::update() { + + if (_smkFileHash != 0) { + // TODO + //**** ALL TODO + //_smackerPlayer = new SmackerPlayer(this, _smkFileHash, true, 0); + _savedUpdateHandlerCb = _updateHandlerCb; + _savedMessageHandlerCb = _messageHandlerCb; + SetUpdateHandler(&Scene::smackerUpdate); + SetMessageHandler(&Scene::smackerHandleMessage); + _smackerDone = false; + // smackerUpdate(); + // g_screen->smackerPlayer = _smackerPlayer; + _smkFileHash = 0; + } else { + if (_mouseClicked) { + //** ALL TODO +#if 0 + if (_playerSprite) { + // TODO: Merge later + if (_playerSprite->hasMessageHandler() && + _playerSprite->sendMessage(0x1008, 0, this) != 0 && + _messageListFlag && + queryPositionClass400(_mouseClickPos.x, _mouseClickPos.y)) { + _mouseClicked = false; + } else if (_playerSprite->hasMessageHandler() && + _playerSprite->sendMessage(0x1008, 0, this) != 0 && + _messageListFlag) { + _mouseClicked = !queryPositionRectList(_mouseClickPos.x, _mouseClickPos.y); + } + } else if (queryPositionClass400(_mouseClickPos.x, _mouseClickPos.y)) { + _mouseClicked = false; + } +#endif + } + + // TODO runMessageList(); + + // Update all entities + for (Common::Array<Entity*>::iterator iter = _entities.begin(); iter != _entities.end(); iter++) + (*iter)->handleUpdate(); + + } + +} + +uint32 Scene::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { + // TODO +#if 0 + switch (messageNum) { + case 0: // mouse moved + if (_mouseSprite && _mouseSprite->hasMessageHandler()) + _mouseSprite->sendMessage(0x4002, param, this); + queryPositionSomeRects(param._point.x, param._point.y); + break; + case 1: // mouse clicked + _mouseClicked = true; + _mouseClickPos = param._point; + break; + /* ORIGINAL DEBUG + case 3: + drawSurfaceRects(); + break; + */ + /* ORIGINAL DEBUG + case 4: + drawRectListRects(); + break; + */ + case 5: + broadcastObjectMessage5(); + break; + case 6: + _parentModule->sendMessage(0x1009, param, this); + break; + case 0x1006: + if (_messageListFlag1) { + _messageListFlag1 = false; + if (_messageListIndex == _messageListCount) + _playerSprite->sendMessage(0x4004, 0, this); + else + runMessageList(); + } + break; + case 0x1007: + if (_messageListFlag1) { + _messageListFlag1 = false; + _messageList = NULL; + _playerSprite->sendMessage(0x4004, 0, this); + } + break; + case 0x101D: + if (_mouseSprite) { + _prevVisible = _mouseSprite->_drawSurface->_visible; + _mouseSprite->_drawSurface->_visible = false; + } + break; + case 0x101E: + if (_prevVisible && _mouseSprite) { + _mouseSprite->_drawSurface->_visible = true; + _mouseSprite->sendMessage(0x4002, g_Screen->_mousePos, this); + } + break; + case 0x1022: + setSurfacePriority(((Sprite*)sender)->_surface, param._integer); + break; + } +#endif + return 0; +} + +void Scene::smackerUpdate() { + //**ALL TODO +#if 0 + _smackerPlayer->handleUpdate(); + if (_smackerDone) { + delete _smackerPlayer; + _smackerPlayer = NULL; + _updateHandlerCb = _savedUpdateHandlerCb; + _messageHandlerCb = _savedMessageHandlerCb; + if (_palette) + _palette->usePalette(); + // TODO class300->restore(); + // TODO g_screen->smackerPlayer = NULL; + } +#endif +} + +uint32 Scene::smackerHandleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { + if (messageNum == 0x3002) + _smackerDone = true; + return 0; +} + +} // End of namespace Neverhood diff --git a/engines/neverhood/scene.h b/engines/neverhood/scene.h new file mode 100644 index 0000000000..3532a43b0b --- /dev/null +++ b/engines/neverhood/scene.h @@ -0,0 +1,100 @@ +/* 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_SCENE_H +#define NEVERHOOD_SCENE_H + +#include "common/array.h" +#include "neverhood/neverhood.h" +#include "neverhood/entity.h" +#include "neverhood/graphics.h" +#include "neverhood/module.h" +#include "neverhood/palette.h" +#include "neverhood/sprite.h" + +namespace Neverhood { + +struct MessageListItem { + uint32 messageNum; + uint32 messageValue; +}; + +class Scene : public Entity { +public: + Scene(NeverhoodEngine *vm, Module *parentModule, bool clearHitRects); + virtual ~Scene(); + virtual void draw(); + void addEntity(Entity *entity); + bool removeEntity(Entity *entity); + void addSurface(BaseSurface *surface); + bool removeSurface(BaseSurface *surface); + Sprite *addSprite(Sprite *sprite); + void setSurfacePriority(BaseSurface *surface, int priority); + void deleteSprite(Sprite **sprite); +protected: + Module *_parentModule; + Common::Array<Entity*> _entities; + Common::Array<BaseSurface*> _surfaces; + bool _systemCallbackFlag; + MessageListItem *_messageList; + int _messageListIndex; + int _messageListCount; + bool _messageListFlag1; + NPoint _mouseClickPos; + bool _mouseClicked; + // TODO RectResource _rectResource; + // TODO 00000080 rectList dd ? + // TODO 00000084 rectType dw ? + // TODO 00000086 rectListCount dw ? + // TODO 00000088 someRects dd ? + // TODO 0000008C someRectsCount dw ? + // TODO 0000008E field_8E dw ? + // TODO 00000090 playerSprite dd ? + // TODO 00000094 mouseSprite dd ? + Palette *_palette; + // TODO 0000009C class300 dd ? + bool _surfaceFlag; + bool _messageListFlag; + MessageListItem *_messageList2; + int _messageListStatus; + // TODO 000000B0 smackerPlayer dd ? + void (Entity::*_savedUpdateHandlerCb)(); + uint32 (Entity::*_savedMessageHandlerCb)(int messageNum, const MessageParam ¶m, Entity *sender); + bool _smackerDone; + // TODO 000000BD field_BD db ? + // TODO 000000BE field_BE db ? + // TODO 000000BF field_BF db ? + uint32 _smkFileHash; + // TODO 000000C4 hitArray dd ? + bool _messageListFlag2; + bool _prevVisible; + int _messageValue; + // TODO 000000CF field_CF db ? + void update(); + uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); + void smackerUpdate(); + uint32 smackerHandleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +} // End of namespace Neverhood + +#endif /* NEVERHOOD_SCENE_H */ diff --git a/engines/neverhood/sprite.cpp b/engines/neverhood/sprite.cpp new file mode 100644 index 0000000000..6ee0a6633c --- /dev/null +++ b/engines/neverhood/sprite.cpp @@ -0,0 +1,179 @@ +/* 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/sprite.h" + +namespace Neverhood { + +// Sprite + +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), + _deltaX1(0), _deltaY1(0), _deltaX2(0), _deltaY2(0), + _flags(0) { + + SetMessageHandler(&Sprite::handleMessage); + +} + +Sprite::~Sprite() { + delete _surface; +} + +void Sprite::processDelta() { + if (_doDeltaX) { + _rect.x1 = _x - _deltaX1 - _deltaX2 + 1; + _rect.x2 = _x - _deltaX1; + } else { + _rect.x1 = _x + _deltaX1; + _rect.x2 = _x + _deltaX1 + _deltaX2 - 1; + } + if (_doDeltaY) { + _rect.y1 = _y - _deltaY1 - _deltaY2 + 1; + _rect.y2 = _y - _deltaY1; + } else { + _rect.y1 = _y + _deltaY1; + _rect.y2 = _y + _deltaY1 + _deltaY2 - 1; + } +} + +void Sprite::setDoDeltaX(int type) { + // Clear, set or toggle + _doDeltaX = type == 2 ? !_doDeltaX : type == 1; +} + +void Sprite::setDoDeltaY(int type) { + // Clear, set or toggle + _doDeltaY = type == 2 ? !_doDeltaY : type == 1; +} + +bool Sprite::isPointInside(int16 x, int16 y) { + return x >= _rect.x1 && x <= _rect.x2 && y >= _rect.y1 && y <= _rect.y2; +} + +uint32 Sprite::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { + if (messageNum == 5) { + // TODO: Draw debug marker (?) + // TODO g_Screen->drawLine(_x - 5, _y, _x + 6, _y); + // TODO g_Screen->drawLine(_x, _y - 5, _x, _y + 6); + } + return 0; +} + +void Sprite::createSurface(int surfacePriority, int16 width, int16 height) { + _surface = new BaseSurface(_vm, surfacePriority, width, height); +} + +// StaticSprite + +StaticSprite::StaticSprite(NeverhoodEngine *vm, int objectPriority) + : Sprite(vm, objectPriority), _spriteResource(vm) { + +} + +StaticSprite::StaticSprite(NeverhoodEngine *vm, const char *filename, int surfacePriority, int16 x, int16 y, int16 width, int16 height) + : Sprite(vm, 0), _spriteResource(vm) { + + // TODO init(calcHash(filename), surfacePriority, x, y, width, height); + +} + +StaticSprite::StaticSprite(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority, int16 x, int16 y, int16 width, int16 height) + : Sprite(vm, 0), _spriteResource(vm) { + + init(fileHash, surfacePriority, x, y, width, height); + +} + +void StaticSprite::init(uint32 fileHash, int surfacePriority, int16 x, int16 y, int16 width, int16 height) { + + _spriteResource.load2(fileHash); + + if (width == 0) + width = _spriteResource.getDimensions().width; + + if (height == 0) + height = _spriteResource.getDimensions().height; + + createSurface(surfacePriority, width, height); + + _x = x == kDefPosition ? _spriteResource.getPosition().x : x; + _y = y == kDefPosition ? _spriteResource.getPosition().y : y; + + _rect1.x1 = 0; + _rect1.y1 = 0; + _rect1.x2 = width; + _rect1.y2 = height; + + _needRedraw = true; + + update(); + +} + +void StaticSprite::update() { + + if (!_surface) + return; + + if (_doDeltaX) { + _x = filterX(_x - _rect1.x1 - _rect1.x2 + 1); + } else { + _x = filterX(_x + _rect1.x1); + } + + if (_doDeltaY) { + _y = filterY(_y - _rect1.y1 - _rect1.y2 + 1); + } else { + _y = filterY(_y + _rect1.y1); + } + + if (_needRedraw) { + // TODO _surface->drawSpriteResourceEx(_spriteResource, _doDeltaX, _doDeltaY, _rect1.x2, _rect1.y2); + _needRedraw = false; + } + +} + +void StaticSprite::load(uint32 fileHash, bool dimensions, bool position) { + + _spriteResource.load2(fileHash); + + if (dimensions) { + _rect1.x1 = 0; + _rect1.y1 = 0; + _rect1.x2 = _spriteResource.getDimensions().width; + _rect1.y2 = _spriteResource.getDimensions().height; + } + + if (position) { + _x = _spriteResource.getPosition().x; + _y = _spriteResource.getPosition().y; + } + + _needRedraw = true; + +} + +} // End of namespace Neverhood diff --git a/engines/neverhood/sprite.h b/engines/neverhood/sprite.h new file mode 100644 index 0000000000..5c08e3c66f --- /dev/null +++ b/engines/neverhood/sprite.h @@ -0,0 +1,90 @@ +/* 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_SPRITE_H +#define NEVERHOOD_SPRITE_H + +#include "neverhood/neverhood.h" +#include "neverhood/entity.h" +#include "neverhood/graphics.h" +#include "neverhood/resource.h" + +namespace Neverhood { + +#define SetSpriteCallback(callback) _spriteCallbackCb = 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) + +const int16 kDefPosition = -32768; + +class Sprite : public Entity { +public: + Sprite(NeverhoodEngine *vm, int objectPriority); + ~Sprite(); + BaseSurface *getSurface() { return _surface; } + void processDelta(); + void setDoDeltaX(int type); + void setDoDeltaY(int type); + bool isPointInside(int16 x, int16 y); +protected: + void (Sprite::*_spriteUpdateCb)(); + int16 (Sprite::*_filterXCb)(int16); + int16 (Sprite::*_filterYCb)(int16); + BaseSurface *_surface; + int16 _x, _y; + bool _doDeltaX, _doDeltaY; + bool _needRedraw; + //0000002B field_2B db ? + //0000002C field2C dd ? // unused + NRect _rect1; + int16 _deltaX1, _deltaY1; + int16 _deltaX2, _deltaY2; + NRect _rect; + uint16 _flags; + //0000004A field4A dw ? // seems to be unused except in ctor + //0000004C rectResource RectResource ? + //void update(); + uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); + void createSurface(int surfacePriority, int16 width, int16 height); + int16 filterX(int16 x) { + return _filterXCb ? (this->*_filterXCb)(x) : x; + } + int16 filterY(int16 y) { + return _filterYCb ? (this->*_filterYCb)(y) : y; + } +}; + +class StaticSprite : public Sprite { +public: + StaticSprite(NeverhoodEngine *vm, int objectPriority); + StaticSprite(NeverhoodEngine *vm, const char *filename, int surfacePriority, int16 x, int16 y, int16 width, int16 height); + StaticSprite(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority, int16 x, int16 y, int16 width, int16 height); + void load(uint32 fileHash, bool dimensions, bool position); +protected: + SpriteResource _spriteResource; + void init(uint32 fileHash, int surfacePriority, int16 x, int16 y, int16 width, int16 height); + void update(); +}; + +} // End of namespace Neverhood + +#endif /* NEVERHOOD_SPRITE_H */ |