diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/toltecs/menu.cpp | 250 | ||||
-rw-r--r-- | engines/toltecs/menu.h | 140 | ||||
-rw-r--r-- | engines/toltecs/microtiles.cpp | 797 | ||||
-rw-r--r-- | engines/toltecs/microtiles.h | 105 | ||||
-rw-r--r-- | engines/toltecs/module.mk | 3 | ||||
-rw-r--r-- | engines/toltecs/movie.cpp | 179 | ||||
-rw-r--r-- | engines/toltecs/movie.h | 65 |
7 files changed, 1539 insertions, 0 deletions
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp new file mode 100644 index 0000000000..9061ff5ddf --- /dev/null +++ b/engines/toltecs/menu.cpp @@ -0,0 +1,250 @@ +/* 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/events.h" +#include "common/keyboard.h" +#include "common/file.h" +#include "common/savefile.h" +#include "common/config-manager.h" + +#include "base/plugins.h" +#include "base/version.h" + +#include "sound/mixer.h" + +#include "toltecs/toltecs.h" +#include "toltecs/menu.h" +#include "toltecs/resource.h" +#include "toltecs/screen.h" + +namespace Toltecs { + +// This code is very experimental. + +Widget::Widget(ToltecsEngine *vm, int x, int y) : _vm(vm) { + _rect.left = x; + _rect.top = y; +} + +Widget::~Widget() { +} + +void Widget::redraw() { +} + +Widget *Widget::getHoveredWidget(int mouseX, int mouseY) { + if (_rect.contains(mouseX, mouseY)) + return this; + else + return NULL; +} + +void Widget::calcDimensions() { +} + +void Widget::setRect(Common::Rect rect) { + _rect = rect; +} + +void Widget::onMouseEnter() { +} + +void Widget::onMouseLeave() { +} + +void Widget::onMouseMove(int mouseX, int mouseY) { +} + +LabelWidget::LabelWidget(ToltecsEngine *vm, int x, int y, Common::String caption, uint flags) : + Widget(vm, x, y), _caption(caption), _flags(flags), _fontColor(kFontColorMenuDefault) { + + calcDimensions(); + +} + +LabelWidget::~LabelWidget() { +} + +void LabelWidget::redraw() { + _vm->_screen->drawString(_rect.left, _rect.top, _fontColor, 14, (byte*)_caption.c_str(), -1, NULL, true); +} + +void LabelWidget::calcDimensions() { + Font font(_vm->_res->load(14)); + _rect.setWidth(font.getTextWidth((byte*)_caption.c_str())); + _rect.setHeight(font.getHeight()); +} + +void LabelWidget::setCaption(Common::String caption) { + _caption = caption; + calcDimensions(); +} + +void LabelWidget::setFontColor(byte fontColor) { + _fontColor = fontColor; +} + +void LabelWidget::onMouseEnter() { + setFontColor(kFontColorMenuActive); +} + +void LabelWidget::onMouseLeave() { + setFontColor(kFontColorMenuDefault); +} + + +VolumeControlWidget::VolumeControlWidget(ToltecsEngine *vm, int x, int y, Common::String caption, uint flags) : + Widget(_vm, x, y), _activeWidget(NULL) { + + _label = new LabelWidget(vm, x, y, caption, flags); + _up = new LabelWidget(vm, x + 350, y + 4, "[", flags); + _down = new LabelWidget(vm, x + 350 + 24, y + 4, "]", flags); + _indicator = new LabelWidget(vm, x + 350 + 24 + 24 + 8, y, "||||||||||", flags); + + _rect.setWidth(350 + 24 + 24 + 8 + 50); + _rect.setHeight(20); + +} + +VolumeControlWidget::~VolumeControlWidget() { + delete _label; + delete _up; + delete _down; + delete _indicator; +} + +void VolumeControlWidget::redraw() { + _label->redraw(); + _up->redraw(); + _down->redraw(); + _indicator->redraw(); +} + +Widget *VolumeControlWidget::getHoveredWidget(int mouseX, int mouseY) { + return Widget::getHoveredWidget(mouseX, mouseY); +} + +void VolumeControlWidget::calcDimensions() { +} + +void VolumeControlWidget::onMouseEnter() { + _label->setFontColor(kFontColorMenuActive); + _indicator->setFontColor(kFontColorMenuActive); + _activeWidget = NULL; +} + +void VolumeControlWidget::onMouseLeave() { + _label->setFontColor(kFontColorMenuDefault); + _up->setFontColor(kFontColorMenuDefault); + _down->setFontColor(kFontColorMenuDefault); + _indicator->setFontColor(kFontColorMenuDefault); +} + +void VolumeControlWidget::onMouseMove(int mouseX, int mouseY) { + + Widget *hoveredWidget = NULL; + + hoveredWidget = _up->getHoveredWidget(mouseX, mouseY); + if (!hoveredWidget) + hoveredWidget = _down->getHoveredWidget(mouseX, mouseY); + + if (_activeWidget != hoveredWidget) { + _activeWidget = hoveredWidget; + if (!_activeWidget) { + _up->setFontColor(kFontColorMenuDefault); + _down->setFontColor(kFontColorMenuDefault); + } else if (_activeWidget == _up) { + _up->setFontColor(kFontColorMenuActive); + _down->setFontColor(kFontColorMenuDefault); + } else if (_activeWidget == _down) { + _up->setFontColor(kFontColorMenuDefault); + _down->setFontColor(kFontColorMenuActive); + } + } + +} + +MenuPage::MenuPage(Common::String caption) { +} + +MenuPage::~MenuPage() { + // TODO: Delete widgets +} + +void MenuPage::addWidget(Widget *widget) { + _widgets.push_back(widget); +} + +void MenuPage::redraw() { + for (WidgetArray::iterator iter = _widgets.begin(); iter != _widgets.end(); iter++) { + (*iter)->redraw(); + } +} + +Widget *MenuPage::getHoveredWidget(int mouseX, int mouseY) { + Widget *hoveredWidget = NULL; + for (WidgetArray::iterator iter = _widgets.begin(); iter != _widgets.end() && !hoveredWidget; iter++) { + hoveredWidget = (*iter)->getHoveredWidget(mouseX, mouseY); + } + return hoveredWidget; +} + +MenuSystem::MenuSystem(ToltecsEngine *vm) : _vm(vm), _activeWidget(NULL), _oldMouseX(-1), _oldMouseY(-1) { + _page = new MenuPage("Welcome"); + _page->addWidget(new LabelWidget(_vm, 10, 10, "Load game", 0)); + _page->addWidget(new LabelWidget(_vm, 10, 35, "Save game", 0)); + _page->addWidget(new VolumeControlWidget(_vm, 10, 60, "Master volume", 0)); + _page->addWidget(new VolumeControlWidget(_vm, 10, 90, "Some other volume", 0)); +} + +MenuSystem::~MenuSystem() { + delete _page; +} + +void MenuSystem::update() { + + _page->redraw(); + + if (_vm->_mouseX != _oldMouseX || _vm->_mouseY != _oldMouseY) { + + _oldMouseX = _vm->_mouseX; + _oldMouseY = _vm->_mouseY; + + Widget *hoveredWidget = _page->getHoveredWidget(_vm->_mouseX, _vm->_mouseY); + if (_activeWidget != hoveredWidget) { + if (_activeWidget) + _activeWidget->onMouseLeave(); + if (hoveredWidget) + hoveredWidget->onMouseEnter(); + _activeWidget = hoveredWidget; + } + + if (_activeWidget) { + _activeWidget->onMouseMove(_vm->_mouseX, _vm->_mouseY); + } + + } + +} + +} // End of namespace Toltecs diff --git a/engines/toltecs/menu.h b/engines/toltecs/menu.h new file mode 100644 index 0000000000..15b73b78f7 --- /dev/null +++ b/engines/toltecs/menu.h @@ -0,0 +1,140 @@ +/* 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 TOLTECS_MENU_H +#define TOLTECS_MENU_H + +#include "common/scummsys.h" +#include "common/endian.h" +#include "common/util.h" +#include "common/file.h" +#include "common/savefile.h" +#include "common/system.h" +#include "common/hash-str.h" +#include "common/events.h" +#include "common/keyboard.h" +#include "common/array.h" +#include "common/rect.h" +#include "common/str.h" + +#include "sound/audiostream.h" +#include "sound/mixer.h" +#include "sound/voc.h" +#include "sound/audiocd.h" + +#include "engines/engine.h" + +namespace Toltecs { + +const byte kFontColorMenuDefault = 229; +const byte kFontColorMenuActive = 255; + +class Widget { +public: + Widget(ToltecsEngine *vm, int x, int y); + virtual ~Widget(); + virtual void redraw(); + virtual Widget *getHoveredWidget(int mouseX, int mouseY); + virtual void calcDimensions(); + void setRect(Common::Rect rect); + //virtual void setHilighted(bool active); + virtual void onMouseEnter(); + virtual void onMouseLeave(); + virtual void onMouseMove(int mouseX, int mouseY); +protected: + ToltecsEngine *_vm; + Common::Rect _rect; + //bool _hilighted; +}; + +const int kLabelCentered = 1 << 1; +const int kLabelHideOnMovie = 1 << 2; + +class LabelWidget : public Widget { +public: + LabelWidget(ToltecsEngine *vm, int x, int y, Common::String caption, uint flags); + ~LabelWidget(); + void redraw(); + void calcDimensions(); + void setCaption(Common::String caption); + void setFontColor(byte fontColor); + void onMouseEnter(); + void onMouseLeave(); +protected: + Common::String _caption; + uint _flags; + byte _fontColor; +}; + +class VolumeControlWidget : public Widget { +public: + VolumeControlWidget(ToltecsEngine *vm, int x, int y, Common::String caption, uint flags); + ~VolumeControlWidget(); + void redraw(); + Widget *getHoveredWidget(int mouseX, int mouseY); + void calcDimensions(); + //void setHilighted(bool active); + void onMouseEnter(); + void onMouseLeave(); + void onMouseMove(int mouseX, int mouseY); +protected: + uint _flags; + LabelWidget *_label, *_up, *_down, *_indicator; + Widget *_activeWidget; +}; + +class MenuPage { +public: + MenuPage(Common::String caption); + ~MenuPage(); + void addWidget(Widget *widget); + void redraw(); + Widget *getHoveredWidget(int mouseX, int mouseY); +protected: + typedef Common::Array<Widget*> WidgetArray; + Common::String _caption; + WidgetArray _widgets; +}; + +class MenuSystem { + +public: + MenuSystem(ToltecsEngine *vm); + ~MenuSystem(); + + void update(); + +protected: + ToltecsEngine *_vm; + + //LabelWidget *label1, *label2; + MenuPage *_page; + + Widget *_activeWidget; + int16 _oldMouseX, _oldMouseY; + +}; + +} // End of namespace Toltecs + +#endif /* TOLTECS_MENU_H */ diff --git a/engines/toltecs/microtiles.cpp b/engines/toltecs/microtiles.cpp new file mode 100644 index 0000000000..3cd5facfa6 --- /dev/null +++ b/engines/toltecs/microtiles.cpp @@ -0,0 +1,797 @@ +/* + SEL - Simple DirectMedia Layer Extension Library + Copyright (C) 2002 Matej Knopp <knopp@users.sf.net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* microtile arrays implementation */ + +/* + * This is a microtile array implementation similiar to the one + * from LibArt_LGPL. First, I wanted to use that one but unfortunately + * I fount out that it suffered from a bad design and simply didn't meet + * my requirements so I decided to write the implementation on my own. + */ + +#include "toltecs/microtiles.h" +#include "common/scummsys.h" +#include "common/endian.h" +#include "common/util.h" + +namespace Toltecs { + +typedef struct _GemUta GemUta; +typedef struct _GemRect GemRect; + +typedef uint32 GemUtaBBox; + +#define GEM_UTA_BBOX_CONS(x0, y0, x1, y1) (((x0) << 24) | ((y0) << 16) | \ + ((x1) << 8) | (y1)) + +#define GEM_UTILE_EMPTY 0x00000000 +#define GEM_UTILE_FULL 0x01012020 + +#define GEM_UTA_BBOX_X0(ub) ((ub) >> 24) +#define GEM_UTA_BBOX_Y0(ub) (((ub) >> 16) & 0xff) +#define GEM_UTA_BBOX_X1(ub) (((ub) >> 8) & 0xff) +#define GEM_UTA_BBOX_Y1(ub) ((ub) & 0xff) + +#define GEM_UTILE_SHIFT 5 +#define GEM_UTILE_SIZE (1 << GEM_UTILE_SHIFT) + +#define GEM_MIN(a,b) ((a) < (b) ? (a) : (b)) +#define GEM_MAX(a,b) ((a) > (b) ? (a) : (b)) + +struct _GemUta { + int x; + int y; + int width; /* number of tiles in one line */ + int height; /* number of tiles in one row */ + GemUtaBBox *tiles; +}; + +struct _GemRect { + int x0; + int x1; + int y0; + int y1; +}; + + +static GemUta * gem_uta_new (int x, int y, int width, int height); +static GemUta * gem_uta_new_coords (int x, int y, int width, int height); +static void gem_uta_free (GemUta *uta); +static void gem_uta_union (GemUta *uta1, const GemUta *uta2); +static void gem_uta_add_rect (GemUta *uta, const GemRect * rect); + +#define GEM_UTA_QUERY_CONTAIN 0 +#define GEM_UTA_QUERY_INTERSECT 1 + +static int gem_uta_query_rect (const GemUta *uta, const GemRect * rect, int query); + +static Common::Rect * gem_uta_get_rects (const GemUta *uta, int * num_rects, + int min_x, int min_y, int max_x, int max_y); + +/************** UTA IMPLEMENTATION **************/ + +#define GEM_UTILE_UNION(b1, b2) \ + { \ + if (b1 == GEM_UTILE_FULL || b2 == GEM_UTILE_EMPTY) \ + { } \ + else if (b1 == GEM_UTILE_EMPTY || b2 == GEM_UTILE_FULL) \ + { b1 = b2; } \ + else { \ + b1 = GEM_UTA_BBOX_CONS ( \ + GEM_MIN(GEM_UTA_BBOX_X0(b1), \ + GEM_UTA_BBOX_X0(b2)), \ + GEM_MIN(GEM_UTA_BBOX_Y0(b1), \ + GEM_UTA_BBOX_Y0(b2)), \ + GEM_MAX(GEM_UTA_BBOX_X1(b1), \ + GEM_UTA_BBOX_X1(b2)), \ + GEM_MAX(GEM_UTA_BBOX_Y1(b1), \ + GEM_UTA_BBOX_Y1(b2))); \ + } \ + } + +static GemUta * gem_uta_new (int x, int y, int width, int height) { + GemUta *uta; + + uta = (GemUta *) malloc (sizeof (GemUta)); + uta->x = x; + uta->y = y; + uta->width = width; + uta->height = height; + + uta->tiles = (GemUtaBBox *) + malloc (sizeof (GemUtaBBox) * width * height); + + memset (uta->tiles, 0, sizeof (GemUtaBBox) * width * height); + + return uta; +} + +static GemUta * gem_uta_new_coords (int x, int y, int width, int height) { + return gem_uta_new (x >> GEM_UTILE_SHIFT, y >> GEM_UTILE_SHIFT, + (width >> GEM_UTILE_SHIFT) + 1, + (height >> GEM_UTILE_SHIFT) + 1); +} + +static void gem_uta_free (GemUta *uta) { + if (uta) { + if (uta->tiles) + free (uta->tiles); + free(uta); + } +} + +static void gem_uta_union (GemUta *uta1, const GemUta *uta2) { + int32 x0, y0, x1, y1; + int x, y; + GemUtaBBox *_b1; + const GemUtaBBox *_b2; + + if (!uta1 || !uta2) + return; + + x0 = GEM_MAX (uta1->x, uta2->x); + y0 = GEM_MAX (uta2->y, uta2->y); + x1 = GEM_MIN (uta1->x + uta1->width - 1, + uta2->x + uta2->width - 1); + y1 = GEM_MIN (uta1->y + uta1->height - 1, + uta2->y + uta2->height - 1); + + if (x0 > x1 || y0 > y1) + return; + + _b1 = & (uta1->tiles [(y0 - uta1->y) * uta1->width + (x0 - uta1->x)]); + _b2 = & (uta2->tiles [(y0 - uta2->y) * uta2->width + (x0 - uta2->x)]); + + for (y = y0; y <= y1; ++y) + { + GemUtaBBox *b1 = _b1; + const GemUtaBBox *b2 = _b2; + + for (x = x0; x <= x1; ++x) + { + GEM_UTILE_UNION (*b1, *b2); + + b1 ++; + b2 ++; + } + _b1 += uta1->width; + _b2 += uta2->width; + } +} + +/* + * Add a rectangle to the microtile array. + * The coordinates of the rectangle are considered absolute. + */ + +static void gem_uta_add_rect (GemUta *uta, const GemRect * _rect) { + int xf0, xf1, yf0, yf1; + int width, height; + int x0, y0, x1, y1; + int x, y; + GemUtaBBox *_b; + GemUtaBBox *b; + GemUtaBBox bbox; + GemRect rect; + + if (!uta || !_rect) + return; + + rect = *_rect; + + rect.x0 -= uta->x << GEM_UTILE_SHIFT; + rect.y0 -= uta->y << GEM_UTILE_SHIFT; + rect.x1 -= uta->x << GEM_UTILE_SHIFT; + rect.y1 -= uta->y << GEM_UTILE_SHIFT; + + if (rect.x0 < 0) + rect.x0 = 0; + if (rect.y0 < 0) + rect.y0 = 0; + if (rect.x1 > (uta->width << GEM_UTILE_SHIFT)) + rect.x1 = (uta->width << GEM_UTILE_SHIFT); + if (rect.y1 > (uta->height << GEM_UTILE_SHIFT)) + rect.y1 = (uta->height << GEM_UTILE_SHIFT); + + if (rect.x0 > rect.x1 || rect.y0 > rect.y1) + return; + + width = ((rect.x1 + GEM_UTILE_SIZE) >> GEM_UTILE_SHIFT) + - (rect.x0 >> GEM_UTILE_SHIFT); + height = ((rect.y1 + GEM_UTILE_SIZE) >> GEM_UTILE_SHIFT) + - (rect.y0 >> GEM_UTILE_SHIFT); + + xf0 = rect.x0 % (GEM_UTILE_SIZE); + yf0 = rect.y0 % (GEM_UTILE_SIZE); + xf1 = rect.x1 % (GEM_UTILE_SIZE); + yf1 = rect.y1 % (GEM_UTILE_SIZE); + + x0 = rect.x0 >> GEM_UTILE_SHIFT; + y0 = rect.y0 >> GEM_UTILE_SHIFT; + x1 = rect.x1 >> GEM_UTILE_SHIFT; + y1 = rect.y1 >> GEM_UTILE_SHIFT; + + _b = & (uta->tiles [(y0 * uta->width) + x0]); + + if (width == 1 && height == 1) { + bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, xf1 + 1, yf1 + 1); + GEM_UTILE_UNION (*_b, bbox); + return; + } + if (width == 1) { + bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, xf1 + 1, + GEM_UTILE_SIZE); + GEM_UTILE_UNION (*_b, bbox); + _b += uta->width; + if (height > 2) { + for (y = y0 + 1; y <= (y1 - 1); ++y) { + bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, xf1 + 1, GEM_UTILE_SIZE); + GEM_UTILE_UNION (*_b, bbox); + _b += uta->width; + } + } + bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, xf1 + 1, yf1 + 1); + GEM_UTILE_UNION (*_b, bbox); + return; + } else if (height == 1) { + bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, GEM_UTILE_SIZE, yf1 + 1); + GEM_UTILE_UNION (*_b, bbox); + ++_b; + if (width > 2) { + for (x = x0 + 1; x <= (x1 - 1); ++x) { + bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, GEM_UTILE_SIZE, xf1 + 1); + GEM_UTILE_UNION (*_b, bbox); + ++_b; + } + } + bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, xf1 + 1, yf1 + 1); + GEM_UTILE_UNION (*_b, bbox); + return; + } + + b = _b; + + /* top-left corner */ + bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, GEM_UTILE_SIZE, GEM_UTILE_SIZE); + GEM_UTILE_UNION (*b, bbox); + ++b; + + /* top edge */ + if (width > 2) { + for (x = x0 + 1; x <= (x1 - 1); ++x) { + bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, GEM_UTILE_SIZE, GEM_UTILE_SIZE); + GEM_UTILE_UNION (*b, bbox); + ++b; + } + } + + /* top-right corner */ + bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, xf1 + 1, GEM_UTILE_SIZE); + GEM_UTILE_UNION (*b, bbox); + + _b += uta->width; + + /* left edge, content, right edge */ + if (height > 2) { + for (y = y0 + 1; y <= (y1 - 1); ++y) { + b = _b; + + /* left edge */ + bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, GEM_UTILE_SIZE, GEM_UTILE_SIZE); + GEM_UTILE_UNION (*b, bbox); + ++b; + + /* content */ + if (width > 2) { + for (x = x0 + 1; x <= (x1 - 1); ++x) { + *b = GEM_UTILE_FULL; + ++b; + } + } + + /* right edge */ + bbox = GEM_UTA_BBOX_CONS (1, 1, xf1 + 1, GEM_UTILE_SIZE); + GEM_UTILE_UNION (*b, bbox); + + _b += uta->width; + } + } + + b = _b; + + /* bottom-left corner */ + bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, GEM_UTILE_SIZE, yf1 + 1); + GEM_UTILE_UNION (*b, bbox); + ++b; + + /* bottom edge */ + if (width > 2) { + for (x = x0 + 1; x <= (x1 - 1); ++x) { + bbox = GEM_UTA_BBOX_CONS (1, 1, GEM_UTILE_SIZE, yf1 + 1); + GEM_UTILE_UNION (*b, bbox); + ++b; + } + } + + /* bottom-left corner */ + bbox = GEM_UTA_BBOX_CONS (1, 1, xf1 + 1, yf1 + 1); + GEM_UTILE_UNION (*b, bbox); + + /* done. */ +} + +#define GEM_UTILE_CONTAINS(b1, b2) \ + ( !(GEM_UTA_BBOX_X0 (b1) > GEM_UTA_BBOX_X0 (b2) || \ + GEM_UTA_BBOX_Y0 (b1) > GEM_UTA_BBOX_Y0 (b2) || \ + GEM_UTA_BBOX_X1 (b1) < GEM_UTA_BBOX_X1 (b2) || \ + GEM_UTA_BBOX_Y1 (b1) < GEM_UTA_BBOX_Y1 (b2)) ) + +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +static inline int gem_utile_intersects (GemUtaBBox b1, GemUtaBBox b2) { + GemUtaBBox b3; + b3 = GEM_UTA_BBOX_CONS ( + MAX (GEM_UTA_BBOX_X0 (b1), GEM_UTA_BBOX_X0 (b2)), + MAX (GEM_UTA_BBOX_Y0 (b1), GEM_UTA_BBOX_Y0 (b2)), + MIN (GEM_UTA_BBOX_X1 (b1), GEM_UTA_BBOX_X1 (b2)), + MIN (GEM_UTA_BBOX_Y1 (b1), GEM_UTA_BBOX_Y1 (b2)) + ); + return (GEM_UTA_BBOX_X0 (b3) <= GEM_UTA_BBOX_X1 (b3) && + GEM_UTA_BBOX_Y0 (b3) <= GEM_UTA_BBOX_Y1 (b3)); +} + +#define GEM_UTILE_INTERSECTS(b1, b2) \ + gem_utile_intersects (b1, b2) +/* + * Return if the uta contains the rectangle. + */ + +static int gem_uta_query_rect (const GemUta *uta, const GemRect * _rect, int query) { + int xf0, xf1, yf0, yf1; + int width, height; + int x0, y0, x1, y1; + int x, y; + GemUtaBBox *_b; + GemUtaBBox *b; + GemUtaBBox bbox; + GemRect rect; + + if (!uta || !_rect) + return 0; + + rect = *_rect; + + rect.x0 -= uta->x << GEM_UTILE_SHIFT; + rect.y0 -= uta->y << GEM_UTILE_SHIFT; + rect.x1 -= uta->x << GEM_UTILE_SHIFT; + rect.y1 -= uta->y << GEM_UTILE_SHIFT; + + if (rect.x0 < 0) + rect.x0 = 0; + if (rect.y0 < 0) + rect.y0 = 0; + if (rect.x1 > (uta->width << GEM_UTILE_SHIFT)) + rect.x1 = (uta->width << GEM_UTILE_SHIFT); + if (rect.y1 > (uta->height << GEM_UTILE_SHIFT)) + rect.y1 = (uta->height << GEM_UTILE_SHIFT); + + if (rect.x0 > rect.x1 || rect.y0 > rect.y1) + return 0; + + width = ((rect.x1 + GEM_UTILE_SIZE) >> GEM_UTILE_SHIFT) + - (rect.x0 >> GEM_UTILE_SHIFT); + height = ((rect.y1 + GEM_UTILE_SIZE) >> GEM_UTILE_SHIFT) + - (rect.y0 >> GEM_UTILE_SHIFT); + + xf0 = rect.x0 % (GEM_UTILE_SIZE); + yf0 = rect.y0 % (GEM_UTILE_SIZE); + xf1 = rect.x1 % (GEM_UTILE_SIZE); + yf1 = rect.y1 % (GEM_UTILE_SIZE); + + x0 = rect.x0 >> GEM_UTILE_SHIFT; + y0 = rect.y0 >> GEM_UTILE_SHIFT; + x1 = rect.x1 >> GEM_UTILE_SHIFT; + y1 = rect.y1 >> GEM_UTILE_SHIFT; + + _b = & (uta->tiles [(y0 * uta->width) + x0]); + + if (width == 1 && height == 1) { + bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, xf1 + 1, yf1 + 1); + if (query == GEM_UTA_QUERY_INTERSECT && + GEM_UTILE_INTERSECTS (*_b, bbox)) + return 1; + else if (query == GEM_UTA_QUERY_CONTAIN && + GEM_UTILE_CONTAINS (*_b, bbox)) + return 1; + return 0; + + } +#define CHECK(b1,b2) \ + { \ + if (query == GEM_UTA_QUERY_INTERSECT && \ + GEM_UTILE_INTERSECTS (b1, b2)) \ + return 1; \ + else if (query == GEM_UTA_QUERY_CONTAIN && \ + !(GEM_UTILE_CONTAINS (b1, b2))) \ + return 0; \ + } + if (width == 1) { + bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, xf1 + 1, GEM_UTILE_SIZE); + CHECK (*_b, bbox); + _b += uta->width; + if (height > 2) { + for (y = y0 + 1; y <= (y1 - 1); ++y) { + bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, xf1 + 1, GEM_UTILE_SIZE); + CHECK (*_b, bbox); + _b += uta->width; + } + } + bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, xf1 + 1, yf1 + 1); + CHECK (*_b, bbox); + if (query == GEM_UTA_QUERY_INTERSECT) + return 0; + else if (query == GEM_UTA_QUERY_CONTAIN) + return 1; + } else if (height == 1) { + bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, GEM_UTILE_SIZE, yf1 + 1); + CHECK (*_b, bbox); + ++_b; + if (width > 2) { + for (x = x0 + 1; x <= (x1 - 1); ++x) { + bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, GEM_UTILE_SIZE, xf1 + 1); + CHECK (*_b, bbox); + ++_b; + } + } + bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, xf1 + 1, yf1 + 1); + CHECK (*_b, bbox); + if (query == GEM_UTA_QUERY_INTERSECT) + return 0; + else if (query == GEM_UTA_QUERY_CONTAIN) + return 1; + } + + b = _b; + + /* top-left corner */ + bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, GEM_UTILE_SIZE, GEM_UTILE_SIZE); + CHECK (*b, bbox); + ++b; + + /* top edge */ + if (width > 2) { + for (x = x0 + 1; x <= (x1 - 1); ++x) { + bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, GEM_UTILE_SIZE, GEM_UTILE_SIZE); + CHECK (*b, bbox); + ++b; + } + } + + /* top-right corner */ + bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, xf1 + 1, GEM_UTILE_SIZE); + CHECK (*b, bbox); + + _b += uta->width; + + /* left edge, content, right edge */ + if (height > 2) { + for (y = y0 + 1; y <= (y1 - 1); ++y) { + b = _b; + + /* left edge */ + bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, GEM_UTILE_SIZE, GEM_UTILE_SIZE); + CHECK (*b, bbox); + ++b; + + /* content */ + if (width > 2) { + for (x = x0 + 1; x <= (x1 - 1); ++x) { + CHECK (*b, GEM_UTILE_FULL); + ++b; + } + } + + /* right edge */ + bbox = GEM_UTA_BBOX_CONS (1, 1, xf1 + 1, GEM_UTILE_SIZE); + CHECK (*b, bbox); + + _b += uta->width; + } + } + + b = _b; + + /* bottom-left corner */ + bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, GEM_UTILE_SIZE, yf1 + 1); + CHECK (*b, bbox); + ++b; + + /* bottom edge */ + if (width > 2) { + for (x = x0 + 1; x <= (x1 - 1); ++x) { + bbox = GEM_UTA_BBOX_CONS (1, 1, GEM_UTILE_SIZE, yf1 + 1); + CHECK (*b, bbox); + ++b; + } + } + + /* bottom-left corner */ + bbox = GEM_UTA_BBOX_CONS (1, 1, xf1 + 1, yf1 + 1); + CHECK (*b, bbox); + +#undef CHECK + + /* done. */ + if (query == GEM_UTA_QUERY_CONTAIN) + return 1; + return 0; +} + + +#undef CLAMP +#define CLAMP(a,min,max) (a = (a < min ? min : (a > max ? max : a))) + +static Common::Rect * gem_uta_get_rects (const GemUta *uta, int * num_rects, + int min_x, int min_y, int max_x, int max_y) { + +#if 1 + + + GemRect *rects = new GemRect[uta->width * uta->height]; + Common::Rect *result = NULL; + int n_rects = 0; + int x, y; + int x0, y0, x1, y1; + + int *glom = new int[uta->width * uta->height]; + int i; /* current */ + + for (i = 0; i < uta->width * uta->height; ++i) + glom [i] = -1; + + i = 0; + + for (y = 0; y < uta->height; ++y) { + for (x = 0; x < uta->width; ++x) { +#define TILE uta->tiles [i] + int start; + int finish = 0; + GemUtaBBox b; + + b = uta->tiles [i]; + + if (TILE == GEM_UTILE_EMPTY) + goto next; + + x0 = ((uta->x + x) << GEM_UTILE_SHIFT) + GEM_UTA_BBOX_X0 (TILE) - 1; + y0 = ((uta->y + y) << GEM_UTILE_SHIFT) + GEM_UTA_BBOX_Y0 (TILE) - 1; + y1 = ((uta->y + y) << GEM_UTILE_SHIFT) + GEM_UTA_BBOX_Y1 (TILE) - 1; + + CLAMP (x0, min_x, max_x); + CLAMP (y0, min_y, max_y); + CLAMP (y1, min_y, max_y); + + start = i; + + if (GEM_UTA_BBOX_X1 (TILE) != GEM_UTILE_SIZE || x == uta->width - 1) { + /* the tile does not continue */ + goto done; + } + + while (!finish) { + ++x; + ++i; + + if (x == uta->width || + GEM_UTA_BBOX_Y0 (TILE) != GEM_UTA_BBOX_Y0 (b) || + GEM_UTA_BBOX_Y1 (TILE) != GEM_UTA_BBOX_Y1 (b) || + GEM_UTA_BBOX_X0 (TILE) != 1) + { + --x; + --i; + finish = 1; + } + } + + done: + x1 = ((uta->x + x) << GEM_UTILE_SHIFT) + GEM_UTA_BBOX_X1 (TILE) - 1; + + CLAMP (x1, min_x, max_x); + + if (glom [start] != -1 && /* try to glom */ + rects [glom [start]].x0 == x0 && + rects [glom [start]].x1 == x1 && + rects [glom [start]].y1 == y0 - 1) + { + rects [glom [start]].y1 = y1; + if (y != uta->height - 1) { + glom [start + uta->width] = glom [start]; + } + } else { + rects [n_rects].x0 = x0; + rects [n_rects].y0 = y0; + rects [n_rects].x1 = x1; + rects [n_rects].y1 = y1; + if (y != uta->height - 1) { + glom [start + uta->width] = n_rects; + } + n_rects ++; + } + next: + ++i; +#undef TILE + } + } + + result = new Common::Rect[n_rects]; + + for (i = 0; i < n_rects; ++i) { + result[i].left = rects [i].x0; + result[i].top = rects [i].y0; + result[i].right = rects[i].x1; // CHECK + result[i].bottom = rects[i].y1; // CHECK + } + + *num_rects = n_rects; + + delete rects; + delete glom; + + return result; + +#else + return NULL; +#endif + +} + +MicroTileArray::MicroTileArray() + : m_uta (NULL) +{ +} + +MicroTileArray::MicroTileArray(int x, int y, int w, int h) + : m_x (x), m_y (y), m_w (w), m_h (h) +{ + m_uta = gem_uta_new_coords (x, y, w, h); + if (!m_uta) + error("MicroTileArray::MicroTileArray() Out of memory"); +} + +MicroTileArray::~MicroTileArray() { + if (m_uta) + gem_uta_free (m_uta); +} + +void MicroTileArray::clear() { + if (!m_uta) + return; + + memset (m_uta->tiles, 0, m_uta->width * m_uta->height * sizeof(GemUtaBBox)); +} + +void MicroTileArray::init(int x, int y, int w, int h) { + if (m_uta) + gem_uta_free (m_uta); + m_uta = gem_uta_new_coords (x, y, w, h); + m_x = x; + m_y = y; + m_w = w; + m_h = h; + if (!m_uta) + error("Out of memory"); +} + +int MicroTileArray::getRectangles(Common::Rect * & rects, int min_x, int max_x, int min_y, int max_y) const { + if (!m_uta) + return 0; + + int n_rects; + + rects = gem_uta_get_rects (m_uta, &n_rects, min_x, max_x, min_y, max_y); + + return n_rects; +} + +int MicroTileArray::getRectangles(Common::Rect * & rects) const { + if (!m_uta) + return 0; + + int n_rects; + + rects = gem_uta_get_rects (m_uta, &n_rects, + m_x, m_y, m_x + m_w - 1, m_y + m_h - 1); + + return n_rects; +} + +bool MicroTileArray::contains(const Common::Rect & rect) const { + if (!m_uta) + return false; + + GemRect r; + r.x0 = rect.left; + r.y0 = rect.top; + r.x1 = rect.right; // CHECK + r.y1 = rect.bottom; // CHECK + + return gem_uta_query_rect (m_uta, &r, GEM_UTA_QUERY_CONTAIN); +} + +bool MicroTileArray::intersects(const Common::Rect & rect) const { + if (!m_uta) + return false; + + GemRect r; + r.x0 = rect.left; + r.y0 = rect.top; + r.x1 = rect.right; // CHECK + r.y1 = rect.bottom; // CHECK + + return gem_uta_query_rect (m_uta, &r, GEM_UTA_QUERY_INTERSECT); +} + +void MicroTileArray::unite(const Common::Rect & rect) { + if (!m_uta || rect.width() == 0 || rect.height() == 0) + return; + + GemRect r; + r.x0 = rect.left; + r.y0 = rect.top; + r.x1 = rect.right; // CHECK + r.y1 = rect.bottom; // CHECK + + gem_uta_add_rect (m_uta, &r); +} + +MicroTileArray & MicroTileArray::operator += (const Common::Rect & rect) { + if (!m_uta || rect.width() == 0 || rect.height() == 0) + return *this; + + GemRect r; + r.x0 = rect.left; + r.y0 = rect.top; + r.x1 = rect.right; // CHECK + r.y1 = rect.bottom; // CHECK + + gem_uta_add_rect (m_uta, &r); + + return *this; +} + +void MicroTileArray::unite (const MicroTileArray & uta) { + if (m_uta) + gem_uta_union (m_uta, uta.m_uta); +} + +MicroTileArray & MicroTileArray::operator += (const MicroTileArray & uta) { + if (m_uta) + gem_uta_union (m_uta, uta.m_uta); + return *this; +} + +} // namespace Toltecs + diff --git a/engines/toltecs/microtiles.h b/engines/toltecs/microtiles.h new file mode 100644 index 0000000000..21dd5a9fcf --- /dev/null +++ b/engines/toltecs/microtiles.h @@ -0,0 +1,105 @@ +/* + SEL - Simple DirectMedia Layer Extension Library + Copyright (C) 2002 Matej Knopp <knopp@users.sf.net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef TOLTECS_MICROTILES_H +#define TOLTECS_MICROTILES_H + +#include "common/rect.h" + +namespace Toltecs { + +//! Class that represents a microtile array. +/*! + Microtile array is an efficient method of representing regions that + need to be redrawn. For more information about the microtile arrays + in general visit the LibArt homepage at + http://www.levien.com/libart/uta.html . + + Note that this implementation is not the one of LibArt and + differs from it. + */ +class MicroTileArray { +public: + //! Create an empty unitialized uta. + /* + \note You must initialize the class using + Uta::init() before doing anything with it. + */ + MicroTileArray(); + + //! Create a new microtile array with given coordinates. + MicroTileArray(int x, int y, int w, int h); + + //! Destroy the microtile array. + ~MicroTileArray(); + + //! Clear the microtile array. + void clear(); + + //! Initialize the array. + /* + You can use this funtion to resize the array as well, + but you should be aware that the content of the array + will be cleared. + */ + void init(int x, int y, int w, int h); + + //! Return the microtile array as rectangles. + /*! + The \a rects array should be freed when no longer needed. + \return The number of rectangles in \a rects. + */ + int getRectangles(Common::Rect * & rects, + int min_x, int max_x, int min_y, int max_y) const; + + //! Return the microtile array as rectangles. + /*! + The \a rects array should be freed when no longer needed. + \return The number of rectangles in \a rects. + */ + int getRectangles(Common::Rect * & rects) const; + + //! Whether the microtile array contains given rectangle. + bool contains(const Common::Rect &) const; + + //! Whether the microtile array intersects given rectangle. + bool intersects(const Common::Rect &) const; + + //! Unite the microtile array with a rectangle. + void unite(const Common::Rect &); + + //! Unite the microtile array with a rectangle. + MicroTileArray & operator+=(const Common::Rect &); + + //! Unite the array with another microtile array. + void unite(const MicroTileArray &); + + //! Unite the array with another microtile array. + MicroTileArray & operator+=(const MicroTileArray &); + +protected: + typedef struct _GemUta GemUta; + GemUta *m_uta; + int m_x, m_y, m_w, m_h; +}; // class Uta + +} // namespace Toltecs + + +#endif // TOLTECS_MICROTILES_H diff --git a/engines/toltecs/module.mk b/engines/toltecs/module.mk index 541bf6be70..0d658f6095 100644 --- a/engines/toltecs/module.mk +++ b/engines/toltecs/module.mk @@ -3,6 +3,9 @@ MODULE := engines/toltecs MODULE_OBJS = \ animation.o \ detection.o \ + menu.o \ + microtiles.o \ + movie.o \ palette.o \ toltecs.o \ resource.o \ diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp new file mode 100644 index 0000000000..ef280fa508 --- /dev/null +++ b/engines/toltecs/movie.cpp @@ -0,0 +1,179 @@ +/* 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/events.h" +#include "common/keyboard.h" +#include "common/file.h" +#include "common/savefile.h" +#include "common/config-manager.h" + +#include "base/plugins.h" +#include "base/version.h" + +#include "sound/mixer.h" + +#include "toltecs/toltecs.h" +#include "toltecs/movie.h" +#include "toltecs/palette.h" +#include "toltecs/resource.h" +#include "toltecs/screen.h" +#include "toltecs/script.h" + +namespace Toltecs { + +MoviePlayer::MoviePlayer(ToltecsEngine *vm) : _vm(vm) { +} + +MoviePlayer::~MoviePlayer() { +} + +void MoviePlayer::playMovie(uint resIndex) { + + uint32 chunkCount, frameCount, subtitleSlot; + byte moviePalette[768]; + + memset(moviePalette, 0, sizeof(moviePalette)); + + _vm->_screen->finishTextDrawItems(); + _vm->_screen->clearSprites(); + + _vm->_arc->openResource(resIndex); + + frameCount = _vm->_arc->readUint32LE(); + chunkCount = _vm->_arc->readUint32LE(); + subtitleSlot = kMaxScriptSlots - 1; + + // TODO: Read/figure out rest of the header + _vm->_arc->seek(0x10, SEEK_CUR); + _vm->_sceneWidth = 640; + _vm->_sceneHeight = 400; + _vm->_cameraHeight = 400; + _vm->_cameraX = 0; + _vm->_cameraY = 0; + + while (chunkCount--) { + + byte chunkType; + uint32 chunkSize; + byte *chunkBuffer; + uint32 movieOffset; + + chunkType = _vm->_arc->readByte(); + chunkSize = _vm->_arc->readUint32LE(); + + debug(0, "chunkType = %d; chunkSize = %d", chunkType, chunkSize); + + chunkBuffer = new byte[chunkSize]; + _vm->_arc->read(chunkBuffer, chunkSize); + + movieOffset = _vm->_arc->pos(); + + switch (chunkType) { + case 0: // image data + case 1: + unpackRle(chunkBuffer, _vm->_screen->_backScreen); + // TODO: Rework this + _vm->_screen->updateShakeScreen(); + _vm->updateInput(); + _vm->updateScreen(); + g_system->delayMillis(80); + break; + case 2: // palette data + unpackPalette(chunkBuffer, moviePalette, 256, 3); + _vm->_palette->setFullPalette(moviePalette); + break; + //case 3: -- what is this type + case 4: // audio data + // TODO: Handle audio data + break; + case 5: + // TODO: Check if the text is a subtitle (last character == 0xFE). + // If so, don't show it if text display is disabled. + memcpy(_vm->_script->getSlotData(subtitleSlot), chunkBuffer, chunkSize); + _vm->_screen->updateTalkText(subtitleSlot, 0); + break; + case 6: // start/stop shakescreen effect + if (chunkBuffer[0] == 0xFF) + _vm->_screen->stopShakeScreen(); + else + _vm->_screen->startShakeScreen(chunkBuffer[0]); + break; + case 7: // setup subtitle parameters + _vm->_screen->_talkTextY = READ_LE_UINT16(&chunkBuffer[0]); + _vm->_screen->_talkTextX = READ_LE_UINT16(&chunkBuffer[2]); + _vm->_screen->_talkTextFontColor = chunkBuffer[4]; + debug(0, "_talkTextX = %d; _talkTextY = %d; _talkTextFontColor = %d", + _vm->_screen->_talkTextX, _vm->_screen->_talkTextY, _vm->_screen->_talkTextFontColor); + break; + case 8: // stop subtitles + _vm->_script->getSlotData(subtitleSlot)[0] = 0xFF; + _vm->_screen->finishTextDrawItems(); + break; + default: + error("Unknown chunk type %d at %08X", chunkType, _vm->_arc->pos() - 5 - chunkSize); + } + + delete[] chunkBuffer; + + _vm->_arc->seek(movieOffset, SEEK_SET); + + } + + _vm->_arc->closeResource(); + +} + +void MoviePlayer::unpackPalette(byte *source, byte *dest, int elemCount, int elemSize) { + int ofs = 0, size = elemCount * elemSize; + while (ofs < size) { + byte len; + len = *source++; + if (len == 0) { + len = *source++; + } else { + byte value = *source++; + memset(dest, value, len); + } + ofs += len; + dest += len; + } +} + +void MoviePlayer::unpackRle(byte *source, byte *dest) { + int size = 256000; + while (size > 0) { + byte a = *source++; + byte b = *source++; + if (a == 0) { + dest += b; + size -= b; + } else { + memset(dest, b, a); + dest += a; + size -= a; + } + } +} + + +} // End of namespace Toltecs diff --git a/engines/toltecs/movie.h b/engines/toltecs/movie.h new file mode 100644 index 0000000000..9ab5435121 --- /dev/null +++ b/engines/toltecs/movie.h @@ -0,0 +1,65 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 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 TOLTECS_MOVIE_H +#define TOLTECS_MOVIE_H + +#include "common/scummsys.h" +#include "common/endian.h" +#include "common/util.h" +#include "common/file.h" +#include "common/savefile.h" +#include "common/system.h" +#include "common/hash-str.h" +#include "common/events.h" +#include "common/keyboard.h" +#include "common/array.h" + +#include "sound/audiostream.h" +#include "sound/mixer.h" +#include "sound/voc.h" +#include "sound/audiocd.h" + +#include "engines/engine.h" + +namespace Toltecs { + +class MoviePlayer { + +public: + MoviePlayer(ToltecsEngine *vm); + ~MoviePlayer(); + + void playMovie(uint resIndex); + +protected: + ToltecsEngine *_vm; + + void unpackPalette(byte *source, byte *dest, int elemCount, int elemSize); + void unpackRle(byte *source, byte *dest); + +}; + +} // End of namespace Toltecs + +#endif /* TOLTECS_MOVIE_H */ |