aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Sandulenko2005-03-16 03:20:32 +0000
committerEugene Sandulenko2005-03-16 03:20:32 +0000
commitf86768fee8aabb448152092b95a0a0b08e59eb63 (patch)
tree0fc24b4274f3b1bca8033e174034d848a9d9452f
parentdd71f57aeb2d921e89d4409a2548bddc4280a2d3 (diff)
downloadscummvm-rg350-f86768fee8aabb448152092b95a0a0b08e59eb63.tar.gz
scummvm-rg350-f86768fee8aabb448152092b95a0a0b08e59eb63.tar.bz2
scummvm-rg350-f86768fee8aabb448152092b95a0a0b08e59eb63.zip
Preliminary support for NES charsets. Colors are wrong and we get glitches
caused by too narrow screen. Also text clearing doesn't work. svn-id: r17164
-rw-r--r--scumm/charset.cpp153
-rw-r--r--scumm/charset.h17
-rw-r--r--scumm/costume.cpp20
-rw-r--r--scumm/gfx.cpp23
-rw-r--r--scumm/gfx.h2
-rw-r--r--scumm/script_v2.cpp2
-rw-r--r--scumm/scumm.cpp8
-rw-r--r--scumm/scumm.h10
8 files changed, 207 insertions, 28 deletions
diff --git a/scumm/charset.cpp b/scumm/charset.cpp
index 52497aef14..8a3ae390f8 100644
--- a/scumm/charset.cpp
+++ b/scumm/charset.cpp
@@ -1669,6 +1669,159 @@ void CharsetRendererNut::printChar(int chr) {
_str.bottom = shadow.bottom;
}
+static byte trNESEnglishTable[] = {
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x0A, 0x07, 0x00,
+ 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
+ 0x13, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
+ 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23,
+ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B,
+ 0x2C, 0x2D, 0x2E, 0x00, 0x00, 0x00, 0x2F, 0x00,
+ 0x03, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
+ 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23,
+ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B,
+ 0x2C, 0x2D, 0x2E, 0x00, 0x00, 0x00, 0x05, 0x08,
+ 0x20, 0x20, 0x21, 0x60, 0x27, 0x7E, 0x2C, 0x2E,
+ 0x7F, 0x3F, 0x2D, 0x30, 0x31, 0x32, 0x33, 0x34,
+ 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43,
+ 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,
+ 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53,
+ 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5E
+};
+
+static byte trNESFrenchTable[] = {
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x64, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x0A, 0x07, 0x00,
+ 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
+ 0x13, 0x14, 0x00, 0x00, 0x15, 0x15, 0x64, 0x09,
+ 0x00, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
+ 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23,
+ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B,
+ 0x2C, 0x2D, 0x2E, 0x19, 0x19, 0x19, 0x2F, 0x29,
+ 0x03, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
+ 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23,
+ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B,
+ 0x2C, 0x2D, 0x2E, 0x1D, 0x23, 0x29, 0x05, 0x08,
+ 0x20, 0x20, 0x21, 0x60, 0x27, 0x7E, 0x2C, 0x2E,
+ 0x7F, 0x3F, 0x2D, 0x30, 0x31, 0x32, 0x33, 0x34,
+ 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43,
+ 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,
+ 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53,
+ 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5E
+};
+
+static byte trNESSwedishTable[] = {
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x0A, 0x07, 0x00,
+ 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
+ 0x13, 0x14, 0x00, 0x00, 0x61, 0x00, 0x64, 0x09,
+ 0x00, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
+ 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23,
+ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B,
+ 0x2C, 0x2D, 0x2E, 0x62, 0x63, 0x00, 0x2F, 0x00,
+ 0x03, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
+ 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23,
+ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B,
+ 0x2C, 0x2D, 0x2E, 0x63, 0x64, 0x61, 0x05, 0x08,
+ 0x20, 0x20, 0x21, 0x60, 0x27, 0x7E, 0x2C, 0x2E,
+ 0x7F, 0x3F, 0x2D, 0x30, 0x31, 0x32, 0x33, 0x34,
+ 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43,
+ 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,
+ 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53,
+ 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5E
+};
+
+
+CharsetRendererNES::CharsetRendererNES(ScummEngine *vm, Common::Language language)
+ : CharsetRendererCommon(vm) {
+ switch (language) {
+ case Common::FR_FRA:
+ _trTable = trNESFrenchTable;
+ break;
+ case Common::SE_SWE:
+ _trTable = trNESSwedishTable;
+ break;
+ default:
+ _trTable = trNESEnglishTable;
+ break;
+ }
+}
+
+void CharsetRendererNES::printChar(int chr) {
+ int width, height, origWidth, origHeight;
+ VirtScreen *vs;
+ byte *charPtr, *dst;
+
+ if ((vs = _vm->findVirtScreen(_top)) == NULL)
+ return;
+
+ if (chr == '@')
+ return;
+
+ charPtr = _vm->_NESPatTable + _trTable[chr - 32] * 16;
+ width = getCharWidth(chr);
+ height = 8;
+
+ origWidth = width;
+ origHeight = height;
+
+ if (_firstChar) {
+ _str.left = _left;
+ _str.top = _top;
+ _str.right = _left;
+ _str.bottom = _top;
+ _firstChar = false;
+ }
+
+ int drawTop = _top - vs->topline;
+
+ _vm->markRectAsDirty(vs->number, _left, _left + width, drawTop, drawTop + height);
+
+ if (!_ignoreCharsetMask) {
+ _hasMask = true;
+ _textScreenID = vs->number;
+ }
+ dst = (byte *)_vm->gdi._textSurface.pixels + _top * _vm->gdi._textSurface.pitch + _left;
+ drawBits1(_vm->gdi._textSurface, dst, charPtr, drawTop, origWidth, origHeight);
+
+ if (_str.left > _left)
+ _str.left = _left;
+
+ _left += origWidth;
+
+ if (_str.right < _left) {
+ _str.right = _left;
+ if (_dropShadow)
+ _str.right++;
+ }
+
+ if (_str.bottom < _top + height)
+ _str.bottom = _top + height;
+}
+
+void CharsetRendererNES::drawChar(int chr, const Graphics::Surface &s, int x, int y) {
+ byte *charPtr, *dst;
+ int width, height;
+
+ charPtr = _vm->_NESPatTable + _trTable[chr - 32] * 16;
+ width = getCharWidth(chr);
+ height = 8;
+
+ dst = (byte *)s.pixels + y * s.pitch + x;
+ drawBits1(s, dst, charPtr, y, width, height);
+}
+
+void CharsetRendererNES::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height) {
+ for (int i = 0; i < 8; i++) {
+ 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)] | _color;
+ dst += s.pitch;
+ }
+}
+
} // End of namespace Scumm
#ifdef __PALM_OS__
diff --git a/scumm/charset.h b/scumm/charset.h
index dbadc1a2c3..e1a023e0d1 100644
--- a/scumm/charset.h
+++ b/scumm/charset.h
@@ -130,6 +130,23 @@ public:
int getCharWidth(byte chr);
};
+class CharsetRendererNES : public CharsetRendererCommon {
+protected:
+ byte *_trTable;
+
+ void drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height);
+
+public:
+ CharsetRendererNES(ScummEngine *vm, Common::Language language);
+
+ void setCurID(byte id) {}
+ void printChar(int chr);
+ void drawChar(int chr, const Graphics::Surface &s, int x, int y);
+
+ int getFontHeight() { return 8; }
+ int getCharWidth(byte chr) { return 8; }
+};
+
class CharsetRendererV3 : public CharsetRendererCommon {
protected:
int _numChars;
diff --git a/scumm/costume.cpp b/scumm/costume.cpp
index d160c27be1..35c7b34e51 100644
--- a/scumm/costume.cpp
+++ b/scumm/costume.cpp
@@ -598,7 +598,7 @@ void LoadedCostume::loadNEScostume(void) {
offset = src[(frameset * 4 + framenum) * 2];
// Lookup & desc
- table = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][0]);
+ table = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_NESCostumeSet][0]);
offset = READ_LE_UINT16(table + v1MMNESLookup[_id] * 2 + 2);
if (v1MMNESLookup[_id] * 2 >= READ_LE_UINT16(table)) {
@@ -686,17 +686,17 @@ void CostumeRenderer::drawNESCostume(const Actor *a, int limb) {
bool flipped = (newDirToOldDir(a->getFacing()) == 1);
// Lookup & desc
- table = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][0]) + 2;
+ table = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_NESCostumeSet][0]) + 2;
offset = READ_LE_UINT16(table + v1MMNESLookup[_loaded._id] * 2);
// lens
- numSpritesTab = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][1]) + 2 + offset;
+ numSpritesTab = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_NESCostumeSet][1]) + 2 + offset;
// offs
- spritesOffsetTab = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][2]) + 2 + offset*2;
+ spritesOffsetTab = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_NESCostumeSet][2]) + 2 + offset*2;
// data
- spritesDefs = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][3]) + 2;
+ spritesDefs = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_NESCostumeSet][3]) + 2;
// data
- spritesPal = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_v1MMNESCostumeSet][5]) + 2;
+ spritesPal = _vm->getResourceAddress(rtCostume, v1MMNEScostTables[_vm->_NESCostumeSet][5]) + 2;
ptr = spritesDefs + READ_LE_UINT16(spritesOffsetTab + frame*2);
numSprites = numSpritesTab[frame] + 1;
@@ -717,8 +717,8 @@ void CostumeRenderer::drawNESCostume(const Actor *a, int limb) {
}
for (int ty = 0; ty < 8; ty++) {
- byte c1 = _vm->_v1MMNESCostumeGfx[_vm->_v1MMNESCostumeSet][tile * 16 + ty];
- byte c2 = _vm->_v1MMNESCostumeGfx[_vm->_v1MMNESCostumeSet][tile * 16 + ty + 8];
+ byte c1 = _vm->_NESCostumeGfx[_vm->_NESCostumeSet][tile * 16 + ty];
+ byte c2 = _vm->_NESCostumeGfx[_vm->_NESCostumeSet][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) {
@@ -816,8 +816,8 @@ void ScummEngine::cost_decodeNESCostumeGfx() {
int maxSprites = patTable[2];
if (maxSprites == 0)
maxSprites = 256;
- _v1MMNESCostumeGfx[n] = (byte *)calloc(maxSprites * 16, 1);
- decodeNESTileData(patTable,_v1MMNESCostumeGfx[n]);
+ _NESCostumeGfx[n] = (byte *)calloc(maxSprites * 16, 1);
+ decodeNESTileData(patTable,_NESCostumeGfx[n]);
// We will not need it anymore
nukeResource(rtCostume, v1MMNEScostTables[n][4]);
}
diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp
index 99d8fb0859..953927fa7d 100644
--- a/scumm/gfx.cpp
+++ b/scumm/gfx.cpp
@@ -184,8 +184,6 @@ Gdi::Gdi(ScummEngine *vm) {
_roomPalette = vm->_roomPalette;
if ((vm->_features & GF_AMIGA) && (vm->_version >= 4))
_roomPalette += 16;
- if (vm->_features & GF_NES)
- _NESBaseTiles = 0;
_compositeBuf = 0;
_textSurface.pixels = 0;
@@ -1830,21 +1828,22 @@ void decodeNESTileData(const byte *src, byte *dest) {
}
}
+void ScummEngine::decodeNESBaseTiles() {
+ byte *basetiles = getResourceAddress(rtCostume, 37);
+ _NESBaseTiles = basetiles[2];
+ decodeNESTileData(basetiles, _NESPatTable);
+}
+
void Gdi::decodeNESGfx(const byte *room) {
- if (_NESBaseTiles == 0) {
- byte *basetiles = _vm->getResourceAddress(rtCostume,37);
- _NESBaseTiles = basetiles[2];
- decodeNESTileData(basetiles,_NESPatTable);
- }
const byte *gdata = room + READ_LE_UINT16(room + 0x0A);
int tileset = *gdata++;
int width = READ_LE_UINT16(room + 0x04);
// int height = READ_LE_UINT16(room + 0x06);
int i, j, n;
- decodeNESTileData(_vm->getResourceAddress(rtCostume, 37 + tileset), _NESPatTable + _NESBaseTiles * 16);
+ decodeNESTileData(_vm->getResourceAddress(rtCostume, 37 + tileset), _vm->_NESPatTable + _vm->_NESBaseTiles * 16);
for (i = 0; i < 16; i++)
- _NESPalette[i] = *gdata++;
+ _vm->_NESPalette[i] = *gdata++;
for (i = 0; i < 16; i++) {
_NESNametable[i][0] = _NESNametable[i][1] = 0;
n = 0;
@@ -1908,10 +1907,10 @@ void Gdi::drawStripNES(byte *dst, int dstPitch, int stripnr, int top, int height
int tile = isObject ? _NESNametableObj[y][x] : _NESNametable[y][x];
for (int i = 0; i < 8; i++) {
- byte c0 = _NESPatTable[tile * 16 + i];
- byte c1 = _NESPatTable[tile * 16 + i + 8];
+ byte c0 = _vm->_NESPatTable[tile * 16 + i];
+ byte c1 = _vm->_NESPatTable[tile * 16 + i + 8];
for (int j = 0; j < 8; j++)
- dst[j] = _NESPalette[((c0 >> (7 - j)) & 1) | (((c1 >> (7 - j)) & 1) << 1) | (palette << 2)];
+ dst[j] = _vm->_NESPalette[((c0 >> (7 - j)) & 1) | (((c1 >> (7 - j)) & 1) << 1) | (palette << 2)];
dst += dstPitch;
}
}
diff --git a/scumm/gfx.h b/scumm/gfx.h
index d32682e5bb..5d61c1da40 100644
--- a/scumm/gfx.h
+++ b/scumm/gfx.h
@@ -229,7 +229,7 @@ protected:
byte _C64MaskMap[4096], _C64MaskChar[4096];
bool _C64ObjectMode;
- byte _NESPatTable[4096], _NESNametable[16][64], _NESAttributes[64], _NESPalette[16];
+ byte _NESNametable[16][64], _NESAttributes[64];
byte _NESBaseTiles;
byte _NESNametableObj[16][64];
int _NESObj_x;
diff --git a/scumm/script_v2.cpp b/scumm/script_v2.cpp
index a509a01f91..1f121d44d7 100644
--- a/scumm/script_v2.cpp
+++ b/scumm/script_v2.cpp
@@ -1538,7 +1538,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)
- _v1MMNESCostumeSet = fetchScriptByte();
+ _NESCostumeSet = fetchScriptByte();
else
o2_dummy();
}
diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp
index a2badf8d68..56da24d0f4 100644
--- a/scumm/scumm.cpp
+++ b/scumm/scumm.cpp
@@ -1232,7 +1232,9 @@ int ScummEngine::init(GameDetector &detector) {
loadCJKFont();
// Create the charset renderer
- if (_version <= 2)
+ if (_features & GF_NES)
+ _charset = new CharsetRendererNES(this, _language);
+ else if (_version <= 2)
_charset = new CharsetRendererV2(this, _language);
else if (_version == 3)
_charset = new CharsetRendererV3(this);
@@ -1500,8 +1502,10 @@ 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?
diff --git a/scumm/scumm.h b/scumm/scumm.h
index 4c7fbb6b32..49daf51cc7 100644
--- a/scumm/scumm.h
+++ b/scumm/scumm.h
@@ -471,8 +471,12 @@ public:
BaseCostumeRenderer* _costumeRenderer;
- int _v1MMNESCostumeSet;
- byte *_v1MMNESCostumeGfx[2];
+ int _NESCostumeSet;
+ byte *_NESCostumeGfx[2];
+
+ byte _NESPatTable[4096];
+ byte _NESPalette[16];
+ byte _NESBaseTiles;
char *_audioNames;
int32 _numAudioNames;
@@ -916,6 +920,8 @@ protected:
void initBGBuffers(int height);
void initCycl(const byte *ptr); // Color cycle
+ void decodeNESBaseTiles();
+
void drawObject(int obj, int arg);
void drawRoomObjects(int arg);
void drawRoomObject(int i, int arg);