diff options
| author | Matthew Stewart | 2018-02-22 21:10:09 -0500 | 
|---|---|---|
| committer | Eugene Sandulenko | 2018-08-09 08:37:30 +0200 | 
| commit | c71a8a6d2acb3be145731e6af344cb16a38c6b46 (patch) | |
| tree | 40ce8abb55d1f7a95fe29f4a66e1850304ea1ff7 | |
| parent | b84a3bb4f28eb4b9e0bcfc19d405c79867360032 (diff) | |
| download | scummvm-rg350-c71a8a6d2acb3be145731e6af344cb16a38c6b46.tar.gz scummvm-rg350-c71a8a6d2acb3be145731e6af344cb16a38c6b46.tar.bz2 scummvm-rg350-c71a8a6d2acb3be145731e6af344cb16a38c6b46.zip | |
STARTREK: Implement drawSprite function
| -rwxr-xr-x | engines/startrek/graphics.cpp | 114 | ||||
| -rwxr-xr-x | engines/startrek/graphics.h | 39 | ||||
| -rwxr-xr-x | engines/startrek/startrek.cpp | 9 | 
3 files changed, 132 insertions, 30 deletions
| diff --git a/engines/startrek/graphics.cpp b/engines/startrek/graphics.cpp index 5304d40dc0..acedd72ea1 100755 --- a/engines/startrek/graphics.cpp +++ b/engines/startrek/graphics.cpp @@ -43,6 +43,10 @@ Bitmap::Bitmap(Common::ReadStreamEndian *stream) {  	stream->read(pixels, width*height);  } +Bitmap::Bitmap(int w, int h) : width(w), height(h) { +	pixels = (byte*)malloc(width*height); +} +  Bitmap::~Bitmap() {  	free(pixels);  } @@ -53,22 +57,30 @@ Bitmap::~Bitmap() {  Graphics::Graphics(StarTrekEngine *vm) : _vm(vm), _egaMode(false) {  	_font = 0;  	_egaData = 0; +	_priData = 0;  	if (ConfMan.hasKey("render_mode"))  		_egaMode = (Common::parseRenderMode(ConfMan.get("render_mode").c_str()) == Common::kRenderEGA) && (_vm->getGameType() != GType_STJR) && !(_vm->getFeatures() & GF_DEMO);  	if (_vm->getGameType() == GType_ST25 && _vm->getPlatform() == Common::kPlatformDOS)  		_font = new Font(_vm); + +	_backgroundImage = new Bitmap(_vm->openFile("DEMON0.BMP")); +	_canvas = new Bitmap(SCREEN_WIDTH, SCREEN_HEIGHT);  }  Graphics::~Graphics() {  	if (_egaData)  		free(_egaData); +	if (_priData) +		free(_priData);  	delete _font; +	delete _backgroundImage; +	delete _canvas;  } -void Graphics::setPalette(const char *paletteFile) { +void Graphics::loadPalette(const char *paletteFile) {  	// Set the palette from a PAL file  	Common::SeekableReadStream *palStream = _vm->openFile(paletteFile); @@ -86,16 +98,84 @@ void Graphics::setPalette(const char *paletteFile) {  	delete palStream;  } -void Graphics::drawBitmap(Bitmap *bitmap) { -	int xoffset = bitmap->xoffset; -	int yoffset = bitmap->yoffset; -	if (xoffset >= 320) -		xoffset = 0; -	if (yoffset >= 200) -		yoffset = 0; +void Graphics::loadPri(const char *priFile) { +	Common::SeekableReadStream *priStream = _vm->openFile(priFile); -	_vm->_system->copyRectToScreen(bitmap->pixels, bitmap->width, xoffset, yoffset, bitmap->width, bitmap->height); -	_vm->_system->updateScreen(); +	free(_priData); +	_priData = (byte*)malloc(SCREEN_WIDTH*SCREEN_HEIGHT/2); +	priStream->read(_priData, SCREEN_WIDTH*SCREEN_HEIGHT/2); +} + +void Graphics::redrawScreen() { +	// TODO: get rid of _canvas for efficiency +	memcpy(_canvas->pixels, _backgroundImage->pixels, SCREEN_WIDTH*SCREEN_HEIGHT); + +	// drawSprite test +	Sprite spr; +	memset(&spr,0,sizeof(Sprite)); +	spr.bitmap = new Bitmap(_vm->openFile("MWALKE00.BMP")); +	spr.drawPriority = 1; +	spr.drawX = 150; +	spr.drawY = 30; + +	drawSprite(spr, Common::Rect(spr.drawX,spr.drawY,spr.drawX+spr.bitmap->width,spr.drawY+spr.bitmap->height)); + +	drawBitmapToScreen(_canvas); +} + +// rect is the rectangle on-screen to draw. It should encompass the sprite itself, but if +// it doesn't, part of the sprite will be cut off. +void Graphics::drawSprite(const Sprite &sprite, const Common::Rect &rect) { +	int drawWidth = rect.right - rect.left; +	int drawHeight = rect.bottom - rect.top; + +	if (drawWidth <= 0 || drawHeight <= 0) +		error("drawSprite: w/h <= 0"); +	 + +	byte *dest = _canvas->pixels + rect.top*SCREEN_WIDTH + rect.left; +	int canvasOffsetToNextLine = SCREEN_WIDTH - drawWidth; + +	switch(sprite.drawMode) { +	case 0: { // Normal sprite +		byte *src = sprite.bitmap->pixels + (rect.left - sprite.drawX) +			+ (rect.top - sprite.drawY) * sprite.bitmap->width; + +		int spriteOffsetToNextLine = sprite.bitmap->width - drawWidth; +		int priOffset = rect.top*SCREEN_WIDTH + rect.left; + +		for (int y=rect.top; y<rect.bottom; y++) { +			for (int x=rect.left; x<rect.right; x++) { +				byte priByte = _priData[priOffset/2]; +				byte bgPri; +				if ((priOffset%2) == 1) +					bgPri = (priByte)&0xf; +				else +					bgPri = (priByte)>>4; +				priOffset++; + +				byte b = *src++; +				if (b == 0 || sprite.drawPriority < bgPri) { +					dest++; +					continue; +				} +				*dest++ = b; +			} + +			src += spriteOffsetToNextLine; +			dest += canvasOffsetToNextLine; +			priOffset += canvasOffsetToNextLine; +		} +		break; +	} + +	case 1: +	case 2: +	case 3: +	default: +		error("drawSprite: draw mode %d not implemented", sprite.drawMode); +		break; +	}  } @@ -139,4 +219,18 @@ void Graphics::drawBackgroundImage(const char *filename) {  	delete imageStream;  } + +void Graphics::drawBitmapToScreen(Bitmap *bitmap) { +	int xoffset = bitmap->xoffset; +	int yoffset = bitmap->yoffset; +	if (xoffset >= 320) +		xoffset = 0; +	if (yoffset >= 200) +		yoffset = 0; + +	_vm->_system->copyRectToScreen(bitmap->pixels, bitmap->width, xoffset, yoffset, bitmap->width, bitmap->height); +	_vm->_system->updateScreen(); +} + +  } diff --git a/engines/startrek/graphics.h b/engines/startrek/graphics.h index 6637928c3e..a2d9f4fa1c 100755 --- a/engines/startrek/graphics.h +++ b/engines/startrek/graphics.h @@ -29,6 +29,7 @@  #include "startrek/startrek.h"  #include "startrek/font.h" +#include "common/rect.h"  #include "common/stream.h"  namespace StarTrek { @@ -37,27 +38,23 @@ class Font;  class StarTrekEngine; -class Bitmap { -public: +const int SCREEN_WIDTH = 320; +const int SCREEN_HEIGHT = 200; + + +struct Bitmap {  	uint16 xoffset;  	uint16 yoffset;  	uint16 width;  	uint16 height;  	byte *pixels; -public:  	Bitmap(Common::ReadStreamEndian *stream); +	Bitmap(int w, int h);  	~Bitmap();  }; -class Rectangle { -	uint16 left; -	uint16 top; -	uint16 right; -	uint16 bottom; -}; - -class Sprite { +struct Sprite {  	uint16 x,y;  	uint16 drawPriority;  	uint16 field6; @@ -69,9 +66,9 @@ class Sprite {  	uint16 redrawCondition2;  	uint16 redrawCondition3;  	uint16 field16; -	Rectangle rectangle1; -	Rectangle clickRectangle; -	Rectangle rectangle2; +	Common::Rect rectangle1; +	Common::Rect clickRectangle; +	Common::Rect rectangle2;  	uint16 drawX,drawY;  }; @@ -81,19 +78,29 @@ public:  	Graphics(StarTrekEngine *vm);  	~Graphics(); -	void setPalette(const char *paletteFile); -	void drawBitmap(Bitmap *bitmap); +	void loadPalette(const char *paletteFile); +	void loadPri(const char *priFile); + +	void redrawScreen(); +	void drawSprite(const Sprite &sprite, const Common::Rect &rect);  	void loadEGAData(const char *egaFile);  	void drawBackgroundImage(const char *filename);  private: +	void drawBitmapToScreen(Bitmap *bitmap); + +  	StarTrekEngine *_vm;  	Font *_font;  	bool _egaMode;  	byte *_egaData; +	byte *_priData; + +	Bitmap *_backgroundImage; +	Bitmap *_canvas;  };  } diff --git a/engines/startrek/startrek.cpp b/engines/startrek/startrek.cpp index 5401e5217b..f007301ed2 100755 --- a/engines/startrek/startrek.cpp +++ b/engines/startrek/startrek.cpp @@ -88,10 +88,9 @@ Common::Error StarTrekEngine::run() {  // EGA not supported  #if 1  	if (getGameType() == GType_ST25) { -		_gfx->setPalette("PALETTE.PAL"); -		Bitmap *b = new Bitmap(openFile("DEMON5.BMP")); -		_gfx->drawBitmap(b); -		delete b; +		_gfx->loadPalette("PALETTE.PAL"); +		_gfx->loadPri("DEMON0.PRI"); +		_gfx->redrawScreen();  		if (getPlatform() == Common::kPlatformAmiga)  			_sound->playSoundEffect("TREK2"); @@ -117,6 +116,8 @@ Common::Error StarTrekEngine::run() {  					break;  			}  		} + +		_system->delayMillis(1000/60);  	}  #endif | 
