Initial commit
This commit is contained in:
575
engines/titanic/support/avi_surface.cpp
Normal file
575
engines/titanic/support/avi_surface.cpp
Normal file
@@ -0,0 +1,575 @@
|
||||
/* 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 "titanic/support/avi_surface.h"
|
||||
#include "titanic/support/screen_manager.h"
|
||||
#include "titanic/support/video_surface.h"
|
||||
#include "titanic/events.h"
|
||||
#include "titanic/titanic.h"
|
||||
#include "common/system.h"
|
||||
#include "graphics/pixelformat.h"
|
||||
#include "graphics/screen.h"
|
||||
#include "video/avi_decoder.h"
|
||||
#include "titanic/translation.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
#define DEFAULT_FPS 15.0
|
||||
|
||||
Video::AVIDecoder::AVIVideoTrack &AVIDecoder::getVideoTrack(uint idx) {
|
||||
assert(idx < _videoTracks.size());
|
||||
AVIVideoTrack *track = static_cast<AVIVideoTrack *>(_videoTracks[idx].track);
|
||||
return *track;
|
||||
}
|
||||
|
||||
AVISurface::AVISurface(const CResourceKey &key) : _movieName(key.getString()) {
|
||||
_videoSurface = nullptr;
|
||||
_streamCount = 0;
|
||||
_movieFrameSurface[0] = _movieFrameSurface[1] = nullptr;
|
||||
_framePixels = false;
|
||||
_priorFrameTime = 0;
|
||||
|
||||
// Reset current frame. We need to keep track of frames separately from the decoder,
|
||||
// since it needs to be able to go beyond the frame count or to negative to allow
|
||||
// correct detection of when range playbacks have finished
|
||||
_currentFrame = -1;
|
||||
_priorFrame = -1;
|
||||
|
||||
// Create a decoder
|
||||
_decoder = new AVIDecoder();
|
||||
|
||||
// Load the video into it
|
||||
if (_movieName == TRANSLATE("y222.avi", "y237.avi")) {
|
||||
// The y222.avi is the bells animation for the music room.
|
||||
// It needs on the fly fixing for the video header
|
||||
_decoder->loadStream(new y222());
|
||||
} else if (!_decoder->loadFile(Common::Path(_movieName))) {
|
||||
error("Could not open video - %s", key.getString().c_str());
|
||||
}
|
||||
|
||||
_streamCount = _decoder->getTransparencyTrack() ? 2 : 1;
|
||||
|
||||
_soundManager = nullptr;
|
||||
_hasAudio = false;
|
||||
_frameRate = DEFAULT_FPS;
|
||||
}
|
||||
|
||||
AVISurface::~AVISurface() {
|
||||
if (_videoSurface)
|
||||
_videoSurface->_flipVertically = false;
|
||||
delete _movieFrameSurface[0];
|
||||
delete _movieFrameSurface[1];
|
||||
delete _decoder;
|
||||
}
|
||||
|
||||
bool AVISurface::play(uint flags, CGameObject *obj) {
|
||||
if (flags & MOVIE_REVERSE)
|
||||
return play(_decoder->getFrameCount() - 1, 0, flags, obj);
|
||||
else
|
||||
return play(0, _decoder->getFrameCount() - 1, flags, obj);
|
||||
}
|
||||
|
||||
bool AVISurface::play(int startFrame, int endFrame, uint flags, CGameObject *obj) {
|
||||
if (flags & MOVIE_STOP_PREVIOUS)
|
||||
stop();
|
||||
|
||||
return play(startFrame, endFrame, -1, flags, obj);
|
||||
}
|
||||
|
||||
bool AVISurface::play(int startFrame, int endFrame, int initialFrame, uint flags, CGameObject *obj) {
|
||||
CMovieRangeInfo *info = new CMovieRangeInfo();
|
||||
info->_startFrame = startFrame;
|
||||
info->_endFrame = endFrame;
|
||||
info->_isReversed = endFrame < startFrame;
|
||||
info->_initialFrame = 0;
|
||||
info->_isRepeat = flags & MOVIE_REPEAT;
|
||||
|
||||
if (obj) {
|
||||
CMovieEvent *me = new CMovieEvent();
|
||||
me->_type = MET_MOVIE_END;
|
||||
me->_startFrame = startFrame;
|
||||
me->_endFrame = endFrame;
|
||||
me->_initialFrame = 0;
|
||||
me->_gameObject = obj;
|
||||
|
||||
info->addEvent(me);
|
||||
}
|
||||
|
||||
_movieRangeInfo.push_back(info);
|
||||
|
||||
if (_movieRangeInfo.size() == 1) {
|
||||
// First play call, so start the movie playing
|
||||
bool isReversePlayback = _movieRangeInfo.front()->_endFrame < _movieRangeInfo.front()->_startFrame;
|
||||
|
||||
if (isReversed() != isReversePlayback)
|
||||
setFrameRate(isReversePlayback ? -DEFAULT_FPS : DEFAULT_FPS);
|
||||
return startAtFrame(initialFrame);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void AVISurface::stop() {
|
||||
_decoder->stop();
|
||||
_movieRangeInfo.destroyContents();
|
||||
}
|
||||
|
||||
void AVISurface::pause() {
|
||||
_decoder->pauseVideo(true);
|
||||
}
|
||||
|
||||
void AVISurface::resume() {
|
||||
if (_decoder->isPaused())
|
||||
_decoder->pauseVideo(false);
|
||||
}
|
||||
|
||||
bool AVISurface::startAtFrame(int frameNumber) {
|
||||
if (isPlaying())
|
||||
// If it's already playing, then don't allow it
|
||||
return false;
|
||||
|
||||
if (frameNumber == -1)
|
||||
// Default to starting frame of first movie range
|
||||
frameNumber = _movieRangeInfo.front()->_startFrame;
|
||||
|
||||
if (frameNumber == (int)_decoder->getFrameCount())
|
||||
--frameNumber;
|
||||
|
||||
// Start the playback
|
||||
_decoder->start();
|
||||
|
||||
// Seek to the starting frame
|
||||
_currentFrame = -1;
|
||||
seekToFrame(frameNumber);
|
||||
|
||||
// If we're in reverse playback, set the decoder to play in reverse
|
||||
if (isReversed())
|
||||
_decoder->setReverse(true);
|
||||
setFrameRate(_frameRate);
|
||||
|
||||
// Render the first frame
|
||||
renderFrame();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AVISurface::seekToFrame(uint frameNumber) {
|
||||
if (isReversed() && frameNumber == _decoder->getFrameCount())
|
||||
--frameNumber;
|
||||
|
||||
if ((int)frameNumber != _currentFrame) {
|
||||
if (!isReversed() && frameNumber > 0) {
|
||||
_decoder->seekToFrame(frameNumber - 1);
|
||||
renderFrame();
|
||||
}
|
||||
|
||||
_decoder->seekToFrame(frameNumber);
|
||||
_currentFrame = _priorFrame = (int)frameNumber;
|
||||
}
|
||||
}
|
||||
|
||||
bool AVISurface::handleEvents(CMovieEventList &events) {
|
||||
if (!isPlaying())
|
||||
return true;
|
||||
|
||||
CMovieRangeInfo *info = _movieRangeInfo.front();
|
||||
_priorFrame = _currentFrame;
|
||||
_currentFrame += isReversed() ? -1 : 1;
|
||||
|
||||
int newFrame = _currentFrame;
|
||||
if ((info->_isReversed && newFrame < info->_endFrame) ||
|
||||
(!info->_isReversed && newFrame > info->_endFrame)) {
|
||||
if (info->_isRepeat) {
|
||||
newFrame = info->_startFrame;
|
||||
} else {
|
||||
info->getMovieEnd(events);
|
||||
_movieRangeInfo.remove(info);
|
||||
delete info;
|
||||
|
||||
if (_movieRangeInfo.empty()) {
|
||||
// No more ranges, so stop playback
|
||||
stop();
|
||||
} else {
|
||||
// Not empty, so move onto new first one
|
||||
info = _movieRangeInfo.front();
|
||||
newFrame = info->_startFrame;
|
||||
bool reversed = info->_endFrame < info->_startFrame;
|
||||
|
||||
if (isReversed() != reversed)
|
||||
// Direction is different, so force frame seek below
|
||||
_priorFrame = -1;
|
||||
|
||||
// Set the next clip's direction
|
||||
setFrameRate(reversed ? -DEFAULT_FPS : DEFAULT_FPS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isPlaying()) {
|
||||
if (newFrame != getFrame())
|
||||
// The frame has been changed, so move to new position
|
||||
seekToFrame(newFrame);
|
||||
|
||||
// Get any events for the given position
|
||||
info->getMovieFrame(events, newFrame);
|
||||
return renderFrame();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void AVISurface::setVideoSurface(CVideoSurface *surface) {
|
||||
_videoSurface = surface;
|
||||
|
||||
// Handling for secondary video stream
|
||||
if (_streamCount == 2) {
|
||||
const Common::String &streamName = _decoder->getTransparencyTrack()->getName();
|
||||
|
||||
if (streamName == "mask0") {
|
||||
_videoSurface->_transparencyMode = TRANS_MASK0;
|
||||
} else if (streamName == "mask255") {
|
||||
_videoSurface->_transparencyMode = TRANS_MASK255;
|
||||
} else if (streamName == "alpha0") {
|
||||
_videoSurface->_transparencyMode = TRANS_ALPHA0;
|
||||
} else if (streamName == "alpha255") {
|
||||
_videoSurface->_transparencyMode = TRANS_ALPHA255;
|
||||
}
|
||||
}
|
||||
|
||||
setupDecompressor();
|
||||
}
|
||||
|
||||
void AVISurface::setupDecompressor() {
|
||||
if (!_decoder)
|
||||
return;
|
||||
|
||||
for (int idx = 0; idx < _streamCount; ++idx) {
|
||||
Graphics::PixelFormat format = (idx == 0) ?
|
||||
_decoder->getVideoTrack(0).getPixelFormat() :
|
||||
_decoder->getTransparencyTrack()->getPixelFormat();
|
||||
int decoderPitch = _decoder->getWidth() * format.bytesPerPixel;
|
||||
bool flag = false;
|
||||
|
||||
if (idx == 0 && _videoSurface && _videoSurface->getPitch() == decoderPitch) {
|
||||
const uint bitCount = _decoder->getVideoTrack(0).getBitCount();
|
||||
const int vDepth = _videoSurface->getPixelDepth();
|
||||
|
||||
switch (bitCount) {
|
||||
case 15:
|
||||
flag = vDepth == 1;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
flag = vDepth == 1 || vDepth == 2;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
flag = vDepth == 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!flag) {
|
||||
_framePixels = true;
|
||||
} else if (idx == 0) {
|
||||
// The original developers used a vertical flipped playback to indicate
|
||||
// an incompatibility between source video and dest surface bit-depths,
|
||||
// which would result in poor playback performance
|
||||
_videoSurface->_flipVertically = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Set a default frame rate
|
||||
_frameRate = DEFAULT_FPS;
|
||||
}
|
||||
|
||||
void AVISurface::copyMovieFrame(const Graphics::Surface &src, Graphics::ManagedSurface &dest) {
|
||||
// WORKAROUND: Handle rare cases where frame sizes don't match the video size
|
||||
Common::Rect copyRect(0, 0, MIN(src.w, dest.w), MIN(src.h, dest.h));
|
||||
|
||||
if (src.format.bytesPerPixel == 1) {
|
||||
// Paletted 8-bit, so convert to 16-bit and copy over
|
||||
const byte *palette = _decoder->getPalette();
|
||||
if (palette) {
|
||||
Graphics::Surface *s = src.convertTo(dest.format, palette);
|
||||
dest.blitFrom(*s, copyRect, Common::Point(0, 0));
|
||||
s->free();
|
||||
delete s;
|
||||
}
|
||||
} else if ((src.format.bytesPerPixel == 2) || (src.format.bytesPerPixel == 3)) {
|
||||
// Source is 16-bit or 24-bit, with no alpha, so do a straight copy
|
||||
dest.blitFrom(src, copyRect, Common::Point(0, 0));
|
||||
} else {
|
||||
// Source is 32-bit which may have transparent pixels. Copy over each
|
||||
// pixel, replacing transparent pixels with the special transparency color
|
||||
byte a, r, g, b;
|
||||
assert(src.format.bytesPerPixel == 4 && dest.format.bytesPerPixel == 2);
|
||||
uint16 transPixel = _videoSurface->getTransparencyColor();
|
||||
|
||||
for (uint y = 0; y < (uint)MIN(src.h, dest.h); ++y) {
|
||||
const uint32 *pSrc = (const uint32 *)src.getBasePtr(0, y);
|
||||
uint16 *pDest = (uint16 *)dest.getBasePtr(0, y);
|
||||
|
||||
for (uint x = 0; x < (uint)MIN(src.w, dest.w); ++x, ++pSrc, ++pDest) {
|
||||
src.format.colorToARGB(*pSrc, a, r, g, b);
|
||||
assert(a == 0 || a == 0xff);
|
||||
|
||||
*pDest = (a == 0 && _streamCount == 1) ? transPixel : dest.format.RGBToColor(r, g, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint AVISurface::getWidth() const {
|
||||
return _decoder->getWidth();
|
||||
}
|
||||
|
||||
uint AVISurface::getHeight() const {
|
||||
return _decoder->getHeight();
|
||||
}
|
||||
|
||||
void AVISurface::setFrame(int frameNumber) {
|
||||
// If playback was in process, stop it
|
||||
if (isPlaying())
|
||||
stop();
|
||||
|
||||
// Ensure the frame number is valid
|
||||
if (frameNumber >= (int)_decoder->getFrameCount())
|
||||
frameNumber = _decoder->getFrameCount() - 1;
|
||||
|
||||
seekToFrame(frameNumber);
|
||||
renderFrame();
|
||||
}
|
||||
|
||||
bool AVISurface::isNextFrame() {
|
||||
if (!_decoder->endOfVideo())
|
||||
return _decoder->getTimeToNextFrame() == 0;
|
||||
|
||||
// We're at the end of the video, so we need to manually
|
||||
// keep track of frame delays.
|
||||
const uint FRAME_TIME = 1000 / DEFAULT_FPS;
|
||||
uint32 currTime = g_system->getMillis();
|
||||
if (currTime >= (_priorFrameTime + FRAME_TIME)) {
|
||||
_priorFrameTime = currTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AVISurface::renderFrame() {
|
||||
// Check there's a frame ready for display
|
||||
if (!_decoder->needsUpdate())
|
||||
return false;
|
||||
|
||||
// Make a copy of each decoder's video frame
|
||||
for (int idx = 0; idx < _streamCount; ++idx) {
|
||||
const Graphics::Surface *frame;
|
||||
|
||||
if (idx == 0) {
|
||||
frame = _decoder->decodeNextFrame();
|
||||
if (!_movieFrameSurface[0])
|
||||
_movieFrameSurface[0] = new Graphics::ManagedSurface(_decoder->getWidth(), _decoder->getHeight(),
|
||||
g_system->getScreenFormat());
|
||||
|
||||
copyMovieFrame(*frame, *_movieFrameSurface[0]);
|
||||
} else {
|
||||
frame = _decoder->decodeNextTransparency();
|
||||
if (!_movieFrameSurface[1])
|
||||
_movieFrameSurface[1] = new Graphics::ManagedSurface(_decoder->getWidth(), _decoder->getHeight(),
|
||||
Graphics::PixelFormat::createFormatCLUT8());
|
||||
|
||||
_movieFrameSurface[1]->blitFrom(*frame);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_framePixels) {
|
||||
if (_videoSurface->lock()) {
|
||||
// Blit the frame directly to the video surface
|
||||
assert(_streamCount == 1);
|
||||
_videoSurface->blitFrom(Point(0, 0), &_movieFrameSurface[0]->rawSurface());
|
||||
|
||||
_videoSurface->unlock();
|
||||
}
|
||||
} else {
|
||||
const Graphics::Surface &frameSurface = _movieFrameSurface[0]->rawSurface();
|
||||
_videoSurface->lock();
|
||||
|
||||
if (frameSurface.format.bytesPerPixel == 1) {
|
||||
// For paletted 8-bit surfaces, we need to convert it to 16-bit,
|
||||
// since the blitting method we're using doesn't support palettes
|
||||
Graphics::Surface *s = frameSurface.convertTo(g_system->getScreenFormat(),
|
||||
_decoder->getPalette());
|
||||
|
||||
_videoSurface->getRawSurface()->blitFrom(*s);
|
||||
s->free();
|
||||
delete s;
|
||||
} else {
|
||||
_videoSurface->getRawSurface()->blitFrom(frameSurface);
|
||||
}
|
||||
|
||||
_videoSurface->unlock();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AVISurface::addEvent(int *frameNumber, CGameObject *obj) {
|
||||
if (!_movieRangeInfo.empty()) {
|
||||
CMovieRangeInfo *tail = _movieRangeInfo.back();
|
||||
assert(frameNumber);
|
||||
if (*frameNumber == -1)
|
||||
*frameNumber = tail->_startFrame;
|
||||
|
||||
CMovieEvent *me = new CMovieEvent();
|
||||
me->_type = MET_FRAME;
|
||||
me->_startFrame = 0;
|
||||
me->_endFrame = 0;
|
||||
me->_initialFrame = *frameNumber;
|
||||
me->_gameObject = obj;
|
||||
tail->addEvent(me);
|
||||
|
||||
return _movieRangeInfo.size() == 1 && *frameNumber == getFrame();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AVISurface::setFrameRate(double rate) {
|
||||
// Store the new frame rate
|
||||
_frameRate = rate;
|
||||
|
||||
if (_decoder->isPlaying()) {
|
||||
// Convert rate from fps to relative to 1.0 (normal speed)
|
||||
const int PRECISION = 10000;
|
||||
double playRate = rate / DEFAULT_FPS;
|
||||
Common::Rational pRate((int)(playRate * PRECISION), PRECISION);
|
||||
|
||||
_decoder->setRate(pRate);
|
||||
}
|
||||
}
|
||||
|
||||
Graphics::ManagedSurface *AVISurface::getSecondarySurface() {
|
||||
return _streamCount <= 1 ? nullptr : _movieFrameSurface[1];
|
||||
}
|
||||
|
||||
Graphics::ManagedSurface *AVISurface::duplicateTransparency() const {
|
||||
if (_streamCount <= 1) {
|
||||
return nullptr;
|
||||
} else {
|
||||
Graphics::ManagedSurface *dest = new Graphics::ManagedSurface(_movieFrameSurface[1]->w,
|
||||
_movieFrameSurface[1]->h, Graphics::PixelFormat::createFormatCLUT8());
|
||||
dest->blitFrom(*_movieFrameSurface[1]);
|
||||
return dest;
|
||||
}
|
||||
}
|
||||
|
||||
bool AVISurface::playCutscene(const Rect &r, uint startFrame, uint endFrame) {
|
||||
if (g_vm->shouldQuit())
|
||||
return false;
|
||||
|
||||
// TODO: Fixes slight "jumping back" when rotating in place in Top Of Well
|
||||
// balcony between two elevators. Need a more generalized fix at some point
|
||||
if (_movieName == "z48.avi")
|
||||
_currentFrame = -1;
|
||||
|
||||
if (_currentFrame != ((int)startFrame - 1) || startFrame == 0) {
|
||||
// Start video playback at the desired starting frame
|
||||
if (startFrame > 0) {
|
||||
// Give a chance for a key frame just prior to the start frame
|
||||
// to be loaded first
|
||||
setFrame(startFrame - 1);
|
||||
}
|
||||
|
||||
setFrame(startFrame);
|
||||
startAtFrame(startFrame);
|
||||
_currentFrame = startFrame;
|
||||
} else {
|
||||
// Already in position, so pick up where we left off
|
||||
_decoder->start();
|
||||
}
|
||||
|
||||
bool isDifferent = _movieFrameSurface[0]->w != r.width() ||
|
||||
_movieFrameSurface[0]->h != r.height();
|
||||
|
||||
bool isFinished = true;
|
||||
while (_currentFrame < (int)endFrame && !g_vm->shouldQuit()) {
|
||||
if (isNextFrame()) {
|
||||
renderFrame();
|
||||
++_currentFrame;
|
||||
|
||||
if (isDifferent) {
|
||||
// Clear the destination area, and use the transBlitFrom method,
|
||||
// which supports arbitrary scaling, to reduce to the desired size
|
||||
g_vm->_screen->fillRect(r, 0);
|
||||
g_vm->_screen->transBlitFrom(*_movieFrameSurface[0],
|
||||
Common::Rect(0, 0, _movieFrameSurface[0]->w, _movieFrameSurface[0]->h), r);
|
||||
} else {
|
||||
g_vm->_screen->blitFrom(*_movieFrameSurface[0], Common::Point(r.left, r.top));
|
||||
}
|
||||
|
||||
g_vm->_screen->update();
|
||||
g_vm->_events->pollEvents();
|
||||
}
|
||||
|
||||
// Brief wait, and check at the same time for clicks to abort the clip
|
||||
if (g_vm->_events->waitForPress(10)) {
|
||||
isFinished = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
stop();
|
||||
return isFinished && !g_vm->shouldQuit();
|
||||
}
|
||||
|
||||
uint AVISurface::getBitDepth() const {
|
||||
return _decoder->getVideoTrack(0).getBitCount();
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
y222::y222() {
|
||||
_innerStream = new File();
|
||||
_innerStream->open(TRANSLATE("y222.avi", "y237.avi"));
|
||||
}
|
||||
|
||||
y222::~y222() {
|
||||
delete _innerStream;
|
||||
}
|
||||
|
||||
uint32 y222::read(void *dataPtr, uint32 dataSize) {
|
||||
int32 currPos = pos();
|
||||
uint32 bytesRead = _innerStream->read(dataPtr, dataSize);
|
||||
|
||||
if (currPos <= 48 && (currPos + bytesRead) >= 52) {
|
||||
byte *framesP = (byte *)dataPtr + (48 - currPos);
|
||||
if (READ_LE_UINT32(framesP) == 1)
|
||||
WRITE_LE_UINT32(framesP, 1085);
|
||||
}
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
273
engines/titanic/support/avi_surface.h
Normal file
273
engines/titanic/support/avi_surface.h
Normal file
@@ -0,0 +1,273 @@
|
||||
/* 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 TITANIC_AVI_SURFACE_H
|
||||
#define TITANIC_AVI_SURFACE_H
|
||||
|
||||
#include "common/stream.h"
|
||||
#include "video/avi_decoder.h"
|
||||
#include "graphics/managed_surface.h"
|
||||
#include "titanic/core/resource_key.h"
|
||||
#include "titanic/support/movie_range_info.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CSoundManager;
|
||||
class CVideoSurface;
|
||||
|
||||
enum MovieFlag {
|
||||
MOVIE_REPEAT = 1, // Repeat movie
|
||||
MOVIE_STOP_PREVIOUS = 2, // Stop any prior movie playing on the object
|
||||
MOVIE_NOTIFY_OBJECT = 4, // Notify the object when the movie finishes
|
||||
MOVIE_REVERSE = 8, // Play the movie in reverse
|
||||
MOVIE_WAIT_FOR_FINISH = 0x10 // Let finish before playing next movie for object
|
||||
};
|
||||
|
||||
/**
|
||||
* This implements a special read stream for the y222.avi video
|
||||
* that fixes that totalFrames field of the header from it's
|
||||
* incorrect value of 1 to a correct 1085.
|
||||
*/
|
||||
class y222 : virtual public Common::SeekableReadStream {
|
||||
private:
|
||||
File *_innerStream;
|
||||
public:
|
||||
y222();
|
||||
~y222() override;
|
||||
|
||||
uint32 read(void *dataPtr, uint32 dataSize) override;
|
||||
bool eos() const override { return _innerStream->eos(); }
|
||||
int64 pos() const override { return _innerStream->pos(); }
|
||||
int64 size() const override { return _innerStream->size(); }
|
||||
bool seek(int64 offset, int whence = SEEK_SET) override {
|
||||
return _innerStream->seek(offset, whence);
|
||||
}
|
||||
bool skip(uint32 offset) override {
|
||||
return _innerStream->skip(offset);
|
||||
}
|
||||
char *readLine(char *s, size_t bufSize, bool handleCR = true) override {
|
||||
return _innerStream->readLine(s, bufSize, handleCR);
|
||||
}
|
||||
Common::String readLine(bool handleCR = true) override {
|
||||
return _innerStream->readLine(handleCR);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class AVIDecoder : public Video::AVIDecoder {
|
||||
public:
|
||||
AVIDecoder() {}
|
||||
AVIDecoder(const Common::Rational &frameRateOverride) :
|
||||
Video::AVIDecoder(frameRateOverride) {}
|
||||
|
||||
/**
|
||||
* Returns the number of video tracks the decoder has
|
||||
*/
|
||||
uint videoTrackCount() const { return _videoTracks.size(); }
|
||||
|
||||
/**
|
||||
* Returns the specified video track
|
||||
*/
|
||||
Video::AVIDecoder::AVIVideoTrack &getVideoTrack(uint idx);
|
||||
|
||||
/**
|
||||
* Returns the transparency video track, if present
|
||||
*/
|
||||
AVIVideoTrack *getTransparencyTrack() {
|
||||
return static_cast<AVIVideoTrack *>(_transparencyTrack.track);
|
||||
}
|
||||
};
|
||||
|
||||
class AVISurface {
|
||||
private:
|
||||
AVIDecoder *_decoder;
|
||||
CVideoSurface *_videoSurface;
|
||||
CMovieRangeInfoList _movieRangeInfo;
|
||||
int _streamCount;
|
||||
Graphics::ManagedSurface *_movieFrameSurface[2];
|
||||
bool _framePixels;
|
||||
double _frameRate;
|
||||
int _currentFrame, _priorFrame;
|
||||
uint32 _priorFrameTime;
|
||||
Common::String _movieName;
|
||||
private:
|
||||
/**
|
||||
* Render a frame to the video surface
|
||||
*/
|
||||
bool renderFrame();
|
||||
|
||||
/**
|
||||
* Sets up for video decompression
|
||||
*/
|
||||
void setupDecompressor();
|
||||
|
||||
/**
|
||||
* Copys a movie frame into a local 16-bit frame surface
|
||||
* @param src Source raw movie frame
|
||||
* @param dest Destination 16-bit copy of the frame
|
||||
* @remarks The important thing this methods different from a straight
|
||||
* copy is that any pixels marked as fully transparent are replaced with
|
||||
* the special transparent color value.
|
||||
*/
|
||||
void copyMovieFrame(const Graphics::Surface &src, Graphics::ManagedSurface &dest);
|
||||
protected:
|
||||
/**
|
||||
* Start playback at the specified frame
|
||||
*/
|
||||
bool startAtFrame(int frameNumber);
|
||||
|
||||
/**
|
||||
* Seeks to a given frame number in the video
|
||||
*/
|
||||
virtual void seekToFrame(uint frameNumber);
|
||||
public:
|
||||
CSoundManager *_soundManager;
|
||||
bool _hasAudio;
|
||||
public:
|
||||
AVISurface(const CResourceKey &key);
|
||||
virtual ~AVISurface();
|
||||
|
||||
/**
|
||||
* Start playing the loaded AVI video
|
||||
*/
|
||||
virtual bool play(uint flags, CGameObject *obj);
|
||||
|
||||
/**
|
||||
* Start playing the loaded AVI video
|
||||
*/
|
||||
virtual bool play(int startFrame, int endFrame, uint flags, CGameObject *obj);
|
||||
|
||||
/**
|
||||
* Start playing the loaded AVI video
|
||||
*/
|
||||
virtual bool play(int startFrame, int endFrame, int initialFrame, uint flags, CGameObject *obj);
|
||||
|
||||
/**
|
||||
* Stop the currently playing video
|
||||
*/
|
||||
virtual void stop();
|
||||
|
||||
/**
|
||||
* Pauses video playback
|
||||
*/
|
||||
virtual void pause();
|
||||
|
||||
/**
|
||||
* Resumes the video if it's paused
|
||||
*/
|
||||
virtual void resume();
|
||||
|
||||
/**
|
||||
* Return true if a video is currently playing
|
||||
*/
|
||||
virtual bool isPlaying() const {
|
||||
return _decoder->isPlaying();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the video is playing (versus paused)
|
||||
*/
|
||||
virtual void setPlaying(bool playingFlag) {
|
||||
_decoder->pauseVideo(!playingFlag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle any movie events relevant for the frame
|
||||
*/
|
||||
virtual bool handleEvents(CMovieEventList &events);
|
||||
|
||||
/**
|
||||
* Set the video surface the AVI Surface will render on
|
||||
*/
|
||||
void setVideoSurface(CVideoSurface *surface);
|
||||
|
||||
/**
|
||||
* Get the width of the video
|
||||
*/
|
||||
uint getWidth() const;
|
||||
|
||||
/**
|
||||
* Get the height of the video
|
||||
*/
|
||||
uint getHeight() const;
|
||||
|
||||
/**
|
||||
* Set the current frame
|
||||
*/
|
||||
void setFrame(int frameNumber);
|
||||
|
||||
/**
|
||||
* Gets the current frame
|
||||
*/
|
||||
int getFrame() const { return _priorFrame; }
|
||||
|
||||
/**
|
||||
* Add a movie event
|
||||
*/
|
||||
bool addEvent(int *frameNumber, CGameObject *obj);
|
||||
|
||||
/**
|
||||
* Set the frame rate
|
||||
*/
|
||||
void setFrameRate(double rate);
|
||||
|
||||
/**
|
||||
* Returns the surface for the secondary video track frame, if present
|
||||
*/
|
||||
Graphics::ManagedSurface *getSecondarySurface();
|
||||
|
||||
/**
|
||||
* Get a reference to the movie range info list
|
||||
*/
|
||||
const CMovieRangeInfoList *getMovieRangeInfo() const {
|
||||
return &_movieRangeInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicates the transparency mask for the frame, if the movie includes it
|
||||
*/
|
||||
Graphics::ManagedSurface *duplicateTransparency() const;
|
||||
|
||||
/**
|
||||
* Returns true if it's time for the next
|
||||
*/
|
||||
bool isNextFrame();
|
||||
|
||||
/**
|
||||
* Plays an interruptable cutscene
|
||||
* @returns True if the cutscene was not interrupted
|
||||
*/
|
||||
bool playCutscene(const Rect &r, uint startFrame, uint endFrame);
|
||||
|
||||
/**
|
||||
* Returns the pixel depth of the movie in bits
|
||||
*/
|
||||
uint getBitDepth() const;
|
||||
|
||||
/**
|
||||
* Returns true if the movie is to play backwards
|
||||
*/
|
||||
bool isReversed() const { return _frameRate < 0.0; }
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_AVI_SURFACE_H */
|
||||
263
engines/titanic/support/credit_text.cpp
Normal file
263
engines/titanic/support/credit_text.cpp
Normal file
@@ -0,0 +1,263 @@
|
||||
/* 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 "titanic/support/credit_text.h"
|
||||
#include "titanic/core/game_object.h"
|
||||
#include "titanic/events.h"
|
||||
#include "titanic/support/files_manager.h"
|
||||
#include "titanic/support/screen_manager.h"
|
||||
#include "titanic/titanic.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
#define FRAMES_PER_CYCLE 16
|
||||
|
||||
CCreditText::CCreditText() : _screenManagerP(nullptr), _ticks(0),
|
||||
_fontHeight(1), _objectP(nullptr), _yOffset(0),
|
||||
_priorInc(0), _textR(0), _textG(0), _textB(0), _deltaR(0),
|
||||
_deltaG(0), _deltaB(0), _counter(0) {
|
||||
}
|
||||
|
||||
void CCreditText::clear() {
|
||||
_groups.destroyContents();
|
||||
_objectP = nullptr;
|
||||
}
|
||||
|
||||
void CCreditText::load(CGameObject *obj, CScreenManager *screenManager,
|
||||
const Rect &rect) {
|
||||
_objectP = obj;
|
||||
_screenManagerP = screenManager;
|
||||
_rect = rect;
|
||||
|
||||
setup();
|
||||
|
||||
_ticks = g_vm->_events->getTicksCount();
|
||||
_priorInc = 0;
|
||||
_textR = 0xFF;
|
||||
_textG = 0xFF;
|
||||
_textB = 0xFF;
|
||||
_deltaR = 0;
|
||||
_deltaG = 0;
|
||||
_deltaB = 0;
|
||||
_counter = 0;
|
||||
}
|
||||
|
||||
void CCreditText::setup() {
|
||||
Common::SeekableReadStream *stream = g_vm->_filesManager->getResource(
|
||||
CString::format("TEXT/155"));
|
||||
int oldFontNumber = _screenManagerP->setFontNumber(3);
|
||||
_fontHeight = _screenManagerP->getFontHeight();
|
||||
|
||||
while (stream->pos() < stream->size()) {
|
||||
// Read in the line
|
||||
CString srcLine = readLine(stream);
|
||||
|
||||
// Create a new group and line within it
|
||||
CCreditLineGroup *group = new CCreditLineGroup();
|
||||
CCreditLine *line = new CCreditLine(srcLine,
|
||||
_screenManagerP->stringWidth(srcLine));
|
||||
group->_lines.push_back(line);
|
||||
|
||||
// Loop to add more lines to the group
|
||||
bool hasDots = false;
|
||||
while (stream->pos() < stream->size()) {
|
||||
srcLine = readLine(stream);
|
||||
if (srcLine.empty())
|
||||
break;
|
||||
|
||||
line = new CCreditLine(srcLine,
|
||||
_screenManagerP->stringWidth(srcLine));
|
||||
group->_lines.push_back(line);
|
||||
|
||||
if (srcLine.contains("...."))
|
||||
hasDots = true;
|
||||
}
|
||||
|
||||
_groups.push_back(group);
|
||||
if (hasDots)
|
||||
handleDots(group);
|
||||
}
|
||||
|
||||
_screenManagerP->setFontNumber(oldFontNumber);
|
||||
_groupIt = _groups.begin();
|
||||
_lineIt = (*_groupIt)->_lines.begin();
|
||||
_yOffset = _objectP->_bounds.height() + _fontHeight * 2;
|
||||
}
|
||||
|
||||
CString CCreditText::readLine(Common::SeekableReadStream *stream) {
|
||||
CString line;
|
||||
char c = stream->readByte();
|
||||
|
||||
while (c != '\r' && c != '\n' && c != '\0') {
|
||||
line += c;
|
||||
|
||||
if (stream->pos() == stream->size())
|
||||
break;
|
||||
c = stream->readByte();
|
||||
}
|
||||
|
||||
if (c == '\r') {
|
||||
// Read following '\n'
|
||||
stream->readByte();
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
void CCreditText::handleDots(CCreditLineGroup *group) {
|
||||
uint maxWidth = 0;
|
||||
CCreditLines::iterator second = group->_lines.begin();
|
||||
++second;
|
||||
|
||||
// Figure out the maximum width of secondary lines
|
||||
for (CCreditLines::iterator i = second; i != group->_lines.end(); ++i)
|
||||
maxWidth = MAX(maxWidth, (*i)->_lineWidth);
|
||||
|
||||
int charWidth = _screenManagerP->stringWidth(".");
|
||||
|
||||
// Process the secondary lines
|
||||
for (CCreditLines::iterator i = second; i != group->_lines.end(); ++i) {
|
||||
CCreditLine *line = *i;
|
||||
if (line->_lineWidth >= maxWidth)
|
||||
continue;
|
||||
|
||||
int dotsCount = (maxWidth + charWidth / 2 - line->_lineWidth) / charWidth;
|
||||
int dotIndex = line->_line.indexOf("....");
|
||||
|
||||
if (dotIndex > 0) {
|
||||
CString leftStr = line->_line.left(dotIndex);
|
||||
CString dotsStr('.', dotsCount);
|
||||
CString rightStr = line->_line.right(dotIndex);
|
||||
|
||||
line->_line = CString::format("%s%s%s", leftStr.c_str(),
|
||||
dotsStr.c_str(), rightStr.c_str());
|
||||
line->_lineWidth = maxWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CCreditText::draw() {
|
||||
if (_groupIt == _groups.end())
|
||||
return false;
|
||||
|
||||
if (++_counter >= FRAMES_PER_CYCLE) {
|
||||
_textR += _deltaR;
|
||||
_textG += _deltaG;
|
||||
_textB += _deltaB;
|
||||
_deltaR = g_vm->getRandomNumber(63) + 192 - _textR;
|
||||
_deltaG = g_vm->getRandomNumber(63) + 192 - _textG;
|
||||
_deltaB = g_vm->getRandomNumber(63) + 192 - _textB;
|
||||
_counter = 0;
|
||||
}
|
||||
|
||||
// Positioning adjustment, changing lines and/or group if necessary
|
||||
int yDiff = (int)(g_vm->_events->getTicksCount() - _ticks) / 22 - _priorInc;
|
||||
|
||||
while (yDiff > 0) {
|
||||
if (_yOffset > 0) {
|
||||
if (yDiff < _yOffset) {
|
||||
_yOffset -= yDiff;
|
||||
_priorInc += yDiff;
|
||||
yDiff = 0;
|
||||
} else {
|
||||
yDiff -= _yOffset;
|
||||
_priorInc += _yOffset;
|
||||
_yOffset = 0;
|
||||
}
|
||||
} else {
|
||||
if (yDiff < _fontHeight)
|
||||
break;
|
||||
|
||||
++_lineIt;
|
||||
yDiff -= _fontHeight;
|
||||
_priorInc += _fontHeight;
|
||||
|
||||
if (_lineIt == (*_groupIt)->_lines.end()) {
|
||||
// Move to next line group
|
||||
++_groupIt;
|
||||
if (_groupIt == _groups.end())
|
||||
// Reached end of groups
|
||||
return false;
|
||||
|
||||
_lineIt = (*_groupIt)->_lines.begin();
|
||||
_yOffset = _fontHeight * 3 / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int oldFontNumber = _screenManagerP->setFontNumber(3);
|
||||
CCreditLineGroups::iterator groupIt = _groupIt;
|
||||
CCreditLines::iterator lineIt = _lineIt;
|
||||
|
||||
Point textPos;
|
||||
for (textPos.y = _rect.top + _yOffset - yDiff; textPos.y <= _rect.bottom;
|
||||
textPos.y += _fontHeight) {
|
||||
int textR = _textR + _deltaR * _counter / FRAMES_PER_CYCLE;
|
||||
int textG = _textG + _deltaG * _counter / FRAMES_PER_CYCLE;
|
||||
int textB = _textB + _deltaB * _counter / FRAMES_PER_CYCLE;
|
||||
|
||||
// Single iteration loop to figure out RGB values for the line
|
||||
do {
|
||||
int percent = 0;
|
||||
if (textPos.y < (_rect.top + 2 * _fontHeight)) {
|
||||
percent = (textPos.y - _rect.top) * 100 / (_fontHeight * 2);
|
||||
if (percent < 0)
|
||||
percent = 0;
|
||||
} else {
|
||||
int bottom = _rect.bottom - 2 * _fontHeight;
|
||||
if (textPos.y < bottom)
|
||||
break;
|
||||
|
||||
percent = (_rect.bottom - textPos.y) * 100
|
||||
/ (_fontHeight * 2);
|
||||
}
|
||||
|
||||
// Adjust the RGB to the specified percentage intensity
|
||||
textR = textR * percent / 100;
|
||||
textG = textG * percent / 100;
|
||||
textB = textB * percent / 100;
|
||||
} while (0);
|
||||
|
||||
// Write out the line
|
||||
_screenManagerP->setFontColor(textR, textG, textB);
|
||||
textPos.x = _rect.left + (_rect.width() - (*lineIt)->_lineWidth) / 2;
|
||||
_screenManagerP->writeString(SURFACE_BACKBUFFER, textPos,
|
||||
_rect, (*lineIt)->_line, (*lineIt)->_lineWidth);
|
||||
|
||||
// Move to next line
|
||||
++lineIt;
|
||||
if (lineIt == (*groupIt)->_lines.end()) {
|
||||
++groupIt;
|
||||
if (groupIt == _groups.end())
|
||||
// Finished all lines
|
||||
break;
|
||||
|
||||
lineIt = (*groupIt)->_lines.begin();
|
||||
textPos.y += _fontHeight * 3 / 2;
|
||||
}
|
||||
}
|
||||
|
||||
_objectP->makeDirty();
|
||||
_screenManagerP->setFontNumber(oldFontNumber);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
100
engines/titanic/support/credit_text.h
Normal file
100
engines/titanic/support/credit_text.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/* 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 TITANIC_CREDIT_TEXT_H
|
||||
#define TITANIC_CREDIT_TEXT_H
|
||||
|
||||
#include "titanic/core/list.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CGameObject;
|
||||
class CScreenManager;
|
||||
|
||||
class CCreditLine : public ListItem {
|
||||
public:
|
||||
CString _line;
|
||||
uint _lineWidth;
|
||||
public:
|
||||
CCreditLine() : _lineWidth(0) {}
|
||||
CCreditLine(const CString &line, uint lineWidth) : _line(line), _lineWidth(lineWidth) {}
|
||||
};
|
||||
typedef List<CCreditLine> CCreditLines;
|
||||
|
||||
class CCreditLineGroup : public ListItem {
|
||||
public:
|
||||
CCreditLines _lines;
|
||||
};
|
||||
typedef List<CCreditLineGroup> CCreditLineGroups;
|
||||
|
||||
class CCreditText {
|
||||
private:
|
||||
/**
|
||||
* Sets up needed data
|
||||
*/
|
||||
void setup();
|
||||
|
||||
/**
|
||||
* Read in a text line from the passed stream
|
||||
*/
|
||||
CString readLine(Common::SeekableReadStream *stream);
|
||||
|
||||
/**
|
||||
* Handles a group where the .... sequence was encountered
|
||||
*/
|
||||
void handleDots(CCreditLineGroup *group);
|
||||
public:
|
||||
CScreenManager *_screenManagerP;
|
||||
Rect _rect;
|
||||
CCreditLineGroups _groups;
|
||||
uint _ticks;
|
||||
int _fontHeight;
|
||||
CGameObject *_objectP;
|
||||
CCreditLineGroups::iterator _groupIt;
|
||||
CCreditLines::iterator _lineIt;
|
||||
int _yOffset;
|
||||
int _priorInc;
|
||||
int _textR, _textG, _textB;
|
||||
int _deltaR, _deltaG, _deltaB;
|
||||
int _counter;
|
||||
public:
|
||||
CCreditText();
|
||||
|
||||
/**
|
||||
* Clears the object
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Sets the game object this override is associated with
|
||||
*/
|
||||
void load(CGameObject *obj, CScreenManager *screenManager,
|
||||
const Rect &rect);
|
||||
|
||||
/**
|
||||
* Draw the item
|
||||
*/
|
||||
bool draw();
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_CREDIT_TEXT_H */
|
||||
98
engines/titanic/support/direct_draw.cpp
Normal file
98
engines/titanic/support/direct_draw.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
/* 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 "titanic/support/direct_draw.h"
|
||||
#include "titanic/debugger.h"
|
||||
#include "titanic/titanic.h"
|
||||
#include "common/debug.h"
|
||||
#include "engines/util.h"
|
||||
#include "graphics/pixelformat.h"
|
||||
#include "graphics/screen.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
DirectDraw::DirectDraw() : _windowed(false), _width(0), _height(0),
|
||||
_bpp(0), _numBackSurfaces(0) {
|
||||
}
|
||||
|
||||
void DirectDraw::setDisplayMode(int width, int height, int bpp, int refreshRate) {
|
||||
debugC(DEBUG_BASIC, kDebugGraphics, "DirectDraw::SetDisplayMode (%d x %d), %d bpp",
|
||||
width, height, bpp);
|
||||
assert(bpp == 16);
|
||||
|
||||
Graphics::PixelFormat pixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
|
||||
initGraphics(width, height, &pixelFormat);
|
||||
}
|
||||
|
||||
void DirectDraw::diagnostics() {
|
||||
debugC(DEBUG_BASIC, kDebugGraphics, "Running DirectDraw Diagnostic...");
|
||||
}
|
||||
|
||||
DirectDrawSurface *DirectDraw::createSurfaceFromDesc(const DDSurfaceDesc &desc) {
|
||||
DirectDrawSurface *surface = new DirectDrawSurface();
|
||||
surface->create(desc._w, desc._h, desc._bpp);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
DirectDrawManager::DirectDrawManager(TitanicEngine *vm, bool windowed) {
|
||||
_mainSurface = nullptr;
|
||||
_backSurfaces[0] = _backSurfaces[1] = nullptr;
|
||||
_directDraw._windowed = windowed;
|
||||
}
|
||||
|
||||
void DirectDrawManager::initVideo(int width, int height, int bpp, int numBackSurfaces) {
|
||||
debugC(DEBUG_BASIC, kDebugGraphics, "Initialising video surfaces");
|
||||
assert(numBackSurfaces == 0);
|
||||
|
||||
_directDraw._width = width;
|
||||
_directDraw._numBackSurfaces = numBackSurfaces;
|
||||
_directDraw._height = height;
|
||||
_directDraw._bpp = bpp;
|
||||
|
||||
if (_directDraw._windowed) {
|
||||
initWindowed();
|
||||
} else {
|
||||
initFullScreen();
|
||||
}
|
||||
}
|
||||
|
||||
void DirectDrawManager::initFullScreen() {
|
||||
debugC(DEBUG_BASIC, kDebugGraphics, "Creating surfaces");
|
||||
_directDraw.setDisplayMode(_directDraw._width, _directDraw._height,
|
||||
_directDraw._bpp, 0);
|
||||
|
||||
// Set up the main surface to point to the screen
|
||||
_mainSurface = new DirectDrawSurface();
|
||||
_mainSurface->create(g_vm->_screen);
|
||||
}
|
||||
|
||||
DirectDrawSurface *DirectDrawManager::createSurface(int w, int h, int bpp, int surfaceNum) {
|
||||
if (surfaceNum)
|
||||
return nullptr;
|
||||
|
||||
assert(_mainSurface);
|
||||
return _directDraw.createSurfaceFromDesc(DDSurfaceDesc(w, h, bpp));
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
94
engines/titanic/support/direct_draw.h
Normal file
94
engines/titanic/support/direct_draw.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/* 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 TITANIC_DIRECT_DRAW_H
|
||||
#define TITANIC_DIRECT_DRAW_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/array.h"
|
||||
#include "titanic/support/direct_draw_surface.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class TitanicEngine;
|
||||
|
||||
class DirectDraw {
|
||||
public:
|
||||
bool _windowed;
|
||||
int _width;
|
||||
int _height;
|
||||
int _bpp;
|
||||
int _numBackSurfaces;
|
||||
public:
|
||||
DirectDraw();
|
||||
|
||||
/**
|
||||
* Sets a new display mode
|
||||
*/
|
||||
void setDisplayMode(int width, int height, int bpp, int refreshRate);
|
||||
|
||||
/**
|
||||
* Logs diagnostic information
|
||||
*/
|
||||
void diagnostics();
|
||||
|
||||
/**
|
||||
* Create a surface from a passed description record
|
||||
*/
|
||||
DirectDrawSurface *createSurfaceFromDesc(const DDSurfaceDesc &desc);
|
||||
};
|
||||
|
||||
class DirectDrawManager {
|
||||
public:
|
||||
DirectDraw _directDraw;
|
||||
DirectDrawSurface *_mainSurface;
|
||||
DirectDrawSurface *_backSurfaces[2];
|
||||
public:
|
||||
DirectDrawManager(TitanicEngine *vm, bool windowed);
|
||||
|
||||
/**
|
||||
* Initializes video surfaces
|
||||
* @param width Screen width
|
||||
* @param height Screen height
|
||||
* @param bpp Bits per pixel
|
||||
* @param numBackSurfaces Number of back surfaces
|
||||
*/
|
||||
void initVideo(int width, int height, int bpp, int numBackSurfaces);
|
||||
|
||||
/**
|
||||
* Initializes the surfaces in windowed mode
|
||||
*/
|
||||
void initWindowed() { initFullScreen(); }
|
||||
|
||||
/**
|
||||
* Initializes the surfaces for the screen
|
||||
*/
|
||||
void initFullScreen();
|
||||
|
||||
/**
|
||||
* Create a surface
|
||||
*/
|
||||
DirectDrawSurface *createSurface(int w, int h, int bpp, int surfaceNum);
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_DIRECT_DRAW_H */
|
||||
103
engines/titanic/support/direct_draw_surface.cpp
Normal file
103
engines/titanic/support/direct_draw_surface.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 "titanic/support/direct_draw_surface.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
DirectDrawSurface::DirectDrawSurface() : _surface(nullptr),
|
||||
_disposeAfterUse(DisposeAfterUse::YES) {
|
||||
}
|
||||
|
||||
DirectDrawSurface::~DirectDrawSurface() {
|
||||
free();
|
||||
}
|
||||
|
||||
void DirectDrawSurface::create(Graphics::ManagedSurface *surface) {
|
||||
free();
|
||||
_surface = surface;
|
||||
_disposeAfterUse = DisposeAfterUse::NO;
|
||||
}
|
||||
|
||||
void DirectDrawSurface::create(int w, int h, int bpp) {
|
||||
assert(bpp == 16 || bpp == 32);
|
||||
Graphics::PixelFormat pixelFormat = (bpp == 32) ?
|
||||
Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0) :
|
||||
Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
|
||||
|
||||
_surface = new Graphics::ManagedSurface(w, h, pixelFormat);
|
||||
_disposeAfterUse = DisposeAfterUse::YES;
|
||||
}
|
||||
|
||||
void DirectDrawSurface::free() {
|
||||
if (_disposeAfterUse == DisposeAfterUse::YES)
|
||||
delete _surface;
|
||||
_surface = nullptr;
|
||||
_disposeAfterUse = DisposeAfterUse::NO;
|
||||
}
|
||||
|
||||
Graphics::ManagedSurface *DirectDrawSurface::lock(const Rect *bounds, int flags) {
|
||||
assert(!_surface->empty());
|
||||
return _surface;
|
||||
}
|
||||
|
||||
void DirectDrawSurface::unlock() {
|
||||
assert(_surface->w != 0 && _surface->h != 0);
|
||||
}
|
||||
|
||||
void DirectDrawSurface::fill(const Rect *bounds, uint32 color) {
|
||||
Rect tempBounds;
|
||||
|
||||
assert(_surface);
|
||||
if (bounds) {
|
||||
// Bounds are provided, clip them to the bounds of this surface
|
||||
tempBounds = *bounds;
|
||||
tempBounds.clip(Rect(0, 0, _surface->w, _surface->h));
|
||||
} else {
|
||||
// No bounds provided, so use the entire surface
|
||||
tempBounds = Rect(0, 0, _surface->w, _surface->h);
|
||||
}
|
||||
|
||||
// Fill the area
|
||||
_surface->fillRect(tempBounds, color);
|
||||
}
|
||||
|
||||
void DirectDrawSurface::fillRect(Rect *rect, byte r, byte g, byte b) {
|
||||
uint color = _surface->format.RGBToColor(r, g, b);
|
||||
Rect tempRect = rect ? *rect : Rect(0, 0, getWidth(), getHeight());
|
||||
|
||||
_surface->fillRect(tempRect, color);
|
||||
}
|
||||
|
||||
void DirectDrawSurface::blit(const Rect &destRect, DirectDrawSurface *srcSurface, Rect &srcRect) {
|
||||
assert(srcSurface);
|
||||
if (!destRect.isEmpty())
|
||||
_surface->transBlitFrom(*srcSurface->_surface, srcRect, destRect, (uint)-1);
|
||||
}
|
||||
|
||||
void DirectDrawSurface::blit(const Point &destPos, DirectDrawSurface *srcSurface, Rect *bounds) {
|
||||
if (bounds)
|
||||
_surface->blitFrom(*srcSurface->_surface, *bounds, destPos);
|
||||
else
|
||||
_surface->blitFrom(*srcSurface->_surface, destPos);
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
127
engines/titanic/support/direct_draw_surface.h
Normal file
127
engines/titanic/support/direct_draw_surface.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/* 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 TITANIC_DIRECT_DRAW_SURFACE_H
|
||||
#define TITANIC_DIRECT_DRAW_SURFACE_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/array.h"
|
||||
#include "graphics/managed_surface.h"
|
||||
#include "titanic/support/rect.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class TitanicEngine;
|
||||
|
||||
struct DDSurfaceDesc {
|
||||
int _w;
|
||||
int _h;
|
||||
int _bpp;
|
||||
int _flags;
|
||||
int _caps;
|
||||
|
||||
DDSurfaceDesc(int w, int h, int bpp) : _w(w), _h(h), _bpp(bpp),
|
||||
_flags(0x1006), _caps(64) {}
|
||||
};
|
||||
|
||||
class DirectDrawSurface {
|
||||
private:
|
||||
Graphics::ManagedSurface *_surface;
|
||||
DisposeAfterUse::Flag _disposeAfterUse;
|
||||
public:
|
||||
DirectDrawSurface();
|
||||
~DirectDrawSurface();
|
||||
|
||||
/**
|
||||
* Create a surface
|
||||
*/
|
||||
void create(int w, int h, int bpp);
|
||||
|
||||
/**
|
||||
* Create a surface based on a passed surface
|
||||
*/
|
||||
void create(Graphics::ManagedSurface *surface);
|
||||
|
||||
/**
|
||||
* Frees the surface
|
||||
*/
|
||||
void free();
|
||||
|
||||
/**
|
||||
* Return the size of the surface in ytes
|
||||
*/
|
||||
int getSize() const { return _surface->pitch * _surface->h; }
|
||||
|
||||
/**
|
||||
* Return the surface width
|
||||
*/
|
||||
int getWidth() const { return _surface->w; }
|
||||
|
||||
/**
|
||||
* Return the surface width
|
||||
*/
|
||||
int getHeight() const { return _surface->h; }
|
||||
|
||||
/**
|
||||
* Return the surface pitch
|
||||
*/
|
||||
int getPitch() const { return _surface->pitch; }
|
||||
|
||||
/**
|
||||
* Return the surface's format
|
||||
*/
|
||||
const Graphics::PixelFormat &getFormat() { return _surface->format; }
|
||||
|
||||
/**
|
||||
* Lock the surface for access
|
||||
*/
|
||||
Graphics::ManagedSurface *lock(const Rect *bounds, int flags);
|
||||
|
||||
/**
|
||||
* Unlocks the surface at the end of direct accesses
|
||||
*/
|
||||
void unlock();
|
||||
|
||||
/**
|
||||
* Fills an area of the surfae with the specified color. If no bounds are passed,
|
||||
* then the entire surface is filled
|
||||
*/
|
||||
void fill(const Rect *bounds, uint32 color);
|
||||
|
||||
/**
|
||||
* Fill an area with a specific color
|
||||
*/
|
||||
void fillRect(Rect *rect, byte r, byte g, byte b);
|
||||
|
||||
/**
|
||||
* Copy data from a source surfcae into this one
|
||||
*/
|
||||
void blit(const Rect &destRect, DirectDrawSurface *srcSurface, Rect &srcRect);
|
||||
|
||||
/**
|
||||
* Copy data from a source surfcae into this one
|
||||
*/
|
||||
void blit(const Point &destPos, DirectDrawSurface *srcSurface, Rect *bounds);
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_DIRECT_DRAW_SURFACE_H */
|
||||
37
engines/titanic/support/exe_resources.cpp
Normal file
37
engines/titanic/support/exe_resources.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/* 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 "titanic/support/exe_resources.h"
|
||||
#include "titanic/true_talk/script_handler.h"
|
||||
#include "titanic/titanic.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
CExeResources::CExeResources() : _owner(nullptr), _field4(0), _field8(0),
|
||||
_fieldC(0), _field10(0), _field14(0), _vocabMode(VOCAB_MODE_NONE) {
|
||||
}
|
||||
|
||||
void CExeResources::reset(CScriptHandler *owner, int val1, VocabMode vocabMode) {
|
||||
_owner = owner;
|
||||
_vocabMode = vocabMode;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
60
engines/titanic/support/exe_resources.h
Normal file
60
engines/titanic/support/exe_resources.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 TITANIC_EXE_RESOURCES_H
|
||||
#define TITANIC_EXE_RESOURCES_H
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CScriptHandler;
|
||||
|
||||
enum FileHandle { HANDLE_STDIN = 0, HANDLE_STDOUT = 1, HANDLE_STDERR = 2 };
|
||||
|
||||
enum VocabMode { VOCAB_MODE_NONE = 0, VOCAB_MODE_EN = 3, VOCAB_MODE_DE = 5 };
|
||||
|
||||
class CExeResources {
|
||||
public:
|
||||
CScriptHandler *_owner;
|
||||
int _field4;
|
||||
int _field8;
|
||||
int _fieldC;
|
||||
int _field10;
|
||||
int _field14;
|
||||
VocabMode _vocabMode;
|
||||
public:
|
||||
CExeResources();
|
||||
|
||||
void reset(CScriptHandler *owner, int val1, VocabMode vocabMode);
|
||||
|
||||
/**
|
||||
* Tests whether the vocab mode equals the passed mode
|
||||
*/
|
||||
bool isVocabMode(int mode) const { return _vocabMode == mode; }
|
||||
|
||||
/**
|
||||
* Returns the vocab mode
|
||||
*/
|
||||
VocabMode getVocabMode() const { return _vocabMode; }
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_EXE_RESOURCES_H */
|
||||
154
engines/titanic/support/files_manager.cpp
Normal file
154
engines/titanic/support/files_manager.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
/* 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/memstream.h"
|
||||
#include "common/compression/deflate.h"
|
||||
#include "titanic/support/files_manager.h"
|
||||
#include "titanic/game_manager.h"
|
||||
#include "titanic/titanic.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
CFilesManager::CFilesManager(TitanicEngine *vm) : _vm(vm), _gameManager(nullptr),
|
||||
_assetsPath("Assets"), _drive(-1), _version(0) {
|
||||
}
|
||||
|
||||
CFilesManager::~CFilesManager() {
|
||||
_datFile.close();
|
||||
}
|
||||
|
||||
bool CFilesManager::loadResourceIndex() {
|
||||
if (!_datFile.open("titanic.dat")) {
|
||||
GUIErrorMessage("Could not find titanic.dat data file");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint headerId = _datFile.readUint32BE();
|
||||
_version = _datFile.readUint16LE();
|
||||
if (headerId != MKTAG('S', 'V', 'T', 'N')) {
|
||||
GUIErrorMessage("titanic.dat has invalid contents");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_version != 5) {
|
||||
GUIErrorMessage("titanic.dat is out of date");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read in entries
|
||||
uint offset, size, flags;
|
||||
char c;
|
||||
Common::String resourceName;
|
||||
for (;;) {
|
||||
offset = _datFile.readUint32LE();
|
||||
size = _datFile.readUint32LE();
|
||||
flags = (_version == 1) ? 0 : _datFile.readUint16LE();
|
||||
|
||||
if (offset == 0 && size == 0)
|
||||
break;
|
||||
|
||||
Common::String resName;
|
||||
while ((c = _datFile.readByte()) != '\0')
|
||||
resName += c;
|
||||
|
||||
_resources[resName] = ResourceEntry(offset, size, flags);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFilesManager::fileExists(const CString &name) {
|
||||
return Common::File::exists(Common::Path(name));
|
||||
}
|
||||
|
||||
bool CFilesManager::scanForFile(const CString &name) {
|
||||
if (name.empty())
|
||||
return false;
|
||||
|
||||
CString filename = name;
|
||||
filename.toLowercase();
|
||||
|
||||
if (filename[0] == 'y' || filename[0] == 'z')
|
||||
return true;
|
||||
else if (filename[0] < 'a' || filename[0] > 'c')
|
||||
return false;
|
||||
|
||||
CString fname = filename;
|
||||
int idx = fname.indexOf('#');
|
||||
if (idx >= 0) {
|
||||
fname = fname.left(idx);
|
||||
fname += ".st";
|
||||
}
|
||||
|
||||
// Return true if the file exists
|
||||
if (fileExists(fname))
|
||||
return true;
|
||||
|
||||
// Couldn't find file. Start by calling the game manager's roomChange
|
||||
// method, which handles all active scene objects freeing their resources
|
||||
if (_gameManager)
|
||||
_gameManager->roomChange();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CFilesManager::loadDrive() {
|
||||
assert(_drive == -1);
|
||||
resetView();
|
||||
}
|
||||
|
||||
void CFilesManager::insertCD(CScreenManager *screenManager) {
|
||||
// We don't support running the game directly from the original CDs,
|
||||
// so this method can remain stubbed
|
||||
}
|
||||
|
||||
void CFilesManager::resetView() {
|
||||
if (_gameManager) {
|
||||
_gameManager->_gameState.setMode(GSMODE_INTERACTIVE);
|
||||
_gameManager->markAllDirty();
|
||||
}
|
||||
}
|
||||
|
||||
void CFilesManager::preload(const CString &name) {
|
||||
// We don't currently do any preloading of resources
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *CFilesManager::getResource(const CString &str) {
|
||||
ResourceEntry resEntry = _resources[str];
|
||||
|
||||
// If we're running the German version, check for the existence of
|
||||
// a German specific version of the given resource
|
||||
if (_vm->isGerman() && _resources.contains(str + "/DE"))
|
||||
resEntry = _resources[str + "/DE"];
|
||||
|
||||
_datFile.seek(resEntry._offset);
|
||||
|
||||
Common::SeekableReadStream *stream = (resEntry._size > 0) ?
|
||||
_datFile.readStream(resEntry._size) :
|
||||
new Common::MemoryReadStream(nullptr, 0);
|
||||
if (resEntry._flags & FLAG_COMPRESSED)
|
||||
stream = Common::wrapCompressedReadStream(stream);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
113
engines/titanic/support/files_manager.h
Normal file
113
engines/titanic/support/files_manager.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/* 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 TITANIC_FILES_MANAGER_H
|
||||
#define TITANIC_FILES_MANAGER_H
|
||||
|
||||
#include "common/hashmap.h"
|
||||
#include "titanic/core/list.h"
|
||||
#include "titanic/support/screen_manager.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
enum ResourceFlag { FLAG_COMPRESSED = 1 };
|
||||
|
||||
class TitanicEngine;
|
||||
class CGameManager;
|
||||
|
||||
class CFilesManagerList : public List<ListItem> {
|
||||
};
|
||||
|
||||
class CFilesManager {
|
||||
struct ResourceEntry {
|
||||
uint _offset;
|
||||
uint _size;
|
||||
uint _flags;
|
||||
|
||||
ResourceEntry() : _offset(0), _size(0), _flags(0) {}
|
||||
ResourceEntry(uint offset, uint size, uint flags) :
|
||||
_offset(offset), _size(size), _flags(flags) {}
|
||||
};
|
||||
typedef Common::HashMap<Common::String, ResourceEntry> ResourceHash;
|
||||
private:
|
||||
TitanicEngine *_vm;
|
||||
CGameManager *_gameManager;
|
||||
Common::File _datFile;
|
||||
ResourceHash _resources;
|
||||
CFilesManagerList _list;
|
||||
int _drive;
|
||||
const CString _assetsPath;
|
||||
int _version;
|
||||
public:
|
||||
CFilesManager(TitanicEngine *vm);
|
||||
~CFilesManager();
|
||||
|
||||
/**
|
||||
* Opens up the titanic.dat support file and loads it's index
|
||||
*/
|
||||
bool loadResourceIndex();
|
||||
|
||||
/**
|
||||
* Sets the game manager
|
||||
*/
|
||||
void setGameManager(CGameManager *gameManager) {
|
||||
_gameManager = gameManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a file of the given name exists
|
||||
*/
|
||||
static bool fileExists(const CString &name);
|
||||
|
||||
/**
|
||||
* Scans for a file with a matching name
|
||||
*/
|
||||
bool scanForFile(const CString &name);
|
||||
|
||||
/**
|
||||
* Handles displaying a load drive view if necessary
|
||||
*/
|
||||
void loadDrive();
|
||||
|
||||
/**
|
||||
* Shows a dialog for inserting a new CD
|
||||
*/
|
||||
void insertCD(CScreenManager *screenManager);
|
||||
|
||||
/**
|
||||
* Resets the view being displayed
|
||||
*/
|
||||
void resetView();
|
||||
|
||||
/**
|
||||
* Preloads and caches a file for access shortly
|
||||
*/
|
||||
void preload(const CString &name);
|
||||
|
||||
/**
|
||||
* Get a resource from the executable
|
||||
*/
|
||||
Common::SeekableReadStream *getResource(const CString &str);
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_FILES_MANAGER_H */
|
||||
142
engines/titanic/support/fixed_queue.h
Normal file
142
engines/titanic/support/fixed_queue.h
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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_FIXED_QUEUE_H
|
||||
#define TITANIC_FIXED_QUEUE_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/array.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
/**
|
||||
* Extremely simple fixed size queue class.
|
||||
*/
|
||||
template<class T, uint MAX_SIZE = 10>
|
||||
class FixedQueue {
|
||||
typedef uint size_type;
|
||||
protected:
|
||||
Common::Array<T> _data;
|
||||
size_type _topIndex;
|
||||
public:
|
||||
FixedQueue() : _topIndex(0) {
|
||||
_data.reserve(MAX_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the queue in use
|
||||
*/
|
||||
size_type size() const { return _data.size() - _topIndex; }
|
||||
|
||||
/**
|
||||
* Returns the amount of free remaining space in the queue
|
||||
*/
|
||||
size_type freeSize() const { return MAX_SIZE - size(); }
|
||||
|
||||
/**
|
||||
* Returns true if the queue is empty
|
||||
*/
|
||||
bool empty() const {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the queue is full
|
||||
*/
|
||||
bool full() const {
|
||||
return freeSize() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the queue
|
||||
*/
|
||||
void clear() {
|
||||
_data.clear();
|
||||
_topIndex = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the tail of the queue in use has reached the end of the internal
|
||||
* array, pushes all pending data back to the start of the array
|
||||
*/
|
||||
void compact() {
|
||||
if (_data.size() == MAX_SIZE && _topIndex > 0) {
|
||||
if (_topIndex < MAX_SIZE)
|
||||
Common::copy(&_data[_topIndex], &_data[0] + MAX_SIZE, &_data[0]);
|
||||
_data.resize(size());
|
||||
_topIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a value to the end of the queue
|
||||
*/
|
||||
void push(const T &v) {
|
||||
assert(size() < MAX_SIZE);
|
||||
compact();
|
||||
_data.push_back(v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the top value on the queue
|
||||
*/
|
||||
const T &top() const {
|
||||
assert(size() > 0);
|
||||
return _data[_topIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the top value on the queue
|
||||
*/
|
||||
T &top() {
|
||||
assert(size() > 0);
|
||||
return _data[_topIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops the top value off the queue
|
||||
*/
|
||||
T pop() {
|
||||
T tmp = top();
|
||||
++_topIndex;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns values from within the queue without popping them
|
||||
*/
|
||||
T &operator[](size_type i) {
|
||||
assert(i < size());
|
||||
return _data[_topIndex + i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns values from within the queue without popping them
|
||||
*/
|
||||
const T &operator[](size_type i) const {
|
||||
assert(i < size());
|
||||
return _data[_topIndex + i];
|
||||
}
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif
|
||||
341
engines/titanic/support/font.cpp
Normal file
341
engines/titanic/support/font.cpp
Normal file
@@ -0,0 +1,341 @@
|
||||
/* 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/textconsole.h"
|
||||
#include "titanic/support/font.h"
|
||||
#include "titanic/support/files_manager.h"
|
||||
#include "titanic/titanic.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
STFont::STFont() {
|
||||
_dataPtr = nullptr;
|
||||
_dataSize = 0;
|
||||
_fontHeight = 0;
|
||||
_dataWidth = 0;
|
||||
_fontR = _fontG = _fontB = 0;
|
||||
}
|
||||
|
||||
STFont::~STFont() {
|
||||
delete[] _dataPtr;
|
||||
}
|
||||
|
||||
void STFont::load(int fontNumber) {
|
||||
assert(!_dataPtr);
|
||||
Common::SeekableReadStream *stream = g_vm->_filesManager->getResource(
|
||||
CString::format("STFONT/%d", fontNumber));
|
||||
if (!stream)
|
||||
error("Could not locate the specified font");
|
||||
|
||||
_fontHeight = stream->readUint32LE();
|
||||
_dataWidth = stream->readUint32LE();
|
||||
for (uint idx = 0; idx < 256; ++idx)
|
||||
_chars[idx]._width = stream->readUint32LE();
|
||||
for (uint idx = 0; idx < 256; ++idx)
|
||||
_chars[idx]._offset = stream->readUint32LE();
|
||||
|
||||
_dataSize = stream->readUint32LE();
|
||||
_dataPtr = new byte[_dataSize];
|
||||
stream->read(_dataPtr, _dataSize);
|
||||
|
||||
delete stream;
|
||||
}
|
||||
|
||||
void STFont::setColor(byte r, byte g, byte b) {
|
||||
_fontR = r;
|
||||
_fontG = g;
|
||||
_fontB = b;
|
||||
}
|
||||
|
||||
uint16 STFont::getColor() const {
|
||||
return g_system->getScreenFormat().RGBToColor(_fontR, _fontG, _fontB);
|
||||
}
|
||||
|
||||
int STFont::getTextBounds(const CString &str, int maxWidth, Point *sizeOut) const {
|
||||
Point textSize;
|
||||
|
||||
// Reset output dimensions if provided
|
||||
if (sizeOut)
|
||||
*sizeOut = Point(0, 0);
|
||||
|
||||
if (_fontHeight == 0 || !_dataPtr)
|
||||
// No font, so return immediately
|
||||
return 0;
|
||||
|
||||
// Loop through the characters of the string
|
||||
if (!str.empty()) {
|
||||
for (const char *strP = str.c_str(); *strP; ++strP) {
|
||||
if (*strP == TEXTCMD_NPC) {
|
||||
strP += 3;
|
||||
} else if (*strP == TEXTCMD_SET_COLOR) {
|
||||
strP += 4;
|
||||
} else {
|
||||
if (*strP == ' ') {
|
||||
// Check for line wrapping
|
||||
checkLineWrap(textSize, maxWidth, strP);
|
||||
}
|
||||
|
||||
extendBounds(textSize, *strP, maxWidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sizeOut)
|
||||
*sizeOut = textSize;
|
||||
|
||||
return textSize.y + _fontHeight;
|
||||
}
|
||||
|
||||
int STFont::stringWidth(const CString &text) const {
|
||||
if (text.empty())
|
||||
return 0;
|
||||
|
||||
const char *srcP = text.c_str();
|
||||
int total = 0;
|
||||
char c;
|
||||
while ((c = *srcP++)) {
|
||||
if (c == 26) {
|
||||
// Skip over command parameter bytes
|
||||
srcP += 3;
|
||||
} else if (c == TEXTCMD_SET_COLOR) {
|
||||
// Skip over command parameter bytes
|
||||
srcP += 4;
|
||||
} else if (c != '\n') {
|
||||
total += _chars[(byte)c]._width;
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
int STFont::writeString(CVideoSurface *surface, const Rect &rect1, const Rect &destRect,
|
||||
int yOffset, const CString &str, CTextCursor *textCursor) {
|
||||
if (!_fontHeight || !_dataPtr)
|
||||
return -1;
|
||||
|
||||
Point textSize(0, -yOffset);
|
||||
Rect destBounds = destRect;
|
||||
destBounds.constrain(rect1);
|
||||
if (destBounds.isEmpty())
|
||||
return -1;
|
||||
|
||||
const char *endP = nullptr;
|
||||
const char *strEndP = str.c_str() + str.size() - 1;
|
||||
for (const char *srcP = str.c_str(); *srcP; ++srcP) {
|
||||
if (*srcP == TEXTCMD_NPC) {
|
||||
srcP += 3;
|
||||
} else if (*srcP == TEXTCMD_SET_COLOR) {
|
||||
// Change the color used for characters
|
||||
byte r = *++srcP;
|
||||
byte g = *++srcP;
|
||||
byte b = *++srcP;
|
||||
++srcP;
|
||||
setColor(r, g, b);
|
||||
} else {
|
||||
if (*srcP == ' ') {
|
||||
// Check for line wrapping
|
||||
checkLineWrap(textSize, rect1.width(), srcP);
|
||||
if (!*srcP)
|
||||
return endP - str.c_str();
|
||||
}
|
||||
|
||||
if (*srcP != '\n') {
|
||||
WriteCharacterResult result = writeChar(surface, *srcP, textSize, rect1, &destBounds);
|
||||
if (result == WC_OUTSIDE_BOTTOM)
|
||||
return endP - str.c_str();
|
||||
else if (result == WC_IN_BOUNDS)
|
||||
endP = srcP;
|
||||
}
|
||||
|
||||
if (srcP < strEndP)
|
||||
extendBounds(textSize, *srcP, rect1.width());
|
||||
}
|
||||
}
|
||||
|
||||
if (textCursor && textCursor->getMode() == -2) {
|
||||
Point cursorPos(rect1.left + textSize.x, rect1.top + textSize.y);
|
||||
textCursor->setPos(cursorPos);
|
||||
}
|
||||
|
||||
return endP ? endP - str.c_str() : 0;
|
||||
}
|
||||
|
||||
void STFont::writeString(CVideoSurface *surface, const Point &destPos, Rect &clipRect,
|
||||
const CString &str, int lineWidth) {
|
||||
if (!_fontHeight || !_dataPtr || str.empty())
|
||||
return;
|
||||
if (!lineWidth)
|
||||
// No line width specified, so get in the width
|
||||
lineWidth = stringWidth(str);
|
||||
|
||||
Rect textRect(0, 0, lineWidth, _fontHeight);
|
||||
Point textPt = destPos;
|
||||
|
||||
// Perform clipping as necessary if the text will fall outside clipping area
|
||||
if (textPt.y > clipRect.bottom)
|
||||
return;
|
||||
|
||||
if ((textPt.y + textRect.height()) > clipRect.bottom)
|
||||
textRect.bottom = textRect.top - textPt.y + clipRect.bottom;
|
||||
|
||||
if (textPt.y < clipRect.top) {
|
||||
if ((textPt.y + textRect.height()) < clipRect.top)
|
||||
return;
|
||||
|
||||
textRect.top += clipRect.top - textPt.y;
|
||||
textPt.y = clipRect.top;
|
||||
}
|
||||
|
||||
// Iterate through each character of the string
|
||||
for (const byte *srcP = (const byte *)str.c_str(); *srcP; ++srcP) {
|
||||
byte c = *srcP;
|
||||
if (c == 0xE9)
|
||||
c = '$';
|
||||
|
||||
// Form a rect of the area of the next character to draw
|
||||
Rect charRect(_chars[c]._offset, textRect.top,
|
||||
_chars[c]._offset + _chars[c]._width, textRect.bottom);
|
||||
int textX = textPt.x;
|
||||
|
||||
if (textPt.x < clipRect.left) {
|
||||
// Character is either partially or entirely left off-screen
|
||||
if ((textPt.x + charRect.width()) < clipRect.left) {
|
||||
textPt.x += _chars[c]._width;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Partially clipped on left-hand side
|
||||
charRect.left = clipRect.left - textPt.x;
|
||||
textPt.x = clipRect.left;
|
||||
} else if ((textPt.x + charRect.width()) > clipRect.right) {
|
||||
if (textPt.x > clipRect.right)
|
||||
// Now entirely off right-hand side, so stop drawing
|
||||
break;
|
||||
|
||||
// Partially clipped on right-hand side
|
||||
charRect.right += clipRect.right - textPt.x - charRect.width();
|
||||
}
|
||||
|
||||
// At this point, we know we've got to draw at least part of a character,
|
||||
// and have figured out the area of the character to draw
|
||||
copyRect(surface, textPt, charRect);
|
||||
textPt.x = textX + _chars[c]._width;
|
||||
}
|
||||
}
|
||||
|
||||
WriteCharacterResult STFont::writeChar(CVideoSurface *surface, unsigned char c, const Point &pt,
|
||||
const Rect &destRect, const Rect *srcRect) {
|
||||
if (c == 233)
|
||||
c = '$';
|
||||
|
||||
Rect charRect(_chars[c]._offset, 0,
|
||||
_chars[c]._offset + _chars[c]._width, _fontHeight);
|
||||
Point destPos(pt.x + destRect.left, pt.y + destRect.top);
|
||||
|
||||
if (srcRect->isEmpty())
|
||||
srcRect = &destRect;
|
||||
if (destPos.y > srcRect->bottom)
|
||||
return WC_OUTSIDE_BOTTOM;
|
||||
|
||||
if ((destPos.y + charRect.height()) > srcRect->bottom) {
|
||||
charRect.bottom += srcRect->bottom - (destPos.y + charRect.height());
|
||||
}
|
||||
|
||||
if (destPos.y < srcRect->top) {
|
||||
if ((charRect.height() + destPos.y) < srcRect->top)
|
||||
return WC_OUTSIDE_TOP;
|
||||
|
||||
charRect.top += srcRect->top - destPos.y;
|
||||
destPos.y = srcRect->top;
|
||||
}
|
||||
|
||||
if (destPos.x < srcRect->left) {
|
||||
if ((charRect.width() + destPos.x) < srcRect->left)
|
||||
return WC_OUTSIDE_LEFT;
|
||||
|
||||
charRect.left += srcRect->left - destPos.x;
|
||||
destPos.x = srcRect->left;
|
||||
} else {
|
||||
if ((destPos.x + charRect.width()) > srcRect->right) {
|
||||
if (destPos.x > srcRect->right)
|
||||
return WC_OUTSIDE_RIGHT;
|
||||
|
||||
charRect.right += srcRect->right - destPos.x - charRect.width();
|
||||
}
|
||||
}
|
||||
|
||||
copyRect(surface, destPos, charRect);
|
||||
return WC_IN_BOUNDS;
|
||||
}
|
||||
|
||||
void STFont::copyRect(CVideoSurface *surface, const Point &pt, Rect &rect) {
|
||||
if (surface->lock()) {
|
||||
uint16 *lineP = surface->getBasePtr(pt.x, pt.y);
|
||||
uint16 color = getColor();
|
||||
|
||||
for (int yp = rect.top; yp < rect.bottom; ++yp, lineP += surface->getWidth()) {
|
||||
uint16 *destP = lineP;
|
||||
for (int xp = rect.left; xp < rect.right; ++xp, ++destP) {
|
||||
const byte *transP = _dataPtr + yp * _dataWidth + xp;
|
||||
surface->copyPixel(destP, &color, *transP >> 3,
|
||||
surface->getRawSurface()->format, true);
|
||||
}
|
||||
}
|
||||
|
||||
surface->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void STFont::extendBounds(Point &textSize, byte c, int maxWidth) const {
|
||||
textSize.x += _chars[c]._width;
|
||||
|
||||
if (c == '\n' || textSize.x > maxWidth) {
|
||||
textSize.x = 0;
|
||||
textSize.y += _fontHeight;
|
||||
}
|
||||
}
|
||||
|
||||
void STFont::checkLineWrap(Point &textSize, int maxWidth, const char *&str) const {
|
||||
bool flag = false;
|
||||
int totalWidth = 0;
|
||||
|
||||
// Loop forward getting the width of the word (including preceding space)
|
||||
// until a space is encountered following at least one character
|
||||
for (const char *srcPtr = str; *srcPtr && (*srcPtr != ' ' || !flag); ++srcPtr) {
|
||||
if (*srcPtr == TEXTCMD_NPC) {
|
||||
srcPtr += 3;
|
||||
} else if (*srcPtr == TEXTCMD_SET_COLOR) {
|
||||
srcPtr += 4;
|
||||
} else {
|
||||
totalWidth += _chars[(byte)*srcPtr]._width;
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((textSize.x + totalWidth) >= maxWidth && totalWidth < maxWidth) {
|
||||
// Word wrap
|
||||
textSize.x = 0;
|
||||
textSize.y += _fontHeight;
|
||||
++str;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
128
engines/titanic/support/font.h
Normal file
128
engines/titanic/support/font.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/* 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 TITANIC_FONT_H
|
||||
#define TITANIC_FONT_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/array.h"
|
||||
#include "titanic/support/rect.h"
|
||||
#include "titanic/support/string.h"
|
||||
#include "titanic/support/text_cursor.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
enum TextCommand { TEXTCMD_NPC = 26, TEXTCMD_SET_COLOR = 27 };
|
||||
|
||||
enum WriteCharacterResult {
|
||||
WC_IN_BOUNDS = 0, WC_OUTSIDE_TOP = -1, WC_OUTSIDE_BOTTOM = -2,
|
||||
WC_OUTSIDE_LEFT = -3, WC_OUTSIDE_RIGHT = -4
|
||||
};
|
||||
|
||||
class CVideoSurface;
|
||||
|
||||
class STFont {
|
||||
struct CharEntry {
|
||||
uint _width;
|
||||
uint _offset;
|
||||
};
|
||||
private:
|
||||
/**
|
||||
* Copys a rectangle representing a character in the font data to
|
||||
* a given destination position in the surface
|
||||
*/
|
||||
void copyRect(CVideoSurface *surface, const Common::Point &destPos,
|
||||
Rect &srcRect);
|
||||
|
||||
/**
|
||||
* Write a character
|
||||
*/
|
||||
WriteCharacterResult writeChar(CVideoSurface *surface, unsigned char c,
|
||||
const Common::Point &pt, const Rect &destRect, const Rect *srcRect);
|
||||
|
||||
/**
|
||||
* Extends a passed text area by the space required for
|
||||
* the given character
|
||||
*/
|
||||
void extendBounds(Point &textSize, byte c, int maxWidth) const;
|
||||
|
||||
/**
|
||||
* Called at spacing between words, checks for line wrapping
|
||||
*/
|
||||
void checkLineWrap(Point &textSize, int maxWidth, const char *&str) const;
|
||||
public:
|
||||
byte *_dataPtr;
|
||||
size_t _dataSize;
|
||||
int _fontHeight;
|
||||
uint _dataWidth;
|
||||
CharEntry _chars[256];
|
||||
byte _fontR, _fontG, _fontB;
|
||||
public:
|
||||
STFont();
|
||||
~STFont();
|
||||
|
||||
/**
|
||||
* Load a specified font
|
||||
*/
|
||||
void load(int fontNumber);
|
||||
|
||||
/**
|
||||
* Return the width in pixels of the specified text
|
||||
*/
|
||||
int stringWidth(const CString &text) const;
|
||||
|
||||
/**
|
||||
* Write a string to the specified surface
|
||||
* @returns The index of the last character that was visible
|
||||
* with the drawing area
|
||||
*/
|
||||
int writeString(CVideoSurface *surface, const Rect &rect1, const Rect &destRect,
|
||||
int yOffset, const CString &str, CTextCursor *textCursor);
|
||||
|
||||
/**
|
||||
* Write a string to the specified surface
|
||||
*/
|
||||
void writeString(CVideoSurface *surface, const Point &destPos, Rect &clipRect,
|
||||
const CString &str, int lineWidth = 0);
|
||||
|
||||
/**
|
||||
* Get the text area a string will fit into
|
||||
* @param str String
|
||||
* @param maxWidth Maximum width in pixels
|
||||
* @param sizeOut Optional pointer to output size (width, height)
|
||||
* @returns Required height
|
||||
*/
|
||||
int getTextBounds(const CString &str, int maxWidth, Point *sizeOut) const;
|
||||
|
||||
/**
|
||||
* Sets the font color
|
||||
*/
|
||||
void setColor(byte r, byte g, byte b);
|
||||
|
||||
/**
|
||||
* Gets the font color
|
||||
*/
|
||||
uint16 getColor() const;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_FONT_H */
|
||||
56
engines/titanic/support/image.cpp
Normal file
56
engines/titanic/support/image.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 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 "titanic/support/image.h"
|
||||
#include "titanic/support/files_manager.h"
|
||||
#include "image/bmp.h"
|
||||
#include "titanic/titanic.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
void Image::load(const CString &resName) {
|
||||
Common::SeekableReadStream *stream = g_vm->_filesManager->getResource(resName);
|
||||
loadBitmap(*stream);
|
||||
delete stream;
|
||||
}
|
||||
|
||||
void Image::loadBitmap(Common::SeekableReadStream &s) {
|
||||
::Image::BitmapDecoder decoder;
|
||||
decoder.loadStream(s);
|
||||
const Graphics::Surface *src = decoder.getSurface();
|
||||
Graphics::PixelFormat scrFormat = g_system->getScreenFormat();
|
||||
|
||||
if (src->format == scrFormat) {
|
||||
create(src->w, src->h, scrFormat);
|
||||
blitFrom(*src);
|
||||
} else {
|
||||
// Convert the loaded surface to the screen surface format
|
||||
const Graphics::Palette &palette = decoder.getPalette();
|
||||
Graphics::Surface *surface = src->convertTo(scrFormat, palette.data(), palette.size());
|
||||
create(surface->w, surface->h, scrFormat);
|
||||
blitFrom(*surface);
|
||||
|
||||
surface->free();
|
||||
delete surface;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
42
engines/titanic/support/image.h
Normal file
42
engines/titanic/support/image.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/* 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 TITANIC_IMAGE_H
|
||||
#define TITANIC_IMAGE_H
|
||||
|
||||
#include "common/stream.h"
|
||||
#include "graphics/managed_surface.h"
|
||||
#include "titanic/support/string.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class Image : public Graphics::ManagedSurface {
|
||||
private:
|
||||
void loadBitmap(Common::SeekableReadStream &s);
|
||||
public:
|
||||
~Image() override {}
|
||||
|
||||
void load(const CString &resName);
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_IMAGE_H */
|
||||
81
engines/titanic/support/image_decoders.cpp
Normal file
81
engines/titanic/support/image_decoders.cpp
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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/system.h"
|
||||
#include "titanic/support/image_decoders.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
void CJPEGDecode::decode(OSVideoSurface &surface, const CString &name) {
|
||||
// Open up the resource
|
||||
StdCWadFile file;
|
||||
file.open(name);
|
||||
|
||||
// Use the ScummVM decoder to decode it
|
||||
setOutputPixelFormat(g_system->getScreenFormat());
|
||||
loadStream(*file.readStream());
|
||||
const Graphics::Surface *srcSurf = getSurface();
|
||||
|
||||
// Resize the surface if necessary
|
||||
if (!surface.hasSurface() || surface.getWidth() != srcSurf->w
|
||||
|| surface.getHeight() != srcSurf->h)
|
||||
surface.recreate(srcSurf->w, srcSurf->h, 16);
|
||||
|
||||
// Copy the decoded surface
|
||||
surface.lock();
|
||||
|
||||
assert(srcSurf->format == surface._rawSurface->format);
|
||||
|
||||
Common::copy((const byte *)srcSurf->getPixels(), (const byte *)srcSurf->getPixels() +
|
||||
surface.getPitch() * surface.getHeight(), (byte *)surface._rawSurface->getPixels());
|
||||
|
||||
surface.unlock();
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void CTargaDecode::decode(OSVideoSurface &surface, const CString &name) {
|
||||
// Open up the resource
|
||||
StdCWadFile file;
|
||||
file.open(name);
|
||||
|
||||
// Use the ScucmmVM deoder to decode it
|
||||
loadStream(*file.readStream());
|
||||
const Graphics::Surface *srcSurf = getSurface();
|
||||
|
||||
// Resize the surface if necessary
|
||||
if (!surface.hasSurface() || surface.getWidth() != srcSurf->w
|
||||
|| surface.getHeight() != srcSurf->h)
|
||||
surface.recreate(srcSurf->w, srcSurf->h, 16);
|
||||
|
||||
// Convert the decoded surface to the correct pixel format, and then copy it over
|
||||
surface.lock();
|
||||
Graphics::Surface *convertedSurface = srcSurf->convertTo(surface._rawSurface->format);
|
||||
|
||||
Common::copy((byte *)convertedSurface->getPixels(), (byte *)convertedSurface->getPixels() +
|
||||
surface.getPitch() * surface.getHeight(), (byte *)surface._rawSurface->getPixels());
|
||||
|
||||
convertedSurface->free();
|
||||
delete convertedSurface;
|
||||
surface.unlock();
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
51
engines/titanic/support/image_decoders.h
Normal file
51
engines/titanic/support/image_decoders.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* 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 TITANIC_IMAGE_DECODERS_H
|
||||
#define TITANIC_IMAGE_DECODERS_H
|
||||
|
||||
#include "image/jpeg.h"
|
||||
#include "image/tga.h"
|
||||
#include "titanic/support/string.h"
|
||||
#include "titanic/support/simple_file.h"
|
||||
#include "titanic/support/video_surface.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CJPEGDecode : public Image::JPEGDecoder {
|
||||
public:
|
||||
/**
|
||||
* Decode the image file onto the passed surface
|
||||
*/
|
||||
void decode(OSVideoSurface &surface, const CString &name);
|
||||
};
|
||||
|
||||
class CTargaDecode : public Image::TGADecoder {
|
||||
public:
|
||||
/**
|
||||
* Decode the image file onto the passed surface
|
||||
*/
|
||||
void decode(OSVideoSurface &surface, const CString &name);
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_IMAGE_DECODERS_H */
|
||||
200
engines/titanic/support/mouse_cursor.cpp
Normal file
200
engines/titanic/support/mouse_cursor.cpp
Normal file
@@ -0,0 +1,200 @@
|
||||
/* 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 "titanic/support/mouse_cursor.h"
|
||||
#include "titanic/support/screen_manager.h"
|
||||
#include "titanic/support/transparency_surface.h"
|
||||
#include "titanic/support/video_surface.h"
|
||||
#include "titanic/events.h"
|
||||
#include "titanic/input_handler.h"
|
||||
#include "titanic/messages/mouse_messages.h"
|
||||
#include "titanic/titanic.h"
|
||||
#include "graphics/cursorman.h"
|
||||
#include "graphics/screen.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
#define CURSOR_SIZE 64
|
||||
|
||||
static const int CURSOR_DATA[NUM_CURSORS][4] = {
|
||||
{ 1, 136, 19, 18 },
|
||||
{ 2, 139, 1, 1 },
|
||||
{ 3, 140, 32, 1 },
|
||||
{ 4, 137, 13, 0 },
|
||||
{ 5, 145, 13, 0 },
|
||||
{ 6, 144, 13, 22 },
|
||||
{ 7, 137, 14, 0 },
|
||||
{ 8, 148, 22, 40 },
|
||||
{ 9, 136, 19, 18 },
|
||||
{ 10, 143, 11, 11 },
|
||||
{ 11, 146, 11, 11 },
|
||||
{ 12, 136, 19, 18 },
|
||||
{ 13, 136, 19, 25 },
|
||||
{ 14, 136, 13, 22 },
|
||||
{ 15, 138, 20, 28 }
|
||||
};
|
||||
|
||||
CMouseCursor::CursorEntry::~CursorEntry() {
|
||||
delete _surface;
|
||||
}
|
||||
|
||||
CMouseCursor::CMouseCursor(CScreenManager *screenManager) :
|
||||
_screenManager(screenManager), _cursorId(CURSOR_HOURGLASS), _hideCounter(0),
|
||||
_busyCount(0), _cursorSuppressed(false), _setCursorCount(0), _inputEnabled(true), _fieldE8(0) {
|
||||
loadCursorImages();
|
||||
setCursor(CURSOR_ARROW);
|
||||
CursorMan.showMouse(true);
|
||||
}
|
||||
|
||||
CMouseCursor::~CMouseCursor() {
|
||||
}
|
||||
|
||||
void CMouseCursor::loadCursorImages() {
|
||||
const CResourceKey key("ycursors.avi");
|
||||
|
||||
// Iterate through getting each cursor
|
||||
for (int idx = 0; idx < NUM_CURSORS; ++idx) {
|
||||
assert(CURSOR_DATA[idx][0] == (idx + 1));
|
||||
_cursors[idx]._centroid = Common::Point(CURSOR_DATA[idx][2],
|
||||
CURSOR_DATA[idx][3]);
|
||||
|
||||
// Create the surface
|
||||
CVideoSurface *surface = _screenManager->createSurface(CURSOR_SIZE, CURSOR_SIZE);
|
||||
|
||||
// Open the cursors video and move to the given frame
|
||||
OSMovie *movie = new OSMovie(key, surface);
|
||||
movie->setFrame(idx);
|
||||
Graphics::ManagedSurface *transSurface = movie->duplicateTransparency();
|
||||
|
||||
// Create a managed surface to hold the RGBA version of the cursor
|
||||
Graphics::PixelFormat rgbaFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
|
||||
_cursors[idx]._surface = new Graphics::ManagedSurface(CURSOR_SIZE, CURSOR_SIZE, rgbaFormat);
|
||||
|
||||
// Copy the cursor from the movie's video surface
|
||||
surface->lock();
|
||||
_cursors[idx]._surface->blitFrom(*surface->getRawSurface());
|
||||
surface->unlock();
|
||||
|
||||
// We need to separately merge in the transparency surface
|
||||
for (int y = 0; y < CURSOR_SIZE; ++y) {
|
||||
const byte *srcP = (const byte *)transSurface->getBasePtr(0, y);
|
||||
uint32 *destP = (uint32 *)_cursors[idx]._surface->getBasePtr(0, y);
|
||||
|
||||
for (int x = 0; x < CURSOR_SIZE; ++x, ++srcP, ++destP)
|
||||
*destP = (*destP & ~0xff) | *srcP;
|
||||
}
|
||||
|
||||
delete movie;
|
||||
delete transSurface;
|
||||
delete surface;
|
||||
}
|
||||
}
|
||||
|
||||
void CMouseCursor::incBusyCount() {
|
||||
if (_busyCount == 0)
|
||||
setCursor(CURSOR_HOURGLASS);
|
||||
++_busyCount;
|
||||
}
|
||||
|
||||
void CMouseCursor::decBusyCount() {
|
||||
assert(_busyCount > 0);
|
||||
if (--_busyCount == 0)
|
||||
setCursor(CURSOR_ARROW);
|
||||
}
|
||||
|
||||
void CMouseCursor::incHideCounter() {
|
||||
if (_hideCounter++ == 0)
|
||||
CursorMan.showMouse(false);
|
||||
}
|
||||
|
||||
void CMouseCursor::decHideCounter() {
|
||||
--_hideCounter;
|
||||
assert(_hideCounter >= 0);
|
||||
if (_hideCounter == 0)
|
||||
CursorMan.showMouse(true);
|
||||
}
|
||||
|
||||
void CMouseCursor::suppressCursor() {
|
||||
_cursorSuppressed = true;
|
||||
CursorMan.showMouse(false);
|
||||
}
|
||||
|
||||
void CMouseCursor::unsuppressCursor() {
|
||||
_cursorSuppressed = false;
|
||||
if (_hideCounter == 0)
|
||||
CursorMan.showMouse(true);
|
||||
}
|
||||
|
||||
void CMouseCursor::setCursor(CursorId cursorId) {
|
||||
++_setCursorCount;
|
||||
|
||||
if (cursorId != _cursorId && _busyCount == 0) {
|
||||
const CursorEntry &ce = _cursors[cursorId - 1];
|
||||
_cursorId = cursorId;
|
||||
|
||||
// Set the cursor
|
||||
CursorMan.replaceCursor(*ce._surface, ce._centroid.x, ce._centroid.y, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
void CMouseCursor::update() {
|
||||
if (!_inputEnabled && _moveStartTime) {
|
||||
uint32 time = CLIP(g_system->getMillis(), _moveStartTime, _moveEndTime);
|
||||
Common::Point pt(
|
||||
_moveStartPos.x + (_moveDestPos.x - _moveStartPos.x) *
|
||||
(int)(time - _moveStartTime) / (int)(_moveEndTime - _moveStartTime),
|
||||
_moveStartPos.y + (_moveDestPos.y - _moveStartPos.y) *
|
||||
(int)(time - _moveStartTime) / (int)(_moveEndTime - _moveStartTime)
|
||||
);
|
||||
|
||||
if (pt != g_vm->_events->getMousePos()) {
|
||||
g_vm->_events->setMousePos(pt);
|
||||
|
||||
CInputHandler &inputHandler = *CScreenManager::_screenManagerPtr->_inputHandler;
|
||||
CMouseMoveMsg msg(pt, 0);
|
||||
inputHandler.handleMessage(msg, false);
|
||||
}
|
||||
|
||||
if (time == _moveEndTime)
|
||||
_moveStartTime = _moveEndTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CMouseCursor::disableControl() {
|
||||
_inputEnabled = false;
|
||||
CScreenManager::_screenManagerPtr->_inputHandler->incLockCount();
|
||||
}
|
||||
|
||||
void CMouseCursor::enableControl() {
|
||||
_inputEnabled = true;
|
||||
_fieldE8 = 0;
|
||||
CScreenManager::_screenManagerPtr->_inputHandler->decLockCount();
|
||||
}
|
||||
|
||||
void CMouseCursor::setPosition(const Point &pt, double duration) {
|
||||
_moveStartPos = g_vm->_events->getMousePos();
|
||||
_moveDestPos = pt;
|
||||
_moveStartTime = g_system->getMillis();
|
||||
_moveEndTime = _moveStartTime + (int)duration;
|
||||
update();
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
153
engines/titanic/support/mouse_cursor.h
Normal file
153
engines/titanic/support/mouse_cursor.h
Normal file
@@ -0,0 +1,153 @@
|
||||
/* 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 TITANIC_MOUSE_CURSOR_H
|
||||
#define TITANIC_MOUSE_CURSOR_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "graphics/managed_surface.h"
|
||||
#include "titanic/support/rect.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
#define NUM_CURSORS 15
|
||||
|
||||
enum CursorId {
|
||||
CURSOR_ARROW = 1,
|
||||
CURSOR_MOVE_LEFT = 2,
|
||||
CURSOR_MOVE_RIGHT = 3,
|
||||
CURSOR_MOVE_FORWARD = 4,
|
||||
CURSOR_LOOK_UP = 5,
|
||||
CURSOR_LOOK_DOWN = 6,
|
||||
CURSOR_MOVE_THROUGH = 7,
|
||||
CURSOR_HAND = 8,
|
||||
CURSOR_ACTIVATE = 9,
|
||||
CURSOR_INVALID = 10,
|
||||
CURSOR_MAGNIFIER = 11,
|
||||
CURSOR_IGNORE = 12,
|
||||
CURSOR_BACKWARDS = 13,
|
||||
CURSOR_DOWN = 14,
|
||||
CURSOR_HOURGLASS = 15
|
||||
};
|
||||
|
||||
class CScreenManager;
|
||||
class CVideoSurface;
|
||||
|
||||
class CMouseCursor {
|
||||
struct CursorEntry {
|
||||
Graphics::ManagedSurface *_surface;
|
||||
Common::Point _centroid;
|
||||
|
||||
CursorEntry() : _surface(nullptr) {}
|
||||
~CursorEntry();
|
||||
};
|
||||
private:
|
||||
CScreenManager *_screenManager;
|
||||
CursorId _cursorId;
|
||||
CursorEntry _cursors[NUM_CURSORS];
|
||||
uint _setCursorCount;
|
||||
int _hideCounter;
|
||||
int _busyCount;
|
||||
bool _cursorSuppressed;
|
||||
int _fieldE8;
|
||||
Common::Point _moveStartPos;
|
||||
Common::Point _moveDestPos;
|
||||
uint32 _moveStartTime, _moveEndTime;
|
||||
|
||||
/**
|
||||
* Load the images for each cursor
|
||||
*/
|
||||
void loadCursorImages();
|
||||
public:
|
||||
bool _inputEnabled;
|
||||
public:
|
||||
CMouseCursor(CScreenManager *screenManager);
|
||||
~CMouseCursor();
|
||||
|
||||
/**
|
||||
* Increment the busy count for the cursor, showing an hourglass
|
||||
*/
|
||||
void incBusyCount();
|
||||
|
||||
/**
|
||||
* Decrements the busy count, resetting back to an arrow cursor
|
||||
* when the count reaches zero
|
||||
*/
|
||||
void decBusyCount();
|
||||
|
||||
/**
|
||||
* Decrements the hide counter, and shows the mouse if
|
||||
* it's reached zero
|
||||
*/
|
||||
void incHideCounter();
|
||||
|
||||
/**
|
||||
* Increments the hide counter, hiding the mouse if it's the first call
|
||||
*/
|
||||
void decHideCounter();
|
||||
|
||||
/**
|
||||
* Suppresses the cursor. When suppressed, the cursor isn't drawn,
|
||||
* even if it's not otherwise being hidden
|
||||
*/
|
||||
void suppressCursor();
|
||||
|
||||
/**
|
||||
* Unflags the cursor as being suppressed, allowing it to be drawn
|
||||
* again if it's enabled
|
||||
*/
|
||||
void unsuppressCursor();
|
||||
|
||||
/**
|
||||
* Set the cursor
|
||||
*/
|
||||
void setCursor(CursorId cursorId);
|
||||
|
||||
/**
|
||||
* Updates the mouse cursor
|
||||
*/
|
||||
void update();
|
||||
|
||||
/**
|
||||
* Returns the number of times the cursor has been set
|
||||
*/
|
||||
uint getChangeCount() const { return _setCursorCount; }
|
||||
|
||||
/**
|
||||
* Disables user control of the mouse
|
||||
*/
|
||||
void disableControl();
|
||||
|
||||
/**
|
||||
* Re-enables user control of the mouse
|
||||
*/
|
||||
void enableControl();
|
||||
|
||||
/**
|
||||
* Move the mouse to a new position
|
||||
*/
|
||||
void setPosition(const Point &pt, double duration);
|
||||
};
|
||||
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_MOUSE_CURSOR_H */
|
||||
209
engines/titanic/support/movie.cpp
Normal file
209
engines/titanic/support/movie.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
/* 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 "titanic/support/movie.h"
|
||||
#include "titanic/core/game_object.h"
|
||||
#include "titanic/events.h"
|
||||
#include "titanic/messages/messages.h"
|
||||
#include "titanic/support/avi_surface.h"
|
||||
#include "titanic/support/screen_manager.h"
|
||||
#include "titanic/support/video_surface.h"
|
||||
#include "titanic/sound/sound_manager.h"
|
||||
#include "titanic/titanic.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
#define CLIP_WIDTH 600
|
||||
#define CLIP_WIDTH_REDUCED (CLIP_WIDTH / 2)
|
||||
#define CLIP_HEIGHT 340
|
||||
#define CLIP_HEIGHT_REDUCED (CLIP_HEIGHT / 2)
|
||||
|
||||
CMovieList *CMovie::_playingMovies;
|
||||
CVideoSurface *CMovie::_movieSurface;
|
||||
|
||||
CMovie::CMovie() : ListItem(), _handled(false), _hasVideoFrame(false) {
|
||||
}
|
||||
|
||||
CMovie::~CMovie() {
|
||||
removeFromPlayingMovies();
|
||||
}
|
||||
|
||||
void CMovie::init() {
|
||||
_playingMovies = new CMovieList();
|
||||
_movieSurface = nullptr;
|
||||
}
|
||||
|
||||
void CMovie::deinit() {
|
||||
// At this point, there shouldn't be any playing movies left,
|
||||
// since their owning objects should have freed them
|
||||
assert(_playingMovies->empty());
|
||||
delete _playingMovies;
|
||||
delete _movieSurface;
|
||||
}
|
||||
|
||||
void CMovie::addToPlayingMovies() {
|
||||
if (!isActive())
|
||||
_playingMovies->push_back(this);
|
||||
}
|
||||
|
||||
void CMovie::removeFromPlayingMovies() {
|
||||
_playingMovies->remove(this);
|
||||
}
|
||||
|
||||
bool CMovie::isActive() const {
|
||||
return _playingMovies->contains(this);
|
||||
}
|
||||
|
||||
bool CMovie::hasVideoFrame() {
|
||||
if (_hasVideoFrame) {
|
||||
_hasVideoFrame = 0;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
OSMovie::OSMovie(const CResourceKey &name, CVideoSurface *surface) :
|
||||
_aviSurface(name), _videoSurface(surface) {
|
||||
_field18 = 0;
|
||||
_field24 = 0;
|
||||
_field28 = 0;
|
||||
_field2C = 0;
|
||||
|
||||
surface->resize(_aviSurface.getWidth(), _aviSurface.getHeight());
|
||||
_aviSurface.setVideoSurface(surface);
|
||||
}
|
||||
|
||||
OSMovie::~OSMovie() {
|
||||
}
|
||||
|
||||
void OSMovie::play(uint flags, CGameObject *obj) {
|
||||
_aviSurface.play(flags, obj);
|
||||
|
||||
if (_aviSurface.isPlaying())
|
||||
movieStarted();
|
||||
}
|
||||
|
||||
void OSMovie::play(uint startFrame, uint endFrame, uint flags, CGameObject *obj) {
|
||||
_aviSurface.play(startFrame, endFrame, flags, obj);
|
||||
|
||||
if (_aviSurface.isPlaying())
|
||||
movieStarted();
|
||||
}
|
||||
|
||||
void OSMovie::play(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) {
|
||||
_aviSurface.play(startFrame, endFrame, initialFrame, flags, obj);
|
||||
|
||||
if (_aviSurface.isPlaying())
|
||||
movieStarted();
|
||||
}
|
||||
|
||||
bool OSMovie::playCutscene(const Rect &drawRect, uint startFrame, uint endFrame) {
|
||||
if (!_movieSurface)
|
||||
_movieSurface = CScreenManager::_screenManagerPtr->createSurface(600, 340, 32);
|
||||
|
||||
// Set a new event target whilst the clip plays, so standard scene drawing isn't called
|
||||
CEventTarget eventTarget;
|
||||
g_vm->_events->addTarget(&eventTarget);
|
||||
|
||||
bool result = _aviSurface.playCutscene(drawRect, startFrame, endFrame);
|
||||
|
||||
g_vm->_events->removeTarget();
|
||||
return result;
|
||||
}
|
||||
|
||||
void OSMovie::pause() {
|
||||
_aviSurface.pause();
|
||||
}
|
||||
|
||||
void OSMovie::stop() {
|
||||
_aviSurface.stop();
|
||||
removeFromPlayingMovies();
|
||||
}
|
||||
|
||||
void OSMovie::addEvent(int frameNumber, CGameObject *obj) {
|
||||
if (_aviSurface.addEvent(&frameNumber, obj)) {
|
||||
CMovieFrameMsg frameMsg(frameNumber, 0);
|
||||
frameMsg.execute(obj);
|
||||
}
|
||||
}
|
||||
|
||||
void OSMovie::setFrame(uint frameNumber) {
|
||||
_aviSurface.setFrame(frameNumber);
|
||||
_videoSurface->setTransparencySurface(_aviSurface.getSecondarySurface());
|
||||
}
|
||||
|
||||
bool OSMovie::handleEvents(CMovieEventList &events) {
|
||||
// WORKAROUND: If a movie is paused as part of initial
|
||||
// scene loading, now's the time to un-pause it
|
||||
_aviSurface.resume();
|
||||
|
||||
if (!_aviSurface.isPlaying())
|
||||
return false;
|
||||
|
||||
// Handle updating the frame
|
||||
while (_aviSurface.isPlaying() && _aviSurface.isNextFrame()) {
|
||||
_aviSurface.handleEvents(events);
|
||||
_videoSurface->setTransparencySurface(_aviSurface.getSecondarySurface());
|
||||
|
||||
// Flag there's a video frame
|
||||
_hasVideoFrame = true;
|
||||
}
|
||||
|
||||
return _aviSurface.isPlaying();
|
||||
}
|
||||
|
||||
const CMovieRangeInfoList *OSMovie::getMovieRangeInfo() const {
|
||||
return _aviSurface.getMovieRangeInfo();
|
||||
}
|
||||
|
||||
void OSMovie::setSoundManager(CSoundManager *soundManager) {
|
||||
_aviSurface._soundManager = soundManager;
|
||||
}
|
||||
|
||||
int OSMovie::getFrame() const {
|
||||
return _aviSurface.getFrame();
|
||||
}
|
||||
|
||||
void OSMovie::movieStarted() {
|
||||
//if (_aviSurface._hasAudio)
|
||||
// _aviSurface._soundManager->movieStarted();
|
||||
|
||||
// Register the movie in the playing list
|
||||
addToPlayingMovies();
|
||||
_hasVideoFrame = true;
|
||||
}
|
||||
|
||||
void OSMovie::setFrameRate(double rate) {
|
||||
_aviSurface.setFrameRate(rate);
|
||||
}
|
||||
|
||||
void OSMovie::setPlaying(bool playingFlag) {
|
||||
_aviSurface.setPlaying(playingFlag);
|
||||
}
|
||||
|
||||
Graphics::ManagedSurface *OSMovie::duplicateTransparency() const {
|
||||
return _aviSurface.duplicateTransparency();
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
265
engines/titanic/support/movie.h
Normal file
265
engines/titanic/support/movie.h
Normal file
@@ -0,0 +1,265 @@
|
||||
/* 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 TITANIC_MOVIE_H
|
||||
#define TITANIC_MOVIE_H
|
||||
|
||||
#include "common/list.h"
|
||||
#include "video/video_decoder.h"
|
||||
#include "titanic/core/list.h"
|
||||
#include "titanic/core/resource_key.h"
|
||||
#include "titanic/support/avi_surface.h"
|
||||
#include "titanic/support/movie_range_info.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CGameObject;
|
||||
class CMovie;
|
||||
class CSoundManager;
|
||||
class CVideoSurface;
|
||||
|
||||
class CMovieList : public List<CMovie> {
|
||||
public:
|
||||
};
|
||||
|
||||
class CMovie : public ListItem {
|
||||
protected:
|
||||
/**
|
||||
* Adds the movie to the list of currently playing movies
|
||||
*/
|
||||
void addToPlayingMovies();
|
||||
public:
|
||||
bool _handled;
|
||||
bool _hasVideoFrame;
|
||||
public:
|
||||
static CMovieList *_playingMovies;
|
||||
static CVideoSurface *_movieSurface;
|
||||
|
||||
/**
|
||||
* Initializes statics
|
||||
*/
|
||||
static void init();
|
||||
|
||||
/**
|
||||
* Deinitializes statics
|
||||
*/
|
||||
static void deinit();
|
||||
public:
|
||||
CMovie();
|
||||
~CMovie() override;
|
||||
|
||||
/**
|
||||
* Starts playing the movie
|
||||
*/
|
||||
virtual void play(uint flags, CGameObject *obj) = 0;
|
||||
|
||||
/**
|
||||
* Starts playing the movie
|
||||
*/
|
||||
virtual void play(uint startFrame, uint endFrame, uint flags, CGameObject *obj) = 0;
|
||||
|
||||
/**
|
||||
* Starts playing the movie
|
||||
*/
|
||||
virtual void play(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) = 0;
|
||||
|
||||
/**
|
||||
* Plays a sub-section of a movie, and doesn't return until either
|
||||
* the playback ends or a key has been pressed
|
||||
* @returns True if the cutscene was not interrupted
|
||||
*/
|
||||
virtual bool playCutscene(const Rect &drawRect, uint startFrame, uint endFrame) = 0;
|
||||
|
||||
/**
|
||||
* Pauses a movie
|
||||
* @remarks Acts a workaround for our video decoder, since some movies started
|
||||
* as part of a scene load need to be paused until the scene is interactive,
|
||||
* or else they get played back too quickly
|
||||
*/
|
||||
virtual void pause() = 0;
|
||||
|
||||
/**
|
||||
* Stops the movie
|
||||
*/
|
||||
virtual void stop() = 0;
|
||||
|
||||
/**
|
||||
* Add a playback event
|
||||
*/
|
||||
virtual void addEvent(int frameNumber, CGameObject *obj) = 0;
|
||||
|
||||
/**
|
||||
* Set the current frame number
|
||||
*/
|
||||
virtual void setFrame(uint frameNumber) = 0;
|
||||
|
||||
/**
|
||||
* Handle any pending movie events
|
||||
*/
|
||||
virtual bool handleEvents(CMovieEventList &events) = 0;
|
||||
|
||||
/**
|
||||
* Return any movie range info associated with the movie
|
||||
*/
|
||||
virtual const CMovieRangeInfoList *getMovieRangeInfo() const = 0;
|
||||
|
||||
/**
|
||||
* Set the sound manager reference
|
||||
*/
|
||||
virtual void setSoundManager(CSoundManager *soundManager) = 0;
|
||||
|
||||
/**
|
||||
* Get the current movie frame
|
||||
*/
|
||||
virtual int getFrame() const = 0;
|
||||
|
||||
/**
|
||||
* Set the frame rate for the movie
|
||||
*/
|
||||
virtual void setFrameRate(double rate) = 0;
|
||||
|
||||
/**
|
||||
* Sets whether the video is playing (versus paused)
|
||||
*/
|
||||
virtual void setPlaying(bool playingFlag) = 0;
|
||||
|
||||
/**
|
||||
* Creates a duplicate of the transparency surface
|
||||
*/
|
||||
virtual Graphics::ManagedSurface *duplicateTransparency() const = 0;
|
||||
|
||||
/**
|
||||
* Removes the movie from the list of currently playing movies
|
||||
*/
|
||||
void removeFromPlayingMovies();
|
||||
|
||||
/**
|
||||
* Returns true if the movie is currently active
|
||||
*/
|
||||
bool isActive() const;
|
||||
|
||||
/**
|
||||
* Returns true if there's a video frame
|
||||
*/
|
||||
bool hasVideoFrame();
|
||||
};
|
||||
|
||||
class OSMovie : public CMovie {
|
||||
private:
|
||||
AVISurface _aviSurface;
|
||||
CVideoSurface *_videoSurface;
|
||||
int _field18;
|
||||
int _field24;
|
||||
int _field28;
|
||||
int _field2C;
|
||||
private:
|
||||
/**
|
||||
* Called when a movie is started playing
|
||||
*/
|
||||
void movieStarted();
|
||||
public:
|
||||
OSMovie(const CResourceKey &name, CVideoSurface *surface);
|
||||
~OSMovie() override;
|
||||
|
||||
/**
|
||||
* Starts playing the movie
|
||||
*/
|
||||
void play(uint flags, CGameObject *obj) override;
|
||||
|
||||
/**
|
||||
* Starts playing the movie
|
||||
*/
|
||||
void play(uint startFrame, uint endFrame, uint flags, CGameObject *obj) override;
|
||||
|
||||
/**
|
||||
* Starts playing the movie
|
||||
*/
|
||||
void play(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) override;
|
||||
|
||||
/**
|
||||
* Plays a sub-section of a movie, and doesn't return until either
|
||||
* the playback ends or a key has been pressed
|
||||
* @returns True if the cutscene was not interrupted
|
||||
*/
|
||||
bool playCutscene(const Rect &drawRect, uint startFrame, uint endFrame) override;
|
||||
|
||||
/**
|
||||
* Pauses a movie
|
||||
* @remarks Acts a workaround for our video decoder, since some movies started
|
||||
* as part of a scene load need to be paused until the scene is interactive,
|
||||
* or else they get played back too quickly
|
||||
*/
|
||||
void pause() override;
|
||||
|
||||
/**
|
||||
* Stops the movie
|
||||
*/
|
||||
void stop() override;
|
||||
|
||||
/**
|
||||
* Add a playback event
|
||||
*/
|
||||
void addEvent(int eventId, CGameObject *obj) override;
|
||||
|
||||
/**
|
||||
* Set the current frame number
|
||||
*/
|
||||
void setFrame(uint frameNumber) override;
|
||||
|
||||
/**
|
||||
* Handle any pending movie events
|
||||
*/
|
||||
bool handleEvents(CMovieEventList &events) override;
|
||||
|
||||
/**
|
||||
* Get the current frame number
|
||||
*/
|
||||
int getFrame() const override;
|
||||
|
||||
/**
|
||||
* Return any movie range info associated with the movie
|
||||
*/
|
||||
const CMovieRangeInfoList *getMovieRangeInfo() const override;
|
||||
|
||||
/**
|
||||
* Set the sound manager reference
|
||||
*/
|
||||
void setSoundManager(CSoundManager *soundManager) override;
|
||||
|
||||
/**
|
||||
* Set the frame rate for the movie
|
||||
*/
|
||||
void setFrameRate(double rate) override;
|
||||
|
||||
/**
|
||||
* Sets whether the video is playing (versus paused)
|
||||
*/
|
||||
void setPlaying(bool playingFlag) override;
|
||||
|
||||
/**
|
||||
* Creates a duplicate of the transparency surface
|
||||
*/
|
||||
Graphics::ManagedSurface *duplicateTransparency() const override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_MOVIE_H */
|
||||
99
engines/titanic/support/movie_clip.cpp
Normal file
99
engines/titanic/support/movie_clip.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
/* 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 "titanic/support/movie_clip.h"
|
||||
#include "titanic/core/game_object.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
CMovieClip::CMovieClip(): ListItem(), _startFrame(0), _endFrame(0) {
|
||||
}
|
||||
|
||||
CMovieClip::CMovieClip(const CString &name, int startFrame, int endFrame):
|
||||
ListItem(), _name(name), _startFrame(startFrame), _endFrame(endFrame) {
|
||||
}
|
||||
|
||||
void CMovieClip::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(2, indent);
|
||||
file->writeQuotedLine("Clip", indent);
|
||||
file->writeQuotedLine(_name, indent);
|
||||
file->writeNumberLine(_startFrame, indent);
|
||||
file->writeNumberLine(_endFrame, indent);
|
||||
|
||||
ListItem::save(file, indent);
|
||||
}
|
||||
|
||||
void CMovieClip::load(SimpleFile *file) {
|
||||
int val = file->readNumber();
|
||||
|
||||
switch (val) {
|
||||
case 1:
|
||||
// This should never be used
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
file->readString();
|
||||
_name = file->readString();
|
||||
_startFrame = file->readNumber();
|
||||
_endFrame = file->readNumber();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ListItem::load(file);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
CMovieClip *CMovieClipList::findByName(const Common::String &name) const {
|
||||
for (const_iterator i = begin(); i != end(); ++i) {
|
||||
CMovieClip *clip = *i;
|
||||
if (clip->_name == name)
|
||||
return clip;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool CMovieClipList::existsByStart(const CString &name, int startFrame) const {
|
||||
for (const_iterator i = begin(); i != end(); ++i) {
|
||||
CMovieClip *clip = *i;
|
||||
if (clip->_startFrame == startFrame && clip->_name == name)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CMovieClipList::existsByEnd(const CString &name, int endFrame) const {
|
||||
for (const_iterator i = begin(); i != end(); ++i) {
|
||||
CMovieClip *clip = *i;
|
||||
if (clip->_endFrame == endFrame && clip->_name == name)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
91
engines/titanic/support/movie_clip.h
Normal file
91
engines/titanic/support/movie_clip.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/* 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 TITANIC_MOVIE_CLIP_H
|
||||
#define TITANIC_MOVIE_CLIP_H
|
||||
|
||||
#include "titanic/core/list.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
enum ClipFlag {
|
||||
CLIPFLAG_HAS_END_FRAME = 1,
|
||||
CLIPFLAG_4 = 4,
|
||||
CLIPFLAG_HAS_START_FRAME = 8,
|
||||
CLIPFLAG_PLAY = 0x10
|
||||
};
|
||||
|
||||
class CGameObject;
|
||||
|
||||
/**
|
||||
* Movie clip
|
||||
*/
|
||||
class CMovieClip : public ListItem {
|
||||
private:
|
||||
Common::List<void *> _items;
|
||||
CString _string2;
|
||||
CString _string3;
|
||||
public:
|
||||
CString _name;
|
||||
int _startFrame;
|
||||
int _endFrame;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CMovieClip();
|
||||
CMovieClip(const CString &name, int startFrame, int endFrame);
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Movie clip list
|
||||
*/
|
||||
class CMovieClipList: public List<CMovieClip> {
|
||||
public:
|
||||
/**
|
||||
* Finds and returns a movie clip in the list by name
|
||||
*/
|
||||
CMovieClip *findByName(const Common::String &name) const;
|
||||
|
||||
/**
|
||||
* Returns true if a clip exists in the list with a given name
|
||||
* and starting frame number
|
||||
*/
|
||||
bool existsByStart(const CString &name, int startFrame = 0) const;
|
||||
|
||||
/**
|
||||
* Returns true if a clip exists in the list with a given name
|
||||
* and starting frame number
|
||||
*/
|
||||
bool existsByEnd(const CString &name, int endFrame = 0) const;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_MOVIE_CLIP_H */
|
||||
63
engines/titanic/support/movie_event.cpp
Normal file
63
engines/titanic/support/movie_event.cpp
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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/support/movie_event.h"
|
||||
#include "titanic/core/game_object.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
CMovieEvent::CMovieEvent() : ListItem(), _type(MET_PLAY), _startFrame(0),
|
||||
_endFrame(0), _initialFrame(0), _gameObject(nullptr) {
|
||||
}
|
||||
|
||||
CMovieEvent::CMovieEvent(const CMovieEvent *src) {
|
||||
_type = src->_type;
|
||||
_startFrame = src->_startFrame;
|
||||
_endFrame = src->_endFrame;
|
||||
_initialFrame = src->_initialFrame;
|
||||
_gameObject = src->_gameObject;
|
||||
}
|
||||
|
||||
void CMovieEvent::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(0, indent);
|
||||
file->writeNumberLine(_startFrame, indent + 1);
|
||||
file->writeNumberLine(_endFrame, indent + 1);
|
||||
error("FIXME: Original save/loaded object pointer");
|
||||
// file->writeNumberLine(_gameObject, indent + 1);
|
||||
file->writeNumberLine(_initialFrame, indent + 1);
|
||||
|
||||
ListItem::save(file, indent);
|
||||
}
|
||||
|
||||
void CMovieEvent::load(SimpleFile *file) {
|
||||
int val = file->readNumber();
|
||||
if (!val) {
|
||||
_startFrame = file->readNumber();
|
||||
_endFrame = file->readNumber();
|
||||
file->readNumber();
|
||||
error("FIXME: Original save/loaded object pointer");
|
||||
_initialFrame = file->readNumber();
|
||||
}
|
||||
|
||||
ListItem::load(file);
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
65
engines/titanic/support/movie_event.h
Normal file
65
engines/titanic/support/movie_event.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* 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 TITANIC_MOVIE_EVENT_H
|
||||
#define TITANIC_MOVIE_EVENT_H
|
||||
|
||||
#include "titanic/core/list.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
enum MovieEventType { MET_PLAY = 0, MET_MOVIE_END = 1, MET_FRAME = 2 };
|
||||
|
||||
class CGameObject;
|
||||
|
||||
class CMovieEvent : public ListItem {
|
||||
public:
|
||||
MovieEventType _type;
|
||||
int _startFrame;
|
||||
int _endFrame;
|
||||
CGameObject *_gameObject;
|
||||
int _initialFrame;
|
||||
public:
|
||||
CMovieEvent();
|
||||
CMovieEvent(const CMovieEvent *src);
|
||||
~CMovieEvent() override {}
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
class CMovieEventList : public List<CMovieEvent> {
|
||||
};
|
||||
|
||||
class CSharedMovieEventList : public Common::List<CMovieEvent> {
|
||||
};
|
||||
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_MOVIE_EVENT_H */
|
||||
34
engines/titanic/support/movie_manager.cpp
Normal file
34
engines/titanic/support/movie_manager.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/* 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 "titanic/support/movie_manager.h"
|
||||
#include "titanic/support/movie.h"
|
||||
#include "titanic/support/video_surface.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
CMovie *CMovieManager::createMovie(const CResourceKey &key, CVideoSurface *surface) {
|
||||
CMovie *movie = new OSMovie(key, surface);
|
||||
movie->setSoundManager(_soundManager);
|
||||
return movie;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
64
engines/titanic/support/movie_manager.h
Normal file
64
engines/titanic/support/movie_manager.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/* 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 TITANIC_MOVIE_MANAGER_H
|
||||
#define TITANIC_MOVIE_MANAGER_H
|
||||
|
||||
#include "titanic/core/list.h"
|
||||
#include "titanic/core/resource_key.h"
|
||||
#include "titanic/sound/sound_manager.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CMovie;
|
||||
class CVideoSurface;
|
||||
|
||||
class CMovieManagerBase {
|
||||
public:
|
||||
virtual ~CMovieManagerBase() {}
|
||||
|
||||
/**
|
||||
* Create a new movie and return it
|
||||
*/
|
||||
virtual CMovie *createMovie(const CResourceKey &key, CVideoSurface *surface) = 0;
|
||||
};
|
||||
|
||||
class CMovieManager : public CMovieManagerBase {
|
||||
private:
|
||||
CSoundManager *_soundManager;
|
||||
public:
|
||||
CMovieManager() : CMovieManagerBase(), _soundManager(nullptr) {}
|
||||
~CMovieManager() override {}
|
||||
|
||||
/**
|
||||
* Create a new movie and return it
|
||||
*/
|
||||
CMovie *createMovie(const CResourceKey &key, CVideoSurface *surface) override;
|
||||
|
||||
/**
|
||||
* Sets the sound manager that will be attached to all created movies
|
||||
*/
|
||||
void setSoundManager(CSoundManager *soundManager) { _soundManager = soundManager; }
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_MOVIE_MANAGER_H */
|
||||
115
engines/titanic/support/movie_range_info.cpp
Normal file
115
engines/titanic/support/movie_range_info.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
/* 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 "titanic/support/movie_range_info.h"
|
||||
#include "titanic/support/movie_clip.h"
|
||||
#include "titanic/core/game_object.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
CMovieRangeInfo::CMovieRangeInfo() : ListItem(), _startFrame(0), _endFrame(0) {
|
||||
}
|
||||
|
||||
CMovieRangeInfo::~CMovieRangeInfo() {
|
||||
_events.destroyContents();
|
||||
}
|
||||
|
||||
CMovieRangeInfo::CMovieRangeInfo(const CMovieRangeInfo *src) : ListItem() {
|
||||
_startFrame = src->_startFrame;
|
||||
_endFrame = src->_endFrame;
|
||||
_initialFrame = src->_initialFrame;
|
||||
_isReversed = src->_isReversed;
|
||||
_isRepeat = src->_isRepeat;
|
||||
|
||||
// Duplicate the events list
|
||||
for (CMovieEventList::const_iterator i = _events.begin();
|
||||
i != _events.end(); ++i) {
|
||||
_events.push_back(new CMovieEvent(*i));
|
||||
}
|
||||
}
|
||||
|
||||
void CMovieRangeInfo::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(0, indent);
|
||||
file->writeNumberLine(_startFrame, indent + 1);
|
||||
file->writeNumberLine(_endFrame, indent + 1);
|
||||
file->writeNumberLine(_initialFrame, indent + 1);
|
||||
file->writeNumberLine(_isRepeat, indent + 1);
|
||||
file->writeNumberLine(_isReversed, indent + 1);
|
||||
_events.save(file, indent + 1);
|
||||
|
||||
ListItem::save(file, indent);
|
||||
}
|
||||
|
||||
void CMovieRangeInfo::load(SimpleFile *file) {
|
||||
int val = file->readNumber();
|
||||
if (!val) {
|
||||
_startFrame = file->readNumber();
|
||||
_endFrame = file->readNumber();
|
||||
_initialFrame = file->readNumber();
|
||||
_isRepeat = file->readNumber();
|
||||
_isReversed = file->readNumber();
|
||||
_events.load(file);
|
||||
}
|
||||
|
||||
ListItem::load(file);
|
||||
}
|
||||
|
||||
void CMovieRangeInfo::getMovieEnd(CMovieEventList &list) {
|
||||
for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
CMovieEvent *movieEvent = *i;
|
||||
if (movieEvent->_type == MET_MOVIE_END)
|
||||
list.push_back(new CMovieEvent(movieEvent));
|
||||
}
|
||||
}
|
||||
|
||||
void CMovieRangeInfo::getMovieFrame(CMovieEventList &list, int frameNumber) {
|
||||
for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
CMovieEvent *movieEvent = *i;
|
||||
if (movieEvent->_type == MET_FRAME && movieEvent->_initialFrame == frameNumber)
|
||||
list.push_back(new CMovieEvent(movieEvent));
|
||||
}
|
||||
}
|
||||
|
||||
void CMovieRangeInfo::process(CGameObject *owner) {
|
||||
int flags = 0;
|
||||
if (_isRepeat)
|
||||
flags |= MOVIE_REPEAT;
|
||||
if (_isReversed)
|
||||
flags |= MOVIE_REVERSE;
|
||||
|
||||
for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
CMovieEvent *movieEvent = *i;
|
||||
if (movieEvent->_type == MET_MOVIE_END) {
|
||||
flags |= CLIPFLAG_PLAY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
owner->playMovie(_startFrame, _endFrame, _initialFrame, flags);
|
||||
|
||||
for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||
CMovieEvent *movieEvent = *i;
|
||||
if (movieEvent->_type == MET_PLAY)
|
||||
owner->movieEvent(movieEvent->_initialFrame);
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
81
engines/titanic/support/movie_range_info.h
Normal file
81
engines/titanic/support/movie_range_info.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 TITANIC_MOVIE_RANGE_INFO_H
|
||||
#define TITANIC_MOVIE_RANGE_INFO_H
|
||||
|
||||
#include "video/video_decoder.h"
|
||||
#include "titanic/core/list.h"
|
||||
#include "titanic/core/resource_key.h"
|
||||
#include "titanic/support/movie_event.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CGameObject;
|
||||
|
||||
class CMovieRangeInfo : public ListItem {
|
||||
public:
|
||||
int _startFrame;
|
||||
int _endFrame;
|
||||
int _initialFrame;
|
||||
bool _isReversed;
|
||||
bool _isRepeat;
|
||||
CMovieEventList _events;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CMovieRangeInfo();
|
||||
CMovieRangeInfo(const CMovieRangeInfo *src);
|
||||
~CMovieRangeInfo() override;
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
|
||||
/**
|
||||
* Adds an event to the events list
|
||||
*/
|
||||
void addEvent(CMovieEvent *movieEvent) { _events.push_back(movieEvent); }
|
||||
|
||||
/**
|
||||
* Get any movie end events for the range
|
||||
*/
|
||||
void getMovieEnd(CMovieEventList &list);
|
||||
|
||||
/**
|
||||
* Get any movie frame events for a specified frame number
|
||||
*/
|
||||
void getMovieFrame(CMovieEventList &list, int frameNumber);
|
||||
|
||||
void process(CGameObject *owner);
|
||||
};
|
||||
|
||||
class CMovieRangeInfoList : public List<CMovieRangeInfo> {
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_MOVIE_RANGE_INFO_H */
|
||||
62
engines/titanic/support/rect.cpp
Normal file
62
engines/titanic/support/rect.cpp
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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/support/rect.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
void Rect::combine(const Rect &r) {
|
||||
if (isEmpty()) {
|
||||
*this = r;
|
||||
} else if (!r.isEmpty()) {
|
||||
Common::Rect::extend(r);
|
||||
}
|
||||
}
|
||||
|
||||
void Rect::constrain(const Rect &r) {
|
||||
if (!isEmpty()) {
|
||||
if (r.isEmpty()) {
|
||||
clear();
|
||||
} else {
|
||||
Common::Rect::clip(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Point Rect::getPoint(Quadrant quadrant) {
|
||||
if (isEmpty())
|
||||
return Point(left, top);
|
||||
|
||||
switch (quadrant) {
|
||||
case Q_LEFT:
|
||||
return Point(MIN(left + 10, (int)right), (top + bottom) / 2);
|
||||
case Q_RIGHT:
|
||||
return Point(MAX(right - 10, (int)left), (top + bottom) / 2);
|
||||
case Q_TOP:
|
||||
return Point((left + right) / 2, MIN(top + 10, (int)bottom));
|
||||
case Q_BOTTOM:
|
||||
return Point((left + right) / 2, MAX(bottom - 10, (int)top));
|
||||
default:
|
||||
return Point((left + right) / 2, (top + bottom) / 2);
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
69
engines/titanic/support/rect.h
Normal file
69
engines/titanic/support/rect.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* 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 TITANIC_RECT_H
|
||||
#define TITANIC_RECT_H
|
||||
|
||||
#include "common/rect.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
enum Quadrant {
|
||||
Q_CENTER = 0, Q_LEFT, Q_RIGHT, Q_TOP, Q_BOTTOM
|
||||
};
|
||||
|
||||
typedef Common::Point Point;
|
||||
|
||||
class Rect : public Common::Rect {
|
||||
public:
|
||||
Rect() : Common::Rect() {}
|
||||
Rect(int16 w, int16 h) : Common::Rect(w, h) {}
|
||||
Rect(int16 x1, int16 y1, int16 x2, int16 y2) : Common::Rect(x1, y1, x2, y2) {}
|
||||
|
||||
/**
|
||||
* Returns the top/left corner of the rect as a point
|
||||
*/
|
||||
operator Point() { return Point(left, top); }
|
||||
|
||||
/**
|
||||
* Clear the rect
|
||||
*/
|
||||
void clear() { left = top = right = bottom = 0; }
|
||||
|
||||
/**
|
||||
* Combine another rect into this one
|
||||
*/
|
||||
void combine(const Rect &r);
|
||||
|
||||
/**
|
||||
* Constrains/clips to the intersection area of the given rect
|
||||
*/
|
||||
void constrain(const Rect &r);
|
||||
|
||||
/**
|
||||
* Returns a center point for a given edge or center of the rect
|
||||
*/
|
||||
Point getPoint(Quadrant quadrant);
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_RECT_H */
|
||||
356
engines/titanic/support/screen_manager.cpp
Normal file
356
engines/titanic/support/screen_manager.cpp
Normal file
@@ -0,0 +1,356 @@
|
||||
/* 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 "titanic/support/screen_manager.h"
|
||||
#include "titanic/support/video_surface.h"
|
||||
#include "titanic/titanic.h"
|
||||
#include "graphics/screen.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
CScreenManager *CScreenManager::_screenManagerPtr;
|
||||
CScreenManager *CScreenManager::_currentScreenManagerPtr;
|
||||
|
||||
CScreenManager::CScreenManager(TitanicEngine *vm): _vm(vm) {
|
||||
_screenManagerPtr = nullptr;
|
||||
_currentScreenManagerPtr = nullptr;
|
||||
|
||||
_frontRenderSurface = nullptr;
|
||||
_mouseCursor = nullptr;
|
||||
_textCursor = nullptr;
|
||||
_inputHandler = nullptr;
|
||||
_fontNumber = 0;
|
||||
|
||||
_screenManagerPtr = this;
|
||||
}
|
||||
|
||||
CScreenManager::~CScreenManager() {
|
||||
_screenManagerPtr = nullptr;
|
||||
}
|
||||
|
||||
void CScreenManager::setWindowHandle(int v) {
|
||||
// Not needed
|
||||
}
|
||||
|
||||
bool CScreenManager::resetWindowHandle(int v) {
|
||||
hideCursor();
|
||||
return true;
|
||||
}
|
||||
|
||||
CScreenManager *CScreenManager::setCurrent() {
|
||||
if (!_currentScreenManagerPtr)
|
||||
_currentScreenManagerPtr = _screenManagerPtr;
|
||||
|
||||
return _currentScreenManagerPtr;
|
||||
}
|
||||
|
||||
void CScreenManager::setSurfaceBounds(SurfaceNum surfaceNum, const Rect &r) {
|
||||
if (surfaceNum >= 0 && surfaceNum < (int)_backSurfaces.size())
|
||||
_backSurfaces[surfaceNum]._bounds = r;
|
||||
else if (surfaceNum == SURFACE_PRIMARY)
|
||||
_frontSurfaceBounds = r;
|
||||
}
|
||||
|
||||
int CScreenManager::setFontNumber(int fontNumber) {
|
||||
int oldFontNumber = _fontNumber;
|
||||
_fontNumber = fontNumber;
|
||||
return oldFontNumber;
|
||||
}
|
||||
|
||||
void CScreenManager::preLoad() {
|
||||
if (_textCursor)
|
||||
_textCursor->hide();
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
OSScreenManager::OSScreenManager(TitanicEngine *vm): CScreenManager(vm),
|
||||
_directDrawManager(vm, false) {
|
||||
_field48 = 0;
|
||||
_field4C = 0;
|
||||
_field50 = 0;
|
||||
_field54 = 0;
|
||||
}
|
||||
|
||||
OSScreenManager::~OSScreenManager() {
|
||||
destroyFrontAndBackBuffers();
|
||||
delete _mouseCursor;
|
||||
delete _textCursor;
|
||||
}
|
||||
|
||||
void OSScreenManager::setMode(int width, int height, int bpp, uint numBackSurfaces, bool flag2) {
|
||||
assert(bpp == 16);
|
||||
destroyFrontAndBackBuffers();
|
||||
_directDrawManager.initVideo(width, height, bpp, numBackSurfaces);
|
||||
|
||||
_vm->_screen->create(width, height, g_system->getScreenFormat());
|
||||
_frontRenderSurface = new OSVideoSurface(this, nullptr);
|
||||
_frontRenderSurface->setSurface(this, _directDrawManager._mainSurface);
|
||||
|
||||
_backSurfaces.resize(numBackSurfaces);
|
||||
for (uint idx = 0; idx < numBackSurfaces; ++idx) {
|
||||
_backSurfaces[idx]._surface = new OSVideoSurface(this, nullptr);
|
||||
_backSurfaces[idx]._surface->setSurface(this, _directDrawManager._backSurfaces[idx]);
|
||||
}
|
||||
|
||||
// Load fonts
|
||||
_fonts[0].load(149);
|
||||
_fonts[1].load(151);
|
||||
_fonts[2].load(152);
|
||||
_fonts[3].load(153);
|
||||
|
||||
// Load the cursors
|
||||
loadCursors();
|
||||
}
|
||||
|
||||
void OSScreenManager::drawCursors() {
|
||||
// The original did both text and mouse cursor drawing here.
|
||||
// For ScummVM, we only need to worry about the text cursor
|
||||
_textCursor->draw();
|
||||
}
|
||||
|
||||
DirectDrawSurface *OSScreenManager::getDDSurface(SurfaceNum surfaceNum) {
|
||||
if (surfaceNum == SURFACE_PRIMARY)
|
||||
return _directDrawManager._mainSurface;
|
||||
else if (surfaceNum < (int)_backSurfaces.size())
|
||||
return _directDrawManager._backSurfaces[surfaceNum];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CVideoSurface *OSScreenManager::lockSurface(SurfaceNum surfaceNum) {
|
||||
CVideoSurface *surface = getSurface(surfaceNum);
|
||||
surface->lock();
|
||||
return surface;
|
||||
}
|
||||
|
||||
void OSScreenManager::unlockSurface(CVideoSurface *surface) {
|
||||
surface->unlock();
|
||||
}
|
||||
|
||||
CVideoSurface *OSScreenManager::getSurface(SurfaceNum surfaceNum) const {
|
||||
if (surfaceNum == SURFACE_PRIMARY)
|
||||
return _frontRenderSurface;
|
||||
else if (surfaceNum >= 0 && surfaceNum < (int)_backSurfaces.size())
|
||||
return _backSurfaces[surfaceNum]._surface;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void OSScreenManager::fillRect(SurfaceNum surfaceNum, Rect *rect, byte r, byte g, byte b) {
|
||||
DirectDrawSurface *surface = getDDSurface(surfaceNum);
|
||||
if (!surface)
|
||||
return;
|
||||
|
||||
// If bounds are provided, clip and use them. Otherwise, use entire surface area
|
||||
Rect surfaceRect(0, 0, surface->getWidth(), surface->getHeight());
|
||||
Rect tempRect;
|
||||
|
||||
if (rect) {
|
||||
tempRect = *rect;
|
||||
tempRect.clip(surfaceRect);
|
||||
} else {
|
||||
tempRect = surfaceRect;
|
||||
}
|
||||
|
||||
// Constrain the fill area to the set modification area of the surface
|
||||
Rect surfaceBounds = (surfaceNum == SURFACE_PRIMARY) ? _frontSurfaceBounds :
|
||||
_backSurfaces[surfaceNum]._bounds;
|
||||
if (!surfaceBounds.isEmpty())
|
||||
tempRect.constrain(surfaceBounds);
|
||||
|
||||
// If there is any area defined, clear it
|
||||
if (tempRect.isValidRect())
|
||||
surface->fillRect(&tempRect, r, g, b);
|
||||
}
|
||||
|
||||
void OSScreenManager::blitFrom(SurfaceNum surfaceNum, CVideoSurface *src,
|
||||
const Point *destPos, const Rect *srcRect) {
|
||||
// Get the dest surface
|
||||
CVideoSurface *destSurface = _frontRenderSurface;
|
||||
if (surfaceNum < -1)
|
||||
return;
|
||||
if (surfaceNum >= 0 && surfaceNum < (int)_backSurfaces.size())
|
||||
destSurface = _backSurfaces[surfaceNum]._surface;
|
||||
if (!destSurface->hasSurface())
|
||||
return;
|
||||
|
||||
Point destPoint = destPos ? *destPos : Point(0, 0);
|
||||
Rect srcBounds = srcRect ? *srcRect : Rect(0, 0, src->getWidth(), src->getHeight());
|
||||
Rect *bounds = &srcBounds;
|
||||
Rect rect2;
|
||||
|
||||
Rect surfaceBounds = (surfaceNum == SURFACE_PRIMARY) ? _frontSurfaceBounds :
|
||||
_backSurfaces[surfaceNum]._bounds;
|
||||
|
||||
if (!surfaceBounds.isEmpty()) {
|
||||
// Perform clipping to the bounds of the back surface
|
||||
rect2 = srcBounds;
|
||||
rect2.translate(-srcBounds.left, -srcBounds.top);
|
||||
rect2.translate(destPoint.x, destPoint.y);
|
||||
rect2.constrain(surfaceBounds);
|
||||
|
||||
rect2.translate(-destPoint.x, -destPoint.y);
|
||||
rect2.translate(srcBounds.left, srcBounds.top);
|
||||
|
||||
if (rect2.isEmpty())
|
||||
return;
|
||||
|
||||
destPoint.x += rect2.left - srcBounds.left;
|
||||
destPoint.y += rect2.top - srcBounds.top;
|
||||
bounds = &rect2;
|
||||
}
|
||||
|
||||
if (!bounds->isEmpty())
|
||||
destSurface->blitFrom(destPoint, src, bounds);
|
||||
}
|
||||
|
||||
void OSScreenManager::blitFrom(SurfaceNum surfaceNum, const Rect *rect, CVideoSurface *src, int v) {
|
||||
// Get the dest surface
|
||||
CVideoSurface *destSurface = _frontRenderSurface;
|
||||
if (surfaceNum < -1)
|
||||
return;
|
||||
if (surfaceNum >= 0 && surfaceNum < (int)_backSurfaces.size())
|
||||
destSurface = _backSurfaces[surfaceNum]._surface;
|
||||
if (!destSurface->hasSurface())
|
||||
return;
|
||||
|
||||
if (!rect->isEmpty())
|
||||
destSurface->blitFrom(Point(rect->left, rect->top), src, rect);
|
||||
}
|
||||
|
||||
int OSScreenManager::writeString(int surfaceNum, const Rect &destRect,
|
||||
int yOffset, const CString &str, CTextCursor *textCursor) {
|
||||
CVideoSurface *surface;
|
||||
Rect bounds;
|
||||
|
||||
if (surfaceNum >= 0 && surfaceNum < (int)_backSurfaces.size()) {
|
||||
surface = _backSurfaces[surfaceNum]._surface;
|
||||
bounds = _backSurfaces[surfaceNum]._bounds;
|
||||
} else if (surfaceNum == SURFACE_PRIMARY) {
|
||||
surface = _frontRenderSurface;
|
||||
bounds = _frontSurfaceBounds;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _fonts[_fontNumber].writeString(surface, destRect, bounds,
|
||||
yOffset, str, textCursor);
|
||||
}
|
||||
|
||||
void OSScreenManager::writeString(int surfaceNum, const Point &destPos,
|
||||
const Rect &clipRect, const CString &str, int lineWidth) {
|
||||
CVideoSurface *surface;
|
||||
Rect bounds;
|
||||
|
||||
if (surfaceNum >= 0 && surfaceNum < (int)_backSurfaces.size()) {
|
||||
surface = _backSurfaces[surfaceNum]._surface;
|
||||
bounds = _backSurfaces[surfaceNum]._bounds;
|
||||
} else if (surfaceNum == -1) {
|
||||
surface = _frontRenderSurface;
|
||||
bounds = Rect(0, 0, surface->getWidth(), surface->getHeight());
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
Rect destRect = clipRect;
|
||||
destRect.constrain(bounds);
|
||||
|
||||
_fonts[_fontNumber].writeString(surface, destPos, destRect, str, lineWidth);
|
||||
}
|
||||
|
||||
void OSScreenManager::setFontColor(byte r, byte g, byte b) {
|
||||
_fonts[_fontNumber].setColor(r, g, b);
|
||||
}
|
||||
|
||||
int OSScreenManager::getTextBounds(const CString &str, int maxWidth, Point *sizeOut) const {
|
||||
return _fonts[_fontNumber].getTextBounds(str, maxWidth, sizeOut);
|
||||
}
|
||||
|
||||
int OSScreenManager::getFontHeight() const {
|
||||
return _fonts[_fontNumber]._fontHeight;
|
||||
}
|
||||
|
||||
int OSScreenManager::stringWidth(const CString &str) {
|
||||
return _fonts[_fontNumber].stringWidth(str);
|
||||
}
|
||||
|
||||
void OSScreenManager::frameRect(SurfaceNum surfaceNum, const Rect &rect, byte r, byte g, byte b) {
|
||||
Rect top(rect.left, rect.top, rect.right, rect.top + 1);
|
||||
fillRect(surfaceNum, &top, r, g, b);
|
||||
Rect bottom(rect.left, rect.bottom - 1, rect.right, rect.bottom);
|
||||
fillRect(surfaceNum, &bottom, r, g, b);
|
||||
Rect left(rect.left, rect.top, rect.left + 1, rect.bottom);
|
||||
fillRect(surfaceNum, &left, r, g, b);
|
||||
Rect right(rect.right - 1, rect.top, rect.right, rect.bottom);
|
||||
}
|
||||
|
||||
void OSScreenManager::clearSurface(SurfaceNum surfaceNum, Rect *bounds) {
|
||||
if (surfaceNum == SURFACE_PRIMARY)
|
||||
_directDrawManager._mainSurface->fill(bounds, 0);
|
||||
else if (surfaceNum >= 0 && surfaceNum < (int)_backSurfaces.size())
|
||||
_directDrawManager._backSurfaces[surfaceNum]->fill(bounds, 0);
|
||||
}
|
||||
|
||||
void OSScreenManager::resizeSurface(CVideoSurface *surface, int width, int height, int bpp) {
|
||||
DirectDrawSurface *ddSurface = _directDrawManager.createSurface(width, height, bpp, 0);
|
||||
surface->setSurface(this, ddSurface);
|
||||
}
|
||||
|
||||
CVideoSurface *OSScreenManager::createSurface(int w, int h, int bpp) {
|
||||
DirectDrawSurface *ddSurface = _directDrawManager.createSurface(w, h, bpp, 0);
|
||||
return new OSVideoSurface(this, ddSurface);
|
||||
}
|
||||
|
||||
CVideoSurface *OSScreenManager::createSurface(const CResourceKey &key) {
|
||||
return new OSVideoSurface(this, key);
|
||||
}
|
||||
|
||||
void OSScreenManager::showCursor() {
|
||||
CScreenManager::_screenManagerPtr->_mouseCursor->unsuppressCursor();
|
||||
}
|
||||
|
||||
void OSScreenManager::hideCursor() {
|
||||
CScreenManager::_screenManagerPtr->_mouseCursor->suppressCursor();
|
||||
}
|
||||
|
||||
void OSScreenManager::destroyFrontAndBackBuffers() {
|
||||
delete _frontRenderSurface;
|
||||
_frontRenderSurface = nullptr;
|
||||
|
||||
for (uint idx = 0; idx < _backSurfaces.size(); ++idx)
|
||||
delete _backSurfaces[idx]._surface;
|
||||
_backSurfaces.clear();
|
||||
}
|
||||
|
||||
void OSScreenManager::loadCursors() {
|
||||
if (_mouseCursor) {
|
||||
hideCursor();
|
||||
delete _mouseCursor;
|
||||
}
|
||||
_mouseCursor = new CMouseCursor(this);
|
||||
|
||||
if (!_textCursor) {
|
||||
_textCursor = new CTextCursor(this);
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
400
engines/titanic/support/screen_manager.h
Normal file
400
engines/titanic/support/screen_manager.h
Normal file
@@ -0,0 +1,400 @@
|
||||
/* 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 TITANIC_SCREEN_MANAGER_H
|
||||
#define TITANIC_SCREEN_MANAGER_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/array.h"
|
||||
#include "titanic/support/direct_draw.h"
|
||||
#include "titanic/support/font.h"
|
||||
#include "titanic/input_handler.h"
|
||||
#include "titanic/support/mouse_cursor.h"
|
||||
#include "titanic/support/text_cursor.h"
|
||||
#include "titanic/support/video_surface.h"
|
||||
#include "titanic/core/resource_key.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
/**
|
||||
* The original used page flipping with one primary and one back buffer.
|
||||
* Since we don't need that in ScummVM, the back buffer number below is
|
||||
* remapped to the primary surface
|
||||
*/
|
||||
enum SurfaceNum {
|
||||
SURFACE_PRIMARY = -1, // Surface 0
|
||||
SURFACE_BACKBUFFER = -1 // Surface -1
|
||||
};
|
||||
|
||||
class TitanicEngine;
|
||||
|
||||
class CScreenManager {
|
||||
struct VideoSurfaceEntry {
|
||||
CVideoSurface *_surface;
|
||||
Rect _bounds;
|
||||
};
|
||||
protected:
|
||||
TitanicEngine *_vm;
|
||||
public:
|
||||
static CScreenManager *_screenManagerPtr;
|
||||
static CScreenManager *_currentScreenManagerPtr;
|
||||
|
||||
/**
|
||||
* Set the current screen manager
|
||||
*/
|
||||
static CScreenManager *setCurrent();
|
||||
public:
|
||||
Common::Array<VideoSurfaceEntry> _backSurfaces;
|
||||
Rect _frontSurfaceBounds;
|
||||
CVideoSurface *_frontRenderSurface;
|
||||
CMouseCursor *_mouseCursor;
|
||||
CTextCursor *_textCursor;
|
||||
CInputHandler *_inputHandler;
|
||||
int _fontNumber;
|
||||
public:
|
||||
CScreenManager(TitanicEngine *vm);
|
||||
virtual ~CScreenManager();
|
||||
|
||||
void fn1() {}
|
||||
void fn2() {}
|
||||
|
||||
virtual void setWindowHandle(int v);
|
||||
virtual bool resetWindowHandle(int v);
|
||||
|
||||
/**
|
||||
* Sets the video mode
|
||||
*/
|
||||
virtual void setMode(int width, int height, int bpp, uint numBackSurfaces, bool flag2) = 0;
|
||||
|
||||
/**
|
||||
* Handles drawing the cursors
|
||||
*/
|
||||
virtual void drawCursors() = 0;
|
||||
|
||||
/**
|
||||
* Locks a specified surface number for access and returns a pointer to it
|
||||
*/
|
||||
virtual CVideoSurface *lockSurface(SurfaceNum surfaceNum) = 0;
|
||||
|
||||
/**
|
||||
* Unlocks a previously locked surface
|
||||
*/
|
||||
virtual void unlockSurface(CVideoSurface *surface) = 0;
|
||||
|
||||
/**
|
||||
* Gets a specified surface number
|
||||
*/
|
||||
virtual CVideoSurface *getSurface(SurfaceNum surfaceNum) const = 0;
|
||||
|
||||
/**
|
||||
* Return the front render surface
|
||||
*/
|
||||
virtual CVideoSurface *getFrontRenderSurface() const = 0;
|
||||
|
||||
/**
|
||||
* Fill an area with a specific color
|
||||
*/
|
||||
virtual void fillRect(SurfaceNum surfaceNum, Rect *rect, byte r, byte g, byte b) = 0;
|
||||
|
||||
/**
|
||||
* Blits a surface onto one of the screen surfaces
|
||||
*/
|
||||
virtual void blitFrom(SurfaceNum surfaceNum, CVideoSurface *src, const Point *destPos = nullptr,
|
||||
const Rect *srcRect = nullptr) = 0;
|
||||
|
||||
/**
|
||||
* Blits a surface onto one of the screen surfaces
|
||||
*/
|
||||
virtual void blitFrom(SurfaceNum surfaceNum, const Rect *rect, CVideoSurface *src, int v = 0) = 0;
|
||||
|
||||
/**
|
||||
* Write a string
|
||||
* @param surfaceNum Destination surface
|
||||
* @param destRect Bounds within dest surface
|
||||
* @param yOffset Y offset for drawing, to allow for parts of
|
||||
* the text to be scrolled off-screen
|
||||
* @param str Line or lines to write
|
||||
* @param textCursor Optional text cursor pointer
|
||||
*/
|
||||
virtual int writeString(int surfaceNum, const Rect &destRect,
|
||||
int yOffset, const CString &str, CTextCursor *textCursor) = 0;
|
||||
|
||||
/**
|
||||
* Write a string
|
||||
* @param surfaceNum Destination surface
|
||||
* @param destPos Position to start writing text at
|
||||
* @param clipRect Clipping area to constrain text to
|
||||
* @param str Line or lines to write
|
||||
* @param maxWidth Maximum allowed line width
|
||||
*/
|
||||
virtual void writeString(int surfaceNum, const Point &destPos,
|
||||
const Rect &clipRect, const CString &str, int maxWidth) = 0;
|
||||
|
||||
/**
|
||||
* Set the font color
|
||||
*/
|
||||
virtual void setFontColor(byte r, byte g, byte b) = 0;
|
||||
|
||||
/**
|
||||
* Get the text area a string will fit into
|
||||
* @param str String
|
||||
* @param maxWidth Maximum width in pixels
|
||||
* @param sizeOut Optional pointer to output size
|
||||
* @returns Required height
|
||||
*/
|
||||
virtual int getTextBounds(const CString &str, int maxWidth, Point *sizeOut = nullptr) const = 0;
|
||||
|
||||
/**
|
||||
* Get the current font height
|
||||
*/
|
||||
virtual int getFontHeight() const = 0;
|
||||
|
||||
/**
|
||||
* Returns the width of a given string in pixels
|
||||
*/
|
||||
virtual int stringWidth(const CString &str) = 0;
|
||||
|
||||
/**
|
||||
* Draws a frame enclosing the specified area
|
||||
*/
|
||||
virtual void frameRect(SurfaceNum surfaceNum, const Rect &rect, byte r, byte g, byte b) = 0;
|
||||
|
||||
/**
|
||||
* Clear a portion of a specified surface
|
||||
*/
|
||||
virtual void clearSurface(SurfaceNum surfaceNum, Rect *_bounds) = 0;
|
||||
|
||||
/**
|
||||
* Resize the passed surface
|
||||
*/
|
||||
virtual void resizeSurface(CVideoSurface *surface, int width, int height, int bpp = 16) = 0;
|
||||
|
||||
/**
|
||||
* Creates a surface of a given size
|
||||
*/
|
||||
virtual CVideoSurface *createSurface(int w, int h, int bpp = 16) = 0;
|
||||
|
||||
/**
|
||||
* Creates a surface from a specified resource
|
||||
*/
|
||||
virtual CVideoSurface *createSurface(const CResourceKey &key) = 0;
|
||||
|
||||
/**
|
||||
* Get the top-left corner of the screen in global screen co-ordinates
|
||||
* For ScummVM, this is always (0, 0), even in Windowed mode
|
||||
*/
|
||||
virtual Point getScreenTopLeft() { return Point(0, 0); }
|
||||
|
||||
/**
|
||||
* Waits for a vertical screen sync
|
||||
* For ScummVM, this can be safely ignored
|
||||
*/
|
||||
virtual void waitForVSync() {}
|
||||
|
||||
/**
|
||||
* Show the mouse cursor
|
||||
*/
|
||||
virtual void showCursor() = 0;
|
||||
|
||||
/**
|
||||
* Hide the mouse cursor
|
||||
*/
|
||||
virtual void hideCursor() = 0;
|
||||
|
||||
/**
|
||||
* Set drawing bounds for a specified surface
|
||||
*/
|
||||
void setSurfaceBounds(SurfaceNum surfaceNum, const Rect &r);
|
||||
|
||||
/**
|
||||
* Set the current font number
|
||||
*/
|
||||
int setFontNumber(int fontNumber);
|
||||
|
||||
/**
|
||||
* Called when a game is about to be loaded
|
||||
*/
|
||||
void preLoad();
|
||||
};
|
||||
|
||||
class OSScreenManager: CScreenManager {
|
||||
private:
|
||||
DirectDrawManager _directDrawManager;
|
||||
|
||||
/**
|
||||
* Frees any surface buffers
|
||||
*/
|
||||
void destroyFrontAndBackBuffers();
|
||||
|
||||
/**
|
||||
* Load game cursors
|
||||
*/
|
||||
void loadCursors();
|
||||
|
||||
/**
|
||||
* Gets an underlying surface
|
||||
*/
|
||||
DirectDrawSurface *getDDSurface(SurfaceNum surfaceNum);
|
||||
public:
|
||||
int _field48;
|
||||
int _field4C;
|
||||
int _field50;
|
||||
int _field54;
|
||||
STFont _fonts[4];
|
||||
public:
|
||||
OSScreenManager(TitanicEngine *vm);
|
||||
~OSScreenManager() override;
|
||||
|
||||
/**
|
||||
* Sets the video mode
|
||||
*/
|
||||
void setMode(int width, int height, int bpp, uint numBackSurfaces, bool flag2) override;
|
||||
|
||||
/**
|
||||
* Handles drawing the cursors
|
||||
*/
|
||||
void drawCursors() override;
|
||||
|
||||
/**
|
||||
* Locks a specified surface number for access and returns a pointer to it
|
||||
*/
|
||||
CVideoSurface *lockSurface(SurfaceNum surfaceNum) override;
|
||||
|
||||
/**
|
||||
* Unlocks a previously locked surface
|
||||
*/
|
||||
void unlockSurface(CVideoSurface *surface) override;
|
||||
|
||||
/**
|
||||
* Gets a specified surface number
|
||||
*/
|
||||
CVideoSurface *getSurface(SurfaceNum surfaceNum) const override;
|
||||
|
||||
/**
|
||||
* Return the front render surface
|
||||
*/
|
||||
CVideoSurface *getFrontRenderSurface() const override {
|
||||
return _frontRenderSurface;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fill an area with a specific color
|
||||
*/
|
||||
void fillRect(SurfaceNum surfaceNum, Rect *rect, byte r, byte g, byte b) override;
|
||||
|
||||
/**
|
||||
* Blits a surface onto one of the screen surfaces
|
||||
*/
|
||||
void blitFrom(SurfaceNum surfaceNum, CVideoSurface *src, const Point *destPos,
|
||||
const Rect *srcRect = nullptr) override;
|
||||
|
||||
/**
|
||||
* Blits a surface onto one of the screen surfaces
|
||||
*/
|
||||
void blitFrom(SurfaceNum surfaceNum, const Rect *rect, CVideoSurface *src, int v = 0) override;
|
||||
|
||||
/**
|
||||
* Write a string
|
||||
* @param surfaceNum Destination surface
|
||||
* @param destRect Bounds within dest surface
|
||||
* @param yOffset Y offset for drawing, to allow for parts of
|
||||
* the text to be scrolled off-screen
|
||||
* @param str Line or lines to write
|
||||
* @param textCursor Optional text cursor pointer
|
||||
*/
|
||||
int writeString(int surfaceNum, const Rect &destRect,
|
||||
int yOffset, const CString &str, CTextCursor *textCursor) override;
|
||||
|
||||
/**
|
||||
* Write a string
|
||||
* @param surfaceNum Destination surface
|
||||
* @param destPos Position to start writing text at
|
||||
* @param clipRect Clipping area to constrain text to
|
||||
* @param str Line or lines to write
|
||||
* @param lineWidth Width in pixels of the string, if known.
|
||||
*/
|
||||
void writeString(int surfaceNum, const Point &destPos,
|
||||
const Rect &clipRect, const CString &str, int lineWidth = 0) override;
|
||||
|
||||
/**
|
||||
* Set the font color
|
||||
*/
|
||||
void setFontColor(byte r, byte g, byte b) override;
|
||||
|
||||
/**
|
||||
* Get the text area a string will fit into
|
||||
* @param str String
|
||||
* @param maxWidth Maximum width in pixels
|
||||
* @param sizeOut Optional pointer to output size
|
||||
* @returns Required height
|
||||
*/
|
||||
int getTextBounds(const CString &str, int maxWidth, Point *sizeOut = nullptr) const override;
|
||||
|
||||
/**
|
||||
* Get the current font height
|
||||
*/
|
||||
int getFontHeight() const override;
|
||||
|
||||
/**
|
||||
* Returns the width of a given string in pixels
|
||||
*/
|
||||
int stringWidth(const CString &str) override;
|
||||
|
||||
/**
|
||||
* Draws a frame enclosing the specified area
|
||||
*/
|
||||
void frameRect(SurfaceNum surfaceNum, const Rect &rect, byte r, byte g, byte b) override;
|
||||
|
||||
/**
|
||||
* Clear a portion of the screen surface
|
||||
*/
|
||||
void clearSurface(SurfaceNum surfaceNum, Rect *bounds) override;
|
||||
|
||||
/**
|
||||
* Resize the passed surface
|
||||
*/
|
||||
void resizeSurface(CVideoSurface *surface, int width, int height, int bpp = 16) override;
|
||||
|
||||
/**
|
||||
* Creates a surface of a given size
|
||||
*/
|
||||
CVideoSurface *createSurface(int w, int h, int bpp = 16) override;
|
||||
|
||||
/**
|
||||
* Creates a surface from a specified resource
|
||||
*/
|
||||
CVideoSurface *createSurface(const CResourceKey &key) override;
|
||||
|
||||
/**
|
||||
* Show the mouse cursor
|
||||
*/
|
||||
void showCursor() override;
|
||||
|
||||
/**
|
||||
* Hide the mouse cursor
|
||||
*/
|
||||
void hideCursor() override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_SCREEN_MANAGER_H */
|
||||
516
engines/titanic/support/simple_file.cpp
Normal file
516
engines/titanic/support/simple_file.cpp
Normal file
@@ -0,0 +1,516 @@
|
||||
/* 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/util.h"
|
||||
#include "titanic/support/simple_file.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
CString readStringFromStream(Common::SeekableReadStream *s) {
|
||||
CString result;
|
||||
char c;
|
||||
while ((c = s->readByte()) != '\0')
|
||||
result += c;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
bool File::open(const Common::Path &filename) {
|
||||
if (!Common::File::open(filename))
|
||||
error("Could not open file - %s", filename.toString(Common::Path::kNativeSeparator).c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
SimpleFile::SimpleFile(): _inStream(nullptr), _outStream(nullptr), _lineCount(1) {
|
||||
}
|
||||
|
||||
SimpleFile::~SimpleFile() {
|
||||
close();
|
||||
}
|
||||
|
||||
void SimpleFile::open(Common::SeekableReadStream *stream) {
|
||||
close();
|
||||
_inStream = stream;
|
||||
}
|
||||
|
||||
void SimpleFile::open(Common::OutSaveFile *stream) {
|
||||
close();
|
||||
_outStream = stream;
|
||||
}
|
||||
|
||||
void SimpleFile::close() {
|
||||
if (_outStream) {
|
||||
_outStream->finalize();
|
||||
delete _outStream;
|
||||
_outStream = nullptr;
|
||||
}
|
||||
|
||||
if (_inStream) {
|
||||
delete _inStream;
|
||||
_inStream = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleFile::safeRead(void *dst, size_t count) {
|
||||
if (unsafeRead(dst, count) != count)
|
||||
error("Could not read %d bytes", (int)count);
|
||||
}
|
||||
|
||||
size_t SimpleFile::unsafeRead(void *dst, size_t count) {
|
||||
assert(_inStream);
|
||||
return _inStream->read(dst, count);
|
||||
}
|
||||
|
||||
size_t SimpleFile::write(const void *src, size_t count) const {
|
||||
assert(_outStream);
|
||||
return _outStream->write(src, count);
|
||||
}
|
||||
|
||||
void SimpleFile::seek(int offset, int origin) {
|
||||
assert(_inStream);
|
||||
_inStream->seek(offset, origin);
|
||||
}
|
||||
|
||||
byte SimpleFile::readByte() {
|
||||
byte b;
|
||||
safeRead(&b, 1);
|
||||
return b;
|
||||
}
|
||||
|
||||
uint SimpleFile::readUint16LE() {
|
||||
uint val;
|
||||
safeRead(&val, 2);
|
||||
return READ_LE_UINT16(&val);
|
||||
}
|
||||
|
||||
uint SimpleFile::readUint32LE() {
|
||||
uint val;
|
||||
safeRead(&val, 4);
|
||||
return READ_LE_UINT32(&val);
|
||||
}
|
||||
|
||||
CString SimpleFile::readString() {
|
||||
char c;
|
||||
CString result;
|
||||
bool backslashFlag = false;
|
||||
|
||||
// First skip any spaces
|
||||
do {
|
||||
safeRead(&c, 1);
|
||||
} while (Common::isSpace(c));
|
||||
|
||||
// Ensure we've found a starting quote for the string
|
||||
if (c != '"')
|
||||
error("Could not find starting quote");
|
||||
|
||||
bool endFlag = false;
|
||||
while (!endFlag) {
|
||||
// Read the next character
|
||||
safeRead(&c, 1);
|
||||
|
||||
if (backslashFlag) {
|
||||
backslashFlag = false;
|
||||
switch (c) {
|
||||
case 'n':
|
||||
result += '\n';
|
||||
break;
|
||||
case 'r':
|
||||
result += '\r';
|
||||
break;
|
||||
case '\t':
|
||||
result += '\t';
|
||||
break;
|
||||
default:
|
||||
result += c;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (c) {
|
||||
case '"':
|
||||
endFlag = true;
|
||||
break;
|
||||
case '\\':
|
||||
backslashFlag = true;
|
||||
break;
|
||||
default:
|
||||
result += c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the string
|
||||
return result;
|
||||
}
|
||||
|
||||
int SimpleFile::readNumber() {
|
||||
char c;
|
||||
int result = 0;
|
||||
bool minusFlag = false;
|
||||
|
||||
// First skip any spaces
|
||||
do {
|
||||
safeRead(&c, 1);
|
||||
} while (Common::isSpace(c));
|
||||
|
||||
// Check for prefix sign
|
||||
if (c == '+' || c == '-') {
|
||||
minusFlag = c == '-';
|
||||
safeRead(&c, 1);
|
||||
}
|
||||
|
||||
// Read in the number
|
||||
if (!Common::isDigit(c))
|
||||
error("Invalid number");
|
||||
|
||||
while (Common::isDigit(c)) {
|
||||
result = result * 10 + (c - '0');
|
||||
safeRead(&c, 1);
|
||||
}
|
||||
|
||||
// Finally, if it's a minus value, then negate it
|
||||
if (minusFlag)
|
||||
result = -result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
double SimpleFile::readFloat() {
|
||||
char c;
|
||||
Common::String result;
|
||||
|
||||
// First skip any spaces
|
||||
do {
|
||||
safeRead(&c, 1);
|
||||
} while (Common::isSpace(c));
|
||||
|
||||
// Check for prefix sign
|
||||
if (c == '+' || c == '-') {
|
||||
result += c;
|
||||
safeRead(&c, 1);
|
||||
}
|
||||
|
||||
// Read in the number
|
||||
if (!Common::isDigit(c))
|
||||
error("Invalid number");
|
||||
|
||||
while (Common::isDigit(c) || c == '.') {
|
||||
result += c;
|
||||
safeRead(&c, 1);
|
||||
}
|
||||
|
||||
// Convert to a float and return it
|
||||
float floatValue;
|
||||
sscanf(result.c_str(), "%f", &floatValue);
|
||||
|
||||
return floatValue;
|
||||
}
|
||||
|
||||
Point SimpleFile::readPoint() {
|
||||
Point pt;
|
||||
pt.x = readNumber();
|
||||
pt.y = readNumber();
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
||||
Rect SimpleFile::readRect() {
|
||||
Rect r;
|
||||
r.left = readNumber();
|
||||
r.top = readNumber();
|
||||
r.right = readNumber();
|
||||
r.bottom = readNumber();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
Rect SimpleFile::readBounds() {
|
||||
Rect r;
|
||||
r.left = readNumber();
|
||||
r.top = readNumber();
|
||||
r.setWidth(readNumber());
|
||||
r.setHeight(readNumber());
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void SimpleFile::readBuffer(char *buffer, size_t count) {
|
||||
CString tempString = readString();
|
||||
if (buffer) {
|
||||
strncpy(buffer, tempString.c_str(), count);
|
||||
buffer[count - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleFile::writeUint16LE(uint val) {
|
||||
byte lo = val & 0xff;
|
||||
byte hi = (val >> 8) & 0xff;
|
||||
write(&lo, 1);
|
||||
write(&hi, 1);
|
||||
}
|
||||
|
||||
void SimpleFile::writeUint32LE(uint val) {
|
||||
uint16 lo = val & 0xffff;
|
||||
uint16 hi = (val >> 16) & 0xff;
|
||||
writeUint16LE(lo);
|
||||
writeUint16LE(hi);
|
||||
}
|
||||
|
||||
void SimpleFile::writeLine(const CString &str) const {
|
||||
write(str.c_str(), str.size());
|
||||
write("\r\n", 2);
|
||||
}
|
||||
|
||||
void SimpleFile::writeString(const CString &str) const {
|
||||
if (str.empty())
|
||||
return;
|
||||
|
||||
const char *msgP = str.c_str();
|
||||
char c;
|
||||
|
||||
while ((c = *msgP++) != '\0') {
|
||||
switch (c) {
|
||||
case '\r':
|
||||
write("\\r", 2);
|
||||
break;
|
||||
case '\n':
|
||||
write("\\n", 2);
|
||||
break;
|
||||
case '\t':
|
||||
write("\\t", 2);
|
||||
break;
|
||||
case '\"':
|
||||
write("\\\"", 2);
|
||||
break;
|
||||
case '\\':
|
||||
write("\\\\", 2);
|
||||
break;
|
||||
case '{':
|
||||
write("\\{", 2);
|
||||
break;
|
||||
case '}':
|
||||
write("\\}", 2);
|
||||
break;
|
||||
default:
|
||||
write(&c, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleFile::writeQuotedString(const CString &str) const {
|
||||
write("\"", 1);
|
||||
writeString(str);
|
||||
write("\" ", 2);
|
||||
}
|
||||
|
||||
void SimpleFile::writeQuotedLine(const CString &str, int indent) const {
|
||||
writeIndent(indent);
|
||||
writeQuotedString(str);
|
||||
write("\n", 1);
|
||||
}
|
||||
|
||||
void SimpleFile::writeNumber(int val) const {
|
||||
CString str = CString::format("%d ", val);
|
||||
write(str.c_str(), str.size());
|
||||
}
|
||||
|
||||
void SimpleFile::writeNumberLine(int val, int indent) const {
|
||||
writeIndent(indent);
|
||||
writeNumber(val);
|
||||
write("\n", 1);
|
||||
}
|
||||
|
||||
void SimpleFile::writeFloat(double val) const {
|
||||
Common::String valStr = Common::String::format("%f ", val);
|
||||
write(valStr.c_str(), valStr.size());
|
||||
}
|
||||
|
||||
void SimpleFile::writeFloatLine(double val, int indent) const {
|
||||
writeIndent(indent);
|
||||
writeFloat(val);
|
||||
write("\n", 1);
|
||||
}
|
||||
|
||||
void SimpleFile::writePoint(const Point &pt, int indent) const {
|
||||
writeIndent(indent);
|
||||
writeNumber(pt.x);
|
||||
writeNumber(pt.y);
|
||||
write("\n", 1);
|
||||
}
|
||||
|
||||
void SimpleFile::writeRect(const Rect &r, int indent) const {
|
||||
writePoint(Point(r.left, r.top), indent);
|
||||
writePoint(Point(r.right, r.bottom), indent);
|
||||
}
|
||||
|
||||
void SimpleFile::writeBounds(const Rect &r, int indent) const {
|
||||
writePoint(Point(r.left, r.top), indent);
|
||||
writePoint(Point(r.width(), r.height()), indent);
|
||||
}
|
||||
|
||||
void SimpleFile::writeFormat(const char *format, ...) const {
|
||||
// Convert the format specifier and params to a string
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
CString line = CString::vformat(format, va);
|
||||
va_end(va);
|
||||
|
||||
// Write out the string
|
||||
write(format, strlen(format));
|
||||
}
|
||||
|
||||
void SimpleFile::writeIndent(uint indent) const {
|
||||
for (uint idx = 0; idx < indent; ++idx)
|
||||
write("\t", 1);
|
||||
}
|
||||
|
||||
bool SimpleFile::isClassStart() {
|
||||
char c;
|
||||
|
||||
do {
|
||||
safeRead(&c, 1);
|
||||
} while (Common::isSpace(c));
|
||||
|
||||
assert(c == '{' || c == '}');
|
||||
return c == '{';
|
||||
}
|
||||
|
||||
void SimpleFile::writeClassStart(const CString &classStr, int indent) {
|
||||
write("\n", 1);
|
||||
writeIndent(indent);
|
||||
write("{\n", 2);
|
||||
writeIndent(indent + 1);
|
||||
writeQuotedString(classStr);
|
||||
write("\n", 1);
|
||||
}
|
||||
|
||||
void SimpleFile::writeClassEnd(int indent) {
|
||||
writeIndent(indent);
|
||||
write("}\n", 2);
|
||||
}
|
||||
|
||||
bool SimpleFile::scanf(const char *format, ...) {
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
char c;
|
||||
|
||||
CString formatStr(format);
|
||||
while (!formatStr.empty()) {
|
||||
if (formatStr.hasPrefix(" ")) {
|
||||
formatStr.deleteChar(0);
|
||||
|
||||
safeRead(&c, 1);
|
||||
if (!Common::isSpace(c)) {
|
||||
va_end(va);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip over whitespaces
|
||||
skipSpaces();
|
||||
} else if (formatStr.hasPrefix("%d")) {
|
||||
// Read in a number
|
||||
formatStr = CString(formatStr.c_str() + 2);
|
||||
int *param = (int *)va_arg(va, int *);
|
||||
*param = readNumber();
|
||||
|
||||
if (!eos())
|
||||
_inStream->seek(-1, SEEK_CUR);
|
||||
} else if (formatStr.hasPrefix("%s")) {
|
||||
// Read in text until the next space
|
||||
formatStr = CString(formatStr.c_str() + 2);
|
||||
CString *str = (CString *)va_arg(va, CString *);
|
||||
str->clear();
|
||||
while (!eos() && !Common::isSpace(c = readByte()))
|
||||
*str += c;
|
||||
|
||||
if (!eos())
|
||||
_inStream->seek(-1, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
|
||||
skipSpaces();
|
||||
va_end(va);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SimpleFile::skipSpaces() {
|
||||
char c = ' ';
|
||||
while (!eos() && Common::isSpace(c))
|
||||
safeRead(&c, 1);
|
||||
|
||||
if (!eos())
|
||||
_inStream->seek(-1, SEEK_CUR);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
bool StdCWadFile::open(const Common::String &filename) {
|
||||
Common::File f;
|
||||
CString name = filename;
|
||||
|
||||
// Check for whether it is indeed a file/resource pair
|
||||
int idx = name.indexOf('#');
|
||||
|
||||
if (idx < 0) {
|
||||
// Nope, so open up file for standard reading
|
||||
assert(!name.empty());
|
||||
if (!f.open(Common::Path(name)))
|
||||
return false;
|
||||
|
||||
SimpleFile::open(f.readStream(f.size()));
|
||||
f.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Split up the name and resource, and get the resource index
|
||||
CString fname = name.left(idx) + ".st";
|
||||
int extPos = name.lastIndexOf('.');
|
||||
CString resStr = name.mid(idx + 1, extPos - idx - 1);
|
||||
int resIndex = resStr.readInt();
|
||||
|
||||
// Open up the index for access
|
||||
if (!f.open(Common::Path(fname)))
|
||||
return false;
|
||||
int indexSize = f.readUint32LE() / 4;
|
||||
assert(resIndex < indexSize);
|
||||
|
||||
// Get the specific resource's offset, and size by also
|
||||
// getting the offset of the following resource
|
||||
f.seek(resIndex * 4);
|
||||
uint resOffset = f.readUint32LE();
|
||||
uint nextOffset = (resIndex == (indexSize - 1)) ? f.size() :
|
||||
f.readUint32LE();
|
||||
|
||||
// Read in the resource
|
||||
f.seek(resOffset);
|
||||
Common::SeekableReadStream *stream = f.readStream(nextOffset - resOffset);
|
||||
SimpleFile::open(stream);
|
||||
|
||||
f.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
320
engines/titanic/support/simple_file.h
Normal file
320
engines/titanic/support/simple_file.h
Normal file
@@ -0,0 +1,320 @@
|
||||
/* 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 TITANIC_SIMPLE_FILE_H
|
||||
#define TITANIC_SIMPLE_FILE_H
|
||||
|
||||
#include "common/file.h"
|
||||
#include "titanic/support/rect.h"
|
||||
#include "common/savefile.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/compression/deflate.h"
|
||||
#include "titanic/support/string.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class Decompressor;
|
||||
class DecompressorData;
|
||||
|
||||
/**
|
||||
* Simple ScummVM File descendent that throws a wobbly if
|
||||
* the file it tries to open isn't present
|
||||
*/
|
||||
class File : public Common::File {
|
||||
public:
|
||||
bool open(const Common::Path &filename) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class implements basic reading and writing to files
|
||||
*/
|
||||
class SimpleFile {
|
||||
private:
|
||||
/**
|
||||
* Skip over any pending spaces
|
||||
*/
|
||||
void skipSpaces();
|
||||
protected:
|
||||
Common::SeekableReadStream *_inStream;
|
||||
Common::OutSaveFile *_outStream;
|
||||
int _lineCount;
|
||||
public:
|
||||
SimpleFile();
|
||||
virtual ~SimpleFile();
|
||||
|
||||
operator Common::SeekableReadStream &() { return *_inStream; }
|
||||
operator Common::WriteStream &() { return *_outStream; }
|
||||
|
||||
/**
|
||||
* Set up a stream for read access
|
||||
*/
|
||||
virtual void open(Common::SeekableReadStream *stream);
|
||||
|
||||
/**
|
||||
* Set up a stream for write access
|
||||
*/
|
||||
virtual void open(Common::OutSaveFile *stream);
|
||||
|
||||
/**
|
||||
* Close the file
|
||||
*/
|
||||
virtual void close();
|
||||
|
||||
/**
|
||||
* Read from the file with validation
|
||||
*/
|
||||
virtual void safeRead(void *dst, size_t count);
|
||||
|
||||
/**
|
||||
* Read from the file
|
||||
*/
|
||||
virtual size_t unsafeRead(void *dst, size_t count);
|
||||
|
||||
/**
|
||||
* Write out data
|
||||
*/
|
||||
virtual size_t write(const void *src, size_t count) const;
|
||||
|
||||
/**
|
||||
* Seek
|
||||
*/
|
||||
virtual void seek(int offset, int origin);
|
||||
/**
|
||||
* Read a byte
|
||||
*/
|
||||
byte readByte();
|
||||
|
||||
/**
|
||||
* Read a 16-bit LE number
|
||||
*/
|
||||
uint readUint16LE();
|
||||
|
||||
/**
|
||||
* Read a 32-bit LE number
|
||||
*/
|
||||
uint readUint32LE();
|
||||
|
||||
/**
|
||||
* Read a string from the file
|
||||
*/
|
||||
CString readString();
|
||||
|
||||
/**
|
||||
* Read a number from the file
|
||||
*/
|
||||
int readNumber();
|
||||
|
||||
/**
|
||||
* Read a floating point number from the file
|
||||
*/
|
||||
double readFloat();
|
||||
|
||||
/**
|
||||
* Read in a point
|
||||
*/
|
||||
Point readPoint();
|
||||
|
||||
/**
|
||||
* Read in a rect
|
||||
*/
|
||||
Rect readRect();
|
||||
|
||||
/**
|
||||
* Rect in a bounds
|
||||
*/
|
||||
Rect readBounds();
|
||||
|
||||
/**
|
||||
* Read a string and copy it into an optionally passed buffer
|
||||
*/
|
||||
void readBuffer(char *buffer = nullptr, size_t count = 0);
|
||||
|
||||
/**
|
||||
* Scan in values from the file
|
||||
*/
|
||||
bool scanf(const char *format, ...);
|
||||
|
||||
/**
|
||||
* Write out a byte
|
||||
*/
|
||||
void writeByte(byte b) { write(&b, 1); }
|
||||
|
||||
/**
|
||||
* Write out a raw 16-bit LE number
|
||||
*/
|
||||
void writeUint16LE(uint val);
|
||||
|
||||
/**
|
||||
* Write out a raw 32-bit LE number
|
||||
*/
|
||||
void writeUint32LE(uint val);
|
||||
|
||||
/**
|
||||
* Write a string line
|
||||
*/
|
||||
void writeLine(const CString &str) const;
|
||||
|
||||
/**
|
||||
* Write a string
|
||||
*/
|
||||
void writeString(const CString &str) const;
|
||||
|
||||
/**
|
||||
* Write a quoted string
|
||||
*/
|
||||
void writeQuotedString(const CString &str) const;
|
||||
|
||||
/**
|
||||
* Write a quoted string line
|
||||
*/
|
||||
void writeQuotedLine(const CString &str, int indent) const;
|
||||
|
||||
/**
|
||||
* Write a number to file
|
||||
*/
|
||||
void writeNumber(int val) const;
|
||||
|
||||
/**
|
||||
* Write a number line to file
|
||||
*/
|
||||
void writeNumberLine(int val, int indent) const;
|
||||
|
||||
/**
|
||||
* Write a floating point number
|
||||
*/
|
||||
void writeFloat(double val) const;
|
||||
|
||||
/**
|
||||
* Write a floating point number as a line
|
||||
*/
|
||||
void writeFloatLine(double val, int indent) const;
|
||||
|
||||
/**
|
||||
* Write out a point line
|
||||
*/
|
||||
void writePoint(const Point &pt, int indent)const;
|
||||
|
||||
/**
|
||||
* Write out a rect line
|
||||
*/
|
||||
void writeRect(const Rect &r, int indent) const;
|
||||
|
||||
/**
|
||||
* Write out a bounds line
|
||||
*/
|
||||
void writeBounds(const Rect &r, int indent) const;
|
||||
|
||||
/**
|
||||
* Write out a string using a format specifier, just like fprintf
|
||||
*/
|
||||
void writeFormat(const char *format, ...) const;
|
||||
|
||||
/**
|
||||
* Write out a number of tabs to form an indent in the output
|
||||
*/
|
||||
void writeIndent(uint indent) const;
|
||||
|
||||
/**
|
||||
* Validates that the following non-space character is either
|
||||
* an opening or closing squiggly bracket denoting a class
|
||||
* definition start or end. Returns true if it's a class start
|
||||
*/
|
||||
bool isClassStart();
|
||||
|
||||
/**
|
||||
* Write the starting header for a class definition
|
||||
*/
|
||||
void writeClassStart(const CString &classStr, int indent);
|
||||
|
||||
/**
|
||||
* Write out the ending footer for a class definition
|
||||
*/
|
||||
void writeClassEnd(int indent);
|
||||
|
||||
/**
|
||||
* Return true if the stream has finished being read
|
||||
*/
|
||||
bool eos() const {
|
||||
assert(_inStream);
|
||||
return _inStream->pos() >= _inStream->size();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Derived file that handles compressed files
|
||||
*/
|
||||
class CompressedFile : public SimpleFile {
|
||||
public:
|
||||
CompressedFile() : SimpleFile() {}
|
||||
~CompressedFile() override {}
|
||||
|
||||
/**
|
||||
* Set up a stream for read access
|
||||
*/
|
||||
void open(Common::SeekableReadStream *stream) override {
|
||||
SimpleFile::open(Common::wrapCompressedReadStream(stream));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up a stream for write access
|
||||
*/
|
||||
void open(Common::OutSaveFile *stream) override {
|
||||
SimpleFile::open(new Common::OutSaveFile(Common::wrapCompressedWriteStream(stream)));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Derived file that handles WAD archives containing multiple files
|
||||
*/
|
||||
class StdCWadFile : public SimpleFile {
|
||||
public:
|
||||
StdCWadFile() : SimpleFile() {}
|
||||
~StdCWadFile() override {}
|
||||
|
||||
/**
|
||||
* Open up the specified file
|
||||
*/
|
||||
virtual bool open(const Common::String &filename);
|
||||
|
||||
/**
|
||||
* Unsupported open method from parent class
|
||||
*/
|
||||
void open(Common::SeekableReadStream *stream) override {}
|
||||
|
||||
/**
|
||||
* Unsupported open method from parent class
|
||||
*/
|
||||
void open(Common::OutSaveFile *stream) override {}
|
||||
|
||||
/**
|
||||
* Return a reference to the read stream
|
||||
*/
|
||||
Common::SeekableReadStream *readStream() const { return _inStream; }
|
||||
};
|
||||
|
||||
/**
|
||||
* General purpose support method for reading an ASCIIZ string from a stream
|
||||
*/
|
||||
CString readStringFromStream(Common::SeekableReadStream *s);
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_SIMPLE_FILE_H */
|
||||
153
engines/titanic/support/string.cpp
Normal file
153
engines/titanic/support/string.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
/* 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/algorithm.h"
|
||||
#include "titanic/support/string.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
CString::CString(char c, uint32 len) : Common::String() {
|
||||
ensureCapacity(len, false);
|
||||
for (uint idx = 0; idx < len; ++idx)
|
||||
(*this) += c;
|
||||
}
|
||||
|
||||
CString::CString(int val) : Common::String() {
|
||||
*this = CString::format("%d", val);
|
||||
}
|
||||
|
||||
CString CString::left(uint count) const {
|
||||
return (count > size()) ? CString() : CString(c_str(), c_str() + count);
|
||||
}
|
||||
|
||||
CString CString::right(uint count) const {
|
||||
uint strSize = size();
|
||||
return (count > strSize) ? CString() :
|
||||
CString(c_str() + strSize - count, c_str() + strSize);
|
||||
}
|
||||
|
||||
CString CString::mid(uint start, uint count) const {
|
||||
if (start >= size())
|
||||
return CString();
|
||||
else
|
||||
return CString(c_str() + start, MIN(count, size() - start));
|
||||
}
|
||||
|
||||
CString CString::mid(uint start) const {
|
||||
uint strSize = size();
|
||||
assert(start <= strSize);
|
||||
return mid(start, strSize - start);
|
||||
}
|
||||
|
||||
CString CString::deleteRight(uint count) const {
|
||||
return (count >= size()) ? CString() : left(size() - count);
|
||||
}
|
||||
|
||||
int CString::indexOf(char c) const {
|
||||
const char *charP = strchr(c_str(), c);
|
||||
return charP ? charP - c_str() : -1;
|
||||
}
|
||||
|
||||
int CString::indexOf(const char *s) const {
|
||||
const char *strP = strstr(c_str(), s);
|
||||
return strP ? strP - c_str() : -1;
|
||||
}
|
||||
|
||||
int CString::lastIndexOf(char c) const {
|
||||
const char *charP = strrchr(c_str(), c);
|
||||
return charP ? charP - c_str() : -1;
|
||||
}
|
||||
|
||||
bool CString::containsIgnoreCase(const CString &str) const {
|
||||
CString lowerStr = *this;
|
||||
CString subStr = str;
|
||||
lowerStr.toLowercase();
|
||||
subStr.toLowercase();
|
||||
|
||||
return lowerStr.contains(subStr);
|
||||
}
|
||||
|
||||
FileType CString::fileTypeSuffix() const {
|
||||
CString ext = right(1);
|
||||
if (ext == "0" || ext == "4")
|
||||
return FILETYPE_IMAGE;
|
||||
else if (ext == "1")
|
||||
return FILETYPE_WAV;
|
||||
else if (ext == "2" || ext == "3")
|
||||
return FILETYPE_MOVIE;
|
||||
|
||||
ext = right(3);
|
||||
if (ext == "tga" || ext == "jpg")
|
||||
return FILETYPE_IMAGE;
|
||||
else if (ext == "wav")
|
||||
return FILETYPE_WAV;
|
||||
else if (ext == "avi" || ext == "mov")
|
||||
return FILETYPE_MOVIE;
|
||||
else if (ext == "dlg")
|
||||
return FILETYPE_DLG;
|
||||
else
|
||||
return FILETYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
ImageType CString::imageTypeSuffix() const {
|
||||
CString ext = right(1);
|
||||
if (ext == "0")
|
||||
return IMAGETYPE_TARGA;
|
||||
else if (ext == "4")
|
||||
return IMAGETYPE_JPEG;
|
||||
|
||||
ext = right(3);
|
||||
if (ext == "tga")
|
||||
return IMAGETYPE_TARGA;
|
||||
else if (ext == "jpg")
|
||||
return IMAGETYPE_JPEG;
|
||||
else
|
||||
return IMAGETYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
CString CString::format(const char *fmt, ...) {
|
||||
String output;
|
||||
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
output = String::vformat(fmt, va);
|
||||
va_end(va);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
bool CString::operator==(const CString &x) const {
|
||||
return compareToIgnoreCase(x) == 0;
|
||||
}
|
||||
|
||||
bool CString::operator==(const char *x) const {
|
||||
return compareToIgnoreCase(x) == 0;
|
||||
}
|
||||
|
||||
bool CString::operator!=(const CString &x) const {
|
||||
return compareToIgnoreCase(x) != 0;
|
||||
}
|
||||
|
||||
bool CString::operator!=(const char *x) const {
|
||||
return compareToIgnoreCase(x) != 0;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
129
engines/titanic/support/string.h
Normal file
129
engines/titanic/support/string.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/* 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 TITANIC_STRING_H
|
||||
#define TITANIC_STRING_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/array.h"
|
||||
#include "common/str.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
enum FileType {
|
||||
FILETYPE_UNKNOWN = 0, FILETYPE_IMAGE = 1, FILETYPE_MOVIE = 2,
|
||||
FILETYPE_WAV = 3, FILETYPE_DLG = 4
|
||||
};
|
||||
|
||||
enum ImageType {
|
||||
IMAGETYPE_UNKNOWN = 0, IMAGETYPE_TARGA = 1, IMAGETYPE_JPEG = 2
|
||||
};
|
||||
|
||||
class CString : public Common::String {
|
||||
public:
|
||||
CString() : Common::String() {}
|
||||
CString(const char *str) : Common::String(str) {}
|
||||
CString(const char *str, uint32 len) : Common::String(str, len) {}
|
||||
CString(const char *beginP, const char *endP) : Common::String(beginP, endP) {}
|
||||
CString(const String &str) : Common::String(str) {}
|
||||
CString(char c, uint32 len);
|
||||
explicit CString(char c) : Common::String(c) {}
|
||||
explicit CString(int val);
|
||||
|
||||
bool operator==(const CString &x) const;
|
||||
bool operator==(const char *x) const;
|
||||
bool operator!=(const CString &x) const;
|
||||
bool operator!=(const char *x) const;
|
||||
|
||||
/**
|
||||
* Returns the left n characters of the string
|
||||
*/
|
||||
CString left(uint count) const;
|
||||
|
||||
/**
|
||||
* Returns the right n characters of the string
|
||||
*/
|
||||
CString right(uint count) const;
|
||||
|
||||
/**
|
||||
* Returns a substring from within the string
|
||||
*/
|
||||
CString mid(uint start, uint count) const;
|
||||
|
||||
/**
|
||||
* Returns a substring from within the string
|
||||
*/
|
||||
CString mid(uint start) const;
|
||||
|
||||
/**
|
||||
* Returns a substring consisting of the entire string
|
||||
* except for a specified number of characters at the end
|
||||
*/
|
||||
CString deleteRight(uint count) const;
|
||||
|
||||
/**
|
||||
* Returns the index of the first occurrence of a given character
|
||||
*/
|
||||
int indexOf(char c) const;
|
||||
|
||||
/**
|
||||
* Returns the index of the first occurrence of a given string
|
||||
*/
|
||||
int indexOf(const char *s) const;
|
||||
|
||||
/**
|
||||
* Returns the index of the last occurrence of a given character
|
||||
*/
|
||||
int lastIndexOf(char c) const;
|
||||
|
||||
/**
|
||||
* Returns true if the string contains a specified substring, ignoring case
|
||||
*/
|
||||
bool containsIgnoreCase(const CString &str) const;
|
||||
|
||||
/**
|
||||
* Returns the type of a filename based on it's extension
|
||||
*/
|
||||
FileType fileTypeSuffix() const;
|
||||
|
||||
/**
|
||||
* Returns the type of an image filename based on it's extension
|
||||
*/
|
||||
ImageType imageTypeSuffix() const;
|
||||
|
||||
/**
|
||||
* Parses the string as an integer and returns the value
|
||||
*/
|
||||
int readInt() const {
|
||||
return atoi(c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a string
|
||||
*/
|
||||
static CString format(const char *fmt, ...);
|
||||
};
|
||||
|
||||
typedef Common::Array<CString> StringArray;
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_STRING_H */
|
||||
96
engines/titanic/support/string_parser.cpp
Normal file
96
engines/titanic/support/string_parser.cpp
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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/support/string_parser.h"
|
||||
#include "common/util.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
void CStringParser::skipSeparators(const CString &separatorChars) {
|
||||
for (; _index < size(); ++_index) {
|
||||
char c = (*this)[_index];
|
||||
if (separatorChars.indexOf(c) == -1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool CStringParser::parse(CString &resultStr, const CString &separatorChars, bool allowQuotes) {
|
||||
if (_index >= size())
|
||||
return false;
|
||||
|
||||
resultStr.clear();
|
||||
bool quoteFlag = false;
|
||||
while (_index < size()) {
|
||||
char c = (*this)[_index];
|
||||
if (!quoteFlag && separatorChars.indexOf(c) >= 0)
|
||||
break;
|
||||
|
||||
if (allowQuotes) {
|
||||
if (quoteFlag) {
|
||||
if (c == '"') {
|
||||
// End of quoted string
|
||||
++_index;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (c == '"') {
|
||||
// Start of quoted string
|
||||
++_index;
|
||||
quoteFlag = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resultStr += c;
|
||||
++_index;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint CStringParser::readInt() {
|
||||
// Get digits from the string
|
||||
CString numStr;
|
||||
while (Common::isDigit(currentChar()))
|
||||
numStr += getNextChar();
|
||||
|
||||
// Throw a wobbly if there wasn't a number
|
||||
if (numStr.empty())
|
||||
error("ReadInt(): No number to read");
|
||||
|
||||
return atoi(numStr.c_str());
|
||||
}
|
||||
|
||||
char CStringParser::currentChar() const {
|
||||
return (_index >= size()) ? '\0' : (*this)[_index];
|
||||
}
|
||||
|
||||
char CStringParser::getNextChar() {
|
||||
return (_index >= size()) ? '\0' : (*this)[_index++];
|
||||
}
|
||||
|
||||
void CStringParser::skipSpaces() {
|
||||
while (_index < size() && Common::isSpace(currentChar()))
|
||||
++_index;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
75
engines/titanic/support/string_parser.h
Normal file
75
engines/titanic/support/string_parser.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/* 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 TITANIC_STRING_PARSER_H
|
||||
#define TITANIC_STRING_PARSER_H
|
||||
|
||||
#include "titanic/support/string.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CStringParser : public CString {
|
||||
private:
|
||||
uint _index;
|
||||
private:
|
||||
/**
|
||||
* Gets the character at the current index
|
||||
*/
|
||||
char currentChar() const;
|
||||
|
||||
/**
|
||||
* Gets the next character, and increments the parsing index
|
||||
*/
|
||||
char getNextChar();
|
||||
|
||||
/**
|
||||
* Skips over any spaces
|
||||
*/
|
||||
void skipSpaces();
|
||||
public:
|
||||
CStringParser() : CString(), _index(0) {}
|
||||
CStringParser(const CString &str) : CString(str), _index(0) {}
|
||||
|
||||
/**
|
||||
* Skips over any specified separator characters in our string
|
||||
* at the current index
|
||||
*/
|
||||
void skipSeparators(const CString &separatorChars);
|
||||
|
||||
/**
|
||||
* Parses out a string from a source string at the current index
|
||||
* @param resultStr String to hold the resulting sring
|
||||
* @param separatorChras List of characters that separate string values
|
||||
* @param allowQuotes If true, handles double-quoted substrings
|
||||
* @returns True if a string entry was extracted
|
||||
*/
|
||||
bool parse(CString &resultStr, const CString &separatorChars, bool allowQuotes = false);
|
||||
|
||||
/**
|
||||
* Reads an integer from the string
|
||||
*/
|
||||
uint readInt();
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_STRING_PARSER_H */
|
||||
35
engines/titanic/support/strings.cpp
Normal file
35
engines/titanic/support/strings.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/* 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 "titanic/support/strings.h"
|
||||
#include "titanic/support/files_manager.h"
|
||||
#include "titanic/titanic.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
void Strings::load() {
|
||||
Common::SeekableReadStream *r = g_vm->_filesManager->getResource("TEXT/STRINGS");
|
||||
while (r->pos() < r->size())
|
||||
push_back(readStringFromStream(r));
|
||||
delete r;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
244
engines/titanic/support/strings.h
Normal file
244
engines/titanic/support/strings.h
Normal file
@@ -0,0 +1,244 @@
|
||||
/* 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 TITANIC_STRINGS_H
|
||||
#define TITANIC_STRINGS_H
|
||||
|
||||
#include "common/str-array.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
enum StringId {
|
||||
BLANK,
|
||||
STANDING_OUTSIDE_PELLERATOR,
|
||||
BOT_BLOCKING_PELLERATOR,
|
||||
FROZEN_PELLERATOR,
|
||||
SUCCUBUS_IS_IN_STANDBY,
|
||||
NOTHING_TO_DELIVER,
|
||||
NOTHING_IN_SUCCUBUS_TRAY,
|
||||
SUCCUBUS_SINGLE_DELIVERY,
|
||||
ONE_ALLOCATED_CHICKEN_PER_CUSTOMER,
|
||||
ONE_CHICKEN_PER_CUSTOMER,
|
||||
UPGRADED_TO_FIRST_CLASS,
|
||||
UPGRADED_TO_SECOND_CLASS,
|
||||
ROOM_RESERVED_FOR_FIRST_CLASS,
|
||||
NO_LOSERS,
|
||||
CLASS_NOT_PERMITTED_IN_AREA,
|
||||
EXIT_FROM_OTHER_SIDE,
|
||||
TRANSPORT_OUT_OF_ORDER,
|
||||
FAN_HAS_BLOWN_A_FUSE,
|
||||
POKE_WITH_LONG_STICK,
|
||||
TOO_SHORT_TO_REACH_BRANCHES,
|
||||
OUTSIDE_ELEVATOR_NUM,
|
||||
BOT_BLOCKING_ELEVATOR,
|
||||
ELEVATOR_NON_FUNCTIONAL,
|
||||
LIGHT_IS_LOOSE,
|
||||
LUMI_GLOW_LIGHTS,
|
||||
ALREADY_HAVE_STICK,
|
||||
GLASS_IS_UNBREAKABLE,
|
||||
FOR_STICK_BREAK_GLASS,
|
||||
DISPENSOR_HAS_UNBREAKABLE_GLASS,
|
||||
CHICKEN_IS_CLEAN,
|
||||
ADJUST_VIEWING_APPARATUS,
|
||||
CANNOT_TAKE_CAGE_LOCKED,
|
||||
ALREADY_AT_DESTINATION,
|
||||
CLASS_NOT_ALLOWED_AT_DEST,
|
||||
AT_LEAST_3RD_CLASS_FOR_HELP,
|
||||
NO_ROOM_ASSIGNED,
|
||||
ELEVATOR_NOT_BELOW_27,
|
||||
SELECT_GAME_TO_LOAD,
|
||||
SELECT_GAME_TO_SAVE,
|
||||
SUPPLY_GALACTIC_REFERENCE,
|
||||
LOCKED_MUSIC_SYSTEM,
|
||||
STUCK_TO_BRANCH,
|
||||
FROZEN_TO_BRANCH,
|
||||
CHECK_IN_AT_RECEPTION,
|
||||
FOODSTUFF_ALREADY_GARNISHED,
|
||||
DISPENSOR_IS_EMPTY,
|
||||
PUT_FOOD_UNDER_DISPENSOR,
|
||||
SEASONAL_SWITCH_NOT_WORKING,
|
||||
YOUR_STATEROOM,
|
||||
BED_NOT_SUPPORT_YOUR_WEIGHT,
|
||||
NOT_YOUR_ASSIGNED_ROOM,
|
||||
OUT_OF_REACH,
|
||||
SUCCUBUS_DESCRIPTION,
|
||||
CANAL_CLOSED_FOR_WINTER,
|
||||
AREA_OFF_LIMIT_TO_PASSENGERS,
|
||||
GO_WHERE,
|
||||
NICE_IF_TAKE_BUT_CANT,
|
||||
BOWL_OF_NUTS,
|
||||
NOT_A_BOWL_OF_NUTS,
|
||||
|
||||
CANT_SUMMON_DOORBOT,
|
||||
CANT_SUMMON_BELLBOT,
|
||||
NO_ONE_TO_TALK_TO,
|
||||
TALKING_TO,
|
||||
DOORBOT_NAME,
|
||||
DESKBOT_NAME,
|
||||
LIFTBOT_NAME,
|
||||
PARROT_NAME,
|
||||
BARBOT_NAME,
|
||||
CHATTERBOT_NAME,
|
||||
BELLBOT_NAME,
|
||||
MAITRED_NAME,
|
||||
SUCCUBUS_NAME,
|
||||
UNKNOWN_NAME,
|
||||
ARM_ALREADY_HOLDING,
|
||||
YOU_CANT_GET_THIS,
|
||||
DOESNT_DO_ANYTHING,
|
||||
DOESNT_WANT_THIS,
|
||||
DOES_NOT_REACH,
|
||||
CHICKEN_ALREADY_CLEAN,
|
||||
HOSE_INCOMPATIBLE,
|
||||
INCORRECTLY_CALIBRATED,
|
||||
GONDOLIERS_FIRST_CLASS_ONLY,
|
||||
NOTHING_ON_CHANNEL,
|
||||
TELEVISION_CONTROL,
|
||||
OPERATE_ENTERTAINMENT,
|
||||
OPERATE_LIGHTS,
|
||||
DEPLOY_FLORAL_ENHANCEMENT,
|
||||
DEPLOY_FULLY_RELAXATION,
|
||||
DEPLOY_COMFORT_WORKSTATION,
|
||||
DEPLOY_MINOR_STORAGE,
|
||||
DEPLOY_MAJOR_RELAXATION,
|
||||
INFLATE_RELAXATION_DEVICE,
|
||||
DEPLOY_MAINTENANCE_HUB,
|
||||
DEPLOY_EXECUTIVE_SURFACE,
|
||||
DEPLOY_MINOR_RELAXATION,
|
||||
DEPLOY_SINK,
|
||||
DEPLOY_MAJOR_STORAGE,
|
||||
SUCCUBUS_DELIVERY_SYSTEM,
|
||||
NAVIGATION_CONTROLLER,
|
||||
SKIP_NAVIGATION,
|
||||
SUMMON_ELEVATOR,
|
||||
SUMMON_PELLERATOR,
|
||||
GO_TO_BOTTOM_OF_WELL,
|
||||
GO_TO_TOP_OF_WELL,
|
||||
GO_TO_STATEROOM,
|
||||
GO_TO_BAR,
|
||||
GO_TO_PROMENADE_DECK,
|
||||
GO_TO_ARBORETUM,
|
||||
GO_TO_MUSIC_ROOM,
|
||||
GO_TO_1ST_CLASS_RESTAURANT,
|
||||
THE_PARROT_LOBBY,
|
||||
THE_CREATORS_CHAMBER,
|
||||
THE_BRIDGE,
|
||||
THE_BILGE_ROOM,
|
||||
THE_SCULPTURE_CHAMBER,
|
||||
THE_ARBORETUM,
|
||||
THE_BOTTOM_OF_THE_WELL,
|
||||
THE_PROMENADE_DECK,
|
||||
RESTAURANT_1ST_CLASS,
|
||||
TITANIAS_ROOM,
|
||||
THE_BAR,
|
||||
THE_EMBARKATION_LOBBY,
|
||||
THE_MUSIC_ROOM,
|
||||
UNKNOWN_ROOM,
|
||||
THE_SERVICE_ELEVATOR,
|
||||
SGT_LEISURE_LOUNGE,
|
||||
THE_ELEVATOR,
|
||||
THE_DOME,
|
||||
THE_PELLERATOR,
|
||||
THE_TOP_OF_THE_WELL,
|
||||
NOWHERE_TO_GO,
|
||||
CLASS_1,
|
||||
CLASS_2,
|
||||
CLASS_3,
|
||||
CLASS_NONE,
|
||||
YOUR_ASSIGNED_ROOM,
|
||||
PREVIOUSLY_ASSIGNED_ROOM,
|
||||
SAVED_CHEVRON,
|
||||
CURRENT_LOCATION,
|
||||
ELEVATOR_NUM,
|
||||
FLOOR_NUM,
|
||||
ROOM_NUM,
|
||||
SHIFT_CLICK_TO_EDIT,
|
||||
A_HOT,
|
||||
A_COLD,
|
||||
LOAD_THE_GAME,
|
||||
SAVE_THE_GAME,
|
||||
EMPTY,
|
||||
QUIT_THE_GAME,
|
||||
SURE_YOU_WANT_TO_QUIT,
|
||||
CHANGE_VOLUME_SETTINGS,
|
||||
MASTER_VOLUME,
|
||||
MUSIC_VOLUME,
|
||||
PARROT_VOLUME,
|
||||
SPEECH_VOLUME,
|
||||
|
||||
// German version only
|
||||
DE_SUMMER,
|
||||
DE_AUTUMN,
|
||||
DE_WINTER,
|
||||
DE_SPRING,
|
||||
DE_SUMMER_ARBORETUM,
|
||||
DE_AUTUMN_ARBORETUM,
|
||||
DE_WINTER_ARBORETUM,
|
||||
DE_SPRING_ARBORETUM,
|
||||
DE_ARBORETUM_MSG1,
|
||||
DE_ARBORETUM_MSG2,
|
||||
DE_BRIDGE_MSG1,
|
||||
DE_BRIDGE_MSG2,
|
||||
DE_BRIDGE_MSG3,
|
||||
DE_BRIDGE_MSG4,
|
||||
DE_BRIDGE_MSG5,
|
||||
DE_BRIDGE_MSG6,
|
||||
DE_BRIDGE_MSG7,
|
||||
DE_BRIDGE_MSG8,
|
||||
DE_BRIDGE_MSG9,
|
||||
DE_BRIDGE_MSG10,
|
||||
DE_PROMENADE_DECK_MSG1,
|
||||
DE_PROMENADE_DECK_MSG2,
|
||||
DE_PROMENADE_DECK_MSG3,
|
||||
DE_PROMENADE_DECK_MSG4,
|
||||
DE_PROMENADE_DECK_MSG5,
|
||||
DE_PROMENADE_DECK_MSG6,
|
||||
DE_PROMENADE_DECK_MSG7,
|
||||
DE_PROMENADE_DECK_MSG8,
|
||||
DE_PROMENADE_DECK_MSG9,
|
||||
DE_PROMENADE_DECK_MSG10,
|
||||
DE_SGTLOBBY_MSG1,
|
||||
DE_SGTLOBBY_MSG2,
|
||||
DE_SGTLOBBY_MSG3,
|
||||
DE_SGTLOBBY_MSG4,
|
||||
DE_SGTLOBBY_MSG5,
|
||||
DE_SGTLOBBY_MSG6,
|
||||
DE_SGTLOBBY_MSG7,
|
||||
DE_SGTLOBBY_MSG8,
|
||||
DE_TITANIA_MSG1,
|
||||
DE_TITANIA_MSG2,
|
||||
DE_TITANIA_MSG3,
|
||||
DE_TITANIA_MSG4,
|
||||
DE_TITANIA_MSG5,
|
||||
DE_TITANIA_MSG6,
|
||||
DE_TITANIA_MSG7,
|
||||
DE_TITANIA_MSG8
|
||||
|
||||
};
|
||||
|
||||
class Strings : public Common::StringArray {
|
||||
public:
|
||||
void load();
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_STRINGS_H */
|
||||
88
engines/titanic/support/text_cursor.cpp
Normal file
88
engines/titanic/support/text_cursor.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/* 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 "titanic/support/text_cursor.h"
|
||||
#include "titanic/events.h"
|
||||
#include "titanic/support/screen_manager.h"
|
||||
#include "titanic/titanic.h"
|
||||
#include "common/textconsole.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
CTextCursor::CTextCursor(CScreenManager *screenManager) :
|
||||
_screenManager(screenManager), _active(false), _blinkVisible(false),
|
||||
_backRenderSurface(nullptr), _frontRenderSurface(nullptr),
|
||||
_blinkDelay(300), _size(2, 10), _priorBlinkTime(0),
|
||||
_cursorR(0), _cursorG(0), _cursorB(0), _mode(-1) {
|
||||
_surface = screenManager->createSurface(10, 10, 16);
|
||||
}
|
||||
|
||||
CTextCursor::~CTextCursor() {
|
||||
delete _surface;
|
||||
}
|
||||
|
||||
void CTextCursor::setColor(byte r, byte g, byte b) {
|
||||
_cursorR = r;
|
||||
_cursorG = g;
|
||||
_cursorB = b;
|
||||
}
|
||||
|
||||
void CTextCursor::show() {
|
||||
_backRenderSurface = _screenManager->getSurface(SURFACE_BACKBUFFER);
|
||||
_frontRenderSurface = _screenManager->getFrontRenderSurface();
|
||||
_active = true;
|
||||
_priorBlinkTime = g_vm->_events->getTicksCount();
|
||||
}
|
||||
|
||||
void CTextCursor::hide() {
|
||||
_active = false;
|
||||
}
|
||||
|
||||
void CTextCursor::draw() {
|
||||
if (!_active)
|
||||
return;
|
||||
|
||||
// Handle updating whether the blinking cursor is visible or not
|
||||
uint newTicks = g_vm->_events->getTicksCount();
|
||||
while (newTicks > (_priorBlinkTime + _blinkDelay)) {
|
||||
_priorBlinkTime += _blinkDelay;
|
||||
_blinkVisible = !_blinkVisible;
|
||||
}
|
||||
|
||||
if (_blinkVisible) {
|
||||
Rect cursorRect = getCursorBounds();
|
||||
_surface->blitFrom(Common::Point(0, 0), _backRenderSurface, &cursorRect);
|
||||
|
||||
if (!_screenBounds.isEmpty())
|
||||
// Limit the cursor rect to only within designated screen area
|
||||
cursorRect.constrain(_screenBounds);
|
||||
|
||||
if (!cursorRect.isEmpty()) {
|
||||
// Draw cursor onto the screen
|
||||
_backRenderSurface->_ddSurface->fillRect(&cursorRect,
|
||||
_cursorR, _cursorG, _cursorB);
|
||||
}
|
||||
|
||||
//_screenManager->blitFrom(SURFACE_BACKBUFFER, _surface, &_pos);
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
120
engines/titanic/support/text_cursor.h
Normal file
120
engines/titanic/support/text_cursor.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/* 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 TITANIC_TEXT_CURSOR_H
|
||||
#define TITANIC_TEXT_CURSOR_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "titanic/support/rect.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CScreenManager;
|
||||
class CVideoSurface;
|
||||
|
||||
class CTextCursor {
|
||||
private:
|
||||
CScreenManager *_screenManager;
|
||||
CVideoSurface *_backRenderSurface;
|
||||
CVideoSurface *_frontRenderSurface;
|
||||
Point _pos;
|
||||
Rect _screenBounds;
|
||||
uint _blinkDelay;
|
||||
bool _blinkVisible;
|
||||
Point _size;
|
||||
Point _screenTopLeft;
|
||||
uint _priorBlinkTime;
|
||||
byte _cursorR;
|
||||
byte _cursorG;
|
||||
byte _cursorB;
|
||||
CVideoSurface *_surface;
|
||||
int _mode;
|
||||
public:
|
||||
bool _active;
|
||||
public:
|
||||
CTextCursor(CScreenManager *screenManager);
|
||||
~CTextCursor();
|
||||
|
||||
/**
|
||||
* Sets the position of the cursor
|
||||
*/
|
||||
void setPos(const Point &pt) { _pos = pt; }
|
||||
|
||||
/**
|
||||
* Sets the size of the cursor
|
||||
*/
|
||||
void setSize(const Point &size) { _size = size; }
|
||||
|
||||
/**
|
||||
* Returns the bounds for the cursor
|
||||
*/
|
||||
Rect getCursorBounds() const {
|
||||
return Rect(_pos.x, _pos.y, _pos.x + _size.x, _pos.y + _size.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set bounds
|
||||
*/
|
||||
void setBounds(const Rect &r) { _screenBounds = r; }
|
||||
|
||||
/**
|
||||
* Clear the bounds
|
||||
*/
|
||||
void clearBounds() { _screenBounds.clear(); }
|
||||
|
||||
/**
|
||||
* Set the blinking rate
|
||||
*/
|
||||
void setBlinkRate(uint ticks) { _blinkDelay = ticks; }
|
||||
|
||||
/**
|
||||
* Set the cursor color
|
||||
*/
|
||||
void setColor(byte r, byte g, byte b);
|
||||
|
||||
/**
|
||||
* Returns whether the text cursor is active
|
||||
*/
|
||||
bool isActive() const { return _active; }
|
||||
|
||||
int getMode() const { return _mode; }
|
||||
|
||||
void setMode(int mode) { _mode = mode; }
|
||||
|
||||
/**
|
||||
* Show the text cursor
|
||||
*/
|
||||
void show();
|
||||
|
||||
/**
|
||||
* Hide the text cursor
|
||||
*/
|
||||
void hide();
|
||||
|
||||
/**
|
||||
* Update and draw the cursor if necessary
|
||||
*/
|
||||
void draw();
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_TEXT_CURSOR_H */
|
||||
205
engines/titanic/support/time_event_info.cpp
Normal file
205
engines/titanic/support/time_event_info.cpp
Normal file
@@ -0,0 +1,205 @@
|
||||
/* 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 "titanic/support/time_event_info.h"
|
||||
#include "titanic/core/game_object.h"
|
||||
#include "titanic/core/project_item.h"
|
||||
#include "titanic/messages/messages.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
void CTimeEventInfoList::postLoad(uint ticks, CProjectItem *project) {
|
||||
for (iterator i = begin(); i != end(); ++i)
|
||||
(*i)->postLoad(ticks, project);
|
||||
}
|
||||
|
||||
void CTimeEventInfoList::preSave(uint ticks) {
|
||||
for (iterator i = begin(); i != end(); ++i)
|
||||
(*i)->preSave(ticks);
|
||||
}
|
||||
|
||||
void CTimeEventInfoList::postSave() {
|
||||
for (iterator i = begin(); i != end(); ++i)
|
||||
(*i)->postSave();
|
||||
}
|
||||
|
||||
void CTimeEventInfoList::update(uint ticks) {
|
||||
// Remove any items that are done
|
||||
for (iterator i = begin(); i != end(); ) {
|
||||
CTimeEventInfo *item = *i;
|
||||
if (item->_done) {
|
||||
i = erase(i);
|
||||
delete item;
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle updating the items
|
||||
for (iterator i = begin(); i != end(); ) {
|
||||
CTimeEventInfo *item = *i;
|
||||
if (!item->update(ticks)) {
|
||||
++i;
|
||||
} else {
|
||||
i = erase(i);
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CTimeEventInfoList::stop(uint id) {
|
||||
for (iterator i = begin(); i != end(); ++i) {
|
||||
CTimeEventInfo *item = *i;
|
||||
if (item->_id == id) {
|
||||
item->_done = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CTimeEventInfoList::setPersisent(uint id, bool flag) {
|
||||
for (iterator i = begin(); i != end(); ++i) {
|
||||
CTimeEventInfo *item = *i;
|
||||
if (item->_id == id) {
|
||||
item->setPersisent(flag);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
uint CTimeEventInfo::_nextId;
|
||||
|
||||
CTimeEventInfo::CTimeEventInfo() : ListItem(), _lockCounter(0),
|
||||
_repeated(false), _firstDuration(0), _repeatDuration(0),
|
||||
_target(nullptr), _actionVal(0), _timerCtr(0), _done(false),
|
||||
_lastTimerTicks(0), _relativeTicks(0), _persisent(true) {
|
||||
_id = _nextId++;
|
||||
}
|
||||
|
||||
CTimeEventInfo::CTimeEventInfo(uint ticks, bool repeated, uint firstDuration,
|
||||
uint repeatDuration, CTreeItem *target, int endVal, const CString &action) :
|
||||
ListItem(), _lockCounter(0), _repeated(repeated), _firstDuration(firstDuration),
|
||||
_repeatDuration(repeatDuration), _target(target), _actionVal(endVal), _action(action),
|
||||
_done(false), _timerCtr(0), _lastTimerTicks(ticks), _relativeTicks(0), _persisent(true) {
|
||||
_id = _nextId++;
|
||||
}
|
||||
|
||||
void CTimeEventInfo::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(0, indent);
|
||||
|
||||
CString targetName;
|
||||
if (_target)
|
||||
targetName = _target->getName();
|
||||
file->writeQuotedLine(targetName, indent);
|
||||
file->writeNumberLine(_id, indent);
|
||||
file->writeNumberLine(_repeated, indent);
|
||||
file->writeNumberLine(_firstDuration, indent);
|
||||
file->writeNumberLine(_repeatDuration, indent);
|
||||
file->writeNumberLine(_actionVal, indent);
|
||||
file->writeQuotedLine(_action, indent);
|
||||
file->writeNumberLine(_timerCtr, indent);
|
||||
file->writeNumberLine(_relativeTicks, indent);
|
||||
file->writeNumberLine(_done, indent);
|
||||
file->writeNumberLine(_persisent, indent);
|
||||
}
|
||||
|
||||
void CTimeEventInfo::load(SimpleFile *file) {
|
||||
lock();
|
||||
int val = file->readNumber();
|
||||
|
||||
if (!val) {
|
||||
_targetName = file->readString();
|
||||
_id = file->readNumber();
|
||||
_repeated = file->readNumber();
|
||||
_firstDuration = file->readNumber();
|
||||
_repeatDuration = file->readNumber();
|
||||
_actionVal = file->readNumber();
|
||||
_action = file->readString();
|
||||
_timerCtr = file->readNumber();
|
||||
_relativeTicks = file->readNumber();
|
||||
_done = file->readNumber() != 0;
|
||||
_persisent = file->readNumber() != 0;
|
||||
_target = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CTimeEventInfo::postLoad(uint ticks, CProjectItem *project) {
|
||||
if (!_persisent || _targetName.empty())
|
||||
_done = true;
|
||||
|
||||
// Get the timer's target
|
||||
if (project)
|
||||
_target = project->findByName(_targetName);
|
||||
if (!_target)
|
||||
_done = true;
|
||||
|
||||
_lastTimerTicks = ticks + _relativeTicks;
|
||||
if (_id >= _nextId)
|
||||
_nextId = _id + 1;
|
||||
|
||||
unlock();
|
||||
}
|
||||
|
||||
void CTimeEventInfo::preSave(uint ticks) {
|
||||
_relativeTicks = _lastTimerTicks - ticks;
|
||||
lock();
|
||||
}
|
||||
|
||||
void CTimeEventInfo::postSave() {
|
||||
unlock();
|
||||
}
|
||||
|
||||
bool CTimeEventInfo::update(uint ticks) {
|
||||
if (_lockCounter)
|
||||
return false;
|
||||
|
||||
if (_timerCtr) {
|
||||
if (ticks > (_lastTimerTicks + _repeatDuration)) {
|
||||
++_timerCtr;
|
||||
_lastTimerTicks = ticks;
|
||||
|
||||
if (_target) {
|
||||
CTimerMsg timerMsg(ticks, _timerCtr, _actionVal, _action);
|
||||
timerMsg.execute(_target);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ticks > (_lastTimerTicks + _firstDuration)) {
|
||||
_timerCtr = 1;
|
||||
_lastTimerTicks = ticks;
|
||||
|
||||
if (_target) {
|
||||
CTimerMsg timerMsg(ticks, _timerCtr, _actionVal, _action);
|
||||
timerMsg.execute(_target);
|
||||
}
|
||||
|
||||
if (!_repeated)
|
||||
// Event is done, and can be removed
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
137
engines/titanic/support/time_event_info.h
Normal file
137
engines/titanic/support/time_event_info.h
Normal file
@@ -0,0 +1,137 @@
|
||||
/* 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 TITANIC_TIMER_H
|
||||
#define TITANIC_TIMER_H
|
||||
|
||||
#include "common/algorithm.h"
|
||||
#include "titanic/core/list.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CTreeItem;
|
||||
class CProjectItem;
|
||||
|
||||
class CTimeEventInfo : public ListItem {
|
||||
private:
|
||||
/**
|
||||
* Increments the counter
|
||||
*/
|
||||
void lock() { ++_lockCounter; }
|
||||
|
||||
/**
|
||||
* Called at the end of both post load and post save actions
|
||||
*/
|
||||
void unlock() {
|
||||
_lockCounter = MAX(_lockCounter - 1, 0);
|
||||
}
|
||||
public:
|
||||
static uint _nextId;
|
||||
public:
|
||||
int _lockCounter;
|
||||
uint _id;
|
||||
bool _repeated;
|
||||
uint _firstDuration;
|
||||
uint _repeatDuration;
|
||||
CTreeItem *_target;
|
||||
uint _actionVal;
|
||||
CString _action;
|
||||
uint _timerCtr;
|
||||
uint _lastTimerTicks;
|
||||
uint _relativeTicks;
|
||||
bool _done;
|
||||
bool _persisent;
|
||||
CString _targetName;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CTimeEventInfo();
|
||||
CTimeEventInfo(uint ticks, bool repeated, uint firstDuration, uint repeatDuration,
|
||||
CTreeItem *target, int endVal, const CString &action);
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
|
||||
/**
|
||||
* Called after loading a game has finished
|
||||
*/
|
||||
void postLoad(uint ticks, CProjectItem *project);
|
||||
|
||||
/**
|
||||
* Called when a game is about to be saved
|
||||
*/
|
||||
void preSave(uint ticks);
|
||||
|
||||
/**
|
||||
* Called when a game has finished being saved
|
||||
*/
|
||||
void postSave();
|
||||
|
||||
bool update(uint ticks);
|
||||
|
||||
/**
|
||||
* Flags whether the timer will be persisent across save & loads
|
||||
*/
|
||||
void setPersisent(bool val) { _persisent = val; }
|
||||
};
|
||||
|
||||
class CTimeEventInfoList : public List<CTimeEventInfo> {
|
||||
public:
|
||||
/**
|
||||
* Called after loading a game has finished
|
||||
*/
|
||||
void postLoad(uint ticks, CProjectItem *project);
|
||||
|
||||
/**
|
||||
* Called when a game is about to be saved
|
||||
*/
|
||||
void preSave(uint ticks);
|
||||
|
||||
/**
|
||||
* Called when a game has finished being saved
|
||||
*/
|
||||
void postSave();
|
||||
|
||||
/**
|
||||
* Handles an update
|
||||
*/
|
||||
void update(uint ticks);
|
||||
|
||||
/**
|
||||
* Remove an item with the given Id
|
||||
*/
|
||||
void stop(uint id);
|
||||
|
||||
/**
|
||||
* Sets whether a timer with a given Id will be persisent across saves
|
||||
*/
|
||||
void setPersisent(uint id, bool flag);
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_TIMER_H */
|
||||
59
engines/titanic/support/transparency_surface.cpp
Normal file
59
engines/titanic/support/transparency_surface.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/* 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 "titanic/support/transparency_surface.h"
|
||||
#include "common/algorithm.h"
|
||||
#include "common/textconsole.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
CTransparencySurface::CTransparencySurface(const Graphics::Surface *surface,
|
||||
TransparencyMode transMode) : _surface(surface) {
|
||||
_pitch = 0;
|
||||
_runLength = 0;
|
||||
_flag = false;
|
||||
_opaqueColor = 0;
|
||||
_transparentColor = 0xff;
|
||||
|
||||
switch (transMode) {
|
||||
case TRANS_MASK0:
|
||||
case TRANS_ALPHA0:
|
||||
_transparentColor = 0;
|
||||
_opaqueColor = 0xff;
|
||||
break;
|
||||
case TRANS_MASK255:
|
||||
case TRANS_ALPHA255:
|
||||
_transparentColor = 0xff;
|
||||
_opaqueColor = 0;
|
||||
break;
|
||||
case TRANS_DEFAULT:
|
||||
// If top left pixel is low, then 0 is the transparent color
|
||||
if (*(const byte *)surface->getPixels() < 0x80) {
|
||||
_opaqueColor = 0xff;
|
||||
_transparentColor = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
107
engines/titanic/support/transparency_surface.h
Normal file
107
engines/titanic/support/transparency_surface.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/* 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 TITANIC_TRANSPARENCY_SURFACE_H
|
||||
#define TITANIC_TRANSPARENCY_SURFACE_H
|
||||
|
||||
#include "common/rect.h"
|
||||
#include "graphics/surface.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
enum TransparencyMode {
|
||||
TRANS_MASK0 = 0, TRANS_MASK255 = 1, TRANS_ALPHA0 = 2,
|
||||
TRANS_ALPHA255 = 3, TRANS_DEFAULT = 4
|
||||
};
|
||||
|
||||
class CTransparencySurface {
|
||||
private:
|
||||
const Graphics::Surface *_surface;
|
||||
Common::Point _pos;
|
||||
int _pitch;
|
||||
int _runLength;
|
||||
bool _flag;
|
||||
byte _transparentColor;
|
||||
byte _opaqueColor;
|
||||
private:
|
||||
/**
|
||||
* Returns a a pixel from the transparency surface
|
||||
*/
|
||||
inline uint getPixel() const {
|
||||
byte pixel = *(const byte *)_surface->getBasePtr(_pos.x, _pos.y);
|
||||
return pixel;
|
||||
}
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
CTransparencySurface(const Graphics::Surface *surface, TransparencyMode transMode);
|
||||
|
||||
/**
|
||||
* Sets the row to get transparencies from
|
||||
*/
|
||||
inline void setRow(int yp) { _pos.y = yp; }
|
||||
|
||||
/**
|
||||
* Sets the column to get transparencies from
|
||||
*/
|
||||
inline void setCol(int xp) { _pos.x = xp; }
|
||||
|
||||
/**
|
||||
* Moves reading position horizontally by a single pixel
|
||||
*/
|
||||
inline int moveX() {
|
||||
if (++_pos.x >= _surface->w) {
|
||||
_pos.x = 0;
|
||||
++_pos.y;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the alpha value for the pixel (0-31)
|
||||
*/
|
||||
inline uint getAlpha() const {
|
||||
byte pixel = getPixel();
|
||||
return _opaqueColor ? 0xFF - pixel : pixel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the pixel is opaque
|
||||
*/
|
||||
inline bool isPixelOpaque() const {
|
||||
byte pixel = getPixel();
|
||||
return _opaqueColor ? pixel >= 0xf0 : pixel < 0x10;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the pixel is completely transparent
|
||||
*/
|
||||
inline bool isPixelTransparent() const {
|
||||
byte pixel = getPixel();
|
||||
return _transparentColor ? pixel >= 0xf0 : pixel < 0x10;
|
||||
}
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_TRANSPARENCY_SURFACE_H */
|
||||
664
engines/titanic/support/video_surface.cpp
Normal file
664
engines/titanic/support/video_surface.cpp
Normal file
@@ -0,0 +1,664 @@
|
||||
/* 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 "titanic/support/video_surface.h"
|
||||
#include "titanic/support/image_decoders.h"
|
||||
#include "titanic/support/screen_manager.h"
|
||||
#include "titanic/support/transparency_surface.h"
|
||||
#include "titanic/titanic.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
int CVideoSurface::_videoSurfaceCounter = 0;
|
||||
byte CVideoSurface::_palette1[32][32];
|
||||
byte CVideoSurface::_palette2[32][32];
|
||||
|
||||
CVideoSurface::CVideoSurface(CScreenManager *screenManager) :
|
||||
_screenManager(screenManager), _rawSurface(nullptr), _movie(nullptr),
|
||||
_pendingLoad(false), _flipVertically(false), _fastBlitFlag(false),
|
||||
_transparencySurface(nullptr), _transparencyMode(TRANS_DEFAULT),
|
||||
_freeTransparencySurface(DisposeAfterUse::NO), _hasFrame(true), _lockCount(0) {
|
||||
_videoSurfaceNum = _videoSurfaceCounter++;
|
||||
}
|
||||
|
||||
CVideoSurface::~CVideoSurface() {
|
||||
--_videoSurfaceCounter;
|
||||
|
||||
if (_freeTransparencySurface == DisposeAfterUse::YES)
|
||||
delete _transparencySurface;
|
||||
}
|
||||
|
||||
void CVideoSurface::setupPalette(byte palette[32][32], byte val) {
|
||||
for (uint idx1 = 0; idx1 < 32; ++idx1) {
|
||||
for (uint idx2 = 0, base = 0; idx2 < 32; ++idx2, base += idx1) {
|
||||
uint v = base / 31;
|
||||
palette[idx1][idx2] = (byte)v;
|
||||
|
||||
if (val != 0xff && v != idx2) {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVideoSurface::setSurface(CScreenManager *screenManager, DirectDrawSurface *surface) {
|
||||
_screenManager = screenManager;
|
||||
_ddSurface = surface;
|
||||
}
|
||||
|
||||
void CVideoSurface::blitFrom(const Point &destPos, CVideoSurface *src, const Rect *srcRect) {
|
||||
if (loadIfReady() && src->loadIfReady() && _ddSurface && src->_ddSurface) {
|
||||
Rect srcBounds, destBounds;
|
||||
clipBounds(srcBounds, destBounds, src, srcRect, &destPos);
|
||||
|
||||
if (src->_flipVertically)
|
||||
flippedBlitRect(srcBounds, destBounds, src);
|
||||
else
|
||||
blitRect(srcBounds, destBounds, src);
|
||||
}
|
||||
}
|
||||
|
||||
void CVideoSurface::blitFrom(const Point &destPos, const Graphics::Surface *src) {
|
||||
lock();
|
||||
_rawSurface->blitFrom(*src, destPos);
|
||||
unlock();
|
||||
}
|
||||
|
||||
void CVideoSurface::clipBounds(Rect &srcRect, Rect &destRect,
|
||||
CVideoSurface *srcSurface, const Rect *subRect, const Point *destPos) {
|
||||
// Figure out initial source rect and dest rect, based on whether
|
||||
// specific subRect and/or destPos have been passed
|
||||
if (destPos) {
|
||||
destRect.left = destPos->x;
|
||||
destRect.top = destPos->y;
|
||||
} else {
|
||||
destRect.left = destRect.top = 0;
|
||||
}
|
||||
|
||||
if (subRect) {
|
||||
destRect.right = destRect.left + subRect->width();
|
||||
destRect.bottom = destRect.top + subRect->height();
|
||||
srcRect = *subRect;
|
||||
} else {
|
||||
srcRect.right = srcRect.left + srcSurface->getWidth();
|
||||
srcRect.bottom = srcRect.top + srcSurface->getHeight();
|
||||
srcRect = Rect(0, 0, srcSurface->getWidth(), srcSurface->getHeight());
|
||||
}
|
||||
|
||||
// Clip destination rect to be on-screen
|
||||
if (destRect.left < 0) {
|
||||
srcRect.left -= destRect.left;
|
||||
destRect.left = 0;
|
||||
}
|
||||
if (destRect.top < 0) {
|
||||
srcRect.top -= destRect.top;
|
||||
destRect.top = 0;
|
||||
}
|
||||
if (destRect.right > getWidth()) {
|
||||
srcRect.right += getWidth() - destRect.right;
|
||||
destRect.right = getWidth();
|
||||
}
|
||||
if (destRect.bottom > getHeight()) {
|
||||
srcRect.bottom += getHeight() - destRect.bottom;
|
||||
destRect.bottom = getHeight();
|
||||
}
|
||||
|
||||
// Clip source rect to be within the source surface
|
||||
if (srcRect.left < 0) {
|
||||
destRect.left -= srcRect.left;
|
||||
srcRect.left = 0;
|
||||
}
|
||||
if (srcRect.top < 0) {
|
||||
destRect.top -= srcRect.top;
|
||||
srcRect.top = 0;
|
||||
}
|
||||
if (srcRect.right > srcSurface->getWidth()) {
|
||||
destRect.right += srcSurface->getWidth() - srcRect.right;
|
||||
srcRect.right = srcSurface->getWidth();
|
||||
}
|
||||
if (srcRect.bottom > srcSurface->getHeight()) {
|
||||
destRect.bottom += srcSurface->getHeight() - srcRect.bottom;
|
||||
srcRect.bottom = srcSurface->getHeight();
|
||||
}
|
||||
|
||||
// Validate that the resulting rects are valid
|
||||
if (destRect.left >= destRect.right || destRect.top >= destRect.bottom
|
||||
|| srcRect.left >= srcRect.right || srcRect.top >= srcRect.bottom)
|
||||
error("Invalid rect");
|
||||
}
|
||||
|
||||
void CVideoSurface::blitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) {
|
||||
src->lock();
|
||||
lock();
|
||||
|
||||
if (src->_fastBlitFlag) {
|
||||
_rawSurface->blitFrom(*src->_rawSurface, srcRect, Point(destRect.left, destRect.top));
|
||||
} else if (src->getTransparencySurface()) {
|
||||
transBlitRect(srcRect, destRect, src, false);
|
||||
} else if (lock()) {
|
||||
if (src->lock()) {
|
||||
const Graphics::ManagedSurface *srcSurface = src->_rawSurface;
|
||||
Graphics::ManagedSurface *destSurface = _rawSurface;
|
||||
const uint transColor = src->getTransparencyColor();
|
||||
|
||||
destSurface->transBlitFrom(*srcSurface, srcRect, destRect, transColor);
|
||||
|
||||
src->unlock();
|
||||
}
|
||||
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void CVideoSurface::flippedBlitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) {
|
||||
if (src->getTransparencySurface()) {
|
||||
transBlitRect(srcRect, destRect, src, true);
|
||||
} else if (lock()) {
|
||||
if (src->lock()) {
|
||||
Graphics::ManagedSurface *srcSurface = src->_rawSurface;
|
||||
Graphics::ManagedSurface *destSurface = _rawSurface;
|
||||
const Graphics::Surface srcArea = srcSurface->getSubArea(srcRect);
|
||||
const uint transColor = src->getTransparencyColor();
|
||||
|
||||
// Vertically flip the source area
|
||||
Graphics::ManagedSurface flippedArea(srcArea.w, srcArea.h, srcArea.format);
|
||||
for (int y = 0; y < srcArea.h; ++y) {
|
||||
const byte *pSrc = (const byte *)srcArea.getBasePtr(0, y);
|
||||
byte *pDest = (byte *)flippedArea.getBasePtr(0, flippedArea.h - y - 1);
|
||||
Common::copy(pSrc, pSrc + srcArea.pitch, pDest);
|
||||
}
|
||||
|
||||
destSurface->transBlitFrom(flippedArea,
|
||||
Common::Point(destRect.left, destRect.top), transColor);
|
||||
|
||||
src->unlock();
|
||||
}
|
||||
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void CVideoSurface::transBlitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src, bool flipFlag) {
|
||||
assert(srcRect.width() == destRect.width() && srcRect.height() == destRect.height());
|
||||
assert(src->getPixelDepth() == 2);
|
||||
|
||||
if (lock()) {
|
||||
if (src->lock()) {
|
||||
Graphics::ManagedSurface *srcSurface = src->_rawSurface;
|
||||
Graphics::ManagedSurface *destSurface = _rawSurface;
|
||||
Graphics::Surface destArea = destSurface->getSubArea(destRect);
|
||||
|
||||
const uint16 *srcPtr = (const uint16 *)srcSurface->getBasePtr(
|
||||
srcRect.left, flipFlag ? srcRect.top : srcRect.bottom - 1);
|
||||
uint16 *destPtr = (uint16 *)destArea.getBasePtr(0, destArea.h - 1);
|
||||
bool isAlpha = src->_transparencyMode == TRANS_ALPHA0 ||
|
||||
src->_transparencyMode == TRANS_ALPHA255;
|
||||
|
||||
CTransparencySurface transSurface(src->getTransparencySurface(), src->_transparencyMode);
|
||||
|
||||
for (int yCtr = 0; yCtr < srcRect.height(); ++yCtr) {
|
||||
// Prepare for copying the line
|
||||
const uint16 *lineSrcP = srcPtr;
|
||||
uint16 *lineDestP = destPtr;
|
||||
transSurface.setRow(flipFlag ? srcRect.top + yCtr : srcRect.bottom - yCtr - 1);
|
||||
transSurface.setCol(srcRect.left);
|
||||
|
||||
for (int srcX = srcRect.left; srcX < srcRect.right; ++srcX) {
|
||||
if (transSurface.isPixelOpaque())
|
||||
*lineDestP = *lineSrcP;
|
||||
else if (!transSurface.isPixelTransparent())
|
||||
copyPixel(lineDestP, lineSrcP, transSurface.getAlpha() >> 3, srcSurface->format, isAlpha);
|
||||
|
||||
++lineSrcP;
|
||||
++lineDestP;
|
||||
transSurface.moveX();
|
||||
}
|
||||
|
||||
// Move to next line
|
||||
srcPtr = flipFlag ? srcPtr + (src->getPitch() / 2) :
|
||||
srcPtr - (src->getPitch() / 2);
|
||||
destPtr -= destArea.pitch / 2;
|
||||
}
|
||||
|
||||
src->unlock();
|
||||
}
|
||||
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
uint CVideoSurface::getTransparencyColor() {
|
||||
return getPixelDepth() == 2 ? 0xf81f : 0x7c1f;
|
||||
}
|
||||
|
||||
bool CVideoSurface::hasFrame() {
|
||||
if (_hasFrame) {
|
||||
_hasFrame = false;
|
||||
return true;
|
||||
} else if (_movie) {
|
||||
return _movie->hasVideoFrame();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#define RGB_SHIFT 3
|
||||
void CVideoSurface::copyPixel(uint16 *destP, const uint16 *srcP, byte alpha,
|
||||
const Graphics::PixelFormat &srcFormat, bool isAlpha) {
|
||||
const Graphics::PixelFormat destFormat = _ddSurface->getFormat();
|
||||
alpha &= 0xff;
|
||||
assert(alpha < 32);
|
||||
|
||||
// Get the source color
|
||||
byte r, g, b;
|
||||
srcFormat.colorToRGB(*srcP, r, g, b);
|
||||
r >>= RGB_SHIFT;
|
||||
g >>= RGB_SHIFT;
|
||||
b >>= RGB_SHIFT;
|
||||
|
||||
if (isAlpha) {
|
||||
r = _palette1[31 - alpha][r];
|
||||
g = _palette1[31 - alpha][g];
|
||||
b = _palette1[31 - alpha][b];
|
||||
}
|
||||
|
||||
byte r2, g2, b2;
|
||||
destFormat.colorToRGB(*destP, r2, g2, b2);
|
||||
r2 >>= RGB_SHIFT;
|
||||
g2 >>= RGB_SHIFT;
|
||||
b2 >>= RGB_SHIFT;
|
||||
r2 = _palette1[alpha][r2];
|
||||
g2 = _palette1[alpha][g2];
|
||||
b2 = _palette1[alpha][b2];
|
||||
|
||||
*destP = destFormat.RGBToColor((r + r2) << RGB_SHIFT,
|
||||
(g + g2) << RGB_SHIFT, (b + b2) << RGB_SHIFT);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
OSVideoSurface::OSVideoSurface(CScreenManager *screenManager, DirectDrawSurface *surface) :
|
||||
CVideoSurface(screenManager) {
|
||||
_ddSurface = surface;
|
||||
}
|
||||
|
||||
OSVideoSurface::OSVideoSurface(CScreenManager *screenManager, const CResourceKey &key, bool pendingLoad) :
|
||||
CVideoSurface(screenManager) {
|
||||
_ddSurface = nullptr;
|
||||
_pendingLoad = pendingLoad;
|
||||
|
||||
if (_pendingLoad) {
|
||||
loadResource(key);
|
||||
} else {
|
||||
_resourceKey = key;
|
||||
load();
|
||||
}
|
||||
}
|
||||
|
||||
OSVideoSurface::~OSVideoSurface() {
|
||||
if (_ddSurface)
|
||||
_videoSurfaceCounter -= OSVideoSurface::freeSurface();
|
||||
}
|
||||
|
||||
void OSVideoSurface::loadResource(const CResourceKey &key) {
|
||||
_resourceKey = key;
|
||||
_pendingLoad = true;
|
||||
|
||||
if (hasSurface())
|
||||
load();
|
||||
}
|
||||
|
||||
void OSVideoSurface::loadTarga(const CResourceKey &key) {
|
||||
// Decode the image
|
||||
CTargaDecode decoder;
|
||||
decoder.decode(*this, key.getString());
|
||||
|
||||
if (getPixelDepth() == 2)
|
||||
shiftColors();
|
||||
|
||||
_resourceKey = key;
|
||||
|
||||
}
|
||||
|
||||
void OSVideoSurface::loadJPEG(const CResourceKey &key) {
|
||||
// Decode the image
|
||||
CJPEGDecode decoder;
|
||||
decoder.decode(*this, key.getString());
|
||||
|
||||
if (getPixelDepth() == 2)
|
||||
shiftColors();
|
||||
|
||||
_resourceKey = key;
|
||||
}
|
||||
|
||||
void OSVideoSurface::loadTarga(const CString &name) {
|
||||
CResourceKey key(name);
|
||||
loadTarga(key);
|
||||
}
|
||||
|
||||
void OSVideoSurface::loadMovie(const CResourceKey &key, bool destroyFlag) {
|
||||
// Delete any prior movie
|
||||
if (_movie) {
|
||||
delete _movie;
|
||||
_movie = nullptr;
|
||||
}
|
||||
|
||||
// Create the new movie and load the first frame to the video surface
|
||||
_movie = g_vm->_movieManager.createMovie(key, this);
|
||||
_movie->setFrame(0);
|
||||
|
||||
// If flagged to destroy, then immediately destroy movie instance
|
||||
if (destroyFlag) {
|
||||
delete _movie;
|
||||
_movie = nullptr;
|
||||
}
|
||||
|
||||
_resourceKey = key;
|
||||
}
|
||||
|
||||
bool OSVideoSurface::lock() {
|
||||
if (!loadIfReady())
|
||||
return false;
|
||||
|
||||
++_lockCount;
|
||||
_rawSurface = _ddSurface->lock(nullptr, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
void OSVideoSurface::unlock() {
|
||||
if (!--_lockCount) {
|
||||
if (_rawSurface)
|
||||
_ddSurface->unlock();
|
||||
_rawSurface = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool OSVideoSurface::hasSurface() {
|
||||
return _ddSurface != nullptr;
|
||||
}
|
||||
|
||||
int OSVideoSurface::getWidth() {
|
||||
if (!loadIfReady())
|
||||
error("Could not load resource");
|
||||
|
||||
return _ddSurface->getWidth();
|
||||
}
|
||||
|
||||
int OSVideoSurface::getHeight() {
|
||||
if (!loadIfReady())
|
||||
error("Could not load resource");
|
||||
|
||||
return _ddSurface->getHeight();
|
||||
}
|
||||
|
||||
int OSVideoSurface::getPitch() {
|
||||
if (!loadIfReady())
|
||||
error("Could not load resource");
|
||||
|
||||
return _ddSurface->getPitch();
|
||||
}
|
||||
|
||||
int OSVideoSurface::getBpp() {
|
||||
if (!loadIfReady())
|
||||
error("Could not load resource");
|
||||
|
||||
return getPixelDepth();
|
||||
}
|
||||
|
||||
void OSVideoSurface::recreate(int width, int height, int bpp) {
|
||||
freeSurface();
|
||||
|
||||
_screenManager->resizeSurface(this, width, height, bpp);
|
||||
if (_ddSurface)
|
||||
_videoSurfaceCounter += _ddSurface->getSize();
|
||||
}
|
||||
|
||||
void OSVideoSurface::resize(int width, int height, int bpp) {
|
||||
if (!_ddSurface || _ddSurface->getWidth() != width ||
|
||||
_ddSurface->getHeight() != height)
|
||||
recreate(width, height, bpp);
|
||||
}
|
||||
|
||||
void OSVideoSurface::detachSurface() {
|
||||
_ddSurface = nullptr;
|
||||
}
|
||||
|
||||
int OSVideoSurface::getPixelDepth() {
|
||||
if (!loadIfReady())
|
||||
error("Could not load resource");
|
||||
|
||||
lock();
|
||||
|
||||
int result = _rawSurface->format.bytesPerPixel;
|
||||
if (result == 1)
|
||||
// Paletted 8-bit images don't store the color directly in the pixels
|
||||
result = 0;
|
||||
|
||||
unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool OSVideoSurface::load() {
|
||||
if (!_resourceKey.scanForFile())
|
||||
return false;
|
||||
|
||||
switch (_resourceKey.fileTypeSuffix()) {
|
||||
case FILETYPE_IMAGE:
|
||||
switch (_resourceKey.imageTypeSuffix()) {
|
||||
case IMAGETYPE_TARGA:
|
||||
loadTarga(_resourceKey);
|
||||
break;
|
||||
case IMAGETYPE_JPEG:
|
||||
loadJPEG(_resourceKey);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
||||
case FILETYPE_MOVIE:
|
||||
loadMovie(_resourceKey);
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint16 OSVideoSurface::getPixel(const Common::Point &pt) {
|
||||
if (!loadIfReady())
|
||||
return 0;
|
||||
|
||||
if (pt.x >= 0 && pt.y >= 0 && pt.x < getWidth() && pt.y < getHeight()) {
|
||||
if (_transparencySurface) {
|
||||
// WORKAROUND: Original had the setRow _flipVertically check in reverse.
|
||||
// Pretty sure putting it the way is below is the correct way
|
||||
CTransparencySurface transSurface(&_transparencySurface->rawSurface(), _transparencyMode);
|
||||
transSurface.setRow(_flipVertically ? getHeight() - pt.y - 1 : pt.y);
|
||||
transSurface.setCol(pt.x);
|
||||
|
||||
if (transSurface.isPixelTransparent())
|
||||
return getTransparencyColor();
|
||||
}
|
||||
|
||||
lock();
|
||||
uint16 pixel = *(uint16 *)_rawSurface->getBasePtr(pt.x, pt.y);
|
||||
unlock();
|
||||
return pixel;
|
||||
} else {
|
||||
return getTransparencyColor();
|
||||
}
|
||||
}
|
||||
|
||||
void OSVideoSurface::setPixel(const Point &pt, uint pixel) {
|
||||
assert(getPixelDepth() == 2);
|
||||
|
||||
uint16 *pixelP = (uint16 *)_rawSurface->getBasePtr(pt.x, pt.y);
|
||||
*pixelP = pixel;
|
||||
}
|
||||
|
||||
void OSVideoSurface::shiftColors() {
|
||||
if (!loadIfReady())
|
||||
return;
|
||||
|
||||
// Currently no further processing is needed, since for ScummVM,
|
||||
// we already convert 16-bit surfaces as soon as they're loaded
|
||||
}
|
||||
|
||||
void OSVideoSurface::clear() {
|
||||
if (!loadIfReady())
|
||||
error("Could not load resource");
|
||||
|
||||
_ddSurface->fill(nullptr, 0);
|
||||
}
|
||||
|
||||
void OSVideoSurface::playMovie(uint flags, CGameObject *obj) {
|
||||
if (loadIfReady() && _movie)
|
||||
_movie->play(flags, obj);
|
||||
}
|
||||
|
||||
void OSVideoSurface::playMovie(uint startFrame, uint endFrame, uint flags, CGameObject *obj) {
|
||||
if (loadIfReady() && _movie) {
|
||||
_movie->play(startFrame, endFrame, flags, obj);
|
||||
_movie->pause();
|
||||
}
|
||||
}
|
||||
|
||||
void OSVideoSurface::playMovie(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) {
|
||||
if (loadIfReady() && _movie) {
|
||||
_movie->play(startFrame, endFrame, initialFrame, flags, obj);
|
||||
}
|
||||
}
|
||||
|
||||
void OSVideoSurface::stopMovie() {
|
||||
if (_movie)
|
||||
_movie->stop();
|
||||
}
|
||||
|
||||
void OSVideoSurface::setMovieFrame(uint frameNumber) {
|
||||
if (loadIfReady() && _movie)
|
||||
_movie->setFrame(frameNumber);
|
||||
}
|
||||
|
||||
void OSVideoSurface::addMovieEvent(int frameNumber, CGameObject *obj) {
|
||||
if (_movie)
|
||||
_movie->addEvent(frameNumber, obj);
|
||||
}
|
||||
|
||||
void OSVideoSurface::setMovieFrameRate(double rate) {
|
||||
if (_movie)
|
||||
_movie->setFrameRate(rate);
|
||||
}
|
||||
|
||||
const CMovieRangeInfoList *OSVideoSurface::getMovieRangeInfo() const {
|
||||
return _movie ? _movie->getMovieRangeInfo() : nullptr;
|
||||
}
|
||||
|
||||
void OSVideoSurface::flipVertically(bool needsLock) {
|
||||
if (!loadIfReady() || !_flipVertically)
|
||||
return;
|
||||
|
||||
if (needsLock)
|
||||
lock();
|
||||
|
||||
byte lineBuffer[SCREEN_WIDTH * 2];
|
||||
int pitch = getBpp() * getWidth();
|
||||
assert(pitch < (SCREEN_WIDTH * 2));
|
||||
|
||||
for (int yp = 0; yp < (_rawSurface->h / 2); ++yp) {
|
||||
byte *line1P = (byte *)_rawSurface->getBasePtr(0, yp);
|
||||
byte *line2P = (byte *)_rawSurface->getBasePtr(0, _rawSurface->h - yp - 1);
|
||||
|
||||
Common::copy(line1P, line1P + pitch, lineBuffer);
|
||||
Common::copy(line2P, line2P + pitch, line1P);
|
||||
Common::copy(lineBuffer, lineBuffer + pitch, line1P);
|
||||
}
|
||||
|
||||
_flipVertically = false;
|
||||
if (needsLock)
|
||||
unlock();
|
||||
}
|
||||
|
||||
bool OSVideoSurface::loadIfReady() {
|
||||
_videoSurfaceNum = _videoSurfaceCounter;
|
||||
|
||||
if (hasSurface()) {
|
||||
return true;
|
||||
} else if (_pendingLoad) {
|
||||
_hasFrame = true;
|
||||
load();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void OSVideoSurface::transPixelate() {
|
||||
if (!loadIfReady())
|
||||
return;
|
||||
|
||||
lock();
|
||||
Graphics::ManagedSurface *surface = _rawSurface;
|
||||
uint transColor = getTransparencyColor();
|
||||
// TODO: Check whether color is correct
|
||||
uint pixelColor = surface->format.RGBToColor(0x50, 0, 0);
|
||||
|
||||
for (int yp = 0; yp < surface->h; ++yp) {
|
||||
uint16 *pixelsP = (uint16 *)surface->getBasePtr(0, yp);
|
||||
bool bitFlag = (yp % 2) == 0;
|
||||
int replaceCtr = yp & 3;
|
||||
|
||||
for (int xp = 0; xp < surface->w; ++xp, ++pixelsP) {
|
||||
if (bitFlag && *pixelsP == transColor && replaceCtr == 0)
|
||||
*pixelsP = pixelColor;
|
||||
|
||||
bitFlag = !bitFlag;
|
||||
replaceCtr = (replaceCtr + 1) & 3;
|
||||
}
|
||||
}
|
||||
|
||||
surface->markAllDirty();
|
||||
unlock();
|
||||
}
|
||||
|
||||
Graphics::ManagedSurface *OSVideoSurface::dupMovieTransparency() const {
|
||||
return _movie ? _movie->duplicateTransparency() : nullptr;
|
||||
}
|
||||
|
||||
int OSVideoSurface::freeSurface() {
|
||||
if (!_ddSurface)
|
||||
return 0;
|
||||
int surfaceSize = _ddSurface->getSize();
|
||||
|
||||
delete _movie;
|
||||
_movie = nullptr;
|
||||
delete _ddSurface;
|
||||
_ddSurface = nullptr;
|
||||
|
||||
return surfaceSize;
|
||||
}
|
||||
|
||||
uint16 *OSVideoSurface::getBasePtr(int x, int y) {
|
||||
assert(_rawSurface);
|
||||
return (uint16 *)_rawSurface->getBasePtr(x, y);
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
544
engines/titanic/support/video_surface.h
Normal file
544
engines/titanic/support/video_surface.h
Normal file
@@ -0,0 +1,544 @@
|
||||
/* 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 TITANIC_VIDEO_SURFACE_H
|
||||
#define TITANIC_VIDEO_SURFACE_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/array.h"
|
||||
#include "graphics/managed_surface.h"
|
||||
#include "titanic/support/font.h"
|
||||
#include "titanic/support/direct_draw.h"
|
||||
#include "titanic/support/movie.h"
|
||||
#include "titanic/support/movie_range_info.h"
|
||||
#include "titanic/support/rect.h"
|
||||
#include "titanic/support/transparency_surface.h"
|
||||
#include "titanic/core/list.h"
|
||||
#include "titanic/core/resource_key.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CScreenManager;
|
||||
class CJPEGDecode;
|
||||
class CTargaDecode;
|
||||
|
||||
class CVideoSurface : public ListItem {
|
||||
friend class CJPEGDecode;
|
||||
friend class CTargaDecode;
|
||||
private:
|
||||
static byte _palette1[32][32];
|
||||
static byte _palette2[32][32];
|
||||
|
||||
/**
|
||||
* Setup the shading palettes
|
||||
*/
|
||||
static void setupPalette(byte palette[32][32], byte val);
|
||||
public:
|
||||
/**
|
||||
* Setup statics
|
||||
*/
|
||||
static void setup() {
|
||||
setupPalette(_palette1, 0xff);
|
||||
}
|
||||
private:
|
||||
/**
|
||||
* Calculates blitting bounds
|
||||
*/
|
||||
void clipBounds(Rect &srcRect, Rect &destRect, CVideoSurface *srcSurface,
|
||||
const Rect *subRect = nullptr, const Point *destPos = nullptr);
|
||||
|
||||
/**
|
||||
* Copies a rect from a given source surface
|
||||
*/
|
||||
void blitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src);
|
||||
|
||||
/**
|
||||
* Copies a rect from a given source surface and draws it vertically flipped
|
||||
*/
|
||||
void flippedBlitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src);
|
||||
|
||||
void transBlitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src, bool flipFlag);
|
||||
protected:
|
||||
static int _videoSurfaceCounter;
|
||||
protected:
|
||||
CScreenManager *_screenManager;
|
||||
Graphics::ManagedSurface *_rawSurface;
|
||||
bool _pendingLoad;
|
||||
Graphics::ManagedSurface *_transparencySurface;
|
||||
DisposeAfterUse::Flag _freeTransparencySurface;
|
||||
int _videoSurfaceNum;
|
||||
bool _hasFrame;
|
||||
int _lockCount;
|
||||
public:
|
||||
CMovie *_movie;
|
||||
DirectDrawSurface *_ddSurface;
|
||||
bool _fastBlitFlag;
|
||||
bool _flipVertically;
|
||||
CResourceKey _resourceKey;
|
||||
TransparencyMode _transparencyMode;
|
||||
public:
|
||||
CVideoSurface(CScreenManager *screenManager);
|
||||
~CVideoSurface() override;
|
||||
|
||||
/**
|
||||
* Set the underlying surface for this video surface
|
||||
*/
|
||||
void setSurface(CScreenManager *screenManager, DirectDrawSurface *surface);
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override {
|
||||
ListItem::load(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the surface with the passed resource
|
||||
*/
|
||||
virtual void loadResource(const CResourceKey &key) = 0;
|
||||
|
||||
/**
|
||||
* Loads a Targa image file specified by the resource key
|
||||
*/
|
||||
virtual void loadTarga(const CResourceKey &key) = 0;
|
||||
|
||||
/**
|
||||
* Loads a JPEG image file specified by the resource key
|
||||
*/
|
||||
virtual void loadJPEG(const CResourceKey &key) = 0;
|
||||
|
||||
/**
|
||||
* Loads a Targa image file specified by the given name
|
||||
*/
|
||||
virtual void loadTarga(const CString &name) = 0;
|
||||
|
||||
/**
|
||||
* Loads a movie file specified by the resource key.
|
||||
* @param key Resource key for movie to load
|
||||
* @param destroyFlag Immediately destroy movie after decoding first frame
|
||||
*/
|
||||
virtual void loadMovie(const CResourceKey &key, bool destroyFlag = false) = 0;
|
||||
|
||||
/**
|
||||
* Lock the surface for direct access to the pixels
|
||||
*/
|
||||
virtual bool lock() = 0;
|
||||
|
||||
/**
|
||||
* Unlocks the surface after prior calls to lock()
|
||||
*/
|
||||
virtual void unlock() = 0;
|
||||
|
||||
/**
|
||||
* Returns true if an underlying raw surface has been set
|
||||
*/
|
||||
virtual bool hasSurface() = 0;
|
||||
|
||||
/**
|
||||
* Returns the width of the surface
|
||||
*/
|
||||
virtual int getWidth() = 0;
|
||||
|
||||
/**
|
||||
* Returns the height of the surface
|
||||
*/
|
||||
virtual int getHeight() = 0;
|
||||
|
||||
/**
|
||||
* Returns the pitch of the surface in bytes
|
||||
*/
|
||||
virtual int getPitch() = 0;
|
||||
|
||||
/**
|
||||
* Returns the bytes per pixel of the surface
|
||||
*/
|
||||
virtual int getBpp() = 0;
|
||||
|
||||
/**
|
||||
* Recreates the surface
|
||||
*/
|
||||
virtual void recreate(int width, int height, int bpp = 16) = 0;
|
||||
|
||||
/**
|
||||
* Resizes the surface
|
||||
*/
|
||||
virtual void resize(int width, int height, int bpp = 16) = 0;
|
||||
|
||||
/**
|
||||
* Detachs the underlying raw surface
|
||||
*/
|
||||
virtual void detachSurface() = 0;
|
||||
|
||||
/**
|
||||
* Returns the number of bytes per pixel in the surface
|
||||
*/
|
||||
virtual int getPixelDepth() = 0;
|
||||
|
||||
/**
|
||||
* Gets the pixel at the specified position within the surface
|
||||
*/
|
||||
virtual uint16 getPixel(const Common::Point &pt) = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Sets a pixel at a specified position within the surface
|
||||
*/
|
||||
virtual void setPixel(const Point &pt, uint pixel) = 0;
|
||||
|
||||
/**
|
||||
* Shifts the colors of the surface.. maybe greys it out?
|
||||
*/
|
||||
virtual void shiftColors() = 0;
|
||||
|
||||
/**
|
||||
* Clears the entire surface to black
|
||||
*/
|
||||
virtual void clear() = 0;
|
||||
|
||||
/**
|
||||
* Plays a movie, loading it from the specified _resource
|
||||
* if not already loaded
|
||||
*/
|
||||
virtual void playMovie(uint flags, CGameObject *obj) = 0;
|
||||
|
||||
/**
|
||||
* Plays a movie, loading it from the specified _resource
|
||||
* if not already loaded
|
||||
*/
|
||||
virtual void playMovie(uint startFrame, uint endFrame, uint flags, CGameObject *obj) = 0;
|
||||
|
||||
/**
|
||||
* Plays a movie, loading it from the specified _resource
|
||||
* if not already loaded
|
||||
*/
|
||||
virtual void playMovie(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) = 0;
|
||||
|
||||
/**
|
||||
* Stops any movie currently attached to the surface
|
||||
*/
|
||||
virtual void stopMovie() = 0;
|
||||
|
||||
/**
|
||||
* Set the current movie frame number
|
||||
*/
|
||||
virtual void setMovieFrame(uint frameNumber) = 0;
|
||||
|
||||
/**
|
||||
* Adds a movie playback event
|
||||
*/
|
||||
virtual void addMovieEvent(int eventId, CGameObject *obj) = 0;
|
||||
|
||||
/**
|
||||
* Set the movie frame rate
|
||||
*/
|
||||
virtual void setMovieFrameRate(double rate) = 0;
|
||||
|
||||
/**
|
||||
* Return any movie range info associated with the surface's movie
|
||||
*/
|
||||
virtual const CMovieRangeInfoList *getMovieRangeInfo() const = 0;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
virtual void flipVertically(bool needsLock = true) = 0;
|
||||
|
||||
/**
|
||||
* Loads the surface's resource if there's one pending
|
||||
*/
|
||||
virtual bool loadIfReady() = 0;
|
||||
|
||||
/**
|
||||
* Loads the surface data based on the currently set resource key
|
||||
*/
|
||||
virtual bool load() = 0;
|
||||
|
||||
/**
|
||||
* Does a replacement of transparent pixels on certain lines at regular
|
||||
* intervals. This is totally weird
|
||||
*/
|
||||
virtual void transPixelate() = 0;
|
||||
|
||||
/**
|
||||
* Returns true if there's a frame to display on the video surface
|
||||
*/
|
||||
virtual bool hasFrame();
|
||||
|
||||
/**
|
||||
* Duplicates movie transparency surface
|
||||
*/
|
||||
virtual Graphics::ManagedSurface *dupMovieTransparency() const = 0;
|
||||
|
||||
/**
|
||||
* Frees the underlying surface
|
||||
*/
|
||||
virtual int freeSurface() { return 0; }
|
||||
|
||||
/**
|
||||
* Get a pointer into the underlying surface
|
||||
*/
|
||||
virtual uint16 *getBasePtr(int x, int y) = 0;
|
||||
|
||||
/**
|
||||
* Blit from another surface
|
||||
*/
|
||||
void blitFrom(const Point &destPos, CVideoSurface *src, const Rect *srcRect = nullptr);
|
||||
|
||||
/**
|
||||
* Blit from another surface
|
||||
*/
|
||||
void blitFrom(const Point &destPos, const Graphics::Surface *src);
|
||||
|
||||
/**
|
||||
* Sets a raw surface to use as a transparency mask for the surface
|
||||
*/
|
||||
void setTransparencySurface(Graphics::ManagedSurface *surface) { _transparencySurface = surface; }
|
||||
|
||||
/**
|
||||
* Get the previously set transparency mask surface
|
||||
*/
|
||||
const Graphics::Surface *getTransparencySurface() const {
|
||||
return _transparencySurface ? &_transparencySurface->rawSurface() : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pixels associated with the surface. Only valid when the
|
||||
* surface has been locked for access
|
||||
*/
|
||||
uint16 *getPixels() { return (uint16 *)_rawSurface->getPixels(); }
|
||||
|
||||
/**
|
||||
* Get a reference to the underlying surface. Only valid when the surface
|
||||
* has been locked for access
|
||||
*/
|
||||
Graphics::ManagedSurface *getRawSurface() { return _rawSurface; }
|
||||
|
||||
/**
|
||||
* Returns the transparent color
|
||||
*/
|
||||
uint getTransparencyColor();
|
||||
|
||||
/**
|
||||
* Copies a pixel, handling transparency
|
||||
* @param destP Dest pointer to 16-bit pixel
|
||||
* @param srcP Source pointer to 16-bit pixel
|
||||
* @param alpha Alpha (0-31). At 0, it's completely opaque,
|
||||
* and overwrites the dest pixel. Through to 31, which is completely
|
||||
* transparent, and ignores the source pixel.
|
||||
* @param srcFormat The source surface format
|
||||
* @param isAlpha If true, has alpha channel
|
||||
*/
|
||||
void copyPixel(uint16 *destP, const uint16 *srcP, byte alpha,
|
||||
const Graphics::PixelFormat &srcFormat, bool isAlpha);
|
||||
};
|
||||
|
||||
class OSVideoSurface : public CVideoSurface {
|
||||
friend class OSMovie;
|
||||
public:
|
||||
OSVideoSurface(CScreenManager *screenManager, DirectDrawSurface *surface);
|
||||
OSVideoSurface(CScreenManager *screenManager, const CResourceKey &key, bool flag = false);
|
||||
~OSVideoSurface() override;
|
||||
|
||||
/**
|
||||
* Load the surface with the passed resource
|
||||
*/
|
||||
void loadResource(const CResourceKey &key) override;
|
||||
|
||||
/**
|
||||
* Loads a Targa image file specified by the resource key
|
||||
*/
|
||||
void loadTarga(const CResourceKey &key) override;
|
||||
|
||||
/**
|
||||
* Loads a JPEG image file specified by the resource key
|
||||
*/
|
||||
void loadJPEG(const CResourceKey &key) override;
|
||||
|
||||
/**
|
||||
* Loads a Targa image file specified by the given name
|
||||
*/
|
||||
void loadTarga(const CString &name) override;
|
||||
|
||||
/**
|
||||
* Loads a movie file specified by the resource key.
|
||||
* @param key Resource key for movie to load
|
||||
* @param destroyFlag Immediately destroy movie after decoding first frame
|
||||
*/
|
||||
void loadMovie(const CResourceKey &key, bool destroyFlag = false) override;
|
||||
|
||||
/**
|
||||
* Lock the surface for direct access to the pixels
|
||||
*/
|
||||
bool lock() override;
|
||||
|
||||
/**
|
||||
* Unlocks the surface after prior calls to lock()
|
||||
*/
|
||||
void unlock() override;
|
||||
|
||||
/**
|
||||
* Returns true if an underlying raw surface has been set
|
||||
*/
|
||||
bool hasSurface() override;
|
||||
|
||||
/**
|
||||
* Returns the width of the surface
|
||||
*/
|
||||
int getWidth() override;
|
||||
|
||||
/**
|
||||
* Returns the height of the surface
|
||||
*/
|
||||
int getHeight() override;
|
||||
|
||||
/**
|
||||
* Returns the pitch of the surface in bytes
|
||||
*/
|
||||
int getPitch() override;
|
||||
|
||||
/**
|
||||
* Returns the bytes per pixel of the surface
|
||||
*/
|
||||
int getBpp() override;
|
||||
|
||||
/**
|
||||
* Recreates the surface with the designated size
|
||||
*/
|
||||
void recreate(int width, int height, int bpp = 16) override;
|
||||
|
||||
/**
|
||||
* Resizes the surface
|
||||
*/
|
||||
void resize(int width, int height, int bpp = 16) override;
|
||||
|
||||
/**
|
||||
* Detachs the underlying raw surface
|
||||
*/
|
||||
void detachSurface() override;
|
||||
|
||||
/**
|
||||
* Returns the number of bytes per pixel in the surface
|
||||
*/
|
||||
int getPixelDepth() override;
|
||||
|
||||
/**
|
||||
* Gets the pixel at the specified position within the surface
|
||||
*/
|
||||
uint16 getPixel(const Point &pt) override;
|
||||
|
||||
/**
|
||||
* Sets a pixel at a specified position within the surface
|
||||
*/
|
||||
void setPixel(const Point &pt, uint pixel) override;
|
||||
|
||||
/**
|
||||
* Shifts the colors of the surface.. maybe greys it out?
|
||||
*/
|
||||
void shiftColors() override;
|
||||
|
||||
/**
|
||||
* Clears the entire surface to black
|
||||
*/
|
||||
void clear() override;
|
||||
|
||||
/**
|
||||
* Plays a movie, loading it from the specified _resource
|
||||
* if not already loaded
|
||||
*/
|
||||
void playMovie(uint flags, CGameObject *obj) override;
|
||||
|
||||
/**
|
||||
* Plays a movie, loading it from the specified _resource
|
||||
* if not already loaded
|
||||
*/
|
||||
void playMovie(uint startFrame, uint endFrame, uint flags, CGameObject *obj) override;
|
||||
|
||||
/**
|
||||
* Plays a movie, loading it from the specified _resource
|
||||
* if not already loaded
|
||||
*/
|
||||
void playMovie(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) override;
|
||||
|
||||
/**
|
||||
* Stops any movie currently attached to the surface
|
||||
*/
|
||||
void stopMovie() override;
|
||||
|
||||
/**
|
||||
* Sets the movie to the specified frame number
|
||||
*/
|
||||
void setMovieFrame(uint frameNumber) override;
|
||||
|
||||
/**
|
||||
* Adds a movie playback event
|
||||
*/
|
||||
void addMovieEvent(int frameNumber, CGameObject *obj) override;
|
||||
|
||||
/**
|
||||
* Set the movie frame rate
|
||||
*/
|
||||
void setMovieFrameRate(double rate) override;
|
||||
|
||||
/**
|
||||
* Return any movie range info associated with the surface's movie
|
||||
*/
|
||||
const CMovieRangeInfoList *getMovieRangeInfo() const override;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void flipVertically(bool needsLock = true) override;
|
||||
|
||||
/**
|
||||
* Loads the surface's resource if there's one pending
|
||||
*/
|
||||
bool loadIfReady() override;
|
||||
|
||||
/**
|
||||
* Loads the surface data based on the currently set resource key
|
||||
*/
|
||||
bool load() override;
|
||||
|
||||
/**
|
||||
* Does a replacement of transparent pixels on certain lines at regular
|
||||
* intervals. This is totally weird
|
||||
*/
|
||||
void transPixelate() override;
|
||||
|
||||
/**
|
||||
* Duplicates movie transparency surface
|
||||
*/
|
||||
Graphics::ManagedSurface *dupMovieTransparency() const override;
|
||||
|
||||
/**
|
||||
* Frees the underlying surface
|
||||
*/
|
||||
int freeSurface() override;
|
||||
|
||||
/**
|
||||
* Get a pointer into the underlying surface
|
||||
*/
|
||||
uint16 *getBasePtr(int x, int y) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_VIDEO_SURFACE_H */
|
||||
Reference in New Issue
Block a user