From 1efbed540948edcbf3ac2c72c0984def044274cf Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 3 Apr 2016 16:16:35 -0400 Subject: TITANIC: Move most of the root classes into new support/ folder --- engines/titanic/support/direct_draw.cpp | 109 +++++++ engines/titanic/support/direct_draw.h | 105 +++++++ engines/titanic/support/direct_draw_surface.cpp | 100 ++++++ engines/titanic/support/direct_draw_surface.h | 121 ++++++++ engines/titanic/support/files_manager.cpp | 106 +++++++ engines/titanic/support/files_manager.h | 96 ++++++ engines/titanic/support/font.cpp | 70 +++++ engines/titanic/support/font.h | 64 ++++ engines/titanic/support/image.cpp | 121 ++++++++ engines/titanic/support/image.h | 82 +++++ engines/titanic/support/image_decoders.cpp | 79 +++++ engines/titanic/support/image_decoders.h | 52 ++++ engines/titanic/support/mouse_cursor.cpp | 113 +++++++ engines/titanic/support/mouse_cursor.h | 97 ++++++ engines/titanic/support/movie.cpp | 114 +++++++ engines/titanic/support/movie.h | 95 ++++++ engines/titanic/support/rect.cpp | 44 +++ engines/titanic/support/rect.h | 61 ++++ engines/titanic/support/screen_manager.cpp | 265 ++++++++++++++++ engines/titanic/support/screen_manager.h | 248 +++++++++++++++ engines/titanic/support/simple_file.cpp | 385 ++++++++++++++++++++++++ engines/titanic/support/simple_file.h | 236 +++++++++++++++ engines/titanic/support/string.cpp | 122 ++++++++ engines/titanic/support/string.h | 106 +++++++ engines/titanic/support/text_cursor.cpp | 36 +++ engines/titanic/support/text_cursor.h | 42 +++ engines/titanic/support/video_surface.cpp | 376 +++++++++++++++++++++++ engines/titanic/support/video_surface.h | 306 +++++++++++++++++++ 28 files changed, 3751 insertions(+) create mode 100644 engines/titanic/support/direct_draw.cpp create mode 100644 engines/titanic/support/direct_draw.h create mode 100644 engines/titanic/support/direct_draw_surface.cpp create mode 100644 engines/titanic/support/direct_draw_surface.h create mode 100644 engines/titanic/support/files_manager.cpp create mode 100644 engines/titanic/support/files_manager.h create mode 100644 engines/titanic/support/font.cpp create mode 100644 engines/titanic/support/font.h create mode 100644 engines/titanic/support/image.cpp create mode 100644 engines/titanic/support/image.h create mode 100644 engines/titanic/support/image_decoders.cpp create mode 100644 engines/titanic/support/image_decoders.h create mode 100644 engines/titanic/support/mouse_cursor.cpp create mode 100644 engines/titanic/support/mouse_cursor.h create mode 100644 engines/titanic/support/movie.cpp create mode 100644 engines/titanic/support/movie.h create mode 100644 engines/titanic/support/rect.cpp create mode 100644 engines/titanic/support/rect.h create mode 100644 engines/titanic/support/screen_manager.cpp create mode 100644 engines/titanic/support/screen_manager.h create mode 100644 engines/titanic/support/simple_file.cpp create mode 100644 engines/titanic/support/simple_file.h create mode 100644 engines/titanic/support/string.cpp create mode 100644 engines/titanic/support/string.h create mode 100644 engines/titanic/support/text_cursor.cpp create mode 100644 engines/titanic/support/text_cursor.h create mode 100644 engines/titanic/support/video_surface.cpp create mode 100644 engines/titanic/support/video_surface.h (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/direct_draw.cpp b/engines/titanic/support/direct_draw.cpp new file mode 100644 index 0000000000..5ddb25bec9 --- /dev/null +++ b/engines/titanic/support/direct_draw.cpp @@ -0,0 +1,109 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/debug.h" +#include "engines/util.h" +#include "graphics/pixelformat.h" +#include "titanic/titanic.h" +#include "titanic/support/direct_draw.h" + +namespace Titanic { + +DirectDraw::DirectDraw(TitanicEngine *vm) : _vm(vm), + _windowed(false), _fieldC(0), _width(0), _height(0), + _bpp(0), _numBackSurfaces(0), _field24(0) { +} + +void DirectDraw::setDisplayMode(int width, int height, int bpp, int refreshRate) { + debugC(ERROR_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, true, &pixelFormat); +} + +void DirectDraw::diagnostics() { + debugC(ERROR_BASIC, kDebugGraphics, "Running DirectDraw Diagnostic..."); +} + +DirectDrawSurface *DirectDraw::createSurfaceFromDesc(const DDSurfaceDesc &desc) { + DirectDrawSurface *surface = new DirectDrawSurface(); + surface->create(desc._w, desc._h); + + return surface; +} + +/*------------------------------------------------------------------------*/ + +DirectDrawManager::DirectDrawManager(TitanicEngine *vm, bool windowed) : _directDraw(vm) { + _mainSurface = nullptr; + _backSurfaces[0] = _backSurfaces[1] = nullptr; + _directDraw._windowed = windowed; +} + +void DirectDrawManager::initVideo(int width, int height, int bpp, int numBackSurfaces) { + debugC(ERROR_BASIC, kDebugGraphics, "Initialising video surfaces"); + _directDraw._width = width; + _directDraw._numBackSurfaces = numBackSurfaces; + _directDraw._height = height; + _directDraw._bpp = bpp; + + if (_directDraw._windowed) { + initWindowed(); + } else { + initFullScreen(); + } +} + +void DirectDrawManager::setResolution() { + // TODO +} + +void DirectDrawManager::proc2() { + +} + +void DirectDrawManager::proc3() { + +} + +void DirectDrawManager::initFullScreen() { + debugC(ERROR_BASIC, kDebugGraphics, "Creating surfaces"); + _directDraw.setDisplayMode(_directDraw._width, _directDraw._height, + _directDraw._bpp, 0); + + _mainSurface = new DirectDrawSurface(); + _mainSurface->create(g_vm->_screen); + _backSurfaces[0] = new DirectDrawSurface(); + _backSurfaces[0]->create(_directDraw._width, _directDraw._height); +} + +DirectDrawSurface *DirectDrawManager::createSurface(int w, int h, int surfaceNum) { + if (surfaceNum) + return nullptr; + + assert(_mainSurface); + return _directDraw.createSurfaceFromDesc(DDSurfaceDesc(w, h)); +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/direct_draw.h b/engines/titanic/support/direct_draw.h new file mode 100644 index 0000000000..85c344c600 --- /dev/null +++ b/engines/titanic/support/direct_draw.h @@ -0,0 +1,105 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef 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 { +private: + TitanicEngine *_vm; +public: + bool _windowed; + int _fieldC; + int _width; + int _height; + int _bpp; + int _numBackSurfaces; + int _field24; +public: + DirectDraw(TitanicEngine *vm); + + /** + * 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); + + void setResolution(); + + void proc2(); + + void proc3(); + + /** + * 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 surfaceNum); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_DIRECT_DRAW_H */ diff --git a/engines/titanic/support/direct_draw_surface.cpp b/engines/titanic/support/direct_draw_surface.cpp new file mode 100644 index 0000000000..9ebda15b0e --- /dev/null +++ b/engines/titanic/support/direct_draw_surface.cpp @@ -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 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "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) { + Graphics::PixelFormat 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 diff --git a/engines/titanic/support/direct_draw_surface.h b/engines/titanic/support/direct_draw_surface.h new file mode 100644 index 0000000000..12848b125d --- /dev/null +++ b/engines/titanic/support/direct_draw_surface.h @@ -0,0 +1,121 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef 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 _flags; + int _caps; + + DDSurfaceDesc(int w, int h) : _w(w), _h(h), _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); + + /** + * 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; } + + /** + * 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 */ diff --git a/engines/titanic/support/files_manager.cpp b/engines/titanic/support/files_manager.cpp new file mode 100644 index 0000000000..179d77f24f --- /dev/null +++ b/engines/titanic/support/files_manager.cpp @@ -0,0 +1,106 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/file.h" +#include "titanic/support/files_manager.h" +#include "titanic/game_manager.h" + +namespace Titanic { + +CFilesManager::CFilesManager() : _gameManager(nullptr), + _assetsPath("Assets"), _exeResources(nullptr), _field0(0), + _drive(-1), _field18(0), _field1C(0), _field3C(0) { +} + +CFilesManager::~CFilesManager() { + delete _exeResources; +} + +bool CFilesManager::fileExists(const CString &name) { + Common::File f; + return f.exists(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"; + } + + if (_gameManager) + _gameManager->viewChange(); + + // The original had a bunch of code here handling determining + // which asset path, if any, the filename was present for, + // and storing the "active asset path" it was found on. + // This is redundant for ScummVM, which takes care of the paths + return fileExists(fname); +} + +void CFilesManager::loadDrive() { + assert(_drive == -1); + resetView(); +} + +void CFilesManager::debug(CScreenManager *screenManager) { + warning("TODO: CFilesManager::debug"); +} + +void CFilesManager::resetView() { + if (_gameManager) { + _gameManager->_gameState.setMode(GSMODE_SELECTED); + _gameManager->initBounds(); + } +} + +void CFilesManager::fn4(const CString &name) { + warning("TODO: CFilesManager::fn4"); +} + +void CFilesManager::fn5(const CString &name) { + warning("TODO: CFilesManager::fn5"); +} + +Common::SeekableReadStream *CFilesManager::getResource(const CString &name, + const CString &area) { + if (!_exeResources) { + _exeResources = new Common::NEResources(); + _exeResources->loadFromEXE("st.exe"); + } + + return nullptr; +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/files_manager.h b/engines/titanic/support/files_manager.h new file mode 100644 index 0000000000..7915149412 --- /dev/null +++ b/engines/titanic/support/files_manager.h @@ -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 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_FILES_MANAGER_H +#define TITANIC_FILES_MANAGER_H + +#include "common/winexe_ne.h" +#include "titanic/core/list.h" +#include "titanic/support/screen_manager.h" + +namespace Titanic { + +class CGameManager; + +class CFilesManagerList : public List { +}; + +class CFilesManager { +private: + CGameManager *_gameManager; + Common::NEResources *_exeResources; + CFilesManagerList _list; + CString _string1; + CString _string2; + int _field0; + int _drive; + int _field18; + int _field1C; + int _field3C; + const CString _assetsPath; +public: + CFilesManager(); + ~CFilesManager(); + + /** + * 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(); + + void debug(CScreenManager *screenManager); + + /** + * Resets the view being displayed + */ + void resetView(); + + void fn4(const CString &name); + + void fn5(const CString &name); + + /** + * Get a resource from the executable + */ + Common::SeekableReadStream *getResource(const CString &name, + const CString &area); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FILES_MANAGER_H */ diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp new file mode 100644 index 0000000000..6862baf79f --- /dev/null +++ b/engines/titanic/support/font.cpp @@ -0,0 +1,70 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/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; + _field8 = 0; + _maxCharWidth = 0; + _field810 = 0; + _field814 = 0; + _field818 = 0; +} + +STFont::~STFont() { + delete[] _dataPtr; +} + +void STFont::load(int fontNumber) { + assert(!_dataPtr); + CString fontNumStr = CString::format("%d", fontNumber); + Common::SeekableReadStream *stream = g_vm->_filesManager.getResource( + fontNumStr, "STFont"); + if (!stream) + return; + + _field8 = stream->readUint32LE(); + _maxCharWidth = stream->readUint32LE(); + for (uint idx = 0; idx < 256; ++idx) + _chars[idx]._charWidth = 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::writeString(int maxWidth, const CString &text, int *v1, int *v2) { + warning("TODO: STFont::writeString"); +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/font.h b/engines/titanic/support/font.h new file mode 100644 index 0000000000..0fff5125df --- /dev/null +++ b/engines/titanic/support/font.h @@ -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 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_FONT_H +#define TITANIC_FONT_H + +#include "common/scummsys.h" +#include "common/array.h" +#include "titanic/support/string.h" + +namespace Titanic { + +class STFont { + struct CharEntry { + uint _charWidth; + uint _offset; + }; +public: + byte *_dataPtr; + size_t _dataSize; + int _field8; + int _maxCharWidth; + Common::Array _chars; + int _field810; + int _field814; + int _field818; +public: + STFont(); + ~STFont(); + + /** + * Load a specified font + */ + void load(int fontNumber); + + /** + * Write out a string + * TODO: Verify this + */ + void writeString(int maxWidth, const CString &text, int *v1, int *v2); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FONT_H */ diff --git a/engines/titanic/support/image.cpp b/engines/titanic/support/image.cpp new file mode 100644 index 0000000000..cabdd64cf3 --- /dev/null +++ b/engines/titanic/support/image.cpp @@ -0,0 +1,121 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/file.h" +#include "titanic/support/image.h" + +namespace Titanic { + +BITMAPINFOHEADER::BITMAPINFOHEADER() { + _biSize = 0; + _biWidth = 0; + _biHeight = 0; + _biPlanes = 0; + _biBitCount = 0; + _biCompression = 0; + _biSizeImage = 0; + _biXPelsPerMeter = 0; + _biYPelsPerMeter = 0; + _biClrUsed = 0; + _biClrImportant = 0; +} + +/*------------------------------------------------------------------------*/ + +RGBQuad::RGBQuad() : _rgbRed(0), _rgbGreen(0), _rgbBlue(0), _rgbReserved(0) {} + +/*------------------------------------------------------------------------*/ + +Image::Image() { + _bitmapInfo = nullptr; + _bits = nullptr; + _flag = true; + + set(16, 16); +} + +void Image::proc6() { + +} + +void Image::set(int width, int height) { + delete _bitmapInfo; + if (_flag && _bitmapInfo) + delete[] _bits; + + _bitmapInfo = new tagBITMAPINFO; + _bits = new byte[(width + 3) & 0xFFFC * height]; + + tagBITMAPINFO &bi = *_bitmapInfo; + bi._bmiHeader._biWidth = width; + bi._bmiHeader._biHeight = height; + bi._bmiHeader._biPlanes = 1; + bi._bmiHeader._biBitCount = 8; +} + +void Image::proc8() { + +} + +bool Image::loadResource(const Common::String &name) { + // This method is hardcoded for the Titanic splash screen resource + assert(name == "TITANIC"); + + Common::File f; + if (!f.open("ST.exe")) + return false; + + // The ST.exe executable has a bitmap called "TITANIC". Since we can't use + // the Windows FindResource function in ScummVM, this is hardcoded for now + f.seek(0x29B660); + uint size = f.readUint32LE(); + if (size != 40) + return false; + + loadBitmap(f); + + return true; +} + +void Image::proc10() { + +} + +void Image::draw() { + +} + +void Image::loadBitmap(Common::SeekableReadStream &s) { + _bitmapInfo->_bmiHeader._biWidth = s.readUint32LE(); + _bitmapInfo->_bmiHeader._biHeight = s.readUint32LE(); + _bitmapInfo->_bmiHeader._biPlanes = s.readUint16LE(); + _bitmapInfo->_bmiHeader._biBitCount = s.readUint16LE(); + _bitmapInfo->_bmiHeader._biCompression = s.readUint32LE(); + _bitmapInfo->_bmiHeader._biSizeImage = s.readUint32LE(); + _bitmapInfo->_bmiHeader._biXPelsPerMeter = s.readUint32LE(); + _bitmapInfo->_bmiHeader._biYPelsPerMeter = s.readUint32LE(); + _bitmapInfo->_bmiHeader._biClrUsed = s.readUint32LE(); + _bitmapInfo->_bmiHeader._biClrImportant = s.readUint32LE(); + +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/image.h b/engines/titanic/support/image.h new file mode 100644 index 0000000000..9030e81ad7 --- /dev/null +++ b/engines/titanic/support/image.h @@ -0,0 +1,82 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_IMAGE_H +#define TITANIC_IMAGE_H + +#include "common/scummsys.h" +#include "common/array.h" + +namespace Titanic { + +struct BITMAPINFOHEADER { + int _biSize; + int _biWidth; + int _biHeight; + int _biPlanes; + int _biBitCount; + int _biCompression; + int _biSizeImage; + int _biXPelsPerMeter; + int _biYPelsPerMeter; + int _biClrUsed; + int _biClrImportant; + + BITMAPINFOHEADER(); +}; + +struct RGBQuad { + byte _rgbRed; + byte _rgbGreen; + byte _rgbBlue; + byte _rgbReserved; + + RGBQuad(); +}; + +struct tagBITMAPINFO { + BITMAPINFOHEADER _bmiHeader; + RGBQuad _bmiColors[256]; +}; + +class Image { +private: + void loadBitmap(Common::SeekableReadStream &s); +public: + tagBITMAPINFO *_bitmapInfo; + byte *_bits; + bool _flag; +public: + Image(); + virtual ~Image() {} + + virtual void proc6(); + virtual void set(int width, int height); + virtual void proc8(); + virtual bool loadResource(const Common::String &name); + virtual void proc10(); + virtual void draw(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_IMAGE_H */ diff --git a/engines/titanic/support/image_decoders.cpp b/engines/titanic/support/image_decoders.cpp new file mode 100644 index 0000000000..9fe55eb02b --- /dev/null +++ b/engines/titanic/support/image_decoders.cpp @@ -0,0 +1,79 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "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 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.resize(srcSurf->w, srcSurf->h); + + // 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()); + + delete convertedSurface; + 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.resize(srcSurf->w, srcSurf->h); + + // 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()); + + delete convertedSurface; + surface.unlock(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/image_decoders.h b/engines/titanic/support/image_decoders.h new file mode 100644 index 0000000000..b824b786a7 --- /dev/null +++ b/engines/titanic/support/image_decoders.h @@ -0,0 +1,52 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef 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 */ diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp new file mode 100644 index 0000000000..dda16c3b93 --- /dev/null +++ b/engines/titanic/support/mouse_cursor.cpp @@ -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 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "graphics/cursorman.h" +#include "common/textconsole.h" +#include "titanic/support/mouse_cursor.h" +#include "titanic/support/movie.h" +#include "titanic/support/screen_manager.h" +#include "titanic/titanic.h" +#include "titanic/support/video_surface.h" +#include "titanic/core/resource_key.h" + +namespace Titanic { + +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::CMouseCursor(CScreenManager *screenManager) : + _screenManager(screenManager), _cursorId(CURSOR_15) { + loadCursorImages(); + setCursor(CURSOR_1); +} + +CMouseCursor::~CMouseCursor() { + for (int idx = 0; idx < NUM_CURSORS; ++idx) + delete _cursors[idx]._videoSurface; +} + +void CMouseCursor::loadCursorImages() { + const CString name("ycursors.avi"); + const CResourceKey key(name); + g_vm->_filesManager.fn4(name); + + // Iterate through 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]); + + CVideoSurface *surface = _screenManager->createSurface(64, 64); + _cursors[idx]._videoSurface = surface; + + OSMovie movie(key, surface); + movie.setFrame(idx); + _cursors[idx]._ptrUnknown = movie.proc21(); + surface->set40(_cursors[idx]._ptrUnknown); + } +} + +void CMouseCursor::show() { + CursorMan.showMouse(true); +} + +void CMouseCursor::hide() { + CursorMan.showMouse(false); +} + +void CMouseCursor::setCursor(CursorId cursorId) { + if (cursorId != _cursorId) { + CursorEntry &ce = _cursors[cursorId - 1]; + CVideoSurface &surface = *ce._videoSurface; + surface.lock(); + + // ***DEBUG*** Dummy cursor + Common::fill(surface.getPixels(), surface.getPixels() + 128, 0x5555); + + CursorMan.replaceCursor(surface.getPixels(), surface.getWidth(), surface.getHeight(), + ce._centroid.x, ce._centroid.y, 0, false, &g_vm->_screen->format); + surface.unlock(); + + _cursorId = cursorId; + } +} + +void CMouseCursor::update() { + // No implementation needed +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/mouse_cursor.h b/engines/titanic/support/mouse_cursor.h new file mode 100644 index 0000000000..507f4ecc17 --- /dev/null +++ b/engines/titanic/support/mouse_cursor.h @@ -0,0 +1,97 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_MOUSE_CURSOR_H +#define TITANIC_MOUSE_CURSOR_H + +#include "common/scummsys.h" +#include "common/rect.h" + +namespace Titanic { + +#define NUM_CURSORS 15 + +enum CursorId { + CURSOR_1 = 1, + CURSOR_2 = 3, + CURSOR_3 = 3, + CURSOR_4 = 4, + CURSOR_5 = 5, + CURSOR_6 = 6, + CURSOR_7 = 7, + CURSOR_8 = 8, + CURSOR_9 = 9, + CURSOR_10 = 10, + CURSOR_11 = 11, + CURSOR_12 = 12, + CURSOR_13 = 13, + CURSOR_14 = 14, + CURSOR_15 = 15 +}; + +class CScreenManager; +class CVideoSurface; + +class CMouseCursor { + struct CursorEntry { + CVideoSurface *_videoSurface; + void *_ptrUnknown; + Common::Point _centroid; + }; +private: + CScreenManager *_screenManager; + CursorId _cursorId; + CursorEntry _cursors[NUM_CURSORS]; + + /** + * Load the images for each cursor + */ + void loadCursorImages(); +public: + CMouseCursor(CScreenManager *screenManager); + ~CMouseCursor(); + + /** + * Make the mouse cursor visible + */ + void show(); + + /** + * Hide the mouse cursor + */ + void hide(); + + /** + * Set the cursor + */ + void setCursor(CursorId cursorId); + + /** + * Updates the mouse cursor + */ + void update(); +}; + + +} // End of namespace Titanic + +#endif /* TITANIC_MOUSE_CURSOR_H */ diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp new file mode 100644 index 0000000000..ed5cffaac1 --- /dev/null +++ b/engines/titanic/support/movie.cpp @@ -0,0 +1,114 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "titanic/support/movie.h" +#include "titanic/titanic.h" + +namespace Titanic { + +CMovie::CMovie() : ListItem(), _state(0), _field10(0) { +} + +bool CMovie::isActive() const { + return g_vm->_movieList.contains(this); +} + +bool CMovie::get10() { + if (_field10) { + _field10 = 0; + return true; + } else { + return false; + } +} + +/*------------------------------------------------------------------------*/ + +OSMovie::OSMovie(const CResourceKey &name, CVideoSurface *surface) : _videoSurface(surface) { +// _aviDecoder.loadFile(name.getString()); +} + +void OSMovie::proc8(int v1, CVideoSurface *surface) { + warning("TODO: OSMovie::proc8"); +} + +void OSMovie::proc9() { + warning("TODO: OSMovie::proc9"); +} + +void OSMovie::proc10() { + warning("TODO: OSMovie::proc10"); +} + +void OSMovie::proc11() { + warning("TODO: OSMovie::proc11"); +} + +void OSMovie::proc12() { + warning("TODO: OSMovie::proc12"); +} + +void OSMovie::stop() { + warning("TODO: OSMovie::proc13"); +} + +void OSMovie::proc14() { + warning("TODO: OSMovie::proc14"); +} + +void OSMovie::setFrame(uint frameNumber) { + warning("TODO: OSMovie::setFrame"); + /* + _aviDecoder.seekToFrame(frameNumber); + const Graphics::Surface *s = _aviDecoder.decodeNextFrame(); + + _videoSurface->blitFrom(Common::Point(0, 0), s); + */ +} + +void OSMovie::proc16() { + warning("TODO: OSMovie::proc16"); +} + +void OSMovie::proc17() { + warning("TODO: OSMovie::proc17"); +} + +void OSMovie::proc18() { + warning("TODO: OSMovie::proc18"); +} + +int OSMovie::proc19() { + warning("TODO: OSMovie::proc19"); + return 0; +} + +void OSMovie::proc20() { + warning("TODO: OSMovie::proc20"); +} + +void *OSMovie::proc21() { + warning("TODO: OSMovie::proc21"); + return nullptr; +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h new file mode 100644 index 0000000000..3529409fa5 --- /dev/null +++ b/engines/titanic/support/movie.h @@ -0,0 +1,95 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_MOVIE_H +#define TITANIC_MOVIE_H + +#include "video/avi_decoder.h" +#include "titanic/core/list.h" +#include "titanic/core/resource_key.h" + +namespace Titanic { + +class CVideoSurface; + +class CMovie : public ListItem { +protected: + int _state; + int _field10; +public: + CMovie(); + + virtual void proc8(int v1, CVideoSurface *surface) = 0; + virtual void proc9() = 0; + virtual void proc10() = 0; + virtual void proc11() = 0; + virtual void proc12() = 0; + virtual void stop() = 0; + virtual void proc14() = 0; + virtual void setFrame(uint frameNumber) = 0; + virtual void proc16() = 0; + virtual void proc17() = 0; + virtual void proc18() = 0; + virtual int proc19() = 0; + virtual void proc20() = 0; + virtual void *proc21() = 0; + + bool isActive() const; + + bool get10(); +}; + +class OSMovie : public CMovie { +private: + Video::AVIDecoder _aviDecoder; + CVideoSurface *_videoSurface; +public: + OSMovie(const CResourceKey &name, CVideoSurface *surface); + + virtual void proc8(int v1, CVideoSurface *surface); + virtual void proc9(); + virtual void proc10(); + virtual void proc11(); + virtual void proc12(); + virtual void stop(); + virtual void proc14(); + + /** + * Set the current frame number + */ + virtual void setFrame(uint frameNumber); + + virtual void proc16(); + virtual void proc17(); + virtual void proc18(); + virtual int proc19(); + virtual void proc20(); + virtual void *proc21(); +}; + +class CGlobalMovies : public List { +public: +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MOVIE_H */ diff --git a/engines/titanic/support/rect.cpp b/engines/titanic/support/rect.cpp new file mode 100644 index 0000000000..5fce4402cb --- /dev/null +++ b/engines/titanic/support/rect.cpp @@ -0,0 +1,44 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "titanic/support/rect.h" + +namespace Titanic { + +void Rect::combine(const Rect &r) { + if (isEmpty() || r.isEmpty()) + return; + + Common::Rect::extend(r); +} + +void Rect::constrain(const Rect &r) { + if (!isEmpty()) { + if (r.isEmpty()) { + clear(); + } else { + Common::Rect::clip(r); + } + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/rect.h b/engines/titanic/support/rect.h new file mode 100644 index 0000000000..1661711870 --- /dev/null +++ b/engines/titanic/support/rect.h @@ -0,0 +1,61 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_RECT_H +#define TITANIC_RECT_H + +#include "common/rect.h" + +namespace Titanic { + +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 const 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); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_RECT_H */ diff --git a/engines/titanic/support/screen_manager.cpp b/engines/titanic/support/screen_manager.cpp new file mode 100644 index 0000000000..05dfa66854 --- /dev/null +++ b/engines/titanic/support/screen_manager.cpp @@ -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 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "titanic/support/screen_manager.h" +#include "titanic/titanic.h" +#include "titanic/support/video_surface.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; + // TODO: Further initialization + + _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; +} + +/*------------------------------------------------------------------------*/ + +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() { + warning("OSScreenManager::drawCursors"); +} + +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; +} + +void OSScreenManager::proc6() {} +void OSScreenManager::proc7() {} + +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::proc9() {} + +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; + } + + 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; + + if (surfaceNum >= 0 && !_backSurfaces[surfaceNum]._bounds.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(_backSurfaces[surfaceNum]._bounds); + + 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::proc12() {} +void OSScreenManager::proc13() {} +void OSScreenManager::proc14() {} +void OSScreenManager::proc15() {} + +void OSScreenManager::writeString(int maxWidth, const CString &text, int *v1, int *v2) { + _fonts[_fontNumber].writeString(maxWidth, text, v1, v2); +} + +void OSScreenManager::getFont() {} +void OSScreenManager::proc18() {} +void OSScreenManager::proc19() {} + +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) { + DirectDrawSurface *ddSurface = _directDrawManager.createSurface(width, height, 0); + surface->setSurface(this, ddSurface); +} + +CVideoSurface *OSScreenManager::createSurface(int w, int h) { + DirectDrawSurface *ddSurface = _directDrawManager.createSurface(w, h, 0); + return new OSVideoSurface(this, ddSurface); +} + +CVideoSurface *OSScreenManager::createSurface(const CResourceKey &key) { + return new OSVideoSurface(this, key); +} + +void OSScreenManager::proc23() {} +void OSScreenManager::proc24() {} +void OSScreenManager::proc25() {} + +void OSScreenManager::showCursor() { + +} + +void OSScreenManager::hideCursor() { + +} + +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); + showCursor(); + + if (!_textCursor) { + _textCursor = new CTextCursor(); + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/screen_manager.h b/engines/titanic/support/screen_manager.h new file mode 100644 index 0000000000..affe2ec0c9 --- /dev/null +++ b/engines/titanic/support/screen_manager.h @@ -0,0 +1,248 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef 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_BACKBUFFER = -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 _backSurfaces; + 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; + + virtual void proc6() = 0; + virtual void proc7() = 0; + virtual CVideoSurface *getSurface(SurfaceNum surfaceNum) const = 0; + virtual void proc9() = 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; + + virtual void proc12() = 0; + virtual void proc13() = 0; + virtual void proc14() = 0; + virtual void proc15() = 0; + + + /** + * Write out a string + */ + virtual void writeString(int maxWidth, const CString &text, int *v1, int *v2) = 0; + + virtual void getFont() = 0; + virtual void proc18() = 0; + virtual void proc19() = 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) = 0; + + /** + * Creates a surface of a given size + */ + virtual CVideoSurface *createSurface(int w, int h) = 0; + + /** + * Creates a surface from a specified resource + */ + virtual CVideoSurface *createSurface(const CResourceKey &key) = 0; + + virtual void proc24() = 0; + virtual void proc25() = 0; + virtual void showCursor() = 0; + virtual void hideCursor() = 0; + + void setSurfaceBounds(SurfaceNum surfaceNum, const Rect &r); +}; + +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); + virtual ~OSScreenManager(); + + /** + * Sets the video mode + */ + virtual void setMode(int width, int height, int bpp, uint numBackSurfaces, bool flag2); + + /** + * Handles drawing the cursors + */ + virtual void drawCursors(); + + virtual void proc6(); + virtual void proc7(); + virtual CVideoSurface *getSurface(SurfaceNum surfaceNum) const; + virtual void proc9(); + + /** + * Fill an area with a specific color + */ + virtual void fillRect(SurfaceNum surfaceNum, Rect *rect, byte r, byte g, byte b); + + /** + * Blits a surface onto one of the screen surfaces + */ + virtual void blitFrom(SurfaceNum surfaceNum, CVideoSurface *src, const Point *destPos, + const Rect *srcRect = nullptr); + + virtual void proc12(); + virtual void proc13(); + virtual void proc14(); + virtual void proc15(); + + /** + * Write out a string + */ + virtual void writeString(int maxWidth, const CString &text, int *v1, int *v2); + + virtual void getFont(); + virtual void proc18(); + virtual void proc19(); + + /** + * Clear a portion of the screen surface + */ + virtual void clearSurface(SurfaceNum surfaceNum, Rect *bounds); + + /** + * Resize the passed surface + */ + virtual void resizeSurface(CVideoSurface *surface, int width, int height); + + /** + * Creates a surface of a given size + */ + virtual CVideoSurface *createSurface(int w, int h); + + /** + * Creates a surface from a specified resource + */ + virtual CVideoSurface *createSurface(const CResourceKey &key); + + virtual void proc23(); + virtual void proc24(); + virtual void proc25(); + virtual void showCursor(); + virtual void hideCursor(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SCREEN_MANAGER_H */ diff --git a/engines/titanic/support/simple_file.cpp b/engines/titanic/support/simple_file.cpp new file mode 100644 index 0000000000..fccf6c5b4f --- /dev/null +++ b/engines/titanic/support/simple_file.cpp @@ -0,0 +1,385 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/util.h" +#include "titanic/support/simple_file.h" + +namespace Titanic { + +bool File::open(const Common::String &name) { + if (!Common::File::open(name)) + error("Could not open file - %s", name.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) { + assert(_outStream); + return _outStream->write(src, count); +} + +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; +} + +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::writeLine(const CString &str) { + write(str.c_str(), str.size()); + write("\r\n", 2); +} + +void SimpleFile::writeString(const CString &str) { + 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) { + write("\"", 1); + writeString(str); + write("\" ", 2); +} + +void SimpleFile::writeQuotedLine(const CString &str, int indent) { + writeIndent(indent); + writeQuotedString(str); + write("\n", 1); +} + +void SimpleFile::writeNumber(int val) { + CString str = CString::format("%d ", val); + write(str.c_str(), str.size()); +} + +void SimpleFile::writeNumberLine(int val, int indent) { + writeIndent(indent); + writeNumber(val); + write("\n", 1); +} + +void SimpleFile::writeFloat(double val) { + Common::String valStr = Common::String::format("%f ", val); + write(valStr.c_str(), valStr.size()); +} + +void SimpleFile::writeFloatLine(double val, int indent) { + writeIndent(indent); + writeFloat(val); + write("\n", 1); +} + +void SimpleFile::writePoint(const Point &pt, int indent) { + writeIndent(indent); + writeNumber(pt.x); + writeNumber(pt.y); + write("\n", 1); +} + +void SimpleFile::writeRect(const Rect &r, int indent) { + writePoint(Point(r.left, r.top), indent); + writePoint(Point(r.right, r.bottom), indent); +} + +void SimpleFile::writeIndent(uint indent) { + 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); +} + +/*------------------------------------------------------------------------*/ + +void StdCWadFile::open(const CString &name) { + File f; + + // 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()); + f.open(name); + + SimpleFile::open(f.readStream(f.size())); + return; + } + + // Split up the name and resource, and get the resource index + CString filename = 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 + f.open(filename); + 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(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/simple_file.h b/engines/titanic/support/simple_file.h new file mode 100644 index 0000000000..0ba7699088 --- /dev/null +++ b/engines/titanic/support/simple_file.h @@ -0,0 +1,236 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef 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/zlib.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: + virtual bool open(const Common::String &name); +}; + +/** + * This class implements basic reading and writing to files + */ +class SimpleFile { +protected: + Common::SeekableReadStream *_inStream; + Common::OutSaveFile *_outStream; + int _lineCount; +public: + SimpleFile(); + virtual ~SimpleFile(); + + /** + * 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); + + /** + * 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(); + + /** + * Read a string and copy it into an optionally passed buffer + */ + void readBuffer(char *buffer = nullptr, size_t count = 0); + + /** + * Write a string line + */ + void writeLine(const CString &str); + + /** + * Write a string + */ + void writeString(const CString &str); + + /** + * Write a quoted string + */ + void writeQuotedString(const CString &str); + + /** + * Write a quoted string line + */ + void writeQuotedLine(const CString &str, int indent); + + /** + * Write a number to file + */ + void writeNumber(int val); + + /** + * Write a number line to file + */ + void writeNumberLine(int val, int indent); + + /** + * Write a floating point number + */ + void writeFloat(double val); + + /** + * Write a floating point number as a line + */ + void writeFloatLine(double val, int indent); + + /** + * Write out a point line + */ + void writePoint(const Point &pt, int indent); + + /** + * Write out a rect line + */ + void writeRect(const Rect &r, int indent); + + /** + * Write out a number of tabs to form an indent in the output + */ + void writeIndent(uint indent); + + /** + * 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); +}; + +/** + * Derived file that handles compressed files + */ +class CompressedFile : public SimpleFile { +public: + CompressedFile() : SimpleFile() {} + virtual ~CompressedFile() {} + + /** + * Set up a stream for read access + */ + virtual void open(Common::SeekableReadStream *stream) { + SimpleFile::open(Common::wrapCompressedReadStream(stream)); + } + + /** + * Set up a stream for write access + */ + virtual void open(Common::OutSaveFile *stream) { + SimpleFile::open(Common::wrapCompressedWriteStream(stream)); + } +}; + +/** + * Derived file that handles WAD archives containing multiple files + */ +class StdCWadFile : public SimpleFile { +public: + StdCWadFile() : SimpleFile() {} + virtual ~StdCWadFile() {} + + /** + * Open up the specified file + */ + void open(const CString &name); + + /** + * Return a reference to the read stream + */ + Common::SeekableReadStream *readStream() const { return _inStream; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_SIMPLE_FILE_H */ diff --git a/engines/titanic/support/string.cpp b/engines/titanic/support/string.cpp new file mode 100644 index 0000000000..86dc0be0b0 --- /dev/null +++ b/engines/titanic/support/string.cpp @@ -0,0 +1,122 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/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() { + char buffer[16]; + itoa(val, buffer, 10); + *this += buffer; +} + +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); +} + +int CString::indexOf(char c) const { + const char *charP = strchr(c_str(), c); + return charP ? charP - c_str() : -1; +} + +int CString::lastIndexOf(char c) const { + const char *charP = strrchr(c_str(), c); + return charP ? charP - c_str() : -1; +} + +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; +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/string.h b/engines/titanic/support/string.h new file mode 100644 index 0000000000..02775de067 --- /dev/null +++ b/engines/titanic/support/string.h @@ -0,0 +1,106 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_STRING_H +#define TITANIC_STRING_H + +#include "common/scummsys.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); + + /** + * 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 the index of the first occurance of a given character + */ + int indexOf(char c) const; + + /** + * Returns the index of the last occurance of a given character + */ + int lastIndexOf(char c) 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, ...); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_STRING_H */ diff --git a/engines/titanic/support/text_cursor.cpp b/engines/titanic/support/text_cursor.cpp new file mode 100644 index 0000000000..fd0c1d22dd --- /dev/null +++ b/engines/titanic/support/text_cursor.cpp @@ -0,0 +1,36 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/textconsole.h" +#include "titanic/support/text_cursor.h" + +namespace Titanic { + +CTextCursor::CTextCursor() : _active(false) { +} + +Rect CTextCursor::getBounds() { + warning("CTextCursor::getBounds"); + return Rect(); +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/text_cursor.h b/engines/titanic/support/text_cursor.h new file mode 100644 index 0000000000..b6480673eb --- /dev/null +++ b/engines/titanic/support/text_cursor.h @@ -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 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_TEXT_CURSOR_H +#define TITANIC_TEXT_CURSOR_H + +#include "common/scummsys.h" +#include "titanic/support/rect.h" + +namespace Titanic { + +class CTextCursor { +public: + bool _active; +public: + CTextCursor(); + + Rect getBounds(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TEXT_CURSOR_H */ diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp new file mode 100644 index 0000000000..6bba24de5f --- /dev/null +++ b/engines/titanic/support/video_surface.cpp @@ -0,0 +1,376 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "titanic/support/video_surface.h" +#include "titanic/support/image_decoders.h" +#include "titanic/support/screen_manager.h" + +namespace Titanic { + +int CVideoSurface::_videoSurfaceCounter = 0; + +CVideoSurface::CVideoSurface(CScreenManager *screenManager) : + _screenManager(screenManager), _rawSurface(nullptr), _movie(nullptr), + _pendingLoad(false), _blitStyleFlag(false), _blitFlag(false), + _field40(nullptr), _field44(4), _field48(0), _field50(1) { + _videoSurfaceNum = _videoSurfaceCounter++; +} + +CVideoSurface::~CVideoSurface() { + if (_ddSurface) + _videoSurfaceCounter -= freeSurface(); + --_videoSurfaceCounter; +} + +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 (_blitStyleFlag) + blitRect2(srcBounds, destBounds, src); + else + blitRect1(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::blitRect1(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) { + src->lock(); + lock(); + + // TODO: Do it like the original does it + _rawSurface->transBlitFrom(*src->_rawSurface, srcRect, destRect, + getTransparencyColor()); + + src->unlock(); + unlock(); +} + +void CVideoSurface::blitRect2(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) { + // TODO: Do it like the original does it + blitRect1(srcRect, destRect, src); +} + +uint CVideoSurface::getTransparencyColor() { + uint32 val = -(getPixelDepth() - 2); + val &= 0xFFFF8400; + val += 0xF81F; + return val; +} + +bool CVideoSurface::proc45() { + if (_field50) { + _field50 = 0; + return true; + } else if (_movie) { + return _movie->get10(); + } else { + return false; + } +} + +/*------------------------------------------------------------------------*/ + +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(); + } +} + +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::loadMovie() { + warning("TODO"); +} + +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(); +} + +void OSVideoSurface::resize(int width, int height) { + freeSurface(); + + _screenManager->resizeSurface(this, width, height); + if (_ddSurface) + _videoSurfaceCounter += _ddSurface->getSize(); +} + +int OSVideoSurface::getPixelDepth() { + if (!loadIfReady()) + assert(0); + + 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(); + 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()) { + lock(); + uint16 pixel = *(uint16 *)_rawSurface->getBasePtr(pt.x, pt.y); + unlock(); + return pixel; + } else { + return getTransparencyColor(); + } +} + +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::proc32(int v1, CVideoSurface *surface) { + if (loadIfReady() && _movie) + _movie->proc8(v1, surface); +} + +void OSVideoSurface::stopMovie() { + if (_movie) + _movie->stop(); +} + +void OSVideoSurface::setMovieFrame(uint frameNumber) { + if (loadIfReady() && _movie) + _movie->setFrame(frameNumber); +} + +bool OSVideoSurface::loadIfReady() { + _videoSurfaceNum = _videoSurfaceCounter; + + if (hasSurface()) { + return true; + } else if (_pendingLoad) { + _field50 = 1; + load(); + return true; + } else { + return false; + } +} + +int OSVideoSurface::freeSurface() { + if (!_ddSurface) + return 0; + int surfaceSize = _ddSurface->getSize(); + + delete _movie; + _movie = nullptr; + delete _ddSurface; + _ddSurface = nullptr; + + return surfaceSize; +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h new file mode 100644 index 0000000000..1de6a1dd34 --- /dev/null +++ b/engines/titanic/support/video_surface.h @@ -0,0 +1,306 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_VIDEO_SURFACE_H +#define TITANIC_VIDEO_SURFACE_H + +#include "common/scummsys.h" +#include "common/array.h" +#include "titanic/support/font.h" +#include "titanic/support/direct_draw.h" +#include "titanic/support/movie.h" +#include "titanic/support/rect.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: + /** + * Calculates blitting bounds + */ + void clipBounds(Rect &srcRect, Rect &destRect, CVideoSurface *srcSurface, + const Rect *subRect = nullptr, const Point *destPos = nullptr); + + void blitRect1(const Rect &srcRect, const Rect &destRect, CVideoSurface *src); + void blitRect2(const Rect &srcRect, const Rect &destRect, CVideoSurface *src); +protected: + static int _videoSurfaceCounter; +protected: + CScreenManager *_screenManager; + CResourceKey _resourceKey; + DirectDrawSurface *_ddSurface; + Graphics::ManagedSurface *_rawSurface; + bool _pendingLoad; + void *_field40; + int _field44; + int _field48; + int _videoSurfaceNum; + int _field50; + int _lockCount; +public: + CMovie *_movie; + bool _blitFlag; + bool _blitStyleFlag; +public: + CVideoSurface(CScreenManager *screenManager); + virtual ~CVideoSurface(); + + /** + * Set the underlying surface for this video surface + */ + void setSurface(CScreenManager *screenManager, DirectDrawSurface *surface); + + /** + * 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 movie file specified by the resource key + */ + virtual void loadMovie() = 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; + + /** + * Reiszes the surface + */ + virtual void resize(int width, int height) = 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; + + /** + * Shifts the colors of the surface.. maybe greys it out? + */ + virtual void shiftColors() = 0; + + virtual void proc32(int v1, CVideoSurface *surface) = 0; + + /** + * Stops any movie currently attached to the surface + */ + virtual void stopMovie() = 0; + + /** + * Sets the movie to the specified frame number + */ + virtual void setMovieFrame(uint frameNumber) = 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; + + virtual bool proc45(); + + /** + * Frees the underlying surface + */ + virtual int freeSurface() { return 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); + + void set40(void *v) { _field40 = v; } + + uint16 *getPixels() { return (uint16 *)_rawSurface->getPixels(); } + + /** + * Returns the transparent color + */ + uint getTransparencyColor(); +}; + +class OSVideoSurface : public CVideoSurface { +public: + OSVideoSurface(CScreenManager *screenManager, DirectDrawSurface *surface); + OSVideoSurface(CScreenManager *screenManager, const CResourceKey &key, bool flag = false); + + /** + * Load the surface with the passed resource + */ + virtual void loadResource(const CResourceKey &key); + + /** + * Loads a Targa image file specified by the resource key + */ + virtual void loadTarga(const CResourceKey &key); + + /** + * Loads a JPEG image file specified by the resource key + */ + virtual void loadJPEG(const CResourceKey &key); + + /** + * Loads a movie file specified by the resource key + */ + virtual void loadMovie(); + + /** + * Lock the surface for direct access to the pixels + */ + virtual bool lock(); + + /** + * Unlocks the surface after prior calls to lock() + */ + virtual void unlock(); + + /** + * Returns true if an underlying raw surface has been set + */ + virtual bool hasSurface(); + + /** + * Returns the width of the surface + */ + virtual int getWidth(); + + /** + * Returns the height of the surface + */ + virtual int getHeight(); + + /** + * Returns the pitch of the surface in bytes + */ + virtual int getPitch(); + + /** + * Reiszes the surface + */ + virtual void resize(int width, int height); + + /** + * Returns the number of bytes per pixel in the surface + */ + virtual int getPixelDepth(); + + /** + * Gets the pixel at the specified position within the surface + */ + virtual uint16 getPixel(const Common::Point &pt); + + /** + * Shifts the colors of the surface.. maybe greys it out? + */ + virtual void shiftColors(); + + virtual void proc32(int v1, CVideoSurface *surface); + + /** + * Stops any movie currently attached to the surface + */ + virtual void stopMovie(); + + /** + * Sets the movie to the specified frame number + */ + virtual void setMovieFrame(uint frameNumber); + + /** + * Loads the surface's resource if there's one pending + */ + virtual bool loadIfReady(); + + /** + * Loads the surface data based on the currently set resource key + */ + virtual bool load(); + + /** + * Frees the underlying surface + */ + virtual int freeSurface(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_VIDEO_SURFACE_H */ -- cgit v1.2.3 From 2699efd633334be7fade6e890c0a9b32edc08677 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 3 Apr 2016 17:44:08 -0400 Subject: TITANIC: Fix reading resources from game executable --- engines/titanic/support/files_manager.cpp | 8 ++++---- engines/titanic/support/files_manager.h | 8 ++++---- engines/titanic/support/font.cpp | 5 ++--- 3 files changed, 10 insertions(+), 11 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/files_manager.cpp b/engines/titanic/support/files_manager.cpp index 179d77f24f..6cd6bfb5f2 100644 --- a/engines/titanic/support/files_manager.cpp +++ b/engines/titanic/support/files_manager.cpp @@ -93,14 +93,14 @@ void CFilesManager::fn5(const CString &name) { warning("TODO: CFilesManager::fn5"); } -Common::SeekableReadStream *CFilesManager::getResource(const CString &name, - const CString &area) { +Common::SeekableReadStream *CFilesManager::getResource( + Common::WinResourceID area, Common::WinResourceID name) { if (!_exeResources) { - _exeResources = new Common::NEResources(); + _exeResources = new Common::PEResources(); _exeResources->loadFromEXE("st.exe"); } - return nullptr; + return _exeResources->getResource(area, name); } } // End of namespace Titanic diff --git a/engines/titanic/support/files_manager.h b/engines/titanic/support/files_manager.h index 7915149412..ae664698ac 100644 --- a/engines/titanic/support/files_manager.h +++ b/engines/titanic/support/files_manager.h @@ -23,7 +23,7 @@ #ifndef TITANIC_FILES_MANAGER_H #define TITANIC_FILES_MANAGER_H -#include "common/winexe_ne.h" +#include "common/winexe_pe.h" #include "titanic/core/list.h" #include "titanic/support/screen_manager.h" @@ -37,7 +37,7 @@ class CFilesManagerList : public List { class CFilesManager { private: CGameManager *_gameManager; - Common::NEResources *_exeResources; + Common::PEResources *_exeResources; CFilesManagerList _list; CString _string1; CString _string2; @@ -87,8 +87,8 @@ public: /** * Get a resource from the executable */ - Common::SeekableReadStream *getResource(const CString &name, - const CString &area); + Common::SeekableReadStream *getResource(Common::WinResourceID area, + Common::WinResourceID name); }; } // End of namespace Titanic diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp index 6862baf79f..3b48e5e301 100644 --- a/engines/titanic/support/font.cpp +++ b/engines/titanic/support/font.cpp @@ -43,11 +43,10 @@ STFont::~STFont() { void STFont::load(int fontNumber) { assert(!_dataPtr); - CString fontNumStr = CString::format("%d", fontNumber); Common::SeekableReadStream *stream = g_vm->_filesManager.getResource( - fontNumStr, "STFont"); + Common::WinResourceID("STFONT"), fontNumber); if (!stream) - return; + error("Could not locate the specified font"); _field8 = stream->readUint32LE(); _maxCharWidth = stream->readUint32LE(); -- cgit v1.2.3 From ebdc773247fb1e6a41f58ee8336986dcdc8e75d6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 3 Apr 2016 18:10:25 -0400 Subject: TITANIC: Implement font loading --- engines/titanic/support/font.cpp | 22 ++++++++++++++++++++++ engines/titanic/support/font.h | 7 ++++++- 2 files changed, 28 insertions(+), 1 deletion(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp index 3b48e5e301..6636a84f22 100644 --- a/engines/titanic/support/font.cpp +++ b/engines/titanic/support/font.cpp @@ -66,4 +66,26 @@ void STFont::writeString(int maxWidth, const CString &text, int *v1, int *v2) { warning("TODO: STFont::writeString"); } +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 == 27) { + // Skip over command parameter bytes + srcP += 4; + } else if (c != '\n') { + total += _chars[c]._charWidth; + } + } + + return total; +} + } // End of namespace Titanic diff --git a/engines/titanic/support/font.h b/engines/titanic/support/font.h index 0fff5125df..c41f4dc1e0 100644 --- a/engines/titanic/support/font.h +++ b/engines/titanic/support/font.h @@ -39,7 +39,7 @@ public: size_t _dataSize; int _field8; int _maxCharWidth; - Common::Array _chars; + CharEntry _chars[256]; int _field810; int _field814; int _field818; @@ -52,6 +52,11 @@ public: */ void load(int fontNumber); + /** + * Return the width in pixels of the specified text + */ + int stringWidth(const CString &text) const; + /** * Write out a string * TODO: Verify this -- cgit v1.2.3 From 56b29987443075faba0495d84eeaf42b443d577f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 4 Apr 2016 00:07:50 -0400 Subject: TITANIC: Further work on STFont character drawing --- engines/titanic/support/font.cpp | 82 +++++++++++++++++++++++++++---- engines/titanic/support/font.h | 36 +++++++++++--- engines/titanic/support/video_surface.cpp | 5 ++ engines/titanic/support/video_surface.h | 10 +++- 4 files changed, 117 insertions(+), 16 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp index 6636a84f22..32652588c0 100644 --- a/engines/titanic/support/font.cpp +++ b/engines/titanic/support/font.cpp @@ -30,11 +30,9 @@ namespace Titanic { STFont::STFont() { _dataPtr = nullptr; _dataSize = 0; - _field8 = 0; - _maxCharWidth = 0; - _field810 = 0; - _field814 = 0; - _field818 = 0; + _fontHeight = 0; + _dataWidth = 0; + _fontR = _fontG = _fontB = 0; } STFont::~STFont() { @@ -48,10 +46,10 @@ void STFont::load(int fontNumber) { if (!stream) error("Could not locate the specified font"); - _field8 = stream->readUint32LE(); - _maxCharWidth = stream->readUint32LE(); + _fontHeight = stream->readUint32LE(); + _dataWidth = stream->readUint32LE(); for (uint idx = 0; idx < 256; ++idx) - _chars[idx]._charWidth = stream->readUint32LE(); + _chars[idx]._width = stream->readUint32LE(); for (uint idx = 0; idx < 256; ++idx) _chars[idx]._offset = stream->readUint32LE(); @@ -62,6 +60,16 @@ void STFont::load(int fontNumber) { 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); +} + void STFont::writeString(int maxWidth, const CString &text, int *v1, int *v2) { warning("TODO: STFont::writeString"); } @@ -81,11 +89,67 @@ int STFont::stringWidth(const CString &text) const { // Skip over command parameter bytes srcP += 4; } else if (c != '\n') { - total += _chars[c]._charWidth; + total += _chars[c]._width; } } return total; } +int STFont::writeChar(CVideoSurface *surface, unsigned char c, const Common::Point &pt, Rect *destRect, Rect *srcRect) { + if (c == 233) + c = '$'; + + Rect tempRect; + tempRect.left = _chars[c]._offset; + tempRect.right = _chars[c]._offset + _chars[c]._width; + tempRect.top = 0; + tempRect.bottom = _fontHeight; + Point destPos(pt.x + destRect->left, pt.y + destRect->top); + + if (srcRect->isEmpty()) + srcRect = destRect; + if (destPos.y > srcRect->bottom) + return -2; + + if ((destPos.y + tempRect.height()) > srcRect->bottom) { + tempRect.bottom += tempRect.top - destPos.y; + } + + if (destPos.y < srcRect->top) { + if ((tempRect.height() + destPos.y) < srcRect->top) + return -1; + + tempRect.top += srcRect->top - destPos.y; + destPos.y = srcRect->top; + } + + if (destPos.x < srcRect->left) { + if ((tempRect.width() + destPos.x) < srcRect->left) + return -3; + + tempRect.left += srcRect->left - destPos.x; + destPos.x = srcRect->left; + } else { + if ((tempRect.width() + destPos.x) > srcRect->right) { + if (destPos.x > srcRect->right) + return -4; + + tempRect.right += srcRect->left - destPos.x; + } + } + + copyRect(surface, destPos, tempRect); + return 0; +} + +void STFont::copyRect(CVideoSurface *surface, const Common::Point &pt, Rect &rect) { + if (surface->lock()) { + uint16 *lineP = surface->getBasePtr(pt.x, pt.y); + uint16 color = getColor(); + + surface->unlock(); + } +} + } // End of namespace Titanic diff --git a/engines/titanic/support/font.h b/engines/titanic/support/font.h index c41f4dc1e0..5ed0b5b7b4 100644 --- a/engines/titanic/support/font.h +++ b/engines/titanic/support/font.h @@ -25,24 +25,38 @@ #include "common/scummsys.h" #include "common/array.h" +#include "titanic/support/rect.h" #include "titanic/support/string.h" namespace Titanic { +class CVideoSurface; + class STFont { struct CharEntry { - uint _charWidth; + 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 + */ + int writeChar(CVideoSurface *surface, unsigned char c, + const Common::Point &pt, Rect *destRect, Rect *srcRect); public: byte *_dataPtr; size_t _dataSize; - int _field8; - int _maxCharWidth; + int _fontHeight; + uint _dataWidth; CharEntry _chars[256]; - int _field810; - int _field814; - int _field818; + byte _fontR, _fontG, _fontB; public: STFont(); ~STFont(); @@ -62,6 +76,16 @@ public: * TODO: Verify this */ void writeString(int maxWidth, const CString &text, int *v1, int *v2); + + /** + * Sets the font color + */ + void setColor(byte r, byte g, byte b); + + /** + * Gets the font color + */ + uint16 getColor() const; }; } // End of namespace Titanic diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index 6bba24de5f..ebe552a062 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -373,4 +373,9 @@ int OSVideoSurface::freeSurface() { return surfaceSize; } +uint16 *OSVideoSurface::getBasePtr(int x, int y) { + assert(_rawSurface); + return (uint16 *)_rawSurface->getBasePtr(x, y); +} + } // End of namespace Titanic diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index 1de6a1dd34..da53270122 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -176,7 +176,10 @@ public: */ virtual int freeSurface() { return 0; } - + /** + * Get a pointer into the underlying surface + */ + virtual uint16 *getBasePtr(int x, int y) = 0; /** * Blit from another surface @@ -299,6 +302,11 @@ public: * Frees the underlying surface */ virtual int freeSurface(); + + /** + * Get a pointer into the underlying surface + */ + virtual uint16 *getBasePtr(int x, int y); }; } // End of namespace Titanic -- cgit v1.2.3 From 3acf1116cd7eff2f98538f8457f724ac25b28df1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 4 Apr 2016 07:54:02 -0400 Subject: TITANIC: Implemented STFont::copyRect --- engines/titanic/support/font.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp index 32652588c0..55865e792c 100644 --- a/engines/titanic/support/font.cpp +++ b/engines/titanic/support/font.cpp @@ -148,6 +148,14 @@ void STFont::copyRect(CVideoSurface *surface, const Common::Point &pt, Rect &rec uint16 *lineP = surface->getBasePtr(pt.x, pt.y); uint16 color = getColor(); + for (int yp = rect.top; yp < rect.bottom; ++yp, lineP += surface->getPitch()) { + uint16 *destP = lineP; + for (int xp = rect.left; xp < rect.right; ++xp, ++destP) { + const byte *srcP = _dataPtr + yp * _dataWidth + xp; + //surface->changePixel(destP, color, *srcP >> 3, 1); + } + } + surface->unlock(); } } -- cgit v1.2.3 From 572301a33efc8c574d7ab2fc9b243050b2db1492 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 4 Apr 2016 18:15:02 -0400 Subject: TITANIC: Implement OSVideoSurface::setupMap --- engines/titanic/support/video_surface.cpp | 32 +++++++++++++++++++++++++++++++ engines/titanic/support/video_surface.h | 22 +++++++++++++++++++++ 2 files changed, 54 insertions(+) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index ebe552a062..a1b26386b3 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -182,6 +182,34 @@ OSVideoSurface::OSVideoSurface(CScreenManager *screenManager, const CResourceKey } } +void OSVideoSurface::setupMap(byte map[0x400], byte val) { + byte *pBase = map; + int incr = 0; + + for (uint idx1 = 0; idx1 < 32; ++idx1, pBase += 32) { + for (uint idx2 = 0, base = 0; idx2 < 32; ++idx2, base += incr) { + int64 v = 0x84210843; + v *= base; + v = ((v >> 32) + base) >> 4; + v += (v >> 31); + pBase[idx2] = v; + + if (val != 0xff) { + v &= 0xff; + if (v != idx2) { + v = 0x80808081 * val * v * val; + v = (v >> 32) + incr; + incr = idx1; + + v >>= 7; + v += (v >> 31); + pBase[idx2] = v; + } + } + } + } +} + void OSVideoSurface::loadResource(const CResourceKey &key) { _resourceKey = key; _pendingLoad = true; @@ -323,6 +351,10 @@ uint16 OSVideoSurface::getPixel(const Common::Point &pt) { } } +void OSVideoSurface::changePixel(uint16 *pixelP, uint16 color, int val3, int val5) { + // TODO +} + void OSVideoSurface::shiftColors() { if (!loadIfReady()) return; diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index da53270122..e1ddde8013 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -142,6 +142,11 @@ public: */ virtual uint16 getPixel(const Common::Point &pt) = 0; + /** + * Change a pixel + */ + virtual void changePixel(uint16 *pixelP, uint16 color, int val3, int val5) = 0; + /** * Shifts the colors of the surface.. maybe greys it out? */ @@ -202,6 +207,18 @@ public: }; class OSVideoSurface : public CVideoSurface { +private: + static byte _map[0x400]; + + /** + * Setup the color mapping table + */ + static void setupMap(byte map[0x400], byte val); +public: + /** + * Setup statics + */ + static void setup() { setupMap(_map, 0xff); } public: OSVideoSurface(CScreenManager *screenManager, DirectDrawSurface *surface); OSVideoSurface(CScreenManager *screenManager, const CResourceKey &key, bool flag = false); @@ -271,6 +288,11 @@ public: */ virtual uint16 getPixel(const Common::Point &pt); + /** + * Change a pixel + */ + virtual void changePixel(uint16 *pixelP, uint16 color, int val3, int val5); + /** * Shifts the colors of the surface.. maybe greys it out? */ -- cgit v1.2.3 From 303f577c4f9b36cd78f5104a2971a27263fb051c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 4 Apr 2016 22:18:18 -0400 Subject: TITANIC: Hacked copy of AVIDecoder to handle ycursors.avi Mouse cursor is now somewhat correctly showing --- engines/titanic/support/avi_decoder.cpp | 946 ++++++++++++++++++++++++++++++++ engines/titanic/support/avi_decoder.h | 285 ++++++++++ engines/titanic/support/movie.cpp | 21 +- engines/titanic/support/movie.h | 6 +- 4 files changed, 1249 insertions(+), 9 deletions(-) create mode 100644 engines/titanic/support/avi_decoder.cpp create mode 100644 engines/titanic/support/avi_decoder.h (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_decoder.cpp b/engines/titanic/support/avi_decoder.cpp new file mode 100644 index 0000000000..81d8a58b8d --- /dev/null +++ b/engines/titanic/support/avi_decoder.cpp @@ -0,0 +1,946 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/stream.h" +#include "common/system.h" +#include "common/textconsole.h" + +#include "audio/audiostream.h" +#include "audio/mixer.h" + +#include "titanic/support/avi_decoder.h" + +// Audio Codecs +#include "audio/decoders/adpcm.h" +#include "audio/decoders/mp3.h" +#include "audio/decoders/raw.h" + +// Video Codecs +#include "image/codecs/codec.h" + +namespace Titanic { + +#define UNKNOWN_HEADER(a) error("Unknown header found -- \'%s\'", tag2str(a)) + +// IDs used throughout the AVI files +// that will be handled by this player +#define ID_RIFF MKTAG('R','I','F','F') +#define ID_AVI MKTAG('A','V','I',' ') +#define ID_LIST MKTAG('L','I','S','T') +#define ID_HDRL MKTAG('h','d','r','l') +#define ID_AVIH MKTAG('a','v','i','h') +#define ID_STRL MKTAG('s','t','r','l') +#define ID_STRH MKTAG('s','t','r','h') +#define ID_VIDS MKTAG('v','i','d','s') +#define ID_AUDS MKTAG('a','u','d','s') +#define ID_MIDS MKTAG('m','i','d','s') +#define ID_TXTS MKTAG('t','x','t','s') +#define ID_JUNK MKTAG('J','U','N','K') +#define ID_JUNQ MKTAG('J','U','N','Q') +#define ID_DMLH MKTAG('d','m','l','h') +#define ID_STRF MKTAG('s','t','r','f') +#define ID_MOVI MKTAG('m','o','v','i') +#define ID_REC MKTAG('r','e','c',' ') +#define ID_VEDT MKTAG('v','e','d','t') +#define ID_IDX1 MKTAG('i','d','x','1') +#define ID_STRD MKTAG('s','t','r','d') +#define ID_INFO MKTAG('I','N','F','O') +#define ID_ISFT MKTAG('I','S','F','T') +#define ID_DISP MKTAG('D','I','S','P') +#define ID_PRMI MKTAG('P','R','M','I') +#define ID_STRN MKTAG('s','t','r','n') + +// Stream Types +enum { + kStreamTypePaletteChange = MKTAG16('p', 'c'), + kStreamTypeAudio = MKTAG16('w', 'b') +}; + + +AVIDecoder::AVIDecoder(Audio::Mixer::SoundType soundType) : _frameRateOverride(0), _soundType(soundType) { + initCommon(); +} + +AVIDecoder::AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType) + : _frameRateOverride(frameRateOverride), _soundType(soundType) { + initCommon(); +} + +AVIDecoder::~AVIDecoder() { + close(); +} + +AVIDecoder::AVIAudioTrack *AVIDecoder::createAudioTrack(AVIStreamHeader sHeader, PCMWaveFormat wvInfo) { + return new AVIAudioTrack(sHeader, wvInfo, _soundType); +} + +void AVIDecoder::initCommon() { + _decodedHeader = false; + _foundMovieList = false; + _movieListStart = 0; + _movieListEnd = 0; + _fileStream = 0; + memset(&_header, 0, sizeof(_header)); +} + +bool AVIDecoder::isSeekable() const { + // Only videos with an index can seek + // Anyone else who wants to seek is crazy. + return isVideoLoaded() && !_indexEntries.empty(); +} + +bool AVIDecoder::parseNextChunk() { + uint32 tag = _fileStream->readUint32BE(); + uint32 size = _fileStream->readUint32LE(); + + if (_fileStream->eos()) + return false; + + debug(3, "Decoding tag %s", tag2str(tag)); + + switch (tag) { + case ID_LIST: + handleList(size); + break; + case ID_AVIH: + _header.size = size; + _header.microSecondsPerFrame = _fileStream->readUint32LE(); + _header.maxBytesPerSecond = _fileStream->readUint32LE(); + _header.padding = _fileStream->readUint32LE(); + _header.flags = _fileStream->readUint32LE(); + _header.totalFrames = _fileStream->readUint32LE(); + _header.initialFrames = _fileStream->readUint32LE(); + _header.streams = _fileStream->readUint32LE(); + _header.bufferSize = _fileStream->readUint32LE(); + _header.width = _fileStream->readUint32LE(); + _header.height = _fileStream->readUint32LE(); + // Ignore 16 bytes of reserved data + _fileStream->skip(16); + break; + case ID_STRH: + handleStreamHeader(size); + break; + case ID_STRD: // Extra stream info, safe to ignore + case ID_VEDT: // Unknown, safe to ignore + case ID_JUNK: // Alignment bytes, should be ignored + case ID_JUNQ: // Same as JUNK, safe to ignore + case ID_ISFT: // Metadata, safe to ignore + case ID_DISP: // Metadata, should be safe to ignore + case ID_STRN: // Metadata, safe to ignore + case ID_DMLH: // OpenDML extension, contains an extra total frames field, safe to ignore + skipChunk(size); + break; + case ID_IDX1: + readOldIndex(size); + break; + case 0: + return false; + default: + error("Unknown tag \'%s\' found", tag2str(tag)); + } + + return true; +} + +void AVIDecoder::skipChunk(uint32 size) { + // Make sure we're aligned on a word boundary + _fileStream->skip(size + (size & 1)); +} + +void AVIDecoder::handleList(uint32 listSize) { + uint32 listType = _fileStream->readUint32BE(); + listSize -= 4; // Subtract away listType's 4 bytes + uint32 curPos = _fileStream->pos(); + + debug(0, "Found LIST of type %s", tag2str(listType)); + + switch (listType) { + case ID_MOVI: // Movie List + // We found the movie block + _foundMovieList = true; + _movieListStart = curPos; + _movieListEnd = _movieListStart + listSize + (listSize & 1); + _fileStream->skip(listSize); + return; + case ID_HDRL: // Header List + // Mark the header as decoded + _decodedHeader = true; + break; + case ID_INFO: // Metadata + case ID_PRMI: // Adobe Premiere metadata, safe to ignore + // Ignore metadata + _fileStream->skip(listSize); + return; + case ID_STRL: // Stream list + default: // (Just hope we can parse it!) + break; + } + + while ((_fileStream->pos() - curPos) < listSize) + parseNextChunk(); +} + +void AVIDecoder::handleStreamHeader(uint32 size) { + AVIStreamHeader sHeader; + sHeader.size = size; + sHeader.streamType = _fileStream->readUint32BE(); + + if (sHeader.streamType == ID_MIDS || sHeader.streamType == ID_TXTS) + error("Unhandled MIDI/Text stream"); + + sHeader.streamHandler = _fileStream->readUint32BE(); + sHeader.flags = _fileStream->readUint32LE(); + sHeader.priority = _fileStream->readUint16LE(); + sHeader.language = _fileStream->readUint16LE(); + sHeader.initialFrames = _fileStream->readUint32LE(); + sHeader.scale = _fileStream->readUint32LE(); + sHeader.rate = _fileStream->readUint32LE(); + sHeader.start = _fileStream->readUint32LE(); + sHeader.length = _fileStream->readUint32LE(); + sHeader.bufferSize = _fileStream->readUint32LE(); + sHeader.quality = _fileStream->readUint32LE(); + sHeader.sampleSize = _fileStream->readUint32LE(); + + _fileStream->skip(sHeader.size - 48); // Skip over the remainder of the chunk (frame) + + if (_fileStream->readUint32BE() != ID_STRF) + error("Could not find STRF tag"); + + uint32 strfSize = _fileStream->readUint32LE(); + uint32 startPos = _fileStream->pos(); + + if (sHeader.streamType == ID_VIDS) { + if (_frameRateOverride != 0) { + sHeader.rate = _frameRateOverride.getNumerator(); + sHeader.scale = _frameRateOverride.getDenominator(); + } + + BitmapInfoHeader bmInfo; + bmInfo.size = _fileStream->readUint32LE(); + bmInfo.width = _fileStream->readUint32LE(); + bmInfo.height = _fileStream->readUint32LE(); + bmInfo.planes = _fileStream->readUint16LE(); + bmInfo.bitCount = _fileStream->readUint16LE(); + bmInfo.compression = _fileStream->readUint32BE(); + bmInfo.sizeImage = _fileStream->readUint32LE(); + bmInfo.xPelsPerMeter = _fileStream->readUint32LE(); + bmInfo.yPelsPerMeter = _fileStream->readUint32LE(); + bmInfo.clrUsed = _fileStream->readUint32LE(); + bmInfo.clrImportant = _fileStream->readUint32LE(); + + if (bmInfo.clrUsed == 0) + bmInfo.clrUsed = 256; + + byte *initialPalette = 0; + + if (bmInfo.bitCount == 8) { + initialPalette = new byte[256 * 3]; + memset(initialPalette, 0, 256 * 3); + + byte *palette = initialPalette; + for (uint32 i = 0; i < bmInfo.clrUsed; i++) { + palette[i * 3 + 2] = _fileStream->readByte(); + palette[i * 3 + 1] = _fileStream->readByte(); + palette[i * 3] = _fileStream->readByte(); + _fileStream->readByte(); + } + } + + addTrack(new AVIVideoTrack(_header.totalFrames, sHeader, bmInfo, initialPalette)); + } else if (sHeader.streamType == ID_AUDS) { + PCMWaveFormat wvInfo; + wvInfo.tag = _fileStream->readUint16LE(); + wvInfo.channels = _fileStream->readUint16LE(); + wvInfo.samplesPerSec = _fileStream->readUint32LE(); + wvInfo.avgBytesPerSec = _fileStream->readUint32LE(); + wvInfo.blockAlign = _fileStream->readUint16LE(); + wvInfo.size = _fileStream->readUint16LE(); + + // AVI seems to treat the sampleSize as including the second + // channel as well, so divide for our sake. + if (wvInfo.channels == 2) + sHeader.sampleSize /= 2; + + AVIAudioTrack *track = createAudioTrack(sHeader, wvInfo); + track->createAudioStream(); + addTrack(track); + } + + // Ensure that we're at the end of the chunk + _fileStream->seek(startPos + strfSize); +} + +bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) { + close(); + + uint32 riffTag = stream->readUint32BE(); + if (riffTag != ID_RIFF) { + warning("Failed to find RIFF header"); + return false; + } + + /* uint32 fileSize = */ stream->readUint32LE(); + uint32 riffType = stream->readUint32BE(); + + if (riffType != ID_AVI) { + warning("RIFF not an AVI file"); + return false; + } + + _fileStream = stream; + + // Go through all chunks in the file + while (parseNextChunk()) + ; + + if (!_decodedHeader) { + warning("Failed to parse AVI header"); + close(); + return false; + } + + if (!_foundMovieList) { + warning("Failed to find 'MOVI' list"); + close(); + return false; + } + + // Create the status entries + uint32 index = 0; + for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++, index++) { + TrackStatus status; + status.track = *it; + status.index = index; + status.chunkSearchOffset = _movieListStart; + + if ((*it)->getTrackType() == Track::kTrackTypeVideo) { + if (_videoTracks.size() == 0) + _videoTracks.push_back(status); + } else { + if (_audioTracks.size() == 0) + _audioTracks.push_back(status); + } + } + + if (_videoTracks.size() != 1) { + warning("Unhandled AVI video track count: %d", _videoTracks.size()); + close(); + return false; + } + + // Check if this is a special Duck Truemotion video + checkTruemotion1(); + + return true; +} + +void AVIDecoder::close() { + VideoDecoder::close(); + + delete _fileStream; + _fileStream = 0; + _decodedHeader = false; + _foundMovieList = false; + _movieListStart = 0; + _movieListEnd = 0; + + _indexEntries.clear(); + memset(&_header, 0, sizeof(_header)); + + _videoTracks.clear(); + _audioTracks.clear(); +} + +void AVIDecoder::readNextPacket() { + // Shouldn't get this unless called on a non-open video + if (_videoTracks.empty()) + return; + + // Get the video frame first + handleNextPacket(_videoTracks[0]); + + // Handle audio tracks next + for (uint32 i = 0; i < _audioTracks.size(); i++) + handleNextPacket(_audioTracks[i]); +} + +void AVIDecoder::handleNextPacket(TrackStatus &status) { + // If there's no more to search, bail out + if (status.chunkSearchOffset + 8 >= _movieListEnd) { + if (status.track->getTrackType() == Track::kTrackTypeVideo) { + // Horrible AVI video has a premature end + // Force the frame to be the last frame + debug(0, "Forcing end of AVI video"); + ((AVIVideoTrack *)status.track)->forceTrackEnd(); + } + + return; + } + + // See if audio needs to be buffered and break out if not + if (status.track->getTrackType() == Track::kTrackTypeAudio && !shouldQueueAudio(status)) + return; + + // Seek to where we shall start searching + _fileStream->seek(status.chunkSearchOffset); + + for (;;) { + // If there's no more to search, bail out + if ((uint32)_fileStream->pos() + 8 >= _movieListEnd) { + if (status.track->getTrackType() == Track::kTrackTypeVideo) { + // Horrible AVI video has a premature end + // Force the frame to be the last frame + debug(0, "Forcing end of AVI video"); + ((AVIVideoTrack *)status.track)->forceTrackEnd(); + } + + break; + } + + uint32 nextTag = _fileStream->readUint32BE(); + uint32 size = _fileStream->readUint32LE(); + + if (nextTag == ID_LIST) { + // A list of audio/video chunks + if (_fileStream->readUint32BE() != ID_REC) + error("Expected 'rec ' LIST"); + + continue; + } else if (nextTag == ID_JUNK || nextTag == ID_IDX1) { + skipChunk(size); + continue; + } + + // Only accept chunks for this stream + uint32 streamIndex = getStreamIndex(nextTag); + if (streamIndex != status.index) { + skipChunk(size); + continue; + } + + Common::SeekableReadStream *chunk = 0; + + if (size != 0) { + chunk = _fileStream->readStream(size); + _fileStream->skip(size & 1); + } + + if (status.track->getTrackType() == Track::kTrackTypeAudio) { + if (getStreamType(nextTag) != kStreamTypeAudio) + error("Invalid audio track tag '%s'", tag2str(nextTag)); + + assert(chunk); + ((AVIAudioTrack *)status.track)->queueSound(chunk); + + // Break out if we have enough audio + if (!shouldQueueAudio(status)) + break; + } else { + AVIVideoTrack *videoTrack = (AVIVideoTrack *)status.track; + + if (getStreamType(nextTag) == kStreamTypePaletteChange) { + // Palette Change + videoTrack->loadPaletteFromChunk(chunk); + } else { + // Otherwise, assume it's a compressed frame + videoTrack->decodeFrame(chunk); + break; + } + } + } + + // Start us off in this position next time + status.chunkSearchOffset = _fileStream->pos(); +} + +bool AVIDecoder::shouldQueueAudio(TrackStatus& status) { + // Sanity check: + if (status.track->getTrackType() != Track::kTrackTypeAudio) + return false; + + // If video is done, make sure that the rest of the audio is queued + // (I guess this is also really a sanity check) + AVIVideoTrack *videoTrack = (AVIVideoTrack *)_videoTracks[0].track; + if (videoTrack->endOfTrack()) + return true; + + // Being three frames ahead should be enough for any video. + return ((AVIAudioTrack *)status.track)->getCurChunk() < (uint32)(videoTrack->getCurFrame() + 3); +} + +bool AVIDecoder::rewind() { + if (!VideoDecoder::rewind()) + return false; + + for (uint32 i = 0; i < _videoTracks.size(); i++) + _videoTracks[i].chunkSearchOffset = _movieListStart; + + for (uint32 i = 0; i < _audioTracks.size(); i++) + _audioTracks[i].chunkSearchOffset = _movieListStart; + + return true; +} + +bool AVIDecoder::seekIntern(const Audio::Timestamp &time) { + // Can't seek beyond the end + if (time > getDuration()) + return false; + + // Get our video + AVIVideoTrack *videoTrack = (AVIVideoTrack *)_videoTracks[0].track; + uint32 videoIndex = _videoTracks[0].index; + + // If we seek directly to the end, just mark the tracks as over + if (time == getDuration()) { + videoTrack->setCurFrame(videoTrack->getFrameCount() - 1); + + for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++) + if ((*it)->getTrackType() == Track::kTrackTypeAudio) + ((AVIAudioTrack *)*it)->resetStream(); + + return true; + } + + // Get the frame we should be on at this time + uint frame = videoTrack->getFrameAtTime(time); + + // Reset any palette, if necessary + videoTrack->useInitialPalette(); + + int lastKeyFrame = -1; + int frameIndex = -1; + uint curFrame = 0; + + // Go through and figure out where we should be + // If there's a palette, we need to find the palette too + for (uint32 i = 0; i < _indexEntries.size(); i++) { + const OldIndex &index = _indexEntries[i]; + + // We don't care about RECs + if (index.id == ID_REC) + continue; + + // We're only looking at entries for this track + if (getStreamIndex(index.id) != videoIndex) + continue; + + uint16 streamType = getStreamType(index.id); + + if (streamType == kStreamTypePaletteChange) { + // We need to handle any palette change we see since there's no + // flag to tell if this is a "key" palette. + // Decode the palette + _fileStream->seek(_indexEntries[i].offset + 8); + Common::SeekableReadStream *chunk = 0; + + if (_indexEntries[i].size != 0) + chunk = _fileStream->readStream(_indexEntries[i].size); + + videoTrack->loadPaletteFromChunk(chunk); + } else { + // Check to see if this is a keyframe + // The first frame has to be a keyframe + if ((_indexEntries[i].flags & AVIIF_INDEX) || curFrame == 0) + lastKeyFrame = i; + + // Did we find the target frame? + if (frame == curFrame) { + frameIndex = i; + break; + } + + curFrame++; + } + } + + if (frameIndex < 0) // This shouldn't happen. + return false; + + // Update all the audio tracks + for (uint32 i = 0; i < _audioTracks.size(); i++) { + AVIAudioTrack *audioTrack = (AVIAudioTrack *)_audioTracks[i].track; + + // Recreate the audio stream + audioTrack->resetStream(); + + // Set the chunk index for the track + audioTrack->setCurChunk(frame); + + uint32 chunksFound = 0; + for (uint32 j = 0; j < _indexEntries.size(); j++) { + const OldIndex &index = _indexEntries[j]; + + // Continue ignoring RECs + if (index.id == ID_REC) + continue; + + if (getStreamIndex(index.id) == _audioTracks[i].index) { + if (chunksFound == frame) { + _fileStream->seek(index.offset + 8); + Common::SeekableReadStream *audioChunk = _fileStream->readStream(index.size); + audioTrack->queueSound(audioChunk); + _audioTracks[i].chunkSearchOffset = (j == _indexEntries.size() - 1) ? _movieListEnd : _indexEntries[j + 1].offset; + break; + } + + chunksFound++; + } + } + + // Skip any audio to bring us to the right time + audioTrack->skipAudio(time, videoTrack->getFrameTime(frame)); + } + + // Decode from keyFrame to curFrame - 1 + for (int i = lastKeyFrame; i < frameIndex; i++) { + if (_indexEntries[i].id == ID_REC) + continue; + + if (getStreamIndex(_indexEntries[i].id) != videoIndex) + continue; + + uint16 streamType = getStreamType(_indexEntries[i].id); + + // Ignore palettes, they were already handled + if (streamType == kStreamTypePaletteChange) + continue; + + // Frame, hopefully + _fileStream->seek(_indexEntries[i].offset + 8); + Common::SeekableReadStream *chunk = 0; + + if (_indexEntries[i].size != 0) + chunk = _fileStream->readStream(_indexEntries[i].size); + + videoTrack->decodeFrame(chunk); + } + + // Set the video track's frame + videoTrack->setCurFrame((int)frame - 1); + + // Set the video track's search offset to the right spot + _videoTracks[0].chunkSearchOffset = _indexEntries[frameIndex].offset; + return true; +} + +byte AVIDecoder::getStreamIndex(uint32 tag) const { + char string[3]; + WRITE_BE_UINT16(string, tag >> 16); + string[2] = 0; + return strtol(string, 0, 16); +} + +void AVIDecoder::readOldIndex(uint32 size) { + uint32 entryCount = size / 16; + + debug(0, "Old Index: %d entries", entryCount); + + if (entryCount == 0) + return; + + // Read the first index separately + OldIndex firstEntry; + firstEntry.id = _fileStream->readUint32BE(); + firstEntry.flags = _fileStream->readUint32LE(); + firstEntry.offset = _fileStream->readUint32LE(); + firstEntry.size = _fileStream->readUint32LE(); + + // Check if the offset is already absolute + // If it's absolute, the offset will equal the start of the movie list + bool isAbsolute = firstEntry.offset == _movieListStart; + + debug(1, "Old index is %s", isAbsolute ? "absolute" : "relative"); + + if (!isAbsolute) + firstEntry.offset += _movieListStart - 4; + + debug(0, "Index 0: Tag '%s', Offset = %d, Size = %d (Flags = %d)", tag2str(firstEntry.id), firstEntry.offset, firstEntry.size, firstEntry.flags); + _indexEntries.push_back(firstEntry); + + for (uint32 i = 1; i < entryCount; i++) { + OldIndex indexEntry; + indexEntry.id = _fileStream->readUint32BE(); + indexEntry.flags = _fileStream->readUint32LE(); + indexEntry.offset = _fileStream->readUint32LE(); + indexEntry.size = _fileStream->readUint32LE(); + + // Adjust to absolute, if necessary + if (!isAbsolute) + indexEntry.offset += _movieListStart - 4; + + _indexEntries.push_back(indexEntry); + debug(0, "Index %d: Tag '%s', Offset = %d, Size = %d (Flags = %d)", i, tag2str(indexEntry.id), indexEntry.offset, indexEntry.size, indexEntry.flags); + } +} + +void AVIDecoder::checkTruemotion1() { + // If we got here from loadStream(), we know the track is valid + assert(!_videoTracks.empty()); + + TrackStatus &status = _videoTracks[0]; + AVIVideoTrack *track = (AVIVideoTrack *)status.track; + + // Ignore non-truemotion tracks + if (!track->isTruemotion1()) + return; + + // Read the next video packet + handleNextPacket(status); + + const Graphics::Surface *frame = track->decodeNextFrame(); + if (!frame) { + rewind(); + return; + } + + // Fill in the width/height based on the frame's width/height + _header.width = frame->w; + _header.height = frame->h; + track->forceDimensions(frame->w, frame->h); + + // Rewind us back to the beginning + rewind(); +} + +Video::VideoDecoder::AudioTrack *AVIDecoder::getAudioTrack(int index) { + // AVI audio track indexes are relative to the first track + Track *track = getTrack(index); + + if (!track || track->getTrackType() != Track::kTrackTypeAudio) + return 0; + + return (AudioTrack *)track; +} + +AVIDecoder::AVIVideoTrack::AVIVideoTrack(int frameCount, const AVIStreamHeader &streamHeader, const BitmapInfoHeader &bitmapInfoHeader, byte *initialPalette) + : _frameCount(frameCount), _vidsHeader(streamHeader), _bmInfo(bitmapInfoHeader), _initialPalette(initialPalette) { + _videoCodec = createCodec(); + _lastFrame = 0; + _curFrame = -1; + + useInitialPalette(); +} + +AVIDecoder::AVIVideoTrack::~AVIVideoTrack() { + delete _videoCodec; + delete[] _initialPalette; +} + +void AVIDecoder::AVIVideoTrack::decodeFrame(Common::SeekableReadStream *stream) { + if (stream) { + if (_videoCodec) + _lastFrame = _videoCodec->decodeFrame(*stream); + } else { + // Empty frame + _lastFrame = 0; + } + + delete stream; + _curFrame++; +} + +Graphics::PixelFormat AVIDecoder::AVIVideoTrack::getPixelFormat() const { + if (_videoCodec) + return _videoCodec->getPixelFormat(); + + return Graphics::PixelFormat(); +} + +void AVIDecoder::AVIVideoTrack::loadPaletteFromChunk(Common::SeekableReadStream *chunk) { + assert(chunk); + byte firstEntry = chunk->readByte(); + uint16 numEntries = chunk->readByte(); + chunk->readUint16LE(); // Reserved + + // 0 entries means all colors are going to be changed + if (numEntries == 0) + numEntries = 256; + + for (uint16 i = firstEntry; i < numEntries + firstEntry; i++) { + _palette[i * 3] = chunk->readByte(); + _palette[i * 3 + 1] = chunk->readByte(); + _palette[i * 3 + 2] = chunk->readByte(); + chunk->readByte(); // Flags that don't serve us any purpose + } + + delete chunk; + _dirtyPalette = true; +} + +void AVIDecoder::AVIVideoTrack::useInitialPalette() { + _dirtyPalette = false; + + if (_initialPalette) { + memcpy(_palette, _initialPalette, sizeof(_palette)); + _dirtyPalette = true; + } +} + +bool AVIDecoder::AVIVideoTrack::isTruemotion1() const { + return _bmInfo.compression == MKTAG('D', 'U', 'C', 'K') || _bmInfo.compression == MKTAG('d', 'u', 'c', 'k'); +} + +void AVIDecoder::AVIVideoTrack::forceDimensions(uint16 width, uint16 height) { + _bmInfo.width = width; + _bmInfo.height = height; +} + +bool AVIDecoder::AVIVideoTrack::rewind() { + _curFrame = -1; + + useInitialPalette(); + + delete _videoCodec; + _videoCodec = createCodec(); + _lastFrame = 0; + return true; +} + +Image::Codec *AVIDecoder::AVIVideoTrack::createCodec() { + return Image::createBitmapCodec(_bmInfo.compression, _bmInfo.width, _bmInfo.height, _bmInfo.bitCount); +} + +void AVIDecoder::AVIVideoTrack::forceTrackEnd() { + _curFrame = _frameCount - 1; +} + +const byte *AVIDecoder::AVIVideoTrack::getPalette() const { + if (_videoCodec && _videoCodec->containsPalette()) + return _videoCodec->getPalette(); + + _dirtyPalette = false; + return _palette; +} + +bool AVIDecoder::AVIVideoTrack::hasDirtyPalette() const { + if (_videoCodec && _videoCodec->containsPalette()) + return _videoCodec->hasDirtyPalette(); + + return _dirtyPalette; +} + +bool AVIDecoder::AVIVideoTrack::canDither() const { + return _videoCodec && _videoCodec->canDither(Image::Codec::kDitherTypeVFW); +} + +void AVIDecoder::AVIVideoTrack::setDither(const byte *palette) { + assert(_videoCodec); + _videoCodec->setDither(Image::Codec::kDitherTypeVFW, palette); +} + +AVIDecoder::AVIAudioTrack::AVIAudioTrack(const AVIStreamHeader &streamHeader, const PCMWaveFormat &waveFormat, Audio::Mixer::SoundType soundType) + : _audsHeader(streamHeader), _wvInfo(waveFormat), _soundType(soundType), _audioStream(0), _packetStream(0), _curChunk(0) { +} + +AVIDecoder::AVIAudioTrack::~AVIAudioTrack() { + delete _audioStream; +} + +void AVIDecoder::AVIAudioTrack::queueSound(Common::SeekableReadStream *stream) { + if (_packetStream) + _packetStream->queuePacket(stream); + else + delete stream; + + _curChunk++; +} + +void AVIDecoder::AVIAudioTrack::skipAudio(const Audio::Timestamp &time, const Audio::Timestamp &frameTime) { + Audio::Timestamp timeDiff = time.convertToFramerate(_wvInfo.samplesPerSec) - frameTime.convertToFramerate(_wvInfo.samplesPerSec); + int skipFrames = timeDiff.totalNumberOfFrames(); + + if (skipFrames <= 0) + return; + + Audio::AudioStream *audioStream = getAudioStream(); + if (!audioStream) + return; + + if (audioStream->isStereo()) + skipFrames *= 2; + + int16 *tempBuffer = new int16[skipFrames]; + audioStream->readBuffer(tempBuffer, skipFrames); + delete[] tempBuffer; +} + +void AVIDecoder::AVIAudioTrack::resetStream() { + delete _audioStream; + createAudioStream(); + _curChunk = 0; +} + +bool AVIDecoder::AVIAudioTrack::rewind() { + resetStream(); + return true; +} + +void AVIDecoder::AVIAudioTrack::createAudioStream() { + _packetStream = 0; + + switch (_wvInfo.tag) { + case kWaveFormatPCM: { + byte flags = 0; + if (_audsHeader.sampleSize == 2) + flags |= Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN; + else + flags |= Audio::FLAG_UNSIGNED; + + if (_wvInfo.channels == 2) + flags |= Audio::FLAG_STEREO; + + _packetStream = Audio::makePacketizedRawStream(_wvInfo.samplesPerSec, flags); + break; + } + case kWaveFormatMSADPCM: + _packetStream = Audio::makePacketizedADPCMStream(Audio::kADPCMMS, _wvInfo.samplesPerSec, _wvInfo.channels, _wvInfo.blockAlign); + break; + case kWaveFormatMSIMAADPCM: + _packetStream = Audio::makePacketizedADPCMStream(Audio::kADPCMMSIma, _wvInfo.samplesPerSec, _wvInfo.channels, _wvInfo.blockAlign); + break; + case kWaveFormatDK3: + _packetStream = Audio::makePacketizedADPCMStream(Audio::kADPCMDK3, _wvInfo.samplesPerSec, _wvInfo.channels, _wvInfo.blockAlign); + break; + case kWaveFormatMP3: +#ifdef USE_MAD + _packetStream = Audio::makePacketizedMP3Stream(_wvInfo.channels, _wvInfo.samplesPerSec); +#else + warning("AVI MP3 stream found, but no libmad support compiled in"); +#endif + break; + case kWaveFormatNone: + break; + default: + warning("Unsupported AVI audio format %d", _wvInfo.tag); + break; + } + + if (_packetStream) + _audioStream = _packetStream; + else + _audioStream = Audio::makeNullAudioStream(); +} + +AVIDecoder::TrackStatus::TrackStatus() : track(0), chunkSearchOffset(0) { +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/avi_decoder.h b/engines/titanic/support/avi_decoder.h new file mode 100644 index 0000000000..acc33cbc4d --- /dev/null +++ b/engines/titanic/support/avi_decoder.h @@ -0,0 +1,285 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_AVI_DECODER_H +#define TITANIC_AVI_DECODER_H + +#include "common/array.h" +#include "common/rational.h" +#include "common/rect.h" +#include "common/str.h" + +#include "video/video_decoder.h" +#include "audio/mixer.h" + +namespace Audio { +class AudioStream; +class PacketizedAudioStream; +} + +namespace Common { +class SeekableReadStream; +} + +namespace Graphics { +struct PixelFormat; +} + +namespace Image { +class Codec; +} + +namespace Titanic { + +/** + * Modified AVI Decoder used by Titanic engine. + */ +class AVIDecoder : public Video::VideoDecoder { +public: + AVIDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); + AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); + virtual ~AVIDecoder(); + + bool loadStream(Common::SeekableReadStream *stream); + void close(); + uint16 getWidth() const { return _header.width; } + uint16 getHeight() const { return _header.height; } + + bool rewind(); + bool isRewindable() const { return true; } + bool isSeekable() const; + +protected: + // VideoDecoder API + void readNextPacket(); + bool seekIntern(const Audio::Timestamp &time); + bool supportsAudioTrackSwitching() const { return true; } + AudioTrack *getAudioTrack(int index); + + struct BitmapInfoHeader { + uint32 size; + uint32 width; + uint32 height; + uint16 planes; + uint16 bitCount; + uint32 compression; + uint32 sizeImage; + uint32 xPelsPerMeter; + uint32 yPelsPerMeter; + uint32 clrUsed; + uint32 clrImportant; + }; + + struct WaveFormat { + uint16 tag; + uint16 channels; + uint32 samplesPerSec; + uint32 avgBytesPerSec; + uint16 blockAlign; + }; + + struct PCMWaveFormat : public WaveFormat { + uint16 size; + }; + + struct WaveFormatEX : public WaveFormat { + uint16 bitsPerSample; + uint16 size; + }; + + struct OldIndex { + uint32 id; + uint32 flags; + uint32 offset; + uint32 size; + }; + + // Index Flags + enum IndexFlags { + AVIIF_INDEX = 0x10 + }; + + struct AVIHeader { + uint32 size; + uint32 microSecondsPerFrame; + uint32 maxBytesPerSecond; + uint32 padding; + uint32 flags; + uint32 totalFrames; + uint32 initialFrames; + uint32 streams; + uint32 bufferSize; + uint32 width; + uint32 height; + }; + + // Flags from the AVIHeader + enum AVIFlags { + AVIF_HASINDEX = 0x00000010, + AVIF_MUSTUSEINDEX = 0x00000020, + AVIF_ISINTERLEAVED = 0x00000100, + AVIF_TRUSTCKTYPE = 0x00000800, + AVIF_WASCAPTUREFILE = 0x00010000, + AVIF_WASCOPYRIGHTED = 0x00020000 + }; + + struct AVIStreamHeader { + uint32 size; + uint32 streamType; + uint32 streamHandler; + uint32 flags; + uint16 priority; + uint16 language; + uint32 initialFrames; + uint32 scale; + uint32 rate; + uint32 start; + uint32 length; + uint32 bufferSize; + uint32 quality; + uint32 sampleSize; + Common::Rect frame; + }; + + class AVIVideoTrack : public FixedRateVideoTrack { + public: + AVIVideoTrack(int frameCount, const AVIStreamHeader &streamHeader, const BitmapInfoHeader &bitmapInfoHeader, byte *initialPalette = 0); + ~AVIVideoTrack(); + + void decodeFrame(Common::SeekableReadStream *stream); + void forceTrackEnd(); + + uint16 getWidth() const { return _bmInfo.width; } + uint16 getHeight() const { return _bmInfo.height; } + Graphics::PixelFormat getPixelFormat() const; + int getCurFrame() const { return _curFrame; } + int getFrameCount() const { return _frameCount; } + const Graphics::Surface *decodeNextFrame() { return _lastFrame; } + + const byte *getPalette() const; + bool hasDirtyPalette() const; + void setCurFrame(int frame) { _curFrame = frame; } + void loadPaletteFromChunk(Common::SeekableReadStream *chunk); + void useInitialPalette(); + bool canDither() const; + void setDither(const byte *palette); + + bool isTruemotion1() const; + void forceDimensions(uint16 width, uint16 height); + + bool isRewindable() const { return true; } + bool rewind(); + + protected: + Common::Rational getFrameRate() const { return Common::Rational(_vidsHeader.rate, _vidsHeader.scale); } + + private: + AVIStreamHeader _vidsHeader; + BitmapInfoHeader _bmInfo; + byte _palette[3 * 256]; + byte *_initialPalette; + mutable bool _dirtyPalette; + int _frameCount, _curFrame; + + Image::Codec *_videoCodec; + const Graphics::Surface *_lastFrame; + Image::Codec *createCodec(); + }; + + class AVIAudioTrack : public AudioTrack { + public: + AVIAudioTrack(const AVIStreamHeader &streamHeader, const PCMWaveFormat &waveFormat, Audio::Mixer::SoundType soundType); + ~AVIAudioTrack(); + + virtual void createAudioStream(); + virtual void queueSound(Common::SeekableReadStream *stream); + Audio::Mixer::SoundType getSoundType() const { return _soundType; } + void skipAudio(const Audio::Timestamp &time, const Audio::Timestamp &frameTime); + virtual void resetStream(); + uint32 getCurChunk() const { return _curChunk; } + void setCurChunk(uint32 chunk) { _curChunk = chunk; } + + bool isRewindable() const { return true; } + bool rewind(); + + protected: + Audio::AudioStream *getAudioStream() const { return _audioStream; } + + // Audio Codecs + enum { + kWaveFormatNone = 0, + kWaveFormatPCM = 1, + kWaveFormatMSADPCM = 2, + kWaveFormatMSIMAADPCM = 17, + kWaveFormatMP3 = 85, + kWaveFormatDK3 = 98 // rogue format number + }; + + AVIStreamHeader _audsHeader; + PCMWaveFormat _wvInfo; + Audio::Mixer::SoundType _soundType; + Audio::AudioStream *_audioStream; + Audio::PacketizedAudioStream *_packetStream; + uint32 _curChunk; + }; + + struct TrackStatus { + TrackStatus(); + + Track *track; + uint32 index; + uint32 chunkSearchOffset; + }; + + AVIHeader _header; + + void readOldIndex(uint32 size); + Common::Array _indexEntries; + + Common::SeekableReadStream *_fileStream; + bool _decodedHeader; + bool _foundMovieList; + uint32 _movieListStart, _movieListEnd; + + Audio::Mixer::SoundType _soundType; + Common::Rational _frameRateOverride; + void initCommon(); + + bool parseNextChunk(); + void skipChunk(uint32 size); + void handleList(uint32 listSize); + void handleStreamHeader(uint32 size); + uint16 getStreamType(uint32 tag) const { return tag & 0xFFFF; } + byte getStreamIndex(uint32 tag) const; + void checkTruemotion1(); + + void handleNextPacket(TrackStatus& status); + bool shouldQueueAudio(TrackStatus& status); + Common::Array _videoTracks, _audioTracks; + +public: + virtual AVIAudioTrack *createAudioTrack(AVIStreamHeader sHeader, PCMWaveFormat wvInfo); +}; + +} // End of namespace Titanic + +#endif diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index ed5cffaac1..25909183dd 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -20,6 +20,8 @@ * */ +#include "image/codecs/cinepak.h" +#include "titanic/support/avi_decoder.h" #include "titanic/support/movie.h" #include "titanic/titanic.h" @@ -44,7 +46,13 @@ bool CMovie::get10() { /*------------------------------------------------------------------------*/ OSMovie::OSMovie(const CResourceKey &name, CVideoSurface *surface) : _videoSurface(surface) { -// _aviDecoder.loadFile(name.getString()); + _video = new AVIDecoder(); + if (!_video->loadFile(name.getString())) + error("Could not open video - %s", name.getString().c_str()); +} + +OSMovie::~OSMovie() { + delete _video; } void OSMovie::proc8(int v1, CVideoSurface *surface) { @@ -76,13 +84,12 @@ void OSMovie::proc14() { } void OSMovie::setFrame(uint frameNumber) { - warning("TODO: OSMovie::setFrame"); - /* - _aviDecoder.seekToFrame(frameNumber); - const Graphics::Surface *s = _aviDecoder.decodeNextFrame(); + _video->seekToFrame(frameNumber); + const Graphics::Surface *s = _video->decodeNextFrame(); + Graphics::Surface *surf = s->convertTo(g_system->getScreenFormat()); - _videoSurface->blitFrom(Common::Point(0, 0), s); - */ + _videoSurface->blitFrom(Common::Point(0, 0), surf); + delete surf; } void OSMovie::proc16() { diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index 3529409fa5..e84e283597 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -23,7 +23,7 @@ #ifndef TITANIC_MOVIE_H #define TITANIC_MOVIE_H -#include "video/avi_decoder.h" +#include "video/video_decoder.h" #include "titanic/core/list.h" #include "titanic/core/resource_key.h" @@ -37,6 +37,7 @@ protected: int _field10; public: CMovie(); + virtual ~CMovie() {} virtual void proc8(int v1, CVideoSurface *surface) = 0; virtual void proc9() = 0; @@ -60,10 +61,11 @@ public: class OSMovie : public CMovie { private: - Video::AVIDecoder _aviDecoder; + Video::VideoDecoder *_video; CVideoSurface *_videoSurface; public: OSMovie(const CResourceKey &name, CVideoSurface *surface); + virtual ~OSMovie(); virtual void proc8(int v1, CVideoSurface *surface); virtual void proc9(); -- cgit v1.2.3 From f65849084cc88d61168742b02553fb269a9f064e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 5 Apr 2016 13:01:53 -0400 Subject: TITANIC: Fix display of initial cursor --- engines/titanic/support/mouse_cursor.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp index dda16c3b93..6db3618003 100644 --- a/engines/titanic/support/mouse_cursor.cpp +++ b/engines/titanic/support/mouse_cursor.cpp @@ -95,9 +95,6 @@ void CMouseCursor::setCursor(CursorId cursorId) { CVideoSurface &surface = *ce._videoSurface; surface.lock(); - // ***DEBUG*** Dummy cursor - Common::fill(surface.getPixels(), surface.getPixels() + 128, 0x5555); - CursorMan.replaceCursor(surface.getPixels(), surface.getWidth(), surface.getHeight(), ce._centroid.x, ce._centroid.y, 0, false, &g_vm->_screen->format); surface.unlock(); -- cgit v1.2.3 From 6f8de06ddb210f71f611e2cfcee106832d100a78 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 5 Apr 2016 13:19:43 -0400 Subject: TITANIC: Fix loading of ycursors.avi video that contains mouse cursors The mouse ccursor is now working correctly in-game, and correctly changing when different areas of the view are highlighted --- engines/titanic/support/avi_decoder.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_decoder.cpp b/engines/titanic/support/avi_decoder.cpp index 81d8a58b8d..578e3a94ea 100644 --- a/engines/titanic/support/avi_decoder.cpp +++ b/engines/titanic/support/avi_decoder.cpp @@ -265,7 +265,10 @@ void AVIDecoder::handleStreamHeader(uint32 size) { } } - addTrack(new AVIVideoTrack(_header.totalFrames, sHeader, bmInfo, initialPalette)); + // WORKAROUND: For Titanic engine, the ycursors.avi file has two video tracks, + // so we do an explicit check below to ignore any second video track + if (getFrameCount() == 0) + addTrack(new AVIVideoTrack(_header.totalFrames, sHeader, bmInfo, initialPalette)); } else if (sHeader.streamType == ID_AUDS) { PCMWaveFormat wvInfo; wvInfo.tag = _fileStream->readUint16LE(); -- cgit v1.2.3 From 4f46928444acb1da4e7cd31ac816ad6c9e7c265d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 5 Apr 2016 20:15:14 -0400 Subject: TITANIC: Fix loading of game object bounds --- engines/titanic/support/simple_file.cpp | 15 +++++++++++++++ engines/titanic/support/simple_file.h | 10 ++++++++++ 2 files changed, 25 insertions(+) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/simple_file.cpp b/engines/titanic/support/simple_file.cpp index fccf6c5b4f..88d74a9f47 100644 --- a/engines/titanic/support/simple_file.cpp +++ b/engines/titanic/support/simple_file.cpp @@ -213,6 +213,16 @@ Rect SimpleFile::readRect() { 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) { @@ -309,6 +319,11 @@ void SimpleFile::writeRect(const Rect &r, int indent) { writePoint(Point(r.right, r.bottom), indent); } +void SimpleFile::writeBounds(const Rect &r, int indent) { + writePoint(Point(r.left, r.top), indent); + writePoint(Point(r.width(), r.height()), indent); +} + void SimpleFile::writeIndent(uint indent) { for (uint idx = 0; idx < indent; ++idx) write("\t", 1); diff --git a/engines/titanic/support/simple_file.h b/engines/titanic/support/simple_file.h index 0ba7699088..115e3805da 100644 --- a/engines/titanic/support/simple_file.h +++ b/engines/titanic/support/simple_file.h @@ -111,6 +111,11 @@ public: */ Rect readRect(); + /** + * Rect in a bounds + */ + Rect readBounds(); + /** * Read a string and copy it into an optionally passed buffer */ @@ -166,6 +171,11 @@ public: */ void writeRect(const Rect &r, int indent); + /** + * Write out a bounds line + */ + void writeBounds(const Rect &r, int indent); + /** * Write out a number of tabs to form an indent in the output */ -- cgit v1.2.3 From 19e4bca41c6ecc1f4f71f04d919af75bc14f2d58 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 5 Apr 2016 21:14:34 -0400 Subject: TITANIC: Set up cursors enum with better names --- engines/titanic/support/mouse_cursor.cpp | 4 ++-- engines/titanic/support/mouse_cursor.h | 30 +++++++++++++++--------------- 2 files changed, 17 insertions(+), 17 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp index 6db3618003..c4c57c6f07 100644 --- a/engines/titanic/support/mouse_cursor.cpp +++ b/engines/titanic/support/mouse_cursor.cpp @@ -50,9 +50,9 @@ static const int CURSOR_DATA[NUM_CURSORS][4] = { }; CMouseCursor::CMouseCursor(CScreenManager *screenManager) : - _screenManager(screenManager), _cursorId(CURSOR_15) { + _screenManager(screenManager), _cursorId(CURSOR_HOURGLASS) { loadCursorImages(); - setCursor(CURSOR_1); + setCursor(CURSOR_ARROW); } CMouseCursor::~CMouseCursor() { diff --git a/engines/titanic/support/mouse_cursor.h b/engines/titanic/support/mouse_cursor.h index 507f4ecc17..28e13a82c4 100644 --- a/engines/titanic/support/mouse_cursor.h +++ b/engines/titanic/support/mouse_cursor.h @@ -31,21 +31,21 @@ namespace Titanic { #define NUM_CURSORS 15 enum CursorId { - CURSOR_1 = 1, - CURSOR_2 = 3, - CURSOR_3 = 3, - CURSOR_4 = 4, - CURSOR_5 = 5, - CURSOR_6 = 6, - CURSOR_7 = 7, - CURSOR_8 = 8, - CURSOR_9 = 9, - CURSOR_10 = 10, - CURSOR_11 = 11, - CURSOR_12 = 12, - CURSOR_13 = 13, - CURSOR_14 = 14, - CURSOR_15 = 15 + CURSOR_ARROW = 1, + CURSOR_MOVE_LEFT = 2, + CURSOR_MOVE_RIGHT = 3, + CURSOR_MOVE_FORWARD = 4, + CURSOR_MOVE_UP = 5, + CURSOR_MOVE_DOWN1 = 6, + CURSOR_MOVE_FORWARD2 = 7, + CURSOR_HAND = 8, + CURSOR_STAR = 9, + CURSOR_INVALID = 10, + CURSOR_MAGNIFIER = 11, + CURSOR_ARROW2 = 12, + CURSOR_BACKWARDS = 13, + CURSOR_DOWN = 14, + CURSOR_HOURGLASS = 15 }; class CScreenManager; -- cgit v1.2.3 From 08ed54f6c9fd72313e759d494a0b92cace2218e8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 6 Apr 2016 07:55:55 -0400 Subject: TITANIC: Beginnings of CProximity class --- engines/titanic/support/proximity.cpp | 36 ++++++++++++++++++++ engines/titanic/support/proximity.h | 62 +++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 engines/titanic/support/proximity.cpp create mode 100644 engines/titanic/support/proximity.h (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/proximity.cpp b/engines/titanic/support/proximity.cpp new file mode 100644 index 0000000000..f7c90f7caf --- /dev/null +++ b/engines/titanic/support/proximity.cpp @@ -0,0 +1,36 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "titanic/support/proximity.h" + +namespace Titanic { + +CProximity::CProximity() : _field4(0), _field8(100), _fieldC(0), + _field10(-1), _field14(0), _field18(0), _field1C(0x3FF00000), + _field20(0), _field24(10), _field28(0), _field2C(0), + _field30(0x3F000000), _field34(0), _double1(0.0), _double2(0.0), + _double3(0.0), _field44(0), _field48(0), _field4C(0), + _field50(0), _field54(0), _field58(0), _field5C(0), + _field60(0), _field64(0), _field68(0) { +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/proximity.h b/engines/titanic/support/proximity.h new file mode 100644 index 0000000000..69979eaeaf --- /dev/null +++ b/engines/titanic/support/proximity.h @@ -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 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_PROXIMITY_H +#define TITANIC_PROXIMITY_H + +namespace Titanic { + +class CProximity { +public: + int _field4; + int _field8; + int _fieldC; + int _field10; + int _field14; + int _field18; + int _field1C; + int _field20; + int _field24; + int _field28; + int _field2C; + int _field30; + int _field34; + double _double1; + double _double2; + double _double3; + int _field44; + int _field48; + int _field4C; + int _field50; + int _field54; + int _field58; + int _field5C; + int _field60; + int _field64; + int _field68; +public: + CProximity(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_PROXIMITY_H */ -- cgit v1.2.3 From ac59f58c8a65e9e27a696da4536693c7d6ec6bc9 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 6 Apr 2016 19:42:45 -0400 Subject: TITANIC: Implement CBackground message handlers --- engines/titanic/support/movie.cpp | 2 +- engines/titanic/support/movie.h | 4 ++-- engines/titanic/support/video_surface.cpp | 6 ++++++ engines/titanic/support/video_surface.h | 2 ++ 4 files changed, 11 insertions(+), 3 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 25909183dd..846dc09d5c 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -59,7 +59,7 @@ void OSMovie::proc8(int v1, CVideoSurface *surface) { warning("TODO: OSMovie::proc8"); } -void OSMovie::proc9() { +void OSMovie::proc9(int v1, int v2, int v3, bool v4) { warning("TODO: OSMovie::proc9"); } diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index e84e283597..b5ae70de13 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -40,7 +40,7 @@ public: virtual ~CMovie() {} virtual void proc8(int v1, CVideoSurface *surface) = 0; - virtual void proc9() = 0; + virtual void proc9(int v1, int v2, int v3, bool v4) = 0; virtual void proc10() = 0; virtual void proc11() = 0; virtual void proc12() = 0; @@ -68,7 +68,7 @@ public: virtual ~OSMovie(); virtual void proc8(int v1, CVideoSurface *surface); - virtual void proc9(); + virtual void proc9(int v1, int v2, int v3, bool v4); virtual void proc10(); virtual void proc11(); virtual void proc12(); diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index a1b26386b3..1a0d48bebe 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -368,6 +368,12 @@ void OSVideoSurface::proc32(int v1, CVideoSurface *surface) { _movie->proc8(v1, surface); } +void OSVideoSurface::proc34(int v1, int v2, int v3, bool v4) { + if (loadIfReady() && _movie) { + _movie->proc9(v1, v2, v3, v4); + } +} + void OSVideoSurface::stopMovie() { if (_movie) _movie->stop(); diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index e1ddde8013..767306cae6 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -153,6 +153,7 @@ public: virtual void shiftColors() = 0; virtual void proc32(int v1, CVideoSurface *surface) = 0; + virtual void proc34(int v1, int v2, int v3, bool v4) = 0; /** * Stops any movie currently attached to the surface @@ -299,6 +300,7 @@ public: virtual void shiftColors(); virtual void proc32(int v1, CVideoSurface *surface); + virtual void proc34(int v1, int v2, int v3, bool v4); /** * Stops any movie currently attached to the surface -- cgit v1.2.3 From e728e901d02aca51858f91ac29b1a177e5e80a07 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 6 Apr 2016 20:32:18 -0400 Subject: TITANIC: Fix for showing link cursors in some screens --- engines/titanic/support/mouse_cursor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/mouse_cursor.h b/engines/titanic/support/mouse_cursor.h index 28e13a82c4..831e207632 100644 --- a/engines/titanic/support/mouse_cursor.h +++ b/engines/titanic/support/mouse_cursor.h @@ -39,7 +39,7 @@ enum CursorId { CURSOR_MOVE_DOWN1 = 6, CURSOR_MOVE_FORWARD2 = 7, CURSOR_HAND = 8, - CURSOR_STAR = 9, + CURSOR_ACTIVATE = 9, CURSOR_INVALID = 10, CURSOR_MAGNIFIER = 11, CURSOR_ARROW2 = 12, -- cgit v1.2.3 From bc7a7deb775568cdbe205e3f8c4f5ebd03e34141 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 7 Apr 2016 00:06:18 -0400 Subject: TITANIC: Fix showing custom cursors when highlighting objects --- engines/titanic/support/mouse_cursor.cpp | 4 +++- engines/titanic/support/mouse_cursor.h | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp index c4c57c6f07..a2bd11657c 100644 --- a/engines/titanic/support/mouse_cursor.cpp +++ b/engines/titanic/support/mouse_cursor.cpp @@ -50,7 +50,7 @@ static const int CURSOR_DATA[NUM_CURSORS][4] = { }; CMouseCursor::CMouseCursor(CScreenManager *screenManager) : - _screenManager(screenManager), _cursorId(CURSOR_HOURGLASS) { + _screenManager(screenManager), _cursorId(CURSOR_HOURGLASS), _setCursorCount(0) { loadCursorImages(); setCursor(CURSOR_ARROW); } @@ -90,6 +90,8 @@ void CMouseCursor::hide() { } void CMouseCursor::setCursor(CursorId cursorId) { + ++_setCursorCount; + if (cursorId != _cursorId) { CursorEntry &ce = _cursors[cursorId - 1]; CVideoSurface &surface = *ce._videoSurface; diff --git a/engines/titanic/support/mouse_cursor.h b/engines/titanic/support/mouse_cursor.h index 831e207632..6e1e6f7c3e 100644 --- a/engines/titanic/support/mouse_cursor.h +++ b/engines/titanic/support/mouse_cursor.h @@ -61,6 +61,7 @@ private: CScreenManager *_screenManager; CursorId _cursorId; CursorEntry _cursors[NUM_CURSORS]; + uint _setCursorCount; /** * Load the images for each cursor @@ -89,6 +90,11 @@ public: * Updates the mouse cursor */ void update(); + + /** + * Returns the number of times the cursor has been set + */ + uint getChangeCount() const { return _setCursorCount; } }; -- cgit v1.2.3 From 6fd32e6dc10e8b3332b0438c069a61f009185441 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 7 Apr 2016 19:50:16 -0400 Subject: TITANIC: Minor change to Cursor enum --- engines/titanic/support/mouse_cursor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/mouse_cursor.h b/engines/titanic/support/mouse_cursor.h index 6e1e6f7c3e..ac5da26382 100644 --- a/engines/titanic/support/mouse_cursor.h +++ b/engines/titanic/support/mouse_cursor.h @@ -42,7 +42,7 @@ enum CursorId { CURSOR_ACTIVATE = 9, CURSOR_INVALID = 10, CURSOR_MAGNIFIER = 11, - CURSOR_ARROW2 = 12, + CURSOR_IGNORE = 12, CURSOR_BACKWARDS = 13, CURSOR_DOWN = 14, CURSOR_HOURGLASS = 15 -- cgit v1.2.3 From e7f2cb1ecbf2637db8dd7be3fe97d485a7c56bc8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 7 Apr 2016 23:39:26 -0400 Subject: TITANIC: Add CComputer messages, more view change logic --- engines/titanic/support/screen_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/screen_manager.cpp b/engines/titanic/support/screen_manager.cpp index 05dfa66854..d2f2468c89 100644 --- a/engines/titanic/support/screen_manager.cpp +++ b/engines/titanic/support/screen_manager.cpp @@ -110,7 +110,7 @@ void OSScreenManager::setMode(int width, int height, int bpp, uint numBackSurfac } void OSScreenManager::drawCursors() { - warning("OSScreenManager::drawCursors"); + // Nothing needed here, since ScummVM handles cursor drawing } DirectDrawSurface *OSScreenManager::getDDSurface(SurfaceNum surfaceNum) { -- cgit v1.2.3 From e3d02532f7a64f194a802e29abef4b03eb6395b4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 8 Apr 2016 20:46:03 -0400 Subject: TITANIC: Implementing preliminary video playback code --- engines/titanic/support/movie.cpp | 59 +++++++++++++++++++++++++++++---- engines/titanic/support/movie.h | 25 +++++++++++--- engines/titanic/support/video_surface.h | 1 + 3 files changed, 74 insertions(+), 11 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 846dc09d5c..4fccc571ee 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -27,11 +27,11 @@ namespace Titanic { -CMovie::CMovie() : ListItem(), _state(0), _field10(0) { +CMovie::CMovie() : ListItem(), _state(MOVIE_STOPPED), _field10(0) { } bool CMovie::isActive() const { - return g_vm->_movieList.contains(this); + return g_vm->_activeMovies.contains(this); } bool CMovie::get10() { @@ -52,6 +52,7 @@ OSMovie::OSMovie(const CResourceKey &name, CVideoSurface *surface) : _videoSurfa } OSMovie::~OSMovie() { + g_vm->_activeMovies.remove(this); delete _video; } @@ -61,6 +62,10 @@ void OSMovie::proc8(int v1, CVideoSurface *surface) { void OSMovie::proc9(int v1, int v2, int v3, bool v4) { warning("TODO: OSMovie::proc9"); + //setFrame(v1); ? + _video->start(); + g_vm->_activeMovies.push_back(this); + _state = MOVIE_NONE; } void OSMovie::proc10() { @@ -85,11 +90,7 @@ void OSMovie::proc14() { void OSMovie::setFrame(uint frameNumber) { _video->seekToFrame(frameNumber); - const Graphics::Surface *s = _video->decodeNextFrame(); - Graphics::Surface *surf = s->convertTo(g_system->getScreenFormat()); - - _videoSurface->blitFrom(Common::Point(0, 0), surf); - delete surf; + decodeFrame(); } void OSMovie::proc16() { @@ -118,4 +119,48 @@ void *OSMovie::proc21() { return nullptr; } +MovieState OSMovie::getState() { + if (!_video) + _state = MOVIE_STOPPED; + return _state; +} + +void OSMovie::update() { + if (_state != MOVIE_STOPPED) { + if (_video->isPlaying()) { + if (_video->needsUpdate()) { + decodeFrame(); + _state = MOVIE_FRAME; + } else { + _state = MOVIE_NONE; + } + } else { + _state = MOVIE_STOPPED; + } + } +} + +void OSMovie::decodeFrame() { + const Graphics::Surface *frame = _video->decodeNextFrame(); + OSVideoSurface *videoSurface = static_cast(_videoSurface); + assert(videoSurface); + + videoSurface->lock(); + assert(videoSurface->_rawSurface); + + if (frame->format == videoSurface->_rawSurface->format) { + // Matching format, so we can copy straight from the video frame + videoSurface->_rawSurface->blitFrom(*frame); + } else { + // Different formats so we have to convert it first + Graphics::Surface *s = frame->convertTo(videoSurface->_rawSurface->format); + videoSurface->_rawSurface->blitFrom(*s); + + s->free(); + delete s; + } + + videoSurface->unlock(); +} + } // End of namespace Titanic diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index b5ae70de13..dfb0ca108a 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -29,11 +29,20 @@ namespace Titanic { +enum MovieState { + MOVIE_STOPPED = -1, MOVIE_NONE = 0, MOVIE_FINISHED = 1, MOVIE_FRAME = 2 +}; + class CVideoSurface; +class CMovie; + +class CMovieList : public List { +public: +}; class CMovie : public ListItem { protected: - int _state; + MovieState _state; int _field10; public: CMovie(); @@ -57,12 +66,20 @@ public: bool isActive() const; bool get10(); + + virtual MovieState getState() = 0; + virtual void update() = 0; }; class OSMovie : public CMovie { private: Video::VideoDecoder *_video; CVideoSurface *_videoSurface; + + /** + * Decodes the next frame + */ + void decodeFrame(); public: OSMovie(const CResourceKey &name, CVideoSurface *surface); virtual ~OSMovie(); @@ -86,10 +103,10 @@ public: virtual int proc19(); virtual void proc20(); virtual void *proc21(); -}; -class CGlobalMovies : public List { -public: + + virtual MovieState getState(); + virtual void update(); }; } // End of namespace Titanic diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index 767306cae6..d39dea627b 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -208,6 +208,7 @@ public: }; class OSVideoSurface : public CVideoSurface { + friend class OSMovie; private: static byte _map[0x400]; -- cgit v1.2.3 From 09a3ca07287b77d4abd5713b6c34548ebd8b84a8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 8 Apr 2016 23:01:02 -0400 Subject: TITANIC: Implement movie loading --- engines/titanic/support/movie.cpp | 6 ++++++ engines/titanic/support/video_surface.cpp | 22 +++++++++++++++++++--- engines/titanic/support/video_surface.h | 12 ++++++++---- 3 files changed, 33 insertions(+), 7 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 4fccc571ee..d614ea7d9b 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -145,6 +145,11 @@ void OSMovie::decodeFrame() { OSVideoSurface *videoSurface = static_cast(_videoSurface); assert(videoSurface); + // If the video surface doesn't yet have an underlying surface, create it + if (!videoSurface->hasSurface()) + videoSurface->resize(frame->w, frame->h); + + // Lock access to the surface videoSurface->lock(); assert(videoSurface->_rawSurface); @@ -160,6 +165,7 @@ void OSMovie::decodeFrame() { delete s; } + // Unlock the surface videoSurface->unlock(); } diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index 1a0d48bebe..c7b437e1e7 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -241,8 +241,24 @@ void OSVideoSurface::loadJPEG(const CResourceKey &key) { _resourceKey = key; } -void OSVideoSurface::loadMovie() { - warning("TODO"); +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 = new OSMovie(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() { @@ -329,7 +345,7 @@ bool OSVideoSurface::load() { return true; case FILETYPE_MOVIE: - loadMovie(); + loadMovie(_resourceKey); return true; default: diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index d39dea627b..335215d1df 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -93,9 +93,11 @@ public: virtual void loadJPEG(const CResourceKey &key) = 0; /** - * Loads a movie file specified by the resource key + * 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() = 0; + virtual void loadMovie(const CResourceKey &key, bool destroyFlag = false) = 0; /** * Lock the surface for direct access to the pixels @@ -241,9 +243,11 @@ public: virtual void loadJPEG(const CResourceKey &key); /** - * Loads a movie file specified by the resource key + * 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(); + virtual void loadMovie(const CResourceKey &key, bool destroyFlag = false); /** * Lock the surface for direct access to the pixels -- cgit v1.2.3 From 3d166fb8a91a4d56bc1abac6f1e3899a0379cd31 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 Apr 2016 14:24:52 -0400 Subject: TITANIC: More implementation code for movie playback --- engines/titanic/support/movie.cpp | 3 ++- engines/titanic/support/movie.h | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index d614ea7d9b..f2c5643f78 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -45,7 +45,8 @@ bool CMovie::get10() { /*------------------------------------------------------------------------*/ -OSMovie::OSMovie(const CResourceKey &name, CVideoSurface *surface) : _videoSurface(surface) { +OSMovie::OSMovie(const CResourceKey &name, CVideoSurface *surface) : + _videoSurface(surface), _gameObject(nullptr) { _video = new AVIDecoder(); if (!_video->loadFile(name.getString())) error("Could not open video - %s", name.getString().c_str()); diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index dfb0ca108a..0772635908 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -35,6 +35,7 @@ enum MovieState { class CVideoSurface; class CMovie; +class CGameObject; class CMovieList : public List { public: @@ -80,6 +81,8 @@ private: * Decodes the next frame */ void decodeFrame(); +public: + CGameObject *_gameObject; public: OSMovie(const CResourceKey &name, CVideoSurface *surface); virtual ~OSMovie(); -- cgit v1.2.3 From 6405ba6ecbbec9a8e45e6093bcacf2cab7f3b94b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 Apr 2016 17:12:41 -0400 Subject: TITANIC: Starting to flesh out timers --- engines/titanic/support/timer.cpp | 109 ++++++++++++++++++++++++++++++++++++++ engines/titanic/support/timer.h | 94 ++++++++++++++++++++++++++++++++ 2 files changed, 203 insertions(+) create mode 100644 engines/titanic/support/timer.cpp create mode 100644 engines/titanic/support/timer.h (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/timer.cpp b/engines/titanic/support/timer.cpp new file mode 100644 index 0000000000..6f99a67fd8 --- /dev/null +++ b/engines/titanic/support/timer.cpp @@ -0,0 +1,109 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "titanic/support/timer.h" +#include "titanic/core/project_item.h" + +namespace Titanic { + +void CTimerList::postLoad(uint ticks, CProjectItem *project) { + for (iterator i = begin(); i != end(); ++i) + (*i)->postLoad(ticks, project); +} + +void CTimerList::preSave() { + for (iterator i = begin(); i != end(); ++i) + (*i)->preSave(); +} + +void CTimerList::postSave() { + for (iterator i = begin(); i != end(); ++i) + (*i)->postSave(); +} + +void CTimerList::update(uint ticks) { + // Remove any items that are done + for (iterator i = begin(); i != end(); ) { + CTimer *item = *i; + if (item->_done) { + i = erase(i); + delete item; + } else { + ++i; + } + } + + // Handle updating the items + for (iterator i = begin(); i != end(); ) { + CTimer *item = *i; + if (!item->update(ticks)) { + ++i; + } else { + i = erase(i); + delete item; + } + } +} + +void CTimerList::stop(uint id) { + for (iterator i = begin(); i != end(); ++i) { + CTimer *item = *i; + if (item->_id == id) { + item->_done = true; + return; + } + } +} + +void CTimerList::set44(uint id, uint val) { + for (iterator i = begin(); i != end(); ++i) { + CTimer *item = *i; + if (item->_id == id) { + item->set44(val); + return; + } + } +} + +/*------------------------------------------------------------------------*/ + +CTimer::CTimer() : _id(0), _done(false), + _field44(0) { +} + +void CTimer::postLoad(uint ticks, CProjectItem *project) { + warning("TODO"); +} + +void CTimer::preSave() { + warning("TODO: CTimer::preSave"); +} + +void CTimer::postSave() { + warning("TODO: CTimer::postSave"); +} + +bool CTimer::update(uint ticks) { + return false; +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/timer.h b/engines/titanic/support/timer.h new file mode 100644 index 0000000000..4d74bae34c --- /dev/null +++ b/engines/titanic/support/timer.h @@ -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 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_TIMER_H +#define TITANIC_TIMER_H + +#include "titanic/core/list.h" + +namespace Titanic { + +class CProjectItem; + +class CTimer : public ListItem { +private: + static int _v1; +public: + uint _id; + bool _done; + uint _field44; +public: + CTimer(); + + /** + * Called after loading a game has finished + */ + void postLoad(uint ticks, CProjectItem *project); + + /** + * Called when a game is about to be saved + */ + void preSave(); + + /** + * Called when a game has finished being saved + */ + void postSave(); + + bool update(uint ticks); + + void set44(uint val) { _field44 = val; } +}; + +class CTimerList : public List { +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(); + + /** + * 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); + + void set44(uint id, uint val); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TIMER_H */ -- cgit v1.2.3 From f7748622faa71729d12f3d0ec063417bdca60eb6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 Apr 2016 19:36:12 -0400 Subject: TITANIC: Further implementation of timers --- engines/titanic/support/time_event_info.cpp | 206 ++++++++++++++++++++++++++++ engines/titanic/support/time_event_info.h | 134 ++++++++++++++++++ engines/titanic/support/timer.cpp | 109 --------------- engines/titanic/support/timer.h | 94 ------------- 4 files changed, 340 insertions(+), 203 deletions(-) create mode 100644 engines/titanic/support/time_event_info.cpp create mode 100644 engines/titanic/support/time_event_info.h delete mode 100644 engines/titanic/support/timer.cpp delete mode 100644 engines/titanic/support/timer.h (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/time_event_info.cpp b/engines/titanic/support/time_event_info.cpp new file mode 100644 index 0000000000..c3312de7d7 --- /dev/null +++ b/engines/titanic/support/time_event_info.cpp @@ -0,0 +1,206 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "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::set44(uint id, uint val) { + for (iterator i = begin(); i != end(); ++i) { + CTimeEventInfo *item = *i; + if (item->_id == id) { + item->set44(val); + return; + } + } +} + +/*------------------------------------------------------------------------*/ + +uint CTimeEventInfo::_nextId; + +CTimeEventInfo::CTimeEventInfo() : ListItem(), _lockCounter(0), + _field14(0), _firstDuration(0), _duration(0), _target(nullptr), + _actionVal(0), _field2C(0), _field30(0), _timerCtr(0), + _lastTimerTicks(0), _field3C(0), _done(false), _field44(0) { + _id = _nextId++; +} + +CTimeEventInfo::CTimeEventInfo(uint ticks, uint f14, uint firstDuration, + uint duration, CTreeItem *target, int timerVal3, const CString &action) : + ListItem(), _lockCounter(0), _field14(f14), _firstDuration(firstDuration), + _duration(duration), _target(target), _field2C(0), _field30(0), + _timerCtr(0), _lastTimerTicks(ticks), _field3C(0), _done(false), + _field44(true) { + _id = _nextId++; +} + +void CTimeEventInfo::save(SimpleFile *file, int indent) const { + file->writeNumberLine(0, indent); + + CString targetName; + if (_target) + targetName = _target->getName(); + file->writeQuotedLine(targetName, indent); + file->writeNumberLine(_id, indent); + file->writeNumberLine(_field14, indent); + file->writeNumberLine(_firstDuration, indent); + file->writeNumberLine(_duration, indent); + file->writeNumberLine(_actionVal, indent); + file->writeQuotedLine(_action, indent); + file->writeNumberLine(_timerCtr, indent); + file->writeNumberLine(_field3C, indent); + file->writeNumberLine(_done, indent); + file->writeNumberLine(_field44, indent); +} + +void CTimeEventInfo::load(SimpleFile *file) { + lock(); + int val = file->readNumber(); + + if (!val) { + _targetName = file->readString(); + _id = file->readNumber(); + _field14 = file->readNumber(); + _firstDuration = file->readNumber(); + _duration = file->readNumber(); + _actionVal = file->readNumber(); + _action = file->readString(); + _timerCtr = file->readNumber(); + _field3C = file->readNumber(); + _done = file->readNumber() != 0; + _field44 = file->readNumber(); + _target = nullptr; + } +} + +void CTimeEventInfo::postLoad(uint ticks, CProjectItem *project) { + if (!_field44 || _targetName.empty()) + _done = true; + + // Get the timer's target + if (project) + _target = project->findByName(_targetName); + if (!_target) + _done = true; + + _lastTimerTicks = ticks + _field3C; + if (_id >= _nextId) + _nextId = _id + 1; + + unlock(); +} + +void CTimeEventInfo::preSave(uint ticks) { + _field3C = _lastTimerTicks - ticks; + lock(); +} + +void CTimeEventInfo::postSave() { + unlock(); +} + +bool CTimeEventInfo::update(uint ticks) { + if (_lockCounter) + return false; + + if (_timerCtr) { + if (ticks > (_lastTimerTicks + _duration)) { + ++_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 (!_field14) + return true; + } + } + + return false; +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/time_event_info.h b/engines/titanic/support/time_event_info.h new file mode 100644 index 0000000000..ee923f5fcb --- /dev/null +++ b/engines/titanic/support/time_event_info.h @@ -0,0 +1,134 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef 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; + uint _field14; + uint _firstDuration; + uint _duration; + CTreeItem *_target; + uint _actionVal; + CString _action; + uint _field2C; + uint _field30; + uint _timerCtr; + uint _lastTimerTicks; + uint _field3C; + bool _done; + uint _field44; + CString _targetName; +public: + CLASSDEF + CTimeEventInfo(); + CTimeEventInfo(uint ticks, uint f14, uint firstDuration, uint duration, + CTreeItem *target, int timerVal3, const CString &action); + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent) const; + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * 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); + + void set44(uint val) { _field44 = val; } +}; + +class CTimeEventInfoList : public List { +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); + + void set44(uint id, uint val); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_TIMER_H */ diff --git a/engines/titanic/support/timer.cpp b/engines/titanic/support/timer.cpp deleted file mode 100644 index 6f99a67fd8..0000000000 --- a/engines/titanic/support/timer.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "titanic/support/timer.h" -#include "titanic/core/project_item.h" - -namespace Titanic { - -void CTimerList::postLoad(uint ticks, CProjectItem *project) { - for (iterator i = begin(); i != end(); ++i) - (*i)->postLoad(ticks, project); -} - -void CTimerList::preSave() { - for (iterator i = begin(); i != end(); ++i) - (*i)->preSave(); -} - -void CTimerList::postSave() { - for (iterator i = begin(); i != end(); ++i) - (*i)->postSave(); -} - -void CTimerList::update(uint ticks) { - // Remove any items that are done - for (iterator i = begin(); i != end(); ) { - CTimer *item = *i; - if (item->_done) { - i = erase(i); - delete item; - } else { - ++i; - } - } - - // Handle updating the items - for (iterator i = begin(); i != end(); ) { - CTimer *item = *i; - if (!item->update(ticks)) { - ++i; - } else { - i = erase(i); - delete item; - } - } -} - -void CTimerList::stop(uint id) { - for (iterator i = begin(); i != end(); ++i) { - CTimer *item = *i; - if (item->_id == id) { - item->_done = true; - return; - } - } -} - -void CTimerList::set44(uint id, uint val) { - for (iterator i = begin(); i != end(); ++i) { - CTimer *item = *i; - if (item->_id == id) { - item->set44(val); - return; - } - } -} - -/*------------------------------------------------------------------------*/ - -CTimer::CTimer() : _id(0), _done(false), - _field44(0) { -} - -void CTimer::postLoad(uint ticks, CProjectItem *project) { - warning("TODO"); -} - -void CTimer::preSave() { - warning("TODO: CTimer::preSave"); -} - -void CTimer::postSave() { - warning("TODO: CTimer::postSave"); -} - -bool CTimer::update(uint ticks) { - return false; -} - -} // End of namespace Titanic diff --git a/engines/titanic/support/timer.h b/engines/titanic/support/timer.h deleted file mode 100644 index 4d74bae34c..0000000000 --- a/engines/titanic/support/timer.h +++ /dev/null @@ -1,94 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef TITANIC_TIMER_H -#define TITANIC_TIMER_H - -#include "titanic/core/list.h" - -namespace Titanic { - -class CProjectItem; - -class CTimer : public ListItem { -private: - static int _v1; -public: - uint _id; - bool _done; - uint _field44; -public: - CTimer(); - - /** - * Called after loading a game has finished - */ - void postLoad(uint ticks, CProjectItem *project); - - /** - * Called when a game is about to be saved - */ - void preSave(); - - /** - * Called when a game has finished being saved - */ - void postSave(); - - bool update(uint ticks); - - void set44(uint val) { _field44 = val; } -}; - -class CTimerList : public List { -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(); - - /** - * 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); - - void set44(uint id, uint val); -}; - -} // End of namespace Titanic - -#endif /* TITANIC_TIMER_H */ -- cgit v1.2.3 From d5e346681f3019a2394eec23f566b347f82edcf6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 Apr 2016 21:45:13 -0400 Subject: TITANIC: Fix deleting movies --- engines/titanic/support/movie.cpp | 4 ++++ engines/titanic/support/movie.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index f2c5643f78..79e0a7bc9f 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -30,6 +30,10 @@ namespace Titanic { CMovie::CMovie() : ListItem(), _state(MOVIE_STOPPED), _field10(0) { } +CMovie::~CMovie() { + g_vm->_activeMovies.remove(this); +} + bool CMovie::isActive() const { return g_vm->_activeMovies.contains(this); } diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index 0772635908..08d2940fe4 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -47,7 +47,7 @@ protected: int _field10; public: CMovie(); - virtual ~CMovie() {} + virtual ~CMovie(); virtual void proc8(int v1, CVideoSurface *surface) = 0; virtual void proc9(int v1, int v2, int v3, bool v4) = 0; -- cgit v1.2.3 From 78d03f9784d17f65b29e5b6836d23d8f494d3c7c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Apr 2016 09:19:37 -0400 Subject: TITANIC: Television video is now playing --- engines/titanic/support/movie.cpp | 10 +++++++--- engines/titanic/support/movie.h | 24 ++++++++++++++++++++---- engines/titanic/support/video_surface.cpp | 8 ++++---- engines/titanic/support/video_surface.h | 26 ++++++++++++++++++++++---- 4 files changed, 53 insertions(+), 15 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 79e0a7bc9f..7593c74e42 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -61,12 +61,13 @@ OSMovie::~OSMovie() { delete _video; } -void OSMovie::proc8(int v1, CVideoSurface *surface) { +void OSMovie::play(int v1, CVideoSurface *surface) { warning("TODO: OSMovie::proc8"); + play(0, 0, 0, 0); } -void OSMovie::proc9(int v1, int v2, int v3, bool v4) { - warning("TODO: OSMovie::proc9"); +void OSMovie::play(int v1, int v2, int v3, bool v4) { + warning("TODO: OSMovie::play properly"); //setFrame(v1); ? _video->start(); g_vm->_activeMovies.push_back(this); @@ -172,6 +173,9 @@ void OSMovie::decodeFrame() { // Unlock the surface videoSurface->unlock(); + + if (_gameObject) + _gameObject->makeDirty(); } } // End of namespace Titanic diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index 08d2940fe4..b488d26e39 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -49,8 +49,16 @@ public: CMovie(); virtual ~CMovie(); - virtual void proc8(int v1, CVideoSurface *surface) = 0; - virtual void proc9(int v1, int v2, int v3, bool v4) = 0; + /** + * Plays the movie + */ + virtual void play(int v1, CVideoSurface *surface) = 0; + + /** + * Plays the movie + */ + virtual void play(int v1, int v2, int v3, bool v4) = 0; + virtual void proc10() = 0; virtual void proc11() = 0; virtual void proc12() = 0; @@ -87,8 +95,16 @@ public: OSMovie(const CResourceKey &name, CVideoSurface *surface); virtual ~OSMovie(); - virtual void proc8(int v1, CVideoSurface *surface); - virtual void proc9(int v1, int v2, int v3, bool v4); + /** + * Plays the movie + */ + virtual void play(int v1, CVideoSurface *surface); + + /** + * Plays the movie + */ + virtual void play(int v1, int v2, int v3, bool v4); + virtual void proc10(); virtual void proc11(); virtual void proc12(); diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index c7b437e1e7..3fb513c5fc 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -379,14 +379,14 @@ void OSVideoSurface::shiftColors() { // we already convert 16-bit surfaces as soon as they're loaded } -void OSVideoSurface::proc32(int v1, CVideoSurface *surface) { +void OSVideoSurface::playMovie(int newStatus, CVideoSurface *surface) { if (loadIfReady() && _movie) - _movie->proc8(v1, surface); + _movie->play(newStatus, surface); } -void OSVideoSurface::proc34(int v1, int v2, int v3, bool v4) { +void OSVideoSurface::playMovie(int v1, int v2, int v3, bool v4) { if (loadIfReady() && _movie) { - _movie->proc9(v1, v2, v3, v4); + _movie->play(v1, v2, v3, v4); } } diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index 335215d1df..c4947ca766 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -154,8 +154,17 @@ public: */ virtual void shiftColors() = 0; - virtual void proc32(int v1, CVideoSurface *surface) = 0; - virtual void proc34(int v1, int v2, int v3, bool v4) = 0; + /** + * Plays a movie, loading it from the specified _resource + * if not already loaded + */ + virtual void playMovie(int newStatus, CVideoSurface *surface) = 0; + + /** + * Plays a movie, loading it from the specified _resource + * if not already loaded + */ + virtual void playMovie(int v1, int v2, int v3, bool v4) = 0; /** * Stops any movie currently attached to the surface @@ -304,8 +313,17 @@ public: */ virtual void shiftColors(); - virtual void proc32(int v1, CVideoSurface *surface); - virtual void proc34(int v1, int v2, int v3, bool v4); + /** + * Plays a movie, loading it from the specified _resource + * if not already loaded + */ + virtual void playMovie(int newStatus, CVideoSurface *surface); + + /** + * Plays a movie, loading it from the specified _resource + * if not already loaded + */ + virtual void playMovie(int v1, int v2, int v3, bool v4); /** * Stops any movie currently attached to the surface -- cgit v1.2.3 From 1ee3f334d39be6944e643c22cd376d5ae4ffaaf5 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Apr 2016 14:40:59 -0400 Subject: TITANIC: Change back to using original AVIDecoder --- engines/titanic/support/avi_decoder.cpp | 949 ------------------------------- engines/titanic/support/avi_decoder.h | 285 ---------- engines/titanic/support/mouse_cursor.cpp | 26 +- engines/titanic/support/movie.cpp | 16 +- engines/titanic/support/movie.h | 1 + 5 files changed, 36 insertions(+), 1241 deletions(-) delete mode 100644 engines/titanic/support/avi_decoder.cpp delete mode 100644 engines/titanic/support/avi_decoder.h (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_decoder.cpp b/engines/titanic/support/avi_decoder.cpp deleted file mode 100644 index 578e3a94ea..0000000000 --- a/engines/titanic/support/avi_decoder.cpp +++ /dev/null @@ -1,949 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "common/stream.h" -#include "common/system.h" -#include "common/textconsole.h" - -#include "audio/audiostream.h" -#include "audio/mixer.h" - -#include "titanic/support/avi_decoder.h" - -// Audio Codecs -#include "audio/decoders/adpcm.h" -#include "audio/decoders/mp3.h" -#include "audio/decoders/raw.h" - -// Video Codecs -#include "image/codecs/codec.h" - -namespace Titanic { - -#define UNKNOWN_HEADER(a) error("Unknown header found -- \'%s\'", tag2str(a)) - -// IDs used throughout the AVI files -// that will be handled by this player -#define ID_RIFF MKTAG('R','I','F','F') -#define ID_AVI MKTAG('A','V','I',' ') -#define ID_LIST MKTAG('L','I','S','T') -#define ID_HDRL MKTAG('h','d','r','l') -#define ID_AVIH MKTAG('a','v','i','h') -#define ID_STRL MKTAG('s','t','r','l') -#define ID_STRH MKTAG('s','t','r','h') -#define ID_VIDS MKTAG('v','i','d','s') -#define ID_AUDS MKTAG('a','u','d','s') -#define ID_MIDS MKTAG('m','i','d','s') -#define ID_TXTS MKTAG('t','x','t','s') -#define ID_JUNK MKTAG('J','U','N','K') -#define ID_JUNQ MKTAG('J','U','N','Q') -#define ID_DMLH MKTAG('d','m','l','h') -#define ID_STRF MKTAG('s','t','r','f') -#define ID_MOVI MKTAG('m','o','v','i') -#define ID_REC MKTAG('r','e','c',' ') -#define ID_VEDT MKTAG('v','e','d','t') -#define ID_IDX1 MKTAG('i','d','x','1') -#define ID_STRD MKTAG('s','t','r','d') -#define ID_INFO MKTAG('I','N','F','O') -#define ID_ISFT MKTAG('I','S','F','T') -#define ID_DISP MKTAG('D','I','S','P') -#define ID_PRMI MKTAG('P','R','M','I') -#define ID_STRN MKTAG('s','t','r','n') - -// Stream Types -enum { - kStreamTypePaletteChange = MKTAG16('p', 'c'), - kStreamTypeAudio = MKTAG16('w', 'b') -}; - - -AVIDecoder::AVIDecoder(Audio::Mixer::SoundType soundType) : _frameRateOverride(0), _soundType(soundType) { - initCommon(); -} - -AVIDecoder::AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType) - : _frameRateOverride(frameRateOverride), _soundType(soundType) { - initCommon(); -} - -AVIDecoder::~AVIDecoder() { - close(); -} - -AVIDecoder::AVIAudioTrack *AVIDecoder::createAudioTrack(AVIStreamHeader sHeader, PCMWaveFormat wvInfo) { - return new AVIAudioTrack(sHeader, wvInfo, _soundType); -} - -void AVIDecoder::initCommon() { - _decodedHeader = false; - _foundMovieList = false; - _movieListStart = 0; - _movieListEnd = 0; - _fileStream = 0; - memset(&_header, 0, sizeof(_header)); -} - -bool AVIDecoder::isSeekable() const { - // Only videos with an index can seek - // Anyone else who wants to seek is crazy. - return isVideoLoaded() && !_indexEntries.empty(); -} - -bool AVIDecoder::parseNextChunk() { - uint32 tag = _fileStream->readUint32BE(); - uint32 size = _fileStream->readUint32LE(); - - if (_fileStream->eos()) - return false; - - debug(3, "Decoding tag %s", tag2str(tag)); - - switch (tag) { - case ID_LIST: - handleList(size); - break; - case ID_AVIH: - _header.size = size; - _header.microSecondsPerFrame = _fileStream->readUint32LE(); - _header.maxBytesPerSecond = _fileStream->readUint32LE(); - _header.padding = _fileStream->readUint32LE(); - _header.flags = _fileStream->readUint32LE(); - _header.totalFrames = _fileStream->readUint32LE(); - _header.initialFrames = _fileStream->readUint32LE(); - _header.streams = _fileStream->readUint32LE(); - _header.bufferSize = _fileStream->readUint32LE(); - _header.width = _fileStream->readUint32LE(); - _header.height = _fileStream->readUint32LE(); - // Ignore 16 bytes of reserved data - _fileStream->skip(16); - break; - case ID_STRH: - handleStreamHeader(size); - break; - case ID_STRD: // Extra stream info, safe to ignore - case ID_VEDT: // Unknown, safe to ignore - case ID_JUNK: // Alignment bytes, should be ignored - case ID_JUNQ: // Same as JUNK, safe to ignore - case ID_ISFT: // Metadata, safe to ignore - case ID_DISP: // Metadata, should be safe to ignore - case ID_STRN: // Metadata, safe to ignore - case ID_DMLH: // OpenDML extension, contains an extra total frames field, safe to ignore - skipChunk(size); - break; - case ID_IDX1: - readOldIndex(size); - break; - case 0: - return false; - default: - error("Unknown tag \'%s\' found", tag2str(tag)); - } - - return true; -} - -void AVIDecoder::skipChunk(uint32 size) { - // Make sure we're aligned on a word boundary - _fileStream->skip(size + (size & 1)); -} - -void AVIDecoder::handleList(uint32 listSize) { - uint32 listType = _fileStream->readUint32BE(); - listSize -= 4; // Subtract away listType's 4 bytes - uint32 curPos = _fileStream->pos(); - - debug(0, "Found LIST of type %s", tag2str(listType)); - - switch (listType) { - case ID_MOVI: // Movie List - // We found the movie block - _foundMovieList = true; - _movieListStart = curPos; - _movieListEnd = _movieListStart + listSize + (listSize & 1); - _fileStream->skip(listSize); - return; - case ID_HDRL: // Header List - // Mark the header as decoded - _decodedHeader = true; - break; - case ID_INFO: // Metadata - case ID_PRMI: // Adobe Premiere metadata, safe to ignore - // Ignore metadata - _fileStream->skip(listSize); - return; - case ID_STRL: // Stream list - default: // (Just hope we can parse it!) - break; - } - - while ((_fileStream->pos() - curPos) < listSize) - parseNextChunk(); -} - -void AVIDecoder::handleStreamHeader(uint32 size) { - AVIStreamHeader sHeader; - sHeader.size = size; - sHeader.streamType = _fileStream->readUint32BE(); - - if (sHeader.streamType == ID_MIDS || sHeader.streamType == ID_TXTS) - error("Unhandled MIDI/Text stream"); - - sHeader.streamHandler = _fileStream->readUint32BE(); - sHeader.flags = _fileStream->readUint32LE(); - sHeader.priority = _fileStream->readUint16LE(); - sHeader.language = _fileStream->readUint16LE(); - sHeader.initialFrames = _fileStream->readUint32LE(); - sHeader.scale = _fileStream->readUint32LE(); - sHeader.rate = _fileStream->readUint32LE(); - sHeader.start = _fileStream->readUint32LE(); - sHeader.length = _fileStream->readUint32LE(); - sHeader.bufferSize = _fileStream->readUint32LE(); - sHeader.quality = _fileStream->readUint32LE(); - sHeader.sampleSize = _fileStream->readUint32LE(); - - _fileStream->skip(sHeader.size - 48); // Skip over the remainder of the chunk (frame) - - if (_fileStream->readUint32BE() != ID_STRF) - error("Could not find STRF tag"); - - uint32 strfSize = _fileStream->readUint32LE(); - uint32 startPos = _fileStream->pos(); - - if (sHeader.streamType == ID_VIDS) { - if (_frameRateOverride != 0) { - sHeader.rate = _frameRateOverride.getNumerator(); - sHeader.scale = _frameRateOverride.getDenominator(); - } - - BitmapInfoHeader bmInfo; - bmInfo.size = _fileStream->readUint32LE(); - bmInfo.width = _fileStream->readUint32LE(); - bmInfo.height = _fileStream->readUint32LE(); - bmInfo.planes = _fileStream->readUint16LE(); - bmInfo.bitCount = _fileStream->readUint16LE(); - bmInfo.compression = _fileStream->readUint32BE(); - bmInfo.sizeImage = _fileStream->readUint32LE(); - bmInfo.xPelsPerMeter = _fileStream->readUint32LE(); - bmInfo.yPelsPerMeter = _fileStream->readUint32LE(); - bmInfo.clrUsed = _fileStream->readUint32LE(); - bmInfo.clrImportant = _fileStream->readUint32LE(); - - if (bmInfo.clrUsed == 0) - bmInfo.clrUsed = 256; - - byte *initialPalette = 0; - - if (bmInfo.bitCount == 8) { - initialPalette = new byte[256 * 3]; - memset(initialPalette, 0, 256 * 3); - - byte *palette = initialPalette; - for (uint32 i = 0; i < bmInfo.clrUsed; i++) { - palette[i * 3 + 2] = _fileStream->readByte(); - palette[i * 3 + 1] = _fileStream->readByte(); - palette[i * 3] = _fileStream->readByte(); - _fileStream->readByte(); - } - } - - // WORKAROUND: For Titanic engine, the ycursors.avi file has two video tracks, - // so we do an explicit check below to ignore any second video track - if (getFrameCount() == 0) - addTrack(new AVIVideoTrack(_header.totalFrames, sHeader, bmInfo, initialPalette)); - } else if (sHeader.streamType == ID_AUDS) { - PCMWaveFormat wvInfo; - wvInfo.tag = _fileStream->readUint16LE(); - wvInfo.channels = _fileStream->readUint16LE(); - wvInfo.samplesPerSec = _fileStream->readUint32LE(); - wvInfo.avgBytesPerSec = _fileStream->readUint32LE(); - wvInfo.blockAlign = _fileStream->readUint16LE(); - wvInfo.size = _fileStream->readUint16LE(); - - // AVI seems to treat the sampleSize as including the second - // channel as well, so divide for our sake. - if (wvInfo.channels == 2) - sHeader.sampleSize /= 2; - - AVIAudioTrack *track = createAudioTrack(sHeader, wvInfo); - track->createAudioStream(); - addTrack(track); - } - - // Ensure that we're at the end of the chunk - _fileStream->seek(startPos + strfSize); -} - -bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) { - close(); - - uint32 riffTag = stream->readUint32BE(); - if (riffTag != ID_RIFF) { - warning("Failed to find RIFF header"); - return false; - } - - /* uint32 fileSize = */ stream->readUint32LE(); - uint32 riffType = stream->readUint32BE(); - - if (riffType != ID_AVI) { - warning("RIFF not an AVI file"); - return false; - } - - _fileStream = stream; - - // Go through all chunks in the file - while (parseNextChunk()) - ; - - if (!_decodedHeader) { - warning("Failed to parse AVI header"); - close(); - return false; - } - - if (!_foundMovieList) { - warning("Failed to find 'MOVI' list"); - close(); - return false; - } - - // Create the status entries - uint32 index = 0; - for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++, index++) { - TrackStatus status; - status.track = *it; - status.index = index; - status.chunkSearchOffset = _movieListStart; - - if ((*it)->getTrackType() == Track::kTrackTypeVideo) { - if (_videoTracks.size() == 0) - _videoTracks.push_back(status); - } else { - if (_audioTracks.size() == 0) - _audioTracks.push_back(status); - } - } - - if (_videoTracks.size() != 1) { - warning("Unhandled AVI video track count: %d", _videoTracks.size()); - close(); - return false; - } - - // Check if this is a special Duck Truemotion video - checkTruemotion1(); - - return true; -} - -void AVIDecoder::close() { - VideoDecoder::close(); - - delete _fileStream; - _fileStream = 0; - _decodedHeader = false; - _foundMovieList = false; - _movieListStart = 0; - _movieListEnd = 0; - - _indexEntries.clear(); - memset(&_header, 0, sizeof(_header)); - - _videoTracks.clear(); - _audioTracks.clear(); -} - -void AVIDecoder::readNextPacket() { - // Shouldn't get this unless called on a non-open video - if (_videoTracks.empty()) - return; - - // Get the video frame first - handleNextPacket(_videoTracks[0]); - - // Handle audio tracks next - for (uint32 i = 0; i < _audioTracks.size(); i++) - handleNextPacket(_audioTracks[i]); -} - -void AVIDecoder::handleNextPacket(TrackStatus &status) { - // If there's no more to search, bail out - if (status.chunkSearchOffset + 8 >= _movieListEnd) { - if (status.track->getTrackType() == Track::kTrackTypeVideo) { - // Horrible AVI video has a premature end - // Force the frame to be the last frame - debug(0, "Forcing end of AVI video"); - ((AVIVideoTrack *)status.track)->forceTrackEnd(); - } - - return; - } - - // See if audio needs to be buffered and break out if not - if (status.track->getTrackType() == Track::kTrackTypeAudio && !shouldQueueAudio(status)) - return; - - // Seek to where we shall start searching - _fileStream->seek(status.chunkSearchOffset); - - for (;;) { - // If there's no more to search, bail out - if ((uint32)_fileStream->pos() + 8 >= _movieListEnd) { - if (status.track->getTrackType() == Track::kTrackTypeVideo) { - // Horrible AVI video has a premature end - // Force the frame to be the last frame - debug(0, "Forcing end of AVI video"); - ((AVIVideoTrack *)status.track)->forceTrackEnd(); - } - - break; - } - - uint32 nextTag = _fileStream->readUint32BE(); - uint32 size = _fileStream->readUint32LE(); - - if (nextTag == ID_LIST) { - // A list of audio/video chunks - if (_fileStream->readUint32BE() != ID_REC) - error("Expected 'rec ' LIST"); - - continue; - } else if (nextTag == ID_JUNK || nextTag == ID_IDX1) { - skipChunk(size); - continue; - } - - // Only accept chunks for this stream - uint32 streamIndex = getStreamIndex(nextTag); - if (streamIndex != status.index) { - skipChunk(size); - continue; - } - - Common::SeekableReadStream *chunk = 0; - - if (size != 0) { - chunk = _fileStream->readStream(size); - _fileStream->skip(size & 1); - } - - if (status.track->getTrackType() == Track::kTrackTypeAudio) { - if (getStreamType(nextTag) != kStreamTypeAudio) - error("Invalid audio track tag '%s'", tag2str(nextTag)); - - assert(chunk); - ((AVIAudioTrack *)status.track)->queueSound(chunk); - - // Break out if we have enough audio - if (!shouldQueueAudio(status)) - break; - } else { - AVIVideoTrack *videoTrack = (AVIVideoTrack *)status.track; - - if (getStreamType(nextTag) == kStreamTypePaletteChange) { - // Palette Change - videoTrack->loadPaletteFromChunk(chunk); - } else { - // Otherwise, assume it's a compressed frame - videoTrack->decodeFrame(chunk); - break; - } - } - } - - // Start us off in this position next time - status.chunkSearchOffset = _fileStream->pos(); -} - -bool AVIDecoder::shouldQueueAudio(TrackStatus& status) { - // Sanity check: - if (status.track->getTrackType() != Track::kTrackTypeAudio) - return false; - - // If video is done, make sure that the rest of the audio is queued - // (I guess this is also really a sanity check) - AVIVideoTrack *videoTrack = (AVIVideoTrack *)_videoTracks[0].track; - if (videoTrack->endOfTrack()) - return true; - - // Being three frames ahead should be enough for any video. - return ((AVIAudioTrack *)status.track)->getCurChunk() < (uint32)(videoTrack->getCurFrame() + 3); -} - -bool AVIDecoder::rewind() { - if (!VideoDecoder::rewind()) - return false; - - for (uint32 i = 0; i < _videoTracks.size(); i++) - _videoTracks[i].chunkSearchOffset = _movieListStart; - - for (uint32 i = 0; i < _audioTracks.size(); i++) - _audioTracks[i].chunkSearchOffset = _movieListStart; - - return true; -} - -bool AVIDecoder::seekIntern(const Audio::Timestamp &time) { - // Can't seek beyond the end - if (time > getDuration()) - return false; - - // Get our video - AVIVideoTrack *videoTrack = (AVIVideoTrack *)_videoTracks[0].track; - uint32 videoIndex = _videoTracks[0].index; - - // If we seek directly to the end, just mark the tracks as over - if (time == getDuration()) { - videoTrack->setCurFrame(videoTrack->getFrameCount() - 1); - - for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++) - if ((*it)->getTrackType() == Track::kTrackTypeAudio) - ((AVIAudioTrack *)*it)->resetStream(); - - return true; - } - - // Get the frame we should be on at this time - uint frame = videoTrack->getFrameAtTime(time); - - // Reset any palette, if necessary - videoTrack->useInitialPalette(); - - int lastKeyFrame = -1; - int frameIndex = -1; - uint curFrame = 0; - - // Go through and figure out where we should be - // If there's a palette, we need to find the palette too - for (uint32 i = 0; i < _indexEntries.size(); i++) { - const OldIndex &index = _indexEntries[i]; - - // We don't care about RECs - if (index.id == ID_REC) - continue; - - // We're only looking at entries for this track - if (getStreamIndex(index.id) != videoIndex) - continue; - - uint16 streamType = getStreamType(index.id); - - if (streamType == kStreamTypePaletteChange) { - // We need to handle any palette change we see since there's no - // flag to tell if this is a "key" palette. - // Decode the palette - _fileStream->seek(_indexEntries[i].offset + 8); - Common::SeekableReadStream *chunk = 0; - - if (_indexEntries[i].size != 0) - chunk = _fileStream->readStream(_indexEntries[i].size); - - videoTrack->loadPaletteFromChunk(chunk); - } else { - // Check to see if this is a keyframe - // The first frame has to be a keyframe - if ((_indexEntries[i].flags & AVIIF_INDEX) || curFrame == 0) - lastKeyFrame = i; - - // Did we find the target frame? - if (frame == curFrame) { - frameIndex = i; - break; - } - - curFrame++; - } - } - - if (frameIndex < 0) // This shouldn't happen. - return false; - - // Update all the audio tracks - for (uint32 i = 0; i < _audioTracks.size(); i++) { - AVIAudioTrack *audioTrack = (AVIAudioTrack *)_audioTracks[i].track; - - // Recreate the audio stream - audioTrack->resetStream(); - - // Set the chunk index for the track - audioTrack->setCurChunk(frame); - - uint32 chunksFound = 0; - for (uint32 j = 0; j < _indexEntries.size(); j++) { - const OldIndex &index = _indexEntries[j]; - - // Continue ignoring RECs - if (index.id == ID_REC) - continue; - - if (getStreamIndex(index.id) == _audioTracks[i].index) { - if (chunksFound == frame) { - _fileStream->seek(index.offset + 8); - Common::SeekableReadStream *audioChunk = _fileStream->readStream(index.size); - audioTrack->queueSound(audioChunk); - _audioTracks[i].chunkSearchOffset = (j == _indexEntries.size() - 1) ? _movieListEnd : _indexEntries[j + 1].offset; - break; - } - - chunksFound++; - } - } - - // Skip any audio to bring us to the right time - audioTrack->skipAudio(time, videoTrack->getFrameTime(frame)); - } - - // Decode from keyFrame to curFrame - 1 - for (int i = lastKeyFrame; i < frameIndex; i++) { - if (_indexEntries[i].id == ID_REC) - continue; - - if (getStreamIndex(_indexEntries[i].id) != videoIndex) - continue; - - uint16 streamType = getStreamType(_indexEntries[i].id); - - // Ignore palettes, they were already handled - if (streamType == kStreamTypePaletteChange) - continue; - - // Frame, hopefully - _fileStream->seek(_indexEntries[i].offset + 8); - Common::SeekableReadStream *chunk = 0; - - if (_indexEntries[i].size != 0) - chunk = _fileStream->readStream(_indexEntries[i].size); - - videoTrack->decodeFrame(chunk); - } - - // Set the video track's frame - videoTrack->setCurFrame((int)frame - 1); - - // Set the video track's search offset to the right spot - _videoTracks[0].chunkSearchOffset = _indexEntries[frameIndex].offset; - return true; -} - -byte AVIDecoder::getStreamIndex(uint32 tag) const { - char string[3]; - WRITE_BE_UINT16(string, tag >> 16); - string[2] = 0; - return strtol(string, 0, 16); -} - -void AVIDecoder::readOldIndex(uint32 size) { - uint32 entryCount = size / 16; - - debug(0, "Old Index: %d entries", entryCount); - - if (entryCount == 0) - return; - - // Read the first index separately - OldIndex firstEntry; - firstEntry.id = _fileStream->readUint32BE(); - firstEntry.flags = _fileStream->readUint32LE(); - firstEntry.offset = _fileStream->readUint32LE(); - firstEntry.size = _fileStream->readUint32LE(); - - // Check if the offset is already absolute - // If it's absolute, the offset will equal the start of the movie list - bool isAbsolute = firstEntry.offset == _movieListStart; - - debug(1, "Old index is %s", isAbsolute ? "absolute" : "relative"); - - if (!isAbsolute) - firstEntry.offset += _movieListStart - 4; - - debug(0, "Index 0: Tag '%s', Offset = %d, Size = %d (Flags = %d)", tag2str(firstEntry.id), firstEntry.offset, firstEntry.size, firstEntry.flags); - _indexEntries.push_back(firstEntry); - - for (uint32 i = 1; i < entryCount; i++) { - OldIndex indexEntry; - indexEntry.id = _fileStream->readUint32BE(); - indexEntry.flags = _fileStream->readUint32LE(); - indexEntry.offset = _fileStream->readUint32LE(); - indexEntry.size = _fileStream->readUint32LE(); - - // Adjust to absolute, if necessary - if (!isAbsolute) - indexEntry.offset += _movieListStart - 4; - - _indexEntries.push_back(indexEntry); - debug(0, "Index %d: Tag '%s', Offset = %d, Size = %d (Flags = %d)", i, tag2str(indexEntry.id), indexEntry.offset, indexEntry.size, indexEntry.flags); - } -} - -void AVIDecoder::checkTruemotion1() { - // If we got here from loadStream(), we know the track is valid - assert(!_videoTracks.empty()); - - TrackStatus &status = _videoTracks[0]; - AVIVideoTrack *track = (AVIVideoTrack *)status.track; - - // Ignore non-truemotion tracks - if (!track->isTruemotion1()) - return; - - // Read the next video packet - handleNextPacket(status); - - const Graphics::Surface *frame = track->decodeNextFrame(); - if (!frame) { - rewind(); - return; - } - - // Fill in the width/height based on the frame's width/height - _header.width = frame->w; - _header.height = frame->h; - track->forceDimensions(frame->w, frame->h); - - // Rewind us back to the beginning - rewind(); -} - -Video::VideoDecoder::AudioTrack *AVIDecoder::getAudioTrack(int index) { - // AVI audio track indexes are relative to the first track - Track *track = getTrack(index); - - if (!track || track->getTrackType() != Track::kTrackTypeAudio) - return 0; - - return (AudioTrack *)track; -} - -AVIDecoder::AVIVideoTrack::AVIVideoTrack(int frameCount, const AVIStreamHeader &streamHeader, const BitmapInfoHeader &bitmapInfoHeader, byte *initialPalette) - : _frameCount(frameCount), _vidsHeader(streamHeader), _bmInfo(bitmapInfoHeader), _initialPalette(initialPalette) { - _videoCodec = createCodec(); - _lastFrame = 0; - _curFrame = -1; - - useInitialPalette(); -} - -AVIDecoder::AVIVideoTrack::~AVIVideoTrack() { - delete _videoCodec; - delete[] _initialPalette; -} - -void AVIDecoder::AVIVideoTrack::decodeFrame(Common::SeekableReadStream *stream) { - if (stream) { - if (_videoCodec) - _lastFrame = _videoCodec->decodeFrame(*stream); - } else { - // Empty frame - _lastFrame = 0; - } - - delete stream; - _curFrame++; -} - -Graphics::PixelFormat AVIDecoder::AVIVideoTrack::getPixelFormat() const { - if (_videoCodec) - return _videoCodec->getPixelFormat(); - - return Graphics::PixelFormat(); -} - -void AVIDecoder::AVIVideoTrack::loadPaletteFromChunk(Common::SeekableReadStream *chunk) { - assert(chunk); - byte firstEntry = chunk->readByte(); - uint16 numEntries = chunk->readByte(); - chunk->readUint16LE(); // Reserved - - // 0 entries means all colors are going to be changed - if (numEntries == 0) - numEntries = 256; - - for (uint16 i = firstEntry; i < numEntries + firstEntry; i++) { - _palette[i * 3] = chunk->readByte(); - _palette[i * 3 + 1] = chunk->readByte(); - _palette[i * 3 + 2] = chunk->readByte(); - chunk->readByte(); // Flags that don't serve us any purpose - } - - delete chunk; - _dirtyPalette = true; -} - -void AVIDecoder::AVIVideoTrack::useInitialPalette() { - _dirtyPalette = false; - - if (_initialPalette) { - memcpy(_palette, _initialPalette, sizeof(_palette)); - _dirtyPalette = true; - } -} - -bool AVIDecoder::AVIVideoTrack::isTruemotion1() const { - return _bmInfo.compression == MKTAG('D', 'U', 'C', 'K') || _bmInfo.compression == MKTAG('d', 'u', 'c', 'k'); -} - -void AVIDecoder::AVIVideoTrack::forceDimensions(uint16 width, uint16 height) { - _bmInfo.width = width; - _bmInfo.height = height; -} - -bool AVIDecoder::AVIVideoTrack::rewind() { - _curFrame = -1; - - useInitialPalette(); - - delete _videoCodec; - _videoCodec = createCodec(); - _lastFrame = 0; - return true; -} - -Image::Codec *AVIDecoder::AVIVideoTrack::createCodec() { - return Image::createBitmapCodec(_bmInfo.compression, _bmInfo.width, _bmInfo.height, _bmInfo.bitCount); -} - -void AVIDecoder::AVIVideoTrack::forceTrackEnd() { - _curFrame = _frameCount - 1; -} - -const byte *AVIDecoder::AVIVideoTrack::getPalette() const { - if (_videoCodec && _videoCodec->containsPalette()) - return _videoCodec->getPalette(); - - _dirtyPalette = false; - return _palette; -} - -bool AVIDecoder::AVIVideoTrack::hasDirtyPalette() const { - if (_videoCodec && _videoCodec->containsPalette()) - return _videoCodec->hasDirtyPalette(); - - return _dirtyPalette; -} - -bool AVIDecoder::AVIVideoTrack::canDither() const { - return _videoCodec && _videoCodec->canDither(Image::Codec::kDitherTypeVFW); -} - -void AVIDecoder::AVIVideoTrack::setDither(const byte *palette) { - assert(_videoCodec); - _videoCodec->setDither(Image::Codec::kDitherTypeVFW, palette); -} - -AVIDecoder::AVIAudioTrack::AVIAudioTrack(const AVIStreamHeader &streamHeader, const PCMWaveFormat &waveFormat, Audio::Mixer::SoundType soundType) - : _audsHeader(streamHeader), _wvInfo(waveFormat), _soundType(soundType), _audioStream(0), _packetStream(0), _curChunk(0) { -} - -AVIDecoder::AVIAudioTrack::~AVIAudioTrack() { - delete _audioStream; -} - -void AVIDecoder::AVIAudioTrack::queueSound(Common::SeekableReadStream *stream) { - if (_packetStream) - _packetStream->queuePacket(stream); - else - delete stream; - - _curChunk++; -} - -void AVIDecoder::AVIAudioTrack::skipAudio(const Audio::Timestamp &time, const Audio::Timestamp &frameTime) { - Audio::Timestamp timeDiff = time.convertToFramerate(_wvInfo.samplesPerSec) - frameTime.convertToFramerate(_wvInfo.samplesPerSec); - int skipFrames = timeDiff.totalNumberOfFrames(); - - if (skipFrames <= 0) - return; - - Audio::AudioStream *audioStream = getAudioStream(); - if (!audioStream) - return; - - if (audioStream->isStereo()) - skipFrames *= 2; - - int16 *tempBuffer = new int16[skipFrames]; - audioStream->readBuffer(tempBuffer, skipFrames); - delete[] tempBuffer; -} - -void AVIDecoder::AVIAudioTrack::resetStream() { - delete _audioStream; - createAudioStream(); - _curChunk = 0; -} - -bool AVIDecoder::AVIAudioTrack::rewind() { - resetStream(); - return true; -} - -void AVIDecoder::AVIAudioTrack::createAudioStream() { - _packetStream = 0; - - switch (_wvInfo.tag) { - case kWaveFormatPCM: { - byte flags = 0; - if (_audsHeader.sampleSize == 2) - flags |= Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN; - else - flags |= Audio::FLAG_UNSIGNED; - - if (_wvInfo.channels == 2) - flags |= Audio::FLAG_STEREO; - - _packetStream = Audio::makePacketizedRawStream(_wvInfo.samplesPerSec, flags); - break; - } - case kWaveFormatMSADPCM: - _packetStream = Audio::makePacketizedADPCMStream(Audio::kADPCMMS, _wvInfo.samplesPerSec, _wvInfo.channels, _wvInfo.blockAlign); - break; - case kWaveFormatMSIMAADPCM: - _packetStream = Audio::makePacketizedADPCMStream(Audio::kADPCMMSIma, _wvInfo.samplesPerSec, _wvInfo.channels, _wvInfo.blockAlign); - break; - case kWaveFormatDK3: - _packetStream = Audio::makePacketizedADPCMStream(Audio::kADPCMDK3, _wvInfo.samplesPerSec, _wvInfo.channels, _wvInfo.blockAlign); - break; - case kWaveFormatMP3: -#ifdef USE_MAD - _packetStream = Audio::makePacketizedMP3Stream(_wvInfo.channels, _wvInfo.samplesPerSec); -#else - warning("AVI MP3 stream found, but no libmad support compiled in"); -#endif - break; - case kWaveFormatNone: - break; - default: - warning("Unsupported AVI audio format %d", _wvInfo.tag); - break; - } - - if (_packetStream) - _audioStream = _packetStream; - else - _audioStream = Audio::makeNullAudioStream(); -} - -AVIDecoder::TrackStatus::TrackStatus() : track(0), chunkSearchOffset(0) { -} - -} // End of namespace Titanic diff --git a/engines/titanic/support/avi_decoder.h b/engines/titanic/support/avi_decoder.h deleted file mode 100644 index acc33cbc4d..0000000000 --- a/engines/titanic/support/avi_decoder.h +++ /dev/null @@ -1,285 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef TITANIC_AVI_DECODER_H -#define TITANIC_AVI_DECODER_H - -#include "common/array.h" -#include "common/rational.h" -#include "common/rect.h" -#include "common/str.h" - -#include "video/video_decoder.h" -#include "audio/mixer.h" - -namespace Audio { -class AudioStream; -class PacketizedAudioStream; -} - -namespace Common { -class SeekableReadStream; -} - -namespace Graphics { -struct PixelFormat; -} - -namespace Image { -class Codec; -} - -namespace Titanic { - -/** - * Modified AVI Decoder used by Titanic engine. - */ -class AVIDecoder : public Video::VideoDecoder { -public: - AVIDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); - AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); - virtual ~AVIDecoder(); - - bool loadStream(Common::SeekableReadStream *stream); - void close(); - uint16 getWidth() const { return _header.width; } - uint16 getHeight() const { return _header.height; } - - bool rewind(); - bool isRewindable() const { return true; } - bool isSeekable() const; - -protected: - // VideoDecoder API - void readNextPacket(); - bool seekIntern(const Audio::Timestamp &time); - bool supportsAudioTrackSwitching() const { return true; } - AudioTrack *getAudioTrack(int index); - - struct BitmapInfoHeader { - uint32 size; - uint32 width; - uint32 height; - uint16 planes; - uint16 bitCount; - uint32 compression; - uint32 sizeImage; - uint32 xPelsPerMeter; - uint32 yPelsPerMeter; - uint32 clrUsed; - uint32 clrImportant; - }; - - struct WaveFormat { - uint16 tag; - uint16 channels; - uint32 samplesPerSec; - uint32 avgBytesPerSec; - uint16 blockAlign; - }; - - struct PCMWaveFormat : public WaveFormat { - uint16 size; - }; - - struct WaveFormatEX : public WaveFormat { - uint16 bitsPerSample; - uint16 size; - }; - - struct OldIndex { - uint32 id; - uint32 flags; - uint32 offset; - uint32 size; - }; - - // Index Flags - enum IndexFlags { - AVIIF_INDEX = 0x10 - }; - - struct AVIHeader { - uint32 size; - uint32 microSecondsPerFrame; - uint32 maxBytesPerSecond; - uint32 padding; - uint32 flags; - uint32 totalFrames; - uint32 initialFrames; - uint32 streams; - uint32 bufferSize; - uint32 width; - uint32 height; - }; - - // Flags from the AVIHeader - enum AVIFlags { - AVIF_HASINDEX = 0x00000010, - AVIF_MUSTUSEINDEX = 0x00000020, - AVIF_ISINTERLEAVED = 0x00000100, - AVIF_TRUSTCKTYPE = 0x00000800, - AVIF_WASCAPTUREFILE = 0x00010000, - AVIF_WASCOPYRIGHTED = 0x00020000 - }; - - struct AVIStreamHeader { - uint32 size; - uint32 streamType; - uint32 streamHandler; - uint32 flags; - uint16 priority; - uint16 language; - uint32 initialFrames; - uint32 scale; - uint32 rate; - uint32 start; - uint32 length; - uint32 bufferSize; - uint32 quality; - uint32 sampleSize; - Common::Rect frame; - }; - - class AVIVideoTrack : public FixedRateVideoTrack { - public: - AVIVideoTrack(int frameCount, const AVIStreamHeader &streamHeader, const BitmapInfoHeader &bitmapInfoHeader, byte *initialPalette = 0); - ~AVIVideoTrack(); - - void decodeFrame(Common::SeekableReadStream *stream); - void forceTrackEnd(); - - uint16 getWidth() const { return _bmInfo.width; } - uint16 getHeight() const { return _bmInfo.height; } - Graphics::PixelFormat getPixelFormat() const; - int getCurFrame() const { return _curFrame; } - int getFrameCount() const { return _frameCount; } - const Graphics::Surface *decodeNextFrame() { return _lastFrame; } - - const byte *getPalette() const; - bool hasDirtyPalette() const; - void setCurFrame(int frame) { _curFrame = frame; } - void loadPaletteFromChunk(Common::SeekableReadStream *chunk); - void useInitialPalette(); - bool canDither() const; - void setDither(const byte *palette); - - bool isTruemotion1() const; - void forceDimensions(uint16 width, uint16 height); - - bool isRewindable() const { return true; } - bool rewind(); - - protected: - Common::Rational getFrameRate() const { return Common::Rational(_vidsHeader.rate, _vidsHeader.scale); } - - private: - AVIStreamHeader _vidsHeader; - BitmapInfoHeader _bmInfo; - byte _palette[3 * 256]; - byte *_initialPalette; - mutable bool _dirtyPalette; - int _frameCount, _curFrame; - - Image::Codec *_videoCodec; - const Graphics::Surface *_lastFrame; - Image::Codec *createCodec(); - }; - - class AVIAudioTrack : public AudioTrack { - public: - AVIAudioTrack(const AVIStreamHeader &streamHeader, const PCMWaveFormat &waveFormat, Audio::Mixer::SoundType soundType); - ~AVIAudioTrack(); - - virtual void createAudioStream(); - virtual void queueSound(Common::SeekableReadStream *stream); - Audio::Mixer::SoundType getSoundType() const { return _soundType; } - void skipAudio(const Audio::Timestamp &time, const Audio::Timestamp &frameTime); - virtual void resetStream(); - uint32 getCurChunk() const { return _curChunk; } - void setCurChunk(uint32 chunk) { _curChunk = chunk; } - - bool isRewindable() const { return true; } - bool rewind(); - - protected: - Audio::AudioStream *getAudioStream() const { return _audioStream; } - - // Audio Codecs - enum { - kWaveFormatNone = 0, - kWaveFormatPCM = 1, - kWaveFormatMSADPCM = 2, - kWaveFormatMSIMAADPCM = 17, - kWaveFormatMP3 = 85, - kWaveFormatDK3 = 98 // rogue format number - }; - - AVIStreamHeader _audsHeader; - PCMWaveFormat _wvInfo; - Audio::Mixer::SoundType _soundType; - Audio::AudioStream *_audioStream; - Audio::PacketizedAudioStream *_packetStream; - uint32 _curChunk; - }; - - struct TrackStatus { - TrackStatus(); - - Track *track; - uint32 index; - uint32 chunkSearchOffset; - }; - - AVIHeader _header; - - void readOldIndex(uint32 size); - Common::Array _indexEntries; - - Common::SeekableReadStream *_fileStream; - bool _decodedHeader; - bool _foundMovieList; - uint32 _movieListStart, _movieListEnd; - - Audio::Mixer::SoundType _soundType; - Common::Rational _frameRateOverride; - void initCommon(); - - bool parseNextChunk(); - void skipChunk(uint32 size); - void handleList(uint32 listSize); - void handleStreamHeader(uint32 size); - uint16 getStreamType(uint32 tag) const { return tag & 0xFFFF; } - byte getStreamIndex(uint32 tag) const; - void checkTruemotion1(); - - void handleNextPacket(TrackStatus& status); - bool shouldQueueAudio(TrackStatus& status); - Common::Array _videoTracks, _audioTracks; - -public: - virtual AVIAudioTrack *createAudioTrack(AVIStreamHeader sHeader, PCMWaveFormat wvInfo); -}; - -} // End of namespace Titanic - -#endif diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp index a2bd11657c..6ddfecfd2a 100644 --- a/engines/titanic/support/mouse_cursor.cpp +++ b/engines/titanic/support/mouse_cursor.cpp @@ -20,8 +20,9 @@ * */ -#include "graphics/cursorman.h" +#include "common/memstream.h" #include "common/textconsole.h" +#include "graphics/cursorman.h" #include "titanic/support/mouse_cursor.h" #include "titanic/support/movie.h" #include "titanic/support/screen_manager.h" @@ -62,20 +63,39 @@ CMouseCursor::~CMouseCursor() { void CMouseCursor::loadCursorImages() { const CString name("ycursors.avi"); - const CResourceKey key(name); g_vm->_filesManager.fn4(name); + // WORKAROUND: We need to manipulate ycursors.avi file so it can be read + // by the ScummVM AVIDecoder, by removing the redundant second video track + Common::File f; + if (!f.open(name)) + error("Could not open cursors file"); + + // Read in the entire file + byte *movieData = (byte *)malloc(f.size()); + f.read(movieData, f.size()); + + if (READ_BE_UINT32(movieData + 254) == MKTAG('s', 't', 'r', 'h')) { + // Change the second video chunk to junk data so it gets ignored + WRITE_BE_UINT32(movieData + 254, MKTAG('J', 'U', 'N', 'K')); + WRITE_LE_UINT32(movieData + 258, 1128); + } + // Iterate through 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(64, 64); _cursors[idx]._videoSurface = surface; - OSMovie movie(key, surface); + Common::SeekableReadStream *stream = new Common::MemoryReadStream( + movieData, f.size(), DisposeAfterUse::NO); + OSMovie movie(stream, surface); movie.setFrame(idx); + _cursors[idx]._ptrUnknown = movie.proc21(); surface->set40(_cursors[idx]._ptrUnknown); } diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 7593c74e42..6599093226 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -20,8 +20,7 @@ * */ -#include "image/codecs/cinepak.h" -#include "titanic/support/avi_decoder.h" +#include "video/avi_decoder.h" #include "titanic/support/movie.h" #include "titanic/titanic.h" @@ -51,11 +50,18 @@ bool CMovie::get10() { OSMovie::OSMovie(const CResourceKey &name, CVideoSurface *surface) : _videoSurface(surface), _gameObject(nullptr) { - _video = new AVIDecoder(); + _video = new Video::AVIDecoder(); if (!_video->loadFile(name.getString())) error("Could not open video - %s", name.getString().c_str()); } +OSMovie::OSMovie(Common::SeekableReadStream *stream, CVideoSurface *surface) : + _videoSurface(surface), _gameObject(nullptr) { + _video = new Video::AVIDecoder(); + if (!_video->loadStream(stream)) + error("Could not parse movie stream"); +} + OSMovie::~OSMovie() { g_vm->_activeMovies.remove(this); delete _video; @@ -134,7 +140,9 @@ MovieState OSMovie::getState() { void OSMovie::update() { if (_state != MOVIE_STOPPED) { if (_video->isPlaying()) { - if (_video->needsUpdate()) { + if (_video->endOfVideo()) { + _state = MOVIE_FINISHED; + } else if (_video->needsUpdate()) { decodeFrame(); _state = MOVIE_FRAME; } else { diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index b488d26e39..2751f2d814 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -93,6 +93,7 @@ public: CGameObject *_gameObject; public: OSMovie(const CResourceKey &name, CVideoSurface *surface); + OSMovie(Common::SeekableReadStream *stream, CVideoSurface *surface); virtual ~OSMovie(); /** -- cgit v1.2.3 From 9db15f6967c8f559e34824213707ed76b45d666e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Apr 2016 14:46:59 -0400 Subject: TITANIC: Allow television video to play multiple times --- engines/titanic/support/movie.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 6599093226..dd0792caa4 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -75,6 +75,7 @@ void OSMovie::play(int v1, CVideoSurface *surface) { void OSMovie::play(int v1, int v2, int v3, bool v4) { warning("TODO: OSMovie::play properly"); //setFrame(v1); ? + _video->seek(0); _video->start(); g_vm->_activeMovies.push_back(this); _state = MOVIE_NONE; -- cgit v1.2.3 From 8e5f7a9453deff3436fc937292a0ff825acd7454 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Apr 2016 15:01:39 -0400 Subject: TITANIC: Fix stopping movies --- engines/titanic/support/movie.cpp | 3 ++- engines/titanic/support/movie.h | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index dd0792caa4..0627da8c4f 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -94,7 +94,8 @@ void OSMovie::proc12() { } void OSMovie::stop() { - warning("TODO: OSMovie::proc13"); + _video->stop(); + _state = MOVIE_STOPPED; } void OSMovie::proc14() { diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index 2751f2d814..d88c7b0be9 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -62,7 +62,12 @@ public: virtual void proc10() = 0; virtual void proc11() = 0; virtual void proc12() = 0; + + /** + * Stops the movie + */ virtual void stop() = 0; + virtual void proc14() = 0; virtual void setFrame(uint frameNumber) = 0; virtual void proc16() = 0; @@ -109,7 +114,12 @@ public: virtual void proc10(); virtual void proc11(); virtual void proc12(); + + /** + * Stops the movie + */ virtual void stop(); + virtual void proc14(); /** -- cgit v1.2.3 From 91336a86115f600e626c333441aa1369b435ab92 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Apr 2016 15:39:20 -0400 Subject: TITANIC: Implement playing a range of frames within movie --- engines/titanic/support/movie.cpp | 21 ++++++++++++--------- engines/titanic/support/movie.h | 9 +++++---- engines/titanic/support/video_surface.cpp | 8 ++++---- engines/titanic/support/video_surface.h | 8 ++++---- 4 files changed, 25 insertions(+), 21 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 0627da8c4f..6f66bec7a7 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -49,14 +49,14 @@ bool CMovie::get10() { /*------------------------------------------------------------------------*/ OSMovie::OSMovie(const CResourceKey &name, CVideoSurface *surface) : - _videoSurface(surface), _gameObject(nullptr) { + _videoSurface(surface), _gameObject(nullptr), _endFrame(-1) { _video = new Video::AVIDecoder(); if (!_video->loadFile(name.getString())) error("Could not open video - %s", name.getString().c_str()); } OSMovie::OSMovie(Common::SeekableReadStream *stream, CVideoSurface *surface) : - _videoSurface(surface), _gameObject(nullptr) { + _videoSurface(surface), _gameObject(nullptr), _endFrame(-1) { _video = new Video::AVIDecoder(); if (!_video->loadStream(stream)) error("Could not parse movie stream"); @@ -67,16 +67,18 @@ OSMovie::~OSMovie() { delete _video; } -void OSMovie::play(int v1, CVideoSurface *surface) { - warning("TODO: OSMovie::proc8"); - play(0, 0, 0, 0); +void OSMovie::play(uint flags, CVideoSurface *surface) { + uint endFrame = _video->getFrameCount(); + play(0, endFrame, 0, 0); } -void OSMovie::play(int v1, int v2, int v3, bool v4) { +void OSMovie::play(uint startFrame, uint endFrame, int v3, bool v4) { warning("TODO: OSMovie::play properly"); - //setFrame(v1); ? - _video->seek(0); + _video->start(); + _video->seekToFrame(startFrame); + _endFrame = endFrame; + g_vm->_activeMovies.push_back(this); _state = MOVIE_NONE; } @@ -142,7 +144,8 @@ MovieState OSMovie::getState() { void OSMovie::update() { if (_state != MOVIE_STOPPED) { if (_video->isPlaying()) { - if (_video->endOfVideo()) { + if (_video->getCurFrame() >= _endFrame) { + _video->stop(); _state = MOVIE_FINISHED; } else if (_video->needsUpdate()) { decodeFrame(); diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index d88c7b0be9..a871af6fc7 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -52,12 +52,12 @@ public: /** * Plays the movie */ - virtual void play(int v1, CVideoSurface *surface) = 0; + virtual void play(uint flags, CVideoSurface *surface) = 0; /** * Plays the movie */ - virtual void play(int v1, int v2, int v3, bool v4) = 0; + virtual void play(uint startFrame, uint endFrame, int v3, bool v4) = 0; virtual void proc10() = 0; virtual void proc11() = 0; @@ -89,6 +89,7 @@ class OSMovie : public CMovie { private: Video::VideoDecoder *_video; CVideoSurface *_videoSurface; + int _endFrame; /** * Decodes the next frame @@ -104,12 +105,12 @@ public: /** * Plays the movie */ - virtual void play(int v1, CVideoSurface *surface); + virtual void play(uint flags, CVideoSurface *surface); /** * Plays the movie */ - virtual void play(int v1, int v2, int v3, bool v4); + virtual void play(uint startFrame, uint endFrame, int v3, bool v4); virtual void proc10(); virtual void proc11(); diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index 3fb513c5fc..089b216347 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -379,14 +379,14 @@ void OSVideoSurface::shiftColors() { // we already convert 16-bit surfaces as soon as they're loaded } -void OSVideoSurface::playMovie(int newStatus, CVideoSurface *surface) { +void OSVideoSurface::playMovie(uint flags, CVideoSurface *surface) { if (loadIfReady() && _movie) - _movie->play(newStatus, surface); + _movie->play(flags, surface); } -void OSVideoSurface::playMovie(int v1, int v2, int v3, bool v4) { +void OSVideoSurface::playMovie(uint startFrame, uint endFrame, int v3, bool v4) { if (loadIfReady() && _movie) { - _movie->play(v1, v2, v3, v4); + _movie->play(startFrame, endFrame, v3, v4); } } diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index c4947ca766..2ec2c9ddba 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -158,13 +158,13 @@ public: * Plays a movie, loading it from the specified _resource * if not already loaded */ - virtual void playMovie(int newStatus, CVideoSurface *surface) = 0; + virtual void playMovie(uint flags, CVideoSurface *surface) = 0; /** * Plays a movie, loading it from the specified _resource * if not already loaded */ - virtual void playMovie(int v1, int v2, int v3, bool v4) = 0; + virtual void playMovie(uint startFrame, uint endFrame, int v3, bool v4) = 0; /** * Stops any movie currently attached to the surface @@ -317,13 +317,13 @@ public: * Plays a movie, loading it from the specified _resource * if not already loaded */ - virtual void playMovie(int newStatus, CVideoSurface *surface); + virtual void playMovie(uint flags, CVideoSurface *surface); /** * Plays a movie, loading it from the specified _resource * if not already loaded */ - virtual void playMovie(int v1, int v2, int v3, bool v4); + virtual void playMovie(uint startFrame, uint endFrame, int v3, bool v4); /** * Stops any movie currently attached to the surface -- cgit v1.2.3 From 066dd4f5cd1b0f5408cd0da5ef9050a738edc4b0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 16 Apr 2016 22:58:37 -0400 Subject: TITANIC: Implementing PET inventory population --- engines/titanic/support/movie.cpp | 6 +++--- engines/titanic/support/movie.h | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 6f66bec7a7..3ae2636404 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -121,9 +121,9 @@ void OSMovie::proc18() { warning("TODO: OSMovie::proc18"); } -int OSMovie::proc19() { - warning("TODO: OSMovie::proc19"); - return 0; +int OSMovie::getFrame() { + assert(_video); + return _video->getCurFrame(); } void OSMovie::proc20() { diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index a871af6fc7..644f582d64 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -73,7 +73,12 @@ public: virtual void proc16() = 0; virtual void proc17() = 0; virtual void proc18() = 0; - virtual int proc19() = 0; + + /** + * Get the current movie frame + */ + virtual int getFrame() = 0; + virtual void proc20() = 0; virtual void *proc21() = 0; @@ -131,7 +136,12 @@ public: virtual void proc16(); virtual void proc17(); virtual void proc18(); - virtual int proc19(); + + /** + * Get the current movie frame + */ + virtual int getFrame(); + virtual void proc20(); virtual void *proc21(); -- cgit v1.2.3 From a88c0b09994562d4576e7dd08db8ad2fe3326f53 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 24 Apr 2016 10:37:34 -0400 Subject: TITANIC: Starting to flesh out CPetText drawing --- engines/titanic/support/screen_manager.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/screen_manager.h b/engines/titanic/support/screen_manager.h index affe2ec0c9..d0580d4957 100644 --- a/engines/titanic/support/screen_manager.h +++ b/engines/titanic/support/screen_manager.h @@ -145,7 +145,15 @@ public: virtual void showCursor() = 0; virtual void hideCursor() = 0; + /** + * Set drawing bounds for a specified surface + */ void setSurfaceBounds(SurfaceNum surfaceNum, const Rect &r); + + /** + * Set the current font number + */ + void setFontNumber(int fontNumber) { _fontNumber = fontNumber; } }; class OSScreenManager: CScreenManager { -- cgit v1.2.3 From c75de59a28c94e364a38af39057af720ba8465d4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 24 Apr 2016 17:16:32 -0400 Subject: TITANIC: Implementing font text bounds calculations --- engines/titanic/support/font.cpp | 67 +++++++++++++++++++++++++++++- engines/titanic/support/font.h | 20 +++++++-- engines/titanic/support/screen_manager.cpp | 14 +++++-- engines/titanic/support/screen_manager.h | 39 +++++++++++++---- 4 files changed, 123 insertions(+), 17 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp index 55865e792c..f5d28ea9ca 100644 --- a/engines/titanic/support/font.cpp +++ b/engines/titanic/support/font.cpp @@ -70,8 +70,39 @@ uint16 STFont::getColor() const { return g_system->getScreenFormat().RGBToColor(_fontR, _fontG, _fontB); } -void STFont::writeString(int maxWidth, const CString &text, int *v1, int *v2) { - warning("TODO: STFont::writeString"); +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 == 26) { + strP += 3; + } else if (*strP == 27) { + strP += 4; + } else { + if (*strP == ' ') { + // Check fo rline wrapping + checkLineWrap(textSize, maxWidth, strP); + } + + extendBounds(textSize, *strP, maxWidth); + } + } + } + + if (sizeOut) + *sizeOut = textSize; + + return textSize.y + _fontHeight; } int STFont::stringWidth(const CString &text) const { @@ -160,4 +191,36 @@ void STFont::copyRect(CVideoSurface *surface, const Common::Point &pt, Rect &rec } } +void STFont::extendBounds(Point &textSize, byte c, int maxWidth) const { + textSize.x += _chars[c]._width; + + if (textSize.x == '\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; + for (const char *srcPtr = str; *srcPtr; ++srcPtr) { + if (*srcPtr == ' ' && flag) + break; + + if (*srcPtr == 26) + srcPtr += 3; + else if (*srcPtr == 27) + srcPtr += 4; + else + totalWidth += _chars[*srcPtr]._width; + } + + if ((textSize.x + totalWidth) >= maxWidth && totalWidth < maxWidth) { + // Word wrap + textSize.x = 0; + textSize.y += _fontHeight; + ++str; + } +} + } // End of namespace Titanic diff --git a/engines/titanic/support/font.h b/engines/titanic/support/font.h index 5ed0b5b7b4..e1c63e6544 100644 --- a/engines/titanic/support/font.h +++ b/engines/titanic/support/font.h @@ -50,6 +50,17 @@ private: */ int writeChar(CVideoSurface *surface, unsigned char c, const Common::Point &pt, Rect *destRect, 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; @@ -72,10 +83,13 @@ public: int stringWidth(const CString &text) const; /** - * Write out a string - * TODO: Verify this + * 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 */ - void writeString(int maxWidth, const CString &text, int *v1, int *v2); + int getTextBounds(const CString &str, int maxWidth, Point *sizeOut) const; /** * Sets the font color diff --git a/engines/titanic/support/screen_manager.cpp b/engines/titanic/support/screen_manager.cpp index d2f2468c89..f772bc6f7e 100644 --- a/engines/titanic/support/screen_manager.cpp +++ b/engines/titanic/support/screen_manager.cpp @@ -199,12 +199,18 @@ void OSScreenManager::proc13() {} void OSScreenManager::proc14() {} void OSScreenManager::proc15() {} -void OSScreenManager::writeString(int maxWidth, const CString &text, int *v1, int *v2) { - _fonts[_fontNumber].writeString(maxWidth, text, v1, v2); +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::getFont() {} -void OSScreenManager::proc18() {} void OSScreenManager::proc19() {} void OSScreenManager::clearSurface(SurfaceNum surfaceNum, Rect *bounds) { diff --git a/engines/titanic/support/screen_manager.h b/engines/titanic/support/screen_manager.h index d0580d4957..baba662564 100644 --- a/engines/titanic/support/screen_manager.h +++ b/engines/titanic/support/screen_manager.h @@ -110,14 +110,25 @@ public: virtual void proc14() = 0; virtual void proc15() = 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; /** - * Write out a string + * Returns the width of a given string in pixels */ - virtual void writeString(int maxWidth, const CString &text, int *v1, int *v2) = 0; + virtual int stringWidth(const CString &str) = 0; - virtual void getFont() = 0; - virtual void proc18() = 0; virtual void proc19() = 0; /** @@ -216,12 +227,24 @@ public: virtual void proc15(); /** - * Write out a string + * 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; + + /** + * Get the current font height + */ + virtual int getFontHeight() const; + + /** + * Returns the width of a given string in pixels */ - virtual void writeString(int maxWidth, const CString &text, int *v1, int *v2); + virtual int stringWidth(const CString &str); - virtual void getFont(); - virtual void proc18(); virtual void proc19(); /** -- cgit v1.2.3 From 36faf0890fec6bab90531ade42c0eb924b31b64a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 24 Apr 2016 22:22:12 -0400 Subject: TITANIC: Minor work towards text display --- engines/titanic/support/font.cpp | 10 +++++++--- engines/titanic/support/font.h | 5 +++++ engines/titanic/support/screen_manager.cpp | 11 ++++++++++- engines/titanic/support/screen_manager.h | 14 +++++++++++--- 4 files changed, 33 insertions(+), 7 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp index f5d28ea9ca..e903abaf97 100644 --- a/engines/titanic/support/font.cpp +++ b/engines/titanic/support/font.cpp @@ -127,7 +127,11 @@ int STFont::stringWidth(const CString &text) const { return total; } -int STFont::writeChar(CVideoSurface *surface, unsigned char c, const Common::Point &pt, Rect *destRect, Rect *srcRect) { +int STFont::writeString(CVideoSurface *surface, const Point &pt, const CString &str) { + return 0; +} + +int STFont::writeChar(CVideoSurface *surface, unsigned char c, const Point &pt, Rect *destRect, Rect *srcRect) { if (c == 233) c = '$'; @@ -174,7 +178,7 @@ int STFont::writeChar(CVideoSurface *surface, unsigned char c, const Common::Poi return 0; } -void STFont::copyRect(CVideoSurface *surface, const Common::Point &pt, Rect &rect) { +void STFont::copyRect(CVideoSurface *surface, const Point &pt, Rect &rect) { if (surface->lock()) { uint16 *lineP = surface->getBasePtr(pt.x, pt.y); uint16 color = getColor(); @@ -203,7 +207,7 @@ void STFont::extendBounds(Point &textSize, byte c, int maxWidth) const { void STFont::checkLineWrap(Point &textSize, int maxWidth, const char *&str) const { bool flag = false; int totalWidth = 0; - for (const char *srcPtr = str; *srcPtr; ++srcPtr) { + for (const char *srcPtr = str; *srcPtr && *srcPtr != ' '; ++srcPtr) { if (*srcPtr == ' ' && flag) break; diff --git a/engines/titanic/support/font.h b/engines/titanic/support/font.h index e1c63e6544..4bb1b2e6d6 100644 --- a/engines/titanic/support/font.h +++ b/engines/titanic/support/font.h @@ -82,6 +82,11 @@ public: */ int stringWidth(const CString &text) const; + /** + * Write a string to the specified surface + */ + int writeString(CVideoSurface *surface, const Point &pt, const CString &str); + /** * Get the text area a string will fit into * @param str String diff --git a/engines/titanic/support/screen_manager.cpp b/engines/titanic/support/screen_manager.cpp index f772bc6f7e..b467c8593d 100644 --- a/engines/titanic/support/screen_manager.cpp +++ b/engines/titanic/support/screen_manager.cpp @@ -68,6 +68,12 @@ void CScreenManager::setSurfaceBounds(SurfaceNum surfaceNum, const Rect &r) { _backSurfaces[surfaceNum]._bounds = r; } +int CScreenManager::setFontNumber(int fontNumber) { + int oldFontNumber = _fontNumber; + _fontNumber = fontNumber; + return oldFontNumber; +} + /*------------------------------------------------------------------------*/ OSScreenManager::OSScreenManager(TitanicEngine *vm): CScreenManager(vm), @@ -197,7 +203,10 @@ void OSScreenManager::blitFrom(SurfaceNum surfaceNum, CVideoSurface *src, void OSScreenManager::proc12() {} void OSScreenManager::proc13() {} void OSScreenManager::proc14() {} -void OSScreenManager::proc15() {} + +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); diff --git a/engines/titanic/support/screen_manager.h b/engines/titanic/support/screen_manager.h index baba662564..b1e949ad58 100644 --- a/engines/titanic/support/screen_manager.h +++ b/engines/titanic/support/screen_manager.h @@ -108,7 +108,11 @@ public: virtual void proc12() = 0; virtual void proc13() = 0; virtual void proc14() = 0; - virtual void proc15() = 0; + + /** + * Set the font color + */ + virtual void setFontColor(byte r, byte g, byte b) = 0; /** * Get the text area a string will fit into @@ -164,7 +168,7 @@ public: /** * Set the current font number */ - void setFontNumber(int fontNumber) { _fontNumber = fontNumber; } + int setFontNumber(int fontNumber); }; class OSScreenManager: CScreenManager { @@ -224,7 +228,11 @@ public: virtual void proc12(); virtual void proc13(); virtual void proc14(); - virtual void proc15(); + + /** + * Set the font color + */ + virtual void setFontColor(byte r, byte g, byte b); /** * Get the text area a string will fit into -- cgit v1.2.3 From 1512545f28c805fd4083be746220f77b72463130 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 25 Apr 2016 20:38:23 -0400 Subject: TITANIC: Resolve color handling code in CPetText --- engines/titanic/support/font.cpp | 10 +++++----- engines/titanic/support/font.h | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp index e903abaf97..819eaadb33 100644 --- a/engines/titanic/support/font.cpp +++ b/engines/titanic/support/font.cpp @@ -84,9 +84,9 @@ int STFont::getTextBounds(const CString &str, int maxWidth, Point *sizeOut) cons // Loop through the characters of the string if (!str.empty()) { for (const char *strP = str.c_str(); *strP; ++strP) { - if (*strP == 26) { + if (*strP == TEXTCMD_26) { strP += 3; - } else if (*strP == 27) { + } else if (*strP == TEXTCMD_SET_COLOR) { strP += 4; } else { if (*strP == ' ') { @@ -116,7 +116,7 @@ int STFont::stringWidth(const CString &text) const { if (c == 26) { // Skip over command parameter bytes srcP += 3; - } else if (c == 27) { + } else if (c == TEXTCMD_SET_COLOR) { // Skip over command parameter bytes srcP += 4; } else if (c != '\n') { @@ -211,9 +211,9 @@ void STFont::checkLineWrap(Point &textSize, int maxWidth, const char *&str) cons if (*srcPtr == ' ' && flag) break; - if (*srcPtr == 26) + if (*srcPtr == TEXTCMD_26) srcPtr += 3; - else if (*srcPtr == 27) + else if (*srcPtr == TEXTCMD_SET_COLOR) srcPtr += 4; else totalWidth += _chars[*srcPtr]._width; diff --git a/engines/titanic/support/font.h b/engines/titanic/support/font.h index 4bb1b2e6d6..087680e933 100644 --- a/engines/titanic/support/font.h +++ b/engines/titanic/support/font.h @@ -30,6 +30,8 @@ namespace Titanic { +enum TextCommand { TEXTCMD_26 = 26, TEXTCMD_SET_COLOR = 27 }; + class CVideoSurface; class STFont { -- cgit v1.2.3 From 34c32e38e2659406e3556f752fcada8491860e92 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 26 Apr 2016 22:18:21 -0400 Subject: TITANIC: More font logic, beginnings of text cursor --- engines/titanic/support/font.cpp | 59 +++++++++++++++++++++++++++--- engines/titanic/support/font.h | 6 ++- engines/titanic/support/screen_manager.cpp | 13 ++++++- engines/titanic/support/screen_manager.h | 24 +++++++++++- engines/titanic/support/text_cursor.cpp | 12 ++++-- engines/titanic/support/text_cursor.h | 54 ++++++++++++++++++++++++++- 6 files changed, 151 insertions(+), 17 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp index 819eaadb33..c6fd871e78 100644 --- a/engines/titanic/support/font.cpp +++ b/engines/titanic/support/font.cpp @@ -127,11 +127,60 @@ int STFont::stringWidth(const CString &text) const { return total; } -int STFont::writeString(CVideoSurface *surface, const Point &pt, const CString &str) { - return 0; +int STFont::writeString(CVideoSurface *surface, const Rect &rect1, const Rect &destRect, + int val1, const CString &str, CTextCursor *textCursor) { + if (!_fontHeight || !_dataPtr) + return -1; + + Point textSize; + 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_26) { + 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 fo rline wrapping + checkLineWrap(textSize, rect1.width(), srcP); + if (!*srcP) + return endP - str.c_str(); + } + + if (*srcP != '\n') { + int result = writeChar(surface, *srcP, textSize, rect1, &destBounds); + if (result == -2) + return endP - str.c_str(); + else if (!result) + endP = srcP; + } + + if (srcP < strEndP) + extendBounds(textSize, *srcP, rect1.width()); + } + } + + if (textCursor && textCursor->get54() == -2) { + Point cursorPos(rect1.left + textSize.x, rect1.top + textSize.y); + textCursor->setPos(cursorPos); + } + + return endP - str.c_str(); } -int STFont::writeChar(CVideoSurface *surface, unsigned char c, const Point &pt, Rect *destRect, Rect *srcRect) { +int STFont::writeChar(CVideoSurface *surface, unsigned char c, const Point &pt, + const Rect &destRect, const Rect *srcRect) { if (c == 233) c = '$'; @@ -140,10 +189,10 @@ int STFont::writeChar(CVideoSurface *surface, unsigned char c, const Point &pt, tempRect.right = _chars[c]._offset + _chars[c]._width; tempRect.top = 0; tempRect.bottom = _fontHeight; - Point destPos(pt.x + destRect->left, pt.y + destRect->top); + Point destPos(pt.x + destRect.left, pt.y + destRect.top); if (srcRect->isEmpty()) - srcRect = destRect; + srcRect = &destRect; if (destPos.y > srcRect->bottom) return -2; diff --git a/engines/titanic/support/font.h b/engines/titanic/support/font.h index 087680e933..f2d7c471d9 100644 --- a/engines/titanic/support/font.h +++ b/engines/titanic/support/font.h @@ -27,6 +27,7 @@ #include "common/array.h" #include "titanic/support/rect.h" #include "titanic/support/string.h" +#include "titanic/support/text_cursor.h" namespace Titanic { @@ -51,7 +52,7 @@ private: * Write a character */ int writeChar(CVideoSurface *surface, unsigned char c, - const Common::Point &pt, Rect *destRect, Rect *srcRect); + const Common::Point &pt, const Rect &destRect, const Rect *srcRect); /** * Extends a passed text area by the space required for @@ -87,7 +88,8 @@ public: /** * Write a string to the specified surface */ - int writeString(CVideoSurface *surface, const Point &pt, const CString &str); + int writeString(CVideoSurface *surface, const Rect &rect1, const Rect &destRect, + int val1, const CString &str, CTextCursor *textCursor); /** * Get the text area a string will fit into diff --git a/engines/titanic/support/screen_manager.cpp b/engines/titanic/support/screen_manager.cpp index b467c8593d..3005bdd446 100644 --- a/engines/titanic/support/screen_manager.cpp +++ b/engines/titanic/support/screen_manager.cpp @@ -201,7 +201,16 @@ void OSScreenManager::blitFrom(SurfaceNum surfaceNum, CVideoSurface *src, } void OSScreenManager::proc12() {} -void OSScreenManager::proc13() {} + +int OSScreenManager::writeString(int surfaceNum, const Rect &destRect, + int val1, const CString &str, CTextCursor *textCursor) { + if (_backSurfaces.empty()) + return -1; + + return _fonts[_fontNumber].writeString(_backSurfaces[surfaceNum]._surface, + destRect, _backSurfaces[surfaceNum]._bounds, val1, str, textCursor); +} + void OSScreenManager::proc14() {} void OSScreenManager::setFontColor(byte r, byte g, byte b) { @@ -273,7 +282,7 @@ void OSScreenManager::loadCursors() { showCursor(); if (!_textCursor) { - _textCursor = new CTextCursor(); + _textCursor = new CTextCursor(this); } } diff --git a/engines/titanic/support/screen_manager.h b/engines/titanic/support/screen_manager.h index b1e949ad58..7fe60d20b7 100644 --- a/engines/titanic/support/screen_manager.h +++ b/engines/titanic/support/screen_manager.h @@ -106,7 +106,17 @@ public: const Rect *srcRect = nullptr) = 0; virtual void proc12() = 0; - virtual void proc13() = 0; + + /** + * Write a string + * @param surfaceNum Destination surface + * @param destRect Bounds within dest surface + * @param str Line or lines to write + * @param textCursor Optional text cursor pointer + */ + virtual int writeString(int surfaceNum, const Rect &destRect, int val1, + const CString &str, CTextCursor *textCursor) = 0; + virtual void proc14() = 0; /** @@ -226,7 +236,17 @@ public: const Rect *srcRect = nullptr); virtual void proc12(); - virtual void proc13(); + + /** + * Write a string + * @param surfaceNum Destination surface + * @param destRect Bounds within dest surface + * @param str Line or lines to write + * @param textCursor Optional text cursor pointer + */ + virtual int writeString(int surfaceNum, const Rect &destRect, + int val1, const CString &str, CTextCursor *textCursor); + virtual void proc14(); /** diff --git a/engines/titanic/support/text_cursor.cpp b/engines/titanic/support/text_cursor.cpp index fd0c1d22dd..2f2ee8af8c 100644 --- a/engines/titanic/support/text_cursor.cpp +++ b/engines/titanic/support/text_cursor.cpp @@ -22,15 +22,19 @@ #include "common/textconsole.h" #include "titanic/support/text_cursor.h" +#include "titanic/support/screen_manager.h" namespace Titanic { -CTextCursor::CTextCursor() : _active(false) { +CTextCursor::CTextCursor(CScreenManager *screenManager) : + _screenManager(screenManager), _priorTicks(300), _active(false), + _field24(0), _size(2, 10), _field38(0), _field3C(0), + _field44(0), _field48(0), _field4C(0), _field54(-1) { + screenManager->createSurface(10, 10); } -Rect CTextCursor::getBounds() { - warning("CTextCursor::getBounds"); - return Rect(); +CTextCursor::~CTextCursor() { + delete _surface; } } // End of namespace Titanic diff --git a/engines/titanic/support/text_cursor.h b/engines/titanic/support/text_cursor.h index b6480673eb..d9dbce0988 100644 --- a/engines/titanic/support/text_cursor.h +++ b/engines/titanic/support/text_cursor.h @@ -28,13 +28,63 @@ namespace Titanic { +class CScreenManager; +class CVideoSurface; + class CTextCursor { +private: + CScreenManager *_screenManager; + Point _pos; + Rect _bounds; + uint _priorTicks; + int _field24; + Point _size; + int _field38; + int _field3C; + int _field44; + int _field48; + int _field4C; + CVideoSurface *_surface; + int _field54; public: bool _active; public: - CTextCursor(); + 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) { _bounds = r; } + + /** + * Clear the bounds + */ + void clearBounds() { _bounds.clear(); } + + /** + * Set the prior ticks + */ + void setTicks(uint ticks) { _priorTicks = ticks; } - Rect getBounds(); + int get54() const { return _field54; } }; } // End of namespace Titanic -- cgit v1.2.3 From d6b104d5a3e4ad7baebee8504ed60537a35a429e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 26 Apr 2016 22:32:49 -0400 Subject: TITANIC: Further work on CTextCursor fields --- engines/titanic/support/text_cursor.cpp | 4 ++-- engines/titanic/support/text_cursor.h | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/text_cursor.cpp b/engines/titanic/support/text_cursor.cpp index 2f2ee8af8c..7e69a2239a 100644 --- a/engines/titanic/support/text_cursor.cpp +++ b/engines/titanic/support/text_cursor.cpp @@ -28,8 +28,8 @@ namespace Titanic { CTextCursor::CTextCursor(CScreenManager *screenManager) : _screenManager(screenManager), _priorTicks(300), _active(false), - _field24(0), _size(2, 10), _field38(0), _field3C(0), - _field44(0), _field48(0), _field4C(0), _field54(-1) { + _field24(0), _size(2, 10), _field44(0), _field48(0), _field4C(0), + _field54(-1) { screenManager->createSurface(10, 10); } diff --git a/engines/titanic/support/text_cursor.h b/engines/titanic/support/text_cursor.h index d9dbce0988..c9fcfa35dd 100644 --- a/engines/titanic/support/text_cursor.h +++ b/engines/titanic/support/text_cursor.h @@ -39,8 +39,7 @@ private: uint _priorTicks; int _field24; Point _size; - int _field38; - int _field3C; + Point _screenTopLeft; int _field44; int _field48; int _field4C; @@ -84,6 +83,11 @@ public: */ void setTicks(uint ticks) { _priorTicks = ticks; } + /** + * Returns whether the text cursor is active + */ + bool isActive() const { return _active; } + int get54() const { return _field54; } }; -- cgit v1.2.3 From a2f933a80e5e830cdbcbb530f334c41725ee87b2 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 27 Apr 2016 19:50:48 -0400 Subject: TITANIC: Minor fleshing out on font drawing --- engines/titanic/support/font.cpp | 9 +++++---- engines/titanic/support/font.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp index c6fd871e78..d1c947f01e 100644 --- a/engines/titanic/support/font.cpp +++ b/engines/titanic/support/font.cpp @@ -128,11 +128,11 @@ int STFont::stringWidth(const CString &text) const { } int STFont::writeString(CVideoSurface *surface, const Rect &rect1, const Rect &destRect, - int val1, const CString &str, CTextCursor *textCursor) { + int yOffset, const CString &str, CTextCursor *textCursor) { if (!_fontHeight || !_dataPtr) return -1; - Point textSize; + Point textSize(0, -yOffset); Rect destBounds = destRect; destBounds.constrain(rect1); if (destBounds.isEmpty()) @@ -171,7 +171,7 @@ int STFont::writeString(CVideoSurface *surface, const Rect &rect1, const Rect &d } } - if (textCursor && textCursor->get54() == -2) { + if (textCursor && textCursor->getMode() == -2) { Point cursorPos(rect1.left + textSize.x, rect1.top + textSize.y); textCursor->setPos(cursorPos); } @@ -236,7 +236,8 @@ void STFont::copyRect(CVideoSurface *surface, const Point &pt, Rect &rect) { uint16 *destP = lineP; for (int xp = rect.left; xp < rect.right; ++xp, ++destP) { const byte *srcP = _dataPtr + yp * _dataWidth + xp; - //surface->changePixel(destP, color, *srcP >> 3, 1); + if (*srcP >> 3) + *destP = color; } } diff --git a/engines/titanic/support/font.h b/engines/titanic/support/font.h index f2d7c471d9..75c91f3d36 100644 --- a/engines/titanic/support/font.h +++ b/engines/titanic/support/font.h @@ -89,7 +89,7 @@ public: * Write a string to the specified surface */ int writeString(CVideoSurface *surface, const Rect &rect1, const Rect &destRect, - int val1, const CString &str, CTextCursor *textCursor); + int yOffset, const CString &str, CTextCursor *textCursor); /** * Get the text area a string will fit into -- cgit v1.2.3 From 74e40be66e231a8eada9bc045828e17f044a7c55 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 27 Apr 2016 19:50:58 -0400 Subject: TITANIC: Implementing text cursor drawing --- engines/titanic/support/screen_manager.cpp | 2 -- engines/titanic/support/screen_manager.h | 15 ++++++-- engines/titanic/support/text_cursor.cpp | 56 ++++++++++++++++++++++++++++-- engines/titanic/support/text_cursor.h | 49 +++++++++++++++++++------- engines/titanic/support/video_surface.h | 2 +- 5 files changed, 104 insertions(+), 20 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/screen_manager.cpp b/engines/titanic/support/screen_manager.cpp index 3005bdd446..0c9d3ab4e0 100644 --- a/engines/titanic/support/screen_manager.cpp +++ b/engines/titanic/support/screen_manager.cpp @@ -140,8 +140,6 @@ CVideoSurface *OSScreenManager::getSurface(SurfaceNum surfaceNum) const { return nullptr; } -void OSScreenManager::proc9() {} - void OSScreenManager::fillRect(SurfaceNum surfaceNum, Rect *rect, byte r, byte g, byte b) { DirectDrawSurface *surface = getDDSurface(surfaceNum); if (!surface) diff --git a/engines/titanic/support/screen_manager.h b/engines/titanic/support/screen_manager.h index 7fe60d20b7..b963fcd3d6 100644 --- a/engines/titanic/support/screen_manager.h +++ b/engines/titanic/support/screen_manager.h @@ -92,7 +92,11 @@ public: virtual void proc6() = 0; virtual void proc7() = 0; virtual CVideoSurface *getSurface(SurfaceNum surfaceNum) const = 0; - virtual void proc9() = 0; + + /** + * Return the front render surface + */ + virtual CVideoSurface *getFrontRenderSurface() const = 0; /** * Fill an area with a specific color @@ -222,7 +226,14 @@ public: virtual void proc6(); virtual void proc7(); virtual CVideoSurface *getSurface(SurfaceNum surfaceNum) const; - virtual void proc9(); + + /** + * Return the front render surface + */ + virtual CVideoSurface *getFrontRenderSurface() const { + return _frontRenderSurface; + } + /** * Fill an area with a specific color diff --git a/engines/titanic/support/text_cursor.cpp b/engines/titanic/support/text_cursor.cpp index 7e69a2239a..c3d2f20f84 100644 --- a/engines/titanic/support/text_cursor.cpp +++ b/engines/titanic/support/text_cursor.cpp @@ -23,13 +23,15 @@ #include "common/textconsole.h" #include "titanic/support/text_cursor.h" #include "titanic/support/screen_manager.h" +#include "titanic/titanic.h" namespace Titanic { CTextCursor::CTextCursor(CScreenManager *screenManager) : - _screenManager(screenManager), _priorTicks(300), _active(false), - _field24(0), _size(2, 10), _field44(0), _field48(0), _field4C(0), - _field54(-1) { + _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) { screenManager->createSurface(10, 10); } @@ -37,4 +39,52 @@ 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); + } + } + + if (_active && _blinkVisible) { + _screenManager->blitFrom(SURFACE_BACKBUFFER, _surface, &_pos); + } +} + } // End of namespace Titanic diff --git a/engines/titanic/support/text_cursor.h b/engines/titanic/support/text_cursor.h index c9fcfa35dd..d8c6ac0653 100644 --- a/engines/titanic/support/text_cursor.h +++ b/engines/titanic/support/text_cursor.h @@ -34,17 +34,20 @@ class CVideoSurface; class CTextCursor { private: CScreenManager *_screenManager; + CVideoSurface *_backRenderSurface; + CVideoSurface *_frontRenderSurface; Point _pos; - Rect _bounds; - uint _priorTicks; - int _field24; + Rect _screenBounds; + uint _blinkDelay; + bool _blinkVisible; Point _size; Point _screenTopLeft; - int _field44; - int _field48; - int _field4C; + uint _priorBlinkTime; + byte _cursorR; + byte _cursorG; + byte _cursorB; CVideoSurface *_surface; - int _field54; + int _mode; public: bool _active; public: @@ -71,24 +74,46 @@ public: /** * Set bounds */ - void setBounds(const Rect &r) { _bounds = r; } + void setBounds(const Rect &r) { _screenBounds = r; } /** * Clear the bounds */ - void clearBounds() { _bounds.clear(); } + void clearBounds() { _screenBounds.clear(); } /** - * Set the prior ticks + * Set the blinking rate */ - void setTicks(uint ticks) { _priorTicks = ticks; } + 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 get54() const { return _field54; } + 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 diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index 2ec2c9ddba..d7061895a5 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -55,7 +55,6 @@ protected: protected: CScreenManager *_screenManager; CResourceKey _resourceKey; - DirectDrawSurface *_ddSurface; Graphics::ManagedSurface *_rawSurface; bool _pendingLoad; void *_field40; @@ -66,6 +65,7 @@ protected: int _lockCount; public: CMovie *_movie; + DirectDrawSurface *_ddSurface; bool _blitFlag; bool _blitStyleFlag; public: -- cgit v1.2.3 From 2675580208561c8c8bd9d6908a202006ddf195b7 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 27 Apr 2016 20:11:40 -0400 Subject: TITANIC: Fix crashes in PET and text cursor --- engines/titanic/support/text_cursor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/text_cursor.cpp b/engines/titanic/support/text_cursor.cpp index c3d2f20f84..dc78d5350d 100644 --- a/engines/titanic/support/text_cursor.cpp +++ b/engines/titanic/support/text_cursor.cpp @@ -32,7 +32,7 @@ CTextCursor::CTextCursor(CScreenManager *screenManager) : _backRenderSurface(nullptr), _frontRenderSurface(nullptr), _blinkDelay(300), _size(2, 10), _priorBlinkTime(0), _cursorR(0), _cursorG(0), _cursorB(0), _mode(-1) { - screenManager->createSurface(10, 10); + _surface = screenManager->createSurface(10, 10); } CTextCursor::~CTextCursor() { -- cgit v1.2.3 From a8835043f54daf54a2c03ccdb02f125a62a7ddcd Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 27 Apr 2016 21:01:12 -0400 Subject: TITANIC: PET Text is now partially showing --- engines/titanic/support/screen_manager.cpp | 18 ++++++++++++++---- engines/titanic/support/screen_manager.h | 12 ++++++++---- 2 files changed, 22 insertions(+), 8 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/screen_manager.cpp b/engines/titanic/support/screen_manager.cpp index 0c9d3ab4e0..1a43d78dd0 100644 --- a/engines/titanic/support/screen_manager.cpp +++ b/engines/titanic/support/screen_manager.cpp @@ -201,12 +201,22 @@ void OSScreenManager::blitFrom(SurfaceNum surfaceNum, CVideoSurface *src, void OSScreenManager::proc12() {} int OSScreenManager::writeString(int surfaceNum, const Rect &destRect, - int val1, const CString &str, CTextCursor *textCursor) { - if (_backSurfaces.empty()) + 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 == -1) { + surface = _frontRenderSurface; + bounds = Rect(0, 0, surface->getWidth(), surface->getHeight()); + } else { return -1; + } - return _fonts[_fontNumber].writeString(_backSurfaces[surfaceNum]._surface, - destRect, _backSurfaces[surfaceNum]._bounds, val1, str, textCursor); + return _fonts[_fontNumber].writeString(surface, destRect, bounds, + yOffset, str, textCursor); } void OSScreenManager::proc14() {} diff --git a/engines/titanic/support/screen_manager.h b/engines/titanic/support/screen_manager.h index b963fcd3d6..2e80869085 100644 --- a/engines/titanic/support/screen_manager.h +++ b/engines/titanic/support/screen_manager.h @@ -115,12 +115,14 @@ public: * 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 val1, - const CString &str, CTextCursor *textCursor) = 0; - + virtual int writeString(int surfaceNum, const Rect &destRect, + int yOffset, const CString &str, CTextCursor *textCursor) = 0; + virtual void proc14() = 0; /** @@ -252,11 +254,13 @@ public: * 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 val1, const CString &str, CTextCursor *textCursor); + int yOffset, const CString &str, CTextCursor *textCursor); virtual void proc14(); -- cgit v1.2.3 From e4b231b39dfb0247afa61ac8afb40be863b9f08c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 27 Apr 2016 21:24:12 -0400 Subject: TITANIC: Fix vertical drawing of text --- engines/titanic/support/font.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp index d1c947f01e..ca9a7ed4b2 100644 --- a/engines/titanic/support/font.cpp +++ b/engines/titanic/support/font.cpp @@ -232,11 +232,11 @@ void STFont::copyRect(CVideoSurface *surface, const Point &pt, Rect &rect) { uint16 *lineP = surface->getBasePtr(pt.x, pt.y); uint16 color = getColor(); - for (int yp = rect.top; yp < rect.bottom; ++yp, lineP += surface->getPitch()) { + 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 *srcP = _dataPtr + yp * _dataWidth + xp; - if (*srcP >> 3) + if (!(*srcP >> 3)) *destP = color; } } -- cgit v1.2.3 From 001a2ac15e5c8722ba283e7380d6dc9ce11e51b0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 27 Apr 2016 23:02:00 -0400 Subject: TITANIC: Implement surface changePixel method --- engines/titanic/support/direct_draw_surface.h | 5 +++++ engines/titanic/support/font.cpp | 3 +-- engines/titanic/support/video_surface.cpp | 24 ++++++++++++++++++++++-- engines/titanic/support/video_surface.h | 4 ++-- 4 files changed, 30 insertions(+), 6 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/direct_draw_surface.h b/engines/titanic/support/direct_draw_surface.h index 12848b125d..af19e369d2 100644 --- a/engines/titanic/support/direct_draw_surface.h +++ b/engines/titanic/support/direct_draw_surface.h @@ -84,6 +84,11 @@ public: */ int getPitch() const { return _surface->pitch; } + /** + * Return the surface's format + */ + const Graphics::PixelFormat &getFormat() { return _surface->format; } + /** * Lock the surface for access */ diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp index ca9a7ed4b2..3d5705ac5a 100644 --- a/engines/titanic/support/font.cpp +++ b/engines/titanic/support/font.cpp @@ -236,8 +236,7 @@ void STFont::copyRect(CVideoSurface *surface, const Point &pt, Rect &rect) { uint16 *destP = lineP; for (int xp = rect.left; xp < rect.right; ++xp, ++destP) { const byte *srcP = _dataPtr + yp * _dataWidth + xp; - if (!(*srcP >> 3)) - *destP = color; + surface->changePixel(destP, &color, *srcP >> 3, true); } } diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index 089b216347..fe694786e4 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -164,6 +164,8 @@ bool CVideoSurface::proc45() { /*------------------------------------------------------------------------*/ +byte OSVideoSurface::_map[0x400]; + OSVideoSurface::OSVideoSurface(CScreenManager *screenManager, DirectDrawSurface *surface) : CVideoSurface(screenManager) { _ddSurface = surface; @@ -367,8 +369,26 @@ uint16 OSVideoSurface::getPixel(const Common::Point &pt) { } } -void OSVideoSurface::changePixel(uint16 *pixelP, uint16 color, int val3, int val5) { - // TODO +void OSVideoSurface::changePixel(uint16 *pixelP, uint16 *color, byte srcVal, bool remapFlag) { + assert(getPixelDepth() == 2); + const Graphics::PixelFormat &format = _ddSurface->getFormat(); + + // Get the color + byte r, g, b; + format.colorToRGB(*color, r, g, b); + if (remapFlag) { + r = _map[0x3e0 - srcVal * 32 + (r >> 2)] << 2; + g = _map[0x3e0 - srcVal * 32 + (g >> 2)] << 2; + b = _map[0x3e0 - srcVal * 32 + (b >> 2)] << 2; + } + + byte r2, g2, b2; + format.colorToRGB(*pixelP, r2, g2, b2); + r2 = _map[srcVal * 32 + (r2 >> 2)] << 2; + g2 = _map[srcVal * 32 + (g2 >> 2)] << 2; + b2 = _map[srcVal * 32 + (b2 >> 2)] << 2; + + *pixelP = format.RGBToColor(r + r2, g + g2, b + b2); } void OSVideoSurface::shiftColors() { diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index d7061895a5..60315a6477 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -147,7 +147,7 @@ public: /** * Change a pixel */ - virtual void changePixel(uint16 *pixelP, uint16 color, int val3, int val5) = 0; + virtual void changePixel(uint16 *pixelP, uint16 *color, byte srcVal, bool remapFlag = true) = 0; /** * Shifts the colors of the surface.. maybe greys it out? @@ -306,7 +306,7 @@ public: /** * Change a pixel */ - virtual void changePixel(uint16 *pixelP, uint16 color, int val3, int val5); + virtual void changePixel(uint16 *pixelP, uint16 *color, byte srcVal, bool remapFlag = true); /** * Shifts the colors of the surface.. maybe greys it out? -- cgit v1.2.3 From 44d95d8e51562d40e5049e9c1c110e6ef9ace83e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 29 Apr 2016 21:21:42 -0400 Subject: TITANIC: Simplify video surface shading palette --- engines/titanic/support/video_surface.cpp | 23 +++++++++++------------ engines/titanic/support/video_surface.h | 8 ++++---- 2 files changed, 15 insertions(+), 16 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index fe694786e4..6ce473172b 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -164,7 +164,7 @@ bool CVideoSurface::proc45() { /*------------------------------------------------------------------------*/ -byte OSVideoSurface::_map[0x400]; +byte OSVideoSurface::_palette[32][32]; OSVideoSurface::OSVideoSurface(CScreenManager *screenManager, DirectDrawSurface *surface) : CVideoSurface(screenManager) { @@ -184,17 +184,16 @@ OSVideoSurface::OSVideoSurface(CScreenManager *screenManager, const CResourceKey } } -void OSVideoSurface::setupMap(byte map[0x400], byte val) { - byte *pBase = map; +void OSVideoSurface::setupPalette(byte palette[32][32], byte val) { int incr = 0; - for (uint idx1 = 0; idx1 < 32; ++idx1, pBase += 32) { + for (uint idx1 = 0; idx1 < 32; ++idx1) { for (uint idx2 = 0, base = 0; idx2 < 32; ++idx2, base += incr) { int64 v = 0x84210843; v *= base; v = ((v >> 32) + base) >> 4; v += (v >> 31); - pBase[idx2] = v; + palette[idx1][idx2] = v; if (val != 0xff) { v &= 0xff; @@ -205,7 +204,7 @@ void OSVideoSurface::setupMap(byte map[0x400], byte val) { v >>= 7; v += (v >> 31); - pBase[idx2] = v; + palette[idx1][idx2] = v; } } } @@ -377,16 +376,16 @@ void OSVideoSurface::changePixel(uint16 *pixelP, uint16 *color, byte srcVal, boo byte r, g, b; format.colorToRGB(*color, r, g, b); if (remapFlag) { - r = _map[0x3e0 - srcVal * 32 + (r >> 2)] << 2; - g = _map[0x3e0 - srcVal * 32 + (g >> 2)] << 2; - b = _map[0x3e0 - srcVal * 32 + (b >> 2)] << 2; + r = _palette[31 - srcVal][r >> 2] << 2; + g = _palette[31 - srcVal][g >> 2] << 2; + b = _palette[31 - srcVal][b >> 2] << 2; } byte r2, g2, b2; format.colorToRGB(*pixelP, r2, g2, b2); - r2 = _map[srcVal * 32 + (r2 >> 2)] << 2; - g2 = _map[srcVal * 32 + (g2 >> 2)] << 2; - b2 = _map[srcVal * 32 + (b2 >> 2)] << 2; + r2 = _palette[srcVal][r2 >> 2] << 2; + g2 = _palette[srcVal][g2 >> 2] << 2; + b2 = _palette[srcVal][b2 >> 2] << 2; *pixelP = format.RGBToColor(r + r2, g + g2, b + b2); } diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index 60315a6477..bf2a1a18f9 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -221,17 +221,17 @@ public: class OSVideoSurface : public CVideoSurface { friend class OSMovie; private: - static byte _map[0x400]; + static byte _palette[32][32]; /** - * Setup the color mapping table + * Setup the shading palettes */ - static void setupMap(byte map[0x400], byte val); + static void setupPalette(byte palette[32][32], byte val); public: /** * Setup statics */ - static void setup() { setupMap(_map, 0xff); } + static void setup() { setupPalette(_palette, 0xff); } public: OSVideoSurface(CScreenManager *screenManager, DirectDrawSurface *surface); OSVideoSurface(CScreenManager *screenManager, const CResourceKey &key, bool flag = false); -- cgit v1.2.3 From 9205f22a43e6e5ae9a63012fe3ad545150a90b34 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 29 Apr 2016 23:22:42 -0400 Subject: TITANIC: Fix generation of shading palettes --- engines/titanic/support/video_surface.cpp | 38 ++++++++++++------------------- engines/titanic/support/video_surface.h | 8 +++++-- 2 files changed, 21 insertions(+), 25 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index 6ce473172b..cdf9e228a7 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -164,7 +164,8 @@ bool CVideoSurface::proc45() { /*------------------------------------------------------------------------*/ -byte OSVideoSurface::_palette[32][32]; +byte OSVideoSurface::_palette1[32][32]; +byte OSVideoSurface::_palette2[32][32]; OSVideoSurface::OSVideoSurface(CScreenManager *screenManager, DirectDrawSurface *surface) : CVideoSurface(screenManager) { @@ -185,27 +186,18 @@ OSVideoSurface::OSVideoSurface(CScreenManager *screenManager, const CResourceKey } void OSVideoSurface::setupPalette(byte palette[32][32], byte val) { - int incr = 0; - for (uint idx1 = 0; idx1 < 32; ++idx1) { - for (uint idx2 = 0, base = 0; idx2 < 32; ++idx2, base += incr) { + for (uint idx2 = 0, base = 0; idx2 < 32; ++idx2, base += idx1) { int64 v = 0x84210843; v *= base; - v = ((v >> 32) + base) >> 4; - v += (v >> 31); + uint v2 = (v >> 36); + v = ((v2 >> 31) + v2) & 0xff; palette[idx1][idx2] = v; - if (val != 0xff) { - v &= 0xff; - if (v != idx2) { - v = 0x80808081 * val * v * val; - v = (v >> 32) + incr; - incr = idx1; - - v >>= 7; - v += (v >> 31); - palette[idx1][idx2] = v; - } + if (val != 0xff && v != idx2) { + v = 0x80808081 * v * val; + v2 = v >> 39; + palette[idx1][idx2] = (v2 >> 31) + v2; } } } @@ -376,16 +368,16 @@ void OSVideoSurface::changePixel(uint16 *pixelP, uint16 *color, byte srcVal, boo byte r, g, b; format.colorToRGB(*color, r, g, b); if (remapFlag) { - r = _palette[31 - srcVal][r >> 2] << 2; - g = _palette[31 - srcVal][g >> 2] << 2; - b = _palette[31 - srcVal][b >> 2] << 2; + r = _palette1[31 - srcVal][r >> 2] << 2; + g = _palette1[31 - srcVal][g >> 2] << 2; + b = _palette1[31 - srcVal][b >> 2] << 2; } byte r2, g2, b2; format.colorToRGB(*pixelP, r2, g2, b2); - r2 = _palette[srcVal][r2 >> 2] << 2; - g2 = _palette[srcVal][g2 >> 2] << 2; - b2 = _palette[srcVal][b2 >> 2] << 2; + r2 = _palette1[srcVal][r2 >> 2] << 2; + g2 = _palette1[srcVal][g2 >> 2] << 2; + b2 = _palette1[srcVal][b2 >> 2] << 2; *pixelP = format.RGBToColor(r + r2, g + g2, b + b2); } diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index bf2a1a18f9..7521a53b4b 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -221,7 +221,8 @@ public: class OSVideoSurface : public CVideoSurface { friend class OSMovie; private: - static byte _palette[32][32]; + static byte _palette1[32][32]; + static byte _palette2[32][32]; /** * Setup the shading palettes @@ -231,7 +232,10 @@ public: /** * Setup statics */ - static void setup() { setupPalette(_palette, 0xff); } + static void setup() { + setupPalette(_palette1, 0xff); + setupPalette(_palette2, 0xe0); + } public: OSVideoSurface(CScreenManager *screenManager, DirectDrawSurface *surface); OSVideoSurface(CScreenManager *screenManager, const CResourceKey &key, bool flag = false); -- cgit v1.2.3 From e55f634686e06ef9bfca9655b7eca5e2d74b4757 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 30 Apr 2016 07:15:31 -0400 Subject: TITANIC: Fix palette usage in changePixel --- engines/titanic/support/video_surface.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index cdf9e228a7..e5a1e3a998 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -362,24 +362,25 @@ uint16 OSVideoSurface::getPixel(const Common::Point &pt) { void OSVideoSurface::changePixel(uint16 *pixelP, uint16 *color, byte srcVal, bool remapFlag) { assert(getPixelDepth() == 2); - const Graphics::PixelFormat &format = _ddSurface->getFormat(); - + const Graphics::PixelFormat &destFormat = _ddSurface->getFormat(); + const Graphics::PixelFormat srcFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); + // Get the color byte r, g, b; - format.colorToRGB(*color, r, g, b); + srcFormat.colorToRGB(*color, r, g, b); if (remapFlag) { - r = _palette1[31 - srcVal][r >> 2] << 2; - g = _palette1[31 - srcVal][g >> 2] << 2; - b = _palette1[31 - srcVal][b >> 2] << 2; + r = _palette1[31 - srcVal][r >> 3] << 3; + g = _palette1[31 - srcVal][g >> 3] << 3; + b = _palette1[31 - srcVal][b >> 3] << 3; } byte r2, g2, b2; - format.colorToRGB(*pixelP, r2, g2, b2); - r2 = _palette1[srcVal][r2 >> 2] << 2; - g2 = _palette1[srcVal][g2 >> 2] << 2; - b2 = _palette1[srcVal][b2 >> 2] << 2; + destFormat.colorToRGB(*pixelP, r2, g2, b2); + r2 = _palette1[srcVal][r2 >> 3] << 3; + g2 = _palette1[srcVal][g2 >> 3] << 3; + b2 = _palette1[srcVal][b2 >> 3] << 3; - *pixelP = format.RGBToColor(r + r2, g + g2, b + b2); + *pixelP = destFormat.RGBToColor(r + r2, g + g2, b + b2); } void OSVideoSurface::shiftColors() { -- cgit v1.2.3 From 210468fae9a51fabe276e8b8485145037dfcb683 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 30 Apr 2016 07:19:16 -0400 Subject: TITANIC: Minor palette cleanup, remove border from PET Quit view text --- engines/titanic/support/video_surface.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index e5a1e3a998..e6b2fa7958 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -192,12 +192,12 @@ void OSVideoSurface::setupPalette(byte palette[32][32], byte val) { v *= base; uint v2 = (v >> 36); v = ((v2 >> 31) + v2) & 0xff; - palette[idx1][idx2] = v; + palette[idx1][idx2] = v << 3; if (val != 0xff && v != idx2) { v = 0x80808081 * v * val; v2 = v >> 39; - palette[idx1][idx2] = (v2 >> 31) + v2; + palette[idx1][idx2] = ((v2 >> 31) + v2) << 3; } } } @@ -369,16 +369,16 @@ void OSVideoSurface::changePixel(uint16 *pixelP, uint16 *color, byte srcVal, boo byte r, g, b; srcFormat.colorToRGB(*color, r, g, b); if (remapFlag) { - r = _palette1[31 - srcVal][r >> 3] << 3; - g = _palette1[31 - srcVal][g >> 3] << 3; - b = _palette1[31 - srcVal][b >> 3] << 3; + r = _palette1[31 - srcVal][r >> 3]; + g = _palette1[31 - srcVal][g >> 3]; + b = _palette1[31 - srcVal][b >> 3]; } byte r2, g2, b2; destFormat.colorToRGB(*pixelP, r2, g2, b2); - r2 = _palette1[srcVal][r2 >> 3] << 3; - g2 = _palette1[srcVal][g2 >> 3] << 3; - b2 = _palette1[srcVal][b2 >> 3] << 3; + r2 = _palette1[srcVal][r2 >> 3]; + g2 = _palette1[srcVal][g2 >> 3]; + b2 = _palette1[srcVal][b2 >> 3]; *pixelP = destFormat.RGBToColor(r + r2, g + g2, b + b2); } -- cgit v1.2.3 From 21f98fff46e48e79d3e977d4f20edf90022a825a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 1 May 2016 09:46:25 -0400 Subject: TITANIC: Fix cursor and entering text in PET Conversations area --- engines/titanic/support/screen_manager.cpp | 4 +++- engines/titanic/support/text_cursor.cpp | 6 ++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/screen_manager.cpp b/engines/titanic/support/screen_manager.cpp index 1a43d78dd0..b0e249d7b3 100644 --- a/engines/titanic/support/screen_manager.cpp +++ b/engines/titanic/support/screen_manager.cpp @@ -116,7 +116,9 @@ void OSScreenManager::setMode(int width, int height, int bpp, uint numBackSurfac } void OSScreenManager::drawCursors() { - // Nothing needed here, since ScummVM handles cursor drawing + // 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) { diff --git a/engines/titanic/support/text_cursor.cpp b/engines/titanic/support/text_cursor.cpp index dc78d5350d..ad3fe4ed26 100644 --- a/engines/titanic/support/text_cursor.cpp +++ b/engines/titanic/support/text_cursor.cpp @@ -80,10 +80,8 @@ void CTextCursor::draw() { _backRenderSurface->_ddSurface->fillRect(&cursorRect, _cursorR, _cursorG, _cursorB); } - } - - if (_active && _blinkVisible) { - _screenManager->blitFrom(SURFACE_BACKBUFFER, _surface, &_pos); + + //_screenManager->blitFrom(SURFACE_BACKBUFFER, _surface, &_pos); } } -- cgit v1.2.3 From f01b8e9c45e3349c84346f270c17610b0e5350b0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 1 May 2016 13:56:42 -0400 Subject: TITANIC: Fix multi-line text writing --- engines/titanic/support/font.cpp | 28 ++++++++++++++-------------- engines/titanic/support/font.h | 11 +++++++++-- 2 files changed, 23 insertions(+), 16 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp index 3d5705ac5a..cc93bbb3c2 100644 --- a/engines/titanic/support/font.cpp +++ b/engines/titanic/support/font.cpp @@ -84,7 +84,7 @@ int STFont::getTextBounds(const CString &str, int maxWidth, Point *sizeOut) cons // Loop through the characters of the string if (!str.empty()) { for (const char *strP = str.c_str(); *strP; ++strP) { - if (*strP == TEXTCMD_26) { + if (*strP == TEXTCMD_NPC) { strP += 3; } else if (*strP == TEXTCMD_SET_COLOR) { strP += 4; @@ -141,7 +141,7 @@ int STFont::writeString(CVideoSurface *surface, const Rect &rect1, const Rect &d 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_26) { + if (*srcP == TEXTCMD_NPC) { srcP += 3; } else if (*srcP == TEXTCMD_SET_COLOR) { // Change the color used for characters @@ -159,10 +159,10 @@ int STFont::writeString(CVideoSurface *surface, const Rect &rect1, const Rect &d } if (*srcP != '\n') { - int result = writeChar(surface, *srcP, textSize, rect1, &destBounds); - if (result == -2) + WriteCharacterResult result = writeChar(surface, *srcP, textSize, rect1, &destBounds); + if (result == WC_OUTSIDE_BOTTOM) return endP - str.c_str(); - else if (!result) + else if (result == WC_IN_BOUNDS) endP = srcP; } @@ -176,10 +176,10 @@ int STFont::writeString(CVideoSurface *surface, const Rect &rect1, const Rect &d textCursor->setPos(cursorPos); } - return endP - str.c_str(); + return endP ? endP - str.c_str() : 0; } -int STFont::writeChar(CVideoSurface *surface, unsigned char c, const Point &pt, +WriteCharacterResult STFont::writeChar(CVideoSurface *surface, unsigned char c, const Point &pt, const Rect &destRect, const Rect *srcRect) { if (c == 233) c = '$'; @@ -194,7 +194,7 @@ int STFont::writeChar(CVideoSurface *surface, unsigned char c, const Point &pt, if (srcRect->isEmpty()) srcRect = &destRect; if (destPos.y > srcRect->bottom) - return -2; + return WC_OUTSIDE_BOTTOM; if ((destPos.y + tempRect.height()) > srcRect->bottom) { tempRect.bottom += tempRect.top - destPos.y; @@ -202,7 +202,7 @@ int STFont::writeChar(CVideoSurface *surface, unsigned char c, const Point &pt, if (destPos.y < srcRect->top) { if ((tempRect.height() + destPos.y) < srcRect->top) - return -1; + return WC_OUTSIDE_TOP; tempRect.top += srcRect->top - destPos.y; destPos.y = srcRect->top; @@ -210,21 +210,21 @@ int STFont::writeChar(CVideoSurface *surface, unsigned char c, const Point &pt, if (destPos.x < srcRect->left) { if ((tempRect.width() + destPos.x) < srcRect->left) - return -3; + return WC_OUTSIDE_LEFT; tempRect.left += srcRect->left - destPos.x; destPos.x = srcRect->left; } else { if ((tempRect.width() + destPos.x) > srcRect->right) { if (destPos.x > srcRect->right) - return -4; + return WC_OUTSIDE_RIGHT; tempRect.right += srcRect->left - destPos.x; } } copyRect(surface, destPos, tempRect); - return 0; + return WC_IN_BOUNDS; } void STFont::copyRect(CVideoSurface *surface, const Point &pt, Rect &rect) { @@ -247,7 +247,7 @@ void STFont::copyRect(CVideoSurface *surface, const Point &pt, Rect &rect) { void STFont::extendBounds(Point &textSize, byte c, int maxWidth) const { textSize.x += _chars[c]._width; - if (textSize.x == '\n' || textSize.x > maxWidth) { + if (c == '\n' || textSize.x > maxWidth) { textSize.x = 0; textSize.y += _fontHeight; } @@ -260,7 +260,7 @@ void STFont::checkLineWrap(Point &textSize, int maxWidth, const char *&str) cons if (*srcPtr == ' ' && flag) break; - if (*srcPtr == TEXTCMD_26) + if (*srcPtr == TEXTCMD_NPC) srcPtr += 3; else if (*srcPtr == TEXTCMD_SET_COLOR) srcPtr += 4; diff --git a/engines/titanic/support/font.h b/engines/titanic/support/font.h index 75c91f3d36..591fb4661c 100644 --- a/engines/titanic/support/font.h +++ b/engines/titanic/support/font.h @@ -31,7 +31,12 @@ namespace Titanic { -enum TextCommand { TEXTCMD_26 = 26, TEXTCMD_SET_COLOR = 27 }; +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; @@ -51,7 +56,7 @@ private: /** * Write a character */ - int writeChar(CVideoSurface *surface, unsigned char c, + WriteCharacterResult writeChar(CVideoSurface *surface, unsigned char c, const Common::Point &pt, const Rect &destRect, const Rect *srcRect); /** @@ -87,6 +92,8 @@ public: /** * 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); -- cgit v1.2.3 From 4963c9f50b53cbd663c18387d8606ad4623cca34 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 4 May 2016 07:03:13 -0400 Subject: TITANIC: Implement CMovieEvent & CMovieRangeInfo --- engines/titanic/support/movie.cpp | 2 +- engines/titanic/support/movie.h | 4 +- engines/titanic/support/movie_event.cpp | 61 +++++++++++++++++++++++++ engines/titanic/support/movie_event.h | 58 ++++++++++++++++++++++++ engines/titanic/support/movie_range_info.cpp | 67 ++++++++++++++++++++++++++++ engines/titanic/support/movie_range_info.h | 64 ++++++++++++++++++++++++++ engines/titanic/support/video_surface.cpp | 6 +++ engines/titanic/support/video_surface.h | 4 ++ 8 files changed, 263 insertions(+), 3 deletions(-) create mode 100644 engines/titanic/support/movie_event.cpp create mode 100644 engines/titanic/support/movie_event.h create mode 100644 engines/titanic/support/movie_range_info.cpp create mode 100644 engines/titanic/support/movie_range_info.h (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 3ae2636404..1c94cab250 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -91,7 +91,7 @@ void OSMovie::proc11() { warning("TODO: OSMovie::proc11"); } -void OSMovie::proc12() { +void OSMovie::proc12(const CString &name, int flags, CGameObject *obj) { warning("TODO: OSMovie::proc12"); } diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index 644f582d64..20de84afa5 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -61,7 +61,7 @@ public: virtual void proc10() = 0; virtual void proc11() = 0; - virtual void proc12() = 0; + virtual void proc12(const CString &name, int flags, CGameObject *obj) = 0; /** * Stops the movie @@ -119,7 +119,7 @@ public: virtual void proc10(); virtual void proc11(); - virtual void proc12(); + virtual void proc12(const CString &name, int flags, CGameObject *obj); /** * Stops the movie diff --git a/engines/titanic/support/movie_event.cpp b/engines/titanic/support/movie_event.cpp new file mode 100644 index 0000000000..b3e788e6fc --- /dev/null +++ b/engines/titanic/support/movie_event.cpp @@ -0,0 +1,61 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "titanic/support/movie_event.h" + +namespace Titanic { + +CMovieEvent::CMovieEvent() : ListItem(), _fieldC(0), _field10(0), + _field14(0), _field1C(0) { +} + +CMovieEvent::CMovieEvent(const CMovieEvent *src) { + _fieldC = src->_fieldC; + _field10 = src->_field10; + _field14 = src->_field14; + _field18 = src->_field18; + _field1C = src->_field1C; +} + +void CMovieEvent::save(SimpleFile *file, int indent) const { + file->writeNumberLine(0, indent); + file->writeNumberLine(_fieldC, indent + 1); + file->writeNumberLine(_field10, indent + 1); + file->writeNumberLine(_field14, indent + 1); + file->writeNumberLine(_field1C, indent + 1); + + ListItem::save(file, indent); +} + +void CMovieEvent::load(SimpleFile *file) { + int val = file->readNumber(); + if (!val) { + _fieldC = file->readNumber(); + _field10 = file->readNumber(); + _field14 = file->readNumber(); + _field1C = file->readNumber(); + } + + ListItem::load(file); +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/movie_event.h b/engines/titanic/support/movie_event.h new file mode 100644 index 0000000000..5c62220919 --- /dev/null +++ b/engines/titanic/support/movie_event.h @@ -0,0 +1,58 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_MOVIE_EVENT_H +#define TITANIC_MOVIE_EVENT_H + +#include "titanic/core/list.h" + +namespace Titanic { + +class CMovieEvent : public ListItem { +public: + int _fieldC; + int _field10; + int _field14; + int _field18; + int _field1C; +public: + CMovieEvent(); + CMovieEvent(const CMovieEvent *src); + virtual ~CMovieEvent() {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent) const; + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +class CMovieEventList : public List { +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MOVIE_EVENT_H */ diff --git a/engines/titanic/support/movie_range_info.cpp b/engines/titanic/support/movie_range_info.cpp new file mode 100644 index 0000000000..6242673c10 --- /dev/null +++ b/engines/titanic/support/movie_range_info.cpp @@ -0,0 +1,67 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "titanic/support/movie_range_info.h" + +namespace Titanic { + +CMovieRangeInfo::CMovieRangeInfo() : ListItem(), _fieldC(0), + _field10(0), _field14(0), _field18(0), _field1C(0) { +} + +CMovieRangeInfo::CMovieRangeInfo(const CMovieRangeInfo *src) : ListItem() { + _fieldC = src->_fieldC; + _field10 = src->_field10; + _field14 = src->_field14; + _field18 = src->_field18; + _field1C = src->_field1C; + + // 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) const { + file->writeNumberLine(0, indent); + file->writeNumberLine(_fieldC, indent + 1); + file->writeNumberLine(_field10, indent + 1); + file->writeNumberLine(_field14, indent + 1); + file->writeNumberLine(_field1C, indent + 1); + file->writeNumberLine(_field18, indent + 1); + _events.save(file, indent + 1); +} + +void CMovieRangeInfo::load(SimpleFile *file) { + int val = file->readNumber(); + if (!val) { + _fieldC = file->readNumber(); + _field10 = file->readNumber(); + _field14 = file->readNumber(); + _field1C = file->readNumber(); + _field18 = file->readNumber(); + _events.load(file); + } +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/movie_range_info.h b/engines/titanic/support/movie_range_info.h new file mode 100644 index 0000000000..e751e303db --- /dev/null +++ b/engines/titanic/support/movie_range_info.h @@ -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 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef 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 CMovieRangeInfo : public ListItem { +public: + int _fieldC; + int _field10; + int _field14; + int _field18; + int _field1C; + CMovieEventList _events; +public: + CMovieRangeInfo(); + CMovieRangeInfo(const CMovieRangeInfo *src); + virtual ~CMovieRangeInfo() {} + + /** + * Save the data for the class to file + */ + virtual void save(SimpleFile *file, int indent) const; + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); + + /** + * Adds an event to the events list + */ + void add(CMovieEvent *movieEvent) { _events.push_back(movieEvent); } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MOVIE_RANGE_INFO_H */ diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index e6b2fa7958..813138da4a 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -402,6 +402,12 @@ void OSVideoSurface::playMovie(uint startFrame, uint endFrame, int v3, bool v4) } } +void OSVideoSurface::proc35(const CString &name, int flags, CGameObject *owner) { + if (loadIfReady() && _movie) { + _movie->proc12(name, flags, owner); + } +} + void OSVideoSurface::stopMovie() { if (_movie) _movie->stop(); diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index 7521a53b4b..aee28be730 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -166,6 +166,8 @@ public: */ virtual void playMovie(uint startFrame, uint endFrame, int v3, bool v4) = 0; + virtual void proc35(const CString &name, int flags, CGameObject *owner) = 0; + /** * Stops any movie currently attached to the surface */ @@ -329,6 +331,8 @@ public: */ virtual void playMovie(uint startFrame, uint endFrame, int v3, bool v4); + virtual void proc35(const CString &name, int flags, CGameObject *owner); + /** * Stops any movie currently attached to the surface */ -- cgit v1.2.3 From b79ed60a8eca775613ec0b36d345dd8fcb4e5f08 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 4 May 2016 20:30:52 -0400 Subject: TITANIC: Added loadSound, support methods, and CSoundItem class --- engines/titanic/support/files_manager.cpp | 4 ++-- engines/titanic/support/files_manager.h | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/files_manager.cpp b/engines/titanic/support/files_manager.cpp index 6cd6bfb5f2..8e70387a5f 100644 --- a/engines/titanic/support/files_manager.cpp +++ b/engines/titanic/support/files_manager.cpp @@ -89,8 +89,8 @@ void CFilesManager::fn4(const CString &name) { warning("TODO: CFilesManager::fn4"); } -void CFilesManager::fn5(const CString &name) { - warning("TODO: CFilesManager::fn5"); +void CFilesManager::preload(const CString &name) { + // We don't currently do any preloading of resources } Common::SeekableReadStream *CFilesManager::getResource( diff --git a/engines/titanic/support/files_manager.h b/engines/titanic/support/files_manager.h index ae664698ac..185670c764 100644 --- a/engines/titanic/support/files_manager.h +++ b/engines/titanic/support/files_manager.h @@ -82,7 +82,10 @@ public: void fn4(const CString &name); - void fn5(const CString &name); + /** + * Preloads and caches a file for access shortly + */ + void preload(const CString &name); /** * Get a resource from the executable -- cgit v1.2.3 From c4375b134a57e3217d24e146592560f1ba9342d7 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 8 May 2016 12:09:32 -0400 Subject: TITANIC: Beginnings of STVocab class, CScriptHandler constructor --- engines/titanic/support/file_reader.cpp | 29 +++++++++++++++++++++++++ engines/titanic/support/file_reader.h | 38 +++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 engines/titanic/support/file_reader.cpp create mode 100644 engines/titanic/support/file_reader.h (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/file_reader.cpp b/engines/titanic/support/file_reader.cpp new file mode 100644 index 0000000000..c332d9995c --- /dev/null +++ b/engines/titanic/support/file_reader.cpp @@ -0,0 +1,29 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "titanic/support/file_reader.h" + +namespace Titanic { + + + +} // End of namespace Titanic diff --git a/engines/titanic/support/file_reader.h b/engines/titanic/support/file_reader.h new file mode 100644 index 0000000000..7e9eb1ac20 --- /dev/null +++ b/engines/titanic/support/file_reader.h @@ -0,0 +1,38 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_FILE_READER_H +#define TITANIC_FILE_READER_H + +#include "common/file.h" + +namespace Titanic { + +class CFileReader { +public: + Common::File _file; +public: +}; + +} // End of namespace Titanic + +#endif /* TITANIC_FILE_READER_H */ -- cgit v1.2.3 From 71179e376363c1c59b9c7819bfbe89196c7bbc23 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 8 May 2016 14:37:18 -0400 Subject: TITANIC: More script handler setup --- engines/titanic/support/file_reader.cpp | 4 ++++ engines/titanic/support/file_reader.h | 2 ++ 2 files changed, 6 insertions(+) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/file_reader.cpp b/engines/titanic/support/file_reader.cpp index c332d9995c..308d748704 100644 --- a/engines/titanic/support/file_reader.cpp +++ b/engines/titanic/support/file_reader.cpp @@ -24,6 +24,10 @@ namespace Titanic { +void CFileReader::reset() { + _file.close(); + _field18 = 0; +} } // End of namespace Titanic diff --git a/engines/titanic/support/file_reader.h b/engines/titanic/support/file_reader.h index 7e9eb1ac20..23ab0a6fce 100644 --- a/engines/titanic/support/file_reader.h +++ b/engines/titanic/support/file_reader.h @@ -30,7 +30,9 @@ namespace Titanic { class CFileReader { public: Common::File _file; + int _field18; public: + void reset(); }; } // End of namespace Titanic -- cgit v1.2.3 From 9ce6391a94db959f3dde54ed3d0153e000aa3d5a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 8 May 2016 20:57:03 -0400 Subject: TITANIC: Beginnings of TTWord hierarchy --- engines/titanic/support/file_reader.cpp | 9 ++++++--- engines/titanic/support/file_reader.h | 13 +++++++++++-- engines/titanic/support/simple_file.cpp | 23 +++++++++++++++++++++++ engines/titanic/support/simple_file.h | 13 +++++++++++++ 4 files changed, 53 insertions(+), 5 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/file_reader.cpp b/engines/titanic/support/file_reader.cpp index 308d748704..f31d72bda5 100644 --- a/engines/titanic/support/file_reader.cpp +++ b/engines/titanic/support/file_reader.cpp @@ -24,10 +24,13 @@ namespace Titanic { -void CFileReader::reset() { - _file.close(); - _field18 = 0; +CFileReader::CFileReader() : _owner(nullptr), _field4(0), _field8(0), + _fieldC(0), _field10(0), _field14(0), _field18(0) { } +void CFileReader::reset(CScriptHandler *owner, int val1, int val2) { + _owner = owner; + _field18 = val2; +} } // End of namespace Titanic diff --git a/engines/titanic/support/file_reader.h b/engines/titanic/support/file_reader.h index 23ab0a6fce..7d00ebd80d 100644 --- a/engines/titanic/support/file_reader.h +++ b/engines/titanic/support/file_reader.h @@ -27,12 +27,21 @@ namespace Titanic { +class CScriptHandler; + class CFileReader { public: - Common::File _file; + CScriptHandler *_owner; + int _field4; + int _field8; + int _fieldC; + int _field10; + int _field14; int _field18; public: - void reset(); + CFileReader(); + + void reset(CScriptHandler *owner, int val1, int val2); }; } // End of namespace Titanic diff --git a/engines/titanic/support/simple_file.cpp b/engines/titanic/support/simple_file.cpp index 88d74a9f47..b7f666a1ef 100644 --- a/engines/titanic/support/simple_file.cpp +++ b/engines/titanic/support/simple_file.cpp @@ -354,6 +354,29 @@ void SimpleFile::writeClassEnd(int 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)) + return false; + } else if (formatStr.hasPrefix("%d")) { + formatStr = CString(formatStr.c_str() + 2); + int *param = (int *)va_arg(va, int *); + *param = readNumber(); + } + } + + va_end(va); +} + /*------------------------------------------------------------------------*/ void StdCWadFile::open(const CString &name) { diff --git a/engines/titanic/support/simple_file.h b/engines/titanic/support/simple_file.h index 115e3805da..431df016ad 100644 --- a/engines/titanic/support/simple_file.h +++ b/engines/titanic/support/simple_file.h @@ -121,6 +121,11 @@ public: */ void readBuffer(char *buffer = nullptr, size_t count = 0); + /** + * Scan in values from the file + */ + bool scanf(const char *format, ...); + /** * Write a string line */ @@ -197,6 +202,14 @@ public: * 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->eos(); + } }; /** -- cgit v1.2.3 From bb8f95ba9d08d9e660b22240a59486166011bd0b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 8 May 2016 23:07:53 -0400 Subject: TITANIC: Implementing vocab load --- engines/titanic/support/simple_file.cpp | 15 +++++++++++++++ engines/titanic/support/simple_file.h | 5 +++++ 2 files changed, 20 insertions(+) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/simple_file.cpp b/engines/titanic/support/simple_file.cpp index b7f666a1ef..18a75864a8 100644 --- a/engines/titanic/support/simple_file.cpp +++ b/engines/titanic/support/simple_file.cpp @@ -78,6 +78,12 @@ size_t SimpleFile::write(const void *src, size_t count) { return _outStream->write(src, count); } +byte SimpleFile::readByte() { + byte b; + safeRead(&b, 1); + return b; +} + CString SimpleFile::readString() { char c; CString result; @@ -368,13 +374,22 @@ bool SimpleFile::scanf(const char *format, ...) { if (!Common::isSpace(c)) return false; } else if (formatStr.hasPrefix("%d")) { + // Read in a number formatStr = CString(formatStr.c_str() + 2); int *param = (int *)va_arg(va, int *); *param = readNumber(); + } 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() && (c = readByte()) != ' ') + *str += c; } } va_end(va); + return !eos(); } /*------------------------------------------------------------------------*/ diff --git a/engines/titanic/support/simple_file.h b/engines/titanic/support/simple_file.h index 431df016ad..db453c46c7 100644 --- a/engines/titanic/support/simple_file.h +++ b/engines/titanic/support/simple_file.h @@ -86,6 +86,11 @@ public: */ virtual size_t write(const void *src, size_t count); + /** + * Read a byte + */ + byte readByte(); + /** * Read a string from the file */ -- cgit v1.2.3 From b99fa6ba8c7f4a5407ff59812e5e6023c8a3301c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 9 May 2016 20:42:55 -0400 Subject: TITANIC: Fix to SimpleFile scanf --- engines/titanic/support/simple_file.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/simple_file.cpp b/engines/titanic/support/simple_file.cpp index 18a75864a8..85f42aeeb5 100644 --- a/engines/titanic/support/simple_file.cpp +++ b/engines/titanic/support/simple_file.cpp @@ -368,23 +368,34 @@ bool SimpleFile::scanf(const char *format, ...) { CString formatStr(format); while (!formatStr.empty()) { if (formatStr.hasPrefix(" ")) { + // Skip over whitespaces formatStr.deleteChar(0); - safeRead(&c, 1); + safeRead(&c, 1); if (!Common::isSpace(c)) return false; + + while (Common::isSpace(c)) + safeRead(&c, 1); + _inStream->skip(-1); } 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->skip(-1); } 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() && (c = readByte()) != ' ') + while (!eos() && !Common::isSpace(c = readByte())) *str += c; + + if (!eos()) + _inStream->skip(-1); } } -- cgit v1.2.3 From 0820c3ffaee211270ab75a14cd1d42047354aa34 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 9 May 2016 21:03:21 -0400 Subject: TITANIC: Refactor CTitleEngine to use CFilesManager for PE resources --- engines/titanic/support/files_manager.cpp | 16 +++++----------- engines/titanic/support/files_manager.h | 2 +- engines/titanic/support/font.cpp | 2 +- engines/titanic/support/mouse_cursor.cpp | 2 +- 4 files changed, 8 insertions(+), 14 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/files_manager.cpp b/engines/titanic/support/files_manager.cpp index 8e70387a5f..eb2f95e92e 100644 --- a/engines/titanic/support/files_manager.cpp +++ b/engines/titanic/support/files_manager.cpp @@ -26,13 +26,12 @@ namespace Titanic { -CFilesManager::CFilesManager() : _gameManager(nullptr), - _assetsPath("Assets"), _exeResources(nullptr), _field0(0), - _drive(-1), _field18(0), _field1C(0), _field3C(0) { +CFilesManager::CFilesManager() : _gameManager(nullptr), _assetsPath("Assets"), + _field0(0), _drive(-1), _field18(0), _field1C(0), _field3C(0) { + _exeResources.loadFromEXE("st.exe"); } CFilesManager::~CFilesManager() { - delete _exeResources; } bool CFilesManager::fileExists(const CString &name) { @@ -94,13 +93,8 @@ void CFilesManager::preload(const CString &name) { } Common::SeekableReadStream *CFilesManager::getResource( - Common::WinResourceID area, Common::WinResourceID name) { - if (!_exeResources) { - _exeResources = new Common::PEResources(); - _exeResources->loadFromEXE("st.exe"); - } - - return _exeResources->getResource(area, name); + Common::WinResourceID area, Common::WinResourceID name) { + return _exeResources.getResource(area, name); } } // End of namespace Titanic diff --git a/engines/titanic/support/files_manager.h b/engines/titanic/support/files_manager.h index 185670c764..6be6a13166 100644 --- a/engines/titanic/support/files_manager.h +++ b/engines/titanic/support/files_manager.h @@ -37,7 +37,7 @@ class CFilesManagerList : public List { class CFilesManager { private: CGameManager *_gameManager; - Common::PEResources *_exeResources; + Common::PEResources _exeResources; CFilesManagerList _list; CString _string1; CString _string2; diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp index cc93bbb3c2..916f02097b 100644 --- a/engines/titanic/support/font.cpp +++ b/engines/titanic/support/font.cpp @@ -41,7 +41,7 @@ STFont::~STFont() { void STFont::load(int fontNumber) { assert(!_dataPtr); - Common::SeekableReadStream *stream = g_vm->_filesManager.getResource( + Common::SeekableReadStream *stream = g_vm->_filesManager->getResource( Common::WinResourceID("STFONT"), fontNumber); if (!stream) error("Could not locate the specified font"); diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp index 6ddfecfd2a..6ebf4f2164 100644 --- a/engines/titanic/support/mouse_cursor.cpp +++ b/engines/titanic/support/mouse_cursor.cpp @@ -63,7 +63,7 @@ CMouseCursor::~CMouseCursor() { void CMouseCursor::loadCursorImages() { const CString name("ycursors.avi"); - g_vm->_filesManager.fn4(name); + g_vm->_filesManager->fn4(name); // WORKAROUND: We need to manipulate ycursors.avi file so it can be read // by the ScummVM AVIDecoder, by removing the redundant second video track -- cgit v1.2.3 From 3a464e8770606d75ec7a641eac207b58c95303c1 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 10 May 2016 20:51:21 -0400 Subject: TITANIC: Added new TTstringNode and TTsynonymNode classes --- engines/titanic/support/file_reader.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/file_reader.h b/engines/titanic/support/file_reader.h index 7d00ebd80d..42ab43c294 100644 --- a/engines/titanic/support/file_reader.h +++ b/engines/titanic/support/file_reader.h @@ -42,6 +42,8 @@ public: CFileReader(); void reset(CScriptHandler *owner, int val1, int val2); + + bool is18Equals(int val) const { return _field18 == val; } }; } // End of namespace Titanic -- cgit v1.2.3 From 01320c06cbb6a25ee226c1037152d5348b73cd68 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 11 May 2016 21:06:14 -0400 Subject: TITANIC: Vocab list is now completely loading --- engines/titanic/support/simple_file.cpp | 16 ++++++++++++---- engines/titanic/support/simple_file.h | 7 ++++++- 2 files changed, 18 insertions(+), 5 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/simple_file.cpp b/engines/titanic/support/simple_file.cpp index 85f42aeeb5..80f5178298 100644 --- a/engines/titanic/support/simple_file.cpp +++ b/engines/titanic/support/simple_file.cpp @@ -368,16 +368,14 @@ bool SimpleFile::scanf(const char *format, ...) { CString formatStr(format); while (!formatStr.empty()) { if (formatStr.hasPrefix(" ")) { - // Skip over whitespaces formatStr.deleteChar(0); safeRead(&c, 1); if (!Common::isSpace(c)) return false; - while (Common::isSpace(c)) - safeRead(&c, 1); - _inStream->skip(-1); + // Skip over whitespaces + skipSpaces(); } else if (formatStr.hasPrefix("%d")) { // Read in a number formatStr = CString(formatStr.c_str() + 2); @@ -399,10 +397,20 @@ bool SimpleFile::scanf(const char *format, ...) { } } + skipSpaces(); va_end(va); return !eos(); } +void SimpleFile::skipSpaces() { + char c = ' '; + while (!eos() && Common::isSpace(c)) + safeRead(&c, 1); + + if (!eos()) + _inStream->skip(-1); +} + /*------------------------------------------------------------------------*/ void StdCWadFile::open(const CString &name) { diff --git a/engines/titanic/support/simple_file.h b/engines/titanic/support/simple_file.h index db453c46c7..2a4cfdbbc0 100644 --- a/engines/titanic/support/simple_file.h +++ b/engines/titanic/support/simple_file.h @@ -48,6 +48,11 @@ public: * 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; @@ -213,7 +218,7 @@ public: */ bool eos() const { assert(_inStream); - return _inStream->eos(); + return _inStream->pos() >= _inStream->size(); } }; -- cgit v1.2.3 From 7700923298da4002a5d0baf28913a46e7e0fcf59 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 11 May 2016 21:17:28 -0400 Subject: TITANIC: Change CFileReader to CExeResoucres --- engines/titanic/support/exe_resources.cpp | 36 ++++++++++++++++++++++ engines/titanic/support/exe_resources.h | 51 +++++++++++++++++++++++++++++++ engines/titanic/support/file_reader.cpp | 36 ---------------------- engines/titanic/support/file_reader.h | 51 ------------------------------- 4 files changed, 87 insertions(+), 87 deletions(-) create mode 100644 engines/titanic/support/exe_resources.cpp create mode 100644 engines/titanic/support/exe_resources.h delete mode 100644 engines/titanic/support/file_reader.cpp delete mode 100644 engines/titanic/support/file_reader.h (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/exe_resources.cpp b/engines/titanic/support/exe_resources.cpp new file mode 100644 index 0000000000..91139dce3d --- /dev/null +++ b/engines/titanic/support/exe_resources.cpp @@ -0,0 +1,36 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "titanic/support/exe_resources.h" + +namespace Titanic { + +CExeResources::CExeResources() : _owner(nullptr), _field4(0), _field8(0), + _fieldC(0), _field10(0), _field14(0), _field18(0) { +} + +void CExeResources::reset(CScriptHandler *owner, int val1, int val2) { + _owner = owner; + _field18 = val2; +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/exe_resources.h b/engines/titanic/support/exe_resources.h new file mode 100644 index 0000000000..48b48d4933 --- /dev/null +++ b/engines/titanic/support/exe_resources.h @@ -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 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_EXE_RESOURCES_H +#define TITANIC_EXE_RESOURCES_H + +#include "common/file.h" + +namespace Titanic { + +class CScriptHandler; + +class CExeResources { +public: + CScriptHandler *_owner; + int _field4; + int _field8; + int _fieldC; + int _field10; + int _field14; + int _field18; +public: + CExeResources(); + + void reset(CScriptHandler *owner, int val1, int val2); + + bool is18Equals(int val) const { return _field18 == val; } +}; + +} // End of namespace Titanic + +#endif /* TITANIC_EXE_RESOURCES_H */ diff --git a/engines/titanic/support/file_reader.cpp b/engines/titanic/support/file_reader.cpp deleted file mode 100644 index f31d72bda5..0000000000 --- a/engines/titanic/support/file_reader.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "titanic/support/file_reader.h" - -namespace Titanic { - -CFileReader::CFileReader() : _owner(nullptr), _field4(0), _field8(0), - _fieldC(0), _field10(0), _field14(0), _field18(0) { -} - -void CFileReader::reset(CScriptHandler *owner, int val1, int val2) { - _owner = owner; - _field18 = val2; -} - -} // End of namespace Titanic diff --git a/engines/titanic/support/file_reader.h b/engines/titanic/support/file_reader.h deleted file mode 100644 index 42ab43c294..0000000000 --- a/engines/titanic/support/file_reader.h +++ /dev/null @@ -1,51 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef TITANIC_FILE_READER_H -#define TITANIC_FILE_READER_H - -#include "common/file.h" - -namespace Titanic { - -class CScriptHandler; - -class CFileReader { -public: - CScriptHandler *_owner; - int _field4; - int _field8; - int _fieldC; - int _field10; - int _field14; - int _field18; -public: - CFileReader(); - - void reset(CScriptHandler *owner, int val1, int val2); - - bool is18Equals(int val) const { return _field18 == val; } -}; - -} // End of namespace Titanic - -#endif /* TITANIC_FILE_READER_H */ -- cgit v1.2.3 From 7b71462046155e2927bd1f76634ea9b5bf45d381 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 12 May 2016 20:16:08 -0400 Subject: TITANIC: Implementing virtual methods for TTword --- engines/titanic/support/exe_resources.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/exe_resources.h b/engines/titanic/support/exe_resources.h index 48b48d4933..bb760626d4 100644 --- a/engines/titanic/support/exe_resources.h +++ b/engines/titanic/support/exe_resources.h @@ -29,6 +29,8 @@ namespace Titanic { class CScriptHandler; +enum FileHandle { HANDLE_STDIN = 0, HANDLE_STDOUT = 1, HANDLE_STDERR = 2 }; + class CExeResources { public: CScriptHandler *_owner; -- cgit v1.2.3 From d649157c5b1afae1ff6a9a565575c1eddcc880fa Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 12 May 2016 23:27:21 -0400 Subject: TITANIC: Figured out original class names for TTword descendents --- engines/titanic/support/simple_file.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/simple_file.cpp b/engines/titanic/support/simple_file.cpp index 80f5178298..61d941b680 100644 --- a/engines/titanic/support/simple_file.cpp +++ b/engines/titanic/support/simple_file.cpp @@ -399,7 +399,7 @@ bool SimpleFile::scanf(const char *format, ...) { skipSpaces(); va_end(va); - return !eos(); + return true; } void SimpleFile::skipSpaces() { -- cgit v1.2.3 From eb948946885bc128c01f5c09da0bbdba95d2c472 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 13 May 2016 20:50:47 -0400 Subject: TITANIC: Implement TTword hierarchy virtual methods --- engines/titanic/support/simple_file.cpp | 43 +++++++++++++++++++++------------ engines/titanic/support/simple_file.h | 31 ++++++++++++++---------- 2 files changed, 45 insertions(+), 29 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/simple_file.cpp b/engines/titanic/support/simple_file.cpp index 61d941b680..f4351f920f 100644 --- a/engines/titanic/support/simple_file.cpp +++ b/engines/titanic/support/simple_file.cpp @@ -73,7 +73,7 @@ size_t SimpleFile::unsafeRead(void *dst, size_t count) { return _inStream->read(dst, count); } -size_t SimpleFile::write(const void *src, size_t count) { +size_t SimpleFile::write(const void *src, size_t count) const { assert(_outStream); return _outStream->write(src, count); } @@ -237,12 +237,12 @@ void SimpleFile::readBuffer(char *buffer, size_t count) { } } -void SimpleFile::writeLine(const CString &str) { +void SimpleFile::writeLine(const CString &str) const { write(str.c_str(), str.size()); write("\r\n", 2); } -void SimpleFile::writeString(const CString &str) { +void SimpleFile::writeString(const CString &str) const { if (str.empty()) return; @@ -279,58 +279,69 @@ void SimpleFile::writeString(const CString &str) { } } -void SimpleFile::writeQuotedString(const CString &str) { +void SimpleFile::writeQuotedString(const CString &str) const { write("\"", 1); writeString(str); write("\" ", 2); } -void SimpleFile::writeQuotedLine(const CString &str, int indent) { +void SimpleFile::writeQuotedLine(const CString &str, int indent) const { writeIndent(indent); writeQuotedString(str); write("\n", 1); } -void SimpleFile::writeNumber(int val) { +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) { +void SimpleFile::writeNumberLine(int val, int indent) const { writeIndent(indent); writeNumber(val); write("\n", 1); } -void SimpleFile::writeFloat(double val) { +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) { +void SimpleFile::writeFloatLine(double val, int indent) const { writeIndent(indent); writeFloat(val); write("\n", 1); } -void SimpleFile::writePoint(const Point &pt, int indent) { +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) { +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) { +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::writeIndent(uint 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); } @@ -383,7 +394,7 @@ bool SimpleFile::scanf(const char *format, ...) { *param = readNumber(); if (!eos()) - _inStream->skip(-1); + _inStream->seek(-1, SEEK_CUR); } else if (formatStr.hasPrefix("%s")) { // Read in text until the next space formatStr = CString(formatStr.c_str() + 2); @@ -393,7 +404,7 @@ bool SimpleFile::scanf(const char *format, ...) { *str += c; if (!eos()) - _inStream->skip(-1); + _inStream->seek(-1, SEEK_CUR); } } @@ -408,7 +419,7 @@ void SimpleFile::skipSpaces() { safeRead(&c, 1); if (!eos()) - _inStream->skip(-1); + _inStream->seek(-1, SEEK_CUR); } /*------------------------------------------------------------------------*/ diff --git a/engines/titanic/support/simple_file.h b/engines/titanic/support/simple_file.h index 2a4cfdbbc0..cf89e5d72c 100644 --- a/engines/titanic/support/simple_file.h +++ b/engines/titanic/support/simple_file.h @@ -89,7 +89,7 @@ public: /** * Write out data */ - virtual size_t write(const void *src, size_t count); + virtual size_t write(const void *src, size_t count) const; /** * Read a byte @@ -139,62 +139,67 @@ public: /** * Write a string line */ - void writeLine(const CString &str); + void writeLine(const CString &str) const; /** * Write a string */ - void writeString(const CString &str); + void writeString(const CString &str) const; /** * Write a quoted string */ - void writeQuotedString(const CString &str); + void writeQuotedString(const CString &str) const; /** * Write a quoted string line */ - void writeQuotedLine(const CString &str, int indent); + void writeQuotedLine(const CString &str, int indent) const; /** * Write a number to file */ - void writeNumber(int val); + void writeNumber(int val) const; /** * Write a number line to file */ - void writeNumberLine(int val, int indent); + void writeNumberLine(int val, int indent) const; /** * Write a floating point number */ - void writeFloat(double val); + void writeFloat(double val) const; /** * Write a floating point number as a line */ - void writeFloatLine(double val, int indent); + void writeFloatLine(double val, int indent) const; /** * Write out a point line */ - void writePoint(const Point &pt, int indent); + void writePoint(const Point &pt, int indent)const; /** * Write out a rect line */ - void writeRect(const Rect &r, int indent); + void writeRect(const Rect &r, int indent) const; /** * Write out a bounds line */ - void writeBounds(const Rect &r, int indent); + 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); + void writeIndent(uint indent) const; /** * Validates that the following non-space character is either -- cgit v1.2.3 From 053ff7ab75e0ee1f18606dd6c7488c5cc0d31ae5 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 15 May 2016 18:44:47 -0400 Subject: TITANIC: Change engine to use titanic.dat --- engines/titanic/support/files_manager.cpp | 38 +++++++++++++++++++++++++++---- engines/titanic/support/files_manager.h | 18 +++++++++++---- engines/titanic/support/font.cpp | 2 +- 3 files changed, 49 insertions(+), 9 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/files_manager.cpp b/engines/titanic/support/files_manager.cpp index eb2f95e92e..c415731f16 100644 --- a/engines/titanic/support/files_manager.cpp +++ b/engines/titanic/support/files_manager.cpp @@ -28,10 +28,38 @@ namespace Titanic { CFilesManager::CFilesManager() : _gameManager(nullptr), _assetsPath("Assets"), _field0(0), _drive(-1), _field18(0), _field1C(0), _field3C(0) { - _exeResources.loadFromEXE("st.exe"); + loadResourceIndex(); } CFilesManager::~CFilesManager() { + _datFile.close(); +} + +void CFilesManager::loadResourceIndex() { + if (!_datFile.open("titanic.dat")) + error("Could not find titanic.dat data file"); + + uint headerId = _datFile.readUint32BE(); + uint version = _datFile.readUint16LE(); + if (headerId != MKTAG('S', 'V', 'T', 'N') || version < 1) + error("Invalid data file"); + + // Read in entries + uint offset, size; + char c; + Common::String resourceName; + for (;;) { + offset = _datFile.readUint32LE(); + size = _datFile.readUint32LE(); + if (size == 0) + break; + + Common::String resName; + while ((c = _datFile.readByte()) != '\0') + resName += c; + + _resources[resName] = ResourceEntry(offset, size); + } } bool CFilesManager::fileExists(const CString &name) { @@ -92,9 +120,11 @@ void CFilesManager::preload(const CString &name) { // We don't currently do any preloading of resources } -Common::SeekableReadStream *CFilesManager::getResource( - Common::WinResourceID area, Common::WinResourceID name) { - return _exeResources.getResource(area, name); +Common::SeekableReadStream *CFilesManager::getResource(const CString &str) { + ResourceEntry resEntry = _resources[str]; + _datFile.seek(resEntry._offset); + + return _datFile.readStream(resEntry._size); } } // End of namespace Titanic diff --git a/engines/titanic/support/files_manager.h b/engines/titanic/support/files_manager.h index 6be6a13166..ec0c7fc008 100644 --- a/engines/titanic/support/files_manager.h +++ b/engines/titanic/support/files_manager.h @@ -23,7 +23,7 @@ #ifndef TITANIC_FILES_MANAGER_H #define TITANIC_FILES_MANAGER_H -#include "common/winexe_pe.h" +#include "common/hashmap.h" #include "titanic/core/list.h" #include "titanic/support/screen_manager.h" @@ -35,9 +35,18 @@ class CFilesManagerList : public List { }; class CFilesManager { + struct ResourceEntry { + uint _offset; + uint _size; + + ResourceEntry() : _offset(0), _size(0) {} + ResourceEntry(uint offset, uint size) : _offset(offset), _size(size) {} + }; + typedef Common::HashMap ResourceHash; private: CGameManager *_gameManager; - Common::PEResources _exeResources; + Common::File _datFile; + ResourceHash _resources; CFilesManagerList _list; CString _string1; CString _string2; @@ -47,6 +56,8 @@ private: int _field1C; int _field3C; const CString _assetsPath; +private: + void loadResourceIndex(); public: CFilesManager(); ~CFilesManager(); @@ -90,8 +101,7 @@ public: /** * Get a resource from the executable */ - Common::SeekableReadStream *getResource(Common::WinResourceID area, - Common::WinResourceID name); + Common::SeekableReadStream *getResource(const CString &str); }; } // End of namespace Titanic diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp index 916f02097b..c960e2fa9e 100644 --- a/engines/titanic/support/font.cpp +++ b/engines/titanic/support/font.cpp @@ -42,7 +42,7 @@ STFont::~STFont() { void STFont::load(int fontNumber) { assert(!_dataPtr); Common::SeekableReadStream *stream = g_vm->_filesManager->getResource( - Common::WinResourceID("STFONT"), fontNumber); + CString::format("STFONT/%d", fontNumber)); if (!stream) error("Could not locate the specified font"); -- cgit v1.2.3 From b37da849c936cc1842969b150e84dd0ad145f576 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 15 May 2016 23:15:24 -0400 Subject: TITANIC: Implement TTparser searchAndReplace methods --- engines/titanic/support/string.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/string.h b/engines/titanic/support/string.h index 02775de067..fdaf92cfad 100644 --- a/engines/titanic/support/string.h +++ b/engines/titanic/support/string.h @@ -24,6 +24,7 @@ #define TITANIC_STRING_H #include "common/scummsys.h" +#include "common/array.h" #include "common/str.h" namespace Titanic { @@ -101,6 +102,8 @@ public: static CString format(const char *fmt, ...); }; +typedef Common::Array StringArray; + } // End of namespace Titanic #endif /* TITANIC_STRING_H */ -- cgit v1.2.3 From e1ba9672330802c458aebd7049e8ae3f4b23f9ca Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 16 May 2016 07:40:10 -0400 Subject: TITANIC: Moved other static arrays from Titanic engine to dat file --- engines/titanic/support/exe_resources.cpp | 3 ++- engines/titanic/support/exe_resources.h | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/exe_resources.cpp b/engines/titanic/support/exe_resources.cpp index 91139dce3d..522e92f718 100644 --- a/engines/titanic/support/exe_resources.cpp +++ b/engines/titanic/support/exe_resources.cpp @@ -21,11 +21,12 @@ */ #include "titanic/support/exe_resources.h" +#include "titanic/titanic.h" namespace Titanic { CExeResources::CExeResources() : _owner(nullptr), _field4(0), _field8(0), - _fieldC(0), _field10(0), _field14(0), _field18(0) { + _fieldC(0), _field10(0), _field14(0), _field18(0) { } void CExeResources::reset(CScriptHandler *owner, int val1, int val2) { diff --git a/engines/titanic/support/exe_resources.h b/engines/titanic/support/exe_resources.h index bb760626d4..49e05aa56f 100644 --- a/engines/titanic/support/exe_resources.h +++ b/engines/titanic/support/exe_resources.h @@ -23,8 +23,6 @@ #ifndef TITANIC_EXE_RESOURCES_H #define TITANIC_EXE_RESOURCES_H -#include "common/file.h" - namespace Titanic { class CScriptHandler; -- cgit v1.2.3 From 3878f38d8c76f2289be1f53bbecf9cda95e43067 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 16 May 2016 19:59:09 -0400 Subject: TITANIC: Move replacement string arrays into TTparser, added NUMBERS array --- engines/titanic/support/simple_file.cpp | 11 +++++++++++ engines/titanic/support/simple_file.h | 5 +++++ 2 files changed, 16 insertions(+) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/simple_file.cpp b/engines/titanic/support/simple_file.cpp index f4351f920f..45b5c8a7cb 100644 --- a/engines/titanic/support/simple_file.cpp +++ b/engines/titanic/support/simple_file.cpp @@ -25,6 +25,17 @@ 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::String &name) { if (!Common::File::open(name)) error("Could not open file - %s", name.c_str()); diff --git a/engines/titanic/support/simple_file.h b/engines/titanic/support/simple_file.h index cf89e5d72c..bca96a631a 100644 --- a/engines/titanic/support/simple_file.h +++ b/engines/titanic/support/simple_file.h @@ -269,6 +269,11 @@ public: 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 */ -- cgit v1.2.3 From fa04a6fdf0271f74c45da180b3c6f1ac16bd3a98 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 28 May 2016 18:13:09 -0400 Subject: TITANIC: Added CTrueTalkManager playSpeech --- engines/titanic/support/proximity.cpp | 5 +++-- engines/titanic/support/proximity.h | 15 +++++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/proximity.cpp b/engines/titanic/support/proximity.cpp index f7c90f7caf..4a832b9217 100644 --- a/engines/titanic/support/proximity.cpp +++ b/engines/titanic/support/proximity.cpp @@ -21,16 +21,17 @@ */ #include "titanic/support/proximity.h" +#include "titanic/true_talk/tt_talker.h" namespace Titanic { CProximity::CProximity() : _field4(0), _field8(100), _fieldC(0), - _field10(-1), _field14(0), _field18(0), _field1C(0x3FF00000), + _speechHandle(-1), _field14(0), _field18(0), _field1C(0x3FF00000), _field20(0), _field24(10), _field28(0), _field2C(0), _field30(0x3F000000), _field34(0), _double1(0.0), _double2(0.0), _double3(0.0), _field44(0), _field48(0), _field4C(0), _field50(0), _field54(0), _field58(0), _field5C(0), - _field60(0), _field64(0), _field68(0) { + _field60(0), _method1(nullptr), _talker(nullptr), _field6C(0) { } } // End of namespace Titanic diff --git a/engines/titanic/support/proximity.h b/engines/titanic/support/proximity.h index 69979eaeaf..935e2e6b1c 100644 --- a/engines/titanic/support/proximity.h +++ b/engines/titanic/support/proximity.h @@ -23,21 +23,27 @@ #ifndef TITANIC_PROXIMITY_H #define TITANIC_PROXIMITY_H +#include "common/scummsys.h" + namespace Titanic { +typedef bool (*CProximityFn)(int val); + +class TTtalker; + class CProximity { public: int _field4; int _field8; int _fieldC; - int _field10; + int _speechHandle; int _field14; int _field18; int _field1C; int _field20; int _field24; int _field28; - int _field2C; + uint32 _field2C; int _field30; int _field34; double _double1; @@ -51,8 +57,9 @@ public: int _field58; int _field5C; int _field60; - int _field64; - int _field68; + CProximityFn _method1; + TTtalker *_talker; + int _field6C; public: CProximity(); }; -- cgit v1.2.3 From 66efdc239c88124296acdcb45427d83793934e91 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 4 Jun 2016 15:56:47 -0400 Subject: TITANIC: gcc compilation fixes --- engines/titanic/support/font.cpp | 4 ++-- engines/titanic/support/string.cpp | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp index c960e2fa9e..f4466def31 100644 --- a/engines/titanic/support/font.cpp +++ b/engines/titanic/support/font.cpp @@ -112,7 +112,7 @@ int STFont::stringWidth(const CString &text) const { const char *srcP = text.c_str(); int total = 0; char c; - while (c = *srcP++) { + while (c = (*srcP++)) { if (c == 26) { // Skip over command parameter bytes srcP += 3; @@ -265,7 +265,7 @@ void STFont::checkLineWrap(Point &textSize, int maxWidth, const char *&str) cons else if (*srcPtr == TEXTCMD_SET_COLOR) srcPtr += 4; else - totalWidth += _chars[*srcPtr]._width; + totalWidth += _chars[(byte)*srcPtr]._width; } if ((textSize.x + totalWidth) >= maxWidth && totalWidth < maxWidth) { diff --git a/engines/titanic/support/string.cpp b/engines/titanic/support/string.cpp index 86dc0be0b0..d85fcfc515 100644 --- a/engines/titanic/support/string.cpp +++ b/engines/titanic/support/string.cpp @@ -32,9 +32,7 @@ CString::CString(char c, uint32 len) : Common::String() { } CString::CString(int val) : Common::String() { - char buffer[16]; - itoa(val, buffer, 10); - *this += buffer; + *this = CString::format("%d", val); } CString CString::left(uint count) const { -- cgit v1.2.3 From 764cfcb6d6ccad3046c9d96788b3edd5857f1c79 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 4 Jun 2016 17:24:38 -0400 Subject: TITANIC: gcc compilation fixes --- engines/titanic/support/font.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/font.cpp b/engines/titanic/support/font.cpp index f4466def31..07e4c28991 100644 --- a/engines/titanic/support/font.cpp +++ b/engines/titanic/support/font.cpp @@ -112,7 +112,7 @@ int STFont::stringWidth(const CString &text) const { const char *srcP = text.c_str(); int total = 0; char c; - while (c = (*srcP++)) { + while ((c = *srcP++)) { if (c == 26) { // Skip over command parameter bytes srcP += 3; @@ -120,7 +120,7 @@ int STFont::stringWidth(const CString &text) const { // Skip over command parameter bytes srcP += 4; } else if (c != '\n') { - total += _chars[c]._width; + total += _chars[(byte)c]._width; } } -- cgit v1.2.3 From 68f13646e185416bb74812ea489764b9b28b8e22 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 19 Jun 2016 09:58:00 -0400 Subject: TITANIC: Implementing more CGameObject/OSScreenManager draw methods --- engines/titanic/support/screen_manager.cpp | 16 ++++++++++++++-- engines/titanic/support/screen_manager.h | 16 +++++++++++----- 2 files changed, 25 insertions(+), 7 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/screen_manager.cpp b/engines/titanic/support/screen_manager.cpp index b0e249d7b3..27c0d9886e 100644 --- a/engines/titanic/support/screen_manager.cpp +++ b/engines/titanic/support/screen_manager.cpp @@ -163,7 +163,7 @@ void OSScreenManager::fillRect(SurfaceNum surfaceNum, Rect *rect, byte r, byte g } void OSScreenManager::blitFrom(SurfaceNum surfaceNum, CVideoSurface *src, - const Point *destPos, const Rect *srcRect) { + const Point *destPos, const Rect *srcRect) { // Get the dest surface CVideoSurface *destSurface = _frontRenderSurface; if (surfaceNum < -1) @@ -200,7 +200,19 @@ void OSScreenManager::blitFrom(SurfaceNum surfaceNum, CVideoSurface *src, destSurface->blitFrom(destPoint, src, bounds); } -void OSScreenManager::proc12() {} +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) { diff --git a/engines/titanic/support/screen_manager.h b/engines/titanic/support/screen_manager.h index 2e80869085..21b40cad37 100644 --- a/engines/titanic/support/screen_manager.h +++ b/engines/titanic/support/screen_manager.h @@ -41,8 +41,8 @@ namespace Titanic { * remapped to the primary surface */ enum SurfaceNum { - SURFACE_PRIMARY = -1, - SURFACE_BACKBUFFER = -1 + SURFACE_PRIMARY = -1, // Surface 0 + SURFACE_BACKBUFFER = -1 // Surface -1 }; class TitanicEngine; @@ -109,8 +109,11 @@ public: virtual void blitFrom(SurfaceNum surfaceNum, CVideoSurface *src, const Point *destPos = nullptr, const Rect *srcRect = nullptr) = 0; - virtual void proc12() = 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 @@ -248,7 +251,10 @@ public: virtual void blitFrom(SurfaceNum surfaceNum, CVideoSurface *src, const Point *destPos, const Rect *srcRect = nullptr); - virtual void proc12(); + /** + * Blits a surface onto one of the screen surfaces + */ + virtual void blitFrom(SurfaceNum surfaceNum, const Rect *rect, CVideoSurface *src, int v = 0); /** * Write a string -- cgit v1.2.3 From 2267c5eb4c5addecbf0012495f84ece6d6df835d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 19 Jun 2016 16:21:49 -0400 Subject: TITANIC: Beginnings of CCreditText class --- engines/titanic/support/credit_text.cpp | 63 +++++++++++++++++++++++ engines/titanic/support/credit_text.h | 90 +++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 engines/titanic/support/credit_text.cpp create mode 100644 engines/titanic/support/credit_text.h (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/credit_text.cpp b/engines/titanic/support/credit_text.cpp new file mode 100644 index 0000000000..e70d1dcf7a --- /dev/null +++ b/engines/titanic/support/credit_text.cpp @@ -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 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "titanic/support/credit_text.h" +#include "titanic/titanic.h" + +namespace Titanic { + +CCreditText::CCreditText() : _screenManagerP(nullptr), _field14(0), + _ticks(0), _fontHeight(1), _objectP(nullptr), _field34(0), _field38(0), + _field3C(0), _field40(0), _field44(0), _field48(0), _field4C(0), + _field50(0), _field54(0), _field58(0), _field5C(0) { +} + +void CCreditText::clear() { + _list.destroyContents(); + _objectP = nullptr; +} + +void CCreditText::load(CGameObject *obj, CScreenManager *screenManager, + const Rect &rect, int v) { + _objectP = obj; + _screenManagerP = screenManager; + _field14 = v; + _ticks = g_vm->_events->getTicksCount(); + _field40 = 0; + _field44 = 0xFF; + _field48 = 0xFF; + _field4C = 0xFF; + _field50 = 0; + _field54 = 0; + _field58 = 0; + _field5C = 0; +} + +void CCreditText::setup() { + // TODO +} + +bool CCreditText::draw() { + return false; +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/credit_text.h b/engines/titanic/support/credit_text.h new file mode 100644 index 0000000000..82da833bbe --- /dev/null +++ b/engines/titanic/support/credit_text.h @@ -0,0 +1,90 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_CREDIT_TEXT_H +#define TITANIC_CREDIT_TEXT_H + +#include "titanic/core/list.h" + +namespace Titanic { + +class CGameObject; +class CScreenManager; + +class COverrideSubItem : public ListItem { + +}; +typedef List CCreditTextSubList; + +class CCreditTextItem : public ListItem { + +}; +typedef List CCreditTextList; + +class CCreditText { +private: + /** + * Sets up needed data + */ + void setup(); +public: + CScreenManager *_screenManagerP; + Rect _rect; + int _field14; + CCreditTextList _list; + uint _ticks; + uint _fontHeight; + CGameObject *_objectP; + int _field34; + int _field38; + int _field3C; + int _field40; + int _field44; + int _field48; + int _field4C; + int _field50; + int _field54; + int _field58; + int _field5C; +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, int v = 0); + + /** + * Draw the item + */ + bool draw(); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_CREDIT_TEXT_H */ -- cgit v1.2.3 From f0889c17a46019b8b294a74d054d0c60e445190b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 19 Jun 2016 20:58:37 -0400 Subject: TITANIC: Implementing lots of cGameObject methods --- engines/titanic/support/movie.cpp | 8 ++++++-- engines/titanic/support/movie.h | 2 ++ engines/titanic/support/video_surface.cpp | 4 ++++ engines/titanic/support/video_surface.h | 4 ++++ 4 files changed, 16 insertions(+), 2 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 1c94cab250..26620de3a6 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -26,7 +26,8 @@ namespace Titanic { -CMovie::CMovie() : ListItem(), _state(MOVIE_STOPPED), _field10(0) { +CMovie::CMovie() : ListItem(), _state(MOVIE_STOPPED), _field10(0), + _field14(0) { } CMovie::~CMovie() { @@ -50,7 +51,10 @@ bool CMovie::get10() { OSMovie::OSMovie(const CResourceKey &name, CVideoSurface *surface) : _videoSurface(surface), _gameObject(nullptr), _endFrame(-1) { - _video = new Video::AVIDecoder(); + Video::AVIDecoder *decoder = new Video::AVIDecoder(); + _video = decoder; + _field14 = 1; + if (!_video->loadFile(name.getString())) error("Could not open video - %s", name.getString().c_str()); } diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index 20de84afa5..01f107ec5b 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -45,6 +45,8 @@ class CMovie : public ListItem { protected: MovieState _state; int _field10; +public: + int _field14; public: CMovie(); virtual ~CMovie(); diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index 813138da4a..3b026c546c 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -418,6 +418,10 @@ void OSVideoSurface::setMovieFrame(uint frameNumber) { _movie->setFrame(frameNumber); } +void OSVideoSurface::proc38(int v1, int v2) { + warning("OSVideoSurface::proc38"); +} + bool OSVideoSurface::loadIfReady() { _videoSurfaceNum = _videoSurfaceCounter; diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index aee28be730..8d0dd2ffac 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -178,6 +178,8 @@ public: */ virtual void setMovieFrame(uint frameNumber) = 0; + virtual void proc38(int v1, int v2) = 0; + /** * Loads the surface's resource if there's one pending */ @@ -343,6 +345,8 @@ public: */ virtual void setMovieFrame(uint frameNumber); + virtual void proc38(int v1, int v2); + /** * Loads the surface's resource if there's one pending */ -- cgit v1.2.3 From 04afc633794035cfcc0cb7030113d7750a7dbae3 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 25 Jun 2016 23:07:44 -0400 Subject: TITANIC: Adding savegame header load/save methods --- engines/titanic/support/simple_file.cpp | 31 +++++++++++++++++++++++++++++++ engines/titanic/support/simple_file.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/simple_file.cpp b/engines/titanic/support/simple_file.cpp index 45b5c8a7cb..e60b7c7485 100644 --- a/engines/titanic/support/simple_file.cpp +++ b/engines/titanic/support/simple_file.cpp @@ -89,12 +89,29 @@ size_t SimpleFile::write(const void *src, size_t count) const { 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; @@ -248,6 +265,20 @@ void SimpleFile::readBuffer(char *buffer, size_t count) { } } +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); diff --git a/engines/titanic/support/simple_file.h b/engines/titanic/support/simple_file.h index bca96a631a..a83e5922e2 100644 --- a/engines/titanic/support/simple_file.h +++ b/engines/titanic/support/simple_file.h @@ -61,6 +61,9 @@ public: SimpleFile(); virtual ~SimpleFile(); + operator Common::SeekableReadStream &() { return *_inStream; } + operator Common::WriteStream &() { return *_outStream; } + /** * Set up a stream for read access */ @@ -91,11 +94,26 @@ public: */ 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 */ @@ -136,6 +154,21 @@ public: */ 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 */ -- cgit v1.2.3 From 0146a3c6b6bdb16eef6f46e116b0d9fe9883858f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Jun 2016 07:23:15 -0400 Subject: TITANIC: Added remaining CPetControl methods --- engines/titanic/support/simple_file.h | 1 - 1 file changed, 1 deletion(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/simple_file.h b/engines/titanic/support/simple_file.h index a83e5922e2..0cfb424fad 100644 --- a/engines/titanic/support/simple_file.h +++ b/engines/titanic/support/simple_file.h @@ -98,7 +98,6 @@ public: * Seek */ virtual void seek(int offset, int origin); - /** * Read a byte */ -- cgit v1.2.3 From ef1d10e926fcf31ffeb5c594a305ec0cd8bf7064 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 26 Jun 2016 23:00:00 -0400 Subject: TITANIC: Implemented remaining CGameManager methods and others --- engines/titanic/support/movie.cpp | 4 ++-- engines/titanic/support/movie.h | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 26620de3a6..cde3b22a8c 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -87,8 +87,8 @@ void OSMovie::play(uint startFrame, uint endFrame, int v3, bool v4) { _state = MOVIE_NONE; } -void OSMovie::proc10() { - warning("TODO: OSMovie::proc10"); +void OSMovie::playClip(const Rect &rect, uint startFrame, uint endFrame) { + warning("TODO: OSMovie::playClip"); } void OSMovie::proc11() { diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index 01f107ec5b..61dd4cf61d 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -61,7 +61,11 @@ public: */ virtual void play(uint startFrame, uint endFrame, int v3, bool v4) = 0; - virtual void proc10() = 0; + /** + * Plays a sub-section of a movie + */ + virtual void playClip(const Rect &rect, uint startFrame, uint endFrame) = 0; + virtual void proc11() = 0; virtual void proc12(const CString &name, int flags, CGameObject *obj) = 0; @@ -119,7 +123,11 @@ public: */ virtual void play(uint startFrame, uint endFrame, int v3, bool v4); - virtual void proc10(); + /** + * Plays a sub-section of a movie + */ + virtual void playClip(const Rect &rect, uint startFrame, uint endFrame); + virtual void proc11(); virtual void proc12(const CString &name, int flags, CGameObject *obj); -- cgit v1.2.3 From f141b337177bb0bd001c753f8cb17999b6ea2bf9 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 27 Jun 2016 19:19:04 -0400 Subject: TITANIC: Adding CGameObject methods --- engines/titanic/support/video_surface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index 8d0dd2ffac..6f707a39ff 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -54,7 +54,6 @@ protected: static int _videoSurfaceCounter; protected: CScreenManager *_screenManager; - CResourceKey _resourceKey; Graphics::ManagedSurface *_rawSurface; bool _pendingLoad; void *_field40; @@ -68,6 +67,7 @@ public: DirectDrawSurface *_ddSurface; bool _blitFlag; bool _blitStyleFlag; + CResourceKey _resourceKey; public: CVideoSurface(CScreenManager *screenManager); virtual ~CVideoSurface(); -- cgit v1.2.3 From a1c181f94945633300a9e9c4f657bb654abad98c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 27 Jun 2016 21:26:00 -0400 Subject: TITANIC: Adding CGameObject methods --- engines/titanic/support/mouse_cursor.cpp | 18 +++++++++++++++++- engines/titanic/support/mouse_cursor.h | 7 +++++++ engines/titanic/support/video_surface.cpp | 4 ++++ engines/titanic/support/video_surface.h | 4 ++++ 4 files changed, 32 insertions(+), 1 deletion(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp index 6ebf4f2164..d87e7a499b 100644 --- a/engines/titanic/support/mouse_cursor.cpp +++ b/engines/titanic/support/mouse_cursor.cpp @@ -51,7 +51,8 @@ static const int CURSOR_DATA[NUM_CURSORS][4] = { }; CMouseCursor::CMouseCursor(CScreenManager *screenManager) : - _screenManager(screenManager), _cursorId(CURSOR_HOURGLASS), _setCursorCount(0) { + _screenManager(screenManager), _cursorId(CURSOR_HOURGLASS), + _setCursorCount(0), _fieldE4(0), _fieldE8(0) { loadCursorImages(); setCursor(CURSOR_ARROW); } @@ -129,4 +130,19 @@ void CMouseCursor::update() { // No implementation needed } +void CMouseCursor::lockE4() { + _fieldE4 = 0; + CScreenManager::_screenManagerPtr->_inputHandler->incLockCount(); +} + +void CMouseCursor::unlockE4() { + _fieldE4 = 1; + _fieldE8 = 0; + CScreenManager::_screenManagerPtr->_inputHandler->decLockCount(); +} + +void CMouseCursor::saveState(int v1, int v2, int v3) { + // TODO +} + } // End of namespace Titanic diff --git a/engines/titanic/support/mouse_cursor.h b/engines/titanic/support/mouse_cursor.h index ac5da26382..55e0cb4da5 100644 --- a/engines/titanic/support/mouse_cursor.h +++ b/engines/titanic/support/mouse_cursor.h @@ -62,6 +62,8 @@ private: CursorId _cursorId; CursorEntry _cursors[NUM_CURSORS]; uint _setCursorCount; + int _fieldE4; + int _fieldE8; /** * Load the images for each cursor @@ -95,6 +97,11 @@ public: * Returns the number of times the cursor has been set */ uint getChangeCount() const { return _setCursorCount; } + + void lockE4(); + void unlockE4(); + + void saveState(int v1, int v2, int v3); }; diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index 3b026c546c..c1af869e1e 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -422,6 +422,10 @@ void OSVideoSurface::proc38(int v1, int v2) { warning("OSVideoSurface::proc38"); } +void OSVideoSurface::proc39(int v1, int v2) { + warning("OSVideoSurface::proc39"); +} + bool OSVideoSurface::loadIfReady() { _videoSurfaceNum = _videoSurfaceCounter; diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index 6f707a39ff..2b66b269e7 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -180,6 +180,8 @@ public: virtual void proc38(int v1, int v2) = 0; + virtual void proc39(int v1, int v2) = 0; + /** * Loads the surface's resource if there's one pending */ @@ -347,6 +349,8 @@ public: virtual void proc38(int v1, int v2); + virtual void proc39(int v1, int v2); + /** * Loads the surface's resource if there's one pending */ -- cgit v1.2.3 From 0715be79269a0830136f76e78da2e893ce2e2ed4 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 27 Jun 2016 23:48:13 -0400 Subject: TITANIC: Added CGameObject text methods --- engines/titanic/support/movie.cpp | 4 ++++ engines/titanic/support/movie.h | 10 ++++++++++ 2 files changed, 14 insertions(+) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index cde3b22a8c..27bcb97ae9 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -87,6 +87,10 @@ void OSMovie::play(uint startFrame, uint endFrame, int v3, bool v4) { _state = MOVIE_NONE; } +void OSMovie::play(const Rect &rect, int v1, int v2) { + warning("TODO: OSMovie::play 3"); +} + void OSMovie::playClip(const Rect &rect, uint startFrame, uint endFrame) { warning("TODO: OSMovie::playClip"); } diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index 61dd4cf61d..da3285547d 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -60,6 +60,11 @@ public: * Plays the movie */ virtual void play(uint startFrame, uint endFrame, int v3, bool v4) = 0; + + /** + * Plays the movie + */ + virtual void play(const Rect &rect, int v1, int v2) = 0; /** * Plays a sub-section of a movie @@ -123,6 +128,11 @@ public: */ virtual void play(uint startFrame, uint endFrame, int v3, bool v4); + /** + * Plays the movie + */ + virtual void play(const Rect &rect, int v1, int v2); + /** * Plays a sub-section of a movie */ -- cgit v1.2.3 From ce0be01e317996c0454a85dd9a24b896e13ddc8e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 29 Jun 2016 13:08:17 -0400 Subject: TITANIC: Cleanup CGameObject list from CMovieClipList to CMovieRangeInfoList --- engines/titanic/support/movie_clip.cpp | 98 ++++++++++++++++++++++++++++ engines/titanic/support/movie_clip.h | 92 ++++++++++++++++++++++++++ engines/titanic/support/movie_range_info.cpp | 14 ++++ engines/titanic/support/movie_range_info.h | 7 ++ 4 files changed, 211 insertions(+) create mode 100644 engines/titanic/support/movie_clip.cpp create mode 100644 engines/titanic/support/movie_clip.h (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie_clip.cpp b/engines/titanic/support/movie_clip.cpp new file mode 100644 index 0000000000..da655ce76a --- /dev/null +++ b/engines/titanic/support/movie_clip.cpp @@ -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 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "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) const { + 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 diff --git a/engines/titanic/support/movie_clip.h b/engines/titanic/support/movie_clip.h new file mode 100644 index 0000000000..0b1106f420 --- /dev/null +++ b/engines/titanic/support/movie_clip.h @@ -0,0 +1,92 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef 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 _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 + */ + virtual void save(SimpleFile *file, int indent) const; + + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file); +}; + +/** + * Movie clip list + */ +class CMovieClipList: public List { +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 */ diff --git a/engines/titanic/support/movie_range_info.cpp b/engines/titanic/support/movie_range_info.cpp index 6242673c10..ff246fbe7b 100644 --- a/engines/titanic/support/movie_range_info.cpp +++ b/engines/titanic/support/movie_range_info.cpp @@ -64,4 +64,18 @@ void CMovieRangeInfo::load(SimpleFile *file) { } } +void CMovieRangeInfo::process(CGameObject *owner) { +/* + int flags = 0; + if (_endFrame) + flags |= CLIPFLAG_HAS_END_FRAME; + if (_startFrame) + flags |= CLIPFLAG_HAS_START_FRAME; + + warning("TODO: CMovieClip::process"); + + owner->checkPlayMovie(_name, flags); + */ +} + } // End of namespace Titanic diff --git a/engines/titanic/support/movie_range_info.h b/engines/titanic/support/movie_range_info.h index e751e303db..2c7d86f3c5 100644 --- a/engines/titanic/support/movie_range_info.h +++ b/engines/titanic/support/movie_range_info.h @@ -30,6 +30,8 @@ namespace Titanic { +class CGameObject; + class CMovieRangeInfo : public ListItem { public: int _fieldC; @@ -57,6 +59,11 @@ public: * Adds an event to the events list */ void add(CMovieEvent *movieEvent) { _events.push_back(movieEvent); } + + void process(CGameObject *owner); +}; + +class CMovieRangeInfoList : public List { }; } // End of namespace Titanic -- cgit v1.2.3 From a82bcd3ce7ef0ae604af45fdb56668fca47e7137 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 29 Jun 2016 19:29:32 -0400 Subject: TITANIC: Added CMovieRangeInfo methods --- engines/titanic/support/movie_range_info.cpp | 67 +++++++++++++++++++--------- engines/titanic/support/movie_range_info.h | 16 ++++--- 2 files changed, 55 insertions(+), 28 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie_range_info.cpp b/engines/titanic/support/movie_range_info.cpp index ff246fbe7b..ab34082540 100644 --- a/engines/titanic/support/movie_range_info.cpp +++ b/engines/titanic/support/movie_range_info.cpp @@ -21,19 +21,22 @@ */ #include "titanic/support/movie_range_info.h" +#include "titanic/support/movie_clip.h" +#include "titanic/core/game_object.h" namespace Titanic { -CMovieRangeInfo::CMovieRangeInfo() : ListItem(), _fieldC(0), - _field10(0), _field14(0), _field18(0), _field1C(0) { +CMovieRangeInfo::CMovieRangeInfo() : ListItem(), _startFrame(0), _endFrame(0) { +} + +CMovieRangeInfo::~CMovieRangeInfo() { + _events.destroyContents(); } CMovieRangeInfo::CMovieRangeInfo(const CMovieRangeInfo *src) : ListItem() { - _fieldC = src->_fieldC; - _field10 = src->_field10; - _field14 = src->_field14; - _field18 = src->_field18; - _field1C = src->_field1C; + _movieName = src->_movieName; + _startFrame = src->_startFrame; + _endFrame = src->_endFrame; // Duplicate the events list for (CMovieEventList::const_iterator i = _events.begin(); @@ -44,38 +47,60 @@ CMovieRangeInfo::CMovieRangeInfo(const CMovieRangeInfo *src) : ListItem() { void CMovieRangeInfo::save(SimpleFile *file, int indent) const { file->writeNumberLine(0, indent); - file->writeNumberLine(_fieldC, indent + 1); - file->writeNumberLine(_field10, indent + 1); - file->writeNumberLine(_field14, indent + 1); - file->writeNumberLine(_field1C, indent + 1); - file->writeNumberLine(_field18, indent + 1); + file->writeQuotedLine(_movieName, indent + 1); + file->writeNumberLine(_endFrame, indent + 1); + file->writeNumberLine(_startFrame, indent + 1); _events.save(file, indent + 1); } void CMovieRangeInfo::load(SimpleFile *file) { int val = file->readNumber(); if (!val) { - _fieldC = file->readNumber(); - _field10 = file->readNumber(); - _field14 = file->readNumber(); - _field1C = file->readNumber(); - _field18 = file->readNumber(); + _movieName = file->readString(); + _endFrame = file->readNumber(); + _startFrame = file->readNumber(); _events.load(file); } } +void CMovieRangeInfo::get1(CMovieEventList &list) { + for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) { + CMovieEvent *movieEvent = *i; + if (movieEvent->_fieldC == 1) + list.push_back(new CMovieEvent(movieEvent)); + } +} + +void CMovieRangeInfo::get2(CMovieEventList &list, int val) { + for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) { + CMovieEvent *movieEvent = *i; + if (movieEvent->_fieldC == 2 && movieEvent->_field1C == val) + list.push_back(new CMovieEvent(movieEvent)); + } +} + void CMovieRangeInfo::process(CGameObject *owner) { -/* int flags = 0; if (_endFrame) flags |= CLIPFLAG_HAS_END_FRAME; if (_startFrame) flags |= CLIPFLAG_HAS_START_FRAME; + + for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) { + CMovieEvent *movieEvent = *i; + if (!movieEvent->_fieldC) { + flags |= CLIPFLAG_PLAY; + break; + } + } - warning("TODO: CMovieClip::process"); + owner->checkPlayMovie(_movieName, flags); - owner->checkPlayMovie(_name, flags); - */ + for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) { + CMovieEvent *movieEvent = *i; + if (!movieEvent->_fieldC) + owner->surface38(movieEvent->_field1C); + } } } // End of namespace Titanic diff --git a/engines/titanic/support/movie_range_info.h b/engines/titanic/support/movie_range_info.h index 2c7d86f3c5..3f077c717e 100644 --- a/engines/titanic/support/movie_range_info.h +++ b/engines/titanic/support/movie_range_info.h @@ -34,16 +34,14 @@ class CGameObject; class CMovieRangeInfo : public ListItem { public: - int _fieldC; - int _field10; - int _field14; - int _field18; - int _field1C; + CString _movieName; + uint _startFrame; + uint _endFrame; CMovieEventList _events; public: CMovieRangeInfo(); CMovieRangeInfo(const CMovieRangeInfo *src); - virtual ~CMovieRangeInfo() {} + virtual ~CMovieRangeInfo(); /** * Save the data for the class to file @@ -58,7 +56,11 @@ public: /** * Adds an event to the events list */ - void add(CMovieEvent *movieEvent) { _events.push_back(movieEvent); } + void addEvent(CMovieEvent *movieEvent) { _events.push_back(movieEvent); } + + void get1(CMovieEventList &list); + + void get2(CMovieEventList &list, int val); void process(CGameObject *owner); }; -- cgit v1.2.3 From 5ccc0a66da38d23520234e7060efaf966d3345b9 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 29 Jun 2016 19:53:16 -0400 Subject: TITANIC: Removed const modifier from all saveable objects Turns out that CGameObject::save regenerates the _movieRangeInfo list. So the const suffix can no longer be used for the entire hierarchy --- engines/titanic/support/movie_clip.cpp | 2 +- engines/titanic/support/movie_clip.h | 2 +- engines/titanic/support/movie_event.cpp | 2 +- engines/titanic/support/movie_event.h | 2 +- engines/titanic/support/movie_range_info.cpp | 2 +- engines/titanic/support/movie_range_info.h | 2 +- engines/titanic/support/time_event_info.cpp | 2 +- engines/titanic/support/time_event_info.h | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie_clip.cpp b/engines/titanic/support/movie_clip.cpp index da655ce76a..2d3187b000 100644 --- a/engines/titanic/support/movie_clip.cpp +++ b/engines/titanic/support/movie_clip.cpp @@ -32,7 +32,7 @@ CMovieClip::CMovieClip(const CString &name, int startFrame, int endFrame): ListItem(), _name(name), _startFrame(startFrame), _endFrame(endFrame) { } -void CMovieClip::save(SimpleFile *file, int indent) const { +void CMovieClip::save(SimpleFile *file, int indent) { file->writeNumberLine(2, indent); file->writeQuotedLine("Clip", indent); file->writeQuotedLine(_name, indent); diff --git a/engines/titanic/support/movie_clip.h b/engines/titanic/support/movie_clip.h index 0b1106f420..813996bbf0 100644 --- a/engines/titanic/support/movie_clip.h +++ b/engines/titanic/support/movie_clip.h @@ -56,7 +56,7 @@ public: /** * Save the data for the class to file */ - virtual void save(SimpleFile *file, int indent) const; + virtual void save(SimpleFile *file, int indent); /** * Load the data for the class from file diff --git a/engines/titanic/support/movie_event.cpp b/engines/titanic/support/movie_event.cpp index b3e788e6fc..870a06fe6f 100644 --- a/engines/titanic/support/movie_event.cpp +++ b/engines/titanic/support/movie_event.cpp @@ -36,7 +36,7 @@ CMovieEvent::CMovieEvent(const CMovieEvent *src) { _field1C = src->_field1C; } -void CMovieEvent::save(SimpleFile *file, int indent) const { +void CMovieEvent::save(SimpleFile *file, int indent) { file->writeNumberLine(0, indent); file->writeNumberLine(_fieldC, indent + 1); file->writeNumberLine(_field10, indent + 1); diff --git a/engines/titanic/support/movie_event.h b/engines/titanic/support/movie_event.h index 5c62220919..ed72e2d349 100644 --- a/engines/titanic/support/movie_event.h +++ b/engines/titanic/support/movie_event.h @@ -42,7 +42,7 @@ public: /** * Save the data for the class to file */ - virtual void save(SimpleFile *file, int indent) const; + virtual void save(SimpleFile *file, int indent); /** * Load the data for the class from file diff --git a/engines/titanic/support/movie_range_info.cpp b/engines/titanic/support/movie_range_info.cpp index ab34082540..d48bab1df6 100644 --- a/engines/titanic/support/movie_range_info.cpp +++ b/engines/titanic/support/movie_range_info.cpp @@ -45,7 +45,7 @@ CMovieRangeInfo::CMovieRangeInfo(const CMovieRangeInfo *src) : ListItem() { } } -void CMovieRangeInfo::save(SimpleFile *file, int indent) const { +void CMovieRangeInfo::save(SimpleFile *file, int indent) { file->writeNumberLine(0, indent); file->writeQuotedLine(_movieName, indent + 1); file->writeNumberLine(_endFrame, indent + 1); diff --git a/engines/titanic/support/movie_range_info.h b/engines/titanic/support/movie_range_info.h index 3f077c717e..2776ac2851 100644 --- a/engines/titanic/support/movie_range_info.h +++ b/engines/titanic/support/movie_range_info.h @@ -46,7 +46,7 @@ public: /** * Save the data for the class to file */ - virtual void save(SimpleFile *file, int indent) const; + virtual void save(SimpleFile *file, int indent); /** * Load the data for the class from file diff --git a/engines/titanic/support/time_event_info.cpp b/engines/titanic/support/time_event_info.cpp index c3312de7d7..041a01ccfb 100644 --- a/engines/titanic/support/time_event_info.cpp +++ b/engines/titanic/support/time_event_info.cpp @@ -106,7 +106,7 @@ CTimeEventInfo::CTimeEventInfo(uint ticks, uint f14, uint firstDuration, _id = _nextId++; } -void CTimeEventInfo::save(SimpleFile *file, int indent) const { +void CTimeEventInfo::save(SimpleFile *file, int indent) { file->writeNumberLine(0, indent); CString targetName; diff --git a/engines/titanic/support/time_event_info.h b/engines/titanic/support/time_event_info.h index ee923f5fcb..b436f87f65 100644 --- a/engines/titanic/support/time_event_info.h +++ b/engines/titanic/support/time_event_info.h @@ -72,7 +72,7 @@ public: /** * Save the data for the class to file */ - virtual void save(SimpleFile *file, int indent) const; + virtual void save(SimpleFile *file, int indent); /** * Load the data for the class from file -- cgit v1.2.3 From 8ea5d533294193a4d220316152cec59580bbf10c Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 29 Jun 2016 22:05:06 -0400 Subject: TITANIC: Added CGameObject saving, and movie range info methods --- engines/titanic/support/movie.cpp | 7 ++++--- engines/titanic/support/movie.h | 20 ++++++++++++++++---- engines/titanic/support/movie_clip.cpp | 2 ++ engines/titanic/support/movie_range_info.cpp | 14 ++++++++++---- engines/titanic/support/movie_range_info.h | 4 +++- engines/titanic/support/video_surface.cpp | 8 ++++++-- engines/titanic/support/video_surface.h | 15 +++++++++++++-- 7 files changed, 54 insertions(+), 16 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 27bcb97ae9..361bf6e1fa 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -99,7 +99,7 @@ void OSMovie::proc11() { warning("TODO: OSMovie::proc11"); } -void OSMovie::proc12(const CString &name, int flags, CGameObject *obj) { +void OSMovie::proc12(int v1, int v2, int frameNumber, int flags, CGameObject *obj) { warning("TODO: OSMovie::proc12"); } @@ -121,8 +121,9 @@ void OSMovie::proc16() { warning("TODO: OSMovie::proc16"); } -void OSMovie::proc17() { - warning("TODO: OSMovie::proc17"); +const Common::List OSMovie::getMovieRangeInfo() const { + warning("TODO: OSMovie::getMovieRangeInfo"); + return Common::List(); } void OSMovie::proc18() { diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index da3285547d..2d7bdc9c6d 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -23,9 +23,11 @@ #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/movie_range_info.h" namespace Titanic { @@ -72,7 +74,7 @@ public: virtual void playClip(const Rect &rect, uint startFrame, uint endFrame) = 0; virtual void proc11() = 0; - virtual void proc12(const CString &name, int flags, CGameObject *obj) = 0; + virtual void proc12(int v1, int v2, int frameNumber, int flags, CGameObject *obj) = 0; /** * Stops the movie @@ -82,7 +84,12 @@ public: virtual void proc14() = 0; virtual void setFrame(uint frameNumber) = 0; virtual void proc16() = 0; - virtual void proc17() = 0; + + /** + * Return any movie range info associated with the movie + */ + virtual const Common::List getMovieRangeInfo() const = 0; + virtual void proc18() = 0; /** @@ -139,7 +146,7 @@ public: virtual void playClip(const Rect &rect, uint startFrame, uint endFrame); virtual void proc11(); - virtual void proc12(const CString &name, int flags, CGameObject *obj); + virtual void proc12(int v1, int v2, int frameNumber, int flags, CGameObject *obj); /** * Stops the movie @@ -154,7 +161,12 @@ public: virtual void setFrame(uint frameNumber); virtual void proc16(); - virtual void proc17(); + + /** + * Return any movie range info associated with the movie + */ + virtual const Common::List getMovieRangeInfo() const; + virtual void proc18(); /** diff --git a/engines/titanic/support/movie_clip.cpp b/engines/titanic/support/movie_clip.cpp index 2d3187b000..1f2ef66428 100644 --- a/engines/titanic/support/movie_clip.cpp +++ b/engines/titanic/support/movie_clip.cpp @@ -65,6 +65,8 @@ void CMovieClip::load(SimpleFile *file) { ListItem::load(file); } +/*------------------------------------------------------------------------*/ + CMovieClip *CMovieClipList::findByName(const Common::String &name) const { for (const_iterator i = begin(); i != end(); ++i) { CMovieClip *clip = *i; diff --git a/engines/titanic/support/movie_range_info.cpp b/engines/titanic/support/movie_range_info.cpp index d48bab1df6..e6b28ce4e8 100644 --- a/engines/titanic/support/movie_range_info.cpp +++ b/engines/titanic/support/movie_range_info.cpp @@ -34,7 +34,9 @@ CMovieRangeInfo::~CMovieRangeInfo() { } CMovieRangeInfo::CMovieRangeInfo(const CMovieRangeInfo *src) : ListItem() { - _movieName = src->_movieName; + _fieldC = src->_fieldC; + _field10 = src->_field10; + _frameNumber = src->_frameNumber; _startFrame = src->_startFrame; _endFrame = src->_endFrame; @@ -47,7 +49,9 @@ CMovieRangeInfo::CMovieRangeInfo(const CMovieRangeInfo *src) : ListItem() { void CMovieRangeInfo::save(SimpleFile *file, int indent) { file->writeNumberLine(0, indent); - file->writeQuotedLine(_movieName, indent + 1); + file->writeNumberLine(_fieldC, indent + 1); + file->writeNumberLine(_field10, indent + 1); + file->writeNumberLine(_frameNumber, indent + 1); file->writeNumberLine(_endFrame, indent + 1); file->writeNumberLine(_startFrame, indent + 1); _events.save(file, indent + 1); @@ -56,7 +60,9 @@ void CMovieRangeInfo::save(SimpleFile *file, int indent) { void CMovieRangeInfo::load(SimpleFile *file) { int val = file->readNumber(); if (!val) { - _movieName = file->readString(); + _fieldC = file->readNumber(); + _field10 = file->readNumber(); + _frameNumber = file->readNumber(); _endFrame = file->readNumber(); _startFrame = file->readNumber(); _events.load(file); @@ -94,7 +100,7 @@ void CMovieRangeInfo::process(CGameObject *owner) { } } - owner->checkPlayMovie(_movieName, flags); + owner->checkPlayMovie(_fieldC, _field10, _frameNumber, flags); for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) { CMovieEvent *movieEvent = *i; diff --git a/engines/titanic/support/movie_range_info.h b/engines/titanic/support/movie_range_info.h index 2776ac2851..be04975cbf 100644 --- a/engines/titanic/support/movie_range_info.h +++ b/engines/titanic/support/movie_range_info.h @@ -34,7 +34,9 @@ class CGameObject; class CMovieRangeInfo : public ListItem { public: - CString _movieName; + int _fieldC; + int _field10; + int _frameNumber; uint _startFrame; uint _endFrame; CMovieEventList _events; diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index c1af869e1e..9293b03f02 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -402,9 +402,9 @@ void OSVideoSurface::playMovie(uint startFrame, uint endFrame, int v3, bool v4) } } -void OSVideoSurface::proc35(const CString &name, int flags, CGameObject *owner) { +void OSVideoSurface::proc35(int v1, int v2, int frameNumber, int flags, CGameObject *owner) { if (loadIfReady() && _movie) { - _movie->proc12(name, flags, owner); + _movie->proc12(v1, v2, frameNumber, flags, owner); } } @@ -426,6 +426,10 @@ void OSVideoSurface::proc39(int v1, int v2) { warning("OSVideoSurface::proc39"); } +const Common::List OSVideoSurface::getMovieRangeInfo() const { + return _movie ? _movie->getMovieRangeInfo() : Common::List(); +} + bool OSVideoSurface::loadIfReady() { _videoSurfaceNum = _videoSurfaceCounter; diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index 2b66b269e7..e5d904f6d6 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -28,6 +28,7 @@ #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/core/list.h" #include "titanic/core/resource_key.h" @@ -166,7 +167,7 @@ public: */ virtual void playMovie(uint startFrame, uint endFrame, int v3, bool v4) = 0; - virtual void proc35(const CString &name, int flags, CGameObject *owner) = 0; + virtual void proc35(int v1, int v2, int frameNumber, int flags, CGameObject *owner) = 0; /** * Stops any movie currently attached to the surface @@ -182,6 +183,11 @@ public: virtual void proc39(int v1, int v2) = 0; + /** + * Return any movie range info associated with the surface's movie + */ + virtual const Common::List getMovieRangeInfo() const = 0; + /** * Loads the surface's resource if there's one pending */ @@ -335,7 +341,7 @@ public: */ virtual void playMovie(uint startFrame, uint endFrame, int v3, bool v4); - virtual void proc35(const CString &name, int flags, CGameObject *owner); + virtual void proc35(int v1, int v2, int frameNumber, int flags, CGameObject *owner); /** * Stops any movie currently attached to the surface @@ -351,6 +357,11 @@ public: virtual void proc39(int v1, int v2); + /** + * Return any movie range info associated with the surface's movie + */ + virtual const Common::List getMovieRangeInfo() const; + /** * Loads the surface's resource if there's one pending */ -- cgit v1.2.3 From d9e05e215c1ba8ab93530e7263b527c03fcc61c8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 3 Jul 2016 12:48:05 -0400 Subject: TITANIC: Fleshing out screen manager --- engines/titanic/support/screen_manager.cpp | 35 +++++++---- engines/titanic/support/screen_manager.h | 95 +++++++++++++++++++++++++----- 2 files changed, 106 insertions(+), 24 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/screen_manager.cpp b/engines/titanic/support/screen_manager.cpp index 27c0d9886e..d795f78764 100644 --- a/engines/titanic/support/screen_manager.cpp +++ b/engines/titanic/support/screen_manager.cpp @@ -130,8 +130,15 @@ DirectDrawSurface *OSScreenManager::getDDSurface(SurfaceNum surfaceNum) { return nullptr; } -void OSScreenManager::proc6() {} -void OSScreenManager::proc7() {} +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) @@ -233,7 +240,11 @@ int OSScreenManager::writeString(int surfaceNum, const Rect &destRect, yOffset, str, textCursor); } -void OSScreenManager::proc14() {} +int OSScreenManager::writeString(int surfaceNum, const Rect &srcRect, + const Rect &destRect, const CString &str, CTextCursor *textCursor) { + // TODO + return 0; +} void OSScreenManager::setFontColor(byte r, byte g, byte b) { _fonts[_fontNumber].setColor(r, g, b); @@ -251,7 +262,15 @@ int OSScreenManager::stringWidth(const CString &str) { return _fonts[_fontNumber].stringWidth(str); } -void OSScreenManager::proc19() {} +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) @@ -274,16 +293,12 @@ CVideoSurface *OSScreenManager::createSurface(const CResourceKey &key) { return new OSVideoSurface(this, key); } -void OSScreenManager::proc23() {} -void OSScreenManager::proc24() {} -void OSScreenManager::proc25() {} - void OSScreenManager::showCursor() { - + CScreenManager::_screenManagerPtr->_mouseCursor->show(); } void OSScreenManager::hideCursor() { - + CScreenManager::_screenManagerPtr->_mouseCursor->hide(); } void OSScreenManager::destroyFrontAndBackBuffers() { diff --git a/engines/titanic/support/screen_manager.h b/engines/titanic/support/screen_manager.h index 21b40cad37..0736f1393c 100644 --- a/engines/titanic/support/screen_manager.h +++ b/engines/titanic/support/screen_manager.h @@ -89,8 +89,19 @@ public: */ virtual void drawCursors() = 0; - virtual void proc6() = 0; - virtual void proc7() = 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; /** @@ -126,7 +137,16 @@ public: virtual int writeString(int surfaceNum, const Rect &destRect, int yOffset, const CString &str, CTextCursor *textCursor) = 0; - virtual void proc14() = 0; + /** + * Write a string + * @param surfaceNum Destination surface + * @param srcRect Drawing area + * @param destRect Bounds of dest surface + * @param str Line or lines to write + * @param textCursor Optional text cursor pointer + */ + virtual int writeString(int surfaceNum, const Rect &srcRect, + const Rect &destRect, const CString &str, CTextCursor *textCursor) = 0; /** * Set the font color @@ -152,7 +172,10 @@ public: */ virtual int stringWidth(const CString &str) = 0; - virtual void proc19() = 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 @@ -173,10 +196,27 @@ public: * Creates a surface from a specified resource */ virtual CVideoSurface *createSurface(const CResourceKey &key) = 0; - - virtual void proc24() = 0; - virtual void proc25() = 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; /** @@ -228,8 +268,19 @@ public: */ virtual void drawCursors(); - virtual void proc6(); - virtual void proc7(); + /** + * Locks a specified surface number for access and returns a pointer to it + */ + virtual CVideoSurface *lockSurface(SurfaceNum surfaceNum); + + /** + * Unlocks a previously locked surface + */ + virtual void unlockSurface(CVideoSurface *surface); + + /** + * Gets a specified surface number + */ virtual CVideoSurface *getSurface(SurfaceNum surfaceNum) const; /** @@ -268,7 +319,16 @@ public: virtual int writeString(int surfaceNum, const Rect &destRect, int yOffset, const CString &str, CTextCursor *textCursor); - virtual void proc14(); + /** + * Write a string + * @param surfaceNum Destination surface + * @param srcRect Drawing area + * @param destRect Bounds of dest surface + * @param str Line or lines to write + * @param textCursor Optional text cursor pointer + */ + virtual int writeString(int surfaceNum, const Rect &srcRect, + const Rect &destRect, const CString &str, CTextCursor *textCursor); /** * Set the font color @@ -294,7 +354,10 @@ public: */ virtual int stringWidth(const CString &str); - virtual void proc19(); + /** + * Draws a frame enclosing the specified area + */ + virtual void frameRect(SurfaceNum surfaceNum, const Rect &rect, byte r, byte g, byte b); /** * Clear a portion of the screen surface @@ -316,10 +379,14 @@ public: */ virtual CVideoSurface *createSurface(const CResourceKey &key); - virtual void proc23(); - virtual void proc24(); - virtual void proc25(); + /** + * Show the mouse cursor + */ virtual void showCursor(); + + /** + * Hide the mouse cursor + */ virtual void hideCursor(); }; -- cgit v1.2.3 From 5ab33f117a0bc3451a1d30024208c45a2a548a4b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 3 Jul 2016 13:52:09 -0400 Subject: TITANIC: Adding more video surface methods --- engines/titanic/support/image_decoders.cpp | 4 +- engines/titanic/support/movie.cpp | 2 +- engines/titanic/support/video_surface.cpp | 36 +++++++++++++++++- engines/titanic/support/video_surface.h | 59 ++++++++++++++++++++++++++++-- 4 files changed, 92 insertions(+), 9 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/image_decoders.cpp b/engines/titanic/support/image_decoders.cpp index 9fe55eb02b..4203dad97c 100644 --- a/engines/titanic/support/image_decoders.cpp +++ b/engines/titanic/support/image_decoders.cpp @@ -36,7 +36,7 @@ void CJPEGDecode::decode(OSVideoSurface &surface, const CString &name) { // Resize the surface if necessary if (!surface.hasSurface() || surface.getWidth() != srcSurf->w || surface.getHeight() != srcSurf->h) - surface.resize(srcSurf->w, srcSurf->h); + surface.recreate(srcSurf->w, srcSurf->h); // Convert the decoded surface to the correct pixel format, and then copy it over surface.lock(); @@ -63,7 +63,7 @@ void CTargaDecode::decode(OSVideoSurface &surface, const CString &name) { // Resize the surface if necessary if (!surface.hasSurface() || surface.getWidth() != srcSurf->w || surface.getHeight() != srcSurf->h) - surface.resize(srcSurf->w, srcSurf->h); + surface.recreate(srcSurf->w, srcSurf->h); // Convert the decoded surface to the correct pixel format, and then copy it over surface.lock(); diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 361bf6e1fa..9b6fd01710 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -175,7 +175,7 @@ void OSMovie::decodeFrame() { // If the video surface doesn't yet have an underlying surface, create it if (!videoSurface->hasSurface()) - videoSurface->resize(frame->w, frame->h); + videoSurface->recreate(frame->w, frame->h); // Lock access to the surface videoSurface->lock(); diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index 9293b03f02..e71b25184b 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -296,7 +296,14 @@ int OSVideoSurface::getPitch() { return _ddSurface->getPitch(); } -void OSVideoSurface::resize(int width, int height) { +int OSVideoSurface::getBpp() { + if (!loadIfReady()) + error("Could not load resource"); + + return getPixelDepth(); +} + +void OSVideoSurface::recreate(int width, int height) { freeSurface(); _screenManager->resizeSurface(this, width, height); @@ -304,9 +311,19 @@ void OSVideoSurface::resize(int width, int height) { _videoSurfaceCounter += _ddSurface->getSize(); } +void OSVideoSurface::resize(int width, int height) { + if (!_ddSurface || _ddSurface->getWidth() != width || + _ddSurface->getHeight() != height) + recreate(width, height); +} + +void OSVideoSurface::detachSurface() { + _ddSurface = nullptr; +} + int OSVideoSurface::getPixelDepth() { if (!loadIfReady()) - assert(0); + error("Could not load resource"); lock(); @@ -360,6 +377,13 @@ uint16 OSVideoSurface::getPixel(const Common::Point &pt) { } } +void OSVideoSurface::setPixel(const Point &pt, uint pixel) { + assert(getPixelDepth() == 2); + + uint16 *pixelP = (uint16 *)_rawSurface->getBasePtr(pt.x, pt.y); + *pixelP = pixel; +} + void OSVideoSurface::changePixel(uint16 *pixelP, uint16 *color, byte srcVal, bool remapFlag) { assert(getPixelDepth() == 2); const Graphics::PixelFormat &destFormat = _ddSurface->getFormat(); @@ -391,9 +415,17 @@ void OSVideoSurface::shiftColors() { // we already convert 16-bit surfaces as soon as they're loaded } +void OSVideoSurface::clear() { + if (!loadIfReady()) + error("Could not load resource"); + +} + void OSVideoSurface::playMovie(uint flags, CVideoSurface *surface) { if (loadIfReady() && _movie) _movie->play(flags, surface); + + _ddSurface->fill(nullptr, 0); } void OSVideoSurface::playMovie(uint startFrame, uint endFrame, int v3, bool v4) { diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index e5d904f6d6..9b7e0fbaec 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -129,12 +129,27 @@ public: * Returns the pitch of the surface in bytes */ virtual int getPitch() = 0; - + + /** + * Returns the bytes per pixel of the surface + */ + virtual int getBpp() = 0; + /** - * Reiszes the surface + * Recreates the surface + */ + virtual void recreate(int width, int height) = 0; + + /** + * Resizes the surface */ virtual void resize(int width, int height) = 0; + /** + * Detachs the underlying raw surface + */ + virtual void detachSurface() = 0; + /** * Returns the number of bytes per pixel in the surface */ @@ -145,6 +160,12 @@ public: */ 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; + /** * Change a pixel */ @@ -155,6 +176,11 @@ public: */ 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 @@ -305,10 +331,25 @@ public: virtual int getPitch(); /** - * Reiszes the surface + * Returns the bytes per pixel of the surface + */ + virtual int getBpp(); + + /** + * Recreates the surface with the designated size + */ + virtual void recreate(int width, int height); + + /** + * Resizes the surface */ virtual void resize(int width, int height); + /** + * Detachs the underlying raw surface + */ + virtual void detachSurface(); + /** * Returns the number of bytes per pixel in the surface */ @@ -317,7 +358,12 @@ public: /** * Gets the pixel at the specified position within the surface */ - virtual uint16 getPixel(const Common::Point &pt); + virtual uint16 getPixel(const Point &pt); + + /** + * Sets a pixel at a specified position within the surface + */ + virtual void setPixel(const Point &pt, uint pixel); /** * Change a pixel @@ -329,6 +375,11 @@ public: */ virtual void shiftColors(); + /** + * Clears the entire surface to black + */ + virtual void clear(); + /** * Plays a movie, loading it from the specified _resource * if not already loaded -- cgit v1.2.3 From 3f12927b77735c17eedfbe14f36607ddc6580c83 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 3 Jul 2016 14:22:33 -0400 Subject: TITANIC: Added CVideoSurface transPixelate --- engines/titanic/support/video_surface.cpp | 28 ++++++++++++++++++++++++++++ engines/titanic/support/video_surface.h | 12 ++++++++++++ 2 files changed, 40 insertions(+) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index e71b25184b..85a1aa1c58 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -476,6 +476,34 @@ bool OSVideoSurface::loadIfReady() { } } +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(); +} + int OSVideoSurface::freeSurface() { if (!_ddSurface) return 0; diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index 9b7e0fbaec..45c6182fe6 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -224,6 +224,12 @@ public: */ virtual bool load() = 0; + /** + * Does a replacement of transparent pixels on certain lines at regular + * intervals. This is totally weird + */ + virtual void transPixelate() = 0; + virtual bool proc45(); /** @@ -423,6 +429,12 @@ public: */ virtual bool load(); + /** + * Does a replacement of transparent pixels on certain lines at regular + * intervals. This is totally weird + */ + virtual void transPixelate(); + /** * Frees the underlying surface */ -- cgit v1.2.3 From fb06cb4dde4d612289ea1b5830f8cd1c9e1bedfc Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 3 Jul 2016 17:43:37 -0400 Subject: TITANIC: Added CMovieManager class --- engines/titanic/support/movie.cpp | 31 +++++++++++++++--- engines/titanic/support/movie.h | 26 +++++++++++++-- engines/titanic/support/movie_manager.cpp | 35 ++++++++++++++++++++ engines/titanic/support/movie_manager.h | 53 +++++++++++++++++++++++++++++++ engines/titanic/support/video_surface.cpp | 8 ++++- engines/titanic/support/video_surface.h | 10 ++++++ 6 files changed, 155 insertions(+), 8 deletions(-) create mode 100644 engines/titanic/support/movie_manager.cpp create mode 100644 engines/titanic/support/movie_manager.h (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 9b6fd01710..869a3518f8 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -26,16 +26,35 @@ namespace Titanic { +CMovieList *CMovie::_activeMovies; + CMovie::CMovie() : ListItem(), _state(MOVIE_STOPPED), _field10(0), _field14(0) { } CMovie::~CMovie() { - g_vm->_activeMovies.remove(this); + removeFromActiveMovies(); +} + +void CMovie::init() { + _activeMovies = new CMovieList(); +} + +void CMovie::deinit() { + delete _activeMovies; +} + +void CMovie::addToActiveMovies() { + if (!isActive()) + _activeMovies->push_back(this); +} + +void CMovie::removeFromActiveMovies() { + _activeMovies->remove(this); } bool CMovie::isActive() const { - return g_vm->_activeMovies.contains(this); + return _activeMovies->contains(this); } bool CMovie::get10() { @@ -67,7 +86,6 @@ OSMovie::OSMovie(Common::SeekableReadStream *stream, CVideoSurface *surface) : } OSMovie::~OSMovie() { - g_vm->_activeMovies.remove(this); delete _video; } @@ -83,7 +101,7 @@ void OSMovie::play(uint startFrame, uint endFrame, int v3, bool v4) { _video->seekToFrame(startFrame); _endFrame = endFrame; - g_vm->_activeMovies.push_back(this); + addToActiveMovies(); _state = MOVIE_NONE; } @@ -126,7 +144,10 @@ const Common::List OSMovie::getMovieRangeInfo() const { return Common::List(); } -void OSMovie::proc18() { +void OSMovie::proc18(int v) { +// if (_aviSurface) +// _aviSurface->_field3C = 0; + warning("TODO: OSMovie::proc18"); } diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index 2d7bdc9c6d..fbbfebc845 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -47,8 +47,30 @@ class CMovie : public ListItem { protected: MovieState _state; int _field10; +protected: + /** + * Adds the movie to the active movies list + */ + void addToActiveMovies(); + + /** + * Removes the movie from the active movies list + */ + void removeFromActiveMovies(); public: int _field14; +public: + static CMovieList *_activeMovies; + + /** + * Initializes statics + */ + static void init(); + + /** + * Deinitializes statics + */ + static void deinit(); public: CMovie(); virtual ~CMovie(); @@ -90,7 +112,7 @@ public: */ virtual const Common::List getMovieRangeInfo() const = 0; - virtual void proc18() = 0; + virtual void proc18(int v) = 0; /** * Get the current movie frame @@ -167,7 +189,7 @@ public: */ virtual const Common::List getMovieRangeInfo() const; - virtual void proc18(); + virtual void proc18(int v); /** * Get the current movie frame diff --git a/engines/titanic/support/movie_manager.cpp b/engines/titanic/support/movie_manager.cpp new file mode 100644 index 0000000000..e3330f0080 --- /dev/null +++ b/engines/titanic/support/movie_manager.cpp @@ -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 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "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->proc18(_field4); + return movie; +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/movie_manager.h b/engines/titanic/support/movie_manager.h new file mode 100644 index 0000000000..91ea75e49b --- /dev/null +++ b/engines/titanic/support/movie_manager.h @@ -0,0 +1,53 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_MOVIE_MANAGER_H +#define TITANIC_MOVIE_MANAGER_H + +#include "titanic/core/list.h" +#include "titanic/core/resource_key.h" + +namespace Titanic { + +class CMovie; +class CVideoSurface; + +class CMovieManagerBase { +public: + virtual ~CMovieManagerBase() {} + + virtual CMovie *createMovie(const CResourceKey &key, CVideoSurface *surface) = 0; +}; + +class CMovieManager : public CMovieManagerBase { +private: + int _field4; +public: + CMovieManager() : CMovieManagerBase(), _field4(0) {} + virtual ~CMovieManager() {} + + virtual CMovie *createMovie(const CResourceKey &key, CVideoSurface *surface); +}; + +} // End of namespace Titanic + +#endif /* TITANIC_MOVIE_MANAGER_H */ diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index 85a1aa1c58..0335e7d9b1 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -23,6 +23,7 @@ #include "titanic/support/video_surface.h" #include "titanic/support/image_decoders.h" #include "titanic/support/screen_manager.h" +#include "titanic/titanic.h" namespace Titanic { @@ -234,6 +235,11 @@ void OSVideoSurface::loadJPEG(const CResourceKey &key) { _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) { @@ -242,7 +248,7 @@ void OSVideoSurface::loadMovie(const CResourceKey &key, bool destroyFlag) { } // Create the new movie and load the first frame to the video surface - _movie = new OSMovie(key, this); + _movie = g_vm->_movieManager.createMovie(key, this); _movie->setFrame(0); // If flagged to destroy, then immediately destroy movie instance diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index 45c6182fe6..37afccf9e1 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -93,6 +93,11 @@ public: */ 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 @@ -299,6 +304,11 @@ public: */ virtual void loadJPEG(const CResourceKey &key); + /** + * Loads a Targa image file specified by the given name + */ + virtual void loadTarga(const CString &name); + /** * Loads a movie file specified by the resource key. * @param key Resource key for movie to load -- cgit v1.2.3 From 8b2d85f8e5b30aeb73817894974a4db53588565b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 3 Jul 2016 19:07:38 -0400 Subject: TITANIC: Figured out remainder of CMovieManager --- engines/titanic/support/movie.cpp | 5 +++-- engines/titanic/support/movie.h | 15 +++++++++++---- engines/titanic/support/movie_manager.cpp | 2 +- engines/titanic/support/movie_manager.h | 16 ++++++++++++++-- 4 files changed, 29 insertions(+), 9 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 869a3518f8..6a79c02a3e 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -21,6 +21,7 @@ */ #include "video/avi_decoder.h" +#include "titanic/sound/sound_manager.h" #include "titanic/support/movie.h" #include "titanic/titanic.h" @@ -144,9 +145,9 @@ const Common::List OSMovie::getMovieRangeInfo() const { return Common::List(); } -void OSMovie::proc18(int v) { +void OSMovie::setSoundManager(CSoundManager *soundManager) { // if (_aviSurface) -// _aviSurface->_field3C = 0; +// _aviSurface->_field3C = soundManager; warning("TODO: OSMovie::proc18"); } diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index fbbfebc845..7abca6bbc0 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -35,9 +35,10 @@ enum MovieState { MOVIE_STOPPED = -1, MOVIE_NONE = 0, MOVIE_FINISHED = 1, MOVIE_FRAME = 2 }; -class CVideoSurface; -class CMovie; class CGameObject; +class CMovie; +class CSoundManager; +class CVideoSurface; class CMovieList : public List { public: @@ -112,7 +113,10 @@ public: */ virtual const Common::List getMovieRangeInfo() const = 0; - virtual void proc18(int v) = 0; + /** + * Set the sound manager reference + */ + virtual void setSoundManager(CSoundManager *soundManager) = 0; /** * Get the current movie frame @@ -189,7 +193,10 @@ public: */ virtual const Common::List getMovieRangeInfo() const; - virtual void proc18(int v); + /** + * Set the sound manager reference + */ + virtual void setSoundManager(CSoundManager *soundManager); /** * Get the current movie frame diff --git a/engines/titanic/support/movie_manager.cpp b/engines/titanic/support/movie_manager.cpp index e3330f0080..bfeb081b5c 100644 --- a/engines/titanic/support/movie_manager.cpp +++ b/engines/titanic/support/movie_manager.cpp @@ -28,7 +28,7 @@ namespace Titanic { CMovie *CMovieManager::createMovie(const CResourceKey &key, CVideoSurface *surface) { CMovie *movie = new OSMovie(key, surface); - movie->proc18(_field4); + movie->setSoundManager(_soundManager); return movie; } diff --git a/engines/titanic/support/movie_manager.h b/engines/titanic/support/movie_manager.h index 91ea75e49b..2920d909b7 100644 --- a/engines/titanic/support/movie_manager.h +++ b/engines/titanic/support/movie_manager.h @@ -25,6 +25,7 @@ #include "titanic/core/list.h" #include "titanic/core/resource_key.h" +#include "titanic/sound/sound_manager.h" namespace Titanic { @@ -35,17 +36,28 @@ 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: - int _field4; + CSoundManager *_soundManager; public: - CMovieManager() : CMovieManagerBase(), _field4(0) {} + CMovieManager() : CMovieManagerBase(), _soundManager(nullptr) {} virtual ~CMovieManager() {} + /** + * Create a new movie and return it + */ virtual CMovie *createMovie(const CResourceKey &key, CVideoSurface *surface); + + /** + * Sets the sound manager that will be attached to all created movies + */ + void setSoundManager(CSoundManager *soundManager) { _soundManager = soundManager; } }; } // End of namespace Titanic -- cgit v1.2.3 From 0b860220fc25d6ba78c7a403913d07561f492a6a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 4 Jul 2016 21:18:04 -0400 Subject: TITANIC: Beginnings of AVISurface class --- engines/titanic/support/avi_surface.cpp | 32 ++++++++++++++++++ engines/titanic/support/avi_surface.h | 57 +++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 engines/titanic/support/avi_surface.cpp create mode 100644 engines/titanic/support/avi_surface.h (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp new file mode 100644 index 0000000000..f6f63a7f1d --- /dev/null +++ b/engines/titanic/support/avi_surface.cpp @@ -0,0 +1,32 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "titanic/support/avi_surface.h" +#include "video/avi_decoder.h" + +namespace Titanic { + +AVISurface::AVISurface(const CResourceKey &key) { + // TODO +} + +} // End of namespace Titanic diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h new file mode 100644 index 0000000000..248f2c5ab3 --- /dev/null +++ b/engines/titanic/support/avi_surface.h @@ -0,0 +1,57 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TITANIC_AVI_SURFACE_H +#define TITANIC_AVI_SURFACE_H + +#include "video/video_decoder.h" +#include "titanic/core/resource_key.h" +#include "titanic/support/movie_range_info.h" + +namespace Titanic { + +class CSoundManager; + +class AVISurface { +private: + int _field4; + int _field8; + int _fieldC; + int _field10; + int _frame; + CMovieRangeInfoList _movieRangeInfo; + int _field28; + int _field2C; + int _field30; + int _field34; + int _field38; + CSoundManager *_soundManager; + // TODO: Lots more fields +public: + AVISurface(const CResourceKey &key); + + +}; + +} // End of namespace Titanic + +#endif /* TITANIC_AVI_SURFACE_H */ -- cgit v1.2.3 From cc9bf88ed56a4c5fbb14c05d30395b1688f5ebe7 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 Jul 2016 11:32:15 -0400 Subject: TITANIC: Major implementation of OSMovie and AVISurface classes --- engines/titanic/support/avi_surface.cpp | 185 ++++++++++++++++++++ engines/titanic/support/avi_surface.h | 110 ++++++++++-- engines/titanic/support/mouse_cursor.cpp | 12 +- engines/titanic/support/mouse_cursor.h | 2 +- engines/titanic/support/movie.cpp | 245 ++++++++++++++------------- engines/titanic/support/movie.h | 132 ++++++++------- engines/titanic/support/movie_event.cpp | 33 ++-- engines/titanic/support/movie_event.h | 18 +- engines/titanic/support/movie_range_info.cpp | 42 ++--- engines/titanic/support/movie_range_info.h | 20 ++- engines/titanic/support/video_surface.cpp | 23 +-- engines/titanic/support/video_surface.h | 58 +++++-- 12 files changed, 608 insertions(+), 272 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp index f6f63a7f1d..47127fe83b 100644 --- a/engines/titanic/support/avi_surface.cpp +++ b/engines/titanic/support/avi_surface.cpp @@ -21,12 +21,197 @@ */ #include "titanic/support/avi_surface.h" +#include "titanic/support/video_surface.h" #include "video/avi_decoder.h" namespace Titanic { AVISurface::AVISurface(const CResourceKey &key) { + // TODO +/* +Video::AVIDecoder *decoder = new Video::AVIDecoder(); +decoder->ignoreSecondaryVideoTracks(); +_video = decoder; +_field14 = 1; + +if (!_video->loadFile(name.getString())) +error("Could not open video - %s", name.getString().c_str()); +*/ +} + +AVISurface::~AVISurface() { + if (_videoSurface) + _videoSurface->_blitStyleFlag = false; + delete _frameInfo; +} + +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->_isFlag1 = flags & MOVIE_1; + + 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) { + changeFrame(initialFrame); + } else { + return true; + } +} + +void AVISurface::stop() { + _isPlaying = false; + _decoder->stop(); + _movieRangeInfo.destroyContents(); +} + +bool AVISurface::changeFrame(int frameNumber) { + if (_isPlaying) + return false; + + if (frameNumber == -1) + // Default to starting frame of first movie range + frameNumber = _movieRangeInfo.front()->_startFrame; + + seekToFrame(frameNumber); + renderFrame(); + + _isPlaying = true; + return true; +} + +void AVISurface::seekToFrame(uint frameNumber) { + _decoder->seekToFrame(frameNumber); + _priorFrame = frameNumber; +} + +bool AVISurface::handleEvents(CMovieEventList &events) { + if (!_isPlaying) + return true; + + CMovieRangeInfo *info = _movieRangeInfo.front(); + _currentPos += info->_isReversed ? -1 : 1; + if ((info->_isReversed && _currentPos < info->_endFrame) || + (!info->_isReversed && _currentPos > info->_endFrame)) { + if (info->_isFlag1) { + 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(); + _currentPos = info->_startFrame; + } + } else { + _currentPos = info->_startFrame; + } + } + + if (_isPlaying) { + // SInce movie ranges can change the position in the movie, + // ensure the decoder is kept in sync + seekToFrame(_currentPos); + + info->getMovieFrame(events, _currentPos); + return renderFrame(); + } else { + return false; + } +} + +void AVISurface::setVideoSurface(CVideoSurface *surface) { + _videoSurface = surface; + + warning("TODO: Get video track list from video decoder"); +} + +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 >= _decoder->getFrameCount()) + frameNumber = _decoder->getFrameCount() - 1; + + seekToFrame(frameNumber); + renderFrame(); +} + +int AVISurface::getFrame() const { + return _decoder->getCurFrame(); +} + +bool AVISurface::renderFrame() { + // Check there's a frame ready for + assert(_videoSurface); + if (!_decoder->needsUpdate()) + return false; + + // Get the frame to render, and draw it on the surface + const Graphics::Surface *frame = _decoder->decodeNextFrame(); + _videoSurface->blitFrom(Point(0, 0), frame); + return false; +} + +bool AVISurface::addEvent(int frameNumber, CGameObject *obj) { + if (!_movieRangeInfo.empty()) { + CMovieRangeInfo *tail = _movieRangeInfo.back(); + 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 == _priorFrame; + } + + return false; } } // End of namespace Titanic diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h index 248f2c5ab3..48c8169e78 100644 --- a/engines/titanic/support/avi_surface.h +++ b/engines/titanic/support/avi_surface.h @@ -23,33 +23,121 @@ #ifndef TITANIC_AVI_SURFACE_H #define TITANIC_AVI_SURFACE_H -#include "video/video_decoder.h" +#include "video/avi_decoder.h" #include "titanic/core/resource_key.h" #include "titanic/support/movie_range_info.h" namespace Titanic { class CSoundManager; +class CVideoSurface; + +enum MovieFlag { + MOVIE_1 = 1, MOVIE_STOP_PREVIOUS = 2, MOVIE_NO_OBJECT = 4, + MOVIE_REVERSE = 8, MOVIE_GAMESTATE = 0x10 +}; class AVISurface { private: + Video::AVIDecoder *_decoder; + CVideoSurface *_videoSurface; int _field4; int _field8; - int _fieldC; - int _field10; - int _frame; + int _currentPos; + int _priorFrame; CMovieRangeInfoList _movieRangeInfo; - int _field28; - int _field2C; - int _field30; - int _field34; - int _field38; + int _streamCount; + void *_frameInfo; +private: + /** + * Render a frame to the video surface + */ + bool renderFrame(); +protected: + /** + * Change the frame with ??? checking + */ + virtual bool changeFrame(int frameNumber); + + /** + * Seeks to a given frame number in the video + */ + virtual void seekToFrame(uint frameNumber); +public: CSoundManager *_soundManager; - // TODO: Lots more fields + bool _hasAudio; + bool _isPlaying; + double _frameRate; public: AVISurface(const CResourceKey &key); + ~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(); + + /** + * Handle any movie events relevent 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; + + /** + * Add a movie event + */ + bool addEvent(int frameNumber, CGameObject *obj); + + const void *getFrameInfo() const { + return _streamCount <= 1 ? nullptr : _frameInfo; + } + + /** + * Get a reference to the movie range info list + */ + const CMovieRangeInfoList *getMovieRangeInfo() const { + return &_movieRangeInfo; + } - }; } // End of namespace Titanic diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp index d87e7a499b..721088f086 100644 --- a/engines/titanic/support/mouse_cursor.cpp +++ b/engines/titanic/support/mouse_cursor.cpp @@ -91,15 +91,17 @@ void CMouseCursor::loadCursorImages() { // Create the surface CVideoSurface *surface = _screenManager->createSurface(64, 64); _cursors[idx]._videoSurface = surface; - +/* Common::SeekableReadStream *stream = new Common::MemoryReadStream( movieData, f.size(), DisposeAfterUse::NO); OSMovie movie(stream, surface); movie.setFrame(idx); - - _cursors[idx]._ptrUnknown = movie.proc21(); - surface->set40(_cursors[idx]._ptrUnknown); - } + + int frameNum = movie.proc21(); + _cursors[idx]._frameNumber = frameNum; + surface->setMovieFrame(frameNum); +*/ + } } void CMouseCursor::show() { diff --git a/engines/titanic/support/mouse_cursor.h b/engines/titanic/support/mouse_cursor.h index 55e0cb4da5..168a7be539 100644 --- a/engines/titanic/support/mouse_cursor.h +++ b/engines/titanic/support/mouse_cursor.h @@ -54,7 +54,7 @@ class CVideoSurface; class CMouseCursor { struct CursorEntry { CVideoSurface *_videoSurface; - void *_ptrUnknown; + int _frameNumber; Common::Point _centroid; }; private: diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 6a79c02a3e..338396ff96 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -20,42 +20,51 @@ * */ -#include "video/avi_decoder.h" -#include "titanic/sound/sound_manager.h" #include "titanic/support/movie.h" +#include "titanic/support/avi_surface.h" +#include "titanic/sound/sound_manager.h" +#include "titanic/messages/messages.h" #include "titanic/titanic.h" namespace Titanic { -CMovieList *CMovie::_activeMovies; +#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(), _state(MOVIE_STOPPED), _field10(0), +CMovie::CMovie() : ListItem(), _state(MSTATE_0), _field10(0), _field14(0) { } CMovie::~CMovie() { - removeFromActiveMovies(); + removeFromPlayingMovies(); } void CMovie::init() { - _activeMovies = new CMovieList(); + _playingMovies = new CMovieList(); + _movieSurface = nullptr; } void CMovie::deinit() { - delete _activeMovies; + delete _playingMovies; + delete _movieSurface; } -void CMovie::addToActiveMovies() { +void CMovie::addToPlayingMovies() { if (!isActive()) - _activeMovies->push_back(this); + _playingMovies->push_back(this); } -void CMovie::removeFromActiveMovies() { - _activeMovies->remove(this); +void CMovie::removeFromPlayingMovies() { + _playingMovies->remove(this); } bool CMovie::isActive() const { - return _activeMovies->contains(this); + return _playingMovies->contains(this); } bool CMovie::get10() { @@ -70,156 +79,148 @@ bool CMovie::get10() { /*------------------------------------------------------------------------*/ OSMovie::OSMovie(const CResourceKey &name, CVideoSurface *surface) : - _videoSurface(surface), _gameObject(nullptr), _endFrame(-1) { - Video::AVIDecoder *decoder = new Video::AVIDecoder(); - _video = decoder; - _field14 = 1; - - if (!_video->loadFile(name.getString())) - error("Could not open video - %s", name.getString().c_str()); -} + _aviSurface(name), _videoSurface(surface) { + _field18 = 0; + _field24 = 0; + _field28 = 0; + _field2C = 0; + _ticksStart = 0; + _frameTime1 = 0; + _frameTime2 = 17066; -OSMovie::OSMovie(Common::SeekableReadStream *stream, CVideoSurface *surface) : - _videoSurface(surface), _gameObject(nullptr), _endFrame(-1) { - _video = new Video::AVIDecoder(); - if (!_video->loadStream(stream)) - error("Could not parse movie stream"); + surface->resize(_aviSurface.getWidth(), _aviSurface.getHeight()); + _aviSurface.setVideoSurface(surface); } OSMovie::~OSMovie() { - delete _video; } -void OSMovie::play(uint flags, CVideoSurface *surface) { - uint endFrame = _video->getFrameCount(); - play(0, endFrame, 0, 0); -} +void OSMovie::play(uint flags, CGameObject *obj) { + _aviSurface.play(flags, obj); -void OSMovie::play(uint startFrame, uint endFrame, int v3, bool v4) { - warning("TODO: OSMovie::play properly"); + if (_aviSurface._isPlaying) + movieStarted(); +} - _video->start(); - _video->seekToFrame(startFrame); - _endFrame = endFrame; +void OSMovie::play(uint startFrame, uint endFrame, uint flags, CGameObject *obj) { + _aviSurface.play(startFrame, endFrame, flags, obj); - addToActiveMovies(); - _state = MOVIE_NONE; + if (_aviSurface._isPlaying) + movieStarted(); } -void OSMovie::play(const Rect &rect, int v1, int v2) { - warning("TODO: OSMovie::play 3"); -} +void OSMovie::play(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) { + _aviSurface.play(startFrame, endFrame, initialFrame, flags, obj); -void OSMovie::playClip(const Rect &rect, uint startFrame, uint endFrame) { - warning("TODO: OSMovie::playClip"); + if (_aviSurface._isPlaying) + movieStarted(); } -void OSMovie::proc11() { - warning("TODO: OSMovie::proc11"); -} +void OSMovie::playClip(const Point &drawPos, uint startFrame, uint endFrame) { + if (!_movieSurface) + _movieSurface = CScreenManager::_screenManagerPtr->createSurface(600, 340); + + bool widthLess = _videoSurface->getWidth() < 600; + bool heightLess = _videoSurface->getHeight() < 340; + Rect r(drawPos.x, drawPos.y, + drawPos.x + widthLess ? CLIP_WIDTH_REDUCED : CLIP_WIDTH, + drawPos.y + heightLess ? CLIP_HEIGHT_REDUCED : CLIP_HEIGHT + ); -void OSMovie::proc12(int v1, int v2, int frameNumber, int flags, CGameObject *obj) { - warning("TODO: OSMovie::proc12"); + uint timePerFrame = 1000 / _aviSurface._frameRate; + + for (; endFrame >= startFrame; ++startFrame) { + // Set the frame + _aviSurface.setFrame(startFrame); + + // TODO: See if we need to do anything further here. The original had a bunch + // of calls and using of the _movieSurface; perhaps to allow scaling down + // videos to half-size + if (widthLess || heightLess) + warning("Not properly reducing clip size: %d %d", r.width(), r.height()); + + // Wait for the next frame, unless the user interrupts the clip + if (g_vm->_events->waitForPress(timePerFrame)) + break; + } } void OSMovie::stop() { - _video->stop(); - _state = MOVIE_STOPPED; + _aviSurface.stop(); + removeFromPlayingMovies(); } -void OSMovie::proc14() { - warning("TODO: OSMovie::proc14"); +void OSMovie::addEvent(int frameNumber, CGameObject *obj) { + if (_aviSurface.addEvent(frameNumber, obj)) { + CMovieFrameMsg frameMsg(frameNumber, 0); + frameMsg.execute(obj); + } } void OSMovie::setFrame(uint frameNumber) { - _video->seekToFrame(frameNumber); - decodeFrame(); + _aviSurface.setFrame(frameNumber); + _videoSurface->setMovieFrame(frameNumber); } -void OSMovie::proc16() { - warning("TODO: OSMovie::proc16"); -} +bool OSMovie::handleEvents(CMovieEventList &events) { + if (!_aviSurface._isPlaying) + return false; -const Common::List OSMovie::getMovieRangeInfo() const { - warning("TODO: OSMovie::getMovieRangeInfo"); - return Common::List(); -} + int time = (g_vm->_events->getTicksCount() + ((_ticksStart << 24) - _ticksStart)) << 8; + if (time < _frameTime1) + return _aviSurface._isPlaying; -void OSMovie::setSoundManager(CSoundManager *soundManager) { -// if (_aviSurface) -// _aviSurface->_field3C = soundManager; + if (!_field14 && (time - _frameTime1) > (_frameTime2 * 2)) + _frameTime1 = time; - warning("TODO: OSMovie::proc18"); -} + _frameTime1 += _frameTime2; + _aviSurface.handleEvents(events); + _videoSurface->setMovieFrameInfo(_aviSurface.getFrameInfo()); -int OSMovie::getFrame() { - assert(_video); - return _video->getCurFrame(); -} + if (_field14) { + while (_frameTime1 >= time && events.empty()) { + _aviSurface.handleEvents(events); + _videoSurface->setMovieFrameInfo(_aviSurface.getFrameInfo()); -void OSMovie::proc20() { - warning("TODO: OSMovie::proc20"); -} - -void *OSMovie::proc21() { - warning("TODO: OSMovie::proc21"); - return nullptr; -} - -MovieState OSMovie::getState() { - if (!_video) - _state = MOVIE_STOPPED; - return _state; -} - -void OSMovie::update() { - if (_state != MOVIE_STOPPED) { - if (_video->isPlaying()) { - if (_video->getCurFrame() >= _endFrame) { - _video->stop(); - _state = MOVIE_FINISHED; - } else if (_video->needsUpdate()) { - decodeFrame(); - _state = MOVIE_FRAME; - } else { - _state = MOVIE_NONE; - } - } else { - _state = MOVIE_STOPPED; + _frameTime1 += _frameTime2; } } + + return _aviSurface._isPlaying; +} + +const CMovieRangeInfoList *OSMovie::getMovieRangeInfo() const { + return _aviSurface.getMovieRangeInfo(); } -void OSMovie::decodeFrame() { - const Graphics::Surface *frame = _video->decodeNextFrame(); - OSVideoSurface *videoSurface = static_cast(_videoSurface); - assert(videoSurface); +void OSMovie::setSoundManager(CSoundManager *soundManager) { + _aviSurface._soundManager = soundManager; +} - // If the video surface doesn't yet have an underlying surface, create it - if (!videoSurface->hasSurface()) - videoSurface->recreate(frame->w, frame->h); +int OSMovie::getFrame() const { + return _aviSurface.getFrame(); +} - // Lock access to the surface - videoSurface->lock(); - assert(videoSurface->_rawSurface); +void OSMovie::movieStarted() { + _frameTime1 = _frameTime2 = 256000.0 / _aviSurface._frameRate; + _ticksStart = g_vm->_events->getTicksCount(); - if (frame->format == videoSurface->_rawSurface->format) { - // Matching format, so we can copy straight from the video frame - videoSurface->_rawSurface->blitFrom(*frame); - } else { - // Different formats so we have to convert it first - Graphics::Surface *s = frame->convertTo(videoSurface->_rawSurface->format); - videoSurface->_rawSurface->blitFrom(*s); + if (_aviSurface._hasAudio) + _aviSurface._soundManager->movieStarted(); - s->free(); - delete s; - } + // Register the movie in the playing list + addToPlayingMovies(); + _field10 = 1; +} - // Unlock the surface - videoSurface->unlock(); +void OSMovie::proc20() { + // TODO +} - if (_gameObject) - _gameObject->makeDirty(); +int OSMovie::proc21() { + // TODO + return 0; } + } // End of namespace Titanic diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index 7abca6bbc0..c839c882ca 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -27,12 +27,13 @@ #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 { enum MovieState { - MOVIE_STOPPED = -1, MOVIE_NONE = 0, MOVIE_FINISHED = 1, MOVIE_FRAME = 2 + MSTATE_0 = 0, MSTATE_1 = 1 }; class CGameObject; @@ -46,22 +47,17 @@ public: class CMovie : public ListItem { protected: - MovieState _state; - int _field10; -protected: - /** - * Adds the movie to the active movies list - */ - void addToActiveMovies(); - /** - * Removes the movie from the active movies list + * Adds the movie to the list of currently playing movies */ - void removeFromActiveMovies(); + void addToPlayingMovies(); public: + MovieState _state; + int _field10; int _field14; public: - static CMovieList *_activeMovies; + static CMovieList *_playingMovies; + static CVideoSurface *_movieSurface; /** * Initializes statics @@ -77,41 +73,49 @@ public: virtual ~CMovie(); /** - * Plays the movie + * Starts playing the movie */ - virtual void play(uint flags, CVideoSurface *surface) = 0; + virtual void play(uint flags, CGameObject *obj) = 0; /** - * Plays the movie + * Starts playing the movie */ - virtual void play(uint startFrame, uint endFrame, int v3, bool v4) = 0; + virtual void play(uint startFrame, uint endFrame, uint flags, CGameObject *obj) = 0; /** - * Plays the movie + * Starts playing the movie */ - virtual void play(const Rect &rect, int v1, int v2) = 0; + virtual void play(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) = 0; /** * Plays a sub-section of a movie */ - virtual void playClip(const Rect &rect, uint startFrame, uint endFrame) = 0; + virtual void playClip(const Point &drawPos, uint startFrame, uint endFrame) = 0; - virtual void proc11() = 0; - virtual void proc12(int v1, int v2, int frameNumber, int flags, CGameObject *obj) = 0; - /** * Stops the movie */ virtual void stop() = 0; - virtual void proc14() = 0; + /** + * Add a playback event + */ + virtual void addEvent(int frameNumber, CGameObject *obj) = 0; + + /** + * Set the current frame number + */ virtual void setFrame(uint frameNumber) = 0; - virtual void proc16() = 0; + + /** + * Handle any pending movie events + */ + virtual bool handleEvents(CMovieEventList &events) = 0; /** * Return any movie range info associated with the movie */ - virtual const Common::List getMovieRangeInfo() const = 0; + virtual const CMovieRangeInfoList *getMovieRangeInfo() const = 0; /** * Set the sound manager reference @@ -121,94 +125,102 @@ public: /** * Get the current movie frame */ - virtual int getFrame() = 0; + virtual int getFrame() const = 0; virtual void proc20() = 0; - virtual void *proc21() = 0; + virtual int proc21() = 0; + + /** + * Removes the movie from the list of currently playing movies + */ + void removeFromPlayingMovies(); + /** + * Returns true if the movie is currently active + */ bool isActive() const; bool get10(); - - virtual MovieState getState() = 0; - virtual void update() = 0; }; class OSMovie : public CMovie { private: - Video::VideoDecoder *_video; + AVISurface _aviSurface; CVideoSurface *_videoSurface; - int _endFrame; - + int _field18; + int _field24; + int _field28; + int _field2C; + int _ticksStart; + int _frameTime1; + int _frameTime2; +private: /** - * Decodes the next frame + * Called when a movie is started playing */ - void decodeFrame(); -public: - CGameObject *_gameObject; + void movieStarted(); public: OSMovie(const CResourceKey &name, CVideoSurface *surface); - OSMovie(Common::SeekableReadStream *stream, CVideoSurface *surface); virtual ~OSMovie(); /** - * Plays the movie + * Starts playing the movie */ - virtual void play(uint flags, CVideoSurface *surface); + virtual void play(uint flags, CGameObject *obj); /** - * Plays the movie + * Starts playing the movie */ - virtual void play(uint startFrame, uint endFrame, int v3, bool v4); + virtual void play(uint startFrame, uint endFrame, uint flags, CGameObject *obj); /** - * Plays the movie + * Starts playing the movie */ - virtual void play(const Rect &rect, int v1, int v2); + virtual void play(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj); /** * Plays a sub-section of a movie */ - virtual void playClip(const Rect &rect, uint startFrame, uint endFrame); - - virtual void proc11(); - virtual void proc12(int v1, int v2, int frameNumber, int flags, CGameObject *obj); + virtual void playClip(const Point &drawPos, uint startFrame, uint endFrame); /** * Stops the movie */ virtual void stop(); - virtual void proc14(); + /** + * Add a playback event + */ + virtual void addEvent(int eventId, CGameObject *obj); /** * Set the current frame number */ virtual void setFrame(uint frameNumber); - virtual void proc16(); + /** + * Handle any pending movie events + */ + virtual bool handleEvents(CMovieEventList &events); /** - * Return any movie range info associated with the movie + * Get the current frame number */ - virtual const Common::List getMovieRangeInfo() const; + virtual int getFrame() const; /** - * Set the sound manager reference + * Return any movie range info associated with the movie */ - virtual void setSoundManager(CSoundManager *soundManager); + virtual const CMovieRangeInfoList *getMovieRangeInfo() const; /** - * Get the current movie frame + * Set the sound manager reference */ - virtual int getFrame(); + virtual void setSoundManager(CSoundManager *soundManager); virtual void proc20(); - virtual void *proc21(); - + virtual int proc21(); - virtual MovieState getState(); - virtual void update(); }; } // End of namespace Titanic diff --git a/engines/titanic/support/movie_event.cpp b/engines/titanic/support/movie_event.cpp index 870a06fe6f..5f8a6da019 100644 --- a/engines/titanic/support/movie_event.cpp +++ b/engines/titanic/support/movie_event.cpp @@ -21,27 +21,29 @@ */ #include "titanic/support/movie_event.h" +#include "titanic/core/game_object.h" namespace Titanic { -CMovieEvent::CMovieEvent() : ListItem(), _fieldC(0), _field10(0), - _field14(0), _field1C(0) { +CMovieEvent::CMovieEvent() : ListItem(), _type(MET_PLAY), _startFrame(0), + _endFrame(0), _initialFrame(0), _gameObject(nullptr) { } CMovieEvent::CMovieEvent(const CMovieEvent *src) { - _fieldC = src->_fieldC; - _field10 = src->_field10; - _field14 = src->_field14; - _field18 = src->_field18; - _field1C = src->_field1C; + _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(_fieldC, indent + 1); - file->writeNumberLine(_field10, indent + 1); - file->writeNumberLine(_field14, indent + 1); - file->writeNumberLine(_field1C, indent + 1); + 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); } @@ -49,10 +51,11 @@ void CMovieEvent::save(SimpleFile *file, int indent) { void CMovieEvent::load(SimpleFile *file) { int val = file->readNumber(); if (!val) { - _fieldC = file->readNumber(); - _field10 = file->readNumber(); - _field14 = file->readNumber(); - _field1C = file->readNumber(); + _startFrame = file->readNumber(); + _endFrame = file->readNumber(); + file->readNumber(); + error("FIXME: Original save/loaded object pointer"); + _initialFrame = file->readNumber(); } ListItem::load(file); diff --git a/engines/titanic/support/movie_event.h b/engines/titanic/support/movie_event.h index ed72e2d349..af93c76a31 100644 --- a/engines/titanic/support/movie_event.h +++ b/engines/titanic/support/movie_event.h @@ -27,13 +27,17 @@ namespace Titanic { +enum MovieEventType { MET_PLAY = 0, MET_MOVIE_END = 1, MET_FRAME = 2 }; + +class CGameObject; + class CMovieEvent : public ListItem { public: - int _fieldC; - int _field10; - int _field14; - int _field18; - int _field1C; + MovieEventType _type; + int _startFrame; + int _endFrame; + CGameObject *_gameObject; + int _initialFrame; public: CMovieEvent(); CMovieEvent(const CMovieEvent *src); @@ -53,6 +57,10 @@ public: class CMovieEventList : public List { }; +class CSharedMovieEventList : public Common::List { +}; + + } // End of namespace Titanic #endif /* TITANIC_MOVIE_EVENT_H */ diff --git a/engines/titanic/support/movie_range_info.cpp b/engines/titanic/support/movie_range_info.cpp index e6b28ce4e8..4c62539864 100644 --- a/engines/titanic/support/movie_range_info.cpp +++ b/engines/titanic/support/movie_range_info.cpp @@ -34,11 +34,11 @@ CMovieRangeInfo::~CMovieRangeInfo() { } CMovieRangeInfo::CMovieRangeInfo(const CMovieRangeInfo *src) : ListItem() { - _fieldC = src->_fieldC; - _field10 = src->_field10; - _frameNumber = src->_frameNumber; _startFrame = src->_startFrame; _endFrame = src->_endFrame; + _initialFrame = src->_initialFrame; + _isReversed = src->_isReversed; + _isFlag1 = src->_isFlag1; // Duplicate the events list for (CMovieEventList::const_iterator i = _events.begin(); @@ -49,38 +49,38 @@ CMovieRangeInfo::CMovieRangeInfo(const CMovieRangeInfo *src) : ListItem() { void CMovieRangeInfo::save(SimpleFile *file, int indent) { file->writeNumberLine(0, indent); - file->writeNumberLine(_fieldC, indent + 1); - file->writeNumberLine(_field10, indent + 1); - file->writeNumberLine(_frameNumber, indent + 1); - file->writeNumberLine(_endFrame, indent + 1); file->writeNumberLine(_startFrame, indent + 1); + file->writeNumberLine(_endFrame, indent + 1); + file->writeNumberLine(_initialFrame, indent + 1); + file->writeNumberLine(_isFlag1, indent + 1); + file->writeNumberLine(_isReversed, indent + 1); _events.save(file, indent + 1); } void CMovieRangeInfo::load(SimpleFile *file) { int val = file->readNumber(); if (!val) { - _fieldC = file->readNumber(); - _field10 = file->readNumber(); - _frameNumber = file->readNumber(); - _endFrame = file->readNumber(); _startFrame = file->readNumber(); + _endFrame = file->readNumber(); + _initialFrame = file->readNumber(); + _isFlag1 = file->readNumber(); + _isReversed = file->readNumber(); _events.load(file); } } -void CMovieRangeInfo::get1(CMovieEventList &list) { +void CMovieRangeInfo::getMovieEnd(CMovieEventList &list) { for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) { CMovieEvent *movieEvent = *i; - if (movieEvent->_fieldC == 1) + if (movieEvent->_type == MET_MOVIE_END) list.push_back(new CMovieEvent(movieEvent)); } } -void CMovieRangeInfo::get2(CMovieEventList &list, int val) { +void CMovieRangeInfo::getMovieFrame(CMovieEventList &list, int frameNumber) { for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) { CMovieEvent *movieEvent = *i; - if (movieEvent->_fieldC == 2 && movieEvent->_field1C == val) + if (movieEvent->_type == MET_FRAME && movieEvent->_initialFrame == frameNumber) list.push_back(new CMovieEvent(movieEvent)); } } @@ -88,24 +88,24 @@ void CMovieRangeInfo::get2(CMovieEventList &list, int val) { void CMovieRangeInfo::process(CGameObject *owner) { int flags = 0; if (_endFrame) - flags |= CLIPFLAG_HAS_END_FRAME; + flags |= MOVIE_1; if (_startFrame) - flags |= CLIPFLAG_HAS_START_FRAME; + flags |= MOVIE_REVERSE; for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) { CMovieEvent *movieEvent = *i; - if (!movieEvent->_fieldC) { + if (!movieEvent->_type == MET_PLAY) { flags |= CLIPFLAG_PLAY; break; } } - owner->checkPlayMovie(_fieldC, _field10, _frameNumber, flags); + owner->playMovie(_startFrame, _endFrame, _initialFrame, flags); for (CMovieEventList::iterator i = _events.begin(); i != _events.end(); ++i) { CMovieEvent *movieEvent = *i; - if (!movieEvent->_fieldC) - owner->surface38(movieEvent->_field1C); + if (movieEvent->_type == MET_PLAY) + owner->movieEvent(movieEvent->_initialFrame); } } diff --git a/engines/titanic/support/movie_range_info.h b/engines/titanic/support/movie_range_info.h index be04975cbf..b8186e6f7e 100644 --- a/engines/titanic/support/movie_range_info.h +++ b/engines/titanic/support/movie_range_info.h @@ -34,11 +34,11 @@ class CGameObject; class CMovieRangeInfo : public ListItem { public: - int _fieldC; - int _field10; - int _frameNumber; - uint _startFrame; - uint _endFrame; + int _startFrame; + int _endFrame; + int _initialFrame; + bool _isReversed; + bool _isFlag1; CMovieEventList _events; public: CMovieRangeInfo(); @@ -60,9 +60,15 @@ public: */ void addEvent(CMovieEvent *movieEvent) { _events.push_back(movieEvent); } - void get1(CMovieEventList &list); + /** + * Get any movie end events for the range + */ + void getMovieEnd(CMovieEventList &list); - void get2(CMovieEventList &list, int val); + /** + * Get any movie frame events for a specified frame number + */ + void getMovieFrame(CMovieEventList &list, int frameNumber); void process(CGameObject *owner); }; diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index 0335e7d9b1..fc7db30391 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -32,7 +32,7 @@ int CVideoSurface::_videoSurfaceCounter = 0; CVideoSurface::CVideoSurface(CScreenManager *screenManager) : _screenManager(screenManager), _rawSurface(nullptr), _movie(nullptr), _pendingLoad(false), _blitStyleFlag(false), _blitFlag(false), - _field40(nullptr), _field44(4), _field48(0), _field50(1) { + _movieFrameInfo(nullptr), _transparencyMode(TRANS_DEFAULT), _field48(0), _field50(1) { _videoSurfaceNum = _videoSurfaceCounter++; } @@ -427,22 +427,22 @@ void OSVideoSurface::clear() { } -void OSVideoSurface::playMovie(uint flags, CVideoSurface *surface) { +void OSVideoSurface::playMovie(uint flags, CGameObject *obj) { if (loadIfReady() && _movie) - _movie->play(flags, surface); + _movie->play(flags, obj); _ddSurface->fill(nullptr, 0); } -void OSVideoSurface::playMovie(uint startFrame, uint endFrame, int v3, bool v4) { +void OSVideoSurface::playMovie(uint startFrame, uint endFrame, uint flags, CGameObject *obj) { if (loadIfReady() && _movie) { - _movie->play(startFrame, endFrame, v3, v4); + _movie->play(startFrame, endFrame, flags, obj); } } -void OSVideoSurface::proc35(int v1, int v2, int frameNumber, int flags, CGameObject *owner) { +void OSVideoSurface::playMovie(uint startFrame, uint endFrame, uint initialFrame, uint flags, CGameObject *obj) { if (loadIfReady() && _movie) { - _movie->proc12(v1, v2, frameNumber, flags, owner); + _movie->play(startFrame, endFrame, initialFrame, flags, obj); } } @@ -456,16 +456,17 @@ void OSVideoSurface::setMovieFrame(uint frameNumber) { _movie->setFrame(frameNumber); } -void OSVideoSurface::proc38(int v1, int v2) { - warning("OSVideoSurface::proc38"); +void OSVideoSurface::addMovieEvent(int frameNumber, CGameObject *obj) { + if (_movie) + _movie->addEvent(frameNumber, obj); } void OSVideoSurface::proc39(int v1, int v2) { warning("OSVideoSurface::proc39"); } -const Common::List OSVideoSurface::getMovieRangeInfo() const { - return _movie ? _movie->getMovieRangeInfo() : Common::List(); +const CMovieRangeInfoList *OSVideoSurface::getMovieRangeInfo() const { + return _movie ? _movie->getMovieRangeInfo() : nullptr; } bool OSVideoSurface::loadIfReady() { diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index 37afccf9e1..3521be6336 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -35,6 +35,11 @@ namespace Titanic { +enum TransparencyMode { + TRANS_MASK0 = 0, TRANS_MASK255 = 1, TRANS_ALPHA0 = 2, + TRANS_ALPHA255 = 3, TRANS_DEFAULT = 4 +}; + class CScreenManager; class CJPEGDecode; class CTargaDecode; @@ -57,8 +62,7 @@ protected: CScreenManager *_screenManager; Graphics::ManagedSurface *_rawSurface; bool _pendingLoad; - void *_field40; - int _field44; + const void *_movieFrameInfo; int _field48; int _videoSurfaceNum; int _field50; @@ -69,6 +73,7 @@ public: bool _blitFlag; bool _blitStyleFlag; CResourceKey _resourceKey; + TransparencyMode _transparencyMode; public: CVideoSurface(CScreenManager *screenManager); virtual ~CVideoSurface(); @@ -190,15 +195,19 @@ public: * Plays a movie, loading it from the specified _resource * if not already loaded */ - virtual void playMovie(uint flags, CVideoSurface *surface) = 0; + 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, int v3, bool v4) = 0; + virtual void playMovie(uint startFrame, uint endFrame, uint flags, CGameObject *obj) = 0; - virtual void proc35(int v1, int v2, int frameNumber, int flags, CGameObject *owner) = 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 @@ -206,18 +215,21 @@ public: virtual void stopMovie() = 0; /** - * Sets the movie to the specified frame number + * Set the current movie frame number */ virtual void setMovieFrame(uint frameNumber) = 0; - virtual void proc38(int v1, int v2) = 0; + /** + * Adds a movie playback event + */ + virtual void addMovieEvent(int eventId, CGameObject *obj) = 0; virtual void proc39(int v1, int v2) = 0; /** * Return any movie range info associated with the surface's movie */ - virtual const Common::List getMovieRangeInfo() const = 0; + virtual const CMovieRangeInfoList *getMovieRangeInfo() const = 0; /** * Loads the surface's resource if there's one pending @@ -257,8 +269,19 @@ public: */ void blitFrom(const Point &destPos, const Graphics::Surface *src); - void set40(void *v) { _field40 = v; } + /** + * + */ + void setMovieFrameInfo(const void *frameInfo) { _movieFrameInfo = frameInfo; } + + /** + */ + const void *getMovieFrameInfo() const { return _movieFrameInfo; } + /** + * Get the pixels associated with the surface. Only valid when the + * surface has been locked for access + */ uint16 *getPixels() { return (uint16 *)_rawSurface->getPixels(); } /** @@ -400,15 +423,19 @@ public: * Plays a movie, loading it from the specified _resource * if not already loaded */ - virtual void playMovie(uint flags, CVideoSurface *surface); + virtual void playMovie(uint flags, CGameObject *obj); /** * Plays a movie, loading it from the specified _resource * if not already loaded */ - virtual void playMovie(uint startFrame, uint endFrame, int v3, bool v4); + virtual void playMovie(uint startFrame, uint endFrame, uint flags, CGameObject *obj); - virtual void proc35(int v1, int v2, int frameNumber, int flags, CGameObject *owner); + /** + * 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); /** * Stops any movie currently attached to the surface @@ -420,14 +447,17 @@ public: */ virtual void setMovieFrame(uint frameNumber); - virtual void proc38(int v1, int v2); + /** + * Adds a movie playback event + */ + virtual void addMovieEvent(int frameNumber, CGameObject *obj); virtual void proc39(int v1, int v2); /** * Return any movie range info associated with the surface's movie */ - virtual const Common::List getMovieRangeInfo() const; + virtual const CMovieRangeInfoList *getMovieRangeInfo() const; /** * Loads the surface's resource if there's one pending -- cgit v1.2.3 From 6c56d5aa11db1401bc0a2277776ec43128174bc2 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 9 Jul 2016 12:07:12 -0400 Subject: TITANIC: Named two remaining OSMovie virtual methods --- engines/titanic/support/avi_surface.cpp | 12 ++++++++++++ engines/titanic/support/avi_surface.h | 9 +++++++++ engines/titanic/support/mouse_cursor.cpp | 10 +++++----- engines/titanic/support/mouse_cursor.h | 5 ++++- engines/titanic/support/movie.cpp | 10 ++++------ engines/titanic/support/movie.h | 23 ++++++++++++++++++----- 6 files changed, 52 insertions(+), 17 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp index 47127fe83b..a416bc3d69 100644 --- a/engines/titanic/support/avi_surface.cpp +++ b/engines/titanic/support/avi_surface.cpp @@ -214,4 +214,16 @@ bool AVISurface::addEvent(int frameNumber, CGameObject *obj) { return false; } +void AVISurface::setFrameRate(double rate) { + if (rate >= 0.0 && rate <= 100.0) { + _frameRate = rate; + warning("TODO: Frame rate set to %d yet to be implemented", (int)rate); + } +} + +void *AVISurface::duplicateFrameInfo() const { + // TODO + return nullptr; +} + } // End of namespace Titanic diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h index 48c8169e78..fe3e972b07 100644 --- a/engines/titanic/support/avi_surface.h +++ b/engines/titanic/support/avi_surface.h @@ -127,6 +127,11 @@ public: */ bool addEvent(int frameNumber, CGameObject *obj); + /** + * Set the frame rate + */ + void setFrameRate(double rate); + const void *getFrameInfo() const { return _streamCount <= 1 ? nullptr : _frameInfo; } @@ -138,6 +143,10 @@ public: return &_movieRangeInfo; } + /** + * Duplicate the frame info + */ + void *duplicateFrameInfo() const; }; } // End of namespace Titanic diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp index 721088f086..be607a432f 100644 --- a/engines/titanic/support/mouse_cursor.cpp +++ b/engines/titanic/support/mouse_cursor.cpp @@ -97,11 +97,11 @@ void CMouseCursor::loadCursorImages() { OSMovie movie(stream, surface); movie.setFrame(idx); - int frameNum = movie.proc21(); - _cursors[idx]._frameNumber = frameNum; - surface->setMovieFrame(frameNum); -*/ - } + void *frameInfo = movie.duplicateFrameInfo(); + _cursors[idx]._frameInfo = frameInfo; + surface->setMovieFrameInfo(frameInfo); + */ + } } void CMouseCursor::show() { diff --git a/engines/titanic/support/mouse_cursor.h b/engines/titanic/support/mouse_cursor.h index 168a7be539..f674ccd23d 100644 --- a/engines/titanic/support/mouse_cursor.h +++ b/engines/titanic/support/mouse_cursor.h @@ -54,8 +54,11 @@ class CVideoSurface; class CMouseCursor { struct CursorEntry { CVideoSurface *_videoSurface; - int _frameNumber; + void *_frameInfo; Common::Point _centroid; + + CursorEntry() : _videoSurface(nullptr), _frameInfo(nullptr) {} + ~CursorEntry() { delete _frameInfo; } }; private: CScreenManager *_screenManager; diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 338396ff96..fc31750508 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -213,14 +213,12 @@ void OSMovie::movieStarted() { _field10 = 1; } -void OSMovie::proc20() { - // TODO +void OSMovie::setFrameRate(double rate) { + _aviSurface.setFrameRate(rate); } -int OSMovie::proc21() { - // TODO - return 0; +void *OSMovie::duplicateFrameInfo() const { + return _aviSurface.duplicateFrameInfo(); } - } // End of namespace Titanic diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index c839c882ca..8034bd4032 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -126,9 +126,16 @@ public: * Get the current movie frame */ virtual int getFrame() const = 0; - - virtual void proc20() = 0; - virtual int proc21() = 0; + + /** + * Set the frame rate for the movie + */ + virtual void setFrameRate(double rate) = 0; + + /** + * Creates a duplicate of the frame info + */ + virtual void *duplicateFrameInfo() const = 0; /** * Removes the movie from the list of currently playing movies @@ -218,9 +225,15 @@ public: */ virtual void setSoundManager(CSoundManager *soundManager); - virtual void proc20(); - virtual int proc21(); + /** + * Set the frame rate for the movie + */ + virtual void setFrameRate(double rate); + /** + * Creates a duplicate of the frame info + */ + virtual void *duplicateFrameInfo() const; }; } // End of namespace Titanic -- cgit v1.2.3 From fd954a8e0b41370ae68f3b409295676de207313d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Jul 2016 11:36:04 -0400 Subject: TITANIC: Added OSVideoSurface flipVertically --- engines/titanic/support/avi_surface.cpp | 21 ++++++++++--------- engines/titanic/support/video_surface.cpp | 34 +++++++++++++++++++++++++++++-- engines/titanic/support/video_surface.h | 31 ++++++++++++++++++++++++++-- 3 files changed, 72 insertions(+), 14 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp index a416bc3d69..e371ccb812 100644 --- a/engines/titanic/support/avi_surface.cpp +++ b/engines/titanic/support/avi_surface.cpp @@ -27,23 +27,24 @@ namespace Titanic { AVISurface::AVISurface(const CResourceKey &key) { + _videoSurface = nullptr; + _field4 = 0; + _field8 = 0; + _currentPos = 0; + _priorFrame = 0; + _streamCount = 0; + _frameInfo = nullptr; - // TODO -/* -Video::AVIDecoder *decoder = new Video::AVIDecoder(); -decoder->ignoreSecondaryVideoTracks(); -_video = decoder; -_field14 = 1; - -if (!_video->loadFile(name.getString())) -error("Could not open video - %s", name.getString().c_str()); -*/ + _decoder = new Video::AVIDecoder(); + if (!_decoder->loadFile(key.getString())) + error("Could not open video - %s", key.getString().c_str()); } AVISurface::~AVISurface() { if (_videoSurface) _videoSurface->_blitStyleFlag = false; delete _frameInfo; + delete _decoder; } bool AVISurface::play(uint flags, CGameObject *obj) { diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index fc7db30391..546c2c475b 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -461,14 +461,40 @@ void OSVideoSurface::addMovieEvent(int frameNumber, CGameObject *obj) { _movie->addEvent(frameNumber, obj); } -void OSVideoSurface::proc39(int v1, int v2) { - warning("OSVideoSurface::proc39"); +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() || !_blitStyleFlag) + 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); + } + + _blitStyleFlag = false; + if (needsLock) + unlock(); +} + bool OSVideoSurface::loadIfReady() { _videoSurfaceNum = _videoSurfaceCounter; @@ -511,6 +537,10 @@ void OSVideoSurface::transPixelate() { unlock(); } +void *OSVideoSurface::dupMovieFrameInfo() const { + return _movie ? _movie->duplicateFrameInfo() : nullptr; +} + int OSVideoSurface::freeSurface() { if (!_ddSurface) return 0; diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index 3521be6336..c8cfb78cd4 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -224,13 +224,21 @@ public: */ virtual void addMovieEvent(int eventId, CGameObject *obj) = 0; - virtual void proc39(int v1, int v2) = 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 */ @@ -249,6 +257,11 @@ public: virtual bool proc45(); + /** + * Duplicates movie frame info + */ + virtual void *dupMovieFrameInfo() const = 0; + /** * Frees the underlying surface */ @@ -452,13 +465,21 @@ public: */ virtual void addMovieEvent(int frameNumber, CGameObject *obj); - virtual void proc39(int v1, int v2); + /** + * Set the movie frame rate + */ + virtual void setMovieFrameRate(double rate); /** * Return any movie range info associated with the surface's movie */ virtual const CMovieRangeInfoList *getMovieRangeInfo() const; + /** + * + */ + virtual void flipVertically(bool needsLock = true); + /** * Loads the surface's resource if there's one pending */ @@ -475,6 +496,12 @@ public: */ virtual void transPixelate(); + /** + * Duplicates movie frame info + */ + virtual void *dupMovieFrameInfo() const; + + /** * Frees the underlying surface */ -- cgit v1.2.3 From 207e1cbb296c8f825d19167d420bbf141398ac1d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Jul 2016 17:19:11 -0400 Subject: TITANIC: Remove old hard-coded video loading code from cursors loading --- engines/titanic/support/mouse_cursor.cpp | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp index be607a432f..496b1527fe 100644 --- a/engines/titanic/support/mouse_cursor.cpp +++ b/engines/titanic/support/mouse_cursor.cpp @@ -63,26 +63,10 @@ CMouseCursor::~CMouseCursor() { } void CMouseCursor::loadCursorImages() { - const CString name("ycursors.avi"); - g_vm->_filesManager->fn4(name); - - // WORKAROUND: We need to manipulate ycursors.avi file so it can be read - // by the ScummVM AVIDecoder, by removing the redundant second video track - Common::File f; - if (!f.open(name)) - error("Could not open cursors file"); - - // Read in the entire file - byte *movieData = (byte *)malloc(f.size()); - f.read(movieData, f.size()); - - if (READ_BE_UINT32(movieData + 254) == MKTAG('s', 't', 'r', 'h')) { - // Change the second video chunk to junk data so it gets ignored - WRITE_BE_UINT32(movieData + 254, MKTAG('J', 'U', 'N', 'K')); - WRITE_LE_UINT32(movieData + 258, 1128); - } + const CResourceKey key("ycursors.avi"); + g_vm->_filesManager->fn4(key.getString()); - // Iterate through each cursor + // 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], @@ -91,16 +75,14 @@ void CMouseCursor::loadCursorImages() { // Create the surface CVideoSurface *surface = _screenManager->createSurface(64, 64); _cursors[idx]._videoSurface = surface; -/* - Common::SeekableReadStream *stream = new Common::MemoryReadStream( - movieData, f.size(), DisposeAfterUse::NO); - OSMovie movie(stream, surface); + + // Open the cursors video and move to the given frame + OSMovie movie(key, surface); movie.setFrame(idx); void *frameInfo = movie.duplicateFrameInfo(); _cursors[idx]._frameInfo = frameInfo; surface->setMovieFrameInfo(frameInfo); - */ } } -- cgit v1.2.3 From 8a6bba0fec0718f9c9fc9b69478b8aa6ff0bd791 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 11 Jul 2016 19:43:42 -0400 Subject: TITANIC: Change AVISurface to use a separate AVIDecoder for each video track --- engines/titanic/support/avi_surface.cpp | 70 +++++++++++++++++++++++++-------- engines/titanic/support/avi_surface.h | 2 +- 2 files changed, 55 insertions(+), 17 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp index e371ccb812..96bd6f7a1b 100644 --- a/engines/titanic/support/avi_surface.cpp +++ b/engines/titanic/support/avi_surface.cpp @@ -26,6 +26,21 @@ namespace Titanic { +/** + * Track filter for AVIDecoder that filters out any secondary video track + */ +static bool primaryTrackSelect(bool isVideo, int trackCounter) { + return !isVideo || trackCounter == 0; +} + +/** + * Track filter for AVIDecoder that only accepts the secondary video track + * for a video, if present + */ +static bool secondaryTrackSelect(bool isVideo, int trackCounter) { + return isVideo && trackCounter > 0; +} + AVISurface::AVISurface(const CResourceKey &key) { _videoSurface = nullptr; _field4 = 0; @@ -34,24 +49,35 @@ AVISurface::AVISurface(const CResourceKey &key) { _priorFrame = 0; _streamCount = 0; _frameInfo = nullptr; + _isPlaying = false; - _decoder = new Video::AVIDecoder(); - if (!_decoder->loadFile(key.getString())) + // Create a decoder for the audio (if any) and primary video track + _decoders[0] = new Video::AVIDecoder(Audio::Mixer::kPlainSoundType, primaryTrackSelect); + if (!_decoders[0]->loadFile(key.getString())) error("Could not open video - %s", key.getString().c_str()); + + // Create a decoder for any secondary video track + Video::AVIDecoder *decoder2 = new Video::AVIDecoder(Audio::Mixer::kPlainSoundType, secondaryTrackSelect); + if (decoder2->loadFile(key.getString())) { + _decoders[1] = decoder2; + } else { + delete decoder2; + } } AVISurface::~AVISurface() { if (_videoSurface) _videoSurface->_blitStyleFlag = false; delete _frameInfo; - delete _decoder; + delete _decoders[0]; + delete _decoders[1]; } bool AVISurface::play(uint flags, CGameObject *obj) { if (flags & MOVIE_REVERSE) - return play(_decoder->getFrameCount() - 1, 0, flags, obj); + return play(_decoders[0]->getFrameCount() - 1, 0, flags, obj); else - return play(0, _decoder->getFrameCount() - 1, flags, obj); + return play(0, _decoders[0]->getFrameCount() - 1, flags, obj); } bool AVISurface::play(int startFrame, int endFrame, uint flags, CGameObject *obj) { @@ -90,7 +116,10 @@ bool AVISurface::play(int startFrame, int endFrame, int initialFrame, uint flags void AVISurface::stop() { _isPlaying = false; - _decoder->stop(); + _decoders[0]->stop(); + if (_decoders[1]) + _decoders[1]->stop(); + _movieRangeInfo.destroyContents(); } @@ -110,7 +139,10 @@ bool AVISurface::changeFrame(int frameNumber) { } void AVISurface::seekToFrame(uint frameNumber) { - _decoder->seekToFrame(frameNumber); + _decoders[0]->seekToFrame(frameNumber); + if (_decoders[1]) + _decoders[1]->seekToFrame(frameNumber); + _priorFrame = frameNumber; } @@ -159,11 +191,11 @@ void AVISurface::setVideoSurface(CVideoSurface *surface) { } uint AVISurface::getWidth() const { - return _decoder->getWidth(); + return _decoders[0]->getWidth(); } uint AVISurface::getHeight() const { - return _decoder->getHeight(); + return _decoders[0]->getHeight(); } void AVISurface::setFrame(int frameNumber) { @@ -172,26 +204,32 @@ void AVISurface::setFrame(int frameNumber) { stop(); // Ensure the frame number is valid - if (frameNumber >= _decoder->getFrameCount()) - frameNumber = _decoder->getFrameCount() - 1; + if (frameNumber >= _decoders[0]->getFrameCount()) + frameNumber = _decoders[0]->getFrameCount() - 1; seekToFrame(frameNumber); renderFrame(); } int AVISurface::getFrame() const { - return _decoder->getCurFrame(); + return _decoders[0]->getCurFrame(); } bool AVISurface::renderFrame() { - // Check there's a frame ready for + // Check there's a frame ready for display assert(_videoSurface); - if (!_decoder->needsUpdate()) + if (!_decoders[0]->needsUpdate() || (_decoders[1] && !_decoders[1]->needsUpdate())) return false; // Get the frame to render, and draw it on the surface - const Graphics::Surface *frame = _decoder->decodeNextFrame(); - _videoSurface->blitFrom(Point(0, 0), frame); + // TODO: Handle transparency + for (int idx = 0; idx < 2; ++idx) { + if (_decoders[idx]) { + const Graphics::Surface *frame = _decoders[idx]->decodeNextFrame(); + _videoSurface->blitFrom(Point(0, 0), frame); + } + } + return false; } diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h index fe3e972b07..f3722ca513 100644 --- a/engines/titanic/support/avi_surface.h +++ b/engines/titanic/support/avi_surface.h @@ -39,7 +39,7 @@ enum MovieFlag { class AVISurface { private: - Video::AVIDecoder *_decoder; + Video::AVIDecoder *_decoders[2]; CVideoSurface *_videoSurface; int _field4; int _field8; -- cgit v1.2.3 From c458c3c9b740602002cd0a130a99af8b10402806 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 11 Jul 2016 21:52:57 -0400 Subject: TITANIC: Fix warnings in AVISurface --- engines/titanic/support/avi_surface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp index 96bd6f7a1b..7f2cd3cc47 100644 --- a/engines/titanic/support/avi_surface.cpp +++ b/engines/titanic/support/avi_surface.cpp @@ -108,7 +108,7 @@ bool AVISurface::play(int startFrame, int endFrame, int initialFrame, uint flags _movieRangeInfo.push_back(info); if (_movieRangeInfo.size() == 1) { - changeFrame(initialFrame); + return changeFrame(initialFrame); } else { return true; } @@ -204,7 +204,7 @@ void AVISurface::setFrame(int frameNumber) { stop(); // Ensure the frame number is valid - if (frameNumber >= _decoders[0]->getFrameCount()) + if (frameNumber >= (int)_decoders[0]->getFrameCount()) frameNumber = _decoders[0]->getFrameCount() - 1; seekToFrame(frameNumber); -- cgit v1.2.3 From 513723c82d5db078236421577924bd9cde29b99b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 Jul 2016 08:38:26 -0400 Subject: TITANIC: Making the AVISurface frameInfo a video surface --- engines/titanic/support/avi_surface.cpp | 65 +++++++++++++++++++++++++------ engines/titanic/support/avi_surface.h | 32 ++++++++++----- engines/titanic/support/mouse_cursor.cpp | 11 ++++-- engines/titanic/support/mouse_cursor.h | 6 +-- engines/titanic/support/movie.cpp | 10 ++--- engines/titanic/support/movie.h | 6 +-- engines/titanic/support/video_surface.cpp | 34 +++++++++------- engines/titanic/support/video_surface.h | 24 ++++++------ 8 files changed, 127 insertions(+), 61 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp index 7f2cd3cc47..85590f1d1e 100644 --- a/engines/titanic/support/avi_surface.cpp +++ b/engines/titanic/support/avi_surface.cpp @@ -21,11 +21,20 @@ */ #include "titanic/support/avi_surface.h" +#include "titanic/support/screen_manager.h" #include "titanic/support/video_surface.h" #include "video/avi_decoder.h" namespace Titanic { +Video::AVIDecoder::AVIVideoTrack &AVIDecoder::getVideoTrack() { + for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++) + if ((*it)->getTrackType() == Track::kTrackTypeVideo) + return *static_cast(*it); + + error("Could not find video track"); +} + /** * Track filter for AVIDecoder that filters out any secondary video track */ @@ -43,21 +52,19 @@ static bool secondaryTrackSelect(bool isVideo, int trackCounter) { AVISurface::AVISurface(const CResourceKey &key) { _videoSurface = nullptr; - _field4 = 0; - _field8 = 0; _currentPos = 0; _priorFrame = 0; _streamCount = 0; - _frameInfo = nullptr; + _movieFrameSurface[0] = _movieFrameSurface[1] = nullptr; _isPlaying = false; // Create a decoder for the audio (if any) and primary video track - _decoders[0] = new Video::AVIDecoder(Audio::Mixer::kPlainSoundType, primaryTrackSelect); + _decoders[0] = new AVIDecoder(Audio::Mixer::kPlainSoundType, primaryTrackSelect); if (!_decoders[0]->loadFile(key.getString())) error("Could not open video - %s", key.getString().c_str()); // Create a decoder for any secondary video track - Video::AVIDecoder *decoder2 = new Video::AVIDecoder(Audio::Mixer::kPlainSoundType, secondaryTrackSelect); + AVIDecoder *decoder2 = new AVIDecoder(Audio::Mixer::kPlainSoundType, secondaryTrackSelect); if (decoder2->loadFile(key.getString())) { _decoders[1] = decoder2; } else { @@ -67,8 +74,9 @@ AVISurface::AVISurface(const CResourceKey &key) { AVISurface::~AVISurface() { if (_videoSurface) - _videoSurface->_blitStyleFlag = false; - delete _frameInfo; + _videoSurface->_transBlitFlag = false; + delete _movieFrameSurface[0]; + delete _movieFrameSurface[1]; delete _decoders[0]; delete _decoders[1]; } @@ -187,7 +195,37 @@ bool AVISurface::handleEvents(CMovieEventList &events) { void AVISurface::setVideoSurface(CVideoSurface *surface) { _videoSurface = surface; - warning("TODO: Get video track list from video decoder"); + // Handling for secondary video stream + if (_decoders[1]) { + const Common::String &streamName = _decoders[1]->getVideoTrack().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() { + for (int idx = 0; idx < 2; ++idx) { + if (!_decoders[idx]) + continue; + AVIDecoder &decoder = *_decoders[idx]; + + // Setup frame surface + _movieFrameSurface[idx] = CScreenManager::_screenManagerPtr->createSurface(decoder.getWidth(), decoder.getHeight()); + + // TODO: See whether this simplified form of original works + if (idx == 2) + _videoSurface->_transBlitFlag = true; + } } uint AVISurface::getWidth() const { @@ -260,9 +298,14 @@ void AVISurface::setFrameRate(double rate) { } } -void *AVISurface::duplicateFrameInfo() const { - // TODO - return nullptr; +CVideoSurface *AVISurface::getSecondarySurface() { + return _streamCount <= 1 ? nullptr : _movieFrameSurface[1]; +} + +CVideoSurface *AVISurface::duplicateSecondaryFrame() const { + // TODO: Make this cleaner + OSVideoSurface *src = dynamic_cast(_movieFrameSurface[1]); + return new OSVideoSurface(*src); } } // End of namespace Titanic diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h index f3722ca513..62fc5172c9 100644 --- a/engines/titanic/support/avi_surface.h +++ b/engines/titanic/support/avi_surface.h @@ -37,22 +37,35 @@ enum MovieFlag { MOVIE_REVERSE = 8, MOVIE_GAMESTATE = 0x10 }; +class AVIDecoder : public Video::AVIDecoder { +public: + AVIDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType, SelectTrackFn trackFn = nullptr) : + Video::AVIDecoder(soundType, trackFn) {} + AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType, + SelectTrackFn trackFn = nullptr) : Video::AVIDecoder(frameRateOverride, soundType, trackFn) {} + + Video::AVIDecoder::AVIVideoTrack &getVideoTrack(); +}; + class AVISurface { private: - Video::AVIDecoder *_decoders[2]; + AVIDecoder *_decoders[2]; CVideoSurface *_videoSurface; - int _field4; - int _field8; int _currentPos; int _priorFrame; CMovieRangeInfoList _movieRangeInfo; int _streamCount; - void *_frameInfo; + CVideoSurface *_movieFrameSurface[2]; private: /** * Render a frame to the video surface */ bool renderFrame(); + + /** + * Sets up for video decompression + */ + void setupDecompressor(); protected: /** * Change the frame with ??? checking @@ -132,9 +145,10 @@ public: */ void setFrameRate(double rate); - const void *getFrameInfo() const { - return _streamCount <= 1 ? nullptr : _frameInfo; - } + /** + * Returns the surface for the secondary video track frame, if present + */ + CVideoSurface *getSecondarySurface(); /** * Get a reference to the movie range info list @@ -144,9 +158,9 @@ public: } /** - * Duplicate the frame info + * Duplicates the secondary frame, if the movie has a second video track */ - void *duplicateFrameInfo() const; + CVideoSurface *duplicateSecondaryFrame() const; }; } // End of namespace Titanic diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp index 496b1527fe..628211c7f1 100644 --- a/engines/titanic/support/mouse_cursor.cpp +++ b/engines/titanic/support/mouse_cursor.cpp @@ -50,6 +50,11 @@ static const int CURSOR_DATA[NUM_CURSORS][4] = { { 15, 138, 20, 28 } }; +CMouseCursor::CursorEntry::~CursorEntry() { + delete _videoSurface; + delete _frameSurface; +} + CMouseCursor::CMouseCursor(CScreenManager *screenManager) : _screenManager(screenManager), _cursorId(CURSOR_HOURGLASS), _setCursorCount(0), _fieldE4(0), _fieldE8(0) { @@ -80,9 +85,9 @@ void CMouseCursor::loadCursorImages() { OSMovie movie(key, surface); movie.setFrame(idx); - void *frameInfo = movie.duplicateFrameInfo(); - _cursors[idx]._frameInfo = frameInfo; - surface->setMovieFrameInfo(frameInfo); + CVideoSurface *frameSurface = movie.duplicateFrame(); + _cursors[idx]._frameSurface = frameSurface; + surface->setMovieFrameSurface(frameSurface); } } diff --git a/engines/titanic/support/mouse_cursor.h b/engines/titanic/support/mouse_cursor.h index f674ccd23d..f6ab92dca7 100644 --- a/engines/titanic/support/mouse_cursor.h +++ b/engines/titanic/support/mouse_cursor.h @@ -54,11 +54,11 @@ class CVideoSurface; class CMouseCursor { struct CursorEntry { CVideoSurface *_videoSurface; - void *_frameInfo; + CVideoSurface *_frameSurface; Common::Point _centroid; - CursorEntry() : _videoSurface(nullptr), _frameInfo(nullptr) {} - ~CursorEntry() { delete _frameInfo; } + CursorEntry() : _videoSurface(nullptr), _frameSurface(nullptr) {} + ~CursorEntry(); }; private: CScreenManager *_screenManager; diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index fc31750508..495cf7c2a7 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -159,7 +159,7 @@ void OSMovie::addEvent(int frameNumber, CGameObject *obj) { void OSMovie::setFrame(uint frameNumber) { _aviSurface.setFrame(frameNumber); - _videoSurface->setMovieFrame(frameNumber); + _videoSurface->setMovieFrameSurface(_aviSurface.getSecondarySurface()); } bool OSMovie::handleEvents(CMovieEventList &events) { @@ -175,12 +175,12 @@ bool OSMovie::handleEvents(CMovieEventList &events) { _frameTime1 += _frameTime2; _aviSurface.handleEvents(events); - _videoSurface->setMovieFrameInfo(_aviSurface.getFrameInfo()); + _videoSurface->setMovieFrameSurface(_aviSurface.getSecondarySurface()); if (_field14) { while (_frameTime1 >= time && events.empty()) { _aviSurface.handleEvents(events); - _videoSurface->setMovieFrameInfo(_aviSurface.getFrameInfo()); + _videoSurface->setMovieFrameSurface(_aviSurface.getSecondarySurface()); _frameTime1 += _frameTime2; } @@ -217,8 +217,8 @@ void OSMovie::setFrameRate(double rate) { _aviSurface.setFrameRate(rate); } -void *OSMovie::duplicateFrameInfo() const { - return _aviSurface.duplicateFrameInfo(); +CVideoSurface *OSMovie::duplicateFrame() const { + return _aviSurface.duplicateSecondaryFrame(); } } // End of namespace Titanic diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index 8034bd4032..f9e368606c 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -133,9 +133,9 @@ public: virtual void setFrameRate(double rate) = 0; /** - * Creates a duplicate of the frame info + * Creates a duplicate of the movie's frame */ - virtual void *duplicateFrameInfo() const = 0; + virtual CVideoSurface *duplicateFrame() const = 0; /** * Removes the movie from the list of currently playing movies @@ -233,7 +233,7 @@ public: /** * Creates a duplicate of the frame info */ - virtual void *duplicateFrameInfo() const; + virtual CVideoSurface *duplicateFrame() const; }; } // End of namespace Titanic diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index 546c2c475b..3e6e93abf1 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -31,8 +31,8 @@ int CVideoSurface::_videoSurfaceCounter = 0; CVideoSurface::CVideoSurface(CScreenManager *screenManager) : _screenManager(screenManager), _rawSurface(nullptr), _movie(nullptr), - _pendingLoad(false), _blitStyleFlag(false), _blitFlag(false), - _movieFrameInfo(nullptr), _transparencyMode(TRANS_DEFAULT), _field48(0), _field50(1) { + _pendingLoad(false), _transBlitFlag(false), _fastBlitFlag(false), + _movieFrameSurface(nullptr), _transparencyMode(TRANS_DEFAULT), _field48(0), _field50(1) { _videoSurfaceNum = _videoSurfaceCounter++; } @@ -52,10 +52,10 @@ void CVideoSurface::blitFrom(const Point &destPos, CVideoSurface *src, const Rec Rect srcBounds, destBounds; clipBounds(srcBounds, destBounds, src, srcRect, &destPos); - if (_blitStyleFlag) - blitRect2(srcBounds, destBounds, src); + if (_transBlitFlag) + transBlitRect(srcBounds, destBounds, src); else - blitRect1(srcBounds, destBounds, src); + blitRect(srcBounds, destBounds, src); } } @@ -128,21 +128,25 @@ void CVideoSurface::clipBounds(Rect &srcRect, Rect &destRect, error("Invalid rect"); } -void CVideoSurface::blitRect1(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) { +void CVideoSurface::blitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) { src->lock(); lock(); - // TODO: Do it like the original does it - _rawSurface->transBlitFrom(*src->_rawSurface, srcRect, destRect, - getTransparencyColor()); + if (_fastBlitFlag) { + _rawSurface->transBlitFrom(*src->_rawSurface, srcRect, destRect, + getTransparencyColor()); + return; + } + + // TODO src->unlock(); unlock(); } -void CVideoSurface::blitRect2(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) { +void CVideoSurface::transBlitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) { // TODO: Do it like the original does it - blitRect1(srcRect, destRect, src); + blitRect(srcRect, destRect, src); } uint CVideoSurface::getTransparencyColor() { @@ -471,7 +475,7 @@ const CMovieRangeInfoList *OSVideoSurface::getMovieRangeInfo() const { } void OSVideoSurface::flipVertically(bool needsLock) { - if (!loadIfReady() || !_blitStyleFlag) + if (!loadIfReady() || !_transBlitFlag) return; if (needsLock) @@ -490,7 +494,7 @@ void OSVideoSurface::flipVertically(bool needsLock) { Common::copy(lineBuffer, lineBuffer + pitch, line1P); } - _blitStyleFlag = false; + _transBlitFlag = false; if (needsLock) unlock(); } @@ -537,8 +541,8 @@ void OSVideoSurface::transPixelate() { unlock(); } -void *OSVideoSurface::dupMovieFrameInfo() const { - return _movie ? _movie->duplicateFrameInfo() : nullptr; +CVideoSurface *OSVideoSurface::dupMovieFrame() const { + return _movie ? _movie->duplicateFrame() : nullptr; } int OSVideoSurface::freeSurface() { diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index c8cfb78cd4..254745805e 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -54,15 +54,15 @@ private: void clipBounds(Rect &srcRect, Rect &destRect, CVideoSurface *srcSurface, const Rect *subRect = nullptr, const Point *destPos = nullptr); - void blitRect1(const Rect &srcRect, const Rect &destRect, CVideoSurface *src); - void blitRect2(const Rect &srcRect, const Rect &destRect, CVideoSurface *src); + void blitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src); + void transBlitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src); protected: static int _videoSurfaceCounter; protected: CScreenManager *_screenManager; Graphics::ManagedSurface *_rawSurface; bool _pendingLoad; - const void *_movieFrameInfo; + CVideoSurface *_movieFrameSurface; int _field48; int _videoSurfaceNum; int _field50; @@ -70,8 +70,8 @@ protected: public: CMovie *_movie; DirectDrawSurface *_ddSurface; - bool _blitFlag; - bool _blitStyleFlag; + bool _fastBlitFlag; + bool _transBlitFlag; CResourceKey _resourceKey; TransparencyMode _transparencyMode; public: @@ -258,9 +258,9 @@ public: virtual bool proc45(); /** - * Duplicates movie frame info - */ - virtual void *dupMovieFrameInfo() const = 0; + * Duplicates movie frame surface + */ + virtual CVideoSurface *dupMovieFrame() const = 0; /** * Frees the underlying surface @@ -285,11 +285,11 @@ public: /** * */ - void setMovieFrameInfo(const void *frameInfo) { _movieFrameInfo = frameInfo; } + void setMovieFrameSurface(CVideoSurface *frameSurface) { _movieFrameSurface = frameSurface; } /** */ - const void *getMovieFrameInfo() const { return _movieFrameInfo; } + CVideoSurface *getMovieFrameSurface() const { return _movieFrameSurface; } /** * Get the pixels associated with the surface. Only valid when the @@ -497,9 +497,9 @@ public: virtual void transPixelate(); /** - * Duplicates movie frame info + * Duplicates movie frame surface */ - virtual void *dupMovieFrameInfo() const; + virtual CVideoSurface *dupMovieFrame() const; /** -- cgit v1.2.3 From 6b250453f90a399b76d373ae9205b1bb985f8e46 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 Jul 2016 17:35:48 -0400 Subject: TITANIC: Further implementation of movie frame decoding --- engines/titanic/support/avi_surface.cpp | 40 ++++++++++++++++++++++++------- engines/titanic/support/avi_surface.h | 7 +++--- engines/titanic/support/mouse_cursor.cpp | 2 +- engines/titanic/support/mouse_cursor.h | 3 ++- engines/titanic/support/movie.cpp | 2 +- engines/titanic/support/movie.h | 4 ++-- engines/titanic/support/video_surface.cpp | 2 +- engines/titanic/support/video_surface.h | 20 +++++++++++----- 8 files changed, 56 insertions(+), 24 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp index 85590f1d1e..ca6a09ade2 100644 --- a/engines/titanic/support/avi_surface.cpp +++ b/engines/titanic/support/avi_surface.cpp @@ -23,6 +23,8 @@ #include "titanic/support/avi_surface.h" #include "titanic/support/screen_manager.h" #include "titanic/support/video_surface.h" +#include "common/system.h" +#include "graphics/pixelformat.h" #include "video/avi_decoder.h" namespace Titanic { @@ -220,7 +222,8 @@ void AVISurface::setupDecompressor() { AVIDecoder &decoder = *_decoders[idx]; // Setup frame surface - _movieFrameSurface[idx] = CScreenManager::_screenManagerPtr->createSurface(decoder.getWidth(), decoder.getHeight()); + _movieFrameSurface[idx] = new Graphics::ManagedSurface(decoder.getWidth(), decoder.getHeight(), + g_system->getScreenFormat()); // TODO: See whether this simplified form of original works if (idx == 2) @@ -259,15 +262,29 @@ bool AVISurface::renderFrame() { if (!_decoders[0]->needsUpdate() || (_decoders[1] && !_decoders[1]->needsUpdate())) return false; - // Get the frame to render, and draw it on the surface - // TODO: Handle transparency + // Decode each decoder's video stream into the appropriate surface for (int idx = 0; idx < 2; ++idx) { if (_decoders[idx]) { const Graphics::Surface *frame = _decoders[idx]->decodeNextFrame(); - _videoSurface->blitFrom(Point(0, 0), frame); + + if (_movieFrameSurface[idx]->format == frame->format) { + _movieFrameSurface[idx]->blitFrom(*frame); + } else { + // Format mis-match, so we need to convert the frame + Graphics::Surface *s = frame->convertTo(_movieFrameSurface[idx]->format, + _decoders[idx]->getPalette()); + _movieFrameSurface[idx]->blitFrom(*s); + s->free(); + delete s; + } } } + // Blit the primary video frame onto the main overall surface + _videoSurface->lock(); + _videoSurface->getRawSurface()->blitFrom(*_movieFrameSurface[0]); + _videoSurface->unlock(); + return false; } @@ -298,14 +315,19 @@ void AVISurface::setFrameRate(double rate) { } } -CVideoSurface *AVISurface::getSecondarySurface() { +Graphics::ManagedSurface *AVISurface::getSecondarySurface() { return _streamCount <= 1 ? nullptr : _movieFrameSurface[1]; } -CVideoSurface *AVISurface::duplicateSecondaryFrame() const { - // TODO: Make this cleaner - OSVideoSurface *src = dynamic_cast(_movieFrameSurface[1]); - return new OSVideoSurface(*src); +Graphics::ManagedSurface *AVISurface::duplicateSecondaryFrame() const { + if (_streamCount <= 1) { + return nullptr; + } else { + Graphics::ManagedSurface *dest = new Graphics::ManagedSurface(_movieFrameSurface[1]->w, + _movieFrameSurface[1]->h, _movieFrameSurface[1]->format); + dest->blitFrom(*_movieFrameSurface[1]); + return dest; + } } } // End of namespace Titanic diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h index 62fc5172c9..f74f6a808e 100644 --- a/engines/titanic/support/avi_surface.h +++ b/engines/titanic/support/avi_surface.h @@ -24,6 +24,7 @@ #define TITANIC_AVI_SURFACE_H #include "video/avi_decoder.h" +#include "graphics/managed_surface.h" #include "titanic/core/resource_key.h" #include "titanic/support/movie_range_info.h" @@ -55,7 +56,7 @@ private: int _priorFrame; CMovieRangeInfoList _movieRangeInfo; int _streamCount; - CVideoSurface *_movieFrameSurface[2]; + Graphics::ManagedSurface *_movieFrameSurface[2]; private: /** * Render a frame to the video surface @@ -148,7 +149,7 @@ public: /** * Returns the surface for the secondary video track frame, if present */ - CVideoSurface *getSecondarySurface(); + Graphics::ManagedSurface *getSecondarySurface(); /** * Get a reference to the movie range info list @@ -160,7 +161,7 @@ public: /** * Duplicates the secondary frame, if the movie has a second video track */ - CVideoSurface *duplicateSecondaryFrame() const; + Graphics::ManagedSurface *duplicateSecondaryFrame() const; }; } // End of namespace Titanic diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp index 628211c7f1..5694d83dc6 100644 --- a/engines/titanic/support/mouse_cursor.cpp +++ b/engines/titanic/support/mouse_cursor.cpp @@ -85,7 +85,7 @@ void CMouseCursor::loadCursorImages() { OSMovie movie(key, surface); movie.setFrame(idx); - CVideoSurface *frameSurface = movie.duplicateFrame(); + Graphics::ManagedSurface *frameSurface = movie.duplicateFrame(); _cursors[idx]._frameSurface = frameSurface; surface->setMovieFrameSurface(frameSurface); } diff --git a/engines/titanic/support/mouse_cursor.h b/engines/titanic/support/mouse_cursor.h index f6ab92dca7..7a81ad43fa 100644 --- a/engines/titanic/support/mouse_cursor.h +++ b/engines/titanic/support/mouse_cursor.h @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "common/rect.h" +#include "graphics/managed_surface.h" namespace Titanic { @@ -54,7 +55,7 @@ class CVideoSurface; class CMouseCursor { struct CursorEntry { CVideoSurface *_videoSurface; - CVideoSurface *_frameSurface; + Graphics::ManagedSurface *_frameSurface; Common::Point _centroid; CursorEntry() : _videoSurface(nullptr), _frameSurface(nullptr) {} diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 495cf7c2a7..b98a5b57a1 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -217,7 +217,7 @@ void OSMovie::setFrameRate(double rate) { _aviSurface.setFrameRate(rate); } -CVideoSurface *OSMovie::duplicateFrame() const { +Graphics::ManagedSurface *OSMovie::duplicateFrame() const { return _aviSurface.duplicateSecondaryFrame(); } diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index f9e368606c..b6c2a09667 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -135,7 +135,7 @@ public: /** * Creates a duplicate of the movie's frame */ - virtual CVideoSurface *duplicateFrame() const = 0; + virtual Graphics::ManagedSurface *duplicateFrame() const = 0; /** * Removes the movie from the list of currently playing movies @@ -233,7 +233,7 @@ public: /** * Creates a duplicate of the frame info */ - virtual CVideoSurface *duplicateFrame() const; + virtual Graphics::ManagedSurface *duplicateFrame() const; }; } // End of namespace Titanic diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index 3e6e93abf1..0429ed4257 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -541,7 +541,7 @@ void OSVideoSurface::transPixelate() { unlock(); } -CVideoSurface *OSVideoSurface::dupMovieFrame() const { +Graphics::ManagedSurface *OSVideoSurface::dupMovieFrame() const { return _movie ? _movie->duplicateFrame() : nullptr; } diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index 254745805e..a0e74b5b3d 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -25,6 +25,7 @@ #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" @@ -62,7 +63,7 @@ protected: CScreenManager *_screenManager; Graphics::ManagedSurface *_rawSurface; bool _pendingLoad; - CVideoSurface *_movieFrameSurface; + Graphics::ManagedSurface *_movieFrameSurface; int _field48; int _videoSurfaceNum; int _field50; @@ -260,7 +261,7 @@ public: /** * Duplicates movie frame surface */ - virtual CVideoSurface *dupMovieFrame() const = 0; + virtual Graphics::ManagedSurface *dupMovieFrame() const = 0; /** * Frees the underlying surface @@ -283,13 +284,14 @@ public: void blitFrom(const Point &destPos, const Graphics::Surface *src); /** - * + * Sets the movie frame surface containing frame data from an active movie */ - void setMovieFrameSurface(CVideoSurface *frameSurface) { _movieFrameSurface = frameSurface; } + void setMovieFrameSurface(Graphics::ManagedSurface *frameSurface) { _movieFrameSurface = frameSurface; } /** + * Get the previously set movie frame surface */ - CVideoSurface *getMovieFrameSurface() const { return _movieFrameSurface; } + Graphics::ManagedSurface *getMovieFrameSurface() const { return _movieFrameSurface; } /** * Get the pixels associated with the surface. Only valid when the @@ -297,6 +299,12 @@ public: */ 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 */ @@ -499,7 +507,7 @@ public: /** * Duplicates movie frame surface */ - virtual CVideoSurface *dupMovieFrame() const; + virtual Graphics::ManagedSurface *dupMovieFrame() const; /** -- cgit v1.2.3 From 1986fa6e83884688a62c0cfbfb9109fcd26fac6e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 Jul 2016 18:13:16 -0400 Subject: TITANIC: Fixes for mouse cursor/movie frame handling --- engines/titanic/support/avi_surface.cpp | 27 ++++++++++++++------------- engines/titanic/support/mouse_cursor.cpp | 2 -- 2 files changed, 14 insertions(+), 15 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp index ca6a09ade2..b685fa8cce 100644 --- a/engines/titanic/support/avi_surface.cpp +++ b/engines/titanic/support/avi_surface.cpp @@ -65,10 +65,13 @@ AVISurface::AVISurface(const CResourceKey &key) { if (!_decoders[0]->loadFile(key.getString())) error("Could not open video - %s", key.getString().c_str()); + _streamCount = 1; + // Create a decoder for any secondary video track AVIDecoder *decoder2 = new AVIDecoder(Audio::Mixer::kPlainSoundType, secondaryTrackSelect); if (decoder2->loadFile(key.getString())) { _decoders[1] = decoder2; + ++_streamCount; } else { delete decoder2; } @@ -263,20 +266,18 @@ bool AVISurface::renderFrame() { return false; // Decode each decoder's video stream into the appropriate surface - for (int idx = 0; idx < 2; ++idx) { - if (_decoders[idx]) { - const Graphics::Surface *frame = _decoders[idx]->decodeNextFrame(); + for (int idx = 0; idx < _streamCount; ++idx) { + const Graphics::Surface *frame = _decoders[idx]->decodeNextFrame(); - if (_movieFrameSurface[idx]->format == frame->format) { - _movieFrameSurface[idx]->blitFrom(*frame); - } else { - // Format mis-match, so we need to convert the frame - Graphics::Surface *s = frame->convertTo(_movieFrameSurface[idx]->format, - _decoders[idx]->getPalette()); - _movieFrameSurface[idx]->blitFrom(*s); - s->free(); - delete s; - } + if (_movieFrameSurface[idx]->format == frame->format) { + _movieFrameSurface[idx]->blitFrom(*frame); + } else { + // Format mis-match, so we need to convert the frame + Graphics::Surface *s = frame->convertTo(_movieFrameSurface[idx]->format, + _decoders[idx]->getPalette()); + _movieFrameSurface[idx]->blitFrom(*s); + s->free(); + delete s; } } diff --git a/engines/titanic/support/mouse_cursor.cpp b/engines/titanic/support/mouse_cursor.cpp index 5694d83dc6..d6a42823f5 100644 --- a/engines/titanic/support/mouse_cursor.cpp +++ b/engines/titanic/support/mouse_cursor.cpp @@ -63,8 +63,6 @@ CMouseCursor::CMouseCursor(CScreenManager *screenManager) : } CMouseCursor::~CMouseCursor() { - for (int idx = 0; idx < NUM_CURSORS; ++idx) - delete _cursors[idx]._videoSurface; } void CMouseCursor::loadCursorImages() { -- cgit v1.2.3 From b843b2fd3385533955a325ff8819e37ab3b0b2f0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 Jul 2016 18:27:33 -0400 Subject: TITANIC: Fix memory leak in image decoders --- engines/titanic/support/image_decoders.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/image_decoders.cpp b/engines/titanic/support/image_decoders.cpp index 4203dad97c..495d1d0982 100644 --- a/engines/titanic/support/image_decoders.cpp +++ b/engines/titanic/support/image_decoders.cpp @@ -45,6 +45,7 @@ void CJPEGDecode::decode(OSVideoSurface &surface, const CString &name) { Common::copy((byte *)convertedSurface->getPixels(), (byte *)convertedSurface->getPixels() + surface.getPitch() * surface.getHeight(), (byte *)surface._rawSurface->getPixels()); + convertedSurface->free(); delete convertedSurface; surface.unlock(); } @@ -72,6 +73,7 @@ void CTargaDecode::decode(OSVideoSurface &surface, const CString &name) { Common::copy((byte *)convertedSurface->getPixels(), (byte *)convertedSurface->getPixels() + surface.getPitch() * surface.getHeight(), (byte *)surface._rawSurface->getPixels()); + convertedSurface->free(); delete convertedSurface; surface.unlock(); } -- cgit v1.2.3 From 6331e3814a7fe501056ec5a356924b9c4c40c16f Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 Jul 2016 19:19:06 -0400 Subject: TITANIC: Fleshing out & fixes for video surface blit methods --- engines/titanic/support/video_surface.cpp | 42 ++++++++++++++++++++----------- engines/titanic/support/video_surface.h | 5 ++-- 2 files changed, 31 insertions(+), 16 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index 0429ed4257..4169a80b4b 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -32,7 +32,8 @@ int CVideoSurface::_videoSurfaceCounter = 0; CVideoSurface::CVideoSurface(CScreenManager *screenManager) : _screenManager(screenManager), _rawSurface(nullptr), _movie(nullptr), _pendingLoad(false), _transBlitFlag(false), _fastBlitFlag(false), - _movieFrameSurface(nullptr), _transparencyMode(TRANS_DEFAULT), _field48(0), _field50(1) { + _movieFrameSurface(nullptr), _transparencyMode(TRANS_DEFAULT), + _field48(0), _field50(1), _lockCount(0) { _videoSurfaceNum = _videoSurfaceCounter++; } @@ -52,10 +53,10 @@ void CVideoSurface::blitFrom(const Point &destPos, CVideoSurface *src, const Rec Rect srcBounds, destBounds; clipBounds(srcBounds, destBounds, src, srcRect, &destPos); - if (_transBlitFlag) - transBlitRect(srcBounds, destBounds, src); + if (src->_transBlitFlag) + blitRect2(srcBounds, destBounds, src); else - blitRect(srcBounds, destBounds, src); + blitRect1(srcBounds, destBounds, src); } } @@ -128,25 +129,38 @@ void CVideoSurface::clipBounds(Rect &srcRect, Rect &destRect, error("Invalid rect"); } -void CVideoSurface::blitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) { +void CVideoSurface::blitRect1(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) { src->lock(); lock(); - if (_fastBlitFlag) { - _rawSurface->transBlitFrom(*src->_rawSurface, srcRect, destRect, - getTransparencyColor()); - return; + if (src->_fastBlitFlag) { + _rawSurface->blitFrom(*src->_rawSurface, srcRect, Point(destRect.left, destRect.top)); + } else if (getMovieFrameSurface()) { + movieBlitRect(srcRect, destRect, src); + } else { + _rawSurface->transBlitFrom(*src->_rawSurface, srcRect, destRect, src->getTransparencyColor()); } - // TODO - src->unlock(); unlock(); } -void CVideoSurface::transBlitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) { - // TODO: Do it like the original does it - blitRect(srcRect, destRect, src); +void CVideoSurface::blitRect2(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) { + if (getMovieFrameSurface()) { + movieBlitRect(srcRect, destRect, src); + } else { + src->lock(); + lock(); + + _rawSurface->blitFrom(*src->_rawSurface, srcRect, Point(destRect.left, destRect.top)); + + src->unlock(); + unlock(); + } +} + +void CVideoSurface::movieBlitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src) { + // TODO } uint CVideoSurface::getTransparencyColor() { diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index a0e74b5b3d..040161fe8e 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -55,8 +55,9 @@ private: void clipBounds(Rect &srcRect, Rect &destRect, CVideoSurface *srcSurface, const Rect *subRect = nullptr, const Point *destPos = nullptr); - void blitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src); - void transBlitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src); + void blitRect1(const Rect &srcRect, const Rect &destRect, CVideoSurface *src); + void blitRect2(const Rect &srcRect, const Rect &destRect, CVideoSurface *src); + void movieBlitRect(const Rect &srcRect, const Rect &destRect, CVideoSurface *src); protected: static int _videoSurfaceCounter; protected: -- cgit v1.2.3 From 87379442ffb497352915b058b100b688d96a98e9 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 Jul 2016 21:47:19 -0400 Subject: TITANIC: Fix scanning for files not to free resources --- engines/titanic/support/files_manager.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/files_manager.cpp b/engines/titanic/support/files_manager.cpp index c415731f16..1d2b1d9a8e 100644 --- a/engines/titanic/support/files_manager.cpp +++ b/engines/titanic/support/files_manager.cpp @@ -86,14 +86,16 @@ bool CFilesManager::scanForFile(const CString &name) { fname += ".st"; } + // Return true if the file exists + if (fileExists(fname)) + return true; + + // Couldn't find file. Start by calling the game manager's viewChange + // method, which handles all active scene objects freeing their resources if (_gameManager) _gameManager->viewChange(); - // The original had a bunch of code here handling determining - // which asset path, if any, the filename was present for, - // and storing the "active asset path" it was found on. - // This is redundant for ScummVM, which takes care of the paths - return fileExists(fname); + return false; } void CFilesManager::loadDrive() { -- cgit v1.2.3 From 18e06f727ab55eb232a8f97c09cb9950b29eeef8 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 Jul 2016 21:51:50 -0400 Subject: TITANIC: Fix loading of movies with only a single video track --- engines/titanic/support/avi_surface.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp index b685fa8cce..7779baf2ff 100644 --- a/engines/titanic/support/avi_surface.cpp +++ b/engines/titanic/support/avi_surface.cpp @@ -74,6 +74,7 @@ AVISurface::AVISurface(const CResourceKey &key) { ++_streamCount; } else { delete decoder2; + _decoders[1] = nullptr; } } -- cgit v1.2.3 From 2ea4116e0ac29c73cad891cb194e16ba645786fa Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 18 Jul 2016 22:32:28 -0400 Subject: TITANIC: gcc compilation fixes --- engines/titanic/support/avi_surface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h index f74f6a808e..32db925d7a 100644 --- a/engines/titanic/support/avi_surface.h +++ b/engines/titanic/support/avi_surface.h @@ -84,7 +84,7 @@ public: double _frameRate; public: AVISurface(const CResourceKey &key); - ~AVISurface(); + virtual ~AVISurface(); /** * Start playing the loaded AVI video -- cgit v1.2.3 From d5bf17e73ff9533d2f54588622048ab755f4151b Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 20 Jul 2016 07:38:13 -0400 Subject: TITANIC: Add movie _handled flag, simplify frame timinig code --- engines/titanic/support/avi_surface.cpp | 7 +++++-- engines/titanic/support/avi_surface.h | 5 +++++ engines/titanic/support/movie.cpp | 30 ++++++------------------------ engines/titanic/support/movie.h | 9 +-------- 4 files changed, 17 insertions(+), 34 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp index 7779baf2ff..38bccafa89 100644 --- a/engines/titanic/support/avi_surface.cpp +++ b/engines/titanic/support/avi_surface.cpp @@ -260,10 +260,13 @@ int AVISurface::getFrame() const { return _decoders[0]->getCurFrame(); } +bool AVISurface::isFrameReady() const { + return _decoders[0]->needsUpdate() && (!_decoders[1] || _decoders[1]->needsUpdate()); +} + bool AVISurface::renderFrame() { // Check there's a frame ready for display - assert(_videoSurface); - if (!_decoders[0]->needsUpdate() || (_decoders[1] && !_decoders[1]->needsUpdate())) + if (!isFrameReady()) return false; // Decode each decoder's video stream into the appropriate surface diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h index 32db925d7a..dfd4c59267 100644 --- a/engines/titanic/support/avi_surface.h +++ b/engines/titanic/support/avi_surface.h @@ -162,6 +162,11 @@ public: * Duplicates the secondary frame, if the movie has a second video track */ Graphics::ManagedSurface *duplicateSecondaryFrame() const; + + /** + * Returns true if a frame is ready to be rendered + */ + bool isFrameReady() const; }; } // End of namespace Titanic diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index b98a5b57a1..2943ee1a84 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -36,7 +36,7 @@ namespace Titanic { CMovieList *CMovie::_playingMovies; CVideoSurface *CMovie::_movieSurface; -CMovie::CMovie() : ListItem(), _state(MSTATE_0), _field10(0), +CMovie::CMovie() : ListItem(), _handled(false), _field10(0), _field14(0) { } @@ -84,9 +84,6 @@ OSMovie::OSMovie(const CResourceKey &name, CVideoSurface *surface) : _field24 = 0; _field28 = 0; _field2C = 0; - _ticksStart = 0; - _frameTime1 = 0; - _frameTime2 = 17066; surface->resize(_aviSurface.getWidth(), _aviSurface.getHeight()); _aviSurface.setVideoSurface(surface); @@ -165,25 +162,13 @@ void OSMovie::setFrame(uint frameNumber) { bool OSMovie::handleEvents(CMovieEventList &events) { if (!_aviSurface._isPlaying) return false; - - int time = (g_vm->_events->getTicksCount() + ((_ticksStart << 24) - _ticksStart)) << 8; - if (time < _frameTime1) + if (!_aviSurface.isFrameReady()) return _aviSurface._isPlaying; - if (!_field14 && (time - _frameTime1) > (_frameTime2 * 2)) - _frameTime1 = time; - - _frameTime1 += _frameTime2; - _aviSurface.handleEvents(events); - _videoSurface->setMovieFrameSurface(_aviSurface.getSecondarySurface()); - - if (_field14) { - while (_frameTime1 >= time && events.empty()) { - _aviSurface.handleEvents(events); - _videoSurface->setMovieFrameSurface(_aviSurface.getSecondarySurface()); - - _frameTime1 += _frameTime2; - } + // Handle updating the frame + while (_aviSurface.isFrameReady()) { + _aviSurface.handleEvents(events); + _videoSurface->setMovieFrameSurface(_aviSurface.getSecondarySurface()); } return _aviSurface._isPlaying; @@ -202,9 +187,6 @@ int OSMovie::getFrame() const { } void OSMovie::movieStarted() { - _frameTime1 = _frameTime2 = 256000.0 / _aviSurface._frameRate; - _ticksStart = g_vm->_events->getTicksCount(); - if (_aviSurface._hasAudio) _aviSurface._soundManager->movieStarted(); diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index b6c2a09667..feb320f0b2 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -32,10 +32,6 @@ namespace Titanic { -enum MovieState { - MSTATE_0 = 0, MSTATE_1 = 1 -}; - class CGameObject; class CMovie; class CSoundManager; @@ -52,7 +48,7 @@ protected: */ void addToPlayingMovies(); public: - MovieState _state; + bool _handled; int _field10; int _field14; public: @@ -158,9 +154,6 @@ private: int _field24; int _field28; int _field2C; - int _ticksStart; - int _frameTime1; - int _frameTime2; private: /** * Called when a movie is started playing -- cgit v1.2.3 From c5792fce4bcf8a4e2e89d83242a248a56f579bc6 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 20 Jul 2016 07:56:26 -0400 Subject: TITANIC: Clarify movie/surface has frame fields & variables --- engines/titanic/support/movie.cpp | 13 ++++++++----- engines/titanic/support/movie.h | 7 +++++-- engines/titanic/support/video_surface.cpp | 12 ++++++------ engines/titanic/support/video_surface.h | 7 +++++-- 4 files changed, 24 insertions(+), 15 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 2943ee1a84..3856c44e7f 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -36,7 +36,7 @@ namespace Titanic { CMovieList *CMovie::_playingMovies; CVideoSurface *CMovie::_movieSurface; -CMovie::CMovie() : ListItem(), _handled(false), _field10(0), +CMovie::CMovie() : ListItem(), _handled(false), _hasVideoFrame(false), _field14(0) { } @@ -67,9 +67,9 @@ bool CMovie::isActive() const { return _playingMovies->contains(this); } -bool CMovie::get10() { - if (_field10) { - _field10 = 0; +bool CMovie::hasVideoFrame() { + if (_hasVideoFrame) { + _hasVideoFrame = 0; return true; } else { return false; @@ -171,6 +171,9 @@ bool OSMovie::handleEvents(CMovieEventList &events) { _videoSurface->setMovieFrameSurface(_aviSurface.getSecondarySurface()); } + // Flag there's a video frame + _hasVideoFrame = true; + return _aviSurface._isPlaying; } @@ -192,7 +195,7 @@ void OSMovie::movieStarted() { // Register the movie in the playing list addToPlayingMovies(); - _field10 = 1; + _hasVideoFrame = true; } void OSMovie::setFrameRate(double rate) { diff --git a/engines/titanic/support/movie.h b/engines/titanic/support/movie.h index feb320f0b2..2a7d589194 100644 --- a/engines/titanic/support/movie.h +++ b/engines/titanic/support/movie.h @@ -49,7 +49,7 @@ protected: void addToPlayingMovies(); public: bool _handled; - int _field10; + bool _hasVideoFrame; int _field14; public: static CMovieList *_playingMovies; @@ -143,7 +143,10 @@ public: */ bool isActive() const; - bool get10(); + /** + * Returns true if there's a video frame + */ + bool hasVideoFrame(); }; class OSMovie : public CMovie { diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index 4169a80b4b..49388b64d8 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -33,7 +33,7 @@ CVideoSurface::CVideoSurface(CScreenManager *screenManager) : _screenManager(screenManager), _rawSurface(nullptr), _movie(nullptr), _pendingLoad(false), _transBlitFlag(false), _fastBlitFlag(false), _movieFrameSurface(nullptr), _transparencyMode(TRANS_DEFAULT), - _field48(0), _field50(1), _lockCount(0) { + _field48(0), _hasFrame(true), _lockCount(0) { _videoSurfaceNum = _videoSurfaceCounter++; } @@ -170,12 +170,12 @@ uint CVideoSurface::getTransparencyColor() { return val; } -bool CVideoSurface::proc45() { - if (_field50) { - _field50 = 0; +bool CVideoSurface::hasFrame() { + if (_hasFrame) { + _hasFrame = false; return true; } else if (_movie) { - return _movie->get10(); + return _movie->hasVideoFrame(); } else { return false; } @@ -519,7 +519,7 @@ bool OSVideoSurface::loadIfReady() { if (hasSurface()) { return true; } else if (_pendingLoad) { - _field50 = 1; + _hasFrame = true; load(); return true; } else { diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index 040161fe8e..0e777bac1e 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -67,7 +67,7 @@ protected: Graphics::ManagedSurface *_movieFrameSurface; int _field48; int _videoSurfaceNum; - int _field50; + bool _hasFrame; int _lockCount; public: CMovie *_movie; @@ -257,7 +257,10 @@ public: */ virtual void transPixelate() = 0; - virtual bool proc45(); + /** + * Returns true if there's a frame to display on the video surface + */ + virtual bool hasFrame(); /** * Duplicates movie frame surface -- cgit v1.2.3 From a13134b38d1400bfc6746657faf87907f9575e80 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 20 Jul 2016 13:44:19 -0400 Subject: TITANIC: Clarify CVideoSurface _field48 as _freeMovieSurface --- engines/titanic/support/video_surface.cpp | 5 ++++- engines/titanic/support/video_surface.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/video_surface.cpp b/engines/titanic/support/video_surface.cpp index 49388b64d8..594f660937 100644 --- a/engines/titanic/support/video_surface.cpp +++ b/engines/titanic/support/video_surface.cpp @@ -33,7 +33,7 @@ CVideoSurface::CVideoSurface(CScreenManager *screenManager) : _screenManager(screenManager), _rawSurface(nullptr), _movie(nullptr), _pendingLoad(false), _transBlitFlag(false), _fastBlitFlag(false), _movieFrameSurface(nullptr), _transparencyMode(TRANS_DEFAULT), - _field48(0), _hasFrame(true), _lockCount(0) { + _freeMovieSurface(DisposeAfterUse::NO), _hasFrame(true), _lockCount(0) { _videoSurfaceNum = _videoSurfaceCounter++; } @@ -41,6 +41,9 @@ CVideoSurface::~CVideoSurface() { if (_ddSurface) _videoSurfaceCounter -= freeSurface(); --_videoSurfaceCounter; + + if (_freeMovieSurface == DisposeAfterUse::YES) + delete _movieFrameSurface; } void CVideoSurface::setSurface(CScreenManager *screenManager, DirectDrawSurface *surface) { diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index 0e777bac1e..1f3a0fa2b3 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -65,7 +65,7 @@ protected: Graphics::ManagedSurface *_rawSurface; bool _pendingLoad; Graphics::ManagedSurface *_movieFrameSurface; - int _field48; + DisposeAfterUse::Flag _freeMovieSurface; int _videoSurfaceNum; bool _hasFrame; int _lockCount; -- cgit v1.2.3 From 21e4d6686f515e70fce1ee177388b5d3bc7a4d61 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Fri, 22 Jul 2016 21:46:32 -0400 Subject: TITANIC: Beginnings of Continue Save dialog --- engines/titanic/support/image.cpp | 113 ++++++++------------------------------ engines/titanic/support/image.h | 49 ++--------------- 2 files changed, 29 insertions(+), 133 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/image.cpp b/engines/titanic/support/image.cpp index cabdd64cf3..1e936b6940 100644 --- a/engines/titanic/support/image.cpp +++ b/engines/titanic/support/image.cpp @@ -20,102 +20,37 @@ * */ -#include "common/file.h" #include "titanic/support/image.h" +#include "titanic/titanic.h" +#include "image/bmp.h" namespace Titanic { -BITMAPINFOHEADER::BITMAPINFOHEADER() { - _biSize = 0; - _biWidth = 0; - _biHeight = 0; - _biPlanes = 0; - _biBitCount = 0; - _biCompression = 0; - _biSizeImage = 0; - _biXPelsPerMeter = 0; - _biYPelsPerMeter = 0; - _biClrUsed = 0; - _biClrImportant = 0; -} - -/*------------------------------------------------------------------------*/ - -RGBQuad::RGBQuad() : _rgbRed(0), _rgbGreen(0), _rgbBlue(0), _rgbReserved(0) {} - -/*------------------------------------------------------------------------*/ - -Image::Image() { - _bitmapInfo = nullptr; - _bits = nullptr; - _flag = true; - - set(16, 16); -} - -void Image::proc6() { - -} - -void Image::set(int width, int height) { - delete _bitmapInfo; - if (_flag && _bitmapInfo) - delete[] _bits; - - _bitmapInfo = new tagBITMAPINFO; - _bits = new byte[(width + 3) & 0xFFFC * height]; - - tagBITMAPINFO &bi = *_bitmapInfo; - bi._bmiHeader._biWidth = width; - bi._bmiHeader._biHeight = height; - bi._bmiHeader._biPlanes = 1; - bi._bmiHeader._biBitCount = 8; -} - -void Image::proc8() { - -} - -bool Image::loadResource(const Common::String &name) { - // This method is hardcoded for the Titanic splash screen resource - assert(name == "TITANIC"); - - Common::File f; - if (!f.open("ST.exe")) - return false; - - // The ST.exe executable has a bitmap called "TITANIC". Since we can't use - // the Windows FindResource function in ScummVM, this is hardcoded for now - f.seek(0x29B660); - uint size = f.readUint32LE(); - if (size != 40) - return false; - - loadBitmap(f); - - return true; -} - -void Image::proc10() { - -} - -void Image::draw() { - +void Image::load(const CString &resName) { + Common::SeekableReadStream *stream = g_vm->_filesManager->getResource(resName); + loadBitmap(*stream); + delete stream; } void Image::loadBitmap(Common::SeekableReadStream &s) { - _bitmapInfo->_bmiHeader._biWidth = s.readUint32LE(); - _bitmapInfo->_bmiHeader._biHeight = s.readUint32LE(); - _bitmapInfo->_bmiHeader._biPlanes = s.readUint16LE(); - _bitmapInfo->_bmiHeader._biBitCount = s.readUint16LE(); - _bitmapInfo->_bmiHeader._biCompression = s.readUint32LE(); - _bitmapInfo->_bmiHeader._biSizeImage = s.readUint32LE(); - _bitmapInfo->_bmiHeader._biXPelsPerMeter = s.readUint32LE(); - _bitmapInfo->_bmiHeader._biYPelsPerMeter = s.readUint32LE(); - _bitmapInfo->_bmiHeader._biClrUsed = s.readUint32LE(); - _bitmapInfo->_bmiHeader._biClrImportant = s.readUint32LE(); - + ::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 byte *palette = decoder.getPalette(); + Graphics::Surface *surface = src->convertTo(scrFormat, palette); + create(surface->w, surface->h, scrFormat); + blitFrom(*surface); + + surface->free(); + delete surface; + } } } // End of namespace Titanic diff --git a/engines/titanic/support/image.h b/engines/titanic/support/image.h index 9030e81ad7..9876f15c40 100644 --- a/engines/titanic/support/image.h +++ b/engines/titanic/support/image.h @@ -23,58 +23,19 @@ #ifndef TITANIC_IMAGE_H #define TITANIC_IMAGE_H -#include "common/scummsys.h" -#include "common/array.h" +#include "common/stream.h" +#include "graphics/managed_surface.h" +#include "titanic/support/string.h" namespace Titanic { -struct BITMAPINFOHEADER { - int _biSize; - int _biWidth; - int _biHeight; - int _biPlanes; - int _biBitCount; - int _biCompression; - int _biSizeImage; - int _biXPelsPerMeter; - int _biYPelsPerMeter; - int _biClrUsed; - int _biClrImportant; - - BITMAPINFOHEADER(); -}; - -struct RGBQuad { - byte _rgbRed; - byte _rgbGreen; - byte _rgbBlue; - byte _rgbReserved; - - RGBQuad(); -}; - -struct tagBITMAPINFO { - BITMAPINFOHEADER _bmiHeader; - RGBQuad _bmiColors[256]; -}; - -class Image { +class Image : public Graphics::ManagedSurface { private: void loadBitmap(Common::SeekableReadStream &s); public: - tagBITMAPINFO *_bitmapInfo; - byte *_bits; - bool _flag; -public: - Image(); virtual ~Image() {} - virtual void proc6(); - virtual void set(int width, int height); - virtual void proc8(); - virtual bool loadResource(const Common::String &name); - virtual void proc10(); - virtual void draw(); + void load(const CString &resName); }; } // End of namespace Titanic -- cgit v1.2.3 From 71b76acc630af3537b7379be24d59d38326f2606 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 23 Jul 2016 11:38:39 -0400 Subject: TITANIC: Fixes and simplification of AVISurface --- engines/titanic/support/avi_surface.cpp | 58 ++++++++++++++++++--------------- engines/titanic/support/avi_surface.h | 12 ++++--- engines/titanic/support/movie.cpp | 12 +++---- 3 files changed, 45 insertions(+), 37 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp index 38bccafa89..c64edca7a4 100644 --- a/engines/titanic/support/avi_surface.cpp +++ b/engines/titanic/support/avi_surface.cpp @@ -54,11 +54,8 @@ static bool secondaryTrackSelect(bool isVideo, int trackCounter) { AVISurface::AVISurface(const CResourceKey &key) { _videoSurface = nullptr; - _currentPos = 0; - _priorFrame = 0; _streamCount = 0; _movieFrameSurface[0] = _movieFrameSurface[1] = nullptr; - _isPlaying = false; // Create a decoder for the audio (if any) and primary video track _decoders[0] = new AVIDecoder(Audio::Mixer::kPlainSoundType, primaryTrackSelect); @@ -122,14 +119,13 @@ bool AVISurface::play(int startFrame, int endFrame, int initialFrame, uint flags _movieRangeInfo.push_back(info); if (_movieRangeInfo.size() == 1) { - return changeFrame(initialFrame); + return startAtFrame(initialFrame); } else { return true; } } void AVISurface::stop() { - _isPlaying = false; _decoders[0]->stop(); if (_decoders[1]) _decoders[1]->stop(); @@ -137,37 +133,46 @@ void AVISurface::stop() { _movieRangeInfo.destroyContents(); } -bool AVISurface::changeFrame(int frameNumber) { - if (_isPlaying) +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; + // Get the initial frame seekToFrame(frameNumber); renderFrame(); - _isPlaying = true; + // Start the playback + _decoders[0]->start(); + if (_decoders[1]) + _decoders[1]->start(); + return true; } void AVISurface::seekToFrame(uint frameNumber) { - _decoders[0]->seekToFrame(frameNumber); - if (_decoders[1]) - _decoders[1]->seekToFrame(frameNumber); + if ((int)frameNumber != getFrame()) { + _decoders[0]->seekToFrame(frameNumber); + if (_decoders[1]) + _decoders[1]->seekToFrame(frameNumber); + } - _priorFrame = frameNumber; + renderFrame(); } bool AVISurface::handleEvents(CMovieEventList &events) { - if (!_isPlaying) + if (!isPlaying()) return true; CMovieRangeInfo *info = _movieRangeInfo.front(); - _currentPos += info->_isReversed ? -1 : 1; - if ((info->_isReversed && _currentPos < info->_endFrame) || - (!info->_isReversed && _currentPos > info->_endFrame)) { + int currentPos = getFrame(); + + if ((info->_isReversed && currentPos < info->_endFrame) || + (!info->_isReversed && currentPos > info->_endFrame)) { if (info->_isFlag1) { info->getMovieEnd(events); _movieRangeInfo.remove(info); @@ -179,19 +184,20 @@ bool AVISurface::handleEvents(CMovieEventList &events) { } else { // Not empty, so move onto new first one info = _movieRangeInfo.front(); - _currentPos = info->_startFrame; + currentPos = info->_startFrame; } } else { - _currentPos = info->_startFrame; + currentPos = info->_startFrame; } } - if (_isPlaying) { - // SInce movie ranges can change the position in the movie, - // ensure the decoder is kept in sync - seekToFrame(_currentPos); - - info->getMovieFrame(events, _currentPos); + if (isPlaying()) { + if (currentPos != getFrame()) + // The frame has been changed, so move to new position + seekToFrame(currentPos); + + // Get any events for the given position + info->getMovieFrame(events, currentPos); return renderFrame(); } else { return false; @@ -245,7 +251,7 @@ uint AVISurface::getHeight() const { void AVISurface::setFrame(int frameNumber) { // If playback was in process, stop it - if (_isPlaying) + if (isPlaying()) stop(); // Ensure the frame number is valid @@ -307,7 +313,7 @@ bool AVISurface::addEvent(int frameNumber, CGameObject *obj) { me->_gameObject = obj; tail->addEvent(me); - return _movieRangeInfo.size() == 1 && frameNumber == _priorFrame; + return _movieRangeInfo.size() == 1 && frameNumber == getFrame(); } return false; diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h index dfd4c59267..4372757bc6 100644 --- a/engines/titanic/support/avi_surface.h +++ b/engines/titanic/support/avi_surface.h @@ -52,8 +52,6 @@ class AVISurface { private: AVIDecoder *_decoders[2]; CVideoSurface *_videoSurface; - int _currentPos; - int _priorFrame; CMovieRangeInfoList _movieRangeInfo; int _streamCount; Graphics::ManagedSurface *_movieFrameSurface[2]; @@ -69,9 +67,9 @@ private: void setupDecompressor(); protected: /** - * Change the frame with ??? checking + * Start playback at the specified frame */ - virtual bool changeFrame(int frameNumber); + virtual bool startAtFrame(int frameNumber); /** * Seeks to a given frame number in the video @@ -80,7 +78,6 @@ protected: public: CSoundManager *_soundManager; bool _hasAudio; - bool _isPlaying; double _frameRate; public: AVISurface(const CResourceKey &key); @@ -106,6 +103,11 @@ public: */ virtual void stop(); + /** + * Return true if a video is currently playing + */ + virtual bool isPlaying() const { return _decoders[0]->isPlaying(); } + /** * Handle any movie events relevent for the frame */ diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 3856c44e7f..9dc57b897a 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -95,21 +95,21 @@ OSMovie::~OSMovie() { void OSMovie::play(uint flags, CGameObject *obj) { _aviSurface.play(flags, obj); - if (_aviSurface._isPlaying) + if (_aviSurface.isPlaying()) movieStarted(); } void OSMovie::play(uint startFrame, uint endFrame, uint flags, CGameObject *obj) { _aviSurface.play(startFrame, endFrame, flags, obj); - if (_aviSurface._isPlaying) + 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) + if (_aviSurface.isPlaying()) movieStarted(); } @@ -160,10 +160,10 @@ void OSMovie::setFrame(uint frameNumber) { } bool OSMovie::handleEvents(CMovieEventList &events) { - if (!_aviSurface._isPlaying) + if (!_aviSurface.isPlaying()) return false; if (!_aviSurface.isFrameReady()) - return _aviSurface._isPlaying; + return _aviSurface.isPlaying(); // Handle updating the frame while (_aviSurface.isFrameReady()) { @@ -174,7 +174,7 @@ bool OSMovie::handleEvents(CMovieEventList &events) { // Flag there's a video frame _hasVideoFrame = true; - return _aviSurface._isPlaying; + return _aviSurface.isPlaying(); } const CMovieRangeInfoList *OSMovie::getMovieRangeInfo() const { -- cgit v1.2.3 From 382ba52e332a02a49343c1ba1c2aed80dfcd5c87 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 23 Jul 2016 12:45:29 -0400 Subject: TITANIC: Fix exit crash when a movie is active --- engines/titanic/support/movie.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 9dc57b897a..33e7d33154 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -50,6 +50,15 @@ void CMovie::init() { } void CMovie::deinit() { + // Delete each movie in turn + for (CMovieList::iterator i = _playingMovies->begin(); i != _playingMovies->end(); ) { + // We need to increment iterator before deleting movie, + // since the CMovie destructor calls removeFromPlayingMovies + CMovie *movie = *i; + ++i; + delete movie; + } + delete _playingMovies; delete _movieSurface; } -- cgit v1.2.3 From 9e02409ef4ece6b3184c1d745106e87f3169e6ca Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 23 Jul 2016 13:15:24 -0400 Subject: TITANIC: Clarification and fixes for movie reverse and repeat flags --- engines/titanic/support/avi_surface.cpp | 23 +++++++++++++++++------ engines/titanic/support/avi_surface.h | 9 +++++++-- engines/titanic/support/movie.cpp | 2 +- engines/titanic/support/movie_range_info.cpp | 8 ++++---- engines/titanic/support/movie_range_info.h | 2 +- 5 files changed, 30 insertions(+), 14 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp index c64edca7a4..c3a720154a 100644 --- a/engines/titanic/support/avi_surface.cpp +++ b/engines/titanic/support/avi_surface.cpp @@ -103,7 +103,7 @@ bool AVISurface::play(int startFrame, int endFrame, int initialFrame, uint flags info->_startFrame = startFrame; info->_endFrame = endFrame; info->_isReversed = endFrame < startFrame; - info->_isFlag1 = flags & MOVIE_1; + info->_isRepeat = flags & MOVIE_REPEAT; if (obj) { CMovieEvent *me = new CMovieEvent(); @@ -119,6 +119,8 @@ bool AVISurface::play(int startFrame, int endFrame, int initialFrame, uint flags _movieRangeInfo.push_back(info); if (_movieRangeInfo.size() == 1) { + // First play call, so start the movie playing + setReversed(info->_isReversed); return startAtFrame(initialFrame); } else { return true; @@ -164,6 +166,12 @@ void AVISurface::seekToFrame(uint frameNumber) { renderFrame(); } +void AVISurface::setReversed(bool isReversed) { + _decoders[0]->setReverse(isReversed); + if (_decoders[1]) + _decoders[1]->setReverse(isReversed); +} + bool AVISurface::handleEvents(CMovieEventList &events) { if (!isPlaying()) return true; @@ -173,7 +181,9 @@ bool AVISurface::handleEvents(CMovieEventList &events) { if ((info->_isReversed && currentPos < info->_endFrame) || (!info->_isReversed && currentPos > info->_endFrame)) { - if (info->_isFlag1) { + if (info->_isRepeat) { + currentPos = info->_startFrame; + } else { info->getMovieEnd(events); _movieRangeInfo.remove(info); delete info; @@ -186,15 +196,15 @@ bool AVISurface::handleEvents(CMovieEventList &events) { info = _movieRangeInfo.front(); currentPos = info->_startFrame; } - } else { - currentPos = info->_startFrame; } } if (isPlaying()) { - if (currentPos != getFrame()) + if (currentPos != getFrame()) { // The frame has been changed, so move to new position + setReversed(info->_isReversed); seekToFrame(currentPos); + } // Get any events for the given position info->getMovieFrame(events, currentPos); @@ -267,7 +277,8 @@ int AVISurface::getFrame() const { } bool AVISurface::isFrameReady() const { - return _decoders[0]->needsUpdate() && (!_decoders[1] || _decoders[1]->needsUpdate()); + return _decoders[0]->needsUpdate() && + (!_decoders[1] || _decoders[1]->needsUpdate()); } bool AVISurface::renderFrame() { diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h index 4372757bc6..77186edeb4 100644 --- a/engines/titanic/support/avi_surface.h +++ b/engines/titanic/support/avi_surface.h @@ -34,7 +34,7 @@ class CSoundManager; class CVideoSurface; enum MovieFlag { - MOVIE_1 = 1, MOVIE_STOP_PREVIOUS = 2, MOVIE_NO_OBJECT = 4, + MOVIE_REPEAT = 1, MOVIE_STOP_PREVIOUS = 2, MOVIE_NO_OBJECT = 4, MOVIE_REVERSE = 8, MOVIE_GAMESTATE = 0x10 }; @@ -69,7 +69,12 @@ protected: /** * Start playback at the specified frame */ - virtual bool startAtFrame(int frameNumber); + bool startAtFrame(int frameNumber); + + /** + * Sets whether the movie is playing in reverse + */ + void setReversed(bool isReversed); /** * Seeks to a given frame number in the video diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index 33e7d33154..eba878e875 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -175,7 +175,7 @@ bool OSMovie::handleEvents(CMovieEventList &events) { return _aviSurface.isPlaying(); // Handle updating the frame - while (_aviSurface.isFrameReady()) { + while (_aviSurface.isPlaying() && _aviSurface.isFrameReady()) { _aviSurface.handleEvents(events); _videoSurface->setMovieFrameSurface(_aviSurface.getSecondarySurface()); } diff --git a/engines/titanic/support/movie_range_info.cpp b/engines/titanic/support/movie_range_info.cpp index 4c62539864..634ab1cc62 100644 --- a/engines/titanic/support/movie_range_info.cpp +++ b/engines/titanic/support/movie_range_info.cpp @@ -38,7 +38,7 @@ CMovieRangeInfo::CMovieRangeInfo(const CMovieRangeInfo *src) : ListItem() { _endFrame = src->_endFrame; _initialFrame = src->_initialFrame; _isReversed = src->_isReversed; - _isFlag1 = src->_isFlag1; + _isRepeat = src->_isRepeat; // Duplicate the events list for (CMovieEventList::const_iterator i = _events.begin(); @@ -52,7 +52,7 @@ void CMovieRangeInfo::save(SimpleFile *file, int indent) { file->writeNumberLine(_startFrame, indent + 1); file->writeNumberLine(_endFrame, indent + 1); file->writeNumberLine(_initialFrame, indent + 1); - file->writeNumberLine(_isFlag1, indent + 1); + file->writeNumberLine(_isRepeat, indent + 1); file->writeNumberLine(_isReversed, indent + 1); _events.save(file, indent + 1); } @@ -63,7 +63,7 @@ void CMovieRangeInfo::load(SimpleFile *file) { _startFrame = file->readNumber(); _endFrame = file->readNumber(); _initialFrame = file->readNumber(); - _isFlag1 = file->readNumber(); + _isRepeat = file->readNumber(); _isReversed = file->readNumber(); _events.load(file); } @@ -88,7 +88,7 @@ void CMovieRangeInfo::getMovieFrame(CMovieEventList &list, int frameNumber) { void CMovieRangeInfo::process(CGameObject *owner) { int flags = 0; if (_endFrame) - flags |= MOVIE_1; + flags |= MOVIE_REPEAT; if (_startFrame) flags |= MOVIE_REVERSE; diff --git a/engines/titanic/support/movie_range_info.h b/engines/titanic/support/movie_range_info.h index b8186e6f7e..6b13fbadb5 100644 --- a/engines/titanic/support/movie_range_info.h +++ b/engines/titanic/support/movie_range_info.h @@ -38,7 +38,7 @@ public: int _endFrame; int _initialFrame; bool _isReversed; - bool _isFlag1; + bool _isRepeat; CMovieEventList _events; public: CMovieRangeInfo(); -- cgit v1.2.3 From 00c568e17572ce2ac4e9c97c21c00a734951ae9a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 23 Jul 2016 14:39:07 -0400 Subject: TITANIC: Fix for movie play ranges that end at the AVI file end --- engines/titanic/support/avi_surface.cpp | 46 +++++++++++++++++++-------------- engines/titanic/support/avi_surface.h | 8 +++--- engines/titanic/support/movie.cpp | 4 +-- 3 files changed, 33 insertions(+), 25 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp index c3a720154a..6507c8bbd4 100644 --- a/engines/titanic/support/avi_surface.cpp +++ b/engines/titanic/support/avi_surface.cpp @@ -57,6 +57,12 @@ AVISurface::AVISurface(const CResourceKey &key) { _streamCount = 0; _movieFrameSurface[0] = _movieFrameSurface[1] = nullptr; + // Reset current frame. We need to keep track of frames separately from the decoders, + // 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; + _isReversed = false; + // Create a decoder for the audio (if any) and primary video track _decoders[0] = new AVIDecoder(Audio::Mixer::kPlainSoundType, primaryTrackSelect); if (!_decoders[0]->loadFile(key.getString())) @@ -103,6 +109,7 @@ bool AVISurface::play(int startFrame, int endFrame, int initialFrame, uint flags info->_startFrame = startFrame; info->_endFrame = endFrame; info->_isReversed = endFrame < startFrame; + info->_initialFrame = 0; info->_isRepeat = flags & MOVIE_REPEAT; if (obj) { @@ -161,6 +168,8 @@ void AVISurface::seekToFrame(uint frameNumber) { _decoders[0]->seekToFrame(frameNumber); if (_decoders[1]) _decoders[1]->seekToFrame(frameNumber); + + _currentFrame = (int)frameNumber; } renderFrame(); @@ -170,6 +179,8 @@ void AVISurface::setReversed(bool isReversed) { _decoders[0]->setReverse(isReversed); if (_decoders[1]) _decoders[1]->setReverse(isReversed); + + _isReversed = isReversed; } bool AVISurface::handleEvents(CMovieEventList &events) { @@ -177,12 +188,13 @@ bool AVISurface::handleEvents(CMovieEventList &events) { return true; CMovieRangeInfo *info = _movieRangeInfo.front(); - int currentPos = getFrame(); + _currentFrame += _isReversed ? -1 : 1; - if ((info->_isReversed && currentPos < info->_endFrame) || - (!info->_isReversed && currentPos > info->_endFrame)) { + int newFrame = _currentFrame; + if ((info->_isReversed && newFrame <= info->_endFrame) || + (!info->_isReversed && newFrame >= info->_endFrame)) { if (info->_isRepeat) { - currentPos = info->_startFrame; + newFrame = info->_startFrame; } else { info->getMovieEnd(events); _movieRangeInfo.remove(info); @@ -194,20 +206,20 @@ bool AVISurface::handleEvents(CMovieEventList &events) { } else { // Not empty, so move onto new first one info = _movieRangeInfo.front(); - currentPos = info->_startFrame; + newFrame = info->_startFrame; } } } if (isPlaying()) { - if (currentPos != getFrame()) { + if (newFrame != getFrame()) { // The frame has been changed, so move to new position setReversed(info->_isReversed); - seekToFrame(currentPos); + seekToFrame(newFrame); } // Get any events for the given position - info->getMovieFrame(events, currentPos); + info->getMovieFrame(events, newFrame); return renderFrame(); } else { return false; @@ -272,18 +284,13 @@ void AVISurface::setFrame(int frameNumber) { renderFrame(); } -int AVISurface::getFrame() const { - return _decoders[0]->getCurFrame(); -} - -bool AVISurface::isFrameReady() const { - return _decoders[0]->needsUpdate() && - (!_decoders[1] || _decoders[1]->needsUpdate()); +bool AVISurface::isNextFrame() const { + return _decoders[0]->getTimeToNextFrame() == 0; } bool AVISurface::renderFrame() { // Check there's a frame ready for display - if (!isFrameReady()) + if (!_decoders[0]->needsUpdate()) return false; // Decode each decoder's video stream into the appropriate surface @@ -331,10 +338,9 @@ bool AVISurface::addEvent(int frameNumber, CGameObject *obj) { } void AVISurface::setFrameRate(double rate) { - if (rate >= 0.0 && rate <= 100.0) { - _frameRate = rate; - warning("TODO: Frame rate set to %d yet to be implemented", (int)rate); - } + _decoders[0]->setRate(Common::Rational(rate)); + if (_decoders[1]) + _decoders[1]->setRate(Common::Rational(rate)); } Graphics::ManagedSurface *AVISurface::getSecondarySurface() { diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h index 77186edeb4..53e2aae6fc 100644 --- a/engines/titanic/support/avi_surface.h +++ b/engines/titanic/support/avi_surface.h @@ -55,6 +55,8 @@ private: CMovieRangeInfoList _movieRangeInfo; int _streamCount; Graphics::ManagedSurface *_movieFrameSurface[2]; + bool _isReversed; + int _currentFrame; private: /** * Render a frame to the video surface @@ -141,7 +143,7 @@ public: /** * Gets the current frame */ - int getFrame() const; + int getFrame() const { return _currentFrame; } /** * Add a movie event @@ -171,9 +173,9 @@ public: Graphics::ManagedSurface *duplicateSecondaryFrame() const; /** - * Returns true if a frame is ready to be rendered + * Returns true if it's time for the next */ - bool isFrameReady() const; + bool isNextFrame() const; }; } // End of namespace Titanic diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp index eba878e875..3c935e83a8 100644 --- a/engines/titanic/support/movie.cpp +++ b/engines/titanic/support/movie.cpp @@ -171,11 +171,11 @@ void OSMovie::setFrame(uint frameNumber) { bool OSMovie::handleEvents(CMovieEventList &events) { if (!_aviSurface.isPlaying()) return false; - if (!_aviSurface.isFrameReady()) + if (!_aviSurface.isNextFrame()) return _aviSurface.isPlaying(); // Handle updating the frame - while (_aviSurface.isPlaying() && _aviSurface.isFrameReady()) { + while (_aviSurface.isPlaying() && _aviSurface.isNextFrame()) { _aviSurface.handleEvents(events); _videoSurface->setMovieFrameSurface(_aviSurface.getSecondarySurface()); } -- cgit v1.2.3 From d979dcd020d65aa0019d7a53c1dcd8b4f4a0f909 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 23 Jul 2016 17:21:38 -0400 Subject: TITANIC: Fixes for movie notification, computer game logic cleanup --- engines/titanic/support/avi_surface.h | 2 +- engines/titanic/support/files_manager.cpp | 2 +- engines/titanic/support/time_event_info.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h index 53e2aae6fc..d21182bca9 100644 --- a/engines/titanic/support/avi_surface.h +++ b/engines/titanic/support/avi_surface.h @@ -34,7 +34,7 @@ class CSoundManager; class CVideoSurface; enum MovieFlag { - MOVIE_REPEAT = 1, MOVIE_STOP_PREVIOUS = 2, MOVIE_NO_OBJECT = 4, + MOVIE_REPEAT = 1, MOVIE_STOP_PREVIOUS = 2, MOVIE_NOTIFY_OBJECT = 4, MOVIE_REVERSE = 8, MOVIE_GAMESTATE = 0x10 }; diff --git a/engines/titanic/support/files_manager.cpp b/engines/titanic/support/files_manager.cpp index 1d2b1d9a8e..04928b96d6 100644 --- a/engines/titanic/support/files_manager.cpp +++ b/engines/titanic/support/files_manager.cpp @@ -109,7 +109,7 @@ void CFilesManager::debug(CScreenManager *screenManager) { void CFilesManager::resetView() { if (_gameManager) { - _gameManager->_gameState.setMode(GSMODE_SELECTED); + _gameManager->_gameState.setMode(GSMODE_INTERACTIVE); _gameManager->initBounds(); } } diff --git a/engines/titanic/support/time_event_info.cpp b/engines/titanic/support/time_event_info.cpp index 041a01ccfb..a1922338d1 100644 --- a/engines/titanic/support/time_event_info.cpp +++ b/engines/titanic/support/time_event_info.cpp @@ -100,7 +100,7 @@ CTimeEventInfo::CTimeEventInfo() : ListItem(), _lockCounter(0), CTimeEventInfo::CTimeEventInfo(uint ticks, uint f14, uint firstDuration, uint duration, CTreeItem *target, int timerVal3, const CString &action) : ListItem(), _lockCounter(0), _field14(f14), _firstDuration(firstDuration), - _duration(duration), _target(target), _field2C(0), _field30(0), + _duration(duration), _target(target), _actionVal(0), _field2C(0), _field30(0), _timerCtr(0), _lastTimerTicks(ticks), _field3C(0), _done(false), _field44(true) { _id = _nextId++; -- cgit v1.2.3 From d690ca322c04ee2044b7502369c5cc104a0c7b76 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 23 Jul 2016 18:10:34 -0400 Subject: TITANIC: Cleanup of CTimeEventInfo class --- engines/titanic/support/time_event_info.cpp | 35 +++++++++++++++-------------- engines/titanic/support/time_event_info.h | 10 ++++----- 2 files changed, 23 insertions(+), 22 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/time_event_info.cpp b/engines/titanic/support/time_event_info.cpp index a1922338d1..1787741809 100644 --- a/engines/titanic/support/time_event_info.cpp +++ b/engines/titanic/support/time_event_info.cpp @@ -91,17 +91,17 @@ void CTimeEventInfoList::set44(uint id, uint val) { uint CTimeEventInfo::_nextId; CTimeEventInfo::CTimeEventInfo() : ListItem(), _lockCounter(0), - _field14(0), _firstDuration(0), _duration(0), _target(nullptr), + _repeated(false), _firstDuration(0), _repeatDuration(0), _target(nullptr), _actionVal(0), _field2C(0), _field30(0), _timerCtr(0), - _lastTimerTicks(0), _field3C(0), _done(false), _field44(0) { + _lastTimerTicks(0), _relativeTicks(0), _done(false), _field44(0) { _id = _nextId++; } -CTimeEventInfo::CTimeEventInfo(uint ticks, uint f14, uint firstDuration, - uint duration, CTreeItem *target, int timerVal3, const CString &action) : - ListItem(), _lockCounter(0), _field14(f14), _firstDuration(firstDuration), - _duration(duration), _target(target), _actionVal(0), _field2C(0), _field30(0), - _timerCtr(0), _lastTimerTicks(ticks), _field3C(0), _done(false), +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), _field2C(0), + _field30(0), _timerCtr(0), _lastTimerTicks(ticks), _relativeTicks(0), _done(false), _field44(true) { _id = _nextId++; } @@ -114,13 +114,13 @@ void CTimeEventInfo::save(SimpleFile *file, int indent) { targetName = _target->getName(); file->writeQuotedLine(targetName, indent); file->writeNumberLine(_id, indent); - file->writeNumberLine(_field14, indent); + file->writeNumberLine(_repeated, indent); file->writeNumberLine(_firstDuration, indent); - file->writeNumberLine(_duration, indent); + file->writeNumberLine(_repeatDuration, indent); file->writeNumberLine(_actionVal, indent); file->writeQuotedLine(_action, indent); file->writeNumberLine(_timerCtr, indent); - file->writeNumberLine(_field3C, indent); + file->writeNumberLine(_relativeTicks, indent); file->writeNumberLine(_done, indent); file->writeNumberLine(_field44, indent); } @@ -132,13 +132,13 @@ void CTimeEventInfo::load(SimpleFile *file) { if (!val) { _targetName = file->readString(); _id = file->readNumber(); - _field14 = file->readNumber(); + _repeated = file->readNumber(); _firstDuration = file->readNumber(); - _duration = file->readNumber(); + _repeatDuration = file->readNumber(); _actionVal = file->readNumber(); _action = file->readString(); _timerCtr = file->readNumber(); - _field3C = file->readNumber(); + _relativeTicks = file->readNumber(); _done = file->readNumber() != 0; _field44 = file->readNumber(); _target = nullptr; @@ -155,7 +155,7 @@ void CTimeEventInfo::postLoad(uint ticks, CProjectItem *project) { if (!_target) _done = true; - _lastTimerTicks = ticks + _field3C; + _lastTimerTicks = ticks + _relativeTicks; if (_id >= _nextId) _nextId = _id + 1; @@ -163,7 +163,7 @@ void CTimeEventInfo::postLoad(uint ticks, CProjectItem *project) { } void CTimeEventInfo::preSave(uint ticks) { - _field3C = _lastTimerTicks - ticks; + _relativeTicks = _lastTimerTicks - ticks; lock(); } @@ -176,7 +176,7 @@ bool CTimeEventInfo::update(uint ticks) { return false; if (_timerCtr) { - if (ticks > (_lastTimerTicks + _duration)) { + if (ticks > (_lastTimerTicks + _repeatDuration)) { ++_timerCtr; _lastTimerTicks = ticks; @@ -195,7 +195,8 @@ bool CTimeEventInfo::update(uint ticks) { timerMsg.execute(_target); } - if (!_field14) + if (!_repeated) + // Event is done, and can be removed return true; } } diff --git a/engines/titanic/support/time_event_info.h b/engines/titanic/support/time_event_info.h index b436f87f65..23d0d2b803 100644 --- a/engines/titanic/support/time_event_info.h +++ b/engines/titanic/support/time_event_info.h @@ -49,9 +49,9 @@ public: public: int _lockCounter; uint _id; - uint _field14; + bool _repeated; uint _firstDuration; - uint _duration; + uint _repeatDuration; CTreeItem *_target; uint _actionVal; CString _action; @@ -59,15 +59,15 @@ public: uint _field30; uint _timerCtr; uint _lastTimerTicks; - uint _field3C; + uint _relativeTicks; bool _done; uint _field44; CString _targetName; public: CLASSDEF CTimeEventInfo(); - CTimeEventInfo(uint ticks, uint f14, uint firstDuration, uint duration, - CTreeItem *target, int timerVal3, const CString &action); + CTimeEventInfo(uint ticks, bool repeated, uint firstDuration, uint repeatDuration, + CTreeItem *target, int endVal, const CString &action); /** * Save the data for the class to file -- cgit v1.2.3 From 2efee2ae8c1c4e285fe81bce66a594d9b949548a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 23 Jul 2016 19:15:26 -0400 Subject: TITANIC: Further timers cleanup --- engines/titanic/support/time_event_info.cpp | 21 ++++++++++----------- engines/titanic/support/time_event_info.h | 14 +++++++++----- 2 files changed, 19 insertions(+), 16 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/time_event_info.cpp b/engines/titanic/support/time_event_info.cpp index 1787741809..0226223f1a 100644 --- a/engines/titanic/support/time_event_info.cpp +++ b/engines/titanic/support/time_event_info.cpp @@ -76,11 +76,11 @@ void CTimeEventInfoList::stop(uint id) { } } -void CTimeEventInfoList::set44(uint id, uint val) { +void CTimeEventInfoList::setPersisent(uint id, bool flag) { for (iterator i = begin(); i != end(); ++i) { CTimeEventInfo *item = *i; if (item->_id == id) { - item->set44(val); + item->setPersisent(flag); return; } } @@ -91,18 +91,17 @@ void CTimeEventInfoList::set44(uint id, uint val) { uint CTimeEventInfo::_nextId; CTimeEventInfo::CTimeEventInfo() : ListItem(), _lockCounter(0), - _repeated(false), _firstDuration(0), _repeatDuration(0), _target(nullptr), - _actionVal(0), _field2C(0), _field30(0), _timerCtr(0), - _lastTimerTicks(0), _relativeTicks(0), _done(false), _field44(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), _field2C(0), - _field30(0), _timerCtr(0), _lastTimerTicks(ticks), _relativeTicks(0), _done(false), - _field44(true) { + _repeatDuration(repeatDuration), _target(target), _actionVal(endVal), _done(false), + _timerCtr(0), _lastTimerTicks(ticks), _relativeTicks(0), _persisent(true) { _id = _nextId++; } @@ -122,7 +121,7 @@ void CTimeEventInfo::save(SimpleFile *file, int indent) { file->writeNumberLine(_timerCtr, indent); file->writeNumberLine(_relativeTicks, indent); file->writeNumberLine(_done, indent); - file->writeNumberLine(_field44, indent); + file->writeNumberLine(_persisent, indent); } void CTimeEventInfo::load(SimpleFile *file) { @@ -140,13 +139,13 @@ void CTimeEventInfo::load(SimpleFile *file) { _timerCtr = file->readNumber(); _relativeTicks = file->readNumber(); _done = file->readNumber() != 0; - _field44 = file->readNumber(); + _persisent = file->readNumber() != 0; _target = nullptr; } } void CTimeEventInfo::postLoad(uint ticks, CProjectItem *project) { - if (!_field44 || _targetName.empty()) + if (!_persisent || _targetName.empty()) _done = true; // Get the timer's target diff --git a/engines/titanic/support/time_event_info.h b/engines/titanic/support/time_event_info.h index 23d0d2b803..ee787bcbef 100644 --- a/engines/titanic/support/time_event_info.h +++ b/engines/titanic/support/time_event_info.h @@ -55,13 +55,11 @@ public: CTreeItem *_target; uint _actionVal; CString _action; - uint _field2C; - uint _field30; uint _timerCtr; uint _lastTimerTicks; uint _relativeTicks; bool _done; - uint _field44; + bool _persisent; CString _targetName; public: CLASSDEF @@ -96,7 +94,10 @@ public: bool update(uint ticks); - void set44(uint val) { _field44 = val; } + /** + * Flags whether the timer will be persisent across save & loads + */ + void setPersisent(bool val) { _persisent = val; } }; class CTimeEventInfoList : public List { @@ -126,7 +127,10 @@ public: */ void stop(uint id); - void set44(uint id, uint val); + /** + * Sets whether a timer with a given Id will be persisent across saves + */ + void setPersisent(uint id, bool flag); }; } // End of namespace Titanic -- cgit v1.2.3 From f1344c2c277125e652092b94a0a5347f842c45d0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 23 Jul 2016 21:50:51 -0400 Subject: TITANIC: Added CCreditText loading --- engines/titanic/support/credit_text.cpp | 101 ++++++++++++++++++++++++++++++-- engines/titanic/support/credit_text.h | 36 ++++++++---- engines/titanic/support/string.cpp | 5 ++ engines/titanic/support/string.h | 5 ++ 4 files changed, 132 insertions(+), 15 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/credit_text.cpp b/engines/titanic/support/credit_text.cpp index e70d1dcf7a..1f12341e71 100644 --- a/engines/titanic/support/credit_text.cpp +++ b/engines/titanic/support/credit_text.cpp @@ -26,13 +26,13 @@ namespace Titanic { CCreditText::CCreditText() : _screenManagerP(nullptr), _field14(0), - _ticks(0), _fontHeight(1), _objectP(nullptr), _field34(0), _field38(0), - _field3C(0), _field40(0), _field44(0), _field48(0), _field4C(0), - _field50(0), _field54(0), _field58(0), _field5C(0) { + _ticks(0), _fontHeight(1), _objectP(nullptr), _totalHeight(0), + _field40(0), _field44(0), _field48(0), _field4C(0), _field50(0), + _field54(0), _field58(0), _field5C(0) { } void CCreditText::clear() { - _list.destroyContents(); + _groups.destroyContents(); _objectP = nullptr; } @@ -41,6 +41,9 @@ void CCreditText::load(CGameObject *obj, CScreenManager *screenManager, _objectP = obj; _screenManagerP = screenManager; _field14 = v; + + setup(); + _ticks = g_vm->_events->getTicksCount(); _field40 = 0; _field44 = 0xFF; @@ -53,7 +56,95 @@ void CCreditText::load(CGameObject *obj, CScreenManager *screenManager, } void CCreditText::setup() { - // TODO + 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; + + CCreditLine *line = new CCreditLine(srcLine, + _screenManagerP->stringWidth(srcLine)); + group->_lines.push_back(line); + + if (srcLine.contains("....")) + hasDots = true; + } + + _groups.push_back(group); + } + + _groupIt = _groups.begin(); + _lineIt = (*_groupIt)->_lines.begin(); + _totalHeight = _objectP->getBounds().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') { + c = stream->readByte(); + if (c != '\n') + stream->skip(-1); + } + + 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() { diff --git a/engines/titanic/support/credit_text.h b/engines/titanic/support/credit_text.h index 82da833bbe..ec8fc22cda 100644 --- a/engines/titanic/support/credit_text.h +++ b/engines/titanic/support/credit_text.h @@ -30,15 +30,21 @@ namespace Titanic { class CGameObject; class CScreenManager; -class COverrideSubItem : public ListItem { - +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 CCreditTextSubList; - -class CCreditTextItem : public ListItem { +typedef List CCreditLines; +class CCreditLineGroup : public ListItem { +public: + CCreditLines _lines; }; -typedef List CCreditTextList; +typedef List CCreditLineGroups; class CCreditText { private: @@ -46,17 +52,27 @@ 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; int _field14; - CCreditTextList _list; + CCreditLineGroups _groups; uint _ticks; uint _fontHeight; CGameObject *_objectP; - int _field34; - int _field38; - int _field3C; + CCreditLineGroups::iterator _groupIt; + CCreditLines::iterator _lineIt; + uint _totalHeight; int _field40; int _field44; int _field48; diff --git a/engines/titanic/support/string.cpp b/engines/titanic/support/string.cpp index d85fcfc515..cd39c03861 100644 --- a/engines/titanic/support/string.cpp +++ b/engines/titanic/support/string.cpp @@ -63,6 +63,11 @@ int CString::indexOf(char c) const { 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; diff --git a/engines/titanic/support/string.h b/engines/titanic/support/string.h index fdaf92cfad..9550ce88a7 100644 --- a/engines/titanic/support/string.h +++ b/engines/titanic/support/string.h @@ -74,6 +74,11 @@ public: */ int indexOf(char c) const; + /** + * Returns the index of the first occurance of a given string + */ + int indexOf(const char *s) const; + /** * Returns the index of the last occurance of a given character */ -- cgit v1.2.3 From fd316a60589f07ac75cfdf1b56188d9d464336bd Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 24 Jul 2016 07:45:30 -0400 Subject: TITANIC: Fleshed out various methods --- engines/titanic/support/credit_text.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/credit_text.cpp b/engines/titanic/support/credit_text.cpp index 1f12341e71..0e9715aaa6 100644 --- a/engines/titanic/support/credit_text.cpp +++ b/engines/titanic/support/credit_text.cpp @@ -78,7 +78,7 @@ void CCreditText::setup() { if (srcLine.empty()) break; - CCreditLine *line = new CCreditLine(srcLine, + line = new CCreditLine(srcLine, _screenManagerP->stringWidth(srcLine)); group->_lines.push_back(line); @@ -107,9 +107,8 @@ CString CCreditText::readLine(Common::SeekableReadStream *stream) { } if (c == '\r') { - c = stream->readByte(); - if (c != '\n') - stream->skip(-1); + // Read following '\n' + stream->readByte(); } return line; -- cgit v1.2.3 From 4d79ee16c07e2398e9058fe93947b4704cd6048a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 24 Jul 2016 20:30:56 -0400 Subject: TITANIC: Add semicolon after CLASSDEF macro usage --- engines/titanic/support/movie_clip.h | 2 +- engines/titanic/support/time_event_info.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/movie_clip.h b/engines/titanic/support/movie_clip.h index 813996bbf0..513ed4a339 100644 --- a/engines/titanic/support/movie_clip.h +++ b/engines/titanic/support/movie_clip.h @@ -49,7 +49,7 @@ public: int _startFrame; int _endFrame; public: - CLASSDEF + CLASSDEF; CMovieClip(); CMovieClip(const CString &name, int startFrame, int endFrame); diff --git a/engines/titanic/support/time_event_info.h b/engines/titanic/support/time_event_info.h index ee787bcbef..ebf5b54458 100644 --- a/engines/titanic/support/time_event_info.h +++ b/engines/titanic/support/time_event_info.h @@ -62,7 +62,7 @@ public: bool _persisent; CString _targetName; public: - CLASSDEF + CLASSDEF; CTimeEventInfo(); CTimeEventInfo(uint ticks, bool repeated, uint firstDuration, uint repeatDuration, CTreeItem *target, int endVal, const CString &action); -- cgit v1.2.3 From 6dbbb173bd7738ff725eefbd12923699d1663392 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 30 Jul 2016 17:39:09 -0400 Subject: TITANIC: Fix identified warnings --- engines/titanic/support/simple_file.cpp | 16 +++++++++------- engines/titanic/support/simple_file.h | 4 ++-- 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/simple_file.cpp b/engines/titanic/support/simple_file.cpp index e60b7c7485..35b2e28e4a 100644 --- a/engines/titanic/support/simple_file.cpp +++ b/engines/titanic/support/simple_file.cpp @@ -36,9 +36,9 @@ CString readStringFromStream(Common::SeekableReadStream *s) { /*------------------------------------------------------------------------*/ -bool File::open(const Common::String &name) { - if (!Common::File::open(name)) - error("Could not open file - %s", name.c_str()); +bool File::open(const Common::String &filename) { + if (!Common::File::open(filename)) + error("Could not open file - %s", filename.c_str()); return true; } @@ -466,8 +466,9 @@ void SimpleFile::skipSpaces() { /*------------------------------------------------------------------------*/ -void StdCWadFile::open(const CString &name) { +bool StdCWadFile::open(const Common::String &filename) { File f; + CString name = filename; // Check for whether it is indeed a file/resource pair int idx = name.indexOf('#'); @@ -478,17 +479,17 @@ void StdCWadFile::open(const CString &name) { f.open(name); SimpleFile::open(f.readStream(f.size())); - return; + return true; } // Split up the name and resource, and get the resource index - CString filename = name.left(idx) + ".st"; + 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 - f.open(filename); + f.open(fname); int indexSize = f.readUint32LE() / 4; assert(resIndex < indexSize); @@ -505,6 +506,7 @@ void StdCWadFile::open(const CString &name) { SimpleFile::open(stream); f.close(); + return true; } } // End of namespace Titanic diff --git a/engines/titanic/support/simple_file.h b/engines/titanic/support/simple_file.h index 0cfb424fad..6cf9995d16 100644 --- a/engines/titanic/support/simple_file.h +++ b/engines/titanic/support/simple_file.h @@ -41,7 +41,7 @@ class DecompressorData; */ class File : public Common::File { public: - virtual bool open(const Common::String &name); + virtual bool open(const Common::String &filename); }; /** @@ -293,7 +293,7 @@ public: /** * Open up the specified file */ - void open(const CString &name); + virtual bool open(const Common::String &filename); /** * Return a reference to the read stream -- cgit v1.2.3 From 8a2491c51b1b7d27382030f3cb9d58c5b56265f0 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 31 Jul 2016 07:24:07 -0400 Subject: TITANIC: Fix some clang warnings --- engines/titanic/support/simple_file.h | 10 ++++++++++ engines/titanic/support/video_surface.h | 7 +++++++ 2 files changed, 17 insertions(+) (limited to 'engines/titanic/support') diff --git a/engines/titanic/support/simple_file.h b/engines/titanic/support/simple_file.h index 6cf9995d16..f5d0bc7c1b 100644 --- a/engines/titanic/support/simple_file.h +++ b/engines/titanic/support/simple_file.h @@ -295,6 +295,16 @@ public: */ virtual bool open(const Common::String &filename); + /** + * Unsupported open method from parent class + */ + virtual void open(Common::SeekableReadStream *stream) {} + + /** + * Unsupported open method from parent class + */ + virtual void open(Common::OutSaveFile *stream) {} + /** * Return a reference to the read stream */ diff --git a/engines/titanic/support/video_surface.h b/engines/titanic/support/video_surface.h index 1f3a0fa2b3..053eabb0f9 100644 --- a/engines/titanic/support/video_surface.h +++ b/engines/titanic/support/video_surface.h @@ -85,6 +85,13 @@ public: */ void setSurface(CScreenManager *screenManager, DirectDrawSurface *surface); + /** + * Load the data for the class from file + */ + virtual void load(SimpleFile *file) { + ListItem::load(file); + } + /** * Load the surface with the passed resource */ -- cgit v1.2.3