mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-23 10:19:27 +00:00
499e58caf0
cause of) bug #2976008 ("BS2: Game lockup in British Museum"). svn-id: r48692
482 lines
13 KiB
C++
482 lines
13 KiB
C++
/* 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.
|
|
*
|
|
* Additional copyright for this file:
|
|
* Copyright (C) 1994-1998 Revolution Software Ltd.
|
|
*
|
|
* 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.
|
|
*
|
|
* $URL$
|
|
* $Id$
|
|
*/
|
|
|
|
#ifndef SWORD2_SCREEN_H
|
|
#define SWORD2_SCREEN_H
|
|
|
|
#include "common/rect.h"
|
|
#include "common/stream.h"
|
|
|
|
#define MAX_bgp0_sprites 6
|
|
#define MAX_bgp1_sprites 6
|
|
#define MAX_back_sprites 30
|
|
#define MAX_sort_sprites 30
|
|
#define MAX_fore_sprites 30
|
|
#define MAX_fgp0_sprites 6
|
|
#define MAX_fgp1_sprites 6
|
|
|
|
#define PALTABLESIZE (64 * 64 * 64)
|
|
|
|
#define BLOCKWIDTH 64
|
|
#define BLOCKHEIGHT 64
|
|
#define MAXLAYERS 5
|
|
|
|
#define MENUDEEP 40
|
|
#define RENDERWIDE 640
|
|
#define RENDERDEEP (480 - (MENUDEEP * 2))
|
|
|
|
// Maximum scaled size of a sprite
|
|
#define SCALE_MAXWIDTH 512
|
|
#define SCALE_MAXHEIGHT 512
|
|
|
|
// Dirty grid cell size
|
|
#define CELLWIDE 10
|
|
#define CELLDEEP 20
|
|
|
|
namespace Sword2 {
|
|
|
|
class Sword2Engine;
|
|
|
|
// Sprite defines
|
|
|
|
enum {
|
|
// This is the low byte part of the sprite type.
|
|
|
|
RDSPR_TRANS = 0x0001,
|
|
RDSPR_BLEND = 0x0004,
|
|
RDSPR_FLIP = 0x0008,
|
|
RDSPR_SHADOW = 0x0010,
|
|
RDSPR_DISPLAYALIGN = 0x0020,
|
|
RDSPR_NOCOMPRESSION = 0x0040,
|
|
RDSPR_EDGEBLEND = 0x0080, // Unused
|
|
|
|
// This is the high byte part of the sprite type, which defines what
|
|
// type of compression is used. Unless RDSPR_NOCOMPRESSION is set.
|
|
|
|
RDSPR_RLE16 = 0x0000,
|
|
RDSPR_RLE256 = 0x0100,
|
|
RDSPR_RLE256FAST = 0x0200
|
|
};
|
|
|
|
// Fading defines
|
|
|
|
enum {
|
|
RDFADE_NONE,
|
|
RDFADE_UP,
|
|
RDFADE_DOWN,
|
|
RDFADE_BLACK
|
|
};
|
|
|
|
// Palette defines
|
|
|
|
enum {
|
|
RDPAL_FADE,
|
|
RDPAL_INSTANT
|
|
};
|
|
|
|
// Blitting FX defines
|
|
|
|
enum {
|
|
RDBLTFX_SPRITEBLEND = 0x01,
|
|
RDBLTFX_SHADOWBLEND = 0x02,
|
|
RDBLTFX_EDGEBLEND = 0x04
|
|
};
|
|
|
|
// Structure filled out by each object to register its graphic printing
|
|
// requrements
|
|
|
|
struct BuildUnit {
|
|
int16 x;
|
|
int16 y;
|
|
uint16 scaled_width;
|
|
uint16 scaled_height;
|
|
int16 sort_y;
|
|
uint32 anim_resource;
|
|
uint16 anim_pc;
|
|
|
|
// Denotes a scaling sprite at print time - and holds the scaling value
|
|
// for the shrink routine
|
|
|
|
uint16 scale;
|
|
|
|
// Non-zero means this item is a layer - retrieve from background layer
|
|
// and send to special renderer
|
|
|
|
uint16 layer_number;
|
|
|
|
// True means we want this frame to be affected by the shading mask
|
|
|
|
bool shadingFlag;
|
|
};
|
|
|
|
struct ScreenInfo {
|
|
uint16 scroll_offset_x; // Position x
|
|
uint16 scroll_offset_y; // Position y
|
|
uint16 max_scroll_offset_x; // Calc'ed in fnInitBackground
|
|
uint16 max_scroll_offset_y;
|
|
int16 player_feet_x; // Feet coordinates to use - cant just
|
|
int16 player_feet_y; // fetch the player compact anymore
|
|
int16 feet_x; // Special offset-to-player position -
|
|
int16 feet_y; // tweek as desired - always set in
|
|
// screen manager object startup
|
|
uint16 screen_wide; // Size of background layer - hence
|
|
uint16 screen_deep; // size of back buffer itself (Paul
|
|
// actually malloc's it)
|
|
uint32 background_layer_id; // Id of the normal background layer
|
|
// from the header of the main
|
|
// background layer
|
|
uint16 number_of_layers;
|
|
uint8 new_palette; // Set to non zero to start the
|
|
// palette held within layer file
|
|
// fading up after a buildDisplay()
|
|
uint8 scroll_flag; // Scroll mode 0 off 1 on
|
|
bool mask_flag; // Using shading mask
|
|
};
|
|
|
|
// The SpriteInfo structure is used to tell the driver96 code what attributes
|
|
// are linked to a sprite for drawing. These include position, scaling and
|
|
// compression.
|
|
|
|
struct SpriteInfo {
|
|
int16 x; // coords for top-left of sprite
|
|
int16 y;
|
|
uint16 w; // dimensions of sprite (before scaling)
|
|
uint16 h;
|
|
uint16 scale; // scale at which to draw, given in 256ths ['0' or '256' MEANS DON'T SCALE]
|
|
uint16 scaledWidth; // new dimensions (we calc these for the mouse area, so may as well pass to you to save time)
|
|
uint16 scaledHeight; //
|
|
uint16 type; // mask containing 'RDSPR_' bits specifying compression type, flip, transparency, etc
|
|
uint16 blend; // holds the blending values.
|
|
byte *data; // pointer to the sprite data
|
|
byte *colourTable; // pointer to 16-byte colour table, only applicable to 16-col compression type
|
|
bool isText; // It is a engine-generated sprite containing text
|
|
};
|
|
|
|
struct BlockSurface {
|
|
byte data[BLOCKWIDTH * BLOCKHEIGHT];
|
|
bool transparent;
|
|
};
|
|
|
|
struct Parallax {
|
|
uint16 w;
|
|
uint16 h;
|
|
|
|
// The dimensions are followed by an offset table, but we don't know in
|
|
// advance how big it is. See initializeBackgroundLayer().
|
|
|
|
static int size() {
|
|
return 4;
|
|
}
|
|
|
|
void read(byte *addr) {
|
|
Common::MemoryReadStream readS(addr, size());
|
|
|
|
w = readS.readUint16LE();
|
|
h = readS.readUint16LE();
|
|
}
|
|
|
|
void write(byte *addr) {
|
|
Common::MemoryWriteStream writeS(addr, size());
|
|
|
|
writeS.writeUint16LE(w);
|
|
writeS.writeUint16LE(h);
|
|
}
|
|
};
|
|
|
|
class Screen {
|
|
private:
|
|
Sword2Engine *_vm;
|
|
|
|
// _thisScreen describes the current back buffer and its in-game scroll
|
|
// positions, etc.
|
|
|
|
ScreenInfo _thisScreen;
|
|
|
|
int32 _renderCaps;
|
|
int8 _renderLevel;
|
|
|
|
byte *_buffer;
|
|
byte *_lightMask;
|
|
|
|
// Game screen metrics
|
|
int16 _screenWide;
|
|
int16 _screenDeep;
|
|
|
|
bool _needFullRedraw;
|
|
|
|
// Scroll variables. _scrollX and _scrollY hold the current scroll
|
|
// position, and _scrollXTarget and _scrollYTarget are the target
|
|
// position for the end of the game cycle.
|
|
|
|
int16 _scrollX;
|
|
int16 _scrollY;
|
|
|
|
int16 _scrollXTarget;
|
|
int16 _scrollYTarget;
|
|
int16 _scrollXOld;
|
|
int16 _scrollYOld;
|
|
|
|
int16 _parallaxScrollX; // current x offset to link a sprite to the
|
|
// parallax layer
|
|
int16 _parallaxScrollY; // current y offset to link a sprite to the
|
|
// parallax layer
|
|
int16 _locationWide;
|
|
int16 _locationDeep;
|
|
|
|
// Dirty grid handling
|
|
byte *_dirtyGrid;
|
|
|
|
uint16 _gridWide;
|
|
uint16 _gridDeep;
|
|
|
|
byte _palette[256 * 4];
|
|
byte _paletteMatch[PALTABLESIZE];
|
|
|
|
uint8 _fadeStatus;
|
|
int32 _fadeStartTime;
|
|
int32 _fadeTotalTime;
|
|
|
|
// 'frames per second' counting stuff
|
|
uint32 _fps;
|
|
uint32 _cycleTime;
|
|
uint32 _frameCount;
|
|
|
|
int32 _initialTime;
|
|
int32 _startTime;
|
|
int32 _totalTime;
|
|
int32 _renderAverageTime;
|
|
int32 _framesPerGameCycle;
|
|
bool _renderTooSlow;
|
|
|
|
void startNewPalette();
|
|
|
|
void resetRenderEngine();
|
|
|
|
void startRenderCycle();
|
|
bool endRenderCycle();
|
|
|
|
// Holds the order of the sort list, i.e. the list stays static and we
|
|
// sort this array.
|
|
|
|
uint16 _sortOrder[MAX_sort_sprites];
|
|
|
|
BuildUnit _bgp0List[MAX_bgp0_sprites];
|
|
BuildUnit _bgp1List[MAX_bgp1_sprites];
|
|
BuildUnit _backList[MAX_back_sprites];
|
|
BuildUnit _sortList[MAX_sort_sprites];
|
|
BuildUnit _foreList[MAX_fore_sprites];
|
|
BuildUnit _fgp0List[MAX_fgp0_sprites];
|
|
BuildUnit _fgp1List[MAX_fgp1_sprites];
|
|
|
|
uint32 _curBgp0;
|
|
uint32 _curBgp1;
|
|
uint32 _curBack;
|
|
uint32 _curSort;
|
|
uint32 _curFore;
|
|
uint32 _curFgp0;
|
|
uint32 _curFgp1;
|
|
|
|
void drawBackPar0Frames();
|
|
void drawBackPar1Frames();
|
|
void drawBackFrames();
|
|
void drawSortFrames(byte *file);
|
|
void drawForeFrames();
|
|
void drawForePar0Frames();
|
|
void drawForePar1Frames();
|
|
|
|
void processLayer(byte *file, uint32 layer_number);
|
|
void processImage(BuildUnit *build_unit);
|
|
|
|
uint8 _scrollFraction;
|
|
|
|
// Last palette used - so that we can restore the correct one after a
|
|
// pause (which dims the screen) and it's not always the main screen
|
|
// palette that we want, eg. during the eclipse
|
|
|
|
// This flag gets set in startNewPalette() and setFullPalette()
|
|
|
|
uint32 _lastPaletteRes;
|
|
|
|
// Debugging stuff
|
|
uint32 _largestLayerArea;
|
|
uint32 _largestSpriteArea;
|
|
char _largestLayerInfo[128];
|
|
char _largestSpriteInfo[128];
|
|
|
|
void registerFrame(byte *ob_mouse, byte *ob_graph, byte *ob_mega, BuildUnit *build_unit);
|
|
|
|
void mirrorSprite(byte *dst, byte *src, int16 w, int16 h);
|
|
int32 decompressRLE256(byte *dst, byte *src, int32 decompSize);
|
|
void unwindRaw16(byte *dst, byte *src, uint16 blockSize, byte *colTable);
|
|
int32 decompressRLE16(byte *dst, byte *src, int32 decompSize, byte *colTable);
|
|
void renderParallax(byte *ptr, int16 layer);
|
|
|
|
|
|
void markAsDirty(int16 x0, int16 y0, int16 x1, int16 y1);
|
|
|
|
uint8 _xBlocks[MAXLAYERS];
|
|
uint8 _yBlocks[MAXLAYERS];
|
|
|
|
// This is used to cache PSX backgrounds and parallaxes
|
|
// data, as they are kept in a file unmanageable from
|
|
// resource manager. These gets freed everytime an user
|
|
// exits from a room.
|
|
byte *_psxScrCache[3];
|
|
bool _psxCacheEnabled[3];
|
|
|
|
// An array of sub-blocks, one for each of the parallax layers.
|
|
|
|
BlockSurface **_blockSurfaces[MAXLAYERS];
|
|
|
|
uint16 _xScale[SCALE_MAXWIDTH];
|
|
uint16 _yScale[SCALE_MAXHEIGHT];
|
|
|
|
void blitBlockSurface(BlockSurface *s, Common::Rect *r, Common::Rect *clipRect);
|
|
|
|
uint16 _layer;
|
|
|
|
bool _dimPalette;
|
|
|
|
uint32 _pauseTicks;
|
|
uint32 _pauseStartTick;
|
|
|
|
uint32 getTick();
|
|
|
|
public:
|
|
Screen(Sword2Engine *vm, int16 width, int16 height);
|
|
~Screen();
|
|
|
|
void pauseScreen(bool pause);
|
|
|
|
int8 getRenderLevel();
|
|
void setRenderLevel(int8 level);
|
|
|
|
byte *getScreen() { return _buffer; }
|
|
byte *getPalette() { return _palette; }
|
|
ScreenInfo *getScreenInfo() { return &_thisScreen; }
|
|
|
|
int16 getScreenWide() { return _screenWide; }
|
|
int16 getScreenDeep() { return _screenDeep; }
|
|
|
|
uint32 getCurBgp0() { return _curBgp0; }
|
|
uint32 getCurBgp1() { return _curBgp1; }
|
|
uint32 getCurBack() { return _curBack; }
|
|
uint32 getCurSort() { return _curSort; }
|
|
uint32 getCurFore() { return _curFore; }
|
|
uint32 getCurFgp0() { return _curFgp0; }
|
|
uint32 getCurFgp1() { return _curFgp1; }
|
|
|
|
uint32 getFps() { return _fps; }
|
|
|
|
uint32 getLargestLayerArea() { return _largestLayerArea; }
|
|
uint32 getLargestSpriteArea() { return _largestSpriteArea; }
|
|
char *getLargestLayerInfo() { return _largestLayerInfo; }
|
|
char *getLargestSpriteInfo() { return _largestSpriteInfo; }
|
|
|
|
void setNeedFullRedraw();
|
|
|
|
void clearScene();
|
|
|
|
void resetRenderLists();
|
|
|
|
void setLocationMetrics(uint16 w, uint16 h);
|
|
int32 initialiseBackgroundLayer(byte *parallax);
|
|
int32 initialisePsxParallaxLayer(byte *parallax); // These are used to initialize psx backgrounds and
|
|
int32 initialisePsxBackgroundLayer(byte *parallax); // parallaxes, which are different from pc counterparts.
|
|
void closeBackgroundLayer();
|
|
|
|
void initialiseRenderCycle();
|
|
|
|
void initBackground(int32 res, int32 new_palette);
|
|
void initPsxBackground(int32 res, int32 new_palette);
|
|
void registerFrame(byte *ob_mouse, byte *ob_graph, byte *ob_mega);
|
|
|
|
void setScrollFraction(uint8 f) { _scrollFraction = f; }
|
|
void setScrollTarget(int16 x, int16 y);
|
|
void setScrolling();
|
|
|
|
void setFullPalette(int32 palRes);
|
|
void setPalette(int16 startEntry, int16 noEntries, byte *palette, uint8 setNow);
|
|
void setSystemPalette(const byte *colors, uint start, uint num);
|
|
uint8 quickMatch(uint8 r, uint8 g, uint8 b);
|
|
int32 fadeUp(float time = 0.75f);
|
|
int32 fadeDown(float time = 0.75f);
|
|
uint8 getFadeStatus();
|
|
void dimPalette(bool dim);
|
|
void waitForFade();
|
|
void fadeServer();
|
|
|
|
void updateDisplay(bool redrawScene = true);
|
|
|
|
void displayMsg(byte *text, int time);
|
|
|
|
int32 createSurface(SpriteInfo *s, byte **surface);
|
|
void drawSurface(SpriteInfo *s, byte *surface, Common::Rect *clipRect = NULL);
|
|
void deleteSurface(byte *surface);
|
|
int32 drawSprite(SpriteInfo *s);
|
|
|
|
void scaleImageFast(byte *dst, uint16 dstPitch, uint16 dstWidth,
|
|
uint16 dstHeight, byte *src, uint16 srcPitch, uint16 srcWidth,
|
|
uint16 srcHeight);
|
|
void scaleImageGood(byte *dst, uint16 dstPitch, uint16 dstWidth,
|
|
uint16 dstHeight, byte *src, uint16 srcPitch, uint16 srcWidth,
|
|
uint16 srcHeight, byte *backBuf, int16 bbXPos, int16 bbYPos);
|
|
|
|
void updateRect(Common::Rect *r);
|
|
|
|
int32 openLightMask(SpriteInfo *s);
|
|
int32 closeLightMask();
|
|
|
|
void buildDisplay();
|
|
|
|
void plotPoint(int x, int y, uint8 colour);
|
|
void drawLine(int x0, int y0, int x1, int y1, uint8 colour);
|
|
|
|
void rollCredits();
|
|
void splashScreen();
|
|
|
|
// Some sprites are compressed in HIF format
|
|
static uint32 decompressHIF(byte *src, byte *dst, uint32 *skipData = NULL);
|
|
// This is used to resize psx sprites back to original resolution
|
|
static void resizePsxSprite(byte *dst, byte *src, uint16 destW, uint16 destH);
|
|
// Some sprites are divided into 254 pixel wide stripes, this recomposes them
|
|
// and generates a "normal" sprite.
|
|
static void recomposePsxSprite(SpriteInfo *s);
|
|
static void recomposeCompPsxSprite(SpriteInfo *s);
|
|
|
|
// These functions manage the PSX screen cache
|
|
void setPsxScrCache(byte *psxScrCache, uint8 level);
|
|
byte *getPsxScrCache(uint8 level);
|
|
bool getPsxScrCacheStatus(uint8 level);
|
|
void flushPsxScrCache();
|
|
|
|
};
|
|
|
|
} // End of namespace Sword2
|
|
|
|
#endif
|