aboutsummaryrefslogtreecommitdiff
path: root/engines/zvision/scripting/controls
diff options
context:
space:
mode:
Diffstat (limited to 'engines/zvision/scripting/controls')
-rw-r--r--engines/zvision/scripting/controls/animation_control.cpp263
-rw-r--r--engines/zvision/scripting/controls/fist_control.cpp319
-rw-r--r--engines/zvision/scripting/controls/fist_control.h86
-rw-r--r--engines/zvision/scripting/controls/hotmov_control.cpp200
-rw-r--r--engines/zvision/scripting/controls/hotmov_control.h62
-rw-r--r--engines/zvision/scripting/controls/input_control.cpp201
-rw-r--r--engines/zvision/scripting/controls/input_control.h35
-rw-r--r--engines/zvision/scripting/controls/lever_control.cpp197
-rw-r--r--engines/zvision/scripting/controls/lever_control.h20
-rw-r--r--engines/zvision/scripting/controls/paint_control.cpp214
-rw-r--r--engines/zvision/scripting/controls/paint_control.h91
-rw-r--r--engines/zvision/scripting/controls/push_toggle_control.cpp99
-rw-r--r--engines/zvision/scripting/controls/push_toggle_control.h22
-rw-r--r--engines/zvision/scripting/controls/safe_control.cpp204
-rw-r--r--engines/zvision/scripting/controls/safe_control.h (renamed from engines/zvision/scripting/controls/animation_control.h)75
-rw-r--r--engines/zvision/scripting/controls/save_control.cpp122
-rw-r--r--engines/zvision/scripting/controls/save_control.h (renamed from engines/zvision/scripting/controls/timer_node.h)38
-rw-r--r--engines/zvision/scripting/controls/slot_control.cpp218
-rw-r--r--engines/zvision/scripting/controls/slot_control.h84
-rw-r--r--engines/zvision/scripting/controls/timer_node.cpp73
-rw-r--r--engines/zvision/scripting/controls/titler_control.cpp107
-rw-r--r--engines/zvision/scripting/controls/titler_control.h54
22 files changed, 2192 insertions, 592 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/fist_control.cpp b/engines/zvision/scripting/controls/fist_control.cpp
new file mode 100644
index 0000000000..dd6a7f11a9
--- /dev/null
+++ b/engines/zvision/scripting/controls/fist_control.cpp
@@ -0,0 +1,319 @@
+/* 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/fist_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/meta_animation.h"
+#include "zvision/utility/utility.h"
+
+#include "common/stream.h"
+#include "common/file.h"
+#include "common/system.h"
+
+#include "graphics/surface.h"
+
+namespace ZVision {
+
+FistControl::FistControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key, CONTROL_FIST) {
+ _cursor = CursorIndex_Idle;
+ _animation = NULL;
+ _soundKey = 0;
+ _fiststatus = 0;
+ _order = 0;
+ _fistnum = 0;
+
+ _frameCur = -1;
+ _frameEnd = -1;
+ _frameTime = 0;
+ _lastRenderedFrame = -1;
+ _animationId = 0;
+
+ clearFistArray(_fistsUp);
+ clearFistArray(_fistsDwn);
+
+ _numEntries = 0;
+ _entries.clear();
+
+ _anmRect = Common::Rect();
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (param.matchString("sound_key", true)) {
+ _soundKey = atoi(values.c_str());
+ } else if (param.matchString("cursor", true)) {
+ _cursor = _engine->getCursorManager()->getCursorId(values);
+ } else if (param.matchString("descfile", true)) {
+ readDescFile(values);
+ } else if (param.matchString("animation_id", true)) {
+ _animationId = atoi(values.c_str());
+ } else if (param.matchString("venus_id", true)) {
+ _venusId = atoi(values.c_str());
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
+ }
+}
+
+FistControl::~FistControl() {
+ if (_animation)
+ delete _animation;
+
+ clearFistArray(_fistsUp);
+ clearFistArray(_fistsDwn);
+ _entries.clear();
+}
+
+void FistControl::renderFrame(uint frameNumber) {
+ if ((int32)frameNumber == _lastRenderedFrame)
+ return;
+
+ _lastRenderedFrame = frameNumber;
+
+ const Graphics::Surface *frameData;
+
+ if (_animation) {
+ frameData = _animation->getFrameData(frameNumber);
+ if (frameData)
+ _engine->getRenderManager()->blitSurfaceToBkgScaled(*frameData, _anmRect);
+ }
+}
+
+bool FistControl::process(uint32 deltaTimeInMillis) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_frameCur >= 0 && _frameEnd >= 0)
+ if (_frameCur <= _frameEnd) {
+ _frameTime -= deltaTimeInMillis;
+
+ if (_frameTime <= 0) {
+ _frameTime = _animation->frameTime();
+
+ renderFrame(_frameCur);
+
+ _frameCur++;
+
+ if (_frameCur > _frameEnd)
+ _engine->getScriptManager()->setStateValue(_animationId, 2);
+ }
+ }
+
+ return false;
+}
+
+bool FistControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (mouseIn(screenSpacePos, backgroundImageSpacePos) >= 0) {
+ _engine->getCursorManager()->changeCursor(_cursor);
+ return true;
+ }
+
+ return false;
+}
+
+bool FistControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ int fistNumber = mouseIn(screenSpacePos, backgroundImageSpacePos);
+
+ if (fistNumber >= 0) {
+ setVenus();
+
+ uint32 oldStatus = _fiststatus;
+ _fiststatus ^= (1 << fistNumber);
+
+ for (int i = 0; i < _numEntries; i++)
+ if (_entries[i]._bitsStrt == oldStatus && _entries[i]._bitsEnd == _fiststatus) {
+ _frameCur = _entries[i]._anmStrt;
+ _frameEnd = _entries[i]._anmEnd;
+ _frameTime = 0;
+
+ _engine->getScriptManager()->setStateValue(_animationId, 1);
+ _engine->getScriptManager()->setStateValue(_soundKey, _entries[i]._sound);
+ break;
+ }
+
+ _engine->getScriptManager()->setStateValue(_key, _fiststatus);
+ }
+
+ return false;
+}
+
+void FistControl::readDescFile(const Common::String &fileName) {
+ Common::File file;
+ if (!_engine->getSearchManager()->openFile(file, fileName)) {
+ warning("Desc file %s could could be opened", fileName.c_str());
+ return;
+ }
+
+ Common::String line;
+ Common::String param;
+ Common::String values;
+
+ while (!file.eos()) {
+ line = file.readLine();
+ getFistParams(line, param, values);
+
+ if (param.matchString("animation_id", true)) {
+ // Not used
+ } else if (param.matchString("animation", true)) {
+ _animation = new MetaAnimation(values, _engine);
+ } else if (param.matchString("anim_rect", true)) {
+ int left, top, right, bottom;
+ sscanf(values.c_str(), "%d %d %d %d", &left, &top, &right, &bottom);
+ _anmRect = Common::Rect(left, top, right, bottom);
+ } else if (param.matchString("num_fingers", true)) {
+ sscanf(values.c_str(), "%d", &_fistnum);
+ _fistsUp.resize(_fistnum);
+ _fistsDwn.resize(_fistnum);
+ } else if (param.matchString("entries", true)) {
+ sscanf(values.c_str(), "%d", &_numEntries);
+ _entries.resize(_numEntries);
+ } else if (param.matchString("eval_order_ascending", true)) {
+ sscanf(values.c_str(), "%d", &_order);
+ } else if (param.matchString("up_hs_num_*", true)) {
+ int fist, num;
+ num = atoi(values.c_str());
+
+ sscanf(param.c_str(), "up_hs_num_%d", &fist);
+ _fistsUp[fist].resize(num);
+ } else if (param.matchString("up_hs_*", true)) {
+ int16 fist, box, x1, y1, x2, y2;
+ sscanf(param.c_str(), "up_hs_%hd_%hd", &fist, &box);
+ sscanf(values.c_str(), "%hd %hd %hd %hd", &x1, &y1, &x2, &y2);
+ (_fistsUp[fist])[box] = Common::Rect(x1, y1, x2, y2);
+ } else if (param.matchString("down_hs_num_*", true)) {
+ int fist, num;
+ num = atoi(values.c_str());
+
+ sscanf(param.c_str(), "down_hs_num_%d", &fist);
+ _fistsDwn[fist].resize(num);
+ } else if (param.matchString("down_hs_*", true)) {
+ int16 fist, box, x1, y1, x2, y2;
+ sscanf(param.c_str(), "down_hs_%hd_%hd", &fist, &box);
+ sscanf(values.c_str(), "%hd %hd %hd %hd", &x1, &y1, &x2, &y2);
+ (_fistsDwn[fist])[box] = Common::Rect(x1, y1, x2, y2);
+ } else {
+ int entry, start, end, sound;
+ char bitsStart[33];
+ char bitsEnd[33];
+ entry = atoi(param.c_str());
+ if (sscanf(values.c_str(), "%s %s %d %d (%d)", bitsStart, bitsEnd, &start, &end, &sound) == 5) {
+ _entries[entry]._bitsStrt = readBits(bitsStart);
+ _entries[entry]._bitsEnd = readBits(bitsEnd);
+ _entries[entry]._anmStrt = start;
+ _entries[entry]._anmEnd = end;
+ _entries[entry]._sound = sound;
+ }
+ }
+ }
+ file.close();
+}
+
+void FistControl::clearFistArray(Common::Array< Common::Array<Common::Rect> > &arr) {
+ for (uint i = 0; i < arr.size(); i++)
+ arr[i].clear();
+
+ arr.clear();
+}
+
+uint32 FistControl::readBits(const char *str) {
+ uint32 bfield = 0;
+ int len = strlen(str);
+ for (int i = 0; i < len; i++)
+ if (str[i] != '0')
+ bfield |= (1 << i);
+ return bfield;
+}
+
+int FistControl::mouseIn(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_order) {
+ for (int i = 0; i < _fistnum; i++) {
+ if (((_fiststatus >> i) & 1) == 1) {
+ for (uint j = 0; j < _fistsDwn[i].size(); j++)
+ if ((_fistsDwn[i])[j].contains(backgroundImageSpacePos))
+ return i;
+ } else {
+ for (uint j = 0; j < _fistsUp[i].size(); j++)
+ if ((_fistsUp[i])[j].contains(backgroundImageSpacePos))
+ return i;
+ }
+ }
+ } else {
+ for (int i = _fistnum - 1; i >= 0; i--) {
+ if (((_fiststatus >> i) & 1) == 1) {
+ for (uint j = 0; j < _fistsDwn[i].size(); j++)
+ if ((_fistsDwn[i])[j].contains(backgroundImageSpacePos))
+ return i;
+ } else {
+ for (uint j = 0; j < _fistsUp[i].size(); j++)
+ if ((_fistsUp[i])[j].contains(backgroundImageSpacePos))
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+void FistControl::getFistParams(const Common::String &inputStr, Common::String &parameter, Common::String &values) {
+ const char *chrs = inputStr.c_str();
+ uint lbr;
+
+ for (lbr = 0; lbr < inputStr.size(); lbr++)
+ if (chrs[lbr] == ':')
+ break;
+
+ if (lbr >= inputStr.size())
+ return;
+
+ uint rbr;
+
+ for (rbr = lbr + 1; rbr < inputStr.size(); rbr++)
+ if (chrs[rbr] == '~')
+ break;
+
+ if (rbr >= inputStr.size())
+ return;
+
+ parameter = Common::String(chrs, chrs + lbr);
+ values = Common::String(chrs + lbr + 1, chrs + rbr);
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/fist_control.h b/engines/zvision/scripting/controls/fist_control.h
new file mode 100644
index 0000000000..cb765c429a
--- /dev/null
+++ b/engines/zvision/scripting/controls/fist_control.h
@@ -0,0 +1,86 @@
+/* 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_FIST_CONTROL_H
+#define ZVISION_FIST_CONTROL_H
+
+#include "zvision/scripting/control.h"
+
+#include "common/array.h"
+#include "common/rect.h"
+
+namespace ZVision {
+
+class MetaAnimation;
+
+class FistControl : public Control {
+public:
+ FistControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
+ ~FistControl();
+
+private:
+ uint32 _fiststatus;
+ int _fistnum;
+ int16 _cursor;
+ int _order;
+
+ Common::Array< Common::Array<Common::Rect> > _fistsUp;
+ Common::Array< Common::Array<Common::Rect> > _fistsDwn;
+
+ int32 _numEntries;
+
+ struct entries {
+ uint32 _bitsStrt;
+ uint32 _bitsEnd;
+ int32 _anmStrt;
+ int32 _anmEnd;
+ int32 _sound;
+ };
+
+ Common::Array<entries> _entries;
+
+ MetaAnimation *_animation;
+ Common::Rect _anmRect;
+ int32 _soundKey;
+ int32 _frameCur;
+ int32 _frameEnd;
+ int32 _frameTime;
+ int32 _lastRenderedFrame;
+ int32 _animationId;
+
+public:
+ bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ bool process(uint32 deltaTimeInMillis);
+
+private:
+ void renderFrame(uint frameNumber);
+ void readDescFile(const Common::String &fileName);
+ void clearFistArray(Common::Array< Common::Array<Common::Rect> > &arr);
+ uint32 readBits(const char *str);
+ int mouseIn(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ void getFistParams(const Common::String &inputStr, Common::String &parameter, Common::String &values);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/hotmov_control.cpp b/engines/zvision/scripting/controls/hotmov_control.cpp
new file mode 100644
index 0000000000..68861dc221
--- /dev/null
+++ b/engines/zvision/scripting/controls/hotmov_control.cpp
@@ -0,0 +1,200 @@
+/* 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/hotmov_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/meta_animation.h"
+#include "zvision/utility/utility.h"
+
+#include "common/stream.h"
+#include "common/file.h"
+#include "common/system.h"
+
+#include "graphics/surface.h"
+
+namespace ZVision {
+
+HotMovControl::HotMovControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key, CONTROL_HOTMOV) {
+ _animation = NULL;
+ _cycle = 0;
+ _curFrame = -1;
+ _lastRenderedFrame = -1;
+ _frames.clear();
+ _frameTime = 0;
+ _cyclesCount = 0;
+ _framesCount = 0;
+
+ _engine->getScriptManager()->setStateValue(_key, 0);
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (param.matchString("hs_frame_list", true)) {
+ readHsFile(values);
+ } else if (param.matchString("rectangle", true)) {
+ int x;
+ int y;
+ int width;
+ int height;
+
+ sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height);
+
+ _rectangle = Common::Rect(x, y, width, height);
+ } else if (param.matchString("num_frames", true)) {
+ _framesCount = atoi(values.c_str());
+ } else if (param.matchString("num_cycles", true)) {
+ _cyclesCount = atoi(values.c_str());
+ } else if (param.matchString("animation", true)) {
+ char filename[64];
+ sscanf(values.c_str(), "%s", filename);
+ values = Common::String(filename);
+ _animation = new MetaAnimation(values, _engine);
+ } else if (param.matchString("venus_id", true)) {
+ _venusId = atoi(values.c_str());
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
+ }
+}
+
+HotMovControl::~HotMovControl() {
+ if (_animation)
+ delete _animation;
+
+ _frames.clear();
+}
+
+void HotMovControl::renderFrame(uint frameNumber) {
+ if ((int)frameNumber == _lastRenderedFrame)
+ return;
+
+ _lastRenderedFrame = frameNumber;
+
+ const Graphics::Surface *frameData;
+
+ if (_animation) {
+ frameData = _animation->getFrameData(frameNumber);
+ if (frameData)
+ _engine->getRenderManager()->blitSurfaceToBkgScaled(*frameData, _rectangle);
+ }
+}
+
+bool HotMovControl::process(uint32 deltaTimeInMillis) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_cycle < _cyclesCount) {
+ _frameTime -= deltaTimeInMillis;
+
+ if (_frameTime <= 0) {
+ _curFrame++;
+ if (_curFrame >= _framesCount) {
+ _curFrame = 0;
+ _cycle++;
+ }
+ if (_cycle != _cyclesCount)
+ renderFrame(_curFrame);
+ else
+ _engine->getScriptManager()->setStateValue(_key, 2);
+
+ _frameTime = _animation->frameTime();
+ }
+ }
+
+ return false;
+}
+
+bool HotMovControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_cycle < _cyclesCount) {
+ if (_frames[_curFrame].contains(backgroundImageSpacePos)) {
+ _engine->getCursorManager()->changeCursor(CursorIndex_Active);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool HotMovControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_cycle < _cyclesCount) {
+ if (_frames[_curFrame].contains(backgroundImageSpacePos)) {
+ setVenus();
+ _engine->getScriptManager()->setStateValue(_key, 1);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void HotMovControl::readHsFile(const Common::String &fileName) {
+ if (_framesCount == 0)
+ return;
+
+ Common::File file;
+ if (!_engine->getSearchManager()->openFile(file, fileName)) {
+ warning("HS file %s could could be opened", fileName.c_str());
+ return;
+ }
+
+ Common::String line;
+
+ _frames.resize(_framesCount);
+
+ while (!file.eos()) {
+ line = file.readLine();
+
+ int frame;
+ int x;
+ int y;
+ int width;
+ int height;
+
+ sscanf(line.c_str(), "%d:%d %d %d %d~", &frame, &x, &y, &width, &height);
+
+ if (frame >= 0 && frame < _framesCount)
+ _frames[frame] = Common::Rect(x, y, width, height);
+ }
+ file.close();
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/hotmov_control.h b/engines/zvision/scripting/controls/hotmov_control.h
new file mode 100644
index 0000000000..86600d65dc
--- /dev/null
+++ b/engines/zvision/scripting/controls/hotmov_control.h
@@ -0,0 +1,62 @@
+/* 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_HOTMOV_CONTROL_H
+#define ZVISION_HOTMOV_CONTROL_H
+
+#include "zvision/scripting/control.h"
+
+#include "common/array.h"
+#include "common/rect.h"
+
+namespace ZVision {
+
+class MetaAnimation;
+
+class HotMovControl : public Control {
+public:
+ HotMovControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
+ ~HotMovControl();
+
+private:
+ int32 _framesCount;
+ int32 _frameTime;
+ int32 _curFrame;
+ int32 _lastRenderedFrame;
+ int32 _cycle;
+ int32 _cyclesCount;
+ MetaAnimation *_animation;
+ Common::Rect _rectangle;
+ Common::Array<Common::Rect> _frames;
+public:
+ bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ bool process(uint32 deltaTimeInMillis);
+
+private:
+ void renderFrame(uint frameNumber);
+ void readHsFile(const Common::String &fileName);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/input_control.cpp b/engines/zvision/scripting/controls/input_control.cpp
index a35548d02e..c541693ec3 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.
@@ -23,10 +23,11 @@
#include "common/scummsys.h"
#include "zvision/scripting/controls/input_control.h"
+#include "zvision/cursors/cursor_manager.h"
#include "zvision/zvision.h"
#include "zvision/scripting/script_manager.h"
-#include "zvision/strings/string_manager.h"
+#include "zvision/text/string_manager.h"
#include "zvision/graphics/render_manager.h"
#include "zvision/utility/utility.h"
@@ -34,109 +35,221 @@
#include "common/stream.h"
#include "common/rect.h"
-
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, CONTROL_INPUT),
+ _nextTabstop(0),
+ _focused(false),
+ _textChanged(false),
+ _cursorOffset(0),
+ _enterPressed(false),
+ _readOnly(false),
+ _txtWidth(0),
+ _animation(NULL) {
// Loop until we find the closing brace
Common::String line = stream.readLine();
trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
while (!stream.eos() && !line.contains('}')) {
- if (line.matchString("*rectangle*", true)) {
+ if (param.matchString("rectangle", true)) {
int x1;
int y1;
int x2;
int y2;
- sscanf(line.c_str(), "%*[^(](%d %d %d %d)", &x1, &y1, &x2, &y2);
+ sscanf(values.c_str(), "%d %d %d %d", &x1, &y1, &x2, &y2);
_textRectangle = Common::Rect(x1, y1, x2, y2);
- } else if (line.matchString("*aux_hotspot*", true)) {
+ } else if (param.matchString("aux_hotspot", true)) {
int x1;
int y1;
int x2;
int y2;
- sscanf(line.c_str(), "%*[^(](%d %d %d %d)", &x1, &y1, &x2, &y2);
+ sscanf(values.c_str(), "%d %d %d %d", &x1, &y1, &x2, &y2);
_headerRectangle = Common::Rect(x1, y1, x2, y2);
- } else if (line.matchString("*string_init*", true)) {
+ } else if (param.matchString("string_init", true)) {
uint fontFormatNumber;
- sscanf(line.c_str(), "%*[^(](%u)", &fontFormatNumber);
+ sscanf(values.c_str(), "%u", &fontFormatNumber);
- _textStyle = _engine->getStringManager()->getTextStyle(fontFormatNumber);
- } else if (line.matchString("*next_tabstop*", true)) {
- sscanf(line.c_str(), "%*[^(](%u)", &_nextTabstop);
- } else if (line.matchString("*cursor_animation*", true)) {
- char fileName[26];
+ _stringInit.readAllStyle(_engine->getStringManager()->getTextLine(fontFormatNumber));
+ } else if (param.matchString("chooser_init_string", true)) {
+ uint fontFormatNumber;
- sscanf(line.c_str(), "%*[^(](%25s %*u)", fileName);
+ sscanf(values.c_str(), "%u", &fontFormatNumber);
- _cursorAnimationFileName = Common::String(fileName);
- } else if (line.matchString("*cursor_dimensions*", true)) {
+ _stringChooserInit.readAllStyle(_engine->getStringManager()->getTextLine(fontFormatNumber));
+ } else if (param.matchString("next_tabstop", true)) {
+ sscanf(values.c_str(), "%u", &_nextTabstop);
+ } else if (param.matchString("cursor_dimensions", true)) {
// Ignore, use the dimensions in the animation file
- } else if (line.matchString("*cursor_animation_frames*", true)) {
+ } else if (param.matchString("cursor_animation_frames", true)) {
// Ignore, use the frame count in the animation file
- } else if (line.matchString("*focus*", true)) {
+ } else if (param.matchString("cursor_animation", true)) {
+ char fileName[25];
+
+ sscanf(values.c_str(), "%25s %*u", fileName);
+
+ _animation = new MetaAnimation(fileName, _engine);
+ _frame = -1;
+ _frameDelay = 0;
+ } else if (param.matchString("focus", true)) {
_focused = true;
+ _engine->getScriptManager()->setFocusControlKey(_key);
+ } else if (param.matchString("venus_id", true)) {
+ _venusId = atoi(values.c_str());
}
line = stream.readLine();
trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
+ }
+}
+
+bool InputControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_textRectangle.contains(backgroundImageSpacePos)) {
+ if (!_readOnly) {
+ // Save
+ _engine->getScriptManager()->focusControl(_key);
+ setVenus();
+ } else {
+ // Restore
+ if (_currentInputText.size()) {
+ setVenus();
+ _enterPressed = true;
+ }
+ }
}
+ return false;
}
-void InputControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
- _engine->getScriptManager()->focusControl(_key);
+bool InputControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_textRectangle.contains(backgroundImageSpacePos)) {
+ if (!_readOnly) {
+ // Save
+ _engine->getCursorManager()->changeCursor(CursorIndex_Active);
+ return true;
+ } else {
+ // Restore
+ if (_currentInputText.size()) {
+ _engine->getCursorManager()->changeCursor(CursorIndex_Active);
+ _engine->getScriptManager()->focusControl(_key);
+ return true;
+ }
+ }
+ }
+ return false;
}
-void InputControl::onKeyDown(Common::KeyState keyState) {
+bool InputControl::onKeyDown(Common::KeyState keyState) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
if (!_focused) {
- return;
+ return false;
}
if (keyState.keycode == Common::KEYCODE_BACKSPACE) {
- _currentInputText.deleteLastChar();
+ if (!_readOnly) {
+ _currentInputText.deleteLastChar();
+ _textChanged = true;
+ }
+ } else if (keyState.keycode == Common::KEYCODE_RETURN) {
+ _enterPressed = true;
} else if (keyState.keycode == Common::KEYCODE_TAB) {
- _focused = false;
+ unfocus();
// Focus the next input control
_engine->getScriptManager()->focusControl(_nextTabstop);
+ // Don't process this event for other controls
+ return true;
} else {
- // Otherwise, append the new character to the end of the current text
-
- uint16 asciiValue = keyState.ascii;
- // We only care about text values
- if (asciiValue >= 32 && asciiValue <= 126) {
- _currentInputText += (char)asciiValue;
- _textChanged = true;
+ if (!_readOnly) {
+ // Otherwise, append the new character to the end of the current text
+ uint16 asciiValue = keyState.ascii;
+ // We only care about text values
+ if (asciiValue >= 32 && asciiValue <= 126) {
+ _currentInputText += (char)asciiValue;
+ _textChanged = true;
+ }
}
}
+ return false;
}
bool InputControl::process(uint32 deltaTimeInMillis) {
- if (!_focused) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
return false;
- }
// 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());
- _cursorOffset = destRect.left - _textRectangle.left;
+ Graphics::Surface txt;
+ txt.create(_textRectangle.width(), _textRectangle.height(), _engine->_pixelFormat);
+
+ if (!_readOnly || !_focused)
+ _txtWidth = _engine->getTextRenderer()->drawTxt(_currentInputText, _stringInit, txt);
+ else
+ _txtWidth = _engine->getTextRenderer()->drawTxt(_currentInputText, _stringChooserInit, txt);
+
+ _engine->getRenderManager()->blitSurfaceToBkg(txt, _textRectangle.left, _textRectangle.top);
+
+ txt.free();
}
- // Render the next frame of the animation
- // TODO: Implement animation handling
+ if (_animation && !_readOnly && _focused) {
+ bool needDraw = true;// = _textChanged;
+ _frameDelay -= deltaTimeInMillis;
+ if (_frameDelay <= 0) {
+ _frame = (_frame + 1) % _animation->frameCount();
+ _frameDelay = _animation->frameTime();
+ needDraw = true;
+ }
+ if (needDraw) {
+ const Graphics::Surface *srf = _animation->getFrameData(_frame);
+ uint32 xx = _textRectangle.left + _txtWidth;
+ if (xx >= _textRectangle.left + (_textRectangle.width() - _animation->width()))
+ xx = _textRectangle.left + _textRectangle.width() - _animation->width();
+ _engine->getRenderManager()->blitSurfaceToBkg(*srf, xx, _textRectangle.top);
+ }
+ }
+
+ _textChanged = false;
+ return false;
+}
+
+bool InputControl::enterPress() {
+ if (_enterPressed) {
+ _enterPressed = false;
+ return true;
+ }
return false;
}
+void InputControl::setText(const Common::String &_str) {
+ _currentInputText = _str;
+ _textChanged = true;
+}
+
+const Common::String InputControl::getText() {
+ return _currentInputText;
+}
+
+void InputControl::setReadOnly(bool readonly) {
+ _readOnly = readonly;
+}
+
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/input_control.h b/engines/zvision/scripting/controls/input_control.h
index 32432438bb..410caf6d49 100644
--- a/engines/zvision/scripting/controls/input_control.h
+++ b/engines/zvision/scripting/controls/input_control.h
@@ -24,11 +24,12 @@
#define ZVISION_INPUT_CONTROL_H
#include "zvision/scripting/control.h"
-#include "zvision/strings/string_manager.h"
+#include "zvision/animation/meta_animation.h"
+#include "zvision/text/text.h"
+#include "zvision/text/string_manager.h"
#include "common/rect.h"
-
namespace ZVision {
class InputControl : public Control {
@@ -38,21 +39,39 @@ public:
private:
Common::Rect _textRectangle;
Common::Rect _headerRectangle;
- StringManager::TextStyle _textStyle;
+ cTxtStyle _stringInit;
+ cTxtStyle _stringChooserInit;
uint32 _nextTabstop;
- Common::String _cursorAnimationFileName;
bool _focused;
Common::String _currentInputText;
bool _textChanged;
uint _cursorOffset;
+ bool _enterPressed;
+ bool _readOnly;
+
+ int16 _txtWidth;
+ MetaAnimation *_animation;
+ int32 _frameDelay;
+ int16 _frame;
public:
- void focus() { _focused = true; }
- void unfocus() { _focused = false; }
- void onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
- void onKeyDown(Common::KeyState keyState);
+ void focus() {
+ _focused = true;
+ _textChanged = true;
+ }
+ void unfocus() {
+ _focused = false;
+ _textChanged = true;
+ }
+ bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ bool onKeyDown(Common::KeyState keyState);
bool process(uint32 deltaTimeInMillis);
+ void setText(const Common::String &_str);
+ const Common::String getText();
+ bool enterPress();
+ void setReadOnly(bool);
};
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/lever_control.cpp b/engines/zvision/scripting/controls/lever_control.cpp
index c029a2a7a1..12b07d7584 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.
@@ -28,8 +28,7 @@
#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/animation/meta_animation.h"
#include "zvision/utility/utility.h"
#include "common/stream.h"
@@ -39,118 +38,116 @@
#include "graphics/surface.h"
-
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, CONTROL_LEVER),
+ _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();
trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
+
while (!stream.eos() && !line.contains('}')) {
- if (line.matchString("*descfile*", true)) {
+ if (param.matchString("descfile", true)) {
char levFileName[25];
- sscanf(line.c_str(), "%*[^(](%25[^)])", levFileName);
+ sscanf(values.c_str(), "%25s", levFileName);
parseLevFile(levFileName);
- } else if (line.matchString("*cursor*", true)) {
+ } else if (param.matchString("cursor", true)) {
char cursorName[25];
- sscanf(line.c_str(), "%*[^(](%25[^)])", cursorName);
+ sscanf(values.c_str(), "%25s", cursorName);
- _cursorName = Common::String(cursorName);
+ _cursor = _engine->getCursorManager()->getCursorId(Common::String(cursorName));
}
line = stream.readLine();
trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
}
renderFrame(_currentFrame);
}
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;
+ Common::String param;
+ Common::String values;
while (!file.eos()) {
- if (line.matchString("*animation_id*", true)) {
+ line = file.readLine();
+ getLevParams(line, param, values);
+
+ if (param.matchString("animation_id", true)) {
// Not used
- } else if (line.matchString("*filename*", true)) {
- char fileNameBuffer[25];
- sscanf(line.c_str(), "%*[^:]:%25[^~]~", fileNameBuffer);
-
- 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;
- }
- } else if (line.matchString("*skipcolor*", true)) {
+ } else if (param.matchString("filename", true)) {
+ _animation = new MetaAnimation(values, _engine);
+ } else if (param.matchString("skipcolor", true)) {
// Not used
- } else if (line.matchString("*anim_coords*", true)) {
+ } else if (param.matchString("anim_coords", true)) {
int left, top, right, bottom;
- sscanf(line.c_str(), "%*[^:]:%d %d %d %d~", &left, &top, &right, &bottom);
+ sscanf(values.c_str(), "%d %d %d %d", &left, &top, &right, &bottom);
_animationCoords.left = left;
_animationCoords.top = top;
_animationCoords.right = right;
_animationCoords.bottom = bottom;
- } else if (line.matchString("*mirrored*", true)) {
+ } else if (param.matchString("mirrored", true)) {
uint mirrored;
- sscanf(line.c_str(), "%*[^:]:%u~", &mirrored);
+ sscanf(values.c_str(), "%u", &mirrored);
_mirrored = mirrored == 0 ? false : true;
- } else if (line.matchString("*frames*", true)) {
- sscanf(line.c_str(), "%*[^:]:%u~", &_frameCount);
+ } else if (param.matchString("frames", true)) {
+ sscanf(values.c_str(), "%u", &_frameCount);
_frameInfo = new FrameInfo[_frameCount];
- } else if (line.matchString("*elsewhere*", true)) {
+ } else if (param.matchString("elsewhere", true)) {
// Not used
- } else if (line.matchString("*out_of_control*", true)) {
+ } else if (param.matchString("out_of_control", true)) {
// Not used
- } else if (line.matchString("*start_pos*", true)) {
- sscanf(line.c_str(), "%*[^:]:%u~", &_startFrame);
+ } else if (param.matchString("start_pos", true)) {
+ sscanf(values.c_str(), "%u", &_startFrame);
_currentFrame = _startFrame;
- } else if (line.matchString("*hotspot_deltas*", true)) {
+ } else if (param.matchString("hotspot_deltas", true)) {
uint x;
uint y;
- sscanf(line.c_str(), "%*[^:]:%u %u~", &x, &y);
+ sscanf(values.c_str(), "%u %u", &x, &y);
_hotspotDelta.x = x;
_hotspotDelta.y = y;
+ } else if (param.matchString("venus_id", true)) {
+ _venusId = atoi(values.c_str());
} else {
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 +155,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 +169,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,25 +183,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)) {
+ setVenus();
_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;
@@ -214,12 +211,12 @@ 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;
@@ -240,7 +237,7 @@ bool LeverControl::onMouseMove(const Common::Point &screenSpacePos, const Common
}
}
} else if (_frameInfo[_currentFrame].hotspot.contains(backgroundImageSpacePos)) {
- _engine->getCursorManager()->changeCursor(_cursorName);
+ _engine->getCursorManager()->changeCursor(_cursor);
cursorWasChanged = true;
}
@@ -248,9 +245,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;
@@ -301,7 +297,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 +346,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 +373,35 @@ void LeverControl::renderFrame(uint frameNumber) {
_lastRenderedFrame = frameNumber;
}
- const uint16 *frameData = 0;
- 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;
- }
+ const Graphics::Surface *frameData;
+
+ frameData = _animation->getFrameData(frameNumber);
+ if (frameData)
+ _engine->getRenderManager()->blitSurfaceToBkgScaled(*frameData, _animationCoords);
+}
+
+void LeverControl::getLevParams(const Common::String &inputStr, Common::String &parameter, Common::String &values) {
+ const char *chrs = inputStr.c_str();
+ uint lbr;
+
+ for (lbr = 0; lbr < inputStr.size(); lbr++)
+ if (chrs[lbr] == ':')
+ break;
+
+ if (lbr >= inputStr.size())
+ return;
+
+ uint rbr;
+
+ for (rbr = lbr + 1; rbr < inputStr.size(); rbr++)
+ if (chrs[rbr] == '~')
+ break;
+
+ if (rbr >= inputStr.size())
+ return;
- _engine->getRenderManager()->copyRectToWorkingWindow(frameData, x, y, width, width, height);
+ parameter = Common::String(chrs, chrs + lbr);
+ values = Common::String(chrs + lbr + 1, chrs + rbr);
}
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/lever_control.h b/engines/zvision/scripting/controls/lever_control.h
index 49e4fd3806..37d4d3bd8d 100644
--- a/engines/zvision/scripting/controls/lever_control.h
+++ b/engines/zvision/scripting/controls/lever_control.h
@@ -28,11 +28,10 @@
#include "common/list.h"
#include "common/rect.h"
-
namespace ZVision {
class ZorkAVIDecoder;
-class RlfAnimation;
+class MetaAnimation;
class LeverControl : public Control {
public:
@@ -40,10 +39,6 @@ public:
~LeverControl();
private:
- enum FileType {
- RLF = 1,
- AVI = 2
- };
struct Direction {
Direction(uint a, uint t) : angle(a), toFrame(t) {}
@@ -64,13 +59,9 @@ private:
};
private:
- union {
- RlfAnimation *rlf;
- ZorkAVIDecoder *avi;
- } _animation;
- FileType _fileType;
+ MetaAnimation *_animation;
- Common::String _cursorName;
+ int _cursor;
Common::Rect _animationCoords;
bool _mirrored;
uint _frameCount;
@@ -88,8 +79,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);
@@ -120,6 +111,7 @@ private:
*/
static int calculateVectorAngle(const Common::Point &pointOne, const Common::Point &pointTwo);
void renderFrame(uint frameNumber);
+ void getLevParams(const Common::String &inputStr, Common::String &parameter, Common::String &values);
};
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/paint_control.cpp b/engines/zvision/scripting/controls/paint_control.cpp
new file mode 100644
index 0000000000..9bad6f2c58
--- /dev/null
+++ b/engines/zvision/scripting/controls/paint_control.cpp
@@ -0,0 +1,214 @@
+/* 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/paint_control.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/cursors/cursor_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/utility/utility.h"
+
+namespace ZVision {
+
+PaintControl::PaintControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key, CONTROL_PAINT) {
+
+ _cursor = CursorIndex_Active;
+ _paint = NULL;
+ _bkg = NULL;
+ _brush = NULL;
+ _colorKey = 0;
+ _mouseDown = false;
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (param.matchString("rectangle", true)) {
+ int x;
+ int y;
+ int width;
+ int height;
+
+ sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height);
+
+ _rectangle = Common::Rect(x, y, width + x, height + y);
+ } else if (param.matchString("cursor", true)) {
+ _cursor = _engine->getCursorManager()->getCursorId(values);
+ } else if (param.matchString("brush_file", true)) {
+ _brush = _engine->getRenderManager()->loadImage(values, false);
+ } else if (param.matchString("venus_id", true)) {
+ _venusId = atoi(values.c_str());
+ } else if (param.matchString("paint_file", true)) {
+ _paint = _engine->getRenderManager()->loadImage(values, false);
+ } else if (param.matchString("eligible_objects", true)) {
+ char buf[256];
+ memset(buf, 0, 256);
+ strcpy(buf, values.c_str());
+
+ char *curpos = buf;
+ char *strend = buf + strlen(buf);
+ while (true) {
+ char *st = curpos;
+
+ if (st >= strend)
+ break;
+
+ while (*curpos != ' ' && curpos < strend)
+ curpos++;
+
+ *curpos = 0;
+ curpos++;
+
+ int obj = atoi(st);
+
+ _eligibleObjects.push_back(obj);
+ }
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
+ }
+
+ if (_paint) {
+ _colorKey = _paint->format.RGBToColor(255, 0, 255);
+ _bkg = new Graphics::Surface;
+ _bkg->create(_rectangle.width(), _rectangle.height(), _paint->format);
+ _bkg->fillRect(Common::Rect(_rectangle.width(), _rectangle.height()), _colorKey);
+
+ Graphics::Surface *tmp = new Graphics::Surface;
+ tmp->create(_rectangle.width(), _rectangle.height(), _paint->format);
+ _engine->getRenderManager()->blitSurfaceToSurface(*_paint, _rectangle, *tmp, 0, 0);
+ _paint->free();
+ delete _paint;
+ _paint = tmp;
+ }
+}
+
+PaintControl::~PaintControl() {
+ // Clear the state value back to 0
+ //_engine->getScriptManager()->setStateValue(_key, 0);
+ if (_paint)
+ delete _paint;
+ if (_brush)
+ delete _brush;
+ if (_bkg)
+ delete _bkg;
+}
+
+bool PaintControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ _mouseDown = false;
+
+ return false;
+}
+
+bool PaintControl::onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_rectangle.contains(backgroundImageSpacePos)) {
+ int mouseItem = _engine->getScriptManager()->getStateValue(StateKey_InventoryItem);
+
+ if (eligeblity(mouseItem)) {
+ setVenus();
+ _mouseDown = true;
+ }
+ }
+
+ return false;
+}
+
+bool PaintControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_rectangle.contains(backgroundImageSpacePos)) {
+ int mouseItem = _engine->getScriptManager()->getStateValue(StateKey_InventoryItem);
+
+ if (eligeblity(mouseItem)) {
+ _engine->getCursorManager()->changeCursor(_cursor);
+
+ if (_mouseDown) {
+ Common::Rect bkgRect = paint(backgroundImageSpacePos);
+ if (!bkgRect.isEmpty()) {
+ Common::Rect imgRect = bkgRect;
+ imgRect.translate(-_rectangle.left, -_rectangle.top);
+
+ Graphics::Surface imgUpdate = _bkg->getSubArea(imgRect);
+
+ _engine->getRenderManager()->blitSurfaceToBkg(imgUpdate, bkgRect.left, bkgRect.top, _colorKey);
+ }
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool PaintControl::eligeblity(int itemId) {
+ for (Common::List<int>::iterator it = _eligibleObjects.begin(); it != _eligibleObjects.end(); it++)
+ if (*it == itemId)
+ return true;
+ return false;
+}
+
+Common::Rect PaintControl::paint(const Common::Point &point) {
+ Common::Rect paintRect = Common::Rect(_brush->w, _brush->h);
+ paintRect.moveTo(point);
+ paintRect.clip(_rectangle);
+
+ if (!paintRect.isEmpty()) {
+ Common::Rect brushRect = paintRect;
+ brushRect.translate(-point.x, -point.y);
+
+ Common::Rect bkgRect = paintRect;
+ bkgRect.translate(-_rectangle.left, -_rectangle.top);
+
+ for (int yy = 0; yy < brushRect.height(); yy++) {
+ uint16 *mask = (uint16 *)_brush->getBasePtr(brushRect.left, brushRect.top + yy);
+ uint16 *from = (uint16 *)_paint->getBasePtr(bkgRect.left, bkgRect.top + yy);
+ uint16 *to = (uint16 *)_bkg->getBasePtr(bkgRect.left, bkgRect.top + yy);
+ for (int xx = 0; xx < brushRect.width(); xx++) {
+ if (*mask != 0)
+ *(to + xx) = *(from + xx);
+
+ mask++;
+ }
+ }
+
+ }
+ return paintRect;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/paint_control.h b/engines/zvision/scripting/controls/paint_control.h
new file mode 100644
index 0000000000..8097290ac2
--- /dev/null
+++ b/engines/zvision/scripting/controls/paint_control.h
@@ -0,0 +1,91 @@
+/* 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_PAINT_CONTROL_H
+#define ZVISION_PAINT_CONTROL_H
+
+#include "zvision/scripting/control.h"
+
+#include "graphics/surface.h"
+
+#include "common/rect.h"
+#include "common/list.h"
+
+namespace ZVision {
+
+class PaintControl : public Control {
+public:
+ PaintControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
+ ~PaintControl();
+
+ /**
+ * @param screenSpacePos The position of the mouse in screen space
+ * @param backgroundImageSpacePos The position of the mouse in background image space
+ */
+ bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+
+ /**
+ * @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 on every MouseMove. Tests if the mouse is inside _hotspot, and if so, sets the cursor.
+ *
+ * @param engine The base engine
+ * @param screenSpacePos The position of the mouse in screen space
+ * @param backgroundImageSpacePos The position of the mouse in background image space
+ * @return Was the cursor changed?
+ */
+ bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+
+ bool process(uint32 deltaTimeInMillis) {
+ return false;
+ };
+
+private:
+ /**
+ * The area that will trigger the event
+ * This is in image space coordinates, NOT screen space
+ */
+
+ uint32 _colorKey;
+
+ Graphics::Surface *_paint;
+ Graphics::Surface *_bkg;
+ Graphics::Surface *_brush;
+
+ Common::List<int> _eligibleObjects;
+
+ int _cursor;
+ Common::Rect _rectangle;
+
+ bool _mouseDown;
+
+ bool eligeblity(int itemId);
+ Common::Rect paint(const Common::Point &point);
+
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/push_toggle_control.cpp b/engines/zvision/scripting/controls/push_toggle_control.cpp
index a96c95b377..c5ec070899 100644
--- a/engines/zvision/scripting/controls/push_toggle_control.cpp
+++ b/engines/zvision/scripting/controls/push_toggle_control.cpp
@@ -31,68 +31,117 @@
#include "common/stream.h"
-
namespace ZVision {
PushToggleControl::PushToggleControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
- : Control(engine, key) {
+ : Control(engine, key, CONTROL_PUSHTGL),
+ _countTo(2),
+ _event(Common::EVENT_LBUTTONUP) {
+
+ _hotspots.clear();
+
// Loop until we find the closing brace
Common::String line = stream.readLine();
trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
while (!stream.eos() && !line.contains('}')) {
- if (line.matchString("*_hotspot*", true)) {
+ if (param.matchString("*_hotspot", true)) {
uint x;
uint y;
uint width;
uint height;
- sscanf(line.c_str(), "%*[^(](%u,%u,%u,%u)", &x, &y, &width, &height);
-
- _hotspot = Common::Rect(x, y, x + width, y + height);
- } else if (line.matchString("cursor*", true)) {
- char nameBuffer[25];
-
- sscanf(line.c_str(), "%*[^(](%25[^)])", nameBuffer);
-
- _hoverCursor = Common::String(nameBuffer);
+ sscanf(values.c_str(), "%u,%u,%u,%u", &x, &y, &width, &height);
+
+ _hotspots.push_back(Common::Rect(x, y, x + width + 1, y + height + 1));
+ } else if (param.matchString("cursor", true)) {
+ _cursor = _engine->getCursorManager()->getCursorId(values);
+ } else if (param.matchString("animation", true)) {
+ // Not used
+ } else if (param.matchString("sound", true)) {
+ // Not used
+ } else if (param.matchString("count_to", true)) {
+ sscanf(values.c_str(), "%u", &_countTo);
+ } else if (param.matchString("mouse_event", true)) {
+ if (values.equalsIgnoreCase("up")) {
+ _event = Common::EVENT_LBUTTONUP;
+ } else if (values.equalsIgnoreCase("down")) {
+ _event = Common::EVENT_LBUTTONDOWN;
+ } else if (values.equalsIgnoreCase("double")) {
+ // Not used
+ }
+ } else if (param.matchString("venus_id", true)) {
+ _venusId = atoi(values.c_str());
}
line = stream.readLine();
trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
}
- if (_hotspot.isEmpty() || _hoverCursor.empty()) {
- warning("Push_toggle cursor %u was parsed incorrectly", key);
+ if (_hotspots.size() == 0) {
+ warning("Push_toggle %u was parsed incorrectly", key);
}
}
PushToggleControl::~PushToggleControl() {
- // Clear the state value back to 0
- _engine->getScriptManager()->setStateValue(_key, 0);
+ _hotspots.clear();
}
-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 (contain(backgroundImageSpacePos)) {
+ setVenus();
+ 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 (_hotspot.contains(backgroundImageSpacePos)) {
- _engine->getScriptManager()->setStateValue(_key, 1);
+ if (_event != Common::EVENT_LBUTTONDOWN)
+ return false;
+
+ if (contain(backgroundImageSpacePos)) {
+ setVenus();
+ 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);
+ if (contain(backgroundImageSpacePos)) {
+ _engine->getCursorManager()->changeCursor(_cursor);
return true;
}
return false;
}
+bool PushToggleControl::contain(const Common::Point &point) {
+ for (uint i = 0; i < _hotspots.size(); i++)
+ if (_hotspots[i].contains(point))
+ return true;
+ return false;
+}
+
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/push_toggle_control.h b/engines/zvision/scripting/controls/push_toggle_control.h
index 3854fc2005..9444c77cb6 100644
--- a/engines/zvision/scripting/controls/push_toggle_control.h
+++ b/engines/zvision/scripting/controls/push_toggle_control.h
@@ -26,7 +26,8 @@
#include "zvision/scripting/control.h"
#include "common/rect.h"
-
+#include "common/events.h"
+#include "common/array.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.
*
@@ -57,9 +65,15 @@ private:
* The area that will trigger the event
* This is in image space coordinates, NOT screen space
*/
- Common::Rect _hotspot;
+ Common::Array<Common::Rect> _hotspots;
/** The cursor to use when hovering over _hotspot */
- Common::String _hoverCursor;
+ int _cursor;
+ /** Button maximal values count */
+ uint _countTo;
+
+ Common::EventType _event;
+
+ bool contain(const Common::Point &point);
};
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/safe_control.cpp b/engines/zvision/scripting/controls/safe_control.cpp
new file mode 100644
index 0000000000..3ad5d3a8ae
--- /dev/null
+++ b/engines/zvision/scripting/controls/safe_control.cpp
@@ -0,0 +1,204 @@
+/* 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/safe_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/meta_animation.h"
+#include "zvision/utility/utility.h"
+
+#include "common/stream.h"
+#include "common/file.h"
+#include "common/tokenizer.h"
+#include "common/system.h"
+
+#include "graphics/surface.h"
+
+namespace ZVision {
+
+SafeControl::SafeControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key, CONTROL_SAFE) {
+ _statesCount = 0;
+ _curState = 0;
+ _animation = NULL;
+ _innerRaduis = 0;
+ _innerRadiusSqr = 0;
+ _outerRadius = 0;
+ _outerRadiusSqr = 0;
+ _zeroPointer = 0;
+ _startPointer = 0;
+ _curFrame = -1;
+ _targetFrame = 0;
+ _frameTime = 0;
+ _lastRenderedFrame = -1;
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (param.matchString("animation", true)) {
+ _animation = new MetaAnimation(values, _engine);
+ } else if (param.matchString("rectangle", true)) {
+ int x;
+ int y;
+ int width;
+ int height;
+
+ sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height);
+
+ _rectangle = Common::Rect(x, y, width, height);
+ } else if (param.matchString("num_states", true)) {
+ _statesCount = atoi(values.c_str());
+ } else if (param.matchString("center", true)) {
+ int x;
+ int y;
+
+ sscanf(values.c_str(), "%d %d", &x, &y);
+ _center = Common::Point(x, y);
+ } else if (param.matchString("dial_inner_radius", true)) {
+ _innerRaduis = atoi(values.c_str());
+ _innerRadiusSqr = _innerRaduis * _innerRaduis;
+ } else if (param.matchString("radius", true)) {
+ _outerRadius = atoi(values.c_str());
+ _outerRadiusSqr = _outerRadius * _outerRadius;
+ } else if (param.matchString("zero_radians_offset", true)) {
+ _zeroPointer = atoi(values.c_str());
+ } else if (param.matchString("pointer_offset", true)) {
+ _startPointer = atoi(values.c_str());
+ _curState = _startPointer;
+ } else if (param.matchString("cursor", true)) {
+ // Not used
+ } else if (param.matchString("mirrored", true)) {
+ // Not used
+ } else if (param.matchString("venus_id", true)) {
+ _venusId = atoi(values.c_str());
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
+ }
+ renderFrame(_curState);
+}
+
+SafeControl::~SafeControl() {
+ if (_animation)
+ delete _animation;
+
+}
+
+void SafeControl::renderFrame(uint frameNumber) {
+ if (frameNumber == 0) {
+ _lastRenderedFrame = frameNumber;
+ } else if ((int16)frameNumber < _lastRenderedFrame) {
+ _lastRenderedFrame = frameNumber;
+ frameNumber = (_statesCount * 2) - frameNumber;
+ } else {
+ _lastRenderedFrame = frameNumber;
+ }
+
+ const Graphics::Surface *frameData;
+ int x = _rectangle.left;
+ int y = _rectangle.top;
+
+ frameData = _animation->getFrameData(frameNumber);
+ if (frameData)
+ _engine->getRenderManager()->blitSurfaceToBkg(*frameData, x, y);
+}
+
+bool SafeControl::process(uint32 deltaTimeInMillis) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_curFrame != _targetFrame) {
+ _frameTime -= deltaTimeInMillis;
+
+ if (_frameTime <= 0) {
+ if (_curFrame < _targetFrame) {
+ _curFrame++;
+ renderFrame(_curFrame);
+ } else if (_curFrame > _targetFrame) {
+ _curFrame--;
+ renderFrame(_curFrame);
+ }
+ _frameTime = _animation->frameTime();
+ }
+ }
+ return false;
+}
+
+bool SafeControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_rectangle.contains(backgroundImageSpacePos)) {
+ int32 mR = backgroundImageSpacePos.sqrDist(_center);
+ if (mR <= _outerRadiusSqr && mR >= _innerRadiusSqr) {
+ _engine->getCursorManager()->changeCursor(CursorIndex_Active);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool SafeControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_rectangle.contains(backgroundImageSpacePos)) {
+ int32 mR = backgroundImageSpacePos.sqrDist(_center);
+ if (mR <= _outerRadiusSqr && mR >= _innerRadiusSqr) {
+ setVenus();
+
+ Common::Point tmp = backgroundImageSpacePos - _center;
+
+ float dd = atan2((float)tmp.x, (float)tmp.y) * 57.29578;
+
+ int16 dp_state = 360 / _statesCount;
+
+ int16 m_state = (_statesCount - ((((int16)dd + 540) % 360) / dp_state)) % _statesCount;
+
+ int16 tmp2 = (m_state + _curState - _zeroPointer + _statesCount - 1) % _statesCount;
+
+ _curFrame = (_curState + _statesCount - _startPointer) % _statesCount;
+
+ _curState = (_statesCount * 2 + tmp2) % _statesCount;
+
+ _targetFrame = (_curState + _statesCount - _startPointer) % _statesCount;
+
+ _engine->getScriptManager()->setStateValue(_key, _curState);
+ return true;
+ }
+ }
+ return false;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/animation_control.h b/engines/zvision/scripting/controls/safe_control.h
index bdb07d39ea..e32ca97b70 100644
--- a/engines/zvision/scripting/controls/animation_control.h
+++ b/engines/zvision/scripting/controls/safe_control.h
@@ -20,66 +20,49 @@
*
*/
-#ifndef ZVISION_ANIMATION_CONTROL_H
-#define ZVISION_ANIMATION_CONTROL_H
+#ifndef ZVISION_SAFE_CONTROL_H
+#define ZVISION_SAFE_CONTROL_H
#include "zvision/scripting/control.h"
-
-namespace Common {
-class String;
-}
-
-namespace Video {
-class VideoDecoder;
-}
-
-namespace Graphics {
-struct Surface;
-}
+#include "common/list.h"
+#include "common/rect.h"
namespace ZVision {
-class ZVision;
-class RlfAnimation;
+class ZorkAVIDecoder;
+class MetaAnimation;
-class AnimationControl : public Control {
+class SafeControl : public Control {
public:
- AnimationControl(ZVision *engine, uint32 controlKey, const Common::String &fileName);
- ~AnimationControl();
-
-private:
- enum FileType {
- RLF = 1,
- AVI = 2
- };
+ SafeControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
+ ~SafeControl();
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;
+ int16 _statesCount;
+ int16 _curState;
+ MetaAnimation *_animation;
+ Common::Point _center;
+ Common::Rect _rectangle;
+ int16 _innerRaduis;
+ int32 _innerRadiusSqr;
+ int16 _outerRadius;
+ int32 _outerRadiusSqr;
+ int16 _zeroPointer;
+ int16 _startPointer;
+ int16 _curFrame;
+ int16 _targetFrame;
+ int32 _frameTime;
+
+ int16 _lastRenderedFrame;
public:
+ bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+ bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
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; }
+private:
+ void renderFrame(uint frameNumber);
};
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/save_control.cpp b/engines/zvision/scripting/controls/save_control.cpp
new file mode 100644
index 0000000000..ad01257e6b
--- /dev/null
+++ b/engines/zvision/scripting/controls/save_control.cpp
@@ -0,0 +1,122 @@
+/* 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/input_control.h"
+#include "zvision/scripting/controls/save_control.h"
+#include "zvision/utility/utility.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/text/string_manager.h"
+
+#include "zvision/core/save_manager.h"
+
+#include "common/str.h"
+#include "common/stream.h"
+
+namespace ZVision {
+
+SaveControl::SaveControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key, CONTROL_SAVE),
+ _saveControl(false) {
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (param.matchString("savebox", true)) {
+ int saveId;
+ int inputId;
+
+ sscanf(values.c_str(), "%d %d", &saveId, &inputId);
+ saveElement elmnt;
+ elmnt.inputKey = inputId;
+ elmnt.saveId = saveId;
+ elmnt.exist = false;
+ _inputs.push_back(elmnt);
+ } else if (param.matchString("control_type", true)) {
+ if (values.contains("save"))
+ _saveControl = true;
+ else
+ _saveControl = false;
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
+ }
+
+ for (saveElmntList::iterator iter = _inputs.begin(); iter != _inputs.end(); ++iter) {
+ Control *ctrl = _engine->getScriptManager()->getControl(iter->inputKey);
+ if (ctrl && ctrl->getType() == Control::CONTROL_INPUT) {
+ InputControl *inp = (InputControl *)ctrl;
+ inp->setReadOnly(!_saveControl);
+ Common::SeekableReadStream *save = _engine->getSaveManager()->getSlotFile(iter->saveId);
+ if (save) {
+ SaveGameHeader header;
+ _engine->getSaveManager()->readSaveGameHeader(save, header);
+ delete save;
+ inp->setText(header.saveName);
+ iter->exist = true;
+ }
+ }
+ }
+}
+
+bool SaveControl::process(uint32 deltaTimeInMillis) {
+ for (saveElmntList::iterator iter = _inputs.begin(); iter != _inputs.end(); ++iter) {
+ Control *ctrl = _engine->getScriptManager()->getControl(iter->inputKey);
+ if (ctrl && ctrl->getType() == Control::CONTROL_INPUT) {
+ InputControl *inp = (InputControl *)ctrl;
+ if (inp->enterPress()) {
+ if (_saveControl) {
+ if (inp->getText().size() > 0) {
+ bool toSave = true;
+ if (iter->exist)
+ if (!_engine->askQuestion(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVEEXIST)))
+ toSave = false;
+
+ if (toSave) {
+ _engine->getSaveManager()->saveGameBuffered(iter->saveId, inp->getText());
+ _engine->delayedMessage(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVED), 2000);
+ _engine->getScriptManager()->changeLocation(_engine->getScriptManager()->getLastMenuLocation());
+ }
+ } else {
+ _engine->timedMessage(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVEEMPTY), 2000);
+ }
+ } else {
+ _engine->getSaveManager()->loadGame(iter->saveId);
+ return true;
+ }
+ break;
+ }
+ }
+ }
+ return false;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/timer_node.h b/engines/zvision/scripting/controls/save_control.h
index 48b5fad1e9..cdc50eb54d 100644
--- a/engines/zvision/scripting/controls/timer_node.h
+++ b/engines/zvision/scripting/controls/save_control.h
@@ -20,34 +20,34 @@
*
*/
-#ifndef ZVISION_TIMER_NODE_H
-#define ZVISION_TIMER_NODE_H
+#ifndef ZVISION_SAVE_CONTROL_H
+#define ZVISION_SAVE_CONTROL_H
#include "zvision/scripting/control.h"
+#include "common/list.h"
+
namespace ZVision {
-class ZVision;
+class SaveControl : public Control {
+public:
+ SaveControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
+
+private:
+ struct saveElement {
+ int saveId;
+ int inputKey;
+ bool exist;
+ };
+ typedef Common::List<saveElement> saveElmntList;
+ saveElmntList _inputs;
+
+ bool _saveControl;
-class TimerNode : public Control {
public:
- TimerNode(ZVision *engine, uint32 key, uint timeInSeconds);
- ~TimerNode();
-
- /**
- * Decrement the timer by the delta time. If the timer is finished, set the status
- * in _globalState and let this node be deleted
- *
- * @param deltaTimeInMillis The number of milliseconds that have passed since last frame
- * @return If true, the node can be deleted after process() finishes
- */
+
bool process(uint32 deltaTimeInMillis);
- void serialize(Common::WriteStream *stream);
- void deserialize(Common::SeekableReadStream *stream);
- inline bool needsSerialization() { return true; }
-private:
- int32 _timeLeft;
};
} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/slot_control.cpp b/engines/zvision/scripting/controls/slot_control.cpp
new file mode 100644
index 0000000000..1d83b44392
--- /dev/null
+++ b/engines/zvision/scripting/controls/slot_control.cpp
@@ -0,0 +1,218 @@
+/* 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/slot_control.h"
+
+#include "zvision/zvision.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/cursors/cursor_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/utility/utility.h"
+
+#include "common/stream.h"
+
+namespace ZVision {
+
+SlotControl::SlotControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key, CONTROL_SLOT) {
+
+ _renderedItem = 0;
+ _bkg = NULL;
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (param.matchString("hotspot", true)) {
+ int x;
+ int y;
+ int width;
+ int height;
+
+ sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height);
+
+ _hotspot = Common::Rect(x, y, width, height);
+ } else if (param.matchString("rectangle", true)) {
+ int x;
+ int y;
+ int width;
+ int height;
+
+ sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height);
+
+ _rectangle = Common::Rect(x, y, width, height);
+ } else if (param.matchString("cursor", true)) {
+ _cursor = _engine->getCursorManager()->getCursorId(values);
+ } else if (param.matchString("distance_id", true)) {
+ sscanf(values.c_str(), "%c", &_distanceId);
+ } else if (param.matchString("venus_id", true)) {
+ _venusId = atoi(values.c_str());
+ } else if (param.matchString("eligible_objects", true)) {
+ char buf[256];
+ memset(buf, 0, 256);
+ strcpy(buf, values.c_str());
+
+ char *curpos = buf;
+ char *strend = buf + strlen(buf);
+ while (true) {
+ char *st = curpos;
+
+ if (st >= strend)
+ break;
+
+ while (*curpos != ' ' && curpos < strend)
+ curpos++;
+
+ *curpos = 0;
+ curpos++;
+
+ int obj = atoi(st);
+
+ _eligibleObjects.push_back(obj);
+ }
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
+ }
+
+ if (_hotspot.isEmpty() || _rectangle.isEmpty()) {
+ warning("Slot %u was parsed incorrectly", key);
+ }
+}
+
+SlotControl::~SlotControl() {
+ // Clear the state value back to 0
+ //_engine->getScriptManager()->setStateValue(_key, 0);
+
+ if (_bkg)
+ delete _bkg;
+}
+
+bool SlotControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_hotspot.contains(backgroundImageSpacePos)) {
+ setVenus();
+
+ int item = _engine->getScriptManager()->getStateValue(_key);
+ int mouseItem = _engine->getScriptManager()->getStateValue(StateKey_InventoryItem);
+ if (item != 0) {
+ if (mouseItem != 0) {
+ if (eligeblity(mouseItem)) {
+ _engine->getScriptManager()->inventoryDrop(mouseItem);
+ _engine->getScriptManager()->inventoryAdd(item);
+ _engine->getScriptManager()->setStateValue(_key, mouseItem);
+ }
+ } else {
+ _engine->getScriptManager()->inventoryAdd(item);
+ _engine->getScriptManager()->setStateValue(_key, 0);
+ }
+ } else if (mouseItem == 0) {
+ if (eligeblity(0)) {
+ _engine->getScriptManager()->inventoryDrop(0);
+ _engine->getScriptManager()->setStateValue(_key, 0);
+ }
+ } else if (eligeblity(mouseItem)) {
+ _engine->getScriptManager()->setStateValue(_key, mouseItem);
+ _engine->getScriptManager()->inventoryDrop(mouseItem);
+ }
+ }
+ return false;
+}
+
+bool SlotControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_hotspot.contains(backgroundImageSpacePos)) {
+ _engine->getCursorManager()->changeCursor(_cursor);
+ return true;
+ }
+
+ return false;
+}
+
+bool SlotControl::process(uint32 deltaTimeInMillis) {
+ if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
+ return false;
+
+ if (_engine->canRender()) {
+ int curItem = _engine->getScriptManager()->getStateValue(_key);
+ if (curItem != _renderedItem) {
+ if (_renderedItem != 0 && curItem == 0) {
+ _engine->getRenderManager()->blitSurfaceToBkg(*_bkg, _rectangle.left, _rectangle.top);
+ _renderedItem = curItem;
+ } else {
+ if (_renderedItem == 0) {
+ if (_bkg)
+ delete _bkg;
+
+ _bkg = _engine->getRenderManager()->getBkgRect(_rectangle);
+ } else {
+ _engine->getRenderManager()->blitSurfaceToBkg(*_bkg, _rectangle.left, _rectangle.top);
+ }
+
+ char buf[16];
+ if (_engine->getGameId() == GID_NEMESIS)
+ sprintf(buf, "%d%cobj.tga", curItem, _distanceId);
+ else
+ sprintf(buf, "g0z%cu%2.2x1.tga", _distanceId, curItem);
+
+ Graphics::Surface *srf = _engine->getRenderManager()->loadImage(buf);
+
+ int16 drawx = _rectangle.left;
+ int16 drawy = _rectangle.top;
+
+ if (_rectangle.width() > srf->w)
+ drawx = _rectangle.left + (_rectangle.width() - srf->w) / 2;
+
+ if (_rectangle.height() > srf->h)
+ drawy = _rectangle.top + (_rectangle.height() - srf->h) / 2;
+
+ _engine->getRenderManager()->blitSurfaceToBkg(*srf, drawx, drawy, 0);
+
+ delete srf;
+
+ _renderedItem = curItem;
+ }
+ }
+ }
+ return false;
+}
+
+bool SlotControl::eligeblity(int itemId) {
+ for (Common::List<int>::iterator it = _eligibleObjects.begin(); it != _eligibleObjects.end(); it++)
+ if (*it == itemId)
+ return true;
+ return false;
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/slot_control.h b/engines/zvision/scripting/controls/slot_control.h
new file mode 100644
index 0000000000..e776d99311
--- /dev/null
+++ b/engines/zvision/scripting/controls/slot_control.h
@@ -0,0 +1,84 @@
+/* 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_SLOT_CONTROL_H
+#define ZVISION_SLOT_CONTROL_H
+
+#include "zvision/scripting/control.h"
+
+#include "graphics/surface.h"
+
+#include "common/rect.h"
+#include "common/list.h"
+
+namespace ZVision {
+
+class SlotControl : public Control {
+public:
+ SlotControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
+ ~SlotControl();
+
+ /**
+ * 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
+ */
+ 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.
+ *
+ * @param engine The base engine
+ * @param screenSpacePos The position of the mouse in screen space
+ * @param backgroundImageSpacePos The position of the mouse in background image space
+ * @return Was the cursor changed?
+ */
+ bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos);
+
+ bool process(uint32 deltaTimeInMillis);
+
+private:
+ /**
+ * The area that will trigger the event
+ * This is in image space coordinates, NOT screen space
+ */
+ Common::Rect _rectangle;
+ Common::Rect _hotspot;
+
+ int _cursor;
+ char _distanceId;
+
+ int _renderedItem;
+
+ Common::List<int> _eligibleObjects;
+
+ bool eligeblity(int itemId);
+
+ Graphics::Surface *_bkg;
+
+ /** The cursor to use when hovering over _hotspot */
+ Common::String _hoverCursor;
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/controls/timer_node.cpp b/engines/zvision/scripting/controls/timer_node.cpp
deleted file mode 100644
index 6f88b056a1..0000000000
--- a/engines/zvision/scripting/controls/timer_node.cpp
+++ /dev/null
@@ -1,73 +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/timer_node.h"
-
-#include "zvision/zvision.h"
-#include "zvision/scripting/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) {
- _timeLeft = timeInSeconds * 1000;
- } else if (_engine->getGameId() == GID_GRANDINQUISITOR) {
- _timeLeft = timeInSeconds * 100;
- }
-
- _engine->getScriptManager()->setStateValue(_key, 1);
-}
-
-TimerNode::~TimerNode() {
- if (_timeLeft <= 0)
- _engine->getScriptManager()->setStateValue(_key, 2);
- else
- _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;
- }
-
- return false;
-}
-
-void TimerNode::serialize(Common::WriteStream *stream) {
- stream->writeUint32LE(_key);
- stream->writeUint32LE(_timeLeft);
-}
-
-void TimerNode::deserialize(Common::SeekableReadStream *stream) {
- _timeLeft = stream->readUint32LE();
-}
-
-} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/titler_control.cpp b/engines/zvision/scripting/controls/titler_control.cpp
new file mode 100644
index 0000000000..f0126bebc2
--- /dev/null
+++ b/engines/zvision/scripting/controls/titler_control.cpp
@@ -0,0 +1,107 @@
+/* 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/titler_control.h"
+
+#include "zvision/zvision.h"
+#include "zvision/text/text.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/graphics/render_manager.h"
+#include "zvision/utility/utility.h"
+
+#include "common/stream.h"
+
+namespace ZVision {
+
+TitlerControl::TitlerControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
+ : Control(engine, key, CONTROL_TITLER) {
+
+ _surface = NULL;
+ _curString = -1;
+
+ // Loop until we find the closing brace
+ Common::String line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ Common::String param;
+ Common::String values;
+ getParams(line, param, values);
+
+ while (!stream.eos() && !line.contains('}')) {
+ if (param.matchString("string_resource_file", true)) {
+ readStringsFile(values);
+ } else if (param.matchString("rectangle", true)) {
+ int x;
+ int y;
+ int x2;
+ int y2;
+
+ sscanf(values.c_str(), "%d %d %d %d", &x, &y, &x2, &y2);
+
+ _rectangle = Common::Rect(x, y, x2, y2);
+ }
+
+ line = stream.readLine();
+ trimCommentsAndWhiteSpace(&line);
+ getParams(line, param, values);
+ }
+
+ if (!_rectangle.isEmpty()) {
+ _surface = new Graphics::Surface;
+ _surface->create(_rectangle.width(), _rectangle.height(), _engine->_pixelFormat);
+ _surface->fillRect(Common::Rect(_surface->w, _surface->h), 0);
+ }
+}
+
+TitlerControl::~TitlerControl() {
+ if (_surface)
+ delete _surface;
+}
+
+void TitlerControl::setString(int strLine) {
+ if (strLine != _curString && strLine >= 0 && strLine < (int)_strings.size()) {
+ _surface->fillRect(Common::Rect(_surface->w, _surface->h), 0);
+ _engine->getTextRenderer()->drawTxtInOneLine(_strings[strLine], *_surface);
+ _engine->getRenderManager()->blitSurfaceToBkg(*_surface, _rectangle.left, _rectangle.top);
+ _curString = strLine;
+ }
+}
+
+void TitlerControl::readStringsFile(const Common::String &fileName) {
+ Common::File file;
+ if (!_engine->getSearchManager()->openFile(file, fileName)) {
+ warning("String_resource_file %s could could be opened", fileName.c_str());
+ return;
+ }
+
+ _strings.clear();
+
+ while (!file.eos()) {
+
+ Common::String line = readWideLine(file);
+ _strings.push_back(line);
+ }
+ file.close();
+}
+
+} // End of namespace ZVision
diff --git a/engines/zvision/scripting/controls/titler_control.h b/engines/zvision/scripting/controls/titler_control.h
new file mode 100644
index 0000000000..075e47c9e9
--- /dev/null
+++ b/engines/zvision/scripting/controls/titler_control.h
@@ -0,0 +1,54 @@
+/* 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_TITLER_CONTROL_H
+#define ZVISION_TITLER_CONTROL_H
+
+#include "zvision/scripting/control.h"
+
+#include "graphics/surface.h"
+
+#include "common/rect.h"
+#include "common/array.h"
+
+namespace ZVision {
+
+class TitlerControl : public Control {
+public:
+ TitlerControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
+ ~TitlerControl();
+
+ void setString(int strLine);
+
+private:
+
+ Common::Array< Common::String > _strings;
+ Common::Rect _rectangle;
+ int16 _curString;
+ Graphics::Surface *_surface;
+
+ void readStringsFile(const Common::String &fileName);
+};
+
+} // End of namespace ZVision
+
+#endif