NANCY: Viewport movement fixes

Added code so viewport edges do not get highlighted in directions the player can't go in.
This commit is contained in:
fracturehill 2021-02-19 18:46:33 +02:00 committed by Eugene Sandulenko
parent 1de1f568d7
commit c73ea1b0cb
4 changed files with 90 additions and 36 deletions

View File

@ -69,7 +69,7 @@ void Map::init() {
Common::String n(name);
_viewport.loadVideo(n, 0, 0);
_viewport.setEdges(0, 0, 0, 0);
_viewport.setEdgesSize(0, 0, 0, 0);
// Load the audio
chunk->seek(0x18 + _mapID * 0x20, SEEK_SET);

View File

@ -179,11 +179,11 @@ void Scene::load() {
_viewport.loadVideo(_sceneState.summary.videoFile, _sceneState.nextScene.frameID, _sceneState.nextScene.verticalOffset);
// TODO TEMPORARY
_viewport.setEdgesSize(25, 25, 25, 25);
if (_viewport.getFrameCount() <= 1) {
_viewport.setEdges(-1, -1, 0, 0);
} else {
// TODO TEMPORARY
_viewport.setEdges(-1, -1, 25, 25);
_viewport.disableEdges(kLeft | kRight);
}
if (!hasLoadedFromSavefile) {
@ -205,10 +205,7 @@ void Scene::load() {
// TODO not sure this ever gets hit
} else if (_sceneState.summary.videoFormat == 2) {
if (_viewport.getMaxScroll() == 0) {
_viewport.setEdges(0, 0, -1, -1);
} else {
// TODO TEMPORARY
_viewport.setEdges(25, 25, -1, -1);
_viewport.disableEdges(kUp | kDown);
}
}
}

View File

@ -64,16 +64,57 @@ void Viewport::handleInput(NancyInput &input) {
_engine->cursorManager->setCursorType(CursorManager::kNormal);
}
if (_upHotspot.contains(input.mousePos)) {
direction |= kUp;
} else if (_downHotspot.contains(input.mousePos)) {
direction |= kDown;
// Do not handle hotspots marked as incative and ignore diagonals if intersecting hotspots are not active
if (_upHotspot.contains(input.mousePos) && (_edgesMask & kUp) == 0) {
if (_upHotspot.findIntersectingRect(_leftHotspot).contains(input.mousePos)) {
if ((_edgesMask & kLeft) == 0) {
direction |= kUp;
}
} else if (_upHotspot.findIntersectingRect(_rightHotspot).contains(input.mousePos)) {
if ((_edgesMask & kRight) == 0) {
direction |= kUp;
}
} else {
direction |= kUp;
}
} else if (_downHotspot.contains(input.mousePos) && (_edgesMask & kDown) == 0) {
if (_downHotspot.findIntersectingRect(_leftHotspot).contains(input.mousePos)) {
if ((_edgesMask & kLeft) == 0) {
direction |= kDown;
}
} else if (_downHotspot.findIntersectingRect(_rightHotspot).contains(input.mousePos)) {
if ((_edgesMask & kRight) == 0) {
direction |= kDown;
}
} else {
direction |= kDown;
}
}
if (_leftHotspot.contains(input.mousePos)) {
direction |= kLeft;
} else if (_rightHotspot.contains(input.mousePos)) {
direction |= kRight;
if (_leftHotspot.contains(input.mousePos) && (_edgesMask & kLeft) == 0) {
if (_leftHotspot.findIntersectingRect(_upHotspot).contains(input.mousePos)) {
if ((_edgesMask & kUp) == 0) {
direction |= kLeft;
}
} else if (_leftHotspot.findIntersectingRect(_downHotspot).contains(input.mousePos)) {
if ((_edgesMask & kDown) == 0) {
direction |= kLeft;
}
} else {
direction |= kLeft;
}
} else if (_rightHotspot.contains(input.mousePos) && (_edgesMask & kRight) == 0) {
if (_rightHotspot.findIntersectingRect(_upHotspot).contains(input.mousePos)) {
if ((_edgesMask & kUp) == 0) {
direction |= kRight;
}
} else if (_rightHotspot.findIntersectingRect(_downHotspot).contains(input.mousePos)) {
if ((_edgesMask & kDown) == 0) {
direction |= kRight;
}
} else {
direction |= kRight;
}
}
if (direction) {
@ -145,6 +186,8 @@ void Viewport::loadVideo(const Common::String &filename, uint frameNr, uint vert
}
_decoder.loadFile(filename + ".avf");
enableEdges(kUp | kDown | kLeft | kRight);
setFrame(frameNr);
setVerticalScroll(verticalScroll);
}
@ -180,6 +223,16 @@ void Viewport::setVerticalScroll(uint scroll) {
sourceBounds.moveTo(0, scroll + 1);
_drawSurface.create(_fullFrame, sourceBounds);
_needsRedraw = true;
if (scroll == getMaxScroll()) {
disableEdges(kDown);
enableEdges(kUp);
} else if (scroll == 0) {
disableEdges(kUp);
enableEdges(kDown);
} else {
enableEdges(kUp | kDown);
}
_engine->scene->getSceneInfo().verticalOffset = scroll;
}
@ -216,26 +269,25 @@ Common::Rect Viewport::convertScreenToViewport(const Common::Rect &viewportRect)
return ret;
}
void Viewport::setEdges(int16 upSize, int16 downSize, int16 leftSize, int16 rightSize) {
if (upSize > -1) {
_upHotspot.setHeight(upSize);
}
void Viewport::setEdgesSize(uint16 upSize, uint16 downSize, uint16 leftSize, uint16 rightSize) {
_upHotspot.setHeight(upSize);
_leftHotspot.setWidth(leftSize);
if (leftSize > -1) {
_leftHotspot.setWidth(leftSize);
}
_downHotspot.top = _screenPosition.bottom;
_downHotspot.setHeight(downSize);
_downHotspot.translate(0, -downSize);
_rightHotspot.left = _screenPosition.right;
_rightHotspot.setWidth(rightSize);
_rightHotspot.translate(-rightSize, 0);
}
if (downSize > -1) {
_downHotspot.top = _screenPosition.bottom;
_downHotspot.setHeight(downSize);
_downHotspot.translate(0, -downSize);
}
void Viewport::disableEdges(byte edges) {
_edgesMask |= edges;
}
if (rightSize > -1) {
_rightHotspot.left = _screenPosition.right;
_rightHotspot.setWidth(rightSize);
_rightHotspot.translate(-rightSize, 0);
}
void Viewport::enableEdges(byte edges) {
_edgesMask &= ~edges;
}
} // End of namespace UI

View File

@ -42,7 +42,8 @@ class Viewport : public Nancy::RenderObject {
public:
Viewport(NancyEngine *engine) :
RenderObject(engine),
_movementLastFrame(0) {}
_movementLastFrame(0),
_edgesMask(0) {}
virtual ~Viewport() { _decoder.close(); _fullFrame.free(); }
virtual void init() override;
@ -71,7 +72,9 @@ public:
Common::Rect convertScreenToViewport(const Common::Rect &viewportRect) const;
// 0 is inactive, -1 is keep unchanged
void setEdges(int16 upSize, int16 downSize, int16 leftSize, int16 rightSize);
void setEdgesSize(uint16 upSize, uint16 downSize, uint16 leftSize, uint16 rightSize);
void disableEdges(byte edges);
void enableEdges(byte edges);
protected:
virtual uint16 getZOrder() const override { return 6; }
@ -81,6 +84,8 @@ protected:
Common::Rect _downHotspot;
Common::Rect _leftHotspot;
Common::Rect _rightHotspot;
byte _edgesMask;
byte _movementLastFrame;
Time _nextMovementTime;