diff options
Diffstat (limited to 'engines/toltecs/screen.h')
-rw-r--r-- | engines/toltecs/screen.h | 378 |
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 */ |