MYST3: Implement dragging the symbols from the inventory

This commit is contained in:
Bastien Bouclet 2012-01-30 20:13:16 +01:00
parent eb6a71ef48
commit b8dbae83e3
7 changed files with 125 additions and 20 deletions

View File

@ -31,9 +31,9 @@ namespace Myst3 {
class Drawable {
public:
virtual void draw() = 0;
virtual void drawOverlay() {};
virtual ~Drawable() {};
virtual void draw() {}
virtual void drawOverlay() {}
virtual ~Drawable() {}
};
class Texture {

View File

@ -68,4 +68,14 @@ bool HotSpot::isPointInRectsFrame(GameState *state, const Common::Point &p) {
return false;
}
bool HotSpot::isEnabled(GameState *state, uint16 var) {
if (!state->evaluate(condition))
return false;
if (var == 0)
return cursor < 12;
else
return cursor == var;
}
} /* namespace Myst3 */

View File

@ -56,6 +56,7 @@ public:
bool isPointInRectsCube(const Common::Point &p);
bool isPointInRectsFrame(GameState *state, const Common::Point &p);
bool isEnabled(GameState *state, uint16 var = 0);
};

View File

@ -61,14 +61,19 @@ void Inventory::draw() {
Common::Point mouse = _vm->_cursor->getPosition();
for (ItemList::const_iterator it = _inventory.begin(); it != _inventory.end(); it++) {
int32 state = _vm->_state->getVar(it->var);
// Don't draw if the item is being dragged
if (state == -1)
continue;
const ItemData &item = getData(it->var);
Common::Rect textureRect = Common::Rect(item.textureWidth,
item.textureHeight);
textureRect.translate(item.textureX, 0);
bool itemHighlighted = it->rect.contains(mouse)
|| (_vm->_state->getVar(it->var) == 2);
bool itemHighlighted = it->rect.contains(mouse) || state == 2;
if (itemHighlighted)
textureRect.translate(0, _texture->height / 2);
@ -205,6 +210,15 @@ void Inventory::useItem(uint16 var) {
_vm->_state->setBookStateReleeshahn(2);
openBook(9, 902, 300);
break;
case 345:
_vm->dragSymbol(345, 1002);
break;
case 398:
_vm->dragSymbol(398, 1001);
break;
case 447:
_vm->dragSymbol(447, 1000);
break;
default:
debug("Used inventory item %d which is not implemented", var);
}
@ -257,4 +271,38 @@ void Inventory::updateState() {
_vm->_state->updateInventory(items);
}
DragItem::DragItem(Myst3Engine *vm, uint id):
_vm(vm),
_texture(0) {
const DirectorySubEntry *movieDesc = _vm->getFileDescription("DRAG", id, 0, DirectorySubEntry::kStillMovie);
if (!movieDesc)
error("Movie %d does not exist", id);
// Load the movie
_movieStream = movieDesc->getData();
_bink.loadStream(_movieStream, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
const Graphics::Surface *frame = _bink.decodeNextFrame();
_texture = _vm->_gfx->createTexture(frame);
}
DragItem::~DragItem() {
_vm->_gfx->freeTexture(_texture);
}
void DragItem::drawOverlay() {
Common::Rect textureRect = Common::Rect(_texture->width, _texture->height);
_vm->_gfx->drawTexturedRect2D(getPosition(), textureRect, _texture, 0.99);
}
Common::Rect DragItem::getPosition() {
Common::Point mouse = _vm->_cursor->getPosition();
uint posX = CLIP<uint>(mouse.x, _texture->width / 2, Renderer::kOriginalWidth - _texture->width / 2);
uint posY = CLIP<uint>(mouse.y, _texture->height / 2, Renderer::kOriginalHeight - _texture->height / 2);
Common::Rect screenRect = Common::Rect::center(posX, posY, _texture->width, _texture->height);
return screenRect;
}
} /* namespace Myst3 */

View File

@ -24,8 +24,13 @@
#define INVENTORY_H_
#include "common/list.h"
#include "common/memstream.h"
#include "common/rect.h"
#include "engines/myst3/gfx.h"
#include "video/bink_decoder_seek.h"
namespace Myst3 {
class Myst3Engine;
@ -81,5 +86,22 @@ private:
void closeAllBooks();
};
class DragItem : public Drawable {
public:
DragItem(Myst3Engine *vm, uint id);
~DragItem();
void drawOverlay();
private:
Myst3Engine *_vm;
Common::MemoryReadStream *_movieStream;
Video::SeekableBinkDecoder _bink;
Texture *_texture;
Common::Rect getPosition();
};
} /* namespace Myst3 */
#endif /* INVENTORY_H_ */

View File

@ -198,7 +198,7 @@ void Myst3Engine::addArchive(const Common::String &file, bool mandatory) {
}
}
Common::Array<HotSpot *> Myst3Engine::listHoveredHotspots(NodePtr nodeData) {
Common::Array<HotSpot *> Myst3Engine::listHoveredHotspots(NodePtr nodeData, uint16 var) {
Common::Array<HotSpot *> hovered;
if (_state->getViewType() == kCube) {
@ -208,8 +208,7 @@ Common::Array<HotSpot *> Myst3Engine::listHoveredHotspots(NodePtr nodeData) {
for (uint j = 0; j < nodeData->hotspots.size(); j++) {
if (nodeData->hotspots[j].isPointInRectsCube(mouse)
&& _state->evaluate(nodeData->hotspots[j].condition)
&& nodeData->hotspots[j].cursor < 12) {
&& nodeData->hotspots[j].isEnabled(_state, var)) {
hovered.push_back(&nodeData->hotspots[j]);
}
}
@ -231,8 +230,7 @@ Common::Array<HotSpot *> Myst3Engine::listHoveredHotspots(NodePtr nodeData) {
for (uint j = 0; j < nodeData->hotspots.size(); j++) {
if (nodeData->hotspots[j].isPointInRectsFrame(_state, scaledMouse)
&& _state->evaluate(nodeData->hotspots[j].condition)
&& nodeData->hotspots[j].cursor < 12) {
&& nodeData->hotspots[j].isEnabled(_state, var)) {
hovered.push_back(&nodeData->hotspots[j]);
}
}
@ -381,15 +379,6 @@ void Myst3Engine::drawFrame() {
if (_state->getViewType() == kCube) {
_gfx->setupCameraOrtho2D();
// Draw overlay 2D movies
for (uint i = 0; i < _movies.size(); i++) {
_movies[i]->drawOverlay();
}
for (uint i = 0; i < _drawables.size(); i++) {
_drawables[i]->drawOverlay();
}
}
if (_state->getViewType() != kMenu) {
@ -403,6 +392,15 @@ void Myst3Engine::drawFrame() {
_inventory->draw();
}
// Draw overlay 2D movies
for (uint i = 0; i < _movies.size(); i++) {
_movies[i]->drawOverlay();
}
for (uint i = 0; i < _drawables.size(); i++) {
_drawables[i]->drawOverlay();
}
if (_cursor->isVisible())
_cursor->draw();
@ -842,6 +840,30 @@ int16 Myst3Engine::openDialog(uint16 id) {
return result;
}
void Myst3Engine::dragSymbol(uint16 var, uint16 id) {
DragItem drag(this, id);
_drawables.push_back(&drag);
_cursor->changeCursor(2);
_state->setVar(var, -1);
NodePtr nodeData = _db->getNodeData(_state->getLocationNode(), _state->getLocationRoom());
while (inputValidatePressed() && !shouldQuit()) {
processInput(true);
drawFrame();
}
Common::Array<HotSpot *> hovered = listHoveredHotspots(nodeData, var);
if (!hovered.empty())
_scriptEngine->run(&hovered.front()->script);
_state->setVar(var, 1);
_drawables.pop_back();
}
bool Myst3Engine::canLoadGameStateCurrently() {
return true;
}

View File

@ -98,6 +98,8 @@ public:
void loadNodeCubeFaces(uint16 nodeID);
void loadNodeFrame(uint16 nodeID);
void loadNodeMenu(uint16 nodeID);
void dragSymbol(uint16 var, uint16 id);
int16 openDialog(uint16 id);
void runNodeInitScripts();
@ -155,7 +157,7 @@ private:
bool _inputEscapePressed;
bool _inputTildePressed;
Common::Array<HotSpot *> listHoveredHotspots(NodePtr nodeData);
Common::Array<HotSpot *> listHoveredHotspots(NodePtr nodeData, uint16 var = 0);
void updateCursor();
void addArchive(const Common::String &file, bool mandatory);