diff options
author | Marisa-Chan | 2014-07-02 19:50:55 +0000 |
---|---|---|
committer | Marisa-Chan | 2014-07-02 19:50:55 +0000 |
commit | 23c1b508611d5fa4e7dfc47f8f5ec10a7de177e3 (patch) | |
tree | 4e5baf796851ebe649c078913fea71972d994c38 /engines/zvision/scripting | |
parent | ace0e5e88f63f34dad94962c95f57f3ec42258ae (diff) | |
download | scummvm-rg350-23c1b508611d5fa4e7dfc47f8f5ec10a7de177e3.tar.gz scummvm-rg350-23c1b508611d5fa4e7dfc47f8f5ec10a7de177e3.tar.bz2 scummvm-rg350-23c1b508611d5fa4e7dfc47f8f5ec10a7de177e3.zip |
ZVISION: Reorgonize source files into directories.
Diffstat (limited to 'engines/zvision/scripting')
22 files changed, 1561 insertions, 13 deletions
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp index 3c341fbc80..22fbd4ff16 100644 --- a/engines/zvision/scripting/actions.cpp +++ b/engines/zvision/scripting/actions.cpp @@ -29,11 +29,11 @@ #include "zvision/graphics/render_manager.h" #include "zvision/sound/zork_raw.h" #include "zvision/video/zork_avi_decoder.h" -#include "zvision/scripting/controls/timer_node.h" -#include "zvision/music_node.h" -#include "zvision/syncsound_node.h" -#include "zvision/animation_node.h" -#include "zvision/ttytext_node.h" +#include "zvision/scripting/sidefx/timer_node.h" +#include "zvision/scripting/sidefx/music_node.h" +#include "zvision/scripting/sidefx/syncsound_node.h" +#include "zvision/scripting/sidefx/animation_node.h" +#include "zvision/scripting/sidefx/ttytext_node.h" #include "common/file.h" diff --git a/engines/zvision/scripting/controls/input_control.cpp b/engines/zvision/scripting/controls/input_control.cpp index ca707b5ab0..ba1b634d42 100644 --- a/engines/zvision/scripting/controls/input_control.cpp +++ b/engines/zvision/scripting/controls/input_control.cpp @@ -26,7 +26,7 @@ #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" diff --git a/engines/zvision/scripting/controls/input_control.h b/engines/zvision/scripting/controls/input_control.h index 4a63f228a0..6fcdb2ca54 100644 --- a/engines/zvision/scripting/controls/input_control.h +++ b/engines/zvision/scripting/controls/input_control.h @@ -24,7 +24,7 @@ #define ZVISION_INPUT_CONTROL_H #include "zvision/scripting/control.h" -#include "zvision/strings/string_manager.h" +#include "zvision/text/string_manager.h" #include "common/rect.h" diff --git a/engines/zvision/scripting/controls/lever_control.cpp b/engines/zvision/scripting/controls/lever_control.cpp index 121fab97e1..7e3ee775fb 100644 --- a/engines/zvision/scripting/controls/lever_control.cpp +++ b/engines/zvision/scripting/controls/lever_control.cpp @@ -28,7 +28,7 @@ #include "zvision/scripting/script_manager.h" #include "zvision/graphics/render_manager.h" #include "zvision/cursors/cursor_manager.h" -#include "zvision/meta_animation.h" +#include "zvision/animation/meta_animation.h" #include "zvision/utility/utility.h" #include "common/stream.h" diff --git a/engines/zvision/scripting/controls/slot_control.cpp b/engines/zvision/scripting/controls/slot_control.cpp new file mode 100644 index 0000000000..c85b02b3cd --- /dev/null +++ b/engines/zvision/scripting/controls/slot_control.cpp @@ -0,0 +1,219 @@ +/* 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) { + + _rendered_item = 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", &_distance_id); + } else if (param.matchString("venus_id", true)) { + _venus_id = 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); + + _eligible_objects.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)) { + //ctrl_setvenus(ct); + + int item = _engine->getScriptManager()->getStateValue(_key); + int mouse_item = _engine->getScriptManager()->getStateValue(StateKey_InventoryItem); + if (item != 0) { + if (mouse_item != 0) { + if (eligeblity(mouse_item)) { + _engine->getScriptManager()->invertory_drop(mouse_item); + _engine->getScriptManager()->invertory_add(item); + _engine->getScriptManager()->setStateValue(_key, mouse_item); + } + } else { + _engine->getScriptManager()->invertory_add(item); + _engine->getScriptManager()->setStateValue(_key, 0); + } + } else if (mouse_item == 0) { + if (eligeblity(0)) { + _engine->getScriptManager()->invertory_drop(0); + _engine->getScriptManager()->setStateValue(_key, 0); + } + } else if (eligeblity(mouse_item)) { + _engine->getScriptManager()->setStateValue(_key, mouse_item); + _engine->getScriptManager()->invertory_drop(mouse_item); + } + } + 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 cur_item = _engine->getScriptManager()->getStateValue(_key); + if (cur_item != _rendered_item) { + if (_rendered_item != 0 && cur_item == 0) { + _engine->getRenderManager()->blitSurfaceToBkg(*_bkg, _rectangle.left, _rectangle.top); + _rendered_item = cur_item; + } else { + if (_rendered_item == 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", cur_item, _distance_id); + else + sprintf(buf, "g0z%cu%2.2x1.tga", _distance_id, cur_item); + + 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; + + _rendered_item = cur_item; + } + } + } + return false; +} + +bool SlotControl::eligeblity(int item_id) { + for (Common::List<int>::iterator it = _eligible_objects.begin(); it != _eligible_objects.end(); it++) + if (*it == item_id) + 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..0ac8ec9ce0 --- /dev/null +++ b/engines/zvision/scripting/controls/slot_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_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 _distance_id; + int _venus_id; + + int _rendered_item; + + Common::List<int> _eligible_objects; + + bool eligeblity(int item_id); + + 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/inventory.cpp b/engines/zvision/scripting/inventory.cpp new file mode 100644 index 0000000000..f8b22970c4 --- /dev/null +++ b/engines/zvision/scripting/inventory.cpp @@ -0,0 +1,123 @@ +/* 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/script_manager.h" + + +namespace ZVision { + +int8 ScriptManager::invertory_getCount() { + return getStateValue(StateKey_Inv_Cnt_Slot); +} + +void ScriptManager::invertory_setCount(int8 cnt) { + setStateValue(StateKey_Inv_Cnt_Slot, cnt); +} + +int16 ScriptManager::invertory_getItem(int8 id) { + if (id < 49 && id >= 0) + return getStateValue(StateKey_Inv_1_Slot + id); + return -1; +} + +void ScriptManager::invertory_setItem(int8 id, int16 item) { + if (id < 49 && id >= 0) + setStateValue(StateKey_Inv_1_Slot + id, item); +} + +void ScriptManager::invertory_add(int16 item) { + int8 cnt = invertory_getCount(); + + if (cnt < 49) { + bool not_exist = true; + + if (cnt == 0) { + invertory_setItem(0, 0); + invertory_setCount(1); // we needed empty item for cycle code + cnt = 1; + } + + for (int8 cur = 0; cur < cnt; cur++) + if (invertory_getItem(cur) == item) { + not_exist = false; + break; + } + + if (not_exist) { + for (int8 i = cnt; i > 0; i--) + invertory_setItem(i, invertory_getItem(i - 1)); + + invertory_setItem(0, item); + + setStateValue(StateKey_InventoryItem, item); + + invertory_setCount(cnt + 1); + } + } +} + +void ScriptManager::invertory_drop(int16 item) { + int8 items_cnt = invertory_getCount(); + + // if items in inventory > 0 + if (items_cnt != 0) { + int8 index = 0; + + // finding needed item + while (index < items_cnt) { + if (invertory_getItem(index) == item) + break; + + index++; + } + + // if item in the inventory + if (items_cnt != index) { + // shift all items left with rewrite founded item + for (int8 v = index; v < items_cnt - 1 ; v++) + invertory_setItem(v, invertory_getItem(v + 1)); + + // del last item + invertory_setItem(items_cnt - 1, 0); + invertory_setCount(invertory_getCount() - 1); + + setStateValue(StateKey_InventoryItem, invertory_getItem(0)); + } + } +} +void ScriptManager::invertory_cycle() { + int8 item_cnt = invertory_getCount(); + int8 cur_item = invertory_getItem(0); + if (item_cnt > 1) { + for (int8 i = 0; i < item_cnt - 1; i++) + invertory_setItem(i, invertory_getItem(i + 1)); + + invertory_setItem(item_cnt - 1, cur_item); + + setStateValue(StateKey_InventoryItem, invertory_getItem(0)); + + } +} + +} // End of namespace ZVision diff --git a/engines/zvision/scripting/scr_file_handling.cpp b/engines/zvision/scripting/scr_file_handling.cpp index fff187d369..5d697bd841 100644 --- a/engines/zvision/scripting/scr_file_handling.cpp +++ b/engines/zvision/scripting/scr_file_handling.cpp @@ -30,7 +30,7 @@ #include "zvision/scripting/actions.h" #include "zvision/scripting/controls/push_toggle_control.h" #include "zvision/scripting/controls/lever_control.h" -#include "zvision/slot_control.h" +#include "zvision/scripting/controls/slot_control.h" #include "common/textconsole.h" #include "common/file.h" diff --git a/engines/zvision/scripting/script_manager.cpp b/engines/zvision/scripting/script_manager.cpp index 9713a34733..a27ae4dbf0 100644 --- a/engines/zvision/scripting/script_manager.cpp +++ b/engines/zvision/scripting/script_manager.cpp @@ -30,7 +30,7 @@ #include "zvision/core/save_manager.h" #include "zvision/scripting/actions.h" #include "zvision/utility/utility.h" -#include "zvision/scripting/controls/timer_node.h" +#include "zvision/scripting/sidefx/timer_node.h" #include "common/algorithm.h" #include "common/hashmap.h" diff --git a/engines/zvision/scripting/script_manager.h b/engines/zvision/scripting/script_manager.h index a835c13951..8ec364b35f 100644 --- a/engines/zvision/scripting/script_manager.h +++ b/engines/zvision/scripting/script_manager.h @@ -25,7 +25,7 @@ #include "zvision/scripting/puzzle.h" #include "zvision/scripting/control.h" -#include "zvision/sidefx.h" +#include "zvision/scripting/sidefx.h" #include "common/hashmap.h" #include "common/queue.h" diff --git a/engines/zvision/scripting/sidefx.cpp b/engines/zvision/scripting/sidefx.cpp new file mode 100644 index 0000000000..c0b8a4d12f --- /dev/null +++ b/engines/zvision/scripting/sidefx.cpp @@ -0,0 +1,36 @@ +/* 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/sidefx.h" + +#include "zvision/zvision.h" +#include "zvision/graphics/render_manager.h" +#include "zvision/utility/utility.h" + +#include "common/stream.h" + +namespace ZVision { + + +} // End of namespace ZVision diff --git a/engines/zvision/scripting/sidefx.h b/engines/zvision/scripting/sidefx.h new file mode 100644 index 0000000000..2c53467559 --- /dev/null +++ b/engines/zvision/scripting/sidefx.h @@ -0,0 +1,124 @@ +/* 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 SIDEFX_H_INCLUDED +#define SIDEFX_H_INCLUDED + +namespace Common { +class SeekableReadStream; +struct Point; +class WriteStream; +} + +namespace ZVision { + +class ZVision; + +class SideFX { +public: + + enum SideFXType { + SIDEFX_ANIM = 1, + SIDEFX_AUDIO = 2, + SIDEFX_DISTORT = 4, + SIDEFX_PANTRACK = 8, + SIDEFX_REGION = 16, + SIDEFX_TIMER = 32, + SIDEFX_TTYTXT = 64, + SIDEFX_UNK = 128, + SIDEFX_ALL = 255 + }; + + SideFX() : _engine(0), _key(0), _type(SIDEFX_UNK) {} + SideFX(ZVision *engine, uint32 key, SideFXType type) : _engine(engine), _key(key), _type(type) {} + virtual ~SideFX() {} + + uint32 getKey() { + return _key; + } + SideFXType getType() { + return _type; + } + + virtual bool process(uint32 deltaTimeInMillis) { + return false; + } + /** + * Serialize a SideFX for save game use. This should only be used if a SideFX needs + * to save values that would be different from initialization. AKA a TimerNode needs to + * store the amount of time left on the timer. Any Controls overriding this *MUST* write + * their key as the first data outputted. The default implementation is NOP. + * + * NOTE: If this method is overridden, you MUST also override deserialize() + * and needsSerialization() + * + * @param stream Stream to write any needed data to + */ + virtual void serialize(Common::WriteStream *stream) {} + /** + * De-serialize data from a save game stream. This should only be implemented if the + * SideFX also implements serialize(). The calling method assumes the size of the + * data read from the stream exactly equals that written in serialize(). The default + * implementation is NOP. + * + * NOTE: If this method is overridden, you MUST also override serialize() + * and needsSerialization() + * + * @param stream Save game file stream + */ + virtual void deserialize(Common::SeekableReadStream *stream) {} + /** + * If a SideFX overrides serialize() and deserialize(), this should return true + * + * @return Does the SideFX need save game serialization? + */ + virtual inline bool needsSerialization() { + return false; + } + + virtual bool stop() { + return true; + } + virtual void kill() {} + +protected: + ZVision *_engine; + uint32 _key; + SideFXType _type; + +// Static member functions +public: + +}; + +// TODO: Implement InputControl +// TODO: Implement SaveControl +// TODO: Implement SlotControl +// TODO: Implement SafeControl +// TODO: Implement FistControl +// TODO: Implement HotMovieControl +// TODO: Implement PaintControl +// TODO: Implement TilterControl + +} // End of namespace ZVision + +#endif // SIDEFX_H_INCLUDED diff --git a/engines/zvision/scripting/sidefx/animation_node.cpp b/engines/zvision/scripting/sidefx/animation_node.cpp new file mode 100644 index 0000000000..4a606adc9e --- /dev/null +++ b/engines/zvision/scripting/sidefx/animation_node.cpp @@ -0,0 +1,211 @@ +/* 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/sidefx/animation_node.h" + +#include "zvision/zvision.h" +#include "zvision/graphics/render_manager.h" +#include "zvision/scripting/script_manager.h" +#include "zvision/animation/meta_animation.h" + +#include "graphics/surface.h" + + +namespace ZVision { + +AnimationNode::AnimationNode(ZVision *engine, uint32 controlKey, const Common::String &fileName, int32 mask, int32 frate, bool DisposeAfterUse) + : SideFX(engine, controlKey, SIDEFX_ANIM), + _DisposeAfterUse(DisposeAfterUse), + _mask(mask), + _animation(NULL) { + + if (fileName.hasSuffix(".rlf") || fileName.hasSuffix(".avi")) { + _animation = new MetaAnimation(fileName, engine); + _frmDelay = _animation->frameTime(); + } else { + warning("Unrecognized animation file type: %s", fileName.c_str()); + } + + if (frate > 0) + _frmDelay = 1000.0 / frate; +} + +AnimationNode::~AnimationNode() { + if (_animation) + delete _animation; + + _engine->getScriptManager()->setStateValue(_key, 2); + + PlayNodes::iterator it = _playList.begin(); + if (it != _playList.end()) { + _engine->getScriptManager()->setStateValue((*it).slot, 2); + + if ((*it)._scaled) + delete(*it)._scaled; + } + + _playList.clear(); +} + +bool AnimationNode::process(uint32 deltaTimeInMillis) { + PlayNodes::iterator it = _playList.begin(); + if (it != _playList.end()) { + playnode *nod = &(*it); + + nod->_delay -= deltaTimeInMillis; + if (nod->_delay <= 0) { + nod->_delay += _frmDelay; + + const Graphics::Surface *frame = NULL; + + if (nod->_cur_frm == -1) { // Start of new playlist node + nod->_cur_frm = nod->start; + + _animation->seekToFrame(nod->_cur_frm); + frame = _animation->decodeNextFrame(); + + nod->_delay = _frmDelay; + if (nod->slot) + _engine->getScriptManager()->setStateValue(nod->slot, 1); + } else { + nod->_cur_frm++; + + if (nod->_cur_frm > nod->stop) { + nod->loop--; + + if (nod->loop == 0) { + if (nod->slot >= 0) + _engine->getScriptManager()->setStateValue(nod->slot, 2); + if (nod->_scaled) + delete nod->_scaled; + _playList.erase(it); + return _DisposeAfterUse; + } + + nod->_cur_frm = nod->start; + _animation->seekToFrame(nod->_cur_frm); + } + + frame = _animation->decodeNextFrame(); + } + + if (frame) { + + uint32 dstw; + uint32 dsth; + if (_engine->getRenderManager()->getRenderTable()->getRenderState() == RenderTable::PANORAMA) { + dstw = nod->pos.height(); + dsth = nod->pos.width(); + } else { + dstw = nod->pos.width(); + dsth = nod->pos.height(); + } + + if (frame->w != dstw || frame->h != dsth) { + if (nod->_scaled) + if (nod->_scaled->w != dstw || nod->_scaled->h != dsth) { + delete nod->_scaled; + nod->_scaled = NULL; + } + + if (!nod->_scaled) { + nod->_scaled = new Graphics::Surface; + nod->_scaled->create(dstw, dsth, frame->format); + } + + _engine->getRenderManager()->scaleBuffer(frame->getPixels(), nod->_scaled->getPixels(), frame->w, frame->h, frame->format.bytesPerPixel, dstw, dsth); + frame = nod->_scaled; + } + + if (_engine->getRenderManager()->getRenderTable()->getRenderState() == RenderTable::PANORAMA) { + Graphics::Surface *transposed = RenderManager::tranposeSurface(frame); + if (_mask > 0) + _engine->getRenderManager()->blitSurfaceToBkg(*transposed, nod->pos.left, nod->pos.top, _mask); + else + _engine->getRenderManager()->blitSurfaceToBkg(*transposed, nod->pos.left, nod->pos.top); + delete transposed; + } else { + if (_mask > 0) + _engine->getRenderManager()->blitSurfaceToBkg(*frame, nod->pos.left, nod->pos.top, _mask); + else + _engine->getRenderManager()->blitSurfaceToBkg(*frame, nod->pos.left, nod->pos.top); + } + } + } + } + + return false; +} + + + +void AnimationNode::addPlayNode(int32 slot, int x, int y, int x2, int y2, int start_frame, int end_frame, int loops) { + playnode nod; + nod.loop = loops; + nod.pos = Common::Rect(x, y, x2 + 1, y2 + 1); + nod.start = start_frame; + nod.stop = end_frame; + + if (nod.stop >= (int)_animation->frameCount()) + nod.stop = _animation->frameCount() - 1; + + nod.slot = slot; + nod._cur_frm = -1; + nod._delay = 0; + nod._scaled = NULL; + _playList.push_back(nod); +} + +bool AnimationNode::stop() { + PlayNodes::iterator it = _playList.begin(); + if (it != _playList.end()) { + _engine->getScriptManager()->setStateValue((*it).slot, 2); + if ((*it)._scaled) + delete(*it)._scaled; + } + + _playList.clear(); + + // We don't need to delete, it's may be reused + return false; +} + +void AnimationNode::setNewFrameDelay(int32 newDelay) { + if (newDelay > 0) { + PlayNodes::iterator it = _playList.begin(); + if (it != _playList.end()) { + playnode *nod = &(*it); + float percent = (float)nod->_delay / (float)_frmDelay; + nod->_delay = percent * newDelay; // Scale to new max + } + + _frmDelay = newDelay; + } +} + +int32 AnimationNode::getFrameDelay() { + return _frmDelay; +} + +} // End of namespace ZVision diff --git a/engines/zvision/scripting/sidefx/animation_node.h b/engines/zvision/scripting/sidefx/animation_node.h new file mode 100644 index 0000000000..4d1c74bccf --- /dev/null +++ b/engines/zvision/scripting/sidefx/animation_node.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_ANIMATION_NODE_H +#define ZVISION_ANIMATION_NODE_H + +#include "zvision/scripting/sidefx.h" +#include "common/rect.h" +#include "common/list.h" + + +namespace Common { +class String; +} + +namespace Graphics { +struct Surface; +} + +namespace ZVision { + +class ZVision; +class MetaAnimation; + +class AnimationNode : public SideFX { +public: + AnimationNode(ZVision *engine, uint32 controlKey, const Common::String &fileName, int32 mask, int32 frate, bool DisposeAfterUse = true); + ~AnimationNode(); + + struct playnode { + Common::Rect pos; + int32 slot; + int32 start; + int32 stop; + int32 loop; + int32 _cur_frm; + int32 _delay; + Graphics::Surface *_scaled; + }; + +private: + typedef Common::List<playnode> PlayNodes; + + PlayNodes _playList; + + int32 _mask; + bool _DisposeAfterUse; + + MetaAnimation *_animation; + int32 _frmDelay; + +public: + bool process(uint32 deltaTimeInMillis); + + void addPlayNode(int32 slot, int x, int y, int x2, int y2, int start_frame, int end_frame, int loops = 1); + + bool stop(); + + void setNewFrameDelay(int32 newDelay); + int32 getFrameDelay(); +}; + +} // End of namespace ZVision + +#endif diff --git a/engines/zvision/scripting/sidefx/music_node.cpp b/engines/zvision/scripting/sidefx/music_node.cpp new file mode 100644 index 0000000000..0351867dd9 --- /dev/null +++ b/engines/zvision/scripting/sidefx/music_node.cpp @@ -0,0 +1,190 @@ +/* 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/sidefx/music_node.h" + +#include "zvision/zvision.h" +#include "zvision/scripting/script_manager.h" +#include "zvision/graphics/render_manager.h" +#include "zvision/sound/zork_raw.h" + +#include "common/stream.h" +#include "common/file.h" +#include "audio/decoders/wave.h" + + +namespace ZVision { + +MusicNode::MusicNode(ZVision *engine, uint32 key, Common::String &filename, bool loop, int8 volume) + : SideFX(engine, key, SIDEFX_AUDIO) { + _loop = loop; + _volume = volume; + _crossfade = false; + _crossfade_target = 0; + _crossfade_time = 0; + _attenuate = 0; + _pantrack = false; + _pantrack_X = 0; + _sub = NULL; + + Audio::RewindableAudioStream *audioStream; + + if (filename.contains(".wav")) { + Common::File *file = new Common::File(); + if (_engine->getSearchManager()->openFile(*file, filename)) { + audioStream = Audio::makeWAVStream(file, DisposeAfterUse::YES); + } + } else { + audioStream = makeRawZorkStream(filename, _engine); + } + + _stereo = audioStream->isStereo(); + + if (_loop) { + Audio::LoopingAudioStream *loopingAudioStream = new Audio::LoopingAudioStream(audioStream, 0, DisposeAfterUse::YES); + _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, loopingAudioStream, -1, _volume); + } else { + _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, audioStream, -1, _volume); + } + + if (_key != StateKey_NotSet) + _engine->getScriptManager()->setStateValue(_key, 1); + + Common::String subname = filename; + subname.setChar('s', subname.size() - 3); + subname.setChar('u', subname.size() - 2); + subname.setChar('b', subname.size() - 1); + + if (_engine->getSearchManager()->hasFile(subname)) + _sub = new Subtitle(_engine, subname); +} + +MusicNode::~MusicNode() { + _engine->_mixer->stopHandle(_handle); + if (_key != StateKey_NotSet) + _engine->getScriptManager()->setStateValue(_key, 2); + if (_sub) + delete _sub; + debug(1, "MusicNode: %d destroyed\n", _key); +} + +void MusicNode::setPanTrack(int16 pos) { + if (!_stereo) { + _pantrack = true; + _pantrack_X = pos; + setVolume(_volume); + } +} + +void MusicNode::unsetPanTrack() { + _pantrack = false; + setVolume(_volume); +} + +void MusicNode::setFade(int32 time, uint8 target) { + _crossfade_target = target; + _crossfade_time = time; + _crossfade = true; +} + +bool MusicNode::process(uint32 deltaTimeInMillis) { + if (! _engine->_mixer->isSoundHandleActive(_handle)) + return stop(); + else { + uint8 _newvol = _volume; + + if (_crossfade) { + if (_crossfade_time > 0) { + if ((int32)deltaTimeInMillis > _crossfade_time) + deltaTimeInMillis = _crossfade_time; + _newvol += floor(((float)(_crossfade_target - _newvol) / (float)_crossfade_time)) * (float)deltaTimeInMillis; + _crossfade_time -= deltaTimeInMillis; + } else { + _crossfade = false; + _newvol = _crossfade_target; + } + } + + if (_pantrack || _volume != _newvol) + setVolume(_newvol); + + if (_sub) + _sub->process(_engine->_mixer->getSoundElapsedTime(_handle) / 100); + } + return false; +} + +void MusicNode::setVolume(uint8 new_volume) { + if (_pantrack) { + int cur_x = _engine->getScriptManager()->getStateValue(StateKey_ViewPos); + cur_x -= _pantrack_X; + int32 _width = _engine->getRenderManager()->getBkgSize().x; + if (cur_x < (-_width) / 2) + cur_x += _width; + else if (cur_x >= _width / 2) + cur_x -= _width; + + float norm = (float)cur_x / ((float)_width / 2.0); + float lvl = fabs(norm); + if (lvl > 0.5) + lvl = (lvl - 0.5) * 1.7; + else + lvl = 1.0; + + float bal = sin(-norm * 3.1415926) * 127.0; + + if (_engine->_mixer->isSoundHandleActive(_handle)) { + _engine->_mixer->setChannelBalance(_handle, bal); + _engine->_mixer->setChannelVolume(_handle, new_volume * lvl); + } + } else { + if (_engine->_mixer->isSoundHandleActive(_handle)) { + _engine->_mixer->setChannelBalance(_handle, 0); + _engine->_mixer->setChannelVolume(_handle, new_volume); + } + } + + _volume = new_volume; +} + +PanTrackNode::PanTrackNode(ZVision *engine, uint32 key, uint32 slot, int16 pos) + : SideFX(engine, key, SIDEFX_PANTRACK) { + _slot = slot; + + SideFX *fx = _engine->getScriptManager()->getSideFX(slot); + if (fx && fx->getType() == SIDEFX_AUDIO) { + MusicNode *mus = (MusicNode *)fx; + mus->setPanTrack(pos); + } +} + +PanTrackNode::~PanTrackNode() { + SideFX *fx = _engine->getScriptManager()->getSideFX(_slot); + if (fx && fx->getType() == SIDEFX_AUDIO) { + MusicNode *mus = (MusicNode *)fx; + mus->unsetPanTrack(); + } +} + +} // End of namespace ZVision diff --git a/engines/zvision/scripting/sidefx/music_node.h b/engines/zvision/scripting/sidefx/music_node.h new file mode 100644 index 0000000000..066b8f80f4 --- /dev/null +++ b/engines/zvision/scripting/sidefx/music_node.h @@ -0,0 +1,82 @@ +/* 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_MUSIC_NODE_H +#define ZVISION_MUSIC_NODE_H + +#include "audio/mixer.h" +#include "zvision/scripting/sidefx.h" +#include "zvision/subtitles/subtitles.h" + +namespace Common { +class String; +} + +namespace ZVision { +class MusicNode : public SideFX { +public: + MusicNode(ZVision *engine, uint32 key, Common::String &file, bool loop, int8 volume); + ~MusicNode(); + + /** + * 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 setVolume(uint8 volume); + + void setPanTrack(int16 pos); + void unsetPanTrack(); + + void setFade(int32 time, uint8 target); + +private: + int32 _timeLeft; + bool _pantrack; + int32 _pantrack_X; + int32 _attenuate; + uint8 _volume; + bool _loop; + bool _crossfade; + uint8 _crossfade_target; + int32 _crossfade_time; + bool _stereo; + Audio::SoundHandle _handle; + Subtitle *_sub; +}; + +class PanTrackNode : public SideFX { +public: + PanTrackNode(ZVision *engine, uint32 key, uint32 slot, int16 pos); + ~PanTrackNode(); + +private: + uint32 _slot; +}; + +} // End of namespace ZVision + +#endif diff --git a/engines/zvision/scripting/sidefx/syncsound_node.cpp b/engines/zvision/scripting/sidefx/syncsound_node.cpp new file mode 100644 index 0000000000..2bfdc349d1 --- /dev/null +++ b/engines/zvision/scripting/sidefx/syncsound_node.cpp @@ -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. + * + */ + +#include "common/scummsys.h" + +#include "zvision/scripting/sidefx/syncsound_node.h" + +#include "zvision/zvision.h" +#include "zvision/scripting/script_manager.h" +#include "zvision/graphics/render_manager.h" +#include "zvision/sound/zork_raw.h" + +#include "common/stream.h" +#include "common/file.h" +#include "audio/decoders/wave.h" + + +namespace ZVision { + +SyncSoundNode::SyncSoundNode(ZVision *engine, uint32 key, Common::String &filename, int32 syncto) + : SideFX(engine, key, SIDEFX_AUDIO) { + _syncto = syncto; + _sub = NULL; + + Audio::RewindableAudioStream *audioStream; + + if (filename.contains(".wav")) { + Common::File *file = new Common::File(); + if (_engine->getSearchManager()->openFile(*file, filename)) { + audioStream = Audio::makeWAVStream(file, DisposeAfterUse::YES); + } + } else { + audioStream = makeRawZorkStream(filename, _engine); + } + + _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, audioStream); + + Common::String subname = filename; + subname.setChar('s', subname.size() - 3); + subname.setChar('u', subname.size() - 2); + subname.setChar('b', subname.size() - 1); + + if (_engine->getSearchManager()->hasFile(subname)) + _sub = new Subtitle(_engine, subname); +} + +SyncSoundNode::~SyncSoundNode() { + _engine->_mixer->stopHandle(_handle); + if (_sub) + delete _sub; +} + +bool SyncSoundNode::process(uint32 deltaTimeInMillis) { + if (! _engine->_mixer->isSoundHandleActive(_handle)) + return stop(); + else { + + if (_engine->getScriptManager()->getSideFX(_syncto) == NULL) + return stop(); + + if (_sub) + _sub->process(_engine->_mixer->getSoundElapsedTime(_handle) / 100); + } + return false; +} + +} // End of namespace ZVision diff --git a/engines/zvision/scripting/sidefx/syncsound_node.h b/engines/zvision/scripting/sidefx/syncsound_node.h new file mode 100644 index 0000000000..c16ffebe7f --- /dev/null +++ b/engines/zvision/scripting/sidefx/syncsound_node.h @@ -0,0 +1,56 @@ +/* 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_SYNCSOUND_NODE_H +#define ZVISION_SYNCSOUND_NODE_H + +#include "audio/mixer.h" +#include "zvision/scripting/sidefx.h" +#include "zvision/subtitles/subtitles.h" + +namespace Common { +class String; +} + +namespace ZVision { +class SyncSoundNode : public SideFX { +public: + SyncSoundNode(ZVision *engine, uint32 key, Common::String &file, int32 syncto); + ~SyncSoundNode(); + + /** + * 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); +private: + int32 _syncto; + Audio::SoundHandle _handle; + Subtitle *_sub; +}; + +} // End of namespace ZVision + +#endif diff --git a/engines/zvision/scripting/controls/timer_node.cpp b/engines/zvision/scripting/sidefx/timer_node.cpp index e68610f537..6e71101acd 100644 --- a/engines/zvision/scripting/controls/timer_node.cpp +++ b/engines/zvision/scripting/sidefx/timer_node.cpp @@ -22,7 +22,7 @@ #include "common/scummsys.h" -#include "zvision/scripting/controls/timer_node.h" +#include "zvision/scripting/sidefx/timer_node.h" #include "zvision/zvision.h" #include "zvision/scripting/script_manager.h" diff --git a/engines/zvision/scripting/controls/timer_node.h b/engines/zvision/scripting/sidefx/timer_node.h index f6584becda..7a26aff251 100644 --- a/engines/zvision/scripting/controls/timer_node.h +++ b/engines/zvision/scripting/sidefx/timer_node.h @@ -23,7 +23,7 @@ #ifndef ZVISION_TIMER_NODE_H #define ZVISION_TIMER_NODE_H -#include "zvision/sidefx.h" +#include "zvision/scripting/sidefx.h" namespace ZVision { diff --git a/engines/zvision/scripting/sidefx/ttytext_node.cpp b/engines/zvision/scripting/sidefx/ttytext_node.cpp new file mode 100644 index 0000000000..68636eb422 --- /dev/null +++ b/engines/zvision/scripting/sidefx/ttytext_node.cpp @@ -0,0 +1,175 @@ +/* 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/sidefx/ttytext_node.h" + +#include "zvision/zvision.h" +#include "zvision/scripting/script_manager.h" +#include "zvision/graphics/render_manager.h" +#include "zvision/text/text.h" + +#include "common/stream.h" +#include "common/file.h" + + +namespace ZVision { + +ttyTextNode::ttyTextNode(ZVision *engine, uint32 key, const Common::String &file, const Common::Rect &r, int32 delay) : + SideFX(engine, key, SIDEFX_TTYTXT), + _fnt(engine) { + _delay = delay; + _r = r; + _txtpos = 0; + _nexttime = 0; + _dx = 0; + _dy = 0; + + Common::File *infile = _engine->getSearchManager()->openFile(file); + if (infile) { + while (!infile->eos()) { + Common::String asciiLine = readWideLine(*infile); + if (asciiLine.empty()) { + continue; + } + _txtbuf += asciiLine; + } + + delete infile; + } + _img.create(_r.width(), _r.height(), _engine->_pixelFormat); + _style.sharp = true; + _style.readAllStyle(_txtbuf); + _style.setFont(_fnt); + _engine->getScriptManager()->setStateValue(_key, 1); +} + +ttyTextNode::~ttyTextNode() { + _engine->getScriptManager()->setStateValue(_key, 2); + _img.free(); +} + +bool ttyTextNode::process(uint32 deltaTimeInMillis) { + _nexttime -= deltaTimeInMillis; + + if (_nexttime < 0) { + if (_txtpos < _txtbuf.size()) { + if (_txtbuf[_txtpos] == '<') { + int32 strt = _txtpos; + int32 endt = 0; + int16 ret = 0; + while (_txtbuf[_txtpos] != '>' && _txtpos < _txtbuf.size()) + _txtpos++; + endt = _txtpos; + if (strt != -1) + if ((endt - strt - 1) > 0) + ret = _style.parseStyle(_txtbuf.c_str() + strt + 1, endt - strt - 1); + + if (ret & (TXT_RET_FNTCHG | TXT_RET_FNTSTL | TXT_RET_NEWLN)) { + if (ret & TXT_RET_FNTCHG) + _style.setFont(_fnt); + if (ret & TXT_RET_FNTSTL) + _style.setFontStyle(_fnt); + + if (ret & TXT_RET_NEWLN) + newline(); + } + + if (ret & TXT_RET_HASSTBOX) { + Common::String buf; + buf.format("%d", _style.statebox); + + for (uint8 j = 0; j < buf.size(); j++) + outchar(buf[j]); + } + + _txtpos++; + } else { + int8 charsz = getUtf8CharSize(_txtbuf[_txtpos]); + + uint16 chr = readUtf8Char(_txtbuf.c_str() + _txtpos); + + if (chr == ' ') { + uint32 i = _txtpos + charsz; + uint16 width = _fnt.getCharWidth(chr); + + while (i < _txtbuf.size() && _txtbuf[i] != ' ' && _txtbuf[i] != '<') { + + int8 chsz = getUtf8CharSize(_txtbuf[i]); + uint16 uchr = readUtf8Char(_txtbuf.c_str() + _txtpos); + + width += _fnt.getCharWidth(uchr); + + i += chsz; + } + + if (_dx + width > _r.width()) + newline(); + else + outchar(chr); + } else + outchar(chr); + + _txtpos += charsz; + } + _nexttime = _delay; + _engine->getRenderManager()->blitSurfaceToBkg(_img, _r.left, _r.top); + } else + return stop(); + } + + return false; +} + +void ttyTextNode::scroll() { + int32 scrl = 0; + while (_dy - scrl > _r.height() - _fnt.getFontHeight()) + scrl += _fnt.getFontHeight(); + int8 *pixels = (int8 *)_img.getPixels(); + for (uint16 h = scrl; h < _img.h; h++) + memcpy(pixels + _img.pitch * (h - scrl), pixels + _img.pitch * h, _img.pitch); + + _img.fillRect(Common::Rect(0, _img.h - scrl, _img.w, _img.h), 0); + _dy -= scrl; +} + +void ttyTextNode::newline() { + _dy += _fnt.getFontHeight(); + _dx = 0; +} + +void ttyTextNode::outchar(uint16 chr) { + uint32 clr = _engine->_pixelFormat.RGBToColor(_style.red, _style.green, _style.blue); + + if (_dx + _fnt.getCharWidth(chr) > _r.width()) + newline(); + + if (_dy + _fnt.getFontHeight() >= _r.height()) + scroll(); + + _fnt.drawChar(&_img, chr, _dx, _dy, clr); + + _dx += _fnt.getCharWidth(chr); +} + +} // End of namespace ZVision diff --git a/engines/zvision/scripting/sidefx/ttytext_node.h b/engines/zvision/scripting/sidefx/ttytext_node.h new file mode 100644 index 0000000000..a6326c733b --- /dev/null +++ b/engines/zvision/scripting/sidefx/ttytext_node.h @@ -0,0 +1,76 @@ +/* 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_TTYTEXT_NODE_H +#define ZVISION_TTYTEXT_NODE_H + +#include "common/rect.h" +#include "graphics/surface.h" + +#include "zvision/scripting/sidefx.h" +#include "zvision/text/text.h" +#include "zvision/fonts/truetype_font.h" + +namespace Common { +class String; +} + +namespace ZVision { +class ttyTextNode : public SideFX { +public: + ttyTextNode(ZVision *engine, uint32 key, const Common::String &file, const Common::Rect &r, int32 delay); + ~ttyTextNode(); + + /** + * 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); +private: + Common::Rect _r; + //int16 x; + //int16 y; + //uint16 w; + //uint16 h; + cTxtStyle _style; + sTTFont _fnt; + Common::String _txtbuf; + uint32 _txtpos; + //int32 txtsize; + int32 _delay; + int32 _nexttime; + Graphics::Surface _img; + int16 _dx; + int16 _dy; +private: + + void newline(); + void scroll(); + void outchar(uint16 chr); +}; + +} // End of namespace ZVision + +#endif |