diff options
author | Travis Howell | 2009-10-25 14:20:47 +0000 |
---|---|---|
committer | Travis Howell | 2009-10-25 14:20:47 +0000 |
commit | 4064d35d1582e6d18b92c5ec352bde902b41e0d8 (patch) | |
tree | ca008bcb480131905aee04d8509e6276cfa394dc /engines/scumm | |
parent | 6e5dd8e357ac5f8c08e9713b59d1858086073a36 (diff) | |
download | scummvm-rg350-4064d35d1582e6d18b92c5ec352bde902b41e0d8.tar.gz scummvm-rg350-4064d35d1582e6d18b92c5ec352bde902b41e0d8.tar.bz2 scummvm-rg350-4064d35d1582e6d18b92c5ec352bde902b41e0d8.zip |
Add patch from Tobias, for initial costume support in PCE version of Loom, with minor changes.
svn-id: r45370
Diffstat (limited to 'engines/scumm')
-rw-r--r-- | engines/scumm/base-costume.h | 2 | ||||
-rw-r--r-- | engines/scumm/costume.cpp | 217 | ||||
-rw-r--r-- | engines/scumm/costume.h | 27 | ||||
-rw-r--r-- | engines/scumm/scumm.cpp | 2 |
4 files changed, 157 insertions, 91 deletions
diff --git a/engines/scumm/base-costume.h b/engines/scumm/base-costume.h index d41d795e34..d586b211f3 100644 --- a/engines/scumm/base-costume.h +++ b/engines/scumm/base-costume.h @@ -103,6 +103,8 @@ protected: // whether to draw the actor mirrored bool _mirror; + int _numBlocks; + // width and height of cel to decode int _width, _height; diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index 5c9cf11ab8..d50ae54480 100644 --- a/engines/scumm/costume.cpp +++ b/engines/scumm/costume.cpp @@ -86,13 +86,9 @@ byte ClassicCostumeRenderer::mainRoutine(int xmoveCur, int ymoveCur) { int step; Codec1 v1; - if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine) { - // FIXME: Unknown costume format - return 0; - } - const int scaletableSize = 128; const bool newAmiCost = (_vm->_game.version == 5) && (_vm->_game.platform == Common::kPlatformAmiga); + const bool pcEngCost = (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine); v1.scaletable = smallCostumeScaleTable; @@ -242,7 +238,7 @@ byte ClassicCostumeRenderer::mainRoutine(int xmoveCur, int ymoveCur) { if (!use_scaling) skip = -v1.x; if (skip > 0) { - if (!newAmiCost && _loaded._format != 0x57) { + if (!newAmiCost && !pcEngCost && _loaded._format != 0x57) { v1.skip_width -= skip; codec1_ignorePakCols(v1, skip); v1.x = 0; @@ -259,7 +255,7 @@ byte ClassicCostumeRenderer::mainRoutine(int xmoveCur, int ymoveCur) { if (!use_scaling) skip = rect.right - _out.w; if (skip > 0) { - if (!newAmiCost && _loaded._format != 0x57) { + if (!newAmiCost && !pcEngCost && _loaded._format != 0x57) { v1.skip_width -= skip; codec1_ignorePakCols(v1, skip); v1.x = _out.w - 1; @@ -311,6 +307,8 @@ byte ClassicCostumeRenderer::mainRoutine(int xmoveCur, int ymoveCur) { procC64(v1, _actorID); } else if (newAmiCost) proc3_ami(v1); + else if (pcEngCost) + procPCEngine(v1); else proc3(v1); @@ -583,14 +581,91 @@ void ClassicCostumeRenderer::proc3_ami(Codec1 &v1) { } while (1); } -void ClassicCostumeLoader::loadCostume(int id) { - _id = id; - byte *ptr = _vm->getResourceAddress(rtCostume, id); +void PCESetCostumeData(byte block[16][16], int index, byte value) { + int row = (index % 16); + int plane = (index / 16) % 4; + int colOffset = (index < 64) ? 8 : 0; + for (int i = 0; i < 8; ++i) { + int bit = (value >> (7-i)) & 0x1; + block[row][i + colOffset] |= bit << plane; + } +} - if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine) { - // FIXME: Unknown costume format +void ClassicCostumeRenderer::procPCEngine(Codec1 &v1) { + const byte *mask, *src; + byte *dst; + byte maskbit; + uint width, height; + byte scaleIndexY; + int vertShift; + + byte block[16][16]; + + src = _srcptr; + width = _width / 16; + height = _height / 16; + + if (_numBlocks == 0) return; + + scaleIndexY = _scaleIndexY; + maskbit = revBitMask(v1.x & 7); + mask = v1.mask_ptr + v1.x / 8; + + for (uint x = 0; x < width; ++x) { + dst = v1.destptr + 16 * x * _out.bytesPerPixel; + for (uint y = 0; y < height; ++y) { + vertShift = *src++; + if (vertShift == 0xFF) { + dst += 16 * _out.pitch; + continue; + } else { + dst += vertShift * _out.pitch; + } + + memset(block, 0, sizeof(block)); + + int index = 0; + while (index < 128) { + byte cmd = *src++; + int cnt = (cmd & 0x3F) + 1; + if (!(cmd & 0xC0)) { + for (int i = 0; i < cnt; ++i) + PCESetCostumeData(block, index++, 0); + } else if (cmd & 0x80) { + int value = *src++; + for (int i = 0; i < cnt; ++i) + PCESetCostumeData(block, index++, value); + } else { + for (int i = 0; i < cnt; ++i) + PCESetCostumeData(block, index++, *src++); + } + } + if (index != 128) { + printf("%d\n", index); + } + + for (int row = 0; row < 16; ++row) { + for (int col = 0; col < 16; ++col) { + int color = block[row][col]; + if (color != 0) { + if (dst < v1.destptr + _out.w * _out.h * _out.bytesPerPixel) { + if (_mirror) + dst[col] = color; + else + dst[-col] = color; + } + } + } + dst += _out.pitch; + } + } } +} + +void ClassicCostumeLoader::loadCostume(int id) { + _id = id; + byte *ptr = _vm->getResourceAddress(rtCostume, id); if (_vm->_game.version >= 6) ptr += 8; @@ -607,6 +682,17 @@ void ClassicCostumeLoader::loadCostume(int id) { _format = ptr[7] & 0x7F; _mirror = (ptr[7] & 0x80) != 0; _palette = ptr + 8; + + if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine) { + _numColors = 16; + + ptr += 8 + 17; + _animCmds = READ_LE_UINT16(ptr) + ptr + 2; + _frameOffsets = ptr + 2; + _dataOffsets = ptr + 34; + return; + } + switch (_format) { case 0x57: // Only used in V1 games _numColors = 0; @@ -737,8 +823,49 @@ byte NESCostumeRenderer::drawLimb(const Actor *a, int limb) { return 0; } +#define PCE_SIGNED(a) (((a) & 0x80) ? -((a) & 0x7F) : (a)) + byte PCEngineCostumeRenderer::drawLimb(const Actor *a, int limb) { - // TODO + int i; + int code; + const byte *frameptr, *offset; + const CostumeData &cost = a->_cost; + + // If the specified limb is stopped or not existing, do nothing. + if (cost.curpos[limb] == 0xFFFF || cost.stopped & (1 << limb)) + return 0; + + // Determine the position the limb is at + i = cost.curpos[limb] & 0x7FFF; + + // Get the frame pointer for that limb + offset = _loaded._frameOffsets + limb * 2; + frameptr = READ_LE_UINT16(offset) + offset + 2; + + // Determine the offset to the costume data for the limb at position i + code = _loaded._animCmds[i] & 0x7F; + + // Code 0x7B indicates a limb for which there is nothing to draw + if (code != 0x7B) { + offset = frameptr + code * 2; + _srcptr = READ_LE_UINT16(offset) + offset + 2; + + if (code < 0x79) { + int xmoveCur, ymoveCur; + + _numBlocks = _srcptr[0]; + _width = _srcptr[1] * 16; + _height = _srcptr[2] * 16; + xmoveCur = _xmove + PCE_SIGNED(_srcptr[3]); + ymoveCur = _ymove + PCE_SIGNED(_srcptr[4]); + _xmove += PCE_SIGNED(_srcptr[5]); + _ymove += PCE_SIGNED(_srcptr[6]); + _srcptr += 7; + + return mainRoutine(xmoveCur, ymoveCur); + } + } + return 0; } @@ -813,17 +940,9 @@ void PCEngineCostumeRenderer::setPalette(uint16 *palette) { // TODO } -void PCEngineCostumeRenderer::setFacing(const Actor *a) { - // TODO - //_mirror = newDirToOldDir(a->getFacing()) != 0 || _loaded._mirror; -} - -void PCEngineCostumeRenderer::setCostume(int costume, int shadow) { - _loaded.loadCostume(costume); -} - void ClassicCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { const byte *r; + const byte *baseptr; uint mask, j; int i; byte extra, cmd; @@ -837,9 +956,13 @@ void ClassicCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) return; } - r = _baseptr + READ_LE_UINT16(_dataOffsets + anim * 2); + if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine) + baseptr = _dataOffsets + anim * 2 + 2; + else + baseptr = _baseptr; - if (r == _baseptr) { + r = baseptr + READ_LE_UINT16(_dataOffsets + anim * 2); + if (r == baseptr) { return; } @@ -852,7 +975,9 @@ void ClassicCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) i = 0; do { if (mask & 0x8000) { - if (_vm->_game.version <= 3) { + if ((_vm->_game.version <= 3) && + !(_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine)) + { j = *r++; if (j == 0xFF) @@ -1042,48 +1167,6 @@ byte NESCostumeLoader::increaseAnim(Actor *a, int slot) { return (a->_cost.curpos[slot] != oldframe); } -void PCEngineCostumeLoader::loadCostume(int id) { - _id = id; - _baseptr = _vm->getResourceAddress(rtCostume, id); - _dataOffsets = _baseptr + 2; - _numAnim = 0x17; -} - -void PCEngineCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { - int anim; - - loadCostume(a->_costume); - - anim = 4 * frame + newDirToOldDir(a->getFacing()); - - if (anim > _numAnim) { - return; - } - - a->_cost.curpos[0] = 0; - a->_cost.start[0] = 0; - a->_cost.end[0] = _dataOffsets[2 * anim + 1]; - a->_cost.frame[0] = frame; -} - -byte PCEngineCostumeLoader::increaseAnims(Actor *a) { - int i; - byte r = 0; - - for (i = 0; i != 16; i++) { - if (a->_cost.curpos[i] != 0xFFFF) - r += increaseAnim(a, i); - } - return r; -} - -byte PCEngineCostumeLoader::increaseAnim(Actor *a, int slot) { - int oldframe = a->_cost.curpos[slot]++; - if (a->_cost.curpos[slot] >= a->_cost.end[slot]) - a->_cost.curpos[slot] = a->_cost.start[slot]; - return (a->_cost.curpos[slot] != oldframe); -} - static const byte actorColorsMMC64[25] = { 0, 7, 2, 6, 9, 1, 3, 7, 7, 1, 1, 9, 1, 4, 5, 5, 4, 1, 0, 5, 4, 2, 2, 7, 7 }; diff --git a/engines/scumm/costume.h b/engines/scumm/costume.h index b845ee2158..5191a9388e 100644 --- a/engines/scumm/costume.h +++ b/engines/scumm/costume.h @@ -71,22 +71,6 @@ protected: byte increaseAnim(Actor *a, int slot); }; -class PCEngineCostumeLoader : public BaseCostumeLoader { -public: - int _id; - const byte *_baseptr; - const byte *_dataOffsets; - byte _numAnim; - - PCEngineCostumeLoader(ScummEngine *vm) : BaseCostumeLoader(vm) {} - void loadCostume(int id); - void costumeDecodeData(Actor *a, int frame, uint usemask); - byte increaseAnims(Actor *a); - -protected: - byte increaseAnim(Actor *a, int slot); -}; - class C64CostumeLoader : public ClassicCostumeLoader { public: C64CostumeLoader(ScummEngine *vm) : ClassicCostumeLoader(vm) {} @@ -126,6 +110,8 @@ protected: void procC64(Codec1 &v1, int actor); + void procPCEngine(Codec1 &v1); + byte mainRoutine(int xmoveCur, int ymoveCur); }; @@ -144,16 +130,11 @@ protected: byte drawLimb(const Actor *a, int limb); }; -class PCEngineCostumeRenderer : public BaseCostumeRenderer { -protected: - PCEngineCostumeLoader _loaded; - +class PCEngineCostumeRenderer : public ClassicCostumeRenderer { public: - PCEngineCostumeRenderer(ScummEngine *vm) : BaseCostumeRenderer(vm), _loaded(vm) {} + PCEngineCostumeRenderer(ScummEngine *vm) : ClassicCostumeRenderer(vm) {} void setPalette(uint16 *palette); - void setFacing(const Actor *a); - void setCostume(int costume, int shadow); protected: byte drawLimb(const Actor *a, int limb); diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 19c76d6b7d..b8afb5460e 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -1284,7 +1284,7 @@ void ScummEngine::setupCostumeRenderer() { _costumeLoader = new NESCostumeLoader(this); } else if (_game.platform == Common::kPlatformPCEngine) { _costumeRenderer = new PCEngineCostumeRenderer(this); - _costumeLoader = new PCEngineCostumeLoader(this); + _costumeLoader = new ClassicCostumeLoader(this); } else { _costumeRenderer = new ClassicCostumeRenderer(this); _costumeLoader = new ClassicCostumeLoader(this); |