Permalink
Browse files

STARTREK: Implement drawSprite function

  • Loading branch information...
Drenn1 authored and sev- committed Feb 23, 2018
1 parent b84a3bb commit c71a8a6d2acb3be145731e6af344cb16a38c6b46
Showing with 132 additions and 30 deletions.
  1. +104 −10 engines/startrek/graphics.cpp
  2. +23 −16 engines/startrek/graphics.h
  3. +5 −4 engines/startrek/startrek.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();
}


}
@@ -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 @@ class Graphics {
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;
};

}
@@ -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

0 comments on commit c71a8a6

Please sign in to comment.