2002-03-22 03:31:55 +00:00
|
|
|
/* ScummVM - Scumm Interpreter
|
|
|
|
* Copyright (C) 2001 Ludvig Strigeus
|
2004-01-06 12:45:34 +00:00
|
|
|
* Copyright (C) 2001-2004 The ScummVM project
|
2002-03-22 03:31:55 +00:00
|
|
|
*
|
|
|
|
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*
|
|
|
|
* $Header$
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2002-07-17 20:55:36 +00:00
|
|
|
#ifndef GFX_H
|
|
|
|
#define GFX_H
|
|
|
|
|
2003-05-15 21:57:38 +00:00
|
|
|
#include "common/rect.h"
|
2004-08-08 22:10:38 +00:00
|
|
|
#include "graphics/surface.h"
|
2003-05-15 21:57:38 +00:00
|
|
|
|
2003-10-03 18:33:57 +00:00
|
|
|
namespace Scumm {
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
class ScummEngine;
|
2003-09-05 20:18:20 +00:00
|
|
|
|
2004-01-03 21:22:07 +00:00
|
|
|
/** Camera modes */
|
|
|
|
enum {
|
|
|
|
kNormalCameraMode = 1,
|
|
|
|
kFollowActorCameraMode = 2,
|
|
|
|
kPanningCameraMode = 3
|
2002-03-22 03:30:57 +00:00
|
|
|
};
|
|
|
|
|
2004-01-03 21:22:07 +00:00
|
|
|
/** Camera state data */
|
|
|
|
struct CameraData {
|
2003-10-02 17:43:02 +00:00
|
|
|
Common::Point _cur;
|
|
|
|
Common::Point _dest;
|
|
|
|
Common::Point _accel;
|
|
|
|
Common::Point _last;
|
2002-03-22 03:30:57 +00:00
|
|
|
int _leftTrigger, _rightTrigger;
|
|
|
|
byte _follows, _mode;
|
|
|
|
bool _movingToActor;
|
|
|
|
};
|
|
|
|
|
2004-01-03 21:22:07 +00:00
|
|
|
/** Virtual screen identifiers */
|
2004-01-03 22:45:23 +00:00
|
|
|
enum VirtScreenNumber {
|
2004-01-03 21:22:07 +00:00
|
|
|
kMainVirtScreen = 0, // The 'stage'
|
|
|
|
kTextVirtScreen = 1, // In V1-V3 games: the area where text is printed
|
2004-01-03 22:45:23 +00:00
|
|
|
kVerbVirtScreen = 2, // The verb area
|
|
|
|
kUnkVirtScreen = 3 // ?? Not sure what this one is good for...
|
2004-01-03 21:22:07 +00:00
|
|
|
};
|
|
|
|
|
2004-01-06 11:47:34 +00:00
|
|
|
/**
|
|
|
|
* In all Scumm games, one to four virtual screen (or 'windows') together make
|
|
|
|
* up the content of the actual screen. Thinking of virtual screens as fixed
|
|
|
|
* size, fixed location windows might help understanding them. Typical, in all
|
|
|
|
* scumm games there is either one single virtual screen covering the entire
|
|
|
|
* real screen (mostly in all newer games, e.g. Sam & Max, and all V7+ games).
|
|
|
|
* The classic setup consists of three virtual screens: one at the top of the
|
|
|
|
* screen, where all conversation texts are printed; then the main one (which
|
|
|
|
* I like calling 'the stage', since all the actors are doing their stuff
|
|
|
|
* there), and finally the lower part of the real screen is taken up by the
|
|
|
|
* verb area.
|
|
|
|
* Finally, in V5 games and some V6 games, it's almost the same as in the
|
|
|
|
* original games, except that there is no separate conversation area.
|
|
|
|
*
|
|
|
|
* If you now wonder what the last screen is/was good for: I am not 100% sure,
|
|
|
|
* but it appears that it was used by the original engine to display stuff
|
|
|
|
* like the pause message, or questions ("Do you really want to restart?").
|
|
|
|
* It seems that it is not used at all by ScummVM, so we probably could just
|
|
|
|
* get rid of it and save a couple kilobytes of RAM.
|
|
|
|
*
|
2004-01-06 12:16:28 +00:00
|
|
|
* Each of these virtual screens has a fixed number or id (see also
|
|
|
|
* \ref VirtScreenNumber).
|
2004-01-06 11:47:34 +00:00
|
|
|
*/
|
2004-08-14 19:42:00 +00:00
|
|
|
struct VirtScreen : Graphics::Surface {
|
2004-01-06 11:47:34 +00:00
|
|
|
/**
|
2004-01-06 11:52:12 +00:00
|
|
|
* The unique id of this screen (corresponds to its position in the
|
2004-01-06 11:47:34 +00:00
|
|
|
* ScummEngine:virtscr array).
|
|
|
|
*/
|
2004-01-03 22:45:23 +00:00
|
|
|
VirtScreenNumber number;
|
2004-01-06 11:47:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Vertical position of the virtual screen. Tells how much the virtual
|
|
|
|
* screen is shifted along the y axis relative to the real screen.
|
|
|
|
* If you wonder why there is no horizontal position: there is none,
|
|
|
|
* because all virtual screens are always exactly as wide as the
|
|
|
|
* real screen. This might change in the future to allow smooth
|
|
|
|
* horizontal scrolling in V7-V8 games.
|
|
|
|
*/
|
2002-03-22 03:30:57 +00:00
|
|
|
uint16 topline;
|
2004-01-06 11:47:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Horizontal scroll offset, tells how far the screen is scrolled to the
|
2004-01-06 12:16:28 +00:00
|
|
|
* right. Only used for the main screen. After all, verbs and the
|
|
|
|
* conversation text box don't have to scroll.
|
2004-01-06 11:47:34 +00:00
|
|
|
*/
|
2002-03-22 03:30:57 +00:00
|
|
|
uint16 xstart;
|
2004-01-06 11:47:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Flag indicating which tells whether this screen has a back buffer or
|
|
|
|
* not. This is yet another feature which is only used by the main screen.
|
|
|
|
* Strictly spoken one could remove this variable and replace checks
|
|
|
|
* on it with checks on backBuf. But since some code needs to temporarily
|
|
|
|
* disable the backBuf (so it can abuse drawBitmap; see drawVerbBitmap()
|
|
|
|
* and useIm01Cursor()), we keep it (at least for now).
|
|
|
|
*/
|
|
|
|
bool hasTwoBuffers;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Pointer to the screen's back buffer, if it has one (see also
|
|
|
|
* the hasTwoBuffers member).
|
|
|
|
* The backBuf is used by drawBitmap to store the background graphics of
|
|
|
|
* the active room. This eases redrawing: whenever a portion of the screen
|
|
|
|
* has to be redrawn, first a copy from the backBuf content to screenPtr is
|
|
|
|
* performed. Then, any objects/actors in that area are redrawn atop that.
|
|
|
|
*/
|
2002-03-22 03:30:57 +00:00
|
|
|
byte *backBuf;
|
2003-06-01 14:30:26 +00:00
|
|
|
|
2004-01-06 11:47:34 +00:00
|
|
|
/**
|
|
|
|
* Array containing for each visible strip of this virtual screen the
|
|
|
|
* coordinate at which the dirty region of that strip starts.
|
|
|
|
* 't' stands for 'top' - the top coordinate of the dirty region.
|
|
|
|
* This together with bdirty is used to do efficient redrawing of
|
|
|
|
* the screen.
|
|
|
|
*/
|
|
|
|
uint16 tdirty[80];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Array containing for each visible strip of this virtual screen the
|
|
|
|
* coordinate at which the dirty region of that strip end.
|
|
|
|
* 'b' stands for 'bottom' - the bottom coordinate of the dirty region.
|
|
|
|
* This together with tdirty is used to do efficient redrawing of
|
|
|
|
* the screen.
|
|
|
|
*/
|
|
|
|
uint16 bdirty[80];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convenience method to set the whole tdirty and bdirty arrays to one
|
|
|
|
* specific value each. This is mostly used to mark every as dirty in
|
|
|
|
* a single step, like so:
|
|
|
|
* vs->setDirtyRange(0, vs->height);
|
|
|
|
* or to mark everything as clean, like so:
|
|
|
|
* vs->setDirtyRange(0, 0);
|
|
|
|
*/
|
2003-06-01 14:30:26 +00:00
|
|
|
void setDirtyRange(int top, int bottom) {
|
|
|
|
for (int i = 0; i < 80; i++) {
|
|
|
|
tdirty[i] = top;
|
|
|
|
bdirty[i] = bottom;
|
|
|
|
}
|
|
|
|
}
|
2004-08-14 19:42:00 +00:00
|
|
|
|
|
|
|
byte *getPixels(int x, int y) const {
|
|
|
|
return (byte *)pixels + xstart + y * pitch + x;
|
|
|
|
}
|
|
|
|
|
|
|
|
byte *getBackPixels(int x, int y) const {
|
|
|
|
return (byte *)backBuf + xstart + y * pitch + x;
|
|
|
|
}
|
2002-03-22 03:30:57 +00:00
|
|
|
};
|
|
|
|
|
2004-01-03 21:22:07 +00:00
|
|
|
/** Palette cycles */
|
|
|
|
struct ColorCycle {
|
2002-03-22 03:30:57 +00:00
|
|
|
uint16 delay;
|
|
|
|
uint16 counter;
|
|
|
|
uint16 flags;
|
|
|
|
byte start;
|
|
|
|
byte end;
|
|
|
|
};
|
|
|
|
|
2004-01-03 21:22:07 +00:00
|
|
|
/** BlastObjects to draw */
|
|
|
|
struct BlastObject {
|
2002-11-06 15:29:49 +00:00
|
|
|
uint16 number;
|
2004-01-08 03:10:16 +00:00
|
|
|
Common::Rect rect;
|
2002-09-19 11:06:10 +00:00
|
|
|
uint16 scaleX, scaleY;
|
|
|
|
uint16 image;
|
2002-04-21 21:20:32 +00:00
|
|
|
uint16 mode;
|
2002-03-22 03:30:57 +00:00
|
|
|
};
|
|
|
|
|
2003-10-02 22:42:03 +00:00
|
|
|
/** Bomp graphics data, used as parameter to ScummEngine::drawBomp. */
|
2003-05-30 20:13:29 +00:00
|
|
|
struct BompDrawData {
|
2002-03-22 03:30:57 +00:00
|
|
|
byte *out;
|
|
|
|
int outwidth, outheight;
|
2002-08-20 02:20:40 +00:00
|
|
|
int x, y;
|
2002-03-22 03:30:57 +00:00
|
|
|
byte scale_x, scale_y;
|
2003-05-28 20:01:47 +00:00
|
|
|
const byte *dataptr;
|
2002-03-22 03:30:57 +00:00
|
|
|
int srcwidth, srcheight;
|
2002-11-06 15:29:49 +00:00
|
|
|
uint16 shadowMode;
|
2003-05-30 15:06:29 +00:00
|
|
|
|
|
|
|
int32 scaleRight, scaleBottom;
|
|
|
|
byte *scalingXPtr, *scalingYPtr;
|
|
|
|
byte *maskPtr;
|
|
|
|
|
|
|
|
BompDrawData() { memset(this, 0, sizeof(*this)); }
|
2002-03-22 03:30:57 +00:00
|
|
|
};
|
|
|
|
|
2004-01-03 22:45:23 +00:00
|
|
|
struct StripTable;
|
2003-06-04 21:45:29 +00:00
|
|
|
|
2002-12-04 13:36:27 +00:00
|
|
|
class Gdi {
|
2003-10-02 22:42:03 +00:00
|
|
|
friend class ScummEngine; // Mostly for the code in saveload.cpp ...
|
|
|
|
ScummEngine *_vm;
|
2002-03-22 03:30:57 +00:00
|
|
|
|
2003-10-13 12:56:53 +00:00
|
|
|
public:
|
2002-03-22 03:30:57 +00:00
|
|
|
int _numZBuffer;
|
2002-12-26 18:10:14 +00:00
|
|
|
int _imgBufOffs[8];
|
2002-10-24 06:28:54 +00:00
|
|
|
int32 _numStrips;
|
2003-06-19 10:45:21 +00:00
|
|
|
byte _C64Colors[4];
|
2003-10-13 12:56:53 +00:00
|
|
|
|
|
|
|
Gdi(ScummEngine *vm);
|
2002-03-22 03:30:57 +00:00
|
|
|
|
2004-08-08 22:10:38 +00:00
|
|
|
Graphics::Surface _textSurface;
|
|
|
|
|
2002-12-04 13:36:27 +00:00
|
|
|
protected:
|
2004-08-08 22:10:38 +00:00
|
|
|
byte *_compositeBuf;
|
|
|
|
|
2003-10-13 12:56:53 +00:00
|
|
|
byte *_roomPalette;
|
2002-03-22 03:30:57 +00:00
|
|
|
byte _decomp_shr, _decomp_mask;
|
2002-12-31 14:59:06 +00:00
|
|
|
byte _transparentColor;
|
2002-04-23 23:58:31 +00:00
|
|
|
uint32 _vertStripNextInc;
|
2002-03-22 03:30:57 +00:00
|
|
|
|
2003-05-15 21:31:03 +00:00
|
|
|
bool _zbufferDisabled;
|
|
|
|
|
2003-06-19 10:45:21 +00:00
|
|
|
byte _C64CharMap[2048], _C64ObjectMap[2048], _C64PicMap[4096], _C64ColorMap[4096];
|
2003-06-05 17:22:15 +00:00
|
|
|
byte _C64MaskMap[4096], _C64MaskChar[4096];
|
2003-06-06 05:27:45 +00:00
|
|
|
bool _C64ObjectMode;
|
2003-06-05 17:22:15 +00:00
|
|
|
|
2002-03-22 03:30:57 +00:00
|
|
|
/* Bitmap decompressors */
|
2003-05-28 20:01:47 +00:00
|
|
|
bool decompressBitmap(byte *bgbak_ptr, const byte *src, int numLinesToProcess);
|
2004-09-18 21:40:07 +00:00
|
|
|
void drawStripEGA(byte *dst, const byte *src, int height);
|
2003-06-06 05:27:45 +00:00
|
|
|
void decodeC64Gfx(const byte *src, byte *dst, int size);
|
|
|
|
void drawStripC64Object(byte *dst, int stripnr, int width, int height);
|
2003-06-05 17:22:15 +00:00
|
|
|
void drawStripC64Background(byte *dst, int stripnr, int height);
|
2003-08-25 14:27:29 +00:00
|
|
|
void drawStripC64Mask(byte *dst, int stripnr, int width, int height);
|
2004-09-18 21:40:07 +00:00
|
|
|
|
|
|
|
void drawStripComplex(byte *dst, const byte *src, int height);
|
|
|
|
void drawStripComplex_trans(byte *dst, const byte *src, int height);
|
|
|
|
void drawStripBasicH(byte *dst, const byte *src, int height);
|
|
|
|
void drawStripBasicH_trans(byte *dst, const byte *src, int height);
|
|
|
|
void drawStripBasicV(byte *dst, const byte *src, int height);
|
|
|
|
void drawStripBasicV_trans(byte *dst, const byte *src, int height);
|
2003-05-26 13:14:57 +00:00
|
|
|
|
|
|
|
void unkDecode7(byte *dst, const byte *src, int height);
|
|
|
|
void unkDecode8(byte *dst, const byte *src, int height);
|
|
|
|
void unkDecode9(byte *dst, const byte *src, int height);
|
|
|
|
void unkDecode10(byte *dst, const byte *src, int height);
|
|
|
|
void unkDecode11(byte *dst, const byte *src, int height);
|
2004-09-18 21:40:07 +00:00
|
|
|
void drawStrip3DO(byte *dst, const byte *src, int height, const bool transpCheck);
|
|
|
|
void drawStripHE(byte *dst, const byte *src, int height, const bool transpCheck);
|
2003-05-26 13:14:57 +00:00
|
|
|
|
|
|
|
void draw8Col(byte *dst, const byte *src, int height);
|
2002-12-04 13:36:27 +00:00
|
|
|
void clear8Col(byte *dst, int height);
|
2003-05-26 13:14:57 +00:00
|
|
|
void decompressMaskImgOr(byte *dst, const byte *src, int height);
|
|
|
|
void decompressMaskImg(byte *dst, const byte *src, int height);
|
2002-03-22 03:30:57 +00:00
|
|
|
|
2002-12-15 23:40:37 +00:00
|
|
|
void drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b);
|
|
|
|
void updateDirtyScreen(VirtScreen *vs);
|
2004-01-04 13:49:03 +00:00
|
|
|
|
2004-08-08 22:10:38 +00:00
|
|
|
byte *getMaskBuffer(int x, int y, int z);
|
2004-09-19 21:14:51 +00:00
|
|
|
|
|
|
|
int getZPlanes(const byte *smap_ptr, const byte *zplane_list[9]);
|
2002-12-15 23:40:37 +00:00
|
|
|
|
2004-09-19 21:14:51 +00:00
|
|
|
void decompressBMAPbg(byte *dst, int screenwidth, int w, int h, const byte *ptr);
|
2004-08-26 02:47:49 +00:00
|
|
|
|
2002-12-04 13:36:27 +00:00
|
|
|
public:
|
2004-08-08 22:10:38 +00:00
|
|
|
void init();
|
|
|
|
|
2003-05-28 20:01:47 +00:00
|
|
|
void drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int width, const int height,
|
2003-06-04 21:45:29 +00:00
|
|
|
int stripnr, int numstrip, byte flag, StripTable *table = 0);
|
2004-08-08 13:24:41 +00:00
|
|
|
void drawBitmapV2Helper(const byte *ptr, VirtScreen *vs, int x, int y, const int width, const int height,
|
|
|
|
int stripnr, int numstrip, StripTable *table);
|
2003-06-04 21:45:29 +00:00
|
|
|
StripTable *generateStripTable(const byte *src, int width, int height, StripTable *table);
|
2004-08-26 02:47:49 +00:00
|
|
|
void drawBMAPBg(const byte *ptr, VirtScreen *vs, int startstrip, int width);
|
2004-09-05 17:39:54 +00:00
|
|
|
void drawBMAPObject(const byte *ptr, VirtScreen *vs, int obj, int x, int y, int w, int h);
|
2004-09-18 00:36:17 +00:00
|
|
|
void copyWizImage(uint8 *dst, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, Common::Rect *rect);
|
|
|
|
void decompressWizImage(uint8 *dst, int dstPitch, const Common::Rect *dstRect, const uint8 *src, const Common::Rect *srcRect);
|
|
|
|
void copyAuxImage(uint8 *dst1, uint8 *dst2, const uint8 *src, int dstw, int dsth, int srcx, int srcy, int srcw, int srch, Common::Rect *rect);
|
|
|
|
void decompressAuxImage(uint8 *dst1, uint8 *dst2, int dstPitch, const Common::Rect *dstRect, const uint8 *src, const Common::Rect *srcRect);
|
2004-09-19 20:17:57 +00:00
|
|
|
void copyVirtScreenBuffers(const Common::Rect &rect);
|
2002-12-04 15:00:35 +00:00
|
|
|
|
2003-05-15 21:31:03 +00:00
|
|
|
void disableZBuffer() { _zbufferDisabled = true; }
|
|
|
|
void enableZBuffer() { _zbufferDisabled = false; }
|
2002-12-04 15:00:35 +00:00
|
|
|
|
|
|
|
void resetBackground(int top, int bottom, int strip);
|
|
|
|
|
2002-03-22 03:30:57 +00:00
|
|
|
enum DrawBitmapFlags {
|
|
|
|
dbAllowMaskOr = 1,
|
2002-09-29 15:20:02 +00:00
|
|
|
dbDrawMaskOnAll = 2,
|
2002-03-22 03:30:57 +00:00
|
|
|
dbClear = 4
|
|
|
|
};
|
|
|
|
};
|
2002-07-17 20:55:36 +00:00
|
|
|
|
2003-05-29 12:55:28 +00:00
|
|
|
|
2004-01-03 22:21:56 +00:00
|
|
|
// If you want to try buggy hacked smooth scrolling support in The Dig, enable
|
2003-05-29 12:55:28 +00:00
|
|
|
// the following preprocessor flag by uncommenting it.
|
|
|
|
//
|
|
|
|
// Note: This is purely experimental, NOT WORKING COMPLETLY and very buggy.
|
|
|
|
// Please do not make reports about problems with it - this is only in CVS
|
|
|
|
// to get it fixed and so that really interested parties can experiment it.
|
|
|
|
// It is NOT FIT FOR GENERAL USAGE! You have been warned.
|
|
|
|
//
|
2004-01-03 21:22:07 +00:00
|
|
|
// Doing this correctly will be complicated. Basically, with smooth scrolling,
|
|
|
|
// the virtual screen strips don't match the display screen strips. Hence we
|
|
|
|
// either have to draw partial strips (but that'd be rather cumbersome). Or the
|
|
|
|
// alternative (and IMHO more elegant) solution is to simply use a screen pitch
|
|
|
|
// that is 8 pixel wider than the real screen width, and always draw one strip
|
|
|
|
// more than needed to the backbuf. This will still require quite some code to
|
|
|
|
// be changed but should otherwise be relatively easy to understand, and using
|
|
|
|
// VirtScreen::pitch will actually clean up the code.
|
2003-05-29 12:55:28 +00:00
|
|
|
//
|
|
|
|
// #define V7_SMOOTH_SCROLLING_HACK
|
|
|
|
|
|
|
|
|
2003-10-03 18:33:57 +00:00
|
|
|
} // End of namespace Scumm
|
|
|
|
|
2002-07-17 20:55:36 +00:00
|
|
|
#endif
|