/* 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 > &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