diff options
author | Eugene Sandulenko | 2005-03-21 23:51:48 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2005-03-21 23:51:48 +0000 |
commit | 0bcb0ac2579faf061ec677e0b4ac8e37697d6dc7 (patch) | |
tree | 83eabb9bb748ae9b72430bf409968fae4cf25f37 /scumm | |
parent | 11a1f9bb00b5b008417e92e4d1c3fbfa8000d96d (diff) | |
download | scummvm-rg350-0bcb0ac2579faf061ec677e0b4ac8e37697d6dc7.tar.gz scummvm-rg350-0bcb0ac2579faf061ec677e0b4ac8e37697d6dc7.tar.bz2 scummvm-rg350-0bcb0ac2579faf061ec677e0b4ac8e37697d6dc7.zip |
Many MM NES fixes/improvements from Quietust:
o Doesn't crash when going upstairs. Now game is playable up to
the green tentacle
o Proper subtitles colors
o Room mask is decoded but doesn't affect sprites yet
o Inventory draw issues fixed
o Fix actors position when they're facing right
svn-id: r17191
Diffstat (limited to 'scumm')
-rw-r--r-- | scumm/actor.cpp | 19 | ||||
-rw-r--r-- | scumm/charset.cpp | 8 | ||||
-rw-r--r-- | scumm/costume.cpp | 6 | ||||
-rw-r--r-- | scumm/gfx.cpp | 45 | ||||
-rw-r--r-- | scumm/gfx.h | 2 | ||||
-rw-r--r-- | scumm/script_v2.cpp | 16 | ||||
-rw-r--r-- | scumm/scumm.cpp | 4 | ||||
-rw-r--r-- | scumm/verbs.cpp | 59 |
8 files changed, 116 insertions, 43 deletions
diff --git a/scumm/actor.cpp b/scumm/actor.cpp index ba1c1b81ad..15cbc22dbd 100644 --- a/scumm/actor.cpp +++ b/scumm/actor.cpp @@ -798,15 +798,16 @@ void Actor::showActor() { // V1 Maniac doesn't have a ScummVar for VAR_TALK_ACTOR, and just uses // an internal variable. Emulate this to prevent overwriting script vars... +// Maniac NES (V1), however, DOES have a ScummVar for VAR_TALK_ACTOR int ScummEngine::getTalkingActor() { - if (_gameId == GID_MANIAC && _version == 1) + if (_gameId == GID_MANIAC && _version == 1 && !(_features & GF_NES)) return _V1TalkingActor; else return VAR(VAR_TALK_ACTOR); } void ScummEngine::setTalkingActor(int value) { - if (_gameId == GID_MANIAC && _version == 1) + if (_gameId == GID_MANIAC && _version == 1 && !(_features & GF_NES)) _V1TalkingActor = value; else VAR(VAR_TALK_ACTOR) = value; @@ -1012,7 +1013,12 @@ void Actor::drawActorCostume(bool hitTestMode) { bcr->_actorX = _pos.x + _offsX - _vm->virtscr[0].xstart; bcr->_actorY = _pos.y + _offsY - _elevation; - if ((_vm->_version <= 2) && !(_vm->_features & GF_NES)) { + if (_vm->_features & GF_NES) { + // In the NES version, when the actor is facing right, + // we need to shift it 8 pixels to the left + if (_facing == 90) + bcr->_actorX -= 8; + } else if (_vm->_version <= 2) { // HACK: We have to adjust the x position by one strip (8 pixels) in // V2 games. However, it is not quite clear to me why. And to fully // match the original, it seems we have to offset by 2 strips if the @@ -1280,6 +1286,13 @@ void ScummEngine::actorTalk(const byte *msg) { if (_heversion >= 72 || getTalkingActor() > 0x7F) { _charsetColor = (byte)_string[0].color; + } else if (_features & GF_NES) { + static int NES_lastActor = 0; + static int NES_color = 0; + if (NES_lastActor != getTalkingActor()) + NES_color ^= 1; + NES_lastActor = getTalkingActor(); + _charsetColor = NES_color; } else { a = derefActor(getTalkingActor(), "actorTalk(2)"); _charsetColor = a->_talkColor; diff --git a/scumm/charset.cpp b/scumm/charset.cpp index 0ad0f40b43..98d0b8810d 100644 --- a/scumm/charset.cpp +++ b/scumm/charset.cpp @@ -1732,12 +1732,6 @@ static byte trNESSwedishTable[] = { 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5e }; -static byte NESColorTransition[] = { - 0x00, 0x02, 0x02, 0x03, 0x02, 0x01, 0x02, 0x03, - 0x00, 0x01, 0x02, 0x01, 0x00, 0x01, 0x00, 0x03 -}; - - CharsetRendererNES::CharsetRendererNES(ScummEngine *vm, Common::Language language) : CharsetRendererCommon(vm) { switch (language) { @@ -1823,7 +1817,7 @@ void CharsetRendererNES::drawBits1(const Graphics::Surface &s, byte *dst, const byte c1 = src[i + 8]; for (int j = 0; j < 8; j++) dst[j] = _vm->_NESPalette[((c0 >> (7 - j)) & 1) | (((c1 >> (7 - j)) & 1) << 1) | - (NESColorTransition[_color] << 2)]; + (_color ? 12 : 8)]; dst += s.pitch; } } diff --git a/scumm/costume.cpp b/scumm/costume.cpp index 35c7b34e51..fb9fa72c9a 100644 --- a/scumm/costume.cpp +++ b/scumm/costume.cpp @@ -711,11 +711,17 @@ void CostumeRenderer::drawNESCostume(const Actor *a, int limb) { int8 x = ptr[2]; x >>= 2; ptr += 3; + if (flipped) { mask = (mask == 0x80) ? 0x01 : 0x80; x = -x; } + if ((_actorX + x < 0) || (_actorX + x + 8 >= _out.w)) + continue; + if ((_actorY + y < 0) || (_actorY + y + 8 >= _out.h)) + continue; + for (int ty = 0; ty < 8; ty++) { byte c1 = _vm->_NESCostumeGfx[_vm->_NESCostumeSet][tile * 16 + ty]; byte c2 = _vm->_NESCostumeGfx[_vm->_NESCostumeSet][tile * 16 + ty + 8]; diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp index 9a9b16b46b..549438da07 100644 --- a/scumm/gfx.cpp +++ b/scumm/gfx.cpp @@ -1438,15 +1438,10 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int wi useOrDecompress = true; if (_vm->_version == 1) { + mask_ptr = getMaskBuffer(x, y, 1); if (_vm->_features & GF_NES) { - //mask_ptr = getMaskBuffer(x, y, 1); - //for (int ii = 0; ii < height; ii++) { - // for (int jj = 0; jj < width; jj++) - // mask_ptr[jj] = 0xff; - // mask_ptr += _numStrips; - //} + drawStripNESMask(mask_ptr, stripnr, height); } else { - mask_ptr = getMaskBuffer(x, y, 1); drawStripC64Mask(mask_ptr, stripnr, width, height); } } else if (_vm->_version == 2) { @@ -1889,7 +1884,25 @@ void Gdi::decodeNESGfx(const byte *room) { adata++; } - // there's another pointer at room + 0x0E, but I don't know what data it points at + const byte *mdata = room + READ_LE_UINT16(room + 0x0E); + int mask = *mdata++; + if (mask == 0) + return; + if (mask != 1) { + debug(0,"NES room %i has irregular mask count %i!",_vm->_currentRoom,mask); + return; + } + int mwidth = *mdata++; + for (i = 0; i < 16; i++) { + n = 0; + while (n < mwidth) { + byte data = *mdata++; + for (j = 0; j < (data & 0x7F); j++) + _NESMasktable[i][n++] = (data & 0x80) ? (*mdata++) : (*mdata); + if (!(data & 0x80)) + mdata++; + } + } } void Gdi::decodeNESObject(const byte *ptr, int xpos, int ypos, int width, int height) { @@ -1937,6 +1950,22 @@ void Gdi::drawStripNES(byte *dst, int dstPitch, int stripnr, int top, int height } } +void Gdi::drawStripNESMask(byte *dst, int stripnr, int height) const { + height /= 8; + int x = stripnr; + if (x > 63) { + debug(0,"NES tried to mask invalid strip %i",stripnr); + return; + } + for (int y = 0; y < height; y++) { + byte c = ((_NESMasktable[y][x >> 3] >> (x & 7)) & 1) ? 0xFF : 0x00; + for (int i = 0; i < 8; i++) { + *dst = c; + dst += _numStrips; + } + } +} + void Gdi::drawStripC64Background(byte *dst, int dstPitch, int stripnr, int height) { int charIdx; height /= 8; diff --git a/scumm/gfx.h b/scumm/gfx.h index 5d61c1da40..fd54c8cd9b 100644 --- a/scumm/gfx.h +++ b/scumm/gfx.h @@ -232,6 +232,7 @@ protected: byte _NESNametable[16][64], _NESAttributes[64]; byte _NESBaseTiles; byte _NESNametableObj[16][64]; + byte _NESMasktable[16][8]; int _NESObj_x; /* Bitmap decompressors */ @@ -257,6 +258,7 @@ protected: /* Mask decompressors */ void drawStripC64Mask(byte *dst, int stripnr, int width, int height) const; + void drawStripNESMask(byte *dst, int stripnr, int height) const; void decompressMaskImgOr(byte *dst, const byte *src, int height) const; void decompressMaskImg(byte *dst, const byte *src, int height) const; diff --git a/scumm/script_v2.cpp b/scumm/script_v2.cpp index bcc58c7417..c3397982e7 100644 --- a/scumm/script_v2.cpp +++ b/scumm/script_v2.cpp @@ -818,8 +818,10 @@ void ScummEngine_v2::o2_verbOps() { slot = getVarOrDirectByte(PARAM_1) + 1; int prep = fetchScriptByte(); // Only used in V1? // V1 Maniac verbs are relative to the 'verb area' - under the sentence - if (_features & GF_NES) + if (_features & GF_NES) { y -= 16; + x -= 8; + } else if ((_gameId == GID_MANIAC) && (_version == 1)) y += 8; @@ -831,7 +833,11 @@ void ScummEngine_v2::o2_verbOps() { vs = &_verbs[slot]; vs->verbid = verb; - if (_version == 1) { + if (_features & GF_NES) { + vs->color = 1; + vs->hicolor = 1; + vs->dimcolor = 1; + } else if (_version == 1) { vs->color = (_gameId == GID_MANIAC && _demoMode) ? 16 : 5; vs->hicolor = 7; vs->dimcolor = 11; @@ -851,7 +857,7 @@ void ScummEngine_v2::o2_verbOps() { vs->curRect.left = x; vs->curRect.top = y; - + // FIXME: again, this map depends on the language of the game. // E.g. a german keyboard has 'z' and 'y' swapped, while a french // keyboard starts with "awert", etc. @@ -1029,7 +1035,9 @@ void ScummEngine_v2::o2_drawSentence() { _string[2].charset = 1; _string[2].ypos = virtscr[2].topline; _string[2].xpos = 0; - if (_version == 1) + if (_features & GF_NES) + _string[2].color = 0; + else if (_version == 1) _string[2].color = 16; else _string[2].color = 13; diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp index 75b9e31d2b..347d840252 100644 --- a/scumm/scumm.cpp +++ b/scumm/scumm.cpp @@ -1451,8 +1451,8 @@ void ScummEngine::scummInit() { VAR(VAR_CAMERA_ACCEL_Y) = 100; } else if (!(_features & GF_NEW_CAMERA)) { if (_features & GF_NES) { - camera._leftTrigger = 4; - camera._rightTrigger = 24; + camera._leftTrigger = 6; // 6 + camera._rightTrigger = 21; // 25 } else { camera._leftTrigger = 10; camera._rightTrigger = (_heversion >= 71) ? 70 : 30; diff --git a/scumm/verbs.cpp b/scumm/verbs.cpp index 5eb3525a5a..be210b5239 100644 --- a/scumm/verbs.cpp +++ b/scumm/verbs.cpp @@ -40,7 +40,11 @@ void ScummEngine_v2::initV2MouseOver() { int i; int arrow_color, color, hi_color; - if (_version == 1) { + if (_features & GF_NES) { + color = 0; + hi_color = 0; + arrow_color = 0; + } else if (_version == 1) { color = 16; hi_color = 7; arrow_color = 6; @@ -57,7 +61,7 @@ void ScummEngine_v2::initV2MouseOver() { for (i = 0; i < 2; i++) { if (_features & GF_NES) { v2_mouseover_boxes[2 * i].rect.left = 0; - v2_mouseover_boxes[2 * i].rect.right = 96; + v2_mouseover_boxes[2 * i].rect.right = 104; v2_mouseover_boxes[2 * i].rect.top = 48 + 8 * i; v2_mouseover_boxes[2 * i].rect.bottom = v2_mouseover_boxes[2 * i].rect.top + 8; } else { @@ -71,7 +75,7 @@ void ScummEngine_v2::initV2MouseOver() { v2_mouseover_boxes[2 * i].hicolor = hi_color; if (_features & GF_NES) { - v2_mouseover_boxes[2 * i + 1].rect.left = 128; + v2_mouseover_boxes[2 * i + 1].rect.left = 120; v2_mouseover_boxes[2 * i + 1].rect.right = 224; v2_mouseover_boxes[2 * i + 1].rect.top = v2_mouseover_boxes[2 * i].rect.top; v2_mouseover_boxes[2 * i + 1].rect.bottom = v2_mouseover_boxes[2 * i].rect.bottom; @@ -89,8 +93,8 @@ void ScummEngine_v2::initV2MouseOver() { // Inventory arrows if (_features & GF_NES) { - v2_mouseover_boxes[kInventoryUpArrow].rect.left = 96; - v2_mouseover_boxes[kInventoryUpArrow].rect.right = 128; + v2_mouseover_boxes[kInventoryUpArrow].rect.left = 104; + v2_mouseover_boxes[kInventoryUpArrow].rect.right = 112; v2_mouseover_boxes[kInventoryUpArrow].rect.top = 48; v2_mouseover_boxes[kInventoryUpArrow].rect.bottom = 56; } else { @@ -104,10 +108,10 @@ void ScummEngine_v2::initV2MouseOver() { v2_mouseover_boxes[kInventoryUpArrow].hicolor = hi_color; if (_features & GF_NES) { - v2_mouseover_boxes[kInventoryDownArrow].rect.left = 96; - v2_mouseover_boxes[kInventoryDownArrow].rect.right = 128; - v2_mouseover_boxes[kInventoryDownArrow].rect.top = 56; - v2_mouseover_boxes[kInventoryDownArrow].rect.bottom = 64; + v2_mouseover_boxes[kInventoryDownArrow].rect.left = 112; + v2_mouseover_boxes[kInventoryDownArrow].rect.right = 120; + v2_mouseover_boxes[kInventoryDownArrow].rect.top = 48; + v2_mouseover_boxes[kInventoryDownArrow].rect.bottom = 56; } else { v2_mouseover_boxes[kInventoryDownArrow].rect.left = 144; v2_mouseover_boxes[kInventoryDownArrow].rect.right = 176; @@ -265,14 +269,25 @@ void ScummEngine::redrawV2Inventory() { const byte *tmp = getObjOrActorName(obj); assert(tmp); - // Prevent inventory entries from overflowing by truncating the text - // after 144/8 = 18 chars - byte msg[18 + 1]; - msg[18] = 0; - strncpy((char *)msg, (const char *)tmp, 18); - - // Draw it - drawString(1, msg); + if (_features & GF_NES) { + // Prevent inventory entries from overflowing by truncating the text + // after 104/8 = 13 chars + byte msg[13 + 1]; + msg[13] = 0; + strncpy((char *)msg, (const char *)tmp, 13); + + // Draw it + drawString(1, msg); + } else { + // Prevent inventory entries from overflowing by truncating the text + // after 144/8 = 18 chars + byte msg[18 + 1]; + msg[18] = 0; + strncpy((char *)msg, (const char *)tmp, 18); + + // Draw it + drawString(1, msg); + } } @@ -281,7 +296,10 @@ void ScummEngine::redrawV2Inventory() { _string[1].xpos = v2_mouseover_boxes[kInventoryUpArrow].rect.left; _string[1].ypos = v2_mouseover_boxes[kInventoryUpArrow].rect.top + vs->topline; _string[1].color = v2_mouseover_boxes[kInventoryUpArrow].color; - drawString(1, (const byte *)" \1\2"); + if (_features & GF_NES) + drawString(1, (const byte *)"\x7E"); + else + drawString(1, (const byte *)" \1\2"); } // If necessary, draw "down" arrow @@ -289,7 +307,10 @@ void ScummEngine::redrawV2Inventory() { _string[1].xpos = v2_mouseover_boxes[kInventoryDownArrow].rect.left; _string[1].ypos = v2_mouseover_boxes[kInventoryDownArrow].rect.top + vs->topline; _string[1].color = v2_mouseover_boxes[kInventoryDownArrow].color; - drawString(1, (const byte *)" \3\4"); + if (_features & GF_NES) + drawString(1, (const byte *)"\x7F"); + else + drawString(1, (const byte *)" \3\4"); } } |