scummvm/engines/tony/gfxcore.h

504 lines
13 KiB
C
Raw Normal View History

/* 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.
*
*/
2012-05-14 07:43:50 +02:00
/*
* This code is based on original Tony Tough source code
*
* Copyright (c) 1997-2003 Nayma Software
*/
#ifndef TONY_GFXCORE_H
#define TONY_GFXCORE_H
#include "common/system.h"
#include "common/coroutines.h"
#include "tony/utils.h"
namespace Tony {
/****************************************************************************\
* Class prototype
\****************************************************************************/
2012-05-21 23:53:13 +02:00
// Class Name Family Treee Abstract?
class RMGfxTask; // Yes
class RMGfxTaskSetPrior; // Task Yes
class RMGfxBuffer; //
class RMGfxSourceBuffer; // TaskP+[Buffer] Yes
class RMGfxTargetBuffer; // [Buffer]
class RMGfxSourceBufferPal; // Source Yes
class RMGfxSourceBuffer4; // SourcePal
class RMGfxSourceBuffer8; // SourcePal
class RMGfxSourceBuffer16; // Source
class RMGfxWoodyBuffer; // Source16+Target
class RMGfxClearTask; // Task
/**
* Graphics buffer
*/
class RMGfxBuffer {
protected:
2012-06-05 08:39:55 +02:00
int _dimx, _dimy;
byte *_buf;
byte *_origBuf;
public:
2012-05-14 21:29:27 +02:00
RMGfxBuffer();
RMGfxBuffer(int dimx, int dimy, int nBpp);
2012-05-14 21:29:27 +02:00
virtual ~RMGfxBuffer();
2012-05-14 21:29:27 +02:00
// Attributes
int getDimx();
int getDimy();
2012-05-14 21:29:27 +02:00
// Creation
void create(int dimx, int dimy, int nBpp);
virtual void destroy();
2012-05-14 21:29:27 +02:00
// These are valid only if the buffer is locked
operator byte *();
operator void *();
// Getting the offset for a given Y position
2012-06-05 08:39:55 +02:00
void offsetY(int nLines, int nBpp);
};
/**
2012-05-14 21:29:27 +02:00
* Graphics primitive
*/
class RMGfxPrimitive {
public:
2012-06-05 08:39:55 +02:00
RMGfxTask *_task;
protected:
2012-06-05 08:39:55 +02:00
RMRect _src;
RMRect _dst;
2012-06-05 08:39:55 +02:00
bool _bStretch;
byte _bFlag;
public:
RMGfxPrimitive();
RMGfxPrimitive(RMGfxTask *task);
RMGfxPrimitive(RMGfxTask *task, const RMRect &src, RMRect &dst);
RMGfxPrimitive(RMGfxTask *task, const RMPoint &src, RMRect &dst);
RMGfxPrimitive(RMGfxTask *task, const RMPoint &src, RMPoint &dst);
RMGfxPrimitive(RMGfxTask *task, const RMRect &src, RMPoint &dst);
RMGfxPrimitive(RMGfxTask *task, const RMRect &dst);
RMGfxPrimitive(RMGfxTask *task, const RMPoint &dst);
virtual ~RMGfxPrimitive();
void setFlag(byte bFlag);
void setTask(RMGfxTask *task);
void setSrc(const RMRect &src);
void setSrc(const RMPoint &src);
void setDst(const RMRect &dst);
void setDst(const RMPoint &dst);
void setStretch(bool bStretch);
bool haveDst();
RMRect &getDst();
bool haveSrc();
RMRect &getSrc();
// Flags
bool isFlipped();
// Duplicate
virtual RMGfxPrimitive *duplicate();
};
/**
* Graphic drawing task
*/
class RMGfxTask {
protected:
2012-06-05 08:39:55 +02:00
int _nPrior;
int _nInList;
public:
// Standard constructor
2012-05-14 21:29:27 +02:00
RMGfxTask();
virtual ~RMGfxTask() { }
2012-06-05 08:39:55 +02:00
virtual int priority();
virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) = 0;
virtual void removeThis(CORO_PARAM, bool &result);
2012-05-14 21:29:27 +02:00
// Registration
2012-09-02 10:34:11 +02:00
virtual void Register();
virtual void unregister();
};
/**
* Graphic drawing with priority
*/
class RMGfxTaskSetPrior : public RMGfxTask {
public:
virtual ~RMGfxTaskSetPrior() { }
2012-06-05 08:39:55 +02:00
void setPriority(int nPrior);
};
/**
* Task that cleans the destination buffer
*/
class RMGfxClearTask : public RMGfxTask {
public:
virtual ~RMGfxClearTask() { }
2012-06-05 18:51:20 +02:00
int priority();
2012-06-05 08:39:55 +02:00
virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim);
virtual void removeThis(CORO_PARAM, bool &result);
};
/**
* Task that draws a colored box
*/
2012-05-14 21:29:27 +02:00
class RMGfxBox : public RMGfxTaskSetPrior {
protected:
2012-06-07 21:14:59 +02:00
uint16 _wFillColor;
public:
virtual ~RMGfxBox() { }
2012-06-07 21:14:59 +02:00
void setColor(byte r, byte g, byte b);
2012-06-05 08:39:55 +02:00
virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim);
virtual void removeThis(CORO_PARAM, bool &result);
};
/**
* Buffer source for the design, which is a task. This is an abstract base.
*/
class RMGfxSourceBuffer : public virtual RMGfxBuffer, public RMGfxTaskSetPrior {
public:
// Load the data for the surface
2012-06-05 08:39:55 +02:00
virtual int init(uint32 resID, int dimx, int dimy, bool bLoadPalette = false);
virtual int init(const byte *buf, int dimx, int dimy, bool bLoadPalette = false);
2012-08-28 14:26:00 +02:00
virtual void init(Common::ReadStream &ds, int dimx, int dimy, bool bLoadPalette = false);
2012-05-14 21:29:27 +02:00
virtual ~RMGfxSourceBuffer();
protected:
virtual void prepareImage();
2012-06-05 08:39:55 +02:00
bool clip2D(int &x1, int &y1, int &u, int &v, int &width, int &height, bool bUseSrc, RMGfxTargetBuffer *buf);
2012-09-02 10:34:11 +02:00
void offsetY(int nLines);
public:
2012-06-07 21:14:59 +02:00
virtual int getBpp() = 0;
};
/**
* 16-bit color source
*/
class RMGfxSourceBuffer16 : public RMGfxSourceBuffer {
2013-08-01 22:55:40 +02:00
public:
virtual void prepareImage();
2013-08-01 22:55:40 +02:00
protected:
2012-06-05 08:39:55 +02:00
bool _bTrasp0;
2012-05-14 21:29:27 +02:00
public:
2012-05-14 21:29:27 +02:00
RMGfxSourceBuffer16(bool bUseTrasp = false);
RMGfxSourceBuffer16(int dimx, int dimy);
virtual ~RMGfxSourceBuffer16();
// Initialization
void create(int dimx, int dimy);
2012-06-07 21:14:59 +02:00
int getBpp();
2012-06-05 08:39:55 +02:00
virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim);
};
/**
* Buffer source with palette
*/
class RMGfxSourceBufferPal : public RMGfxSourceBuffer {
protected:
// The size of the palette is (1 << Bpp()) * 4
2012-06-05 08:39:55 +02:00
byte _pal[256 * 3];
uint16 _palFinal[256];
// Post process to prepare the palette for drawing
virtual void preparePalette();
public:
virtual ~RMGfxSourceBufferPal();
2012-06-05 08:39:55 +02:00
virtual int init(const byte *buf, int dimx, int dimy, bool bLoadPalette = false);
2012-08-28 14:26:00 +02:00
virtual void init(Common::ReadStream &ds, int dimx, int dimy, bool bLoadPalette = false);
2012-05-14 21:29:27 +02:00
2012-06-05 08:39:55 +02:00
int loadPaletteWA(uint32 resID, bool bSwapped = false);
int loadPaletteWA(const byte *buf, bool bSwapped = false);
int loadPalette(uint32 resID);
int loadPalette(const byte *buf);
};
/**
* Buffer source with a 256 color palette
*/
class RMGfxSourceBuffer8 : public RMGfxSourceBufferPal {
protected:
2012-06-05 08:39:55 +02:00
bool _bTrasp0;
2012-05-14 21:29:27 +02:00
public:
RMGfxSourceBuffer8(bool bTrasp0 = true);
RMGfxSourceBuffer8(int dimx, int dimy);
virtual ~RMGfxSourceBuffer8();
// Initialization
void create(int dimx, int dimy);
2012-06-07 21:14:59 +02:00
int getBpp();
2012-06-05 08:39:55 +02:00
virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim);
};
/**
* Buffer source with a 256 color palette, and alpha blending
*/
class RMGfxSourceBuffer8AB : public RMGfxSourceBuffer8 {
protected:
2012-06-05 08:39:55 +02:00
int calcTrasp(int f, int b);
public:
virtual ~RMGfxSourceBuffer8AB();
2012-06-05 08:39:55 +02:00
virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim);
};
/**
* Buffer source with a 256 color palette, RLE compressed
*/
class RMGfxSourceBuffer8RLE : public virtual RMGfxSourceBuffer8 {
protected:
2012-06-07 21:14:59 +02:00
int _alphaBlendColor;
int _alphaR, _alphaB, _alphaG;
bool _bNeedRLECompress;
protected:
2012-06-07 21:14:59 +02:00
static byte _megaRLEBuf[];
2012-05-14 21:29:27 +02:00
virtual void rleWriteTrasp(byte *&cur, int rep) = 0;
virtual void rleWriteData(byte *&cur, int rep, byte *src) = 0;
virtual void rleWriteEOL(byte *&cur) = 0;
virtual void rleWriteAlphaBlend(byte *&cur, int rep) = 0;
virtual void rleDecompressLine(uint16 *dst, byte *src, int nStartSkip, int nLength) = 0;
virtual void rleDecompressLineFlipped(uint16 *dst, byte *src, int nStartSkip, int nLength) = 0;
// Perform image compression in RLE
void compressRLE();
2012-05-14 21:29:27 +02:00
protected:
// Overriding initialization methods
virtual void prepareImage();
virtual void preparePalette();
public:
RMGfxSourceBuffer8RLE();
virtual ~RMGfxSourceBuffer8RLE();
// Overload of the initialization method
2012-08-28 14:26:00 +02:00
virtual void init(Common::ReadStream &ds, int dimx, int dimy, bool bLoadPalette = false);
2012-06-05 08:39:55 +02:00
virtual int init(const byte *buf, int dimx, int dimy, bool bLoadPalette = false);
// Draw image with RLE decompression
2012-06-05 08:39:55 +02:00
virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim);
// Sets the color that will be alpha blended
2012-06-05 08:39:55 +02:00
void setAlphaBlendColor(int color);
// Warn if the data is already compressed
void setAlreadyCompressed();
};
class RMGfxSourceBuffer8RLEByte : public RMGfxSourceBuffer8RLE {
protected:
void rleWriteTrasp(byte * &cur, int rep);
void rleWriteAlphaBlend(byte * &cur, int rep);
void rleWriteData(byte * &cur, int rep, byte *src);
void rleWriteEOL(byte * &cur);
void rleDecompressLine(uint16 *dst, byte *src, int nStartSkip, int nLength);
void rleDecompressLineFlipped(uint16 *dst, byte *src, int nStartSkip, int nLength);
public:
virtual ~RMGfxSourceBuffer8RLEByte();
};
class RMGfxSourceBuffer8RLEWord : public RMGfxSourceBuffer8RLE {
protected:
void rleWriteTrasp(byte * &cur, int rep);
void rleWriteAlphaBlend(byte * &cur, int rep);
void rleWriteData(byte * &cur, int rep, byte *src);
void rleWriteEOL(byte * &cur);
virtual void rleDecompressLine(uint16 *dst, byte *src, int nStartSkip, int nLength);
virtual void rleDecompressLineFlipped(uint16 *dst, byte *src, int nStartSkip, int nLength);
public:
virtual ~RMGfxSourceBuffer8RLEWord();
};
class RMGfxSourceBuffer8RLEWordAB : public RMGfxSourceBuffer8RLEWord {
protected:
virtual void rleDecompressLine(uint16 *dst, byte *src, int nStartSkip, int nLength);
public:
virtual ~RMGfxSourceBuffer8RLEWordAB();
};
/**
* Buffer source with a 256 color palette, with anti-aliasing
*/
class RMGfxSourceBuffer8AA : public virtual RMGfxSourceBuffer8 {
protected:
2012-06-07 21:14:59 +02:00
static byte _megaAABuf[];
static byte _megaAABuf2[];
2012-06-05 08:39:55 +02:00
byte *_aabuf;
// Calculate the buffer for the anti-aliasing
void calculateAA();
// Draw the AA
2012-06-05 08:39:55 +02:00
void drawAA(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim);
protected:
void prepareImage();
public:
RMGfxSourceBuffer8AA();
virtual ~RMGfxSourceBuffer8AA();
// Draw with anti-aliasing
2012-06-05 08:39:55 +02:00
virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim);
};
class RMGfxSourceBuffer8RLEByteAA : public RMGfxSourceBuffer8RLEByte, public RMGfxSourceBuffer8AA {
protected:
void prepareImage();
public:
2012-06-05 08:39:55 +02:00
virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim);
// Overloaded initialization methods
2012-08-28 14:26:00 +02:00
virtual void init(Common::ReadStream &ds, int dimx, int dimy, bool bLoadPalette = false);
2012-06-05 08:39:55 +02:00
virtual int init(const byte *buf, int dimx, int dimy, bool bLoadPalette = false);
virtual ~RMGfxSourceBuffer8RLEByteAA();
};
class RMGfxSourceBuffer8RLEWordAA : public RMGfxSourceBuffer8RLEWord, public RMGfxSourceBuffer8AA {
protected:
void prepareImage();
public:
2012-06-05 08:39:55 +02:00
virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim);
// Overloaded initialization methods
2012-08-28 14:26:00 +02:00
virtual void init(Common::ReadStream &ds, int dimx, int dimy, bool bLoadPalette = false);
virtual int init(const byte *buf, int dimx, int dimy, bool bLoadPalette = false);
virtual ~RMGfxSourceBuffer8RLEWordAA();
};
/**
* Source buffer with 16 colors
*/
class RMGfxSourceBuffer4 : public RMGfxSourceBufferPal {
public:
2012-05-14 21:29:27 +02:00
RMGfxSourceBuffer4();
RMGfxSourceBuffer4(int dimx, int dimy);
// Initialization
void create(int dimx, int dimy);
2012-06-07 21:14:59 +02:00
int getBpp();
2012-06-05 08:39:55 +02:00
virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim);
};
/**
* Destination buffer which manages its own internal list of tasks
*/
class RMGfxTargetBuffer : public virtual RMGfxBuffer {
private:
struct OTList {
RMGfxPrimitive *_prim;
OTList *_next;
OTList();
2012-05-14 21:29:27 +02:00
OTList(RMGfxPrimitive *pr) {
_prim = pr;
2016-06-17 12:06:46 +02:00
_next = NULL;
2012-05-14 21:29:27 +02:00
}
};
bool _trackDirtyRects;
Common::List<Common::Rect> _currentDirtyRects, _previousDirtyRects, _dirtyRects;
void mergeDirtyRects();
private:
//OSystem::MutexRef csModifyingOT;
protected:
2012-06-07 21:14:59 +02:00
OTList *_otlist;
2012-06-05 08:39:55 +02:00
int _otSize;
public:
RMGfxTargetBuffer();
virtual ~RMGfxTargetBuffer();
static uint16 *_precalcTable;
static void createBWPrecalcTable();
static void freeBWPrecalcTable();
// management of the OT list
void clearOT();
2012-06-05 08:39:55 +02:00
void drawOT(CORO_PARAM);
void addPrim(RMGfxPrimitive *prim); // The pointer must be delted
2012-09-02 10:34:11 +02:00
operator byte *();
operator void *();
operator uint16 *();
// Offseting buffer
2012-09-02 10:34:11 +02:00
void offsetY(int nLines);
// Dirty rect methods
void addDirtyRect(const Common::Rect &r);
Common::List<Common::Rect> &getDirtyRects();
void clearDirtyRects();
2012-09-02 10:34:11 +02:00
void setTrackDirtyRects(bool v);
bool getTrackDirtyRects() const;
};
/**
* Ring buffer, which is both source and by destination
*/
class RMGfxWoodyBuffer: public RMGfxSourceBuffer16, public RMGfxTargetBuffer {
public:
2012-05-14 21:29:27 +02:00
RMGfxWoodyBuffer();
RMGfxWoodyBuffer(int dimx, int dimy);
virtual ~RMGfxWoodyBuffer();
2012-06-05 08:39:55 +02:00
virtual void draw(CORO_PARAM, RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim);
};
} // End of namespace Tony
#endif