aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/zvision/module.mk1
-rw-r--r--engines/zvision/scripting/controls/fist_control.cpp294
-rw-r--r--engines/zvision/scripting/controls/fist_control.h86
-rw-r--r--engines/zvision/scripting/scr_file_handling.cpp3
4 files changed, 384 insertions, 0 deletions
diff --git a/engines/zvision/module.mk b/engines/zvision/module.mk
index 0e6f1ce042..4cfb8f3182 100644
--- a/engines/zvision/module.mk
+++ b/engines/zvision/module.mk
@@ -17,6 +17,7 @@ MODULE_OBJS := \
graphics/render_table.o \
scripting/actions.o \
scripting/control.o \
+ scripting/controls/fist_control.o \
scripting/controls/hotmov_control.o \
scripting/controls/input_control.o \
scripting/controls/lever_control.o \
diff --git a/engines/zvision/scripting/controls/fist_control.cpp b/engines/zvision/scripting/controls/fist_control.cpp
new file mode 100644
index 0000000000..46b87ddb79
--- /dev/null
+++ b/engines/zvision/scripting/controls/fist_control.cpp
@@ -0,0 +1,294 @@
+/* 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)) {
+ _venus_id = 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 n_fist = mouseIn(screenSpacePos, backgroundImageSpacePos);
+
+ if (n_fist >= 0) {
+ //ctrl_setvenus(ct);
+
+ uint32 oldStatus = _fiststatus;
+ _fiststatus ^= (1 << n_fist);
+
+ 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);
+
+ //_engine->getScriptManager()->FlushMouseBtn(SDL_BUTTON_LEFT);
+ }
+
+ 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;
+
+ while (!file.eos()) {
+ line = file.readLine();
+
+ for (int i = line.size() - 1; i >= 0; i--)
+ if (line[i] == '~')
+ line.deleteChar(i);
+
+ if (line.matchString("*animation_id*", true)) {
+ // Not used
+ } else if (line.matchString("*animation*", true)) {
+ char filename[64];
+ sscanf(line.c_str(), "animation:%s", filename);
+ _animation = new MetaAnimation(Common::String(filename), _engine);
+ } else if (line.matchString("*anim_rect*", true)) {
+ int left, top, right, bottom;
+ sscanf(line.c_str(), "anim_rect:%d %d %d %d", &left, &top, &right, &bottom);
+ _anmRect = Common::Rect(left, top, right, bottom);
+ } else if (line.matchString("*num_fingers*", true)) {
+ sscanf(line.c_str(), "num_fingers:%d", &_fistnum);
+ _fistsUp.resize(_fistnum);
+ _fistsDwn.resize(_fistnum);
+ } else if (line.matchString("*entries*", true)) {
+ sscanf(line.c_str(), "entries:%d", &_numEntries);
+ _entries.resize(_numEntries);
+ } else if (line.matchString("*eval_order_ascending*", true)) {
+ sscanf(line.c_str(), "eval_order_ascending:%d", &_order);
+ } else if (line.matchString("*up_hs_num_*", true)) {
+ int fist, num;
+ sscanf(line.c_str(), "up_hs_num_%d:%d", &fist, &num);
+ _fistsUp[fist].resize(num);
+ } else if (line.matchString("*up_hs_*", true)) {
+ int16 fist, box, x1, y1, x2, y2;
+ sscanf(line.c_str(), "up_hs_%hd_%hd:%hd %hd %hd %hd", &fist, &box, &x1, &y1, &x2, &y2);
+ (_fistsUp[fist])[box] = Common::Rect(x1, y1, x2, y2);
+ } else if (line.matchString("*down_hs_num_*", true)) {
+ int fist, num;
+ sscanf(line.c_str(), "down_hs_num_%d:%d", &fist, &num);
+ _fistsDwn[fist].resize(num);
+ } else if (line.matchString("*down_hs_*", true)) {
+ int16 fist, box, x1, y1, x2, y2;
+ sscanf(line.c_str(), "down_hs_%hd_%hd:%hd %hd %hd %hd", &fist, &box, &x1, &y1, &x2, &y2);
+ (_fistsDwn[fist])[box] = Common::Rect(x1, y1, x2, y2);
+ } else {
+ int entry, start, end, sound;
+ char bits_start[33];
+ char bits_end[33];
+ if (sscanf(line.c_str(), "%d:%s %s %d %d (%d)", &entry, bits_start, bits_end, &start, &end, &sound) == 6) {
+ _entries[entry]._bitsStrt = readBits(bits_start);
+ _entries[entry]._bitsEnd = readBits(bits_end);
+ _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;
+}
+
+} // 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..940bc96d69
--- /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);
+};
+
+} // End of namespace ZVision
+
+#endif
diff --git a/engines/zvision/scripting/scr_file_handling.cpp b/engines/zvision/scripting/scr_file_handling.cpp
index d6c5aa0cb5..5afa5b2871 100644
--- a/engines/zvision/scripting/scr_file_handling.cpp
+++ b/engines/zvision/scripting/scr_file_handling.cpp
@@ -35,6 +35,7 @@
#include "zvision/scripting/controls/input_control.h"
#include "zvision/scripting/controls/safe_control.h"
#include "zvision/scripting/controls/hotmov_control.h"
+#include "zvision/scripting/controls/fist_control.h"
#include "common/textconsole.h"
#include "common/file.h"
@@ -358,6 +359,8 @@ Control *ScriptManager::parseControl(Common::String &line, Common::SeekableReadS
return new SafeControl(_engine, key, stream);
} else if (controlType.equalsIgnoreCase("hotmovie")) {
return new HotMovControl(_engine, key, stream);
+ } else if (controlType.equalsIgnoreCase("fist")) {
+ return new FistControl(_engine, key, stream);
}
return NULL;
}