aboutsummaryrefslogtreecommitdiff
path: root/engines/toltecs/screen.h
diff options
context:
space:
mode:
Diffstat (limited to 'engines/toltecs/screen.h')
-rw-r--r--engines/toltecs/screen.h378
1 files changed, 378 insertions, 0 deletions
diff --git a/engines/toltecs/screen.h b/engines/toltecs/screen.h
new file mode 100644
index 0000000000..352eeaec29
--- /dev/null
+++ b/engines/toltecs/screen.h
@@ -0,0 +1,378 @@
+/* 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_SCREEN_H
+#define TOLTECS_SCREEN_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/list.h"
+#include "common/array.h"
+
+#include "graphics/surface.h"
+
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+#include "sound/voc.h"
+#include "sound/audiocd.h"
+
+#include "engines/engine.h"
+
+namespace Toltecs {
+
+struct DrawRequest {
+ int16 x, y;
+ int16 resIndex;
+ uint16 flags;
+ int16 baseColor;
+ int8 scaling;
+};
+
+struct SpriteDrawItem {
+ int16 x, y;
+ int16 width, height;
+ int16 origWidth, origHeight;
+ int16 resIndex;
+ uint32 offset;
+ int16 xdelta, ydelta;
+ uint16 flags;
+ int16 value1, yerror;
+ int16 ybottom;
+ int16 baseColor;
+};
+
+struct SpriteFrameEntry {
+ int16 y, x, h, w;
+ uint32 offset;
+ SpriteFrameEntry() {
+ }
+ SpriteFrameEntry(byte *data) {
+ y = READ_LE_UINT16(data + 0);
+ x = READ_LE_UINT16(data + 2);
+ h = READ_LE_UINT16(data + 4);
+ w = READ_LE_UINT16(data + 6);
+ offset = READ_LE_UINT32(data + 8);
+ }
+};
+
+class Font {
+public:
+ Font(byte *fontData) : _fontData(fontData) {
+ }
+ ~Font() {
+ }
+ int16 getSpacing() const {
+ return _fontData[1];
+ }
+ int16 getHeight() const {
+ return _fontData[2];
+ }
+ int16 getWidth() const {
+ return _fontData[3];
+ }
+ int16 getCharWidth(byte ch) const {
+ return _fontData[4 + (ch - 0x21)];
+ }
+ byte *getCharData(byte ch) const {
+ return _fontData + 0x298 + READ_LE_UINT16(&_fontData[0xE0 + (ch - 0x21) * 2]);
+ }
+protected:
+ byte *_fontData;
+};
+
+//*BEGIN*TEST*CODE********************************************************************************************
+
+struct PixelPacket {
+ byte count;
+ byte pixel;
+};
+
+enum SpriteReaderStatus {
+ kSrsPixelsLeft,
+ kSrsEndOfLine,
+ kSrsEndOfSprite
+};
+
+class SpriteFilter {
+public:
+ SpriteFilter(SpriteDrawItem *sprite) : _sprite(sprite) {
+ }
+ virtual SpriteReaderStatus readPacket(PixelPacket &packet) = 0;
+protected:
+ SpriteDrawItem *_sprite;
+};
+
+class SpriteReader : public SpriteFilter {
+public:
+ SpriteReader(byte *source, SpriteDrawItem *sprite) : SpriteFilter(sprite), _source(source) {
+ _curWidth = _sprite->origWidth;
+ _curHeight = _sprite->origHeight;
+ }
+ SpriteReaderStatus readPacket(PixelPacket &packet) {
+ if ((_sprite->flags & 0x40) || (_sprite->flags & 0x10)) {
+ packet.pixel = *_source++;
+ packet.count = *_source++;
+ } else {
+ packet.count = _source[0] & 0x0F;
+ packet.pixel = (_source[0] & 0xF0) >> 4;
+ _source++;
+ }
+ _curWidth -= packet.count;
+ if (_curWidth <= 0) {
+ _curHeight--;
+ if (_curHeight == 0) {
+ return kSrsEndOfSprite;
+ } else {
+ _curWidth = _sprite->origWidth;
+ return kSrsEndOfLine;
+ }
+ } else {
+ return kSrsPixelsLeft;
+ }
+ }
+ byte *getSource() {
+ return _source;
+ }
+ void setSource(byte *source) {
+ _source = source;
+ _curHeight++;
+ }
+protected:
+ byte *_source;
+ int16 _curWidth, _curHeight;
+};
+
+class SpriteFilterScaleDown : public SpriteFilter {
+public:
+ SpriteFilterScaleDown(SpriteDrawItem *sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
+ _height = _sprite->height;
+ _yerror = _sprite->yerror;
+ _origHeight = _sprite->origHeight;
+ _scalerStatus = 0;
+ }
+ SpriteReaderStatus readPacket(PixelPacket &packet) {
+ SpriteReaderStatus status;
+ if (_scalerStatus == 0) {
+ _xerror = _sprite->xdelta;
+ _yerror -= 100;
+ while (_yerror <= 0) {
+ do {
+ status = _reader->readPacket(packet);
+ } while (status == kSrsPixelsLeft);
+ _yerror += _sprite->ydelta - 100;
+ }
+ if (status == kSrsEndOfSprite)
+ return kSrsEndOfSprite;
+ _scalerStatus = 1;
+ }
+ if (_scalerStatus == 1) {
+ status = _reader->readPacket(packet);
+ byte updcount = packet.count;
+ while (updcount--) {
+ _xerror -= 100;
+ if (_xerror <= 0) {
+ if (packet.count > 0)
+ packet.count--;
+ _xerror += _sprite->xdelta;
+ }
+ }
+ if (status == kSrsEndOfLine) {
+ if (--_height == 0)
+ return kSrsEndOfSprite;
+ _scalerStatus = 0;
+ return kSrsEndOfLine;
+ }
+ }
+ return kSrsPixelsLeft;
+ }
+protected:
+ SpriteReader *_reader;
+ int16 _xerror, _yerror;
+ int16 _height;
+ int16 _origHeight;
+ int _scalerStatus;
+};
+
+class SpriteFilterScaleUp : public SpriteFilter {
+public:
+ SpriteFilterScaleUp(SpriteDrawItem *sprite, SpriteReader *reader) : SpriteFilter(sprite), _reader(reader) {
+ _height = _sprite->height;
+ _yerror = _sprite->yerror;
+ _origHeight = _sprite->origHeight;
+ _scalerStatus = 0;
+ }
+ SpriteReaderStatus readPacket(PixelPacket &packet) {
+ SpriteReaderStatus status;
+ if (_scalerStatus == 0) {
+ _xerror = _sprite->xdelta;
+ _sourcep = _reader->getSource();
+ _scalerStatus = 1;
+ }
+ if (_scalerStatus == 1) {
+ status = _reader->readPacket(packet);
+ byte updcount = packet.count;
+ while (updcount--) {
+ _xerror -= 100;
+ if (_xerror <= 0) {
+ packet.count++;
+ _xerror += _sprite->xdelta;
+ }
+ }
+ if (status == kSrsEndOfLine) {
+ if (--_height == 0)
+ return kSrsEndOfSprite;
+ _yerror -= 100;
+ if (_yerror <= 0) {
+ _reader->setSource(_sourcep);
+ _yerror += _sprite->ydelta + 100;
+ }
+ _scalerStatus = 0;
+ return kSrsEndOfLine;
+ }
+ }
+ return kSrsPixelsLeft;
+ }
+protected:
+ SpriteReader *_reader;
+ byte *_sourcep;
+ int16 _xerror, _yerror;
+ int16 _height;
+ int16 _origHeight;
+ int _scalerStatus;
+};
+
+//*END*TEST*CODE**********************************************************************************************
+
+struct TextRect {
+ int16 x, y;
+ int16 width, length;
+};
+
+struct TalkTextItem {
+ int16 duration;
+ int16 slotIndex;
+ int16 slotOffset;
+ int16 fontNum;
+ byte color;
+ byte rectCount;
+ TextRect rects[15];
+};
+
+class Screen {
+public:
+ Screen(ToltecsEngine *vm);
+ ~Screen();
+
+ void unpackRle(byte *source, byte *dest, uint16 width, uint16 height);
+
+ void loadMouseCursor(uint resIndex);
+
+ void drawGuiImage(int16 x, int16 y, uint resIndex);
+
+ void startShakeScreen(int16 shakeCounter);
+ void stopShakeScreen();
+ void updateShakeScreen();
+
+ // Sprite list
+ void addStaticSprite(byte *spriteItem);
+ void addAnimatedSprite(int16 x, int16 y, int16 fragmentId, byte *data, int16 *spriteArray, bool loop, int mode);
+ void clearSprites();
+
+ // Sprite drawing
+ void drawSprite(SpriteDrawItem *sprite);
+ void drawSpriteCore(byte *dest, SpriteFilter &reader, SpriteDrawItem *sprite);
+ void drawSprites();
+
+ // Verb line
+ void updateVerbLine(int16 slotIndex, int16 slotOffset);
+
+ // Talk text
+ void updateTalkText(int16 slotIndex, int16 slotOffset);
+ void addTalkTextRect(Font &font, int16 x, int16 &y, int16 length, int16 width, TalkTextItem *item);
+ void drawTalkTextItems();
+ int16 getTalkTextDuration();
+
+ // Font/text
+ void registerFont(uint fontIndex, uint resIndex);
+ void printText(byte *textData);
+ void preprocessText(uint fontResIndex, int maxWidth, int &width, byte *&sourceString, byte *&destString, byte &len);
+ void drawString(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex);
+ void drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color);
+ void drawChar2(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color);
+
+//protected:
+public:
+
+ struct VerbLineItem {
+ int16 slotIndex;
+ int16 slotOffset;
+ };
+
+ struct Rect {
+ int16 x, y, width, height;
+ };
+
+ ToltecsEngine *_vm;
+
+ byte *_frontScreen, *_backScreen;
+
+ Common::List<SpriteDrawItem> _spriteDrawList;
+
+ uint _fontResIndexArray[10];
+ byte _fontColor1, _fontColor2;
+
+ byte _tempString[100];
+ byte _tempStringLen1, _tempStringLen2;
+
+ // Screen shaking
+ bool _shakeActive;
+ int16 _shakeCounterInit, _shakeCounter;
+ int _shakePos;
+
+ // Verb line
+ int16 _verbLineNum;
+ VerbLineItem _verbLineItems[8];
+ int16 _verbLineX, _verbLineY, _verbLineWidth;
+ int16 _verbLineCount;
+
+ // Talk text
+ int16 _talkTextX, _talkTextY;
+ int16 _talkTextMaxWidth;
+ byte _talkTextFontColor;
+ int16 _talkTextItemNum;
+ TalkTextItem _talkTextItems[5];
+
+ void addDrawRequest(const DrawRequest &drawRequest);
+
+};
+
+} // End of namespace Toltecs
+
+#endif /* TOLTECS_SCREEN_H */