aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Sandulenko2005-03-24 03:22:32 +0000
committerEugene Sandulenko2005-03-24 03:22:32 +0000
commit9ab0962f6de96fb28dd7ee6b1589fb1b343dda7a (patch)
tree4468cc52c76f506216933126c28fbf47176f6a84
parentb0a1228c439a1fbca682af4f4f87a9cb44cdbc69 (diff)
downloadscummvm-rg350-9ab0962f6de96fb28dd7ee6b1589fb1b343dda7a.tar.gz
scummvm-rg350-9ab0962f6de96fb28dd7ee6b1589fb1b343dda7a.tar.bz2
scummvm-rg350-9ab0962f6de96fb28dd7ee6b1589fb1b343dda7a.zip
Lots of MM NES changes from Quietust and me
o Swap palette entries 0x00 and 0x1D in all necessary places. This gets rid of gray background o added a function NES_loadCostumeSet(int n) in order to do #1 for sprites o Widen screen to 256 pixels and center narrow rooms in it o Partial fix for subtitle rendering, now at least first line is rendered with identation svn-id: r17212
-rw-r--r--scumm/charset.cpp7
-rw-r--r--scumm/costume.cpp48
-rw-r--r--scumm/cursor.cpp4
-rw-r--r--scumm/gfx.cpp86
-rw-r--r--scumm/palette.cpp4
-rw-r--r--scumm/script_v2.cpp12
-rw-r--r--scumm/scumm.cpp20
-rw-r--r--scumm/scumm.h12
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();