diff options
author | Eugene Sandulenko | 2004-12-21 16:12:03 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2004-12-21 16:12:03 +0000 |
commit | c6c2ed9c484ada25bad4861e52495592620718c9 (patch) | |
tree | b30190c05caa911193ccd629c7a7d879e72dd668 /saga | |
parent | 118cc4d2552844622b633223c3677a4eafd0275e (diff) | |
download | scummvm-rg350-c6c2ed9c484ada25bad4861e52495592620718c9.tar.gz scummvm-rg350-c6c2ed9c484ada25bad4861e52495592620718c9.tar.bz2 scummvm-rg350-c6c2ed9c484ada25bad4861e52495592620718c9.zip |
Implement sprites scaling. Though it seems too zealous for me, i.e. sprites
scale down too fast. Will compare it with original soon.
svn-id: r16244
Diffstat (limited to 'saga')
-rw-r--r-- | saga/sprite.cpp | 78 | ||||
-rw-r--r-- | saga/sprite.h | 4 |
2 files changed, 64 insertions, 18 deletions
diff --git a/saga/sprite.cpp b/saga/sprite.cpp index 897a10f386..fabdf8a06f 100644 --- a/saga/sprite.cpp +++ b/saga/sprite.cpp @@ -181,8 +181,8 @@ int Sprite::draw(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, const Poi int i, j; byte *buf_row_p; byte *src_row_p; - int s_width; - int s_height; + int s_width, so_width; + int s_height, so_height; int clip_width; int clip_height; int x_align; @@ -205,13 +205,21 @@ int Sprite::draw(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, const Poi x_align = readS.readSByte(); y_align = readS.readSByte(); - s_width = readS.readByte(); - s_height = readS.readByte(); + spr_pt.x = screenCoord.x + x_align; + spr_pt.y = screenCoord.y + y_align; + + so_width = s_width = readS.readByte(); + so_height = s_height = readS.readByte(); + + if (scale < 256) + scaleSpriteCoords(scale, &s_width, &s_height, &x_align, &y_align); sprite_data_p = sprite_p + readS.pos(); - spr_pt.x = screenCoord.x + x_align; - spr_pt.y = screenCoord.y + y_align; + decodeRLESprite(sprite_data_p, 64000, _decodeBuf, so_width * so_height); + + if (scale < 256) + scaleSprite(_decodeBuf, so_width, so_height, scale); if (spr_pt.x < 0) { return 0; @@ -221,8 +229,6 @@ int Sprite::draw(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, const Poi return 0; } - decodeRLESprite(sprite_data_p, 64000, _decodeBuf, s_width * s_height, scale); - buf_row_p = (byte *)ds->pixels + ds->pitch * spr_pt.y; src_row_p = _decodeBuf; @@ -262,8 +268,8 @@ int Sprite::drawOccluded(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, c byte *src_p; byte *dst_p; byte *mask_p; - int s_width; - int s_height; + int s_width, so_width; + int s_height, so_height; int x_align; int y_align; @@ -309,15 +315,16 @@ int Sprite::drawOccluded(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, c x_align = readS.readSByte(); y_align = readS.readSByte(); - s_width = readS.readByte(); - s_height = readS.readByte(); + so_width = s_width = readS.readByte(); + so_height = s_height = readS.readByte(); sprite_data_p = sprite_p + readS.pos(); - - _vm->_scene->getBGMaskInfo(&mask_w, &mask_h, &mask_buf, &mask_buf_len); + if (scale < 256) + scaleSpriteCoords(scale, &s_width, &s_height, &x_align, &y_align); + spr_src_rect.left = 0; spr_src_rect.top = 0; spr_src_rect.right = s_width; @@ -341,7 +348,10 @@ int Sprite::drawOccluded(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, c return SUCCESS; } - decodeRLESprite(sprite_data_p, 64000, _decodeBuf, s_width * s_height, scale); + decodeRLESprite(sprite_data_p, 64000, _decodeBuf, so_width * so_height); + + if (scale < 256) + scaleSprite(_decodeBuf, so_width, so_height, scale); // Finally, draw the occluded sprite src_row_p = _decodeBuf + ci.src_draw_x + (ci.src_draw_y * s_width); @@ -379,8 +389,7 @@ int Sprite::drawOccluded(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, c return SUCCESS; } -//TODO write scale support -int Sprite::decodeRLESprite(const byte *inbuf, size_t inbuf_len, byte *outbuf, size_t outbuf_len, int scale) { +int Sprite::decodeRLESprite(const byte *inbuf, size_t inbuf_len, byte *outbuf, size_t outbuf_len) { int bg_runcount; int fg_runcount; const byte *inbuf_ptr; @@ -436,4 +445,39 @@ int Sprite::decodeRLESprite(const byte *inbuf, size_t inbuf_len, byte *outbuf, s return SUCCESS; } +void Sprite::scaleSprite(byte *buf, int width, int height, int scale) { + byte skip = 256 - scale; // skip factor + + byte vskip = 0x80, hskip; + byte *src, *dst; + + src = dst = buf; + + for (int i = 0; i < height; i++) { + vskip += skip; + + if(vskip < skip) { // We had an overflow + src += width; + } else { + hskip = 0x80; + + for (int j = 0; j < width; j++) { + *dst++ = *src++; + + hskip += skip; + if (hskip < skip) // overflow + dst--; + } + } + } +} + +void Sprite::scaleSpriteCoords(int scale, int *width, int *height, int *x_align, int *y_align) { + *x_align = (*x_align * scale) >> 8; + *y_align = (*y_align * scale) >> 8; + *height = (*height * scale + 0x80) >> 8; + *width = (*width * scale + 0x80) >> 8; +} + + } // End of namespace Saga diff --git a/saga/sprite.h b/saga/sprite.h index 99623bc1d3..d4d7e3cab2 100644 --- a/saga/sprite.h +++ b/saga/sprite.h @@ -69,7 +69,9 @@ class Sprite { int drawOccluded(SURFACE *ds, SPRITELIST *sprite_list, int sprite_num, const Point &screenCoord, int scale, int depth); private: - int decodeRLESprite(const byte *inbuf, size_t inbuf_len, byte *outbuf, size_t outbuf_len, int scale); + int decodeRLESprite(const byte *inbuf, size_t inbuf_len, byte *outbuf, size_t outbuf_len); + void scaleSprite(byte *buf, int width, int height, int scale); + void scaleSpriteCoords(int scale, int *width, int *height, int *x_align, int *y_align); SagaEngine *_vm; bool _initialized; |