diff options
Diffstat (limited to 'engines/zvision/scripting/controls')
-rw-r--r-- | engines/zvision/scripting/controls/animation_control.cpp | 263 | ||||
-rw-r--r-- | engines/zvision/scripting/controls/animation_control.h | 87 | ||||
-rw-r--r-- | engines/zvision/scripting/controls/input_control.cpp | 31 | ||||
-rw-r--r-- | engines/zvision/scripting/controls/input_control.h | 10 | ||||
-rw-r--r-- | engines/zvision/scripting/controls/lever_control.cpp | 136 | ||||
-rw-r--r-- | engines/zvision/scripting/controls/lever_control.h | 16 | ||||
-rw-r--r-- | engines/zvision/scripting/controls/push_toggle_control.cpp | 67 | ||||
-rw-r--r-- | engines/zvision/scripting/controls/push_toggle_control.h | 14 | ||||
-rw-r--r-- | engines/zvision/scripting/controls/timer_node.cpp | 41 | ||||
-rw-r--r-- | engines/zvision/scripting/controls/timer_node.h | 14 |
10 files changed, 186 insertions, 493 deletions
diff --git a/engines/zvision/scripting/controls/animation_control.cpp b/engines/zvision/scripting/controls/animation_control.cpp deleted file mode 100644 index e351e81d25..0000000000 --- a/engines/zvision/scripting/controls/animation_control.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/* 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 "common/scummsys.h" - -#include "zvision/scripting/controls/animation_control.h" - -#include "zvision/zvision.h" -#include "zvision/graphics/render_manager.h" -#include "zvision/scripting/script_manager.h" -#include "zvision/animation/rlf_animation.h" -#include "zvision/video/zork_avi_decoder.h" - -#include "video/video_decoder.h" - -#include "graphics/surface.h" - - -namespace ZVision { - -AnimationControl::AnimationControl(ZVision *engine, uint32 controlKey, const Common::String &fileName) - : Control(engine, controlKey), - _fileType(RLF), - _loopCount(1), - _currentLoop(0), - _accumulatedTime(0), - _cachedFrame(0), - _cachedFrameNeedsDeletion(false) { - if (fileName.hasSuffix(".rlf")) { - _fileType = RLF; - _animation.rlf = new RlfAnimation(fileName, false); - } else if (fileName.hasSuffix(".avi")) { - _fileType = AVI; - _animation.avi = new ZorkAVIDecoder(); - _animation.avi->loadFile(fileName); - } else { - warning("Unrecognized animation file type: %s", fileName.c_str()); - } - - _cachedFrame = new Graphics::Surface(); -} - -AnimationControl::~AnimationControl() { - if (_fileType == RLF) { - delete _animation.rlf; - } else if (_fileType == AVI) { - delete _animation.avi; - } - - _cachedFrame->free(); - delete _cachedFrame; -} - -bool AnimationControl::process(uint32 deltaTimeInMillis) { - if (!_enabled) { - return false; - } - - bool finished = false; - - if (_fileType == RLF) { - _accumulatedTime += deltaTimeInMillis; - - uint32 frameTime = _animation.rlf->frameTime(); - if (_accumulatedTime >= frameTime) { - while (_accumulatedTime >= frameTime) { - _accumulatedTime -= frameTime; - - // Make sure the frame is inside the working window - // If it's not, then just return - - RenderManager *renderManager = _engine->getRenderManager(); - Common::Point workingWindowPoint = renderManager->imageSpaceToWorkingWindowSpace(Common::Point(_x, _y)); - Common::Rect subRect(workingWindowPoint.x, workingWindowPoint.y, workingWindowPoint.x + _animation.rlf->width(), workingWindowPoint.y + _animation.rlf->height()); - - // If the clip returns false, it means the animation is outside the working window - if (!renderManager->clipRectToWorkingWindow(subRect)) { - return false; - } - - const Graphics::Surface *frame = _animation.rlf->getNextFrame(); - - // Animation frames for PANORAMAs are transposed, so un-transpose them - RenderTable::RenderState state = renderManager->getRenderTable()->getRenderState(); - if (state == RenderTable::PANORAMA) { - Graphics::Surface *tranposedFrame = RenderManager::tranposeSurface(frame); - - renderManager->copyRectToWorkingWindow((uint16 *)tranposedFrame->getBasePtr(tranposedFrame->w - subRect.width(), tranposedFrame->h - subRect.height()), subRect.left, subRect.top, _animation.rlf->width(), subRect.width(), subRect.height()); - - // If the background can move, we need to cache the last frame so it can be rendered during background movement - if (state == RenderTable::PANORAMA || state == RenderTable::TILT) { - if (_cachedFrameNeedsDeletion) { - _cachedFrame->free(); - delete _cachedFrame; - _cachedFrameNeedsDeletion = false; - } - _cachedFrame = tranposedFrame; - _cachedFrameNeedsDeletion = true; - } else { - // Cleanup - tranposedFrame->free(); - delete tranposedFrame; - } - } else { - renderManager->copyRectToWorkingWindow((const uint16 *)frame->getBasePtr(frame->w - subRect.width(), frame->h - subRect.height()), subRect.left, subRect.top, _animation.rlf->width(), subRect.width(), subRect.height()); - - // If the background can move, we need to cache the last frame so it can be rendered during background movement - if (state == RenderTable::PANORAMA || state == RenderTable::TILT) { - if (_cachedFrameNeedsDeletion) { - _cachedFrame->free(); - delete _cachedFrame; - _cachedFrameNeedsDeletion = false; - } - _cachedFrame->copyFrom(*frame); - } - } - - // Check if we should continue looping - if (_animation.rlf->endOfAnimation()) { - _animation.rlf->seekToFrame(-1); - if (_loopCount > 0) { - _currentLoop++; - if (_currentLoop >= _loopCount) { - finished = true; - } - } - } - } - } else { - // If the background can move, we have to keep rendering animation frames, otherwise the animation flickers during background movement - RenderManager *renderManager = _engine->getRenderManager(); - RenderTable::RenderState state = renderManager->getRenderTable()->getRenderState(); - - if (state == RenderTable::PANORAMA || state == RenderTable::TILT) { - Common::Point workingWindowPoint = renderManager->imageSpaceToWorkingWindowSpace(Common::Point(_x, _y)); - Common::Rect subRect(workingWindowPoint.x, workingWindowPoint.y, workingWindowPoint.x + _cachedFrame->w, workingWindowPoint.y + _cachedFrame->h); - - // If the clip returns false, it means the animation is outside the working window - if (!renderManager->clipRectToWorkingWindow(subRect)) { - return false; - } - - renderManager->copyRectToWorkingWindow((uint16 *)_cachedFrame->getBasePtr(_cachedFrame->w - subRect.width(), _cachedFrame->h - subRect.height()), subRect.left, subRect.top, _cachedFrame->w, subRect.width(), subRect.height()); - } - } - } else if (_fileType == AVI) { - if (!_animation.avi->isPlaying()) { - _animation.avi->start(); - } - - if (_animation.avi->needsUpdate()) { - const Graphics::Surface *frame = _animation.avi->decodeNextFrame(); - - if (frame) { - // Make sure the frame is inside the working window - // If it's not, then just return - - RenderManager *renderManager = _engine->getRenderManager(); - Common::Point workingWindowPoint = renderManager->imageSpaceToWorkingWindowSpace(Common::Point(_x, _y)); - Common::Rect subRect(workingWindowPoint.x, workingWindowPoint.y, workingWindowPoint.x + frame->w, workingWindowPoint.y + frame->h); - - // If the clip returns false, it means the animation is outside the working window - if (!renderManager->clipRectToWorkingWindow(subRect)) { - return false; - } - - // Animation frames for PANORAMAs are transposed, so un-transpose them - RenderTable::RenderState state = renderManager->getRenderTable()->getRenderState(); - if (state == RenderTable::PANORAMA) { - Graphics::Surface *tranposedFrame = RenderManager::tranposeSurface(frame); - - renderManager->copyRectToWorkingWindow((uint16 *)tranposedFrame->getBasePtr(tranposedFrame->w - subRect.width(), tranposedFrame->h - subRect.height()), subRect.left, subRect.top, frame->w, subRect.width(), subRect.height()); - - // If the background can move, we need to cache the last frame so it can be rendered during background movement - if (state == RenderTable::PANORAMA || state == RenderTable::TILT) { - if (_cachedFrameNeedsDeletion) { - _cachedFrame->free(); - delete _cachedFrame; - _cachedFrameNeedsDeletion = false; - } - _cachedFrame = tranposedFrame; - _cachedFrameNeedsDeletion = true; - } else { - // Cleanup - tranposedFrame->free(); - delete tranposedFrame; - } - } else { - renderManager->copyRectToWorkingWindow((const uint16 *)frame->getBasePtr(frame->w - subRect.width(), frame->h - subRect.height()), subRect.left, subRect.top, frame->w, subRect.width(), subRect.height()); - - // If the background can move, we need to cache the last frame so it can be rendered during background movement - if (state == RenderTable::PANORAMA || state == RenderTable::TILT) { - if (_cachedFrameNeedsDeletion) { - _cachedFrame->free(); - delete _cachedFrame; - _cachedFrameNeedsDeletion = false; - } - _cachedFrame->copyFrom(*frame); - } - } - } else { - // If the background can move, we have to keep rendering animation frames, otherwise the animation flickers during background movement - RenderManager *renderManager = _engine->getRenderManager(); - RenderTable::RenderState state = renderManager->getRenderTable()->getRenderState(); - - if (state == RenderTable::PANORAMA || state == RenderTable::TILT) { - Common::Point workingWindowPoint = renderManager->imageSpaceToWorkingWindowSpace(Common::Point(_x, _y)); - Common::Rect subRect(workingWindowPoint.x, workingWindowPoint.y, workingWindowPoint.x + _cachedFrame->w, workingWindowPoint.y + _cachedFrame->h); - - // If the clip returns false, it means the animation is outside the working window - if (!renderManager->clipRectToWorkingWindow(subRect)) { - return false; - } - - renderManager->copyRectToWorkingWindow((uint16 *)_cachedFrame->getBasePtr(_cachedFrame->w - subRect.width(), _cachedFrame->h - subRect.height()), subRect.left, subRect.top, _cachedFrame->w, subRect.width(), subRect.height()); - } - } - } - - // Check if we should continue looping - if (_animation.avi->endOfVideo()) { - _animation.avi->rewind(); - if (_loopCount > 0) { - _currentLoop++; - if (_currentLoop >= _loopCount) { - _animation.avi->stop(); - finished = true; - } - } - } - } - - // If we're done, set _animation key = 2 (Why 2? I don't know. It's just the value that they used) - // Then disable the control. DON'T delete it. It can be re-used - if (finished) { - _engine->getScriptManager()->setStateValue(_animationKey, 2); - disable(); - _currentLoop = 0; - } - - return false; -} - -} // End of namespace ZVision diff --git a/engines/zvision/scripting/controls/animation_control.h b/engines/zvision/scripting/controls/animation_control.h deleted file mode 100644 index 6c4d6dfcf7..0000000000 --- a/engines/zvision/scripting/controls/animation_control.h +++ /dev/null @@ -1,87 +0,0 @@ -/* 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 ZVISION_ANIMATION_CONTROL_H -#define ZVISION_ANIMATION_CONTROL_H - -#include "zvision/scripting/control.h" - - -namespace Common { -class String; -} - -namespace Video { -class VideoDecoder; -} - -namespace Graphics { -struct Surface; -} - -namespace ZVision { - -class ZVision; -class RlfAnimation; - -class AnimationControl : public Control { -public: - AnimationControl(ZVision *engine, uint32 controlKey, const Common::String &fileName); - ~AnimationControl(); - -private: - enum FileType { - RLF = 1, - AVI = 2 - }; - -private: - uint32 _animationKey; - - union { - RlfAnimation *rlf; - Video::VideoDecoder *avi; - } _animation; - - FileType _fileType; - uint _loopCount; - int32 _x; - int32 _y; - - uint _accumulatedTime; - uint _currentLoop; - - Graphics::Surface *_cachedFrame; - bool _cachedFrameNeedsDeletion; - -public: - bool process(uint32 deltaTimeInMillis); - - void setAnimationKey(uint32 animationKey) { _animationKey = animationKey; } - void setLoopCount(uint loopCount) { _loopCount = loopCount; } - void setXPos(int32 x) { _x = x; } - void setYPost(int32 y) { _y = y; } -}; - -} // End of namespace ZVision - -#endif diff --git a/engines/zvision/scripting/controls/input_control.cpp b/engines/zvision/scripting/controls/input_control.cpp index 5cf5086691..a366e06923 100644 --- a/engines/zvision/scripting/controls/input_control.cpp +++ b/engines/zvision/scripting/controls/input_control.cpp @@ -8,12 +8,12 @@ * 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. @@ -22,13 +22,13 @@ #include "common/scummsys.h" -#include "zvision/scripting/controls/input_control.h" +#include "zvision/input_control.h" #include "zvision/zvision.h" -#include "zvision/scripting/script_manager.h" -#include "zvision/strings/string_manager.h" -#include "zvision/graphics/render_manager.h" -#include "zvision/utility/utility.h" +#include "zvision/script_manager.h" +#include "zvision/string_manager.h" +#include "zvision/render_manager.h" +#include "zvision/utility.h" #include "common/str.h" #include "common/stream.h" @@ -38,11 +38,11 @@ namespace ZVision { InputControl::InputControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream) - : Control(engine, key), - _nextTabstop(0), - _focused(false), - _textChanged(false), - _cursorOffset(0) { + : Control(engine, key), + _nextTabstop(0), + _focused(false), + _textChanged(false), + _cursorOffset(0) { // Loop until we find the closing brace Common::String line = stream.readLine(); trimCommentsAndWhiteSpace(&line); @@ -93,8 +93,9 @@ InputControl::InputControl(ZVision *engine, uint32 key, Common::SeekableReadStre } } -void InputControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) { +bool InputControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) { _engine->getScriptManager()->focusControl(_key); + return false; } void InputControl::onKeyDown(Common::KeyState keyState) { @@ -128,9 +129,9 @@ bool InputControl::process(uint32 deltaTimeInMillis) { // First see if we need to render the text if (_textChanged) { // Blit the text using the RenderManager - Common::Rect destRect = _engine->getRenderManager()->renderTextToWorkingWindow(_key, _currentInputText, _textStyle.font, _textRectangle.left, _textRectangle.top, _textStyle.color, _textRectangle.width()); + //Common::Rect destRect = _engine->getRenderManager()->renderTextToWorkingWindow(_key, _currentInputText, _textStyle.font, _textRectangle.left, _textRectangle.top, _textStyle.color, _textRectangle.width()); - _cursorOffset = destRect.left - _textRectangle.left; + //_cursorOffset = destRect.left - _textRectangle.left; } // Render the next frame of the animation diff --git a/engines/zvision/scripting/controls/input_control.h b/engines/zvision/scripting/controls/input_control.h index 32432438bb..4a63f228a0 100644 --- a/engines/zvision/scripting/controls/input_control.h +++ b/engines/zvision/scripting/controls/input_control.h @@ -48,9 +48,13 @@ private: uint _cursorOffset; public: - void focus() { _focused = true; } - void unfocus() { _focused = false; } - void onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos); + void focus() { + _focused = true; + } + void unfocus() { + _focused = false; + } + bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos); void onKeyDown(Common::KeyState keyState); bool process(uint32 deltaTimeInMillis); }; diff --git a/engines/zvision/scripting/controls/lever_control.cpp b/engines/zvision/scripting/controls/lever_control.cpp index 9724e661b7..f68f256229 100644 --- a/engines/zvision/scripting/controls/lever_control.cpp +++ b/engines/zvision/scripting/controls/lever_control.cpp @@ -8,12 +8,12 @@ * 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. @@ -22,15 +22,14 @@ #include "common/scummsys.h" -#include "zvision/scripting/controls/lever_control.h" +#include "zvision/lever_control.h" #include "zvision/zvision.h" -#include "zvision/scripting/script_manager.h" -#include "zvision/graphics/render_manager.h" -#include "zvision/cursors/cursor_manager.h" -#include "zvision/animation/rlf_animation.h" -#include "zvision/video/zork_avi_decoder.h" -#include "zvision/utility/utility.h" +#include "zvision/script_manager.h" +#include "zvision/render_manager.h" +#include "zvision/cursor_manager.h" +#include "zvision/meta_animation.h" +#include "zvision/utility.h" #include "common/stream.h" #include "common/file.h" @@ -43,16 +42,16 @@ namespace ZVision { LeverControl::LeverControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream) - : Control(engine, key), - _frameInfo(0), - _frameCount(0), - _startFrame(0), - _currentFrame(0), - _lastRenderedFrame(0), - _mouseIsCaptured(false), - _isReturning(false), - _accumulatedTime(0), - _returnRoutesCurrentFrame(0) { + : Control(engine, key), + _frameInfo(0), + _frameCount(0), + _startFrame(0), + _currentFrame(0), + _lastRenderedFrame(0), + _mouseIsCaptured(false), + _isReturning(false), + _accumulatedTime(0), + _returnRoutesCurrentFrame(0) { // Loop until we find the closing brace Common::String line = stream.readLine(); @@ -79,25 +78,24 @@ LeverControl::LeverControl(ZVision *engine, uint32 key, Common::SeekableReadStre } LeverControl::~LeverControl() { - if (_fileType == AVI) { - delete _animation.avi; - } else if (_fileType == RLF) { - delete _animation.rlf; - } - + if (_animation) + delete _animation; + delete[] _frameInfo; } void LeverControl::parseLevFile(const Common::String &fileName) { Common::File file; - if (!file.open(fileName)) { + if (!_engine->getSearchManager()->openFile(file, fileName)) { warning("LEV file %s could could be opened", fileName.c_str()); return; } - Common::String line = file.readLine(); + Common::String line; while (!file.eos()) { + line = file.readLine(); + if (line.matchString("*animation_id*", true)) { // Not used } else if (line.matchString("*filename*", true)) { @@ -106,14 +104,9 @@ void LeverControl::parseLevFile(const Common::String &fileName) { Common::String animationFileName(fileNameBuffer); - if (animationFileName.hasSuffix(".avi")) { - _animation.avi = new ZorkAVIDecoder(); - _animation.avi->loadFile(animationFileName); - _fileType = AVI; - } else if (animationFileName.hasSuffix(".rlf")) { - _animation.rlf = new RlfAnimation(animationFileName, false); - _fileType = RLF; - } + if (animationFileName.hasSuffix(".avi") || animationFileName.hasSuffix(".rlf")) + _animation = new MetaAnimation(animationFileName, _engine); + } else if (line.matchString("*skipcolor*", true)) { // Not used } else if (line.matchString("*anim_coords*", true)) { @@ -151,6 +144,8 @@ void LeverControl::parseLevFile(const Common::String &fileName) { uint frameNumber; uint x, y; + line.toLowercase(); + if (sscanf(line.c_str(), "%u:%u %u", &frameNumber, &x, &y) == 3) { _frameInfo[frameNumber].hotspot.left = x; _frameInfo[frameNumber].hotspot.top = y; @@ -158,13 +153,13 @@ void LeverControl::parseLevFile(const Common::String &fileName) { _frameInfo[frameNumber].hotspot.bottom = y + _hotspotDelta.y; } - Common::StringTokenizer tokenizer(line, " ^=()"); + Common::StringTokenizer tokenizer(line, " ^=()~"); tokenizer.nextToken(); tokenizer.nextToken(); Common::String token = tokenizer.nextToken(); while (!tokenizer.empty()) { - if (token == "D") { + if (token == "d") { token = tokenizer.nextToken(); uint angle; @@ -172,7 +167,7 @@ void LeverControl::parseLevFile(const Common::String &fileName) { sscanf(token.c_str(), "%u,%u", &toFrame, &angle); _frameInfo[frameNumber].directions.push_back(Direction(angle, toFrame)); - } else if (token.hasPrefix("P")) { + } else if (token.hasPrefix("p")) { // Format: P(<from> to <to>) tokenizer.nextToken(); tokenizer.nextToken(); @@ -186,26 +181,25 @@ void LeverControl::parseLevFile(const Common::String &fileName) { } } - line = file.readLine(); + // Don't read lines in this place because last will not be parsed. } } -void LeverControl::onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) { - if (!_enabled) { - return; - } - +bool LeverControl::onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) { + if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED) + return false; + if (_frameInfo[_currentFrame].hotspot.contains(backgroundImageSpacePos)) { _mouseIsCaptured = true; _lastMousePos = backgroundImageSpacePos; } + return false; } -void LeverControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) { - if (!_enabled) { - return; - } - +bool LeverControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) { + if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED) + return false; + if (_mouseIsCaptured) { _mouseIsCaptured = false; _engine->getScriptManager()->setStateValue(_key, _currentFrame); @@ -214,13 +208,13 @@ void LeverControl::onMouseUp(const Common::Point &screenSpacePos, const Common:: _returnRoutesCurrentProgress = _frameInfo[_currentFrame].returnRoute.begin(); _returnRoutesCurrentFrame = _currentFrame; } + return false; } bool LeverControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) { - if (!_enabled) { + if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED) return false; - } - + bool cursorWasChanged = false; if (_mouseIsCaptured) { @@ -240,7 +234,7 @@ bool LeverControl::onMouseMove(const Common::Point &screenSpacePos, const Common } } } else if (_frameInfo[_currentFrame].hotspot.contains(backgroundImageSpacePos)) { - _engine->getCursorManager()->changeCursor(_cursorName); + _engine->getCursorManager()->changeCursor(_engine->getCursorManager()->getCursorId(_cursorName)); cursorWasChanged = true; } @@ -248,9 +242,8 @@ bool LeverControl::onMouseMove(const Common::Point &screenSpacePos, const Common } bool LeverControl::process(uint32 deltaTimeInMillis) { - if (!_enabled) { + if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED) return false; - } if (_isReturning) { _accumulatedTime += deltaTimeInMillis; @@ -276,7 +269,7 @@ bool LeverControl::process(uint32 deltaTimeInMillis) { renderFrame(_returnRoutesCurrentFrame); } } - + return false; } @@ -301,7 +294,7 @@ int LeverControl::calculateVectorAngle(const Common::Point &pointOne, const Comm // Calculate the angle using arctan // Then convert to degrees. (180 / 3.14159 = 57.2958) - int angle = int(atan((float)yDist / (float)xDist) * 57); + int angle = int(atan((float)yDist / (float)abs(xDist)) * 57); // Calculate what quadrant pointTwo is in uint quadrant = ((yDist > 0 ? 1 : 0) << 1) | (xDist < 0 ? 1 : 0); @@ -350,16 +343,16 @@ int LeverControl::calculateVectorAngle(const Common::Point &pointOne, const Comm // Convert the local angles to unit circle angles switch (quadrant) { case 0: - angle = 180 + angle; + angle = -angle; break; case 1: - // Do nothing + angle = angle + 180; break; case 2: - angle = 180 + angle; + angle = 360 - angle; break; case 3: - angle = 360 + angle; + angle = 180 + angle; break; } @@ -377,26 +370,13 @@ void LeverControl::renderFrame(uint frameNumber) { _lastRenderedFrame = frameNumber; } - const uint16 *frameData = 0; + const Graphics::Surface *frameData; int x = _animationCoords.left; int y = _animationCoords.top; - int width = 0; - int height = 0; - - if (_fileType == RLF) { - // getFrameData() will automatically optimize to getNextFrame() / getPreviousFrame() if it can - frameData = (const uint16 *)_animation.rlf->getFrameData(frameNumber)->getPixels(); - width = _animation.rlf->width(); // Use the animation width instead of _animationCoords.width() - height = _animation.rlf->height(); // Use the animation height instead of _animationCoords.height() - } else if (_fileType == AVI) { - _animation.avi->seekToFrame(frameNumber); - const Graphics::Surface *surface = _animation.avi->decodeNextFrame(); - frameData = (const uint16 *)surface->getPixels(); - width = surface->w; - height = surface->h; - } - _engine->getRenderManager()->copyRectToWorkingWindow(frameData, x, y, width, width, height); + frameData = _animation->getFrameData(frameNumber); + if (frameData) + _engine->getRenderManager()->blitSurfaceToBkg(*frameData, x, y); } } // End of namespace ZVision diff --git a/engines/zvision/scripting/controls/lever_control.h b/engines/zvision/scripting/controls/lever_control.h index 49e4fd3806..712d688523 100644 --- a/engines/zvision/scripting/controls/lever_control.h +++ b/engines/zvision/scripting/controls/lever_control.h @@ -32,7 +32,7 @@ namespace ZVision { class ZorkAVIDecoder; -class RlfAnimation; +class MetaAnimation; class LeverControl : public Control { public: @@ -40,10 +40,6 @@ public: ~LeverControl(); private: - enum FileType { - RLF = 1, - AVI = 2 - }; struct Direction { Direction(uint a, uint t) : angle(a), toFrame(t) {} @@ -64,11 +60,7 @@ private: }; private: - union { - RlfAnimation *rlf; - ZorkAVIDecoder *avi; - } _animation; - FileType _fileType; + MetaAnimation *_animation; Common::String _cursorName; Common::Rect _animationCoords; @@ -88,8 +80,8 @@ private: uint32 _accumulatedTime; public: - void onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos); - void onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos); + bool onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos); + bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos); bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos); bool process(uint32 deltaTimeInMillis); diff --git a/engines/zvision/scripting/controls/push_toggle_control.cpp b/engines/zvision/scripting/controls/push_toggle_control.cpp index 82736b7576..16cd971ad5 100644 --- a/engines/zvision/scripting/controls/push_toggle_control.cpp +++ b/engines/zvision/scripting/controls/push_toggle_control.cpp @@ -35,10 +35,13 @@ namespace ZVision { PushToggleControl::PushToggleControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream) - : Control(engine, key) { + : Control(engine, key), + _countTo(2), + _event(Common::EVENT_LBUTTONUP) { // Loop until we find the closing brace Common::String line = stream.readLine(); trimCommentsAndWhiteSpace(&line); + line.toLowercase(); while (!stream.eos() && !line.contains('}')) { if (line.matchString("*_hotspot*", true)) { @@ -56,6 +59,27 @@ PushToggleControl::PushToggleControl(ZVision *engine, uint32 key, Common::Seekab sscanf(line.c_str(), "%*[^(](%25[^)])", nameBuffer); _hoverCursor = Common::String(nameBuffer); + } else if (line.matchString("animation*", true)) { + // Not used + } else if (line.matchString("sound*", true)) { + // Not used + } else if (line.matchString("count_to*", true)) { + sscanf(line.c_str(), "%*[^(](%u)", &_countTo); + } else if (line.matchString("mouse_event*", true)) { + char nameBuffer[25]; + + sscanf(line.c_str(), "%*[^(](%25[^)])", nameBuffer); + + Common::String evntStr(nameBuffer); + if (evntStr.equalsIgnoreCase("up")) { + _event = Common::EVENT_LBUTTONUP; + } else if (evntStr.equalsIgnoreCase("down")) { + _event = Common::EVENT_LBUTTONDOWN; + } else if (evntStr.equalsIgnoreCase("double")) { + // Not used + } + } else if (line.matchString("venus_id*", true)) { + // Not used } line = stream.readLine(); @@ -68,27 +92,46 @@ PushToggleControl::PushToggleControl(ZVision *engine, uint32 key, Common::Seekab } PushToggleControl::~PushToggleControl() { - // Clear the state value back to 0 - _engine->getScriptManager()->setStateValue(_key, 0); } -void PushToggleControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) { - if (!_enabled) { - return; +bool PushToggleControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) { + if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED) + return false; + + if (_event != Common::EVENT_LBUTTONUP) + return false; + + if (_hotspot.contains(backgroundImageSpacePos)) { + int32 val = _engine->getScriptManager()->getStateValue(_key); + val = (val + 1) % _countTo; + _engine->getScriptManager()->setStateValue(_key, val); + return true; } - + return false; +} + +bool PushToggleControl::onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) { + if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED) + return false; + + if (_event != Common::EVENT_LBUTTONDOWN) + return false; + if (_hotspot.contains(backgroundImageSpacePos)) { - _engine->getScriptManager()->setStateValue(_key, 1); + int32 val = _engine->getScriptManager()->getStateValue(_key); + val = (val + 1) % _countTo; + _engine->getScriptManager()->setStateValue(_key, val); + return true; } + return false; } bool PushToggleControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) { - if (!_enabled) { + if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED) return false; - } - + if (_hotspot.contains(backgroundImageSpacePos)) { - _engine->getCursorManager()->changeCursor(_hoverCursor); + _engine->getCursorManager()->changeCursor(_engine->getCursorManager()->getCursorId(_hoverCursor)); return true; } diff --git a/engines/zvision/scripting/controls/push_toggle_control.h b/engines/zvision/scripting/controls/push_toggle_control.h index 3854fc2005..6ba1bd77fa 100644 --- a/engines/zvision/scripting/controls/push_toggle_control.h +++ b/engines/zvision/scripting/controls/push_toggle_control.h @@ -26,6 +26,7 @@ #include "zvision/scripting/control.h" #include "common/rect.h" +#include "common/events.h" namespace ZVision { @@ -36,12 +37,19 @@ public: ~PushToggleControl(); /** + * Called when LeftMouse is pushed. Default is NOP. + * + * @param screenSpacePos The position of the mouse in screen space + * @param backgroundImageSpacePos The position of the mouse in background image space + */ + bool onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos); + /** * Called when LeftMouse is lifted. Calls ScriptManager::setStateValue(_key, 1); * * @param screenSpacePos The position of the mouse in screen space * @param backgroundImageSpacePos The position of the mouse in background image space */ - void onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos); + bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos); /** * Called on every MouseMove. Tests if the mouse is inside _hotspot, and if so, sets the cursor. * @@ -60,6 +68,10 @@ private: Common::Rect _hotspot; /** The cursor to use when hovering over _hotspot */ Common::String _hoverCursor; + /** Button maximal values count */ + uint _countTo; + + Common::EventType _event; }; } // End of namespace ZVision diff --git a/engines/zvision/scripting/controls/timer_node.cpp b/engines/zvision/scripting/controls/timer_node.cpp index c8c8a85d34..a94f6db19b 100644 --- a/engines/zvision/scripting/controls/timer_node.cpp +++ b/engines/zvision/scripting/controls/timer_node.cpp @@ -8,12 +8,12 @@ * 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. @@ -22,46 +22,53 @@ #include "common/scummsys.h" -#include "zvision/scripting/controls/timer_node.h" +#include "zvision/timer_node.h" #include "zvision/zvision.h" -#include "zvision/scripting/script_manager.h" +#include "zvision/script_manager.h" #include "common/stream.h" namespace ZVision { - + TimerNode::TimerNode(ZVision *engine, uint32 key, uint timeInSeconds) - : Control(engine, key) { - if (_engine->getGameId() == GID_NEMESIS) { + : SideFX(engine, key, SIDEFX_TIMER) { + if (_engine->getGameId() == GID_NEMESIS) _timeLeft = timeInSeconds * 1000; - } else if (_engine->getGameId() == GID_GRANDINQUISITOR) { + else if (_engine->getGameId() == GID_GRANDINQUISITOR) _timeLeft = timeInSeconds * 100; - } - _engine->getScriptManager()->setStateValue(_key, 1); + if (_key != StateKey_NotSet) + _engine->getScriptManager()->setStateValue(_key, 1); } TimerNode::~TimerNode() { - if (_timeLeft <= 0) + if (_key != StateKey_NotSet) _engine->getScriptManager()->setStateValue(_key, 2); - else - _engine->getScriptManager()->setStateValue(_key, _timeLeft); // If timer was stopped by stop or kill + int32 timeLeft = _timeLeft / (_engine->getGameId() == GID_NEMESIS ? 1000 : 100); + if (timeLeft > 0) + _engine->getScriptManager()->setStateValue(_key, timeLeft); // If timer was stopped by stop or kill } bool TimerNode::process(uint32 deltaTimeInMillis) { _timeLeft -= deltaTimeInMillis; - if (_timeLeft <= 0) { - // Let the destructor reset the state value - return true; - } + if (_timeLeft <= 0) + return stop(); return false; } +bool TimerNode::stop() { + if (_key != StateKey_NotSet) + _engine->getScriptManager()->setStateValue(_key, 2); + return true; +} + void TimerNode::serialize(Common::WriteStream *stream) { + stream->writeUint32BE(MKTAG('T', 'I', 'M', 'R')); + stream->writeUint32LE(8); // size stream->writeUint32LE(_key); stream->writeUint32LE(_timeLeft); } diff --git a/engines/zvision/scripting/controls/timer_node.h b/engines/zvision/scripting/controls/timer_node.h index 48b5fad1e9..f6584becda 100644 --- a/engines/zvision/scripting/controls/timer_node.h +++ b/engines/zvision/scripting/controls/timer_node.h @@ -8,12 +8,12 @@ * 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. @@ -23,13 +23,13 @@ #ifndef ZVISION_TIMER_NODE_H #define ZVISION_TIMER_NODE_H -#include "zvision/scripting/control.h" +#include "zvision/sidefx.h" namespace ZVision { class ZVision; -class TimerNode : public Control { +class TimerNode : public SideFX { public: TimerNode(ZVision *engine, uint32 key, uint timeInSeconds); ~TimerNode(); @@ -44,7 +44,11 @@ public: bool process(uint32 deltaTimeInMillis); void serialize(Common::WriteStream *stream); void deserialize(Common::SeekableReadStream *stream); - inline bool needsSerialization() { return true; } + inline bool needsSerialization() { + return true; + } + + bool stop(); private: int32 _timeLeft; |