diff options
-rw-r--r-- | scumm/charset.cpp | 7 | ||||
-rw-r--r-- | scumm/costume.cpp | 48 | ||||
-rw-r--r-- | scumm/cursor.cpp | 4 | ||||
-rw-r--r-- | scumm/gfx.cpp | 86 | ||||
-rw-r--r-- | scumm/palette.cpp | 4 | ||||
-rw-r--r-- | scumm/script_v2.cpp | 12 | ||||
-rw-r--r-- | scumm/scumm.cpp | 20 | ||||
-rw-r--r-- | scumm/scumm.h | 12 |
8 files changed, 116 insertions, 77 deletions
diff --git a/scumm/charset.cpp b/scumm/charset.cpp index 57684f5441..9ba5619c43 100644 --- a/scumm/charset.cpp +++ b/scumm/charset.cpp @@ -1758,7 +1758,7 @@ void CharsetRendererNES::printChar(int chr) { if (chr == '@') return; - charPtr = _vm->_NESPatTable + _trTable[chr - 32] * 16; + charPtr = _vm->_NESPatTable[1] + _trTable[chr - 32] * 16; width = getCharWidth(chr); height = 8; @@ -1766,6 +1766,7 @@ void CharsetRendererNES::printChar(int chr) { origHeight = height; if (_firstChar) { + _left += 16; _str.left = _left; _str.top = _top; _str.right = _left; @@ -1809,7 +1810,7 @@ void CharsetRendererNES::drawChar(int chr, const Graphics::Surface &s, int x, in byte *charPtr, *dst; int width, height; - charPtr = _vm->_NESPatTable + _trTable[chr - 32] * 16; + charPtr = _vm->_NESPatTable[1] + _trTable[chr - 32] * 16; width = getCharWidth(chr); height = 8; @@ -1822,7 +1823,7 @@ void CharsetRendererNES::drawBits1(const Graphics::Surface &s, byte *dst, const byte c0 = src[i]; 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) | + dst[j] = _vm->_NESPalette[0][((c0 >> (7 - j)) & 1) | (((c1 >> (7 - j)) & 1) << 1) | (_color ? 12 : 8)]; dst += s.pitch; } diff --git a/scumm/costume.cpp b/scumm/costume.cpp index fb9fa72c9a..fdf4d4145a 100644 --- a/scumm/costume.cpp +++ b/scumm/costume.cpp @@ -572,11 +572,6 @@ static const int v1MMNESLookup[25] = { 0x17, 0x00, 0x01, 0x05, 0x16 }; -static const int v1MMNEScostTables[2][6] = { - /* desc lens offs data gfx pal */ - { 25, 27, 29, 31, 33, 35}, - { 26, 28, 30, 32, 34, 36} -}; /** * costume ID -> v1MMNESLookup[] -> desc -> lens & offs -> data -> Gfx & pal */ @@ -598,13 +593,13 @@ void LoadedCostume::loadNEScostume(void) { offset = src[(frameset * 4 + framenum) * 2]; // Lookup & desc - table = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_NESCostumeSet][0]); - offset = READ_LE_UINT16(table + v1MMNESLookup[_id] * 2 + 2); + table = _vm->_NEScostdesc; + offset = READ_LE_UINT16(table + v1MMNESLookup[_id] * 2); - if (v1MMNESLookup[_id] * 2 >= READ_LE_UINT16(table)) { - _numAnim = (READ_LE_UINT16(table) - v1MMNESLookup[_id] * 2) / 2; // should never happen + if (v1MMNESLookup[_id] * 2 + 2 >= READ_LE_UINT16(table - 2)) { + _numAnim = (READ_LE_UINT16(table) - v1MMNESLookup[_id] * 2) / 2; } else { - _numAnim = (READ_LE_UINT16(table + v1MMNESLookup[_id] * 2 + 4) - offset) / 2; + _numAnim = (READ_LE_UINT16(table + v1MMNESLookup[_id] * 2 + 2) - offset) / 2; } } @@ -674,7 +669,7 @@ void LoadedCostume::loadCostume(int id) { void CostumeRenderer::drawNESCostume(const Actor *a, int limb) { const byte *src; int offset, numSprites; - byte *table, *ptr, *spritesDefs, *spritesOffsetTab, *numSpritesTab, *spritesPal; + const byte *table, *ptr, *spritesDefs, *spritesOffsetTab, *numSpritesTab; const CostumeData &cost = a->_cost; int anim = cost.frame[limb]; int frameNum = cost.curpos[limb]; @@ -686,17 +681,15 @@ void CostumeRenderer::drawNESCostume(const Actor *a, int limb) { bool flipped = (newDirToOldDir(a->getFacing()) == 1); // Lookup & desc - table = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_NESCostumeSet][0]) + 2; + table = _vm->_NEScostdesc; offset = READ_LE_UINT16(table + v1MMNESLookup[_loaded._id] * 2); // lens - numSpritesTab = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_NESCostumeSet][1]) + 2 + offset; + numSpritesTab = _vm->_NEScostlens + offset; // offs - spritesOffsetTab = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_NESCostumeSet][2]) + 2 + offset*2; - // data - spritesDefs = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_NESCostumeSet][3]) + 2; + spritesOffsetTab = _vm->_NEScostoffs + offset*2; // data - spritesPal = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_NESCostumeSet][5]) + 2; + spritesDefs = _vm->_NEScostdata; ptr = spritesDefs + READ_LE_UINT16(spritesOffsetTab + frame*2); numSprites = numSpritesTab[frame] + 1; @@ -723,8 +716,8 @@ void CostumeRenderer::drawNESCostume(const Actor *a, int limb) { 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]; + byte c1 = _vm->_NESPatTable[0][tile * 16 + ty]; + byte c2 = _vm->_NESPatTable[0][tile * 16 + ty + 8]; for (int tx = 0; tx < 8; tx++) { unsigned char c = ((c1 & mask) ? 1 : 0) | ((c2 & mask) ? 2 : 0) | palette; if (mask == 0x01) { @@ -736,7 +729,7 @@ void CostumeRenderer::drawNESCostume(const Actor *a, int limb) { } if (!(c & 3)) continue; - *((byte *)_out.pixels + (_actorY + y + ty) * _out.pitch + (_actorX + x + tx)) = spritesPal[c]; + *((byte *)_out.pixels + (_actorY + y + ty) * _out.pitch + (_actorX + x + tx)) = _vm->_NESPalette[1][c]; } } if (left > _actorX + x) @@ -814,21 +807,6 @@ byte CostumeRenderer::drawLimb(const Actor *a, int limb) { } -extern void decodeNESTileData(const byte *src, byte *dest); - -void ScummEngine::cost_decodeNESCostumeGfx() { - for (int n = 0; n < 2; n++) { - byte *patTable = getResourceAddress(rtCostume, v1MMNEScostTables[n][4]); - int maxSprites = patTable[2]; - if (maxSprites == 0) - maxSprites = 256; - _NESCostumeGfx[n] = (byte *)calloc(maxSprites * 16, 1); - decodeNESTileData(patTable,_NESCostumeGfx[n]); - // We will not need it anymore - nukeResource(rtCostume, v1MMNEScostTables[n][4]); - } -} - void ScummEngine::cost_decodeData(Actor *a, int frame, uint usemask) { const byte *r; uint mask, j; diff --git a/scumm/cursor.cpp b/scumm/cursor.cpp index 7a87c5d3a3..9d025c6e60 100644 --- a/scumm/cursor.cpp +++ b/scumm/cursor.cpp @@ -343,8 +343,8 @@ void ScummEngine_v5::setBuiltinCursor(int idx) { _cursor.hotspotY = 0; byte *dst = _grabbedCursor; - byte *src = &_NESCostumeGfx[0][0xfa * 16]; - byte *palette = getResourceAddress(rtCostume, 35) + 2; + byte *src = &_NESPatTable[0][0xfa * 16]; + byte *palette = _NESPalette[1]; for (i = 0; i < 8; i++) { byte c0 = src[i]; diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp index 4707758312..abb697c7e4 100644 --- a/scumm/gfx.cpp +++ b/scumm/gfx.cpp @@ -171,7 +171,7 @@ static const TransitionEffect transitionEffects[6] = { // Horizontal wipe (a box expands from left to right side). For MM NES { - 14, // Number of iterations + 16, // Number of iterations { 2, 0, 2, 0, 2, 0, 2, 0, @@ -326,7 +326,7 @@ void ScummEngine::initVirtScreen(VirtScreenNumber slot, int number, int top, int createResource(rtBuffer, slot + 1, size); vs->pixels = getResourceAddress(rtBuffer, slot + 1); - memset(vs->pixels, 0, size); // reset background + memset(vs->pixels, 0, size); // reset background if (twobufs) { vs->backBuf = createResource(rtBuffer, slot + 5, size); @@ -544,7 +544,17 @@ void Gdi::drawStripToScreen(VirtScreen *vs, int x, int width, int top, int botto Common::kHercW, x + (Common::kHercW - _vm->_screenWidth * 2) / 2, y, width, height); } else { // Finally blit the whole thing to the screen - _vm->_system->copyRectToScreen(_compositeBuf + x + y * _vm->_screenWidth, _vm->_screenWidth, x, y, width, height); + int x1 = x; + + // HACK: This is dirty hack which renders narrow NES rooms centered + // NES can address negative number sprites and that poses problem for + // our code. So instead adding zillions of fixes and potentially break + // other games we shift it right on rendering stage + if (_vm->_features & GF_NES && _vm->_NESStartStrip > 0 && vs->number == kMainVirtScreen) { + x += _vm->_NESStartStrip * 8; + } + + _vm->_system->copyRectToScreen(_compositeBuf + x1 + y * _vm->_screenWidth, _vm->_screenWidth, x, y, width, height); } } @@ -878,16 +888,12 @@ void CharsetRenderer::restoreCharsetBg() { } } else { // Clear area - if (_vm->_features & GF_NES) - memset(screenBuf, 0x1d, vs->h * vs->pitch); - else - memset(screenBuf, 0, vs->h * vs->pitch); + memset(screenBuf, 0, vs->h * vs->pitch); } if (vs->hasTwoBuffers) { // Clean out the charset mask - memset(_vm->gdi._textSurface.pixels, (_vm->_features & GF_NES) ? 0x1d : - CHARSET_MASK_TRANSPARENCY, _vm->gdi._textSurface.pitch * _vm->gdi._textSurface.h); + memset(_vm->gdi._textSurface.pixels, CHARSET_MASK_TRANSPARENCY, _vm->gdi._textSurface.pitch * _vm->gdi._textSurface.h); } } } @@ -1371,6 +1377,9 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int wi sx = 0; } + //if (_vm->_NESStartStrip > 0) + // stripnr -= _vm->_NESStartStrip; + // FIXME Still not been calculated correctly while (numstrip > 0 && sx < _numStrips && x * 8 < MAX(_vm->_roomWidth, (int) vs->w)) { CHECK_HEAP; @@ -1833,7 +1842,7 @@ void Gdi::decompressMaskImgOr(byte *dst, const byte *src, int height) const { void decodeNESTileData(const byte *src, byte *dest) { int len = READ_LE_UINT16(src); src += 2; const byte *end = src + len; - /* int numtiles = */ *src++; + src++; // skip number-of-tiles byte, assume it is correct while (src < end) { byte data = *src++; for (int j = 0; j < (data & 0x7F); j++) @@ -1846,7 +1855,33 @@ void decodeNESTileData(const byte *src, byte *dest) { void ScummEngine::decodeNESBaseTiles() { byte *basetiles = getResourceAddress(rtCostume, 37); _NESBaseTiles = basetiles[2]; - decodeNESTileData(basetiles, _NESPatTable); + decodeNESTileData(basetiles, _NESPatTable[1]); +} + +static const int v1MMNEScostTables[2][6] = { + /* desc lens offs data gfx pal */ + { 25, 27, 29, 31, 33, 35}, + { 26, 28, 30, 32, 34, 36} +}; +void ScummEngine::NES_loadCostumeSet(int n) { + int i; + _NESCostumeSet = n; + + _NEScostdesc = getResourceAddress(rtCostume, v1MMNEScostTables[n][0]) + 2; + _NEScostlens = getResourceAddress(rtCostume, v1MMNEScostTables[n][1]) + 2; + _NEScostoffs = getResourceAddress(rtCostume, v1MMNEScostTables[n][2]) + 2; + _NEScostdata = getResourceAddress(rtCostume, v1MMNEScostTables[n][3]) + 2; + decodeNESTileData(getResourceAddress(rtCostume, v1MMNEScostTables[n][4]), _NESPatTable[0]); + byte *palette = getResourceAddress(rtCostume, v1MMNEScostTables[n][5]) + 2; + for (i = 0; i < 16; i++) { + byte c = *palette++; + //if (c == 0x1D) // HACK - switch around colors 0x00 and 0x1D + // c = 0; // so we don't need a zillion extra checks + //else if (c == 0)// for determining the proper background color + // c = 0x1D; + _NESPalette[1][i] = c; + } + } void Gdi::decodeNESGfx(const byte *room) { @@ -1856,9 +1891,26 @@ void Gdi::decodeNESGfx(const byte *room) { // int height = READ_LE_UINT16(room + 0x06); int i, j, n; - decodeNESTileData(_vm->getResourceAddress(rtCostume, 37 + tileset), _vm->_NESPatTable + _vm->_NESBaseTiles * 16); - for (i = 0; i < 16; i++) - _vm->_NESPalette[i] = *gdata++; + // We have narrow room. so expand it + if (width < 32) { + _vm->_NESStartStrip = (32 - width) >> 1; + } else { + _vm->_NESStartStrip = 0; + } + + decodeNESTileData(_vm->getResourceAddress(rtCostume, 37 + tileset), _vm->_NESPatTable[1] + _vm->_NESBaseTiles * 16); + for (i = 0; i < 16; i++) { + byte c = *gdata++; + if (c == 0x0D) + c = 0x1D; + + if (c == 0x1D) // HACK - switch around colors 0x00 and 0x1D + c = 0; // so we don't need a zillion extra checks + else if (c == 0) // for determining the proper background color + c = 0x1D; + + _vm->_NESPalette[0][i] = c; + } for (i = 0; i < 16; i++) { _NESNametable[i][0] = _NESNametable[i][1] = 0; n = 0; @@ -2001,10 +2053,10 @@ void Gdi::drawStripNES(byte *dst, int dstPitch, int stripnr, int top, int height int tile = (isObject ? _NESNametableObj : _NESNametable)[y][x]; for (int i = 0; i < 8; i++) { - byte c0 = _vm->_NESPatTable[tile * 16 + i]; - byte c1 = _vm->_NESPatTable[tile * 16 + i + 8]; + byte c0 = _vm->_NESPatTable[1][tile * 16 + i]; + byte c1 = _vm->_NESPatTable[1][tile * 16 + i + 8]; for (int j = 0; j < 8; j++) - dst[j] = _vm->_NESPalette[((c0 >> (7 - j)) & 1) | (((c1 >> (7 - j)) & 1) << 1) | (palette << 2)]; + dst[j] = _vm->_NESPalette[0][((c0 >> (7 - j)) & 1) | (((c1 >> (7 - j)) & 1) << 1) | (palette << 2)]; dst += dstPitch; } } diff --git a/scumm/palette.cpp b/scumm/palette.cpp index 86e629f8c4..7f8290d5da 100644 --- a/scumm/palette.cpp +++ b/scumm/palette.cpp @@ -30,7 +30,7 @@ namespace Scumm { void ScummEngine::setupNESPalette() { - setPalColor(0x00,0x6D,0x6D,0x6D); + setPalColor(0x00,0x24,0x24,0x24); // 0x1D setPalColor(0x01,0x00,0x24,0x92); setPalColor(0x02,0x00,0x00,0xDB); setPalColor(0x03,0x6D,0x49,0xDB); @@ -60,7 +60,7 @@ void ScummEngine::setupNESPalette() { setPalColor(0x1A,0x00,0x92,0x00); setPalColor(0x1B,0x00,0xB6,0x6D); setPalColor(0x1C,0x00,0x92,0x92); - setPalColor(0x1D,0x24,0x24,0x24); + setPalColor(0x1D,0x6D,0x6D,0x6D); // 0x00 setPalColor(0x1E,0x00,0x00,0x00); setPalColor(0x1F,0x00,0x00,0x00); diff --git a/scumm/script_v2.cpp b/scumm/script_v2.cpp index c3397982e7..2cc833265c 100644 --- a/scumm/script_v2.cpp +++ b/scumm/script_v2.cpp @@ -1060,10 +1060,7 @@ void ScummEngine_v2::o2_drawSentence() { sentenceline.bottom = virtscr[2].topline + 8; sentenceline.left = 0; sentenceline.right = 319; - if (_features & GF_NES) - restoreBG(sentenceline, 0x1d); - else - restoreBG(sentenceline); + restoreBG(sentenceline); drawString(2, (byte*)sentence); } @@ -1525,10 +1522,7 @@ void ScummEngine_v2::setUserState(byte state) { rect.bottom = virtscr[2].topline + 8 * 88; rect.left = 0; rect.right = 319; - if (_features & GF_NES) - restoreBG(rect, 0x1d); - else - restoreBG(rect); + restoreBG(rect); // Draw all verbs and inventory redrawVerbs(); @@ -1552,7 +1546,7 @@ void ScummEngine_v2::o2_switchCostumeSet() { // NES version of maniac uses this to switch between the two // groups of costumes it has if (_features & GF_NES) - _NESCostumeSet = fetchScriptByte(); + NES_loadCostumeSet(fetchScriptByte()); else o2_dummy(); } diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp index bcfece4d3c..510903292a 100644 --- a/scumm/scumm.cpp +++ b/scumm/scumm.cpp @@ -857,6 +857,7 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS _costumeRenderer = NULL; _2byteFontPtr = 0; _V1TalkingActor = 0; + _NESStartStrip = 0; _actorClipOverride.top = 0; _actorClipOverride.bottom = 480; @@ -1109,7 +1110,7 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS _screenWidth = 640; _screenHeight = 480; } else if (_features & GF_NES) { - _screenWidth = 224; + _screenWidth = 256; // 224 _screenHeight = 240; } else if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) { _features |= GF_DEFAULT_TO_1X_SCALER; @@ -1514,10 +1515,8 @@ void ScummEngine::scummInit() { clearDrawObjectQueue(); - if (_features & GF_NES) { + if (_features & GF_NES) decodeNESBaseTiles(); - cost_decodeNESCostumeGfx(); - } for (i = 0; i < 6; i++) { if (_version == 3) { // FIXME - what is this? @@ -1787,6 +1786,13 @@ int ScummEngine::scummLoop(int delta) { if (_version <= 2) { VAR(VAR_VIRT_MOUSE_X) = _virtualMouse.x / 8; VAR(VAR_VIRT_MOUSE_Y) = _virtualMouse.y / 2; + + // Adjust mouse coordinates as narrow rooms in NES are centered + if (_features & GF_NES && _virtualMouse.y >= 16 && _virtualMouse.y < 144) { + VAR(VAR_VIRT_MOUSE_X) -= _NESStartStrip; + if (VAR(VAR_VIRT_MOUSE_X) < 0) + VAR(VAR_VIRT_MOUSE_X) = 0; + } } else { VAR(VAR_VIRT_MOUSE_X) = _virtualMouse.x; VAR(VAR_VIRT_MOUSE_Y) = _virtualMouse.y; @@ -2266,6 +2272,12 @@ void ScummEngine::initRoomSubBlocks() { if (_version == 1) { if (_features & GF_NES) { _roomWidth = READ_LE_UINT16(roomptr + 4) * 8; + + // HACK: To let our code work normal with narrow rooms we + // adjust width. It will render garbage on right edge but we do + // not render it anyway + if (_roomWidth < 32 * 8) + _roomWidth = 32 * 8; _roomHeight = READ_LE_UINT16(roomptr + 6) * 8; } else { _roomWidth = roomptr[4] * 8; diff --git a/scumm/scumm.h b/scumm/scumm.h index f6e66548c9..5163ee63fd 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -473,12 +473,14 @@ public: BaseCostumeRenderer* _costumeRenderer; int _NESCostumeSet; - byte *_NESCostumeGfx[2]; - - byte _NESPatTable[4096]; - byte _NESPalette[16]; + void NES_loadCostumeSet(int n); + byte *_NEScostdesc, *_NEScostlens, *_NEScostoffs, *_NEScostdata; + byte _NESPatTable[2][4096]; + byte _NESPalette[2][16]; byte _NESBaseTiles; + int _NESStartStrip; + char *_audioNames; int32 _numAudioNames; @@ -928,7 +930,7 @@ protected: void drawRoomObject(int i, int arg); void drawBox(int x, int y, int x2, int y2, int color); - void restoreBG(Common::Rect rect, byte backColor = 0); + void restoreBG(Common::Rect rect, byte backcolor = 0); void redrawBGStrip(int start, int num); virtual void redrawBGAreas(); |