diff options
-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 |