Initial commit
This commit is contained in:
304
engines/zvision/scripting/controls/fist_control.cpp
Normal file
304
engines/zvision/scripting/controls/fist_control.cpp
Normal file
@@ -0,0 +1,304 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/file.h"
|
||||
#include "common/scummsys.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/system.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "video/video_decoder.h"
|
||||
#include "zvision/zvision.h"
|
||||
#include "zvision/graphics/render_manager.h"
|
||||
#include "zvision/graphics/cursors/cursor_manager.h"
|
||||
#include "zvision/scripting/script_manager.h"
|
||||
#include "zvision/scripting/controls/fist_control.h"
|
||||
#include "zvision/video/rlf_decoder.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;
|
||||
|
||||
_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();
|
||||
_engine->getScriptManager()->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(Common::Path(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();
|
||||
_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
|
||||
getParams(line, param, values);
|
||||
}
|
||||
}
|
||||
|
||||
FistControl::~FistControl() {
|
||||
if (_animation)
|
||||
delete _animation;
|
||||
|
||||
clearFistArray(_fistsUp);
|
||||
clearFistArray(_fistsDwn);
|
||||
_entries.clear();
|
||||
}
|
||||
|
||||
bool FistControl::process(uint32 deltaTimeInMillis) {
|
||||
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
|
||||
return false;
|
||||
|
||||
if (_animation && _animation->isPlaying()) {
|
||||
if (_animation->endOfVideo()) {
|
||||
_animation->stop();
|
||||
_engine->getScriptManager()->setStateValue(_animationId, 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_animation->needsUpdate()) {
|
||||
const Graphics::Surface *frameData = _animation->decodeNextFrame();
|
||||
if (frameData)
|
||||
// WORKAROUND: Ignore the target frame dimensions for the finger animations.
|
||||
// The target dimensions specify an area smaller than expected, thus if we
|
||||
// scale the finger videos to fit these dimensions, they are not aligned
|
||||
// correctly. Not scaling these videos yields a result identical to the
|
||||
// original. Fixes bug #6784.
|
||||
_engine->getRenderManager()->blitSurfaceToBkg(*frameData, _anmRect.left, _anmRect.top);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
if (_animation) {
|
||||
_animation->stop();
|
||||
_animation->seekToFrame(_entries[i]._anmStrt);
|
||||
_animation->setEndFrame(_entries[i]._anmEnd);
|
||||
_animation->start();
|
||||
}
|
||||
|
||||
_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::Path &fileName) {
|
||||
Common::File file;
|
||||
if (!file.open(fileName)) {
|
||||
warning("Desc file %s could could be opened", fileName.toString().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 = _engine->loadAnimation(Common::Path(values));
|
||||
} else if (param.matchString("anim_rect", true)) {
|
||||
int left, top, right, bottom;
|
||||
if (sscanf(values.c_str(), "%d %d %d %d", &left, &top, &right, &bottom) == 4)
|
||||
_anmRect = Common::Rect(left, top, right, bottom);
|
||||
} else if (param.matchString("num_fingers", true)) {
|
||||
if (sscanf(values.c_str(), "%d", &_fistnum) == 1) {
|
||||
_fistsUp.resize(_fistnum);
|
||||
_fistsDwn.resize(_fistnum);
|
||||
}
|
||||
} else if (param.matchString("entries", true)) {
|
||||
if (sscanf(values.c_str(), "%d", &_numEntries) == 1)
|
||||
_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());
|
||||
|
||||
if (sscanf(param.c_str(), "up_hs_num_%d", &fist) == 1)
|
||||
_fistsUp[fist].resize(num);
|
||||
} else if (param.matchString("up_hs_*", true)) {
|
||||
int16 fist, box, x1, y1, x2, y2;
|
||||
if (sscanf(param.c_str(), "up_hs_%hd_%hd", &fist, &box) == 2) {
|
||||
if (sscanf(values.c_str(), "%hd %hd %hd %hd", &x1, &y1, &x2, &y2) == 4)
|
||||
(_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());
|
||||
|
||||
if (sscanf(param.c_str(), "down_hs_num_%d", &fist) == 1)
|
||||
_fistsDwn[fist].resize(num);
|
||||
} else if (param.matchString("down_hs_*", true)) {
|
||||
int16 fist, box, x1, y1, x2, y2;
|
||||
if (sscanf(param.c_str(), "down_hs_%hd_%hd", &fist, &box) == 2) {
|
||||
if (sscanf(values.c_str(), "%hd %hd %hd %hd", &x1, &y1, &x2, &y2) == 4)
|
||||
(_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 ¶meter, 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
|
||||
82
engines/zvision/scripting/controls/fist_control.h
Normal file
82
engines/zvision/scripting/controls/fist_control.h
Normal file
@@ -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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ZVISION_FIST_CONTROL_H
|
||||
#define ZVISION_FIST_CONTROL_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/rect.h"
|
||||
#include "zvision/scripting/control.h"
|
||||
|
||||
namespace Video {
|
||||
class VideoDecoder;
|
||||
}
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
// Only used in Zork Nemesis, handles the door lock puzzle with the skeletal fingers (td9e)
|
||||
class FistControl : public Control {
|
||||
public:
|
||||
FistControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
|
||||
~FistControl() override;
|
||||
|
||||
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;
|
||||
|
||||
Video::VideoDecoder *_animation;
|
||||
Common::Rect _anmRect;
|
||||
int32 _soundKey;
|
||||
int32 _animationId;
|
||||
|
||||
public:
|
||||
bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) override;
|
||||
bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) override;
|
||||
bool process(uint32 deltaTimeInMillis) override;
|
||||
|
||||
private:
|
||||
void readDescFile(const Common::Path &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 ¶meter, Common::String &values);
|
||||
};
|
||||
|
||||
} // End of namespace ZVision
|
||||
|
||||
#endif
|
||||
184
engines/zvision/scripting/controls/hotmov_control.cpp
Normal file
184
engines/zvision/scripting/controls/hotmov_control.cpp
Normal file
@@ -0,0 +1,184 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/file.h"
|
||||
#include "common/scummsys.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/system.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "video/video_decoder.h"
|
||||
#include "zvision/zvision.h"
|
||||
#include "zvision/graphics/render_manager.h"
|
||||
#include "zvision/graphics/cursors/cursor_manager.h"
|
||||
#include "zvision/scripting/script_manager.h"
|
||||
#include "zvision/scripting/controls/hotmov_control.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
HotMovControl::HotMovControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
|
||||
: Control(engine, key, CONTROL_HOTMOV) {
|
||||
_animation = NULL;
|
||||
_cycle = 0;
|
||||
_frames.clear();
|
||||
_cyclesCount = 0;
|
||||
_framesCount = 0;
|
||||
|
||||
_engine->getScriptManager()->setStateValue(_key, 0);
|
||||
|
||||
// Loop until we find the closing brace
|
||||
Common::String line = stream.readLine();
|
||||
_engine->getScriptManager()->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(Common::Path(values));
|
||||
} else if (param.matchString("rectangle", true)) {
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
if (sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height) == 4)
|
||||
_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];
|
||||
if (sscanf(values.c_str(), "%s", filename) == 1) {
|
||||
values = Common::String(filename);
|
||||
_animation = _engine->loadAnimation(Common::Path(values));
|
||||
_animation->start();
|
||||
}
|
||||
} else if (param.matchString("venus_id", true)) {
|
||||
_venusId = atoi(values.c_str());
|
||||
}
|
||||
|
||||
line = stream.readLine();
|
||||
_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
|
||||
getParams(line, param, values);
|
||||
}
|
||||
}
|
||||
|
||||
HotMovControl::~HotMovControl() {
|
||||
if (_animation)
|
||||
delete _animation;
|
||||
|
||||
_frames.clear();
|
||||
}
|
||||
|
||||
bool HotMovControl::process(uint32 deltaTimeInMillis) {
|
||||
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
|
||||
return false;
|
||||
|
||||
if (_cycle < _cyclesCount) {
|
||||
if (_animation && _animation->endOfVideo()) {
|
||||
_cycle++;
|
||||
|
||||
if (_cycle == _cyclesCount) {
|
||||
_engine->getScriptManager()->setStateValue(_key, 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
_animation->rewind();
|
||||
}
|
||||
|
||||
if (_animation && _animation->needsUpdate()) {
|
||||
const Graphics::Surface *frameData = _animation->decodeNextFrame();
|
||||
if (frameData)
|
||||
_engine->getRenderManager()->blitSurfaceToBkgScaled(*frameData, _rectangle);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HotMovControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
|
||||
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
|
||||
return false;
|
||||
|
||||
if (!_animation)
|
||||
return false;
|
||||
|
||||
if (_cycle < _cyclesCount) {
|
||||
if (_frames[_animation->getCurFrame()].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 (!_animation)
|
||||
return false;
|
||||
|
||||
if (_cycle < _cyclesCount) {
|
||||
if (_frames[_animation->getCurFrame()].contains(backgroundImageSpacePos)) {
|
||||
setVenus();
|
||||
_engine->getScriptManager()->setStateValue(_key, 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void HotMovControl::readHsFile(const Common::Path &fileName) {
|
||||
if (_framesCount == 0)
|
||||
return;
|
||||
|
||||
Common::File file;
|
||||
if (!file.open(fileName)) {
|
||||
warning("HS file %s could could be opened", fileName.toString().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;
|
||||
|
||||
if (sscanf(line.c_str(), "%d:%d %d %d %d~", &frame, &x, &y, &width, &height) == 5) {
|
||||
if (frame >= 0 && frame < _framesCount)
|
||||
_frames[frame] = Common::Rect(x, y, width, height);
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
} // End of namespace ZVision
|
||||
60
engines/zvision/scripting/controls/hotmov_control.h
Normal file
60
engines/zvision/scripting/controls/hotmov_control.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ZVISION_HOTMOV_CONTROL_H
|
||||
#define ZVISION_HOTMOV_CONTROL_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/path.h"
|
||||
#include "common/rect.h"
|
||||
#include "zvision/scripting/control.h"
|
||||
|
||||
namespace Video {
|
||||
class VideoDecoder;
|
||||
}
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
// Only used in Zork Nemesis, handles movies where the player needs to click on something (mj7g, vw3g)
|
||||
class HotMovControl : public Control {
|
||||
public:
|
||||
HotMovControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
|
||||
~HotMovControl() override;
|
||||
|
||||
private:
|
||||
int32 _framesCount;
|
||||
int32 _cycle;
|
||||
int32 _cyclesCount;
|
||||
Video::VideoDecoder *_animation;
|
||||
Common::Rect _rectangle;
|
||||
Common::Array<Common::Rect> _frames;
|
||||
public:
|
||||
bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) override;
|
||||
bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) override;
|
||||
bool process(uint32 deltaTimeInMillis) override;
|
||||
|
||||
private:
|
||||
void readHsFile(const Common::Path &fileName);
|
||||
};
|
||||
|
||||
} // End of namespace ZVision
|
||||
|
||||
#endif
|
||||
271
engines/zvision/scripting/controls/input_control.cpp
Normal file
271
engines/zvision/scripting/controls/input_control.cpp
Normal file
@@ -0,0 +1,271 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "backends/keymapper/keymap.h"
|
||||
#include "common/rect.h"
|
||||
#include "common/scummsys.h"
|
||||
#include "common/str.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/system.h"
|
||||
#include "video/video_decoder.h"
|
||||
#include "zvision/zvision.h"
|
||||
#include "zvision/graphics/render_manager.h"
|
||||
#include "zvision/graphics/cursors/cursor_manager.h"
|
||||
#include "zvision/scripting/script_manager.h"
|
||||
#include "zvision/scripting/controls/input_control.h"
|
||||
#include "zvision/text/string_manager.h"
|
||||
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
InputControl::InputControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
|
||||
: Control(engine, key, CONTROL_INPUT),
|
||||
_background(0),
|
||||
_nextTabstop(0),
|
||||
_focused(false),
|
||||
_textChanged(false),
|
||||
_enterPressed(false),
|
||||
_readOnly(false),
|
||||
_txtWidth(0),
|
||||
_animation(NULL) {
|
||||
// Loop until we find the closing brace
|
||||
Common::String line = stream.readLine();
|
||||
_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
|
||||
Common::String param;
|
||||
Common::String values;
|
||||
getParams(line, param, values);
|
||||
|
||||
while (!stream.eos() && !line.contains('}')) {
|
||||
if (param.matchString("rectangle", true)) {
|
||||
int x1, y1, x2, y2;
|
||||
if (sscanf(values.c_str(), "%d %d %d %d", &x1, &y1, &x2, &y2) == 4)
|
||||
_textRectangle = Common::Rect(x1, y1, x2, y2);
|
||||
} else if (param.matchString("aux_hotspot", true)) {
|
||||
int x1, y1, x2, y2;
|
||||
if (sscanf(values.c_str(), "%d %d %d %d", &x1, &y1, &x2, &y2) == 4)
|
||||
_headerRectangle = Common::Rect(x1, y1, x2, y2);
|
||||
} else if (param.matchString("string_init", true)) {
|
||||
uint fontFormatNumber;
|
||||
if (sscanf(values.c_str(), "%u", &fontFormatNumber) == 1)
|
||||
_stringInit.readAllStyles(_engine->getStringManager()->getTextLine(fontFormatNumber));
|
||||
} else if (param.matchString("chooser_init_string", true)) {
|
||||
uint fontFormatNumber;
|
||||
if (sscanf(values.c_str(), "%u", &fontFormatNumber) == 1)
|
||||
_stringChooserInit.readAllStyles(_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 (param.matchString("cursor_animation_frames", true)) {
|
||||
// Ignore, use the frame count in the animation file
|
||||
} else if (param.matchString("cursor_animation", true)) {
|
||||
char fileName[25];
|
||||
if (sscanf(values.c_str(), "%24s %*u", fileName) == 1) {
|
||||
_animation = _engine->loadAnimation(fileName);
|
||||
_animation->start();
|
||||
}
|
||||
} 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();
|
||||
_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
|
||||
getParams(line, param, values);
|
||||
}
|
||||
|
||||
_maxTxtWidth = _textRectangle.width();
|
||||
if (_animation)
|
||||
_maxTxtWidth -= _animation->getWidth();
|
||||
}
|
||||
|
||||
InputControl::~InputControl() {
|
||||
_background->free();
|
||||
delete _background;
|
||||
unfocus();
|
||||
}
|
||||
|
||||
void InputControl::focus() {
|
||||
if (!_readOnly) {
|
||||
_engine->getGameKeymap()->setEnabled(false);
|
||||
}
|
||||
_focused = true;
|
||||
_textChanged = true;
|
||||
}
|
||||
|
||||
void InputControl::unfocus() {
|
||||
if (!_readOnly) {
|
||||
_engine->getGameKeymap()->setEnabled(true);
|
||||
}
|
||||
_focused = false;
|
||||
_textChanged = true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool InputControl::onKeyDown(Common::KeyState keyState) {
|
||||
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
|
||||
return false;
|
||||
|
||||
if (!_focused) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keyState.keycode == Common::KEYCODE_BACKSPACE) {
|
||||
if (!_readOnly) {
|
||||
_currentInputText.deleteLastChar();
|
||||
_textChanged = true;
|
||||
}
|
||||
} else if (keyState.keycode == Common::KEYCODE_RETURN) {
|
||||
_enterPressed = true;
|
||||
} else if (keyState.keycode == Common::KEYCODE_TAB) {
|
||||
unfocus();
|
||||
// Focus the next input control
|
||||
_engine->getScriptManager()->focusControl(_nextTabstop);
|
||||
// Don't process this event for other controls
|
||||
return true;
|
||||
} else {
|
||||
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 (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
|
||||
return false;
|
||||
|
||||
if (!_background) {
|
||||
_background = _engine->getRenderManager()->getBkgRect(_textRectangle);
|
||||
}
|
||||
|
||||
// First see if we need to render the text
|
||||
if (_textChanged) {
|
||||
// Blit the text using the RenderManager
|
||||
|
||||
Graphics::Surface txt;
|
||||
txt.copyFrom(*_background);
|
||||
|
||||
int32 oldTxtWidth = _txtWidth;
|
||||
|
||||
if (!_readOnly || !_focused)
|
||||
_txtWidth = _engine->getTextRenderer()->drawText(_currentInputText, _stringInit, txt);
|
||||
else
|
||||
_txtWidth = _engine->getTextRenderer()->drawText(_currentInputText, _stringChooserInit, txt);
|
||||
|
||||
if (_readOnly || _txtWidth <= _maxTxtWidth)
|
||||
_engine->getRenderManager()->blitSurfaceToBkg(txt, _textRectangle.left, _textRectangle.top);
|
||||
else {
|
||||
// Assume the last character caused the overflow.
|
||||
_currentInputText.deleteLastChar();
|
||||
_txtWidth = oldTxtWidth;
|
||||
}
|
||||
|
||||
txt.free();
|
||||
}
|
||||
|
||||
if (_animation && !_readOnly && _focused) {
|
||||
if (_animation->endOfVideo())
|
||||
_animation->rewind();
|
||||
|
||||
if (_animation->needsUpdate()) {
|
||||
const Graphics::Surface *srf = _animation->decodeNextFrame();
|
||||
int16 xx = _textRectangle.left + _txtWidth;
|
||||
if (xx >= _textRectangle.left + (_textRectangle.width() - (int16)_animation->getWidth()))
|
||||
xx = _textRectangle.left + _textRectangle.width() - (int16)_animation->getWidth();
|
||||
_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
|
||||
74
engines/zvision/scripting/controls/input_control.h
Normal file
74
engines/zvision/scripting/controls/input_control.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ZVISION_INPUT_CONTROL_H
|
||||
#define ZVISION_INPUT_CONTROL_H
|
||||
|
||||
#include "common/rect.h"
|
||||
#include "zvision/scripting/control.h"
|
||||
#include "zvision/text/string_manager.h"
|
||||
#include "zvision/text/text.h"
|
||||
|
||||
namespace Video {
|
||||
class VideoDecoder;
|
||||
}
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
class InputControl : public Control {
|
||||
public:
|
||||
InputControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
|
||||
~InputControl() override;
|
||||
|
||||
private:
|
||||
Graphics::Surface *_background;
|
||||
Common::Rect _textRectangle;
|
||||
Common::Rect _headerRectangle;
|
||||
TextStyleState _stringInit;
|
||||
TextStyleState _stringChooserInit;
|
||||
uint32 _nextTabstop;
|
||||
bool _focused;
|
||||
|
||||
Common::String _currentInputText;
|
||||
bool _textChanged;
|
||||
bool _enterPressed;
|
||||
bool _readOnly;
|
||||
|
||||
int16 _txtWidth;
|
||||
int16 _maxTxtWidth;
|
||||
Video::VideoDecoder *_animation;
|
||||
|
||||
public:
|
||||
void focus() override;
|
||||
void unfocus() override;
|
||||
bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) override;
|
||||
bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) override;
|
||||
bool onKeyDown(Common::KeyState keyState) override;
|
||||
bool process(uint32 deltaTimeInMillis) override;
|
||||
void setText(const Common::String &_str);
|
||||
const Common::String getText();
|
||||
bool enterPress();
|
||||
void setReadOnly(bool);
|
||||
};
|
||||
|
||||
} // End of namespace ZVision
|
||||
|
||||
#endif
|
||||
352
engines/zvision/scripting/controls/lever_control.cpp
Normal file
352
engines/zvision/scripting/controls/lever_control.cpp
Normal file
@@ -0,0 +1,352 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/file.h"
|
||||
#include "common/scummsys.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/system.h"
|
||||
#include "common/tokenizer.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "video/video_decoder.h"
|
||||
#include "zvision/zvision.h"
|
||||
#include "zvision/graphics/render_manager.h"
|
||||
#include "zvision/graphics/cursors/cursor_manager.h"
|
||||
#include "zvision/scripting/script_manager.h"
|
||||
#include "zvision/scripting/controls/lever_control.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
LeverControl::LeverControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
|
||||
: Control(engine, key, CONTROL_LEVER),
|
||||
_frameInfo(0),
|
||||
_frameCount(0),
|
||||
_startFrame(0),
|
||||
_currentFrame(0),
|
||||
_lastRenderedFrame(0),
|
||||
_mouseIsCaptured(false),
|
||||
_isReturning(false),
|
||||
_accumulatedTime(0),
|
||||
_returnRoutesCurrentFrame(0),
|
||||
_animation(NULL),
|
||||
_cursor(CursorIndex_Active),
|
||||
_mirrored(false) {
|
||||
|
||||
// Loop until we find the closing brace
|
||||
Common::String line = stream.readLine();
|
||||
_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
|
||||
|
||||
Common::String param;
|
||||
Common::String values;
|
||||
getParams(line, param, values);
|
||||
|
||||
while (!stream.eos() && !line.contains('}')) {
|
||||
if (param.matchString("descfile", true)) {
|
||||
char levFileName[25];
|
||||
if (sscanf(values.c_str(), "%24s", levFileName) == 1)
|
||||
parseLevFile(levFileName);
|
||||
} else if (param.matchString("cursor", true)) {
|
||||
char cursorName[25];
|
||||
if (sscanf(values.c_str(), "%24s", cursorName) == 1)
|
||||
_cursor = _engine->getCursorManager()->getCursorId(Common::String(cursorName));
|
||||
}
|
||||
|
||||
line = stream.readLine();
|
||||
_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
|
||||
getParams(line, param, values);
|
||||
}
|
||||
|
||||
renderFrame(_currentFrame);
|
||||
}
|
||||
|
||||
LeverControl::~LeverControl() {
|
||||
if (_animation)
|
||||
delete _animation;
|
||||
|
||||
delete[] _frameInfo;
|
||||
}
|
||||
|
||||
void LeverControl::parseLevFile(const Common::Path &fileName) {
|
||||
debugC(2, kDebugControl, "LeverControl::parseLevFile(%s)", fileName.toString().c_str());
|
||||
Common::File file;
|
||||
if (!file.open(fileName)) {
|
||||
warning("LEV file %s could could be opened", fileName.toString().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
Common::String line;
|
||||
Common::String param;
|
||||
Common::String values;
|
||||
|
||||
int id = 0;
|
||||
|
||||
while (!file.eos()) {
|
||||
line = file.readLine();
|
||||
getLevParams(line, param, values);
|
||||
|
||||
if (param.matchString("animation_id", true)) {
|
||||
sscanf(values.c_str(), "%d", &id);
|
||||
debugC(2, kDebugControl, "Lever animation ID: %d", id);
|
||||
} else if (param.matchString("filename", true)) {
|
||||
_animation = _engine->loadAnimation(Common::Path(values));
|
||||
} else if (param.matchString("skipcolor", true)) {
|
||||
// Not used
|
||||
} else if (param.matchString("anim_coords", true)) {
|
||||
int left, top, right, bottom;
|
||||
if (sscanf(values.c_str(), "%d %d %d %d", &left, &top, &right, &bottom) == 4) {
|
||||
_animationCoords.left = left;
|
||||
_animationCoords.top = top;
|
||||
_animationCoords.right = right;
|
||||
_animationCoords.bottom = bottom;
|
||||
}
|
||||
} else if (param.matchString("mirrored", true)) {
|
||||
uint mirrored;
|
||||
if (sscanf(values.c_str(), "%u", &mirrored) == 1)
|
||||
_mirrored = mirrored == 0 ? false : true;
|
||||
} else if (param.matchString("frames", true)) {
|
||||
if (sscanf(values.c_str(), "%u", &_frameCount) == 1)
|
||||
_frameInfo = new FrameInfo[_frameCount];
|
||||
} else if (param.matchString("elsewhere", true)) {
|
||||
// Not used
|
||||
} else if (param.matchString("out_of_control", true)) {
|
||||
// Not used
|
||||
} else if (param.matchString("start_pos", true)) {
|
||||
if (sscanf(values.c_str(), "%u", &_startFrame) == 1)
|
||||
_currentFrame = _startFrame;
|
||||
} else if (param.matchString("hotspot_deltas", true)) {
|
||||
uint x;
|
||||
uint y;
|
||||
if (sscanf(values.c_str(), "%u %u", &x, &y) == 2) {
|
||||
_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;
|
||||
_frameInfo[frameNumber].hotspot.right = x + _hotspotDelta.x;
|
||||
_frameInfo[frameNumber].hotspot.bottom = y + _hotspotDelta.y;
|
||||
}
|
||||
|
||||
Common::StringTokenizer tokenizer(line, " ^=()~");
|
||||
tokenizer.nextToken();
|
||||
tokenizer.nextToken();
|
||||
|
||||
Common::String token = tokenizer.nextToken();
|
||||
while (!tokenizer.empty()) {
|
||||
if (token == "d") {
|
||||
token = tokenizer.nextToken();
|
||||
|
||||
uint angle;
|
||||
uint toFrame;
|
||||
if (sscanf(token.c_str(), "%u,%u", &toFrame, &angle) == 2)
|
||||
_frameInfo[frameNumber].paths.push_back(PathSegment(angle, toFrame));
|
||||
} else if (token.hasPrefix("p")) {
|
||||
// Format: P(<from> to <to>)
|
||||
tokenizer.nextToken();
|
||||
tokenizer.nextToken();
|
||||
token = tokenizer.nextToken();
|
||||
uint to = atoi(token.c_str());
|
||||
|
||||
_frameInfo[frameNumber].returnRoute.push_back(to);
|
||||
}
|
||||
|
||||
token = tokenizer.nextToken();
|
||||
}
|
||||
}
|
||||
|
||||
// Don't read lines in this place because last will not be parsed.
|
||||
}
|
||||
// WORKAROUND for a script bug in Zork: Nemesis, room tz2e (orrery)
|
||||
// Animation coordinates for left hand lever do not properly align with background image
|
||||
switch (id) {
|
||||
case 2926:
|
||||
_animationCoords.bottom -= 4;
|
||||
_animationCoords.right += 1;
|
||||
_animationCoords.left -= 1;
|
||||
_animationCoords.top += 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Cycle through all unit direction vectors in path segments & determine step distance
|
||||
debugC(3, kDebugControl, "Setting step distances");
|
||||
for (uint frame=0; frame < _frameCount; frame++) {
|
||||
debugC(3, kDebugControl, "Frame %d", frame);
|
||||
for (auto &iter : _frameInfo[frame].paths) {
|
||||
uint destFrame = iter.toFrame;
|
||||
Common::Point deltaPos = _frameInfo[destFrame].hotspot.origin() - _frameInfo[frame].hotspot.origin();
|
||||
Math::Vector2d deltaPosVector((float)deltaPos.x, (float)deltaPos.y);
|
||||
iter.distance *= deltaPosVector.getMagnitude();
|
||||
debugC(3, kDebugControl, "\tdeltaPos = %d,%d, Distance %f", deltaPos.x, deltaPos.y, iter.distance);
|
||||
}
|
||||
}
|
||||
debugC(2, kDebugControl, "LeverControl::~parseLevFile()");
|
||||
}
|
||||
|
||||
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;
|
||||
_gripOffset = backgroundImageSpacePos - _frameInfo[_currentFrame].hotspot.origin();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LeverControl::onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
|
||||
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
|
||||
return false;
|
||||
|
||||
if (_mouseIsCaptured) {
|
||||
_mouseIsCaptured = false;
|
||||
_engine->getScriptManager()->setStateValue(_key, _currentFrame);
|
||||
|
||||
_isReturning = true;
|
||||
_returnRoutesCurrentProgress = _frameInfo[_currentFrame].returnRoute.begin();
|
||||
_returnRoutesCurrentFrame = _currentFrame;
|
||||
}
|
||||
_gripOffset = Common::Point(0,0);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LeverControl::onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) {
|
||||
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
|
||||
return false;
|
||||
|
||||
bool cursorWasChanged = false;
|
||||
|
||||
if (_mouseIsCaptured) {
|
||||
uint nextFrame = _currentFrame;
|
||||
do {
|
||||
Common::Point gripOrigin = _frameInfo[_currentFrame].hotspot.origin() + _gripOffset;
|
||||
debugC(1, kDebugControl, "LeverControl::onMouseMove() screenPos = %d,%d, imagePos = %d,%d, gripOrigin = %d,%d", screenSpacePos.x, screenSpacePos.y, backgroundImageSpacePos.x, backgroundImageSpacePos.y, gripOrigin.x, gripOrigin.y);
|
||||
Common::Point deltaPos = backgroundImageSpacePos - gripOrigin;
|
||||
nextFrame = getNextFrame(deltaPos);
|
||||
if (nextFrame != _currentFrame) {
|
||||
_currentFrame = nextFrame;
|
||||
_engine->getScriptManager()->setStateValue(_key, _currentFrame);
|
||||
}
|
||||
} while (nextFrame != _currentFrame);
|
||||
|
||||
if (_lastRenderedFrame != _currentFrame)
|
||||
renderFrame(_currentFrame);
|
||||
|
||||
_engine->getCursorManager()->changeCursor(_cursor);
|
||||
cursorWasChanged = true;
|
||||
} else if (_frameInfo[_currentFrame].hotspot.contains(backgroundImageSpacePos)) {
|
||||
_engine->getCursorManager()->changeCursor(_cursor);
|
||||
cursorWasChanged = true;
|
||||
}
|
||||
return cursorWasChanged;
|
||||
}
|
||||
|
||||
uint LeverControl::getNextFrame(Common::Point &deltaPos) {
|
||||
Math::Vector2d movement((float)deltaPos.x, (float)deltaPos.y);
|
||||
for (auto &iter : _frameInfo[_currentFrame].paths) {
|
||||
debugC(1, kDebugControl, "\tPossible step = %f,%f, angle = %d, distance %f", iter.direction.getX(), iter.direction.getY(), (uint)Math::rad2deg(iter.angle), iter.distance);
|
||||
if (movement.dotProduct(iter.direction) >= iter.distance/2) {
|
||||
return iter.toFrame;
|
||||
}
|
||||
}
|
||||
return _currentFrame;
|
||||
}
|
||||
|
||||
bool LeverControl::process(uint32 deltaTimeInMillis) {
|
||||
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
|
||||
return false;
|
||||
|
||||
if (_isReturning) {
|
||||
_accumulatedTime += deltaTimeInMillis;
|
||||
while (_accumulatedTime >= _returnFramePeriod) {
|
||||
_accumulatedTime -= _returnFramePeriod;
|
||||
if (_returnRoutesCurrentFrame == *_returnRoutesCurrentProgress) {
|
||||
_returnRoutesCurrentProgress++;
|
||||
}
|
||||
if (_returnRoutesCurrentProgress == _frameInfo[_currentFrame].returnRoute.end()) {
|
||||
_isReturning = false;
|
||||
_currentFrame = _returnRoutesCurrentFrame;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint toFrame = *_returnRoutesCurrentProgress;
|
||||
if (_returnRoutesCurrentFrame < toFrame) {
|
||||
_returnRoutesCurrentFrame++;
|
||||
} else if (_returnRoutesCurrentFrame > toFrame) {
|
||||
_returnRoutesCurrentFrame--;
|
||||
}
|
||||
|
||||
_engine->getScriptManager()->setStateValue(_key, _returnRoutesCurrentFrame);
|
||||
renderFrame(_returnRoutesCurrentFrame);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LeverControl::renderFrame(uint frameNumber) {
|
||||
_lastRenderedFrame = frameNumber;
|
||||
if (frameNumber != 0 && frameNumber < _lastRenderedFrame && _mirrored)
|
||||
frameNumber = (_frameCount * 2) - frameNumber - 1;
|
||||
|
||||
const Graphics::Surface *frameData;
|
||||
|
||||
_animation->seekToFrame(frameNumber);
|
||||
frameData = _animation->decodeNextFrame();
|
||||
if (frameData)
|
||||
_engine->getRenderManager()->blitSurfaceToBkgScaled(*frameData, _animationCoords);
|
||||
}
|
||||
|
||||
void LeverControl::getLevParams(const Common::String &inputStr, Common::String ¶meter, 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
|
||||
96
engines/zvision/scripting/controls/lever_control.h
Normal file
96
engines/zvision/scripting/controls/lever_control.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ZVISION_LEVER_CONTROL_H
|
||||
#define ZVISION_LEVER_CONTROL_H
|
||||
|
||||
#include "common/list.h"
|
||||
#include "common/path.h"
|
||||
#include "common/rect.h"
|
||||
#include "math/vector2d.h"
|
||||
#include "zvision/scripting/control.h"
|
||||
|
||||
namespace Video {
|
||||
class VideoDecoder;
|
||||
}
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
// Only used in Zork Nemesis, handles draggable levers (te2e, tm7e, tp2e, tt2e, tz2e)
|
||||
class LeverControl : public Control {
|
||||
public:
|
||||
LeverControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
|
||||
~LeverControl() override;
|
||||
|
||||
private:
|
||||
|
||||
struct PathSegment {
|
||||
PathSegment(uint a, uint t) : angle(Math::deg2rad<float>(a)), toFrame(t), direction(cos(angle), -sin(angle)) {}
|
||||
|
||||
float angle; // Radians
|
||||
uint toFrame;
|
||||
Math::Vector2d direction; // NB unit vector upon initialisation
|
||||
float distance = 1.0f;
|
||||
};
|
||||
|
||||
struct FrameInfo {
|
||||
Common::Rect hotspot;
|
||||
Common::List<PathSegment> paths;
|
||||
Common::List<uint> returnRoute;
|
||||
};
|
||||
|
||||
private:
|
||||
Video::VideoDecoder *_animation;
|
||||
|
||||
int _cursor;
|
||||
Common::Rect _animationCoords;
|
||||
bool _mirrored;
|
||||
uint _frameCount;
|
||||
uint _startFrame;
|
||||
Common::Point _hotspotDelta;
|
||||
FrameInfo *_frameInfo;
|
||||
|
||||
uint _currentFrame;
|
||||
uint _lastRenderedFrame;
|
||||
bool _mouseIsCaptured;
|
||||
bool _isReturning;
|
||||
Common::Point _gripOffset;
|
||||
Common::List<uint>::iterator _returnRoutesCurrentProgress;
|
||||
uint _returnRoutesCurrentFrame;
|
||||
const uint8 _returnFramePeriod = 60; // milliseconds
|
||||
uint32 _accumulatedTime;
|
||||
|
||||
public:
|
||||
bool onMouseDown(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) override;
|
||||
bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) override;
|
||||
bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) override;
|
||||
bool process(uint32 deltaTimeInMillis) override;
|
||||
|
||||
private:
|
||||
void parseLevFile(const Common::Path &fileName);
|
||||
void renderFrame(uint frameNumber);
|
||||
void getLevParams(const Common::String &inputStr, Common::String ¶meter, Common::String &values);
|
||||
uint getNextFrame(Common::Point &deltaPos);
|
||||
};
|
||||
|
||||
} // End of namespace ZVision
|
||||
|
||||
#endif
|
||||
216
engines/zvision/scripting/controls/paint_control.cpp
Normal file
216
engines/zvision/scripting/controls/paint_control.cpp
Normal file
@@ -0,0 +1,216 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/stream.h"
|
||||
#include "zvision/zvision.h"
|
||||
#include "zvision/graphics/cursors/cursor_manager.h"
|
||||
#include "zvision/graphics/render_manager.h"
|
||||
#include "zvision/scripting/script_manager.h"
|
||||
#include "zvision/scripting/controls/paint_control.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();
|
||||
_engine->getScriptManager()->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;
|
||||
|
||||
if (sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height) == 4)
|
||||
_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(Common::Path(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(Common::Path(values), false);
|
||||
} else if (param.matchString("eligible_objects", true)) {
|
||||
char buf[256];
|
||||
memset(buf, 0, 256);
|
||||
strncpy(buf, values.c_str(), 255);
|
||||
|
||||
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();
|
||||
_engine->getScriptManager()->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) {
|
||||
_paint->free();
|
||||
delete _paint;
|
||||
}
|
||||
if (_brush) {
|
||||
_brush->free();
|
||||
delete _brush;
|
||||
}
|
||||
if (_bkg) {
|
||||
_bkg->free();
|
||||
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
|
||||
89
engines/zvision/scripting/controls/paint_control.h
Normal file
89
engines/zvision/scripting/controls/paint_control.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ZVISION_PAINT_CONTROL_H
|
||||
#define ZVISION_PAINT_CONTROL_H
|
||||
|
||||
#include "common/list.h"
|
||||
#include "common/rect.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "zvision/scripting/control.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
// Only used in Zork Nemesis, handles the painting puzzle screen in Lucien's room in Irondune (ch4g)
|
||||
class PaintControl : public Control {
|
||||
public:
|
||||
PaintControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
|
||||
~PaintControl() override;
|
||||
|
||||
/**
|
||||
* @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) override;
|
||||
|
||||
/**
|
||||
* @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) override;
|
||||
/**
|
||||
* 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) override;
|
||||
|
||||
bool process(uint32 deltaTimeInMillis) override {
|
||||
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
|
||||
142
engines/zvision/scripting/controls/push_toggle_control.cpp
Normal file
142
engines/zvision/scripting/controls/push_toggle_control.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/stream.h"
|
||||
#include "zvision/zvision.h"
|
||||
#include "zvision/graphics/cursors/cursor_manager.h"
|
||||
#include "zvision/scripting/script_manager.h"
|
||||
#include "zvision/scripting/controls/push_toggle_control.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
PushToggleControl::PushToggleControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
|
||||
: Control(engine, key, CONTROL_PUSHTGL),
|
||||
_countTo(2),
|
||||
_cursor(CursorIndex_Active),
|
||||
_event(Common::EVENT_LBUTTONUP) {
|
||||
|
||||
_hotspots.clear();
|
||||
|
||||
// Loop until we find the closing brace
|
||||
Common::String line = stream.readLine();
|
||||
_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
|
||||
Common::String param;
|
||||
Common::String values;
|
||||
getParams(line, param, values);
|
||||
|
||||
while (!stream.eos() && !line.contains('}')) {
|
||||
if (param.matchString("*_hotspot", true)) {
|
||||
uint x;
|
||||
uint y;
|
||||
uint width;
|
||||
uint height;
|
||||
|
||||
if (sscanf(values.c_str(), "%u,%u,%u,%u", &x, &y, &width, &height) == 4)
|
||||
_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();
|
||||
_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
|
||||
getParams(line, param, values);
|
||||
}
|
||||
|
||||
if (_hotspots.size() == 0) {
|
||||
warning("Push_toggle %u was parsed incorrectly", key);
|
||||
}
|
||||
}
|
||||
|
||||
PushToggleControl::~PushToggleControl() {
|
||||
_hotspots.clear();
|
||||
}
|
||||
|
||||
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 (_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 (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
|
||||
return false;
|
||||
|
||||
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
|
||||
79
engines/zvision/scripting/controls/push_toggle_control.h
Normal file
79
engines/zvision/scripting/controls/push_toggle_control.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ZVISION_PUSH_TOGGLE_CONTROL_H
|
||||
#define ZVISION_PUSH_TOGGLE_CONTROL_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/events.h"
|
||||
#include "common/rect.h"
|
||||
#include "zvision/scripting/control.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
class PushToggleControl : public Control {
|
||||
public:
|
||||
PushToggleControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
|
||||
~PushToggleControl() override;
|
||||
|
||||
/**
|
||||
* 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) override;
|
||||
/**
|
||||
* 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) override;
|
||||
/**
|
||||
* 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) override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* The area that will trigger the event
|
||||
* This is in image space coordinates, NOT screen space
|
||||
*/
|
||||
Common::Array<Common::Rect> _hotspots;
|
||||
/** The cursor to use when hovering over _hotspot */
|
||||
int _cursor;
|
||||
/** Button maximal values count */
|
||||
uint _countTo;
|
||||
|
||||
Common::EventType _event;
|
||||
|
||||
bool contain(const Common::Point &point);
|
||||
};
|
||||
|
||||
} // End of namespace ZVision
|
||||
|
||||
#endif
|
||||
177
engines/zvision/scripting/controls/safe_control.cpp
Normal file
177
engines/zvision/scripting/controls/safe_control.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/file.h"
|
||||
#include "common/scummsys.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/system.h"
|
||||
#include "common/tokenizer.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "video/video_decoder.h"
|
||||
#include "zvision/zvision.h"
|
||||
#include "zvision/graphics/render_manager.h"
|
||||
#include "zvision/graphics/cursors/cursor_manager.h"
|
||||
#include "zvision/scripting/script_manager.h"
|
||||
#include "zvision/scripting/controls/safe_control.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;
|
||||
_targetFrame = 0;
|
||||
|
||||
// Loop until we find the closing brace
|
||||
Common::String line = stream.readLine();
|
||||
_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
|
||||
Common::String param;
|
||||
Common::String values;
|
||||
getParams(line, param, values);
|
||||
|
||||
while (!stream.eos() && !line.contains('}')) {
|
||||
if (param.matchString("animation", true)) {
|
||||
_animation = _engine->loadAnimation(Common::Path(values));
|
||||
_animation->start();
|
||||
} else if (param.matchString("rectangle", true)) {
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
if (sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height) == 4)
|
||||
_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;
|
||||
|
||||
if (sscanf(values.c_str(), "%d %d", &x, &y) == 2)
|
||||
_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();
|
||||
_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
|
||||
getParams(line, param, values);
|
||||
}
|
||||
|
||||
if (_animation)
|
||||
_animation->seekToFrame(_curState);
|
||||
}
|
||||
|
||||
SafeControl::~SafeControl() {
|
||||
if (_animation)
|
||||
delete _animation;
|
||||
|
||||
}
|
||||
|
||||
bool SafeControl::process(uint32 deltaTimeInMillis) {
|
||||
if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
|
||||
return false;
|
||||
|
||||
if (_animation && _animation->getCurFrame() != _targetFrame && _animation->needsUpdate()) {
|
||||
// If we're past the target frame, move back one
|
||||
if (_animation->getCurFrame() > _targetFrame)
|
||||
_animation->seekToFrame(_animation->getCurFrame() - 1);
|
||||
|
||||
const Graphics::Surface *frameData = _animation->decodeNextFrame();
|
||||
if (_animation->getCurFrame() == _targetFrame)
|
||||
_engine->getScriptManager()->setStateValue(_key, _curState);
|
||||
if (frameData)
|
||||
_engine->getRenderManager()->blitSurfaceToBkg(*frameData, _rectangle.left, _rectangle.top);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// Coverity complains about the order of arguments here,
|
||||
// but changing that breaks the Zork Nemesis safe puzzle.
|
||||
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;
|
||||
|
||||
if (_animation)
|
||||
_animation->seekToFrame((_curState + _statesCount - _startPointer) % _statesCount);
|
||||
|
||||
_curState = (_statesCount * 2 + tmp2) % _statesCount;
|
||||
|
||||
_targetFrame = (_curState + _statesCount - _startPointer) % _statesCount;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End of namespace ZVision
|
||||
63
engines/zvision/scripting/controls/safe_control.h
Normal file
63
engines/zvision/scripting/controls/safe_control.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ZVISION_SAFE_CONTROL_H
|
||||
#define ZVISION_SAFE_CONTROL_H
|
||||
|
||||
#include "common/list.h"
|
||||
#include "common/rect.h"
|
||||
#include "zvision/scripting/control.h"
|
||||
|
||||
namespace Video {
|
||||
class VideoDecoder;
|
||||
}
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
// Only used in Zork Nemesis, handles the safe in the Asylum (ac4g)
|
||||
class SafeControl : public Control {
|
||||
public:
|
||||
SafeControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
|
||||
~SafeControl() override;
|
||||
|
||||
private:
|
||||
int16 _statesCount;
|
||||
int16 _curState;
|
||||
Video::VideoDecoder *_animation;
|
||||
Common::Point _center;
|
||||
Common::Rect _rectangle;
|
||||
int16 _innerRaduis;
|
||||
int32 _innerRadiusSqr;
|
||||
int16 _outerRadius;
|
||||
int32 _outerRadiusSqr;
|
||||
int16 _zeroPointer;
|
||||
int16 _startPointer;
|
||||
int16 _targetFrame;
|
||||
|
||||
public:
|
||||
bool onMouseUp(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) override;
|
||||
bool onMouseMove(const Common::Point &screenSpacePos, const Common::Point &backgroundImageSpacePos) override;
|
||||
bool process(uint32 deltaTimeInMillis) override;
|
||||
};
|
||||
|
||||
} // End of namespace ZVision
|
||||
|
||||
#endif
|
||||
118
engines/zvision/scripting/controls/save_control.cpp
Normal file
118
engines/zvision/scripting/controls/save_control.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/str.h"
|
||||
#include "common/stream.h"
|
||||
#include "zvision/zvision.h"
|
||||
#include "zvision/file/save_manager.h"
|
||||
#include "zvision/scripting/script_manager.h"
|
||||
#include "zvision/scripting/controls/input_control.h"
|
||||
#include "zvision/scripting/controls/save_control.h"
|
||||
#include "zvision/text/string_manager.h"
|
||||
#include "zvision/text/subtitle_manager.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();
|
||||
_engine->getScriptManager()->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;
|
||||
if (sscanf(values.c_str(), "%d %d", &saveId, &inputId) == 2) {
|
||||
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();
|
||||
_engine->getScriptManager()->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;
|
||||
if (_engine->getSaveManager()->readSaveGameHeader(save, header)) {
|
||||
inp->setText(header.saveName);
|
||||
iter->exist = true;
|
||||
}
|
||||
delete save;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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->getSubtitleManager()->askQuestion(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVEEXIST)))
|
||||
toSave = false;
|
||||
|
||||
if (toSave) {
|
||||
_engine->getSaveManager()->saveGame(iter->saveId, inp->getText(), true);
|
||||
_engine->getSubtitleManager()->delayedMessage(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVED), 2000);
|
||||
_engine->getScriptManager()->changeLocation(_engine->getScriptManager()->getLastMenuLocation());
|
||||
}
|
||||
} else {
|
||||
_engine->getSubtitleManager()->timedMessage(_engine->getStringManager()->getTextLine(StringManager::ZVISION_STR_SAVEEMPTY), 2000);
|
||||
}
|
||||
} else {
|
||||
_engine->getSaveManager()->loadGame(iter->saveId);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End of namespace ZVision
|
||||
53
engines/zvision/scripting/controls/save_control.h
Normal file
53
engines/zvision/scripting/controls/save_control.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ZVISION_SAVE_CONTROL_H
|
||||
#define ZVISION_SAVE_CONTROL_H
|
||||
|
||||
#include "common/list.h"
|
||||
#include "zvision/scripting/control.h"
|
||||
|
||||
namespace 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;
|
||||
|
||||
public:
|
||||
|
||||
bool process(uint32 deltaTimeInMillis) override;
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace ZVision
|
||||
|
||||
#endif
|
||||
213
engines/zvision/scripting/controls/slot_control.cpp
Normal file
213
engines/zvision/scripting/controls/slot_control.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/stream.h"
|
||||
#include "zvision/zvision.h"
|
||||
#include "zvision/graphics/cursors/cursor_manager.h"
|
||||
#include "zvision/graphics/render_manager.h"
|
||||
#include "zvision/scripting/script_manager.h"
|
||||
#include "zvision/scripting/controls/slot_control.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
SlotControl::SlotControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
|
||||
: Control(engine, key, CONTROL_SLOT),
|
||||
_cursor(CursorIndex_Active),
|
||||
_distanceId('0') {
|
||||
|
||||
_renderedItem = 0;
|
||||
_bkg = NULL;
|
||||
|
||||
// Loop until we find the closing brace
|
||||
Common::String line = stream.readLine();
|
||||
_engine->getScriptManager()->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;
|
||||
|
||||
if (sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height) == 4)
|
||||
_hotspot = Common::Rect(x, y, width, height);
|
||||
} else if (param.matchString("rectangle", true)) {
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
if (sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height) == 4)
|
||||
_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);
|
||||
strncpy(buf, values.c_str(), 255);
|
||||
|
||||
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();
|
||||
_engine->getScriptManager()->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)
|
||||
Common::sprintf_s(buf, "%d%cobj.tga", curItem, _distanceId);
|
||||
else
|
||||
Common::sprintf_s(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
|
||||
81
engines/zvision/scripting/controls/slot_control.h
Normal file
81
engines/zvision/scripting/controls/slot_control.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ZVISION_SLOT_CONTROL_H
|
||||
#define ZVISION_SLOT_CONTROL_H
|
||||
|
||||
#include "common/list.h"
|
||||
#include "common/rect.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "zvision/scripting/control.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
class SlotControl : public Control {
|
||||
public:
|
||||
SlotControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
|
||||
~SlotControl() override;
|
||||
|
||||
/**
|
||||
* 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) override;
|
||||
/**
|
||||
* 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) override;
|
||||
|
||||
bool process(uint32 deltaTimeInMillis) override;
|
||||
|
||||
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
|
||||
103
engines/zvision/scripting/controls/titler_control.cpp
Normal file
103
engines/zvision/scripting/controls/titler_control.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/stream.h"
|
||||
#include "zvision/zvision.h"
|
||||
#include "zvision/graphics/render_manager.h"
|
||||
#include "zvision/scripting/script_manager.h"
|
||||
#include "zvision/scripting/controls/titler_control.h"
|
||||
#include "zvision/text/text.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();
|
||||
_engine->getScriptManager()->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(Common::Path(values));
|
||||
} else if (param.matchString("rectangle", true)) {
|
||||
int x;
|
||||
int y;
|
||||
int x2;
|
||||
int y2;
|
||||
|
||||
if (sscanf(values.c_str(), "%d %d %d %d", &x, &y, &x2, &y2) == 4)
|
||||
_rectangle = Common::Rect(x, y, x2, y2);
|
||||
}
|
||||
|
||||
line = stream.readLine();
|
||||
_engine->getScriptManager()->trimCommentsAndWhiteSpace(&line);
|
||||
getParams(line, param, values);
|
||||
}
|
||||
|
||||
if (!_rectangle.isEmpty()) {
|
||||
_surface = new Graphics::Surface;
|
||||
_surface->create(_rectangle.width(), _rectangle.height(), _engine->_resourcePixelFormat);
|
||||
_surface->fillRect(Common::Rect(_surface->w, _surface->h), 0);
|
||||
}
|
||||
}
|
||||
|
||||
TitlerControl::~TitlerControl() {
|
||||
if (_surface) {
|
||||
_surface->free();
|
||||
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()->drawTextWithWordWrapping(_strings[strLine], *_surface);
|
||||
_engine->getRenderManager()->blitSurfaceToBkg(*_surface, _rectangle.left, _rectangle.top);
|
||||
_curString = strLine;
|
||||
}
|
||||
}
|
||||
|
||||
void TitlerControl::readStringsFile(const Common::Path &fileName) {
|
||||
Common::File file;
|
||||
if (!file.open(fileName)) {
|
||||
warning("String_resource_file %s could could be opened", fileName.toString().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
_strings.clear();
|
||||
|
||||
while (!file.eos()) {
|
||||
|
||||
Common::String line = readWideLine(file).encode();
|
||||
_strings.push_back(line);
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
} // End of namespace ZVision
|
||||
55
engines/zvision/scripting/controls/titler_control.h
Normal file
55
engines/zvision/scripting/controls/titler_control.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ZVISION_TITLER_CONTROL_H
|
||||
#define ZVISION_TITLER_CONTROL_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/file.h"
|
||||
#include "common/path.h"
|
||||
#include "common/rect.h"
|
||||
#include "common/stream.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "zvision/scripting/control.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
// Only used in Zork Nemesis, handles the death screen with the Restore/Exit buttons
|
||||
class TitlerControl : public Control {
|
||||
public:
|
||||
TitlerControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream);
|
||||
~TitlerControl() override;
|
||||
|
||||
void setString(int strLine);
|
||||
|
||||
private:
|
||||
|
||||
Common::Array< Common::String > _strings;
|
||||
Common::Rect _rectangle;
|
||||
int16 _curString;
|
||||
Graphics::Surface *_surface;
|
||||
|
||||
void readStringsFile(const Common::Path &fileName);
|
||||
};
|
||||
|
||||
} // End of namespace ZVision
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user