diff options
-rw-r--r-- | scumm/akos.cpp | 136 | ||||
-rw-r--r-- | scumm/akos.h | 8 | ||||
-rw-r--r-- | scumm/base-costume.h | 20 | ||||
-rw-r--r-- | scumm/costume.cpp | 47 |
4 files changed, 116 insertions, 95 deletions
diff --git a/scumm/akos.cpp b/scumm/akos.cpp index 306b65a426..a59bcf8252 100644 --- a/scumm/akos.cpp +++ b/scumm/akos.cpp @@ -19,6 +19,7 @@ * $Header$ * */ + #include "stdafx.h" #include "scumm.h" #include "actor.h" @@ -44,12 +45,6 @@ struct AkosOffset { uint16 akci; } GCC_PACK; -struct AkosCI { - uint16 width, height; - int16 rel_x, rel_y; - int16 move_x, move_y; -} GCC_PACK; - #if !defined(__GNUC__) #pragma END_PACK_STRUCTS #endif @@ -239,11 +234,12 @@ byte AkosRenderer::drawLimb(const CostumeData &cost, int limb) { uint code; const byte *p; const AkosOffset *off; - const AkosCI *the_akci; + const CostumeInfo *costumeInfo; uint i, extra; + byte result = 0; if (!cost.active[limb] || cost.stopped & (1 << limb)) - return false; + return 0; p = aksq + cost.curpos[limb]; @@ -252,7 +248,7 @@ byte AkosRenderer::drawLimb(const CostumeData &cost, int limb) { code = (code << 8) | p[1]; if (code == AKC_Return || code == AKC_EndSeq) - return false; + return 0; if (code != AKC_ComplexChan) { off = akof + (code & 0xFFF); @@ -261,24 +257,24 @@ byte AkosRenderer::drawLimb(const CostumeData &cost, int limb) { assert((code & 0x7000) == 0); srcptr = akcd + READ_LE_UINT32(&off->akcd); - the_akci = (const AkosCI *) (akci + READ_LE_UINT16(&off->akci)); + costumeInfo = (const CostumeInfo *) (akci + READ_LE_UINT16(&off->akci)); - _xmoveCur = _xmove + (int16)READ_LE_UINT16(&the_akci->rel_x); - _ymoveCur = _ymove + (int16)READ_LE_UINT16(&the_akci->rel_y); - _width = READ_LE_UINT16(&the_akci->width); - _height = READ_LE_UINT16(&the_akci->height); - _xmove += (int16)READ_LE_UINT16(&the_akci->move_x); - _ymove -= (int16)READ_LE_UINT16(&the_akci->move_y); + _width = READ_LE_UINT16(&costumeInfo->width); + _height = READ_LE_UINT16(&costumeInfo->height); + _xmoveCur = _xmove + (int16)READ_LE_UINT16(&costumeInfo->rel_x); + _ymoveCur = _ymove + (int16)READ_LE_UINT16(&costumeInfo->rel_y); + _xmove += (int16)READ_LE_UINT16(&costumeInfo->move_x); + _ymove -= (int16)READ_LE_UINT16(&costumeInfo->move_y); switch (codec) { case 1: - codec1(); + result |= codec1(); break; case 5: - codec5(); + result |= codec5(); break; case 16: - codec16(); + result |= codec16(); break; default: error("akos_drawCostumeChannel: invalid codec %d", codec); @@ -294,25 +290,25 @@ byte AkosRenderer::drawLimb(const CostumeData &cost, int limb) { off = akof + code; srcptr = akcd + READ_LE_UINT32(&off->akcd); - the_akci = (const AkosCI *) (akci + READ_LE_UINT16(&off->akci)); + costumeInfo = (const CostumeInfo *) (akci + READ_LE_UINT16(&off->akci)); + + _width = READ_LE_UINT16(&costumeInfo->width); + _height = READ_LE_UINT16(&costumeInfo->height); _xmoveCur = _xmove + (int16)READ_LE_UINT16(p + 0); _ymoveCur = _ymove + (int16)READ_LE_UINT16(p + 2); p += (p[4] & 0x80) ? 6 : 5; - _width = READ_LE_UINT16(&the_akci->width); - _height = READ_LE_UINT16(&the_akci->height); - switch (codec) { case 1: - codec1(); + result |= codec1(); break; case 5: - codec5(); + result |= codec5(); break; case 16: - codec16(); + result |= codec16(); break; default: error("akos_drawCostumeChannel: invalid codec %d", codec); @@ -320,7 +316,7 @@ byte AkosRenderer::drawLimb(const CostumeData &cost, int limb) { } } - return true; + return result; } void AkosRenderer::codec1_genericDecode() { @@ -347,7 +343,7 @@ void AkosRenderer::codec1_genericDecode() { do { len = *src++; - color = len >> v1.shl; + color = len >> v1.shr; len &= v1.mask; if (!len) len = *src++; @@ -411,7 +407,7 @@ void AkosRenderer::codec1_spec1() { do { len = *src++; - color = len >> v1.shl; + color = len >> v1.shr; len &= v1.mask; if (!len) len = *src++; @@ -482,7 +478,7 @@ void AkosRenderer::codec1_spec3() { do { len = *src++; - color = len >> v1.shl; + color = len >> v1.shr; len &= v1.mask; if (!len) len = *src++; @@ -632,15 +628,16 @@ const byte default_scale_table[768] = { }; #endif -void AkosRenderer::codec1() { +byte AkosRenderer::codec1() { int num_colors; bool use_scaling; int i, j; - int cur_x, x_right, x_left, skip = 0, tmp_x, tmp_y; + int cur_x, x_right, x_left, skip = 0, startScaleIndexX, tmp_y; int cur_y, y_top, y_bottom; bool y_clipping; bool charsetmask, masking; int step; + byte drawFlag = 1; /* implement custom scale table */ @@ -655,13 +652,13 @@ void AkosRenderer::codec1() { num_colors = _vm->getResourceDataSize(akpl); if (num_colors == 32) { v1.mask = (1 << 3) - 1; - v1.shl = 3; + v1.shr = 3; } else if (num_colors == 64) { v1.mask = (1 << 2) - 1; - v1.shl = 2; + v1.shr = 2; } else { v1.mask = (1 << 4) - 1; - v1.shl = 4; + v1.shr = 4; } use_scaling = (_scaleX != 0xFF) || (_scaleY != 0xFF); @@ -680,8 +677,8 @@ void AkosRenderer::codec1() { if (_mirror) { /* Adjust X position */ - tmp_x = 0x180 - _xmoveCur; - j = tmp_x; + startScaleIndexX = 0x180 - _xmoveCur; + j = startScaleIndexX; for (i = 0; i < _xmoveCur; i++) { if (v1.scaletable[j++] < _scaleX) cur_x -= v1.scaleXstep; @@ -689,11 +686,11 @@ void AkosRenderer::codec1() { x_left = x_right = cur_x; - j = tmp_x; + j = startScaleIndexX; for (i = 0, skip = 0; i < _width; i++) { if (x_right < 0) { skip++; - tmp_x = j; + startScaleIndexX = j; } if (v1.scaletable[j++] < _scaleX) x_right++; @@ -701,8 +698,8 @@ void AkosRenderer::codec1() { } else { /* No mirror */ /* Adjust X position */ - tmp_x = 0x180 + _xmoveCur; - j = tmp_x; + startScaleIndexX = 0x180 + _xmoveCur; + j = startScaleIndexX; for (i = 0; i < _xmoveCur; i++) { if (v1.scaletable[j++] < _scaleX) cur_x += v1.scaleXstep; @@ -710,10 +707,10 @@ void AkosRenderer::codec1() { x_left = x_right = cur_x; - j = tmp_x; + j = startScaleIndexX; for (i = 0, skip = 0; i < _width; i++) { if (x_left >= (int)outwidth) { - tmp_x = j; + startScaleIndexX = j; skip++; } if (v1.scaletable[j--] < _scaleX) @@ -762,11 +759,11 @@ void AkosRenderer::codec1() { y_top = cur_y; y_bottom = cur_y + _height; - tmp_x = 0x180; + startScaleIndexX = 0x180; tmp_y = 0x180; } - v1.tmp_x = tmp_x; + v1.tmp_x = startScaleIndexX; v1.tmp_y = tmp_y; v1.skip_width = _width; @@ -775,10 +772,10 @@ void AkosRenderer::codec1() { v1.scaleXstep = -v1.scaleXstep; if ((int) y_top >= (int)outheight || y_bottom <= 0) - return; + return 0; if ((int)x_left >= (int)outwidth || x_right <= 0) - return; + return 1; v1.replen = 0; v1.y_pitch = _height * outwidth; @@ -793,8 +790,11 @@ void AkosRenderer::codec1() { cur_x = 0; } else { skip = x_right - outwidth; - if (skip > 0) + if (skip <= 0) { + drawFlag = 2; + } else { v1.skip_width -= skip; + } } } else { v1.y_pitch++; @@ -807,8 +807,11 @@ void AkosRenderer::codec1() { cur_x = outwidth - 1; } else { skip = -1 - x_left; - if (skip > 0) + if (skip <= 0) { + drawFlag = 2; + } else { v1.skip_width -= skip; + } } } @@ -816,7 +819,7 @@ void AkosRenderer::codec1() { v1.y = cur_y; if (v1.skip_width <= 0 || _height <= 0) - return; + return 0; _vm->updateDirtyRect(0, x_left, x_right, y_top, y_bottom, _dirty_id); @@ -872,6 +875,8 @@ void AkosRenderer::codec1() { codec1_genericDecode(); break; } + + return drawFlag; } @@ -893,7 +898,7 @@ void AkosRenderer::codec1_ignorePakCols(int num) { } do { if (!--n) { - v1.repcolor = repcolor >> v1.shl; + v1.repcolor = repcolor >> v1.shr; v1.replen = replen; srcptr = src; return; @@ -902,7 +907,7 @@ void AkosRenderer::codec1_ignorePakCols(int num) { } while (1); } -void AkosRenderer::codec5() { +byte AkosRenderer::codec5() { int32 clip_left, clip_right, clip_top, clip_bottom, maxw, maxh, tmp_x, tmp_y; if (!_mirror) { @@ -937,7 +942,7 @@ void AkosRenderer::codec5() { } if ((clip_right <= clip_left) || (clip_top >= clip_bottom)) - return; + return 0; _vm->updateDirtyRect(0, clip_left, clip_right + 1, clip_top, clip_bottom + 1, _dirty_id); @@ -981,6 +986,8 @@ void AkosRenderer::codec5() { } _vm->_bompActorPalletePtr = NULL; + + return 0; } void AkosRenderer::akos16SetupBitReader(const byte *src) { @@ -1214,7 +1221,7 @@ void AkosRenderer::akos16DecompressMask(byte *dest, int32 pitch, const byte *src } } -void AkosRenderer::codec16() { +byte AkosRenderer::codec16() { int32 clip_left; if(!_mirror) { @@ -1269,7 +1276,7 @@ void AkosRenderer::codec16() { } if ((clip_left >= clip_right) || (clip_top >= clip_bottom)) - return; + return 0; _vm->updateDirtyRect(0, clip_left, clip_right + 1, clip_top, clip_bottom + 1, _dirty_id); @@ -1283,7 +1290,7 @@ void AkosRenderer::codec16() { height_unk = clip_top; int32 pitch = _vm->_screenWidth; - int32 /*tmp1, tmp2, tmp3,*/ dir; + int32 dir; if (!_mirror) { dir = -1; @@ -1292,18 +1299,7 @@ void AkosRenderer::codec16() { skip_x = _width - 1 - cur_x; cur_x = _width - 1 - tmp_skip_x; width_unk = clip_right; -/* - tmp1 = width - 1; - tmp2 = cur_x; - tmp3 = tmp1; - cur_x = skip_x; - tmp3 -= tmp2; - tmp1 -= cur_x; - width_unk = clip_right; - skip_x = tmp3; - cur_x = tmp1; -*/ - } else { + } else { dir = 1; width_unk = clip_left; } @@ -1329,12 +1325,14 @@ void AkosRenderer::codec16() { if (_zbuf == 0) { akos16Decompress(dest, pitch, srcptr, cur_x, out_height, dir, numskip_before, numskip_after, transparency); - return; + return 0; } byte *ptr = _vm->_screenStartStrip + _vm->getResourceAddress(rtBuffer, 9) + _vm->gdi._imgBufOffs[_zbuf]; ptr += _numStrips * clip_top + (clip_left / 8); akos16DecompressMask(dest, pitch, srcptr, cur_x, out_height, dir, numskip_before, numskip_after, transparency, ptr, clip_left / 8); + + return 0; } bool Scumm::akos_increaseAnims(const byte *akos, Actor *a) { diff --git a/scumm/akos.h b/scumm/akos.h index 4c30acfdab..e40294c759 100644 --- a/scumm/akos.h +++ b/scumm/akos.h @@ -55,7 +55,7 @@ protected: struct { /* codec stuff */ const byte *scaletable; - byte mask, shl; + byte mask, shr; bool doContinue; byte repcolor; byte replen; @@ -101,16 +101,16 @@ public: protected: byte drawLimb(const CostumeData &cost, int limb); - void codec1(); + byte codec1(); void codec1_spec1(); void codec1_spec2(); void codec1_spec3(); void codec1_genericDecode(); void codec1_ignorePakCols(int num); - void codec5(); + byte codec5(); - void codec16(); + byte codec16(); void akos16SetupBitReader(const byte *src); void akos16PutOnScreen(byte *dest, const byte *src, byte transparency, int32 count); void akos16SkipData(int32 numskip); diff --git a/scumm/base-costume.h b/scumm/base-costume.h index 172ac92697..327bb8bf99 100644 --- a/scumm/base-costume.h +++ b/scumm/base-costume.h @@ -23,9 +23,27 @@ #ifndef BASE_COSTUME_H #define BASE_COSTUME_H -class Scumm; +#include "scummsys.h" + +#if !defined(__GNUC__) +#pragma START_PACK_STRUCTS +#endif + +struct CostumeInfo { + uint16 width, height; + int16 rel_x, rel_y; + int16 move_x, move_y; +} GCC_PACK; +#if !defined(__GNUC__) +#pragma END_PACK_STRUCTS +#endif + +class Scumm; +/* + * Base class for both CostumeRenderer and AkosRenderer + */ struct BaseCostumeRenderer { public: byte _dirty_id; diff --git a/scumm/costume.cpp b/scumm/costume.cpp index 0fdf98cfe1..c6603d5cce 100644 --- a/scumm/costume.cpp +++ b/scumm/costume.cpp @@ -78,11 +78,13 @@ const byte cost_scaleTable[256] = { }; byte CostumeRenderer::mainRoutine(int slot, int frame) { - int xmove, ymove, i, b, s; + int xmove, ymove, i, s; + byte drawFlag = 1; uint scal; - bool scaling; + bool use_scaling; byte startScaleIndexX; int ex1, ex2; + const CostumeInfo *costumeInfo; CHECK_HEAP _maskval = 0xF; @@ -92,14 +94,17 @@ byte CostumeRenderer::mainRoutine(int slot, int frame) { _shrval = 3; } - _width2 = _srcptr[0]; - _width = _width2; - _height2 = _srcptr[2]; - _height = _height2; - xmove = (int16)READ_LE_UINT16(_srcptr + 4) + _xmove; - ymove = (int16)READ_LE_UINT16(_srcptr + 6) + _ymove; - _xmove += (int16)READ_LE_UINT16(_srcptr + 8); - _ymove -= (int16)READ_LE_UINT16(_srcptr + 10); + // FIXME: those are here just in case... you never now... + assert(_srcptr[1] == 0); + assert(_srcptr[3] == 0); + + costumeInfo = (const CostumeInfo *)_srcptr; + _width = _width2 = READ_LE_UINT16(&costumeInfo->width); + _height = _height2 = READ_LE_UINT16(&costumeInfo->height); + xmove = _xmove + (int16)READ_LE_UINT16(&costumeInfo->rel_x); + ymove = _ymove + (int16)READ_LE_UINT16(&costumeInfo->rel_y); + _xmove += (int16)READ_LE_UINT16(&costumeInfo->move_x); + _ymove -= (int16)READ_LE_UINT16(&costumeInfo->move_y); _srcptr += 12; switch (_loaded._ptr[7] & 0x7F) { @@ -117,10 +122,11 @@ byte CostumeRenderer::mainRoutine(int slot, int frame) { _xpos = _actorX; _ypos = _actorY; - scaling = _scaleX == 255 && _scaleY == 255 ? 0 : 1; + use_scaling = (_scaleX != 0xFF) || (_scaleY != 0xFF); + s = 0; - if (scaling) { + if (use_scaling) { _scaleIndexXStep = -1; if (xmove < 0) { xmove = -xmove; @@ -130,8 +136,7 @@ byte CostumeRenderer::mainRoutine(int slot, int frame) { if (_mirror) { startScaleIndexX = _scaleIndexX = 128 - xmove; for (i = 0; i < xmove; i++) { - scal = cost_scaleTable[_scaleIndexX++]; - if (scal < _scaleX) + if (cost_scaleTable[_scaleIndexX++] < _scaleX) _xpos -= _scaleIndexXStep; } _right = _left = _xpos; @@ -214,12 +219,12 @@ byte CostumeRenderer::mainRoutine(int slot, int frame) { _ypitch = _height * _vm->_screenWidth; _docontinue = 0; - b = 1; if (_left >= _vm->_screenWidth || _right <= 0) return 1; + if (_mirror) { _ypitch--; - if (scaling == 0) + if (use_scaling == 0) s = -_xpos; if (s > 0) { _width2 -= s; @@ -229,14 +234,14 @@ byte CostumeRenderer::mainRoutine(int slot, int frame) { } else { s = _right - _vm->_screenWidth; if (s <= 0) { - b = 2; + drawFlag = 2; } else { _width2 -= s; } } } else { _ypitch++; - if (scaling == 0) + if (use_scaling == 0) s = _right - _vm->_screenWidth; if (s > 0) { _width2 -= s; @@ -246,7 +251,7 @@ byte CostumeRenderer::mainRoutine(int slot, int frame) { } else { s = -1 - _left; if (s <= 0) - b = 2; + drawFlag = 2; else _width2 -= s; } @@ -302,7 +307,7 @@ byte CostumeRenderer::mainRoutine(int slot, int frame) { proc3(); CHECK_HEAP - return b; + return drawFlag; } void CostumeRenderer::proc3() { @@ -360,7 +365,7 @@ void CostumeRenderer::proc3() { y = _ypostop; _scaleIndexY = _scaleIndexYTop; t = _scaleIndexX; - _scaleIndexX = t + _scaleIndexXStep; + _scaleIndexX += _scaleIndexXStep; if (_scaleX == 255 || cost_scaleTable[t] < _scaleX) { _xpos += _scaleIndexXStep; if (_xpos < 0 || _xpos >= _vm->_screenWidth) |