Initial commit
This commit is contained in:
213
engines/zvision/scripting/effects/animation_effect.cpp
Normal file
213
engines/zvision/scripting/effects/animation_effect.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 "graphics/surface.h"
|
||||
#include "video/video_decoder.h"
|
||||
#include "zvision/zvision.h"
|
||||
#include "zvision/graphics/render_manager.h"
|
||||
#include "zvision/scripting/script_manager.h"
|
||||
#include "zvision/scripting/effects/animation_effect.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
AnimationEffect::AnimationEffect(ZVision *engine, uint32 controlKey, const Common::Path &fileName, int32 mask, int32 frate, bool disposeAfterUse)
|
||||
: ScriptingEffect(engine, controlKey, SCRIPTING_EFFECT_ANIM),
|
||||
_disposeAfterUse(disposeAfterUse),
|
||||
_mask(mask),
|
||||
_animation(NULL) {
|
||||
|
||||
_animation = engine->loadAnimation(fileName);
|
||||
|
||||
if (frate > 0) {
|
||||
_frmDelayOverride = (int32)(1000.0 / frate);
|
||||
|
||||
// WORKAROUND: We do not allow the engine to delay more than 66 msec
|
||||
// per frame (15fps max)
|
||||
if (_frmDelayOverride > 66)
|
||||
_frmDelayOverride = 66;
|
||||
} else {
|
||||
_frmDelayOverride = 0;
|
||||
}
|
||||
}
|
||||
|
||||
AnimationEffect::~AnimationEffect() {
|
||||
if (_animation)
|
||||
delete _animation;
|
||||
|
||||
_engine->getScriptManager()->setStateValue(_key, 2);
|
||||
|
||||
PlayNodes::iterator it = _playList.begin();
|
||||
if (it != _playList.end()) {
|
||||
_engine->getScriptManager()->setStateValue((*it).slot, 2);
|
||||
|
||||
if ((*it)._scaled) {
|
||||
(*it)._scaled->free();
|
||||
delete(*it)._scaled;
|
||||
}
|
||||
}
|
||||
|
||||
_playList.clear();
|
||||
}
|
||||
|
||||
bool AnimationEffect::process(uint32 deltaTimeInMillis) {
|
||||
ScriptManager *scriptManager = _engine->getScriptManager();
|
||||
RenderManager *renderManager = _engine->getRenderManager();
|
||||
RenderTable::RenderState renderState = renderManager->getRenderTable()->getRenderState();
|
||||
bool isPanorama = (renderState == RenderTable::PANORAMA);
|
||||
int16 velocity = _engine->getMouseVelocity() + _engine->getKeyboardVelocity();
|
||||
|
||||
// Do not update animation nodes in panoramic mode while turning, if the user
|
||||
// has set this option
|
||||
if (scriptManager->getStateValue(StateKey_NoTurnAnim) == 1 && isPanorama && velocity)
|
||||
return false;
|
||||
|
||||
PlayNodes::iterator it = _playList.begin();
|
||||
if (it != _playList.end()) {
|
||||
playnode *nod = &(*it);
|
||||
|
||||
if (nod->_curFrame == -1) {
|
||||
// The node is just beginning playback
|
||||
nod->_curFrame = nod->start;
|
||||
|
||||
_animation->start();
|
||||
_animation->seekToFrame(nod->start);
|
||||
_animation->setEndFrame(nod->stop);
|
||||
|
||||
nod->_delay = deltaTimeInMillis; // Force the frame to draw
|
||||
if (nod->slot)
|
||||
scriptManager->setStateValue(nod->slot, 1);
|
||||
} else if (_animation->endOfVideo()) {
|
||||
// The node has reached the end; check if we need to loop
|
||||
nod->loop--;
|
||||
|
||||
if (nod->loop == 0) {
|
||||
if (nod->slot >= 0)
|
||||
scriptManager->setStateValue(nod->slot, 2);
|
||||
if (nod->_scaled) {
|
||||
nod->_scaled->free();
|
||||
delete nod->_scaled;
|
||||
}
|
||||
_playList.erase(it);
|
||||
return _disposeAfterUse;
|
||||
}
|
||||
|
||||
nod->_curFrame = nod->start;
|
||||
_animation->seekToFrame(nod->start);
|
||||
}
|
||||
|
||||
// Check if we need to draw a frame
|
||||
bool needsUpdate = false;
|
||||
if (_frmDelayOverride == 0) {
|
||||
// If not overridden, use the VideoDecoder's check
|
||||
needsUpdate = _animation->needsUpdate();
|
||||
} else {
|
||||
// Otherwise, implement our own timing
|
||||
nod->_delay -= deltaTimeInMillis;
|
||||
|
||||
if (nod->_delay <= 0) {
|
||||
nod->_delay += _frmDelayOverride;
|
||||
needsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (needsUpdate) {
|
||||
const Graphics::Surface *frame = _animation->decodeNextFrame();
|
||||
|
||||
if (frame) {
|
||||
int dstw;
|
||||
int dsth;
|
||||
if (isPanorama) {
|
||||
dstw = nod->pos.height();
|
||||
dsth = nod->pos.width();
|
||||
} else {
|
||||
dstw = nod->pos.width();
|
||||
dsth = nod->pos.height();
|
||||
}
|
||||
|
||||
// We only scale down the animation to fit its frame, not up, otherwise we
|
||||
// end up with distorted animations - e.g. the armor visor in location cz1e
|
||||
// in Nemesis (one of the armors inside Irondune), or the planet in location
|
||||
// aa10 in Nemesis (Juperon, outside the asylum). We do allow scaling up only
|
||||
// when a simple 2x filter is requested (e.g. the alchemists and cup sequence
|
||||
// in Nemesis)
|
||||
if (frame->w > dstw || frame->h > dsth || (frame->w == dstw / 2 && frame->h == dsth / 2)) {
|
||||
if (nod->_scaled)
|
||||
if (nod->_scaled->w != dstw || nod->_scaled->h != dsth) {
|
||||
nod->_scaled->free();
|
||||
delete nod->_scaled;
|
||||
nod->_scaled = NULL;
|
||||
}
|
||||
|
||||
if (!nod->_scaled) {
|
||||
nod->_scaled = new Graphics::Surface;
|
||||
nod->_scaled->create(dstw, dsth, frame->format);
|
||||
}
|
||||
|
||||
renderManager->scaleBuffer(frame->getPixels(), nod->_scaled->getPixels(), frame->w, frame->h, frame->format.bytesPerPixel, dstw, dsth);
|
||||
frame = nod->_scaled;
|
||||
}
|
||||
|
||||
if (isPanorama) {
|
||||
Graphics::Surface *transposed = RenderManager::tranposeSurface(frame);
|
||||
renderManager->blitSurfaceToBkg(*transposed, nod->pos.left, nod->pos.top, _mask);
|
||||
transposed->free();
|
||||
delete transposed;
|
||||
} else {
|
||||
renderManager->blitSurfaceToBkg(*frame, nod->pos.left, nod->pos.top, _mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AnimationEffect::addPlayNode(int32 slot, int x, int y, int x2, int y2, int startFrame, int endFrame, int loops) {
|
||||
playnode nod;
|
||||
nod.loop = loops;
|
||||
nod.pos = Common::Rect(x, y, x2 + 1, y2 + 1);
|
||||
nod.start = startFrame;
|
||||
nod.stop = CLIP<int>(endFrame, 0, _animation->getFrameCount() - 1);
|
||||
nod.slot = slot;
|
||||
nod._curFrame = -1;
|
||||
nod._delay = 0;
|
||||
nod._scaled = NULL;
|
||||
_playList.push_back(nod);
|
||||
}
|
||||
|
||||
bool AnimationEffect::stop() {
|
||||
PlayNodes::iterator it = _playList.begin();
|
||||
if (it != _playList.end()) {
|
||||
_engine->getScriptManager()->setStateValue((*it).slot, 2);
|
||||
if ((*it)._scaled) {
|
||||
(*it)._scaled->free();
|
||||
delete(*it)._scaled;
|
||||
}
|
||||
}
|
||||
|
||||
_playList.clear();
|
||||
|
||||
// We don't need to delete, it's may be reused
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End of namespace ZVision
|
||||
79
engines/zvision/scripting/effects/animation_effect.h
Normal file
79
engines/zvision/scripting/effects/animation_effect.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_ANIMATION_NODE_H
|
||||
#define ZVISION_ANIMATION_NODE_H
|
||||
|
||||
#include "common/list.h"
|
||||
#include "common/path.h"
|
||||
#include "common/rect.h"
|
||||
#include "zvision/scripting/scripting_effect.h"
|
||||
|
||||
namespace Graphics {
|
||||
struct Surface;
|
||||
}
|
||||
|
||||
namespace Video {
|
||||
class VideoDecoder;
|
||||
}
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
class ZVision;
|
||||
|
||||
class AnimationEffect : public ScriptingEffect {
|
||||
public:
|
||||
AnimationEffect(ZVision *engine, uint32 controlKey, const Common::Path &fileName, int32 mask, int32 frate, bool disposeAfterUse = true);
|
||||
~AnimationEffect() override;
|
||||
|
||||
struct playnode {
|
||||
Common::Rect pos;
|
||||
int32 slot;
|
||||
int32 start;
|
||||
int32 stop;
|
||||
int32 loop;
|
||||
int32 _curFrame;
|
||||
int32 _delay;
|
||||
Graphics::Surface *_scaled;
|
||||
};
|
||||
|
||||
private:
|
||||
typedef Common::List<playnode> PlayNodes;
|
||||
|
||||
PlayNodes _playList;
|
||||
|
||||
int32 _mask;
|
||||
bool _disposeAfterUse;
|
||||
|
||||
Video::VideoDecoder *_animation;
|
||||
int32 _frmDelayOverride;
|
||||
|
||||
public:
|
||||
bool process(uint32 deltaTimeInMillis) override;
|
||||
|
||||
void addPlayNode(int32 slot, int x, int y, int x2, int y2, int startFrame, int endFrame, int loops = 1);
|
||||
|
||||
bool stop() override;
|
||||
};
|
||||
|
||||
} // End of namespace ZVision
|
||||
|
||||
#endif
|
||||
108
engines/zvision/scripting/effects/distort_effect.cpp
Normal file
108
engines/zvision/scripting/effects/distort_effect.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
/* 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/graphics/render_table.h"
|
||||
#include "zvision/scripting/script_manager.h"
|
||||
#include "zvision/scripting/effects/distort_effect.h"
|
||||
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
DistortNode::DistortNode(ZVision *engine, uint32 key, int16 speed, float startAngle, float endAngle, float startLineScale, float endLineScale)
|
||||
: ScriptingEffect(engine, key, SCRIPTING_EFFECT_DISTORT) {
|
||||
|
||||
_angle = _engine->getRenderManager()->getRenderTable()->getAngle();
|
||||
_linScale = _engine->getRenderManager()->getRenderTable()->getLinscale();
|
||||
|
||||
_speed = speed;
|
||||
_incr = true;
|
||||
_startAngle = startAngle;
|
||||
_endAngle = endAngle;
|
||||
_startLineScale = startLineScale;
|
||||
_endLineScale = endLineScale;
|
||||
|
||||
_curFrame = 1.0;
|
||||
|
||||
_diffAngle = endAngle - startAngle;
|
||||
_diffLinScale = endLineScale - startLineScale;
|
||||
|
||||
_frmSpeed = (float)speed / 15.0;
|
||||
_frames = (int)ceil((5.0 - _frmSpeed * 2.0) / _frmSpeed);
|
||||
if (_frames <= 0)
|
||||
_frames = 1;
|
||||
|
||||
if (_key != StateKey_NotSet)
|
||||
_engine->getScriptManager()->setStateValue(_key, 1);
|
||||
}
|
||||
|
||||
DistortNode::~DistortNode() {
|
||||
setParams(_angle, _linScale);
|
||||
}
|
||||
|
||||
bool DistortNode::process(uint32 deltaTimeInMillis) {
|
||||
float updTime = deltaTimeInMillis / (1000.0 / 60.0);
|
||||
|
||||
if (_incr)
|
||||
_curFrame += updTime;
|
||||
else
|
||||
_curFrame -= updTime;
|
||||
|
||||
if (_curFrame < 1.0) {
|
||||
_curFrame = 1.0;
|
||||
_incr = true;
|
||||
} else if (_curFrame > _frames) {
|
||||
_curFrame = _frames;
|
||||
_incr = false;
|
||||
}
|
||||
|
||||
float diff = (1.0 / (5.0 - (_curFrame * _frmSpeed))) / (5.0 - _frmSpeed);
|
||||
setParams(_startAngle + diff * _diffAngle, _startLineScale + diff * _diffLinScale);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DistortNode::setParams(float angl, float linScale) {
|
||||
RenderTable *table = _engine->getRenderManager()->getRenderTable();
|
||||
switch (table->getRenderState()) {
|
||||
case RenderTable::PANORAMA: {
|
||||
table->setPanoramaFoV(angl);
|
||||
table->setPanoramaScale(linScale);
|
||||
table->generateRenderTable();
|
||||
_engine->getRenderManager()->markDirty();
|
||||
break;
|
||||
}
|
||||
case RenderTable::TILT: {
|
||||
table->setTiltFoV(angl);
|
||||
table->setTiltScale(linScale);
|
||||
table->generateRenderTable();
|
||||
_engine->getRenderManager()->markDirty();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace ZVision
|
||||
62
engines/zvision/scripting/effects/distort_effect.h
Normal file
62
engines/zvision/scripting/effects/distort_effect.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 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_DISTORT_NODE_H
|
||||
#define ZVISION_DISTORT_NODE_H
|
||||
|
||||
#include "zvision/scripting/scripting_effect.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
class ZVision;
|
||||
|
||||
class DistortNode : public ScriptingEffect {
|
||||
public:
|
||||
DistortNode(ZVision *engine, uint32 key, int16 speed, float startAngle, float endAngle, float startLineScale, float endLineScale);
|
||||
~DistortNode() override;
|
||||
|
||||
bool process(uint32 deltaTimeInMillis) override;
|
||||
|
||||
private:
|
||||
int16 _speed;
|
||||
float _startAngle;
|
||||
float _endAngle;
|
||||
float _startLineScale;
|
||||
float _endLineScale;
|
||||
|
||||
float _frmSpeed;
|
||||
float _diffAngle;
|
||||
float _diffLinScale;
|
||||
bool _incr;
|
||||
int16 _frames;
|
||||
|
||||
float _curFrame;
|
||||
|
||||
float _angle;
|
||||
float _linScale;
|
||||
|
||||
private:
|
||||
void setParams(float angl, float linScale);
|
||||
};
|
||||
|
||||
} // End of namespace ZVision
|
||||
|
||||
#endif
|
||||
290
engines/zvision/scripting/effects/music_effect.cpp
Normal file
290
engines/zvision/scripting/effects/music_effect.cpp
Normal file
@@ -0,0 +1,290 @@
|
||||
/* 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 "audio/decoders/wave.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/file.h"
|
||||
#include "common/scummsys.h"
|
||||
#include "common/stream.h"
|
||||
#include "math/utils.h"
|
||||
#include "math/angle.h"
|
||||
#include "zvision/zvision.h"
|
||||
#include "zvision/graphics/render_manager.h"
|
||||
#include "zvision/scripting/script_manager.h"
|
||||
#include "zvision/scripting/effects/music_effect.h"
|
||||
#include "zvision/sound/midi.h"
|
||||
#include "zvision/sound/volume_manager.h"
|
||||
#include "zvision/sound/zork_raw.h"
|
||||
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
void MusicNodeBASE::setDirection(Math::Angle azimuth, uint8 magnitude) {
|
||||
if (_engine->getScriptManager()->getStateValue(StateKey_Qsound) >= 1) {
|
||||
_azimuth = azimuth;
|
||||
_directionality = magnitude;
|
||||
_balance = ((int)(127 * _azimuth.getSine()) * _directionality) / 255;
|
||||
} else
|
||||
setBalance(0);
|
||||
updateMixer();
|
||||
}
|
||||
|
||||
void MusicNodeBASE::setBalance(int8 balance) {
|
||||
_balance = balance;
|
||||
_azimuth.setDegrees(0);
|
||||
_directionality = 255;
|
||||
updateMixer();
|
||||
}
|
||||
|
||||
void MusicNodeBASE::updateMixer() {
|
||||
if (_engine->getScriptManager()->getStateValue(StateKey_Qsound) >= 1)
|
||||
_volumeOut = _engine->getVolumeManager()->convert(_volume, _azimuth, _directionality); // Apply game-specific volume profile and then attenuate according to azimuth
|
||||
else
|
||||
_volumeOut = _engine->getVolumeManager()->convert(_volume); // Apply game-specific volume profile and ignore azimuth
|
||||
outputMixer();
|
||||
}
|
||||
|
||||
MusicNode::MusicNode(ZVision *engine, uint32 key, Common::Path &filename, bool loop, uint8 volume)
|
||||
: MusicNodeBASE(engine, key, SCRIPTING_EFFECT_AUDIO) {
|
||||
_loop = loop;
|
||||
_volume = volume;
|
||||
_balance = 0;
|
||||
_fade = false;
|
||||
_fadeStartVol = volume;
|
||||
_fadeEndVol = 0;
|
||||
_fadeTime = 0;
|
||||
_fadeElapsed = 0;
|
||||
_sub = 0;
|
||||
_stereo = false;
|
||||
_loaded = false;
|
||||
|
||||
Audio::RewindableAudioStream *audioStream = NULL;
|
||||
|
||||
if (filename.baseName().contains(".wav")) {
|
||||
Common::File *file = new Common::File();
|
||||
if (file->open(filename)) {
|
||||
audioStream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
|
||||
}
|
||||
} else {
|
||||
audioStream = makeRawZorkStream(filename, _engine);
|
||||
}
|
||||
|
||||
if (audioStream) {
|
||||
_stereo = audioStream->isStereo();
|
||||
|
||||
if (_loop) {
|
||||
Audio::LoopingAudioStream *loopingAudioStream = new Audio::LoopingAudioStream(audioStream, 0, DisposeAfterUse::YES);
|
||||
_engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, loopingAudioStream, -1, _volume);
|
||||
} else {
|
||||
_engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, audioStream, -1, _volume);
|
||||
}
|
||||
|
||||
if (_key != StateKey_NotSet) {
|
||||
debugC(3, kDebugSound, "setting musicnode state value to 1");
|
||||
_engine->getScriptManager()->setStateValue(_key, 1);
|
||||
}
|
||||
|
||||
// Change filename.raw into filename.sub
|
||||
Common::String subname = filename.baseName();
|
||||
subname.setChar('s', subname.size() - 3);
|
||||
subname.setChar('u', subname.size() - 2);
|
||||
subname.setChar('b', subname.size() - 1);
|
||||
|
||||
Common::Path subpath(filename.getParent().appendComponent(subname));
|
||||
if (SearchMan.hasFile(subpath))
|
||||
_sub = _engine->getSubtitleManager()->create(subpath, _handle); // NB automatic subtitle!
|
||||
|
||||
_loaded = true;
|
||||
updateMixer();
|
||||
}
|
||||
debugC(3, kDebugSound, "MusicNode: %d created", _key);
|
||||
}
|
||||
|
||||
MusicNode::~MusicNode() {
|
||||
if (_loaded)
|
||||
_engine->_mixer->stopHandle(_handle);
|
||||
if (_key != StateKey_NotSet)
|
||||
_engine->getScriptManager()->setStateValue(_key, 2);
|
||||
if (_sub)
|
||||
_engine->getSubtitleManager()->destroy(_sub);
|
||||
debugC(3, kDebugSound, "MusicNode: %d destroyed", _key);
|
||||
}
|
||||
|
||||
void MusicNode::outputMixer() {
|
||||
_engine->_mixer->setChannelBalance(_handle, _balance);
|
||||
_engine->_mixer->setChannelVolume(_handle, _volumeOut);
|
||||
}
|
||||
|
||||
void MusicNode::setFade(int32 time, uint8 target) {
|
||||
_fadeStartVol = _volume;
|
||||
_fadeEndVol = target;
|
||||
_fadeElapsed = 0;
|
||||
_fadeTime = time <= 0 ? 0 : (uint32)time;
|
||||
_fade = true;
|
||||
}
|
||||
|
||||
bool MusicNode::process(uint32 deltaTimeInMillis) {
|
||||
if (!_loaded || ! _engine->_mixer->isSoundHandleActive(_handle))
|
||||
return stop();
|
||||
else {
|
||||
if (_fade) {
|
||||
debugC(3, kDebugSound, "Fading music, endVol %d, startVol %d, current %d, fade time %d, elapsed time %dms", _fadeEndVol, _fadeStartVol, _volume, _fadeTime, _fadeElapsed);
|
||||
uint8 _newvol = 0;
|
||||
_fadeElapsed += deltaTimeInMillis;
|
||||
if ((_fadeTime <= 0) | (_fadeElapsed >= _fadeTime)) {
|
||||
_newvol = _fadeEndVol;
|
||||
_fade = false;
|
||||
} else {
|
||||
if (_fadeEndVol > _fadeStartVol)
|
||||
_newvol = _fadeStartVol + (_fadeElapsed * (_fadeEndVol - _fadeStartVol)) / _fadeTime;
|
||||
else
|
||||
_newvol = _fadeStartVol - (_fadeElapsed * (_fadeStartVol - _fadeEndVol)) / _fadeTime;
|
||||
}
|
||||
if (_volume != _newvol)
|
||||
setVolume(_newvol);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MusicNode::setVolume(uint8 newVolume) {
|
||||
if (_loaded) {
|
||||
debugC(4, kDebugSound, "Changing volume of music node %d from %d to %d", _key, _volume, newVolume);
|
||||
_volume = newVolume;
|
||||
updateMixer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PanTrackNode::PanTrackNode(ZVision *engine, uint32 key, uint32 slot, int16 pos, uint8 mag, bool resetMixerOnDelete, bool staticScreen)
|
||||
: ScriptingEffect(engine, key, SCRIPTING_EFFECT_PANTRACK),
|
||||
_slot(slot),
|
||||
_sourcePos(0),
|
||||
_viewPos(0),
|
||||
_mag(mag),
|
||||
_width(0),
|
||||
_pos(pos),
|
||||
_staticScreen(staticScreen),
|
||||
_resetMixerOnDelete(resetMixerOnDelete) {
|
||||
debugC(3, kDebugSound, "Created PanTrackNode, key %d, slot %d", _key, _slot);
|
||||
process(0); // Try to set pan value for music node immediately
|
||||
}
|
||||
|
||||
PanTrackNode::~PanTrackNode() {
|
||||
debugC(1, kDebugSound, "Deleting PanTrackNode, key %d, slot %d", _key, _slot);
|
||||
ScriptManager *scriptManager = _engine->getScriptManager();
|
||||
ScriptingEffect *fx = scriptManager->getSideFX(_slot);
|
||||
if (fx && fx->getType() == SCRIPTING_EFFECT_AUDIO && _resetMixerOnDelete) {
|
||||
debugC(1, kDebugSound, "Resetting mixer, slot %d", _slot);
|
||||
MusicNodeBASE *mus = (MusicNodeBASE *)fx;
|
||||
mus->setBalance(0);
|
||||
} else
|
||||
debugC(1, kDebugSound, "NOT resetting mixer, slot %d", _slot);
|
||||
}
|
||||
|
||||
bool PanTrackNode::process(uint32 deltaTimeInMillis) {
|
||||
debugC(3, kDebugSound, "Processing PanTrackNode, key %d", _key);
|
||||
ScriptManager *scriptManager = _engine->getScriptManager();
|
||||
ScriptingEffect *fx = scriptManager->getSideFX(_slot);
|
||||
if (fx && fx->getType() == SCRIPTING_EFFECT_AUDIO) {
|
||||
MusicNodeBASE *mus = (MusicNodeBASE *)fx;
|
||||
if (!_staticScreen)
|
||||
// Original game scripted behaviour
|
||||
switch (_engine->getRenderManager()->getRenderTable()->getRenderState()) {
|
||||
case RenderTable::PANORAMA:
|
||||
debugC(3, kDebugSound, "PanTrackNode in panorama mode");
|
||||
_width = _engine->getRenderManager()->getBkgSize().x;
|
||||
if (_width) {
|
||||
_sourcePos.setDegrees(360 * _pos / _width);
|
||||
_viewPos.setDegrees(360 * scriptManager->getStateValue(StateKey_ViewPos) / _width);
|
||||
} else {
|
||||
warning("Encountered zero background width whilst processing PanTrackNode in panoramic mode!");
|
||||
}
|
||||
break;
|
||||
case RenderTable::FLAT:
|
||||
case RenderTable::TILT:
|
||||
default:
|
||||
debugC(3, kDebugSound, "PanTrackNode in FLAT/TILT mode");
|
||||
_sourcePos.setDegrees(0);
|
||||
_viewPos.setDegrees(0);
|
||||
break;
|
||||
} else {
|
||||
// Used for auxiliary scripts only
|
||||
_sourcePos.setDegrees(_pos);
|
||||
_viewPos.setDegrees(0);
|
||||
}
|
||||
Math::Angle azimuth;
|
||||
azimuth = _sourcePos - _viewPos;
|
||||
debugC(3, kDebugSound, "soundPos: %f, _viewPos: %f, azimuth: %f, width %d", _sourcePos.getDegrees(), _viewPos.getDegrees(), azimuth.getDegrees(), _width);
|
||||
// azimuth is sound source position relative to player, clockwise from centre of camera axis to front when viewed top-down
|
||||
mus->setDirection(azimuth, _mag);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
MusicMidiNode::MusicMidiNode(ZVision *engine, uint32 key, uint8 program, uint8 note, uint8 volume)
|
||||
: MusicNodeBASE(engine, key, SCRIPTING_EFFECT_AUDIO) {
|
||||
_volume = volume;
|
||||
_prog = program;
|
||||
_noteNumber = note;
|
||||
_pan = 0;
|
||||
|
||||
_chan = _engine->getMidiManager()->getFreeChannel();
|
||||
|
||||
if (_chan >= 0) {
|
||||
updateMixer();
|
||||
_engine->getMidiManager()->setProgram(_chan, _prog);
|
||||
_engine->getMidiManager()->noteOn(_chan, _noteNumber, _volume);
|
||||
}
|
||||
|
||||
if (_key != StateKey_NotSet)
|
||||
_engine->getScriptManager()->setStateValue(_key, 1);
|
||||
}
|
||||
|
||||
MusicMidiNode::~MusicMidiNode() {
|
||||
if (_chan >= 0) {
|
||||
_engine->getMidiManager()->noteOff(_chan);
|
||||
}
|
||||
if (_key != StateKey_NotSet)
|
||||
_engine->getScriptManager()->setStateValue(_key, 2);
|
||||
}
|
||||
|
||||
void MusicMidiNode::setFade(int32 time, uint8 target) {
|
||||
}
|
||||
|
||||
bool MusicMidiNode::process(uint32 deltaTimeInMillis) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void MusicMidiNode::setVolume(uint8 newVolume) {
|
||||
if (_chan >= 0) {
|
||||
_volume = newVolume;
|
||||
updateMixer();
|
||||
}
|
||||
}
|
||||
|
||||
void MusicMidiNode::outputMixer() {
|
||||
_engine->getMidiManager()->setBalance(_chan, _balance);
|
||||
_engine->getMidiManager()->setPan(_chan, _pan);
|
||||
_engine->getMidiManager()->setVolume(_chan, _volumeOut);
|
||||
}
|
||||
|
||||
} // End of namespace ZVision
|
||||
146
engines/zvision/scripting/effects/music_effect.h
Normal file
146
engines/zvision/scripting/effects/music_effect.h
Normal file
@@ -0,0 +1,146 @@
|
||||
/* 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_MUSIC_NODE_H
|
||||
#define ZVISION_MUSIC_NODE_H
|
||||
|
||||
#include "audio/mixer.h"
|
||||
#include "math/angle.h"
|
||||
#include "zvision/scripting/scripting_effect.h"
|
||||
#include "zvision/sound/volume_manager.h"
|
||||
#include "zvision/text/subtitle_manager.h"
|
||||
|
||||
namespace Common {
|
||||
class String;
|
||||
}
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
class MusicNodeBASE : public ScriptingEffect {
|
||||
public:
|
||||
MusicNodeBASE(ZVision *engine, uint32 key, ScriptingEffectType type) : ScriptingEffect(engine, key, type) {}
|
||||
~MusicNodeBASE() override {}
|
||||
|
||||
/**
|
||||
* Decrement the timer by the delta time. If the timer is finished, set the status
|
||||
* in _globalState and let this node be deleted
|
||||
*
|
||||
* @param deltaTimeInMillis The number of milliseconds that have passed since last frame
|
||||
* @return If true, the node can be deleted after process() finishes
|
||||
*/
|
||||
bool process(uint32 deltaTimeInMillis) override = 0;
|
||||
|
||||
virtual void setVolume(uint8 volume) = 0;
|
||||
uint8 getVolume() {
|
||||
return _volume;
|
||||
}
|
||||
virtual void setFade(int32 time, uint8 target) = 0;
|
||||
virtual void setBalance(int8 balance); // NB Overrides effects of setDirection()
|
||||
void setDirection(Math::Angle azimuth, uint8 magnitude = 255); // NB Overrides effects of setBalance()
|
||||
protected:
|
||||
void updateMixer();
|
||||
virtual void outputMixer() = 0;
|
||||
|
||||
uint8 _volume = 0;
|
||||
int8 _balance = 0;
|
||||
Math::Angle _azimuth;
|
||||
uint8 _directionality; // 0 = fully ambient, 255 = fully directional
|
||||
uint8 _volumeOut = 0;
|
||||
};
|
||||
|
||||
class MusicNode : public MusicNodeBASE {
|
||||
public:
|
||||
MusicNode(ZVision *engine, uint32 key, Common::Path &file, bool loop, uint8 volume);
|
||||
~MusicNode() override;
|
||||
|
||||
/**
|
||||
* Decrement the timer by the delta time. If the timer is finished, set the status
|
||||
* in _globalState and let this node be deleted
|
||||
*
|
||||
* @param deltaTimeInMillis The number of milliseconds that have passed since last frame
|
||||
* @return If true, the node can be deleted after process() finishes
|
||||
*/
|
||||
bool process(uint32 deltaTimeInMillis) override;
|
||||
|
||||
void setVolume(uint8 volume) override;
|
||||
|
||||
void setFade(int32 time, uint8 target) override;
|
||||
|
||||
private:
|
||||
void outputMixer() override;
|
||||
bool _loop;
|
||||
bool _fade;
|
||||
uint8 _fadeStartVol;
|
||||
uint8 _fadeEndVol;
|
||||
uint32 _fadeTime;
|
||||
uint32 _fadeElapsed; // Cumulative time since fade start
|
||||
bool _stereo;
|
||||
Audio::SoundHandle _handle;
|
||||
uint16 _sub;
|
||||
bool _loaded;
|
||||
};
|
||||
|
||||
// Only used by Zork: Nemesis, for the flute and piano puzzles (tj4e and ve6f, as well as vr)
|
||||
class MusicMidiNode : public MusicNodeBASE {
|
||||
public:
|
||||
MusicMidiNode(ZVision *engine, uint32 key, uint8 program, uint8 note, uint8 volume);
|
||||
~MusicMidiNode() override;
|
||||
|
||||
/**
|
||||
* Decrement the timer by the delta time. If the timer is finished, set the status
|
||||
* in _globalState and let this node be deleted
|
||||
*
|
||||
* @param deltaTimeInMillis The number of milliseconds that have passed since last frame
|
||||
* @return If true, the node can be deleted after process() finishes
|
||||
*/
|
||||
bool process(uint32 deltaTimeInMillis) override;
|
||||
|
||||
void setVolume(uint8 volume) override;
|
||||
|
||||
void setFade(int32 time, uint8 target) override;
|
||||
|
||||
private:
|
||||
void outputMixer() override;
|
||||
int8 _chan;
|
||||
uint8 _noteNumber;
|
||||
int8 _pan;
|
||||
uint8 _prog;
|
||||
};
|
||||
|
||||
class PanTrackNode : public ScriptingEffect {
|
||||
public:
|
||||
PanTrackNode(ZVision *engine, uint32 key, uint32 slot, int16 pos, uint8 mag = 255, bool resetMixerOnDelete = false, bool staticScreen = false);
|
||||
~PanTrackNode() override;
|
||||
|
||||
bool process(uint32 deltaTimeInMillis) override;
|
||||
|
||||
private:
|
||||
uint32 _slot;
|
||||
int16 _width, _pos;
|
||||
Math::Angle _sourcePos, _viewPos;
|
||||
uint8 _mag;
|
||||
bool _resetMixerOnDelete;
|
||||
bool _staticScreen;
|
||||
};
|
||||
|
||||
} // End of namespace ZVision
|
||||
|
||||
#endif
|
||||
53
engines/zvision/scripting/effects/region_effect.cpp
Normal file
53
engines/zvision/scripting/effects/region_effect.cpp
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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "zvision/zvision.h"
|
||||
#include "zvision/graphics/render_manager.h"
|
||||
#include "zvision/scripting/script_manager.h"
|
||||
#include "zvision/scripting/effects/region_effect.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
RegionNode::RegionNode(ZVision *engine, uint32 key, GraphicsEffect *effect, uint32 delay)
|
||||
: ScriptingEffect(engine, key, SCRIPTING_EFFECT_REGION) {
|
||||
_effect = effect;
|
||||
_delay = delay;
|
||||
_timeLeft = 0;
|
||||
}
|
||||
|
||||
RegionNode::~RegionNode() {
|
||||
_engine->getRenderManager()->deleteEffect(_key);
|
||||
}
|
||||
|
||||
bool RegionNode::process(uint32 deltaTimeInMillis) {
|
||||
_timeLeft -= deltaTimeInMillis;
|
||||
|
||||
if (_timeLeft <= 0) {
|
||||
_timeLeft = _delay;
|
||||
if (_effect)
|
||||
_effect->update();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End of namespace ZVision
|
||||
55
engines/zvision/scripting/effects/region_effect.h
Normal file
55
engines/zvision/scripting/effects/region_effect.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_REGION_NODE_H
|
||||
#define ZVISION_REGION_NODE_H
|
||||
|
||||
#include "graphics/surface.h"
|
||||
#include "zvision/graphics/graphics_effect.h"
|
||||
#include "zvision/scripting/scripting_effect.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
class ZVision;
|
||||
|
||||
class RegionNode : public ScriptingEffect {
|
||||
public:
|
||||
RegionNode(ZVision *engine, uint32 key, GraphicsEffect *effect, uint32 delay);
|
||||
~RegionNode() override;
|
||||
|
||||
/**
|
||||
* Decrement the timer by the delta time. If the timer is finished, set the status
|
||||
* in _globalState and let this node be deleted
|
||||
*
|
||||
* @param deltaTimeInMillis The number of milliseconds that have passed since last frame
|
||||
* @return If true, the node can be deleted after process() finishes
|
||||
*/
|
||||
bool process(uint32 deltaTimeInMillis) override;
|
||||
|
||||
private:
|
||||
int32 _timeLeft;
|
||||
uint32 _delay;
|
||||
GraphicsEffect *_effect;
|
||||
};
|
||||
|
||||
} // End of namespace ZVision
|
||||
|
||||
#endif
|
||||
80
engines/zvision/scripting/effects/syncsound_effect.cpp
Normal file
80
engines/zvision/scripting/effects/syncsound_effect.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
/* 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 "audio/decoders/wave.h"
|
||||
#include "common/file.h"
|
||||
#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/effects/syncsound_effect.h"
|
||||
#include "zvision/sound/zork_raw.h"
|
||||
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
SyncSoundNode::SyncSoundNode(ZVision *engine, uint32 key, Common::Path &filename, int32 syncto)
|
||||
: ScriptingEffect(engine, key, SCRIPTING_EFFECT_AUDIO) {
|
||||
_syncto = syncto;
|
||||
_sub = 0;
|
||||
|
||||
Audio::RewindableAudioStream *audioStream = NULL;
|
||||
|
||||
if (filename.baseName().contains(".wav")) {
|
||||
Common::File *file = new Common::File();
|
||||
if (file->open(filename)) {
|
||||
audioStream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
|
||||
}
|
||||
} else {
|
||||
audioStream = makeRawZorkStream(filename, _engine);
|
||||
}
|
||||
|
||||
_engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, audioStream);
|
||||
|
||||
Common::String subname = filename.baseName();
|
||||
subname.setChar('s', subname.size() - 3);
|
||||
subname.setChar('u', subname.size() - 2);
|
||||
subname.setChar('b', subname.size() - 1);
|
||||
|
||||
Common::Path subpath(filename.getParent().appendComponent(subname));
|
||||
if (SearchMan.hasFile(subpath))
|
||||
_sub = _engine->getSubtitleManager()->create(subpath, _handle); // NB automatic subtitle!
|
||||
}
|
||||
|
||||
SyncSoundNode::~SyncSoundNode() {
|
||||
_engine->_mixer->stopHandle(_handle);
|
||||
if (_sub)
|
||||
_engine->getSubtitleManager()->destroy(_sub);
|
||||
}
|
||||
|
||||
bool SyncSoundNode::process(uint32 deltaTimeInMillis) {
|
||||
if (! _engine->_mixer->isSoundHandleActive(_handle))
|
||||
return stop();
|
||||
else {
|
||||
|
||||
if (_engine->getScriptManager()->getSideFX(_syncto) == NULL)
|
||||
return stop();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End of namespace ZVision
|
||||
55
engines/zvision/scripting/effects/syncsound_effect.h
Normal file
55
engines/zvision/scripting/effects/syncsound_effect.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_SYNCSOUND_NODE_H
|
||||
#define ZVISION_SYNCSOUND_NODE_H
|
||||
|
||||
#include "audio/mixer.h"
|
||||
#include "zvision/scripting/scripting_effect.h"
|
||||
#include "zvision/text/subtitle_manager.h"
|
||||
|
||||
namespace Common {
|
||||
class String;
|
||||
}
|
||||
|
||||
namespace ZVision {
|
||||
class SyncSoundNode : public ScriptingEffect {
|
||||
public:
|
||||
SyncSoundNode(ZVision *engine, uint32 key, Common::Path &file, int32 syncto);
|
||||
~SyncSoundNode() override;
|
||||
|
||||
/**
|
||||
* Decrement the timer by the delta time. If the timer is finished, set the status
|
||||
* in _globalState and let this node be deleted
|
||||
*
|
||||
* @param deltaTimeInMillis The number of milliseconds that have passed since last frame
|
||||
* @return If true, the node can be deleted after process() finishes
|
||||
*/
|
||||
bool process(uint32 deltaTimeInMillis) override;
|
||||
private:
|
||||
int32 _syncto;
|
||||
Audio::SoundHandle _handle;
|
||||
uint16 _sub;
|
||||
};
|
||||
|
||||
} // End of namespace ZVision
|
||||
|
||||
#endif
|
||||
77
engines/zvision/scripting/effects/timer_effect.cpp
Normal file
77
engines/zvision/scripting/effects/timer_effect.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
/* 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/scripting/script_manager.h"
|
||||
#include "zvision/scripting/effects/timer_effect.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
TimerNode::TimerNode(ZVision *engine, uint32 key, uint timeInSeconds)
|
||||
: ScriptingEffect(engine, key, SCRIPTING_EFFECT_TIMER) {
|
||||
_timeLeft = 0;
|
||||
|
||||
if (_engine->getGameId() == GID_NEMESIS)
|
||||
_timeLeft = timeInSeconds * 1000;
|
||||
else if (_engine->getGameId() == GID_GRANDINQUISITOR)
|
||||
_timeLeft = timeInSeconds * 100;
|
||||
|
||||
if (_key != StateKey_NotSet)
|
||||
_engine->getScriptManager()->setStateValue(_key, 1);
|
||||
}
|
||||
|
||||
TimerNode::~TimerNode() {
|
||||
if (_key != StateKey_NotSet)
|
||||
_engine->getScriptManager()->setStateValue(_key, 2);
|
||||
int32 timeLeft = _timeLeft / (_engine->getGameId() == GID_NEMESIS ? 1000 : 100);
|
||||
if (timeLeft > 0)
|
||||
_engine->getScriptManager()->setStateValue(_key, timeLeft); // If timer was stopped by stop or kill
|
||||
}
|
||||
|
||||
bool TimerNode::process(uint32 deltaTimeInMillis) {
|
||||
_timeLeft -= deltaTimeInMillis;
|
||||
|
||||
if (_timeLeft <= 0)
|
||||
return stop();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TimerNode::stop() {
|
||||
if (_key != StateKey_NotSet)
|
||||
_engine->getScriptManager()->setStateValue(_key, 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
void TimerNode::serialize(Common::WriteStream *stream) {
|
||||
stream->writeUint32BE(MKTAG('T', 'I', 'M', 'R'));
|
||||
stream->writeUint32LE(8); // size
|
||||
stream->writeUint32LE(_key);
|
||||
stream->writeUint32LE(_timeLeft);
|
||||
}
|
||||
|
||||
void TimerNode::deserialize(Common::SeekableReadStream *stream) {
|
||||
_timeLeft = stream->readUint32LE();
|
||||
}
|
||||
|
||||
} // End of namespace ZVision
|
||||
58
engines/zvision/scripting/effects/timer_effect.h
Normal file
58
engines/zvision/scripting/effects/timer_effect.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/* 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_TIMER_NODE_H
|
||||
#define ZVISION_TIMER_NODE_H
|
||||
|
||||
#include "zvision/scripting/scripting_effect.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
class ZVision;
|
||||
|
||||
class TimerNode : public ScriptingEffect {
|
||||
public:
|
||||
TimerNode(ZVision *engine, uint32 key, uint timeInSeconds);
|
||||
~TimerNode() override;
|
||||
|
||||
/**
|
||||
* Decrement the timer by the delta time. If the timer is finished, set the status
|
||||
* in _globalState and let this node be deleted
|
||||
*
|
||||
* @param deltaTimeInMillis The number of milliseconds that have passed since last frame
|
||||
* @return If true, the node can be deleted after process() finishes
|
||||
*/
|
||||
bool process(uint32 deltaTimeInMillis) override;
|
||||
void serialize(Common::WriteStream *stream) override;
|
||||
void deserialize(Common::SeekableReadStream *stream) override;
|
||||
inline bool needsSerialization() override {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool stop() override;
|
||||
|
||||
private:
|
||||
int32 _timeLeft;
|
||||
};
|
||||
|
||||
} // End of namespace ZVision
|
||||
|
||||
#endif
|
||||
199
engines/zvision/scripting/effects/ttytext_effect.cpp
Normal file
199
engines/zvision/scripting/effects/ttytext_effect.cpp
Normal file
@@ -0,0 +1,199 @@
|
||||
/* 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/unicode-bidi.h"
|
||||
#include "zvision/zvision.h"
|
||||
#include "zvision/graphics/render_manager.h"
|
||||
#include "zvision/scripting/script_manager.h"
|
||||
#include "zvision/scripting/effects/ttytext_effect.h"
|
||||
#include "zvision/text/text.h"
|
||||
|
||||
namespace ZVision {
|
||||
|
||||
ttyTextNode::ttyTextNode(ZVision *engine, uint32 key, const Common::Path &file, const Common::Rect &r, int32 delay) :
|
||||
ScriptingEffect(engine, key, SCRIPTING_EFFECT_TTYTXT),
|
||||
_fnt(engine) {
|
||||
_delay = delay;
|
||||
_r = r;
|
||||
_txtpos = 0;
|
||||
_nexttime = 0;
|
||||
_dx = 0;
|
||||
_dy = 0;
|
||||
_lineStartPos = 0;
|
||||
_startX = 0;
|
||||
|
||||
Common::File *infile = new Common::File;
|
||||
infile->open(file);
|
||||
if (infile) {
|
||||
while (!infile->eos()) {
|
||||
Common::U32String asciiLine = readWideLine(*infile);
|
||||
if (asciiLine.empty()) {
|
||||
continue;
|
||||
}
|
||||
_txtbuf += asciiLine;
|
||||
}
|
||||
|
||||
delete infile;
|
||||
}
|
||||
_isRTL = Common::convertBiDiU32String(_txtbuf).visual != _txtbuf;
|
||||
_img.create(_r.width(), _r.height(), _engine->_resourcePixelFormat);
|
||||
_state._sharp = true;
|
||||
_state.readAllStyles(_txtbuf.encode());
|
||||
_state.updateFontWithTextState(_fnt);
|
||||
_engine->getScriptManager()->setStateValue(_key, 1);
|
||||
}
|
||||
|
||||
ttyTextNode::~ttyTextNode() {
|
||||
_engine->getScriptManager()->setStateValue(_key, 2);
|
||||
_img.free();
|
||||
}
|
||||
|
||||
bool ttyTextNode::process(uint32 deltaTimeInMillis) {
|
||||
_nexttime -= deltaTimeInMillis;
|
||||
|
||||
if (_nexttime < 0) {
|
||||
if (_txtpos < _txtbuf.size()) {
|
||||
if (_txtbuf[_txtpos] == '<') {
|
||||
int32 start = _txtpos;
|
||||
int32 end = 0;
|
||||
int16 ret = 0;
|
||||
while (_txtbuf[_txtpos] != '>' && _txtpos < _txtbuf.size())
|
||||
_txtpos++;
|
||||
end = _txtpos;
|
||||
if (start != -1) {
|
||||
if ((end - start - 1) > 0) {
|
||||
Common::String buf = _txtbuf.substr(start + 1, end - start - 1);
|
||||
ret = _state.parseStyle(buf, buf.size());
|
||||
}
|
||||
}
|
||||
|
||||
if (ret & (TEXT_CHANGE_FONT_TYPE | TEXT_CHANGE_FONT_STYLE)) {
|
||||
_state.updateFontWithTextState(_fnt);
|
||||
} else if (ret & TEXT_CHANGE_NEWLINE) {
|
||||
newline();
|
||||
}
|
||||
|
||||
if (ret & TEXT_CHANGE_HAS_STATE_BOX) {
|
||||
Common::String buf;
|
||||
buf = Common::String::format("%d", _engine->getScriptManager()->getStateValue(_state._statebox));
|
||||
|
||||
if (_isRTL) {
|
||||
int16 currDx = _dx + _fnt.getStringWidth(buf);
|
||||
_dx = _r.width() - currDx;
|
||||
_isRTL = false;
|
||||
for (uint8 j = 0; j < buf.size(); j++)
|
||||
outchar(buf[j]);
|
||||
_isRTL = true;
|
||||
_dx = currDx;
|
||||
} else {
|
||||
for (uint8 j = 0; j < buf.size(); j++)
|
||||
outchar(buf[j]);
|
||||
}
|
||||
}
|
||||
|
||||
_txtpos++;
|
||||
_lineStartPos = _txtpos;
|
||||
_startX = _dx;
|
||||
} else {
|
||||
uint32 pos = _lineStartPos;
|
||||
int16 dx = _startX;
|
||||
|
||||
while (pos < _txtbuf.size() && _txtbuf[pos] != '<') {
|
||||
uint16 chr = _txtbuf[pos];
|
||||
|
||||
if (chr == ' ') {
|
||||
uint32 i = pos + 1;
|
||||
uint16 width = _fnt.getCharWidth(chr);
|
||||
|
||||
while (i < _txtbuf.size() && _txtbuf[i] != ' ' && _txtbuf[i] != '<') {
|
||||
|
||||
uint16 uchr = _txtbuf[i];
|
||||
|
||||
width += _fnt.getCharWidth(uchr);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if (dx + width > _r.width())
|
||||
break;
|
||||
}
|
||||
dx += _fnt.getCharWidth(chr);
|
||||
pos++;
|
||||
}
|
||||
|
||||
Common::U32String lineBuffer = Common::convertBiDiU32String(_txtbuf.substr(_lineStartPos, pos - _lineStartPos)).visual;
|
||||
if (pos == _txtpos)
|
||||
newline();
|
||||
else if (_isRTL)
|
||||
outchar(lineBuffer[pos - _txtpos - 1]);
|
||||
else
|
||||
outchar(lineBuffer[_txtpos - _lineStartPos]);
|
||||
|
||||
_txtpos++;
|
||||
}
|
||||
_nexttime = _delay;
|
||||
_engine->getRenderManager()->blitSurfaceToBkg(_img, _r.left, _r.top);
|
||||
} else
|
||||
return stop();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ttyTextNode::scroll() {
|
||||
int32 scrl = 0;
|
||||
while (_dy - scrl > _r.height() - _fnt.getFontHeight())
|
||||
scrl += _fnt.getFontHeight();
|
||||
int8 *pixels = (int8 *)_img.getPixels();
|
||||
for (uint16 h = scrl; h < _img.h; h++)
|
||||
memcpy(pixels + _img.pitch * (h - scrl), pixels + _img.pitch * h, _img.pitch);
|
||||
|
||||
_img.fillRect(Common::Rect(0, _img.h - scrl, _img.w, _img.h), 0);
|
||||
_dy -= scrl;
|
||||
}
|
||||
|
||||
void ttyTextNode::newline() {
|
||||
_dy += _fnt.getFontHeight();
|
||||
_dx = 0;
|
||||
_lineStartPos = _txtpos + 1;
|
||||
_startX = _dx;
|
||||
}
|
||||
|
||||
void ttyTextNode::outchar(uint16 chr) {
|
||||
uint32 clr = _engine->_resourcePixelFormat.RGBToColor(_state._red, _state._green, _state._blue);
|
||||
|
||||
if (_dx + _fnt.getCharWidth(chr) > _r.width())
|
||||
newline();
|
||||
|
||||
if (_dy + _fnt.getFontHeight() >= _r.height())
|
||||
scroll();
|
||||
|
||||
if (_isRTL)
|
||||
_fnt.drawChar(&_img, chr, _r.width() - _dx - _fnt.getCharWidth(chr), _dy, clr);
|
||||
else
|
||||
_fnt.drawChar(&_img, chr, _dx, _dy, clr);
|
||||
_dx += _fnt.getCharWidth(chr);
|
||||
}
|
||||
|
||||
} // End of namespace ZVision
|
||||
74
engines/zvision/scripting/effects/ttytext_effect.h
Normal file
74
engines/zvision/scripting/effects/ttytext_effect.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_TTYTEXT_NODE_H
|
||||
#define ZVISION_TTYTEXT_NODE_H
|
||||
|
||||
#include "common/rect.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "zvision/scripting/scripting_effect.h"
|
||||
#include "zvision/text/text.h"
|
||||
#include "zvision/text/truetype_font.h"
|
||||
|
||||
namespace Common {
|
||||
class String;
|
||||
}
|
||||
|
||||
namespace ZVision {
|
||||
class ttyTextNode : public ScriptingEffect {
|
||||
public:
|
||||
ttyTextNode(ZVision *engine, uint32 key, const Common::Path &file, const Common::Rect &r, int32 delay);
|
||||
~ttyTextNode() override;
|
||||
|
||||
/**
|
||||
* Decrement the timer by the delta time. If the timer is finished, set the status
|
||||
* in _globalState and let this node be deleted
|
||||
*
|
||||
* @param deltaTimeInMillis The number of milliseconds that have passed since last frame
|
||||
* @return If true, the node can be deleted after process() finishes
|
||||
*/
|
||||
bool process(uint32 deltaTimeInMillis) override;
|
||||
private:
|
||||
Common::Rect _r;
|
||||
|
||||
TextStyleState _state;
|
||||
StyledTTFont _fnt;
|
||||
Common::U32String _txtbuf;
|
||||
uint32 _txtpos;
|
||||
uint32 _lineStartPos;
|
||||
bool _isRTL;
|
||||
|
||||
int32 _delay;
|
||||
int32 _nexttime;
|
||||
Graphics::Surface _img;
|
||||
int16 _dx;
|
||||
int16 _startX;
|
||||
int16 _dy;
|
||||
private:
|
||||
|
||||
void newline();
|
||||
void scroll();
|
||||
void outchar(uint16 chr);
|
||||
};
|
||||
|
||||
} // End of namespace ZVision
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user