diff options
-rw-r--r-- | engines/scumm/gfx.cpp | 119 | ||||
-rw-r--r-- | engines/scumm/gfx.h | 61 | ||||
-rw-r--r-- | engines/scumm/scumm.cpp | 6 |
3 files changed, 113 insertions, 73 deletions
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp index 7dfd91bd59..05d0476467 100644 --- a/engines/scumm/gfx.cpp +++ b/engines/scumm/gfx.cpp @@ -194,9 +194,7 @@ static const TransitionEffect transitionEffects[6] = { #endif -Gdi::Gdi(ScummEngine *vm) { - _vm = vm; - +Gdi::Gdi(ScummEngine *vm) : _vm(vm) { _numZBuffer = 0; memset(_imgBufOffs, 0, sizeof(_imgBufOffs)); _numStrips = 0; @@ -210,10 +208,13 @@ Gdi::Gdi(ScummEngine *vm) { _zbufferDisabled = false; _objectMode = false; memset(&_C64, 0, sizeof(_C64)); - memset(&_NES, 0, sizeof(_NES)); _roomStrips = 0; } +GdiNES::GdiNES(ScummEngine *vm) : Gdi(vm) { + memset(&_NES, 0, sizeof(_NES)); +} + Gdi::~Gdi() { free(_roomStrips); } @@ -240,19 +241,15 @@ void Gdi::init() { void Gdi::roomChanged(byte *roomptr, uint32 IM00_offs, byte transparentColor) { if (_vm->_game.version <= 1) { - if (_vm->_game.platform == Common::kPlatformNES) { - decodeNESGfx(roomptr); - } else { - for (int i = 0; i < 4; i++){ - _C64.colors[i] = roomptr[6 + i]; - } - decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 10), _C64.charMap, 2048); - decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 12), _C64.picMap, roomptr[4] * roomptr[5]); - decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 14), _C64.colorMap, roomptr[4] * roomptr[5]); - decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 16), _C64.maskMap, roomptr[4] * roomptr[5]); - decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 18) + 2, _C64.maskChar, READ_LE_UINT16(roomptr + READ_LE_UINT16(roomptr + 18))); - _objectMode = true; - } + for (int i = 0; i < 4; i++){ + _C64.colors[i] = roomptr[6 + i]; + } + decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 10), _C64.charMap, 2048); + decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 12), _C64.picMap, roomptr[4] * roomptr[5]); + decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 14), _C64.colorMap, roomptr[4] * roomptr[5]); + decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 16), _C64.maskMap, roomptr[4] * roomptr[5]); + decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 18) + 2, _C64.maskChar, READ_LE_UINT16(roomptr + READ_LE_UINT16(roomptr + 18))); + _objectMode = true; } else if (_vm->_game.version == 2) { _roomStrips = generateStripTable(roomptr + IM00_offs, _vm->_roomWidth, _vm->_roomHeight, _roomStrips); } @@ -260,6 +257,10 @@ void Gdi::roomChanged(byte *roomptr, uint32 IM00_offs, byte transparentColor) { _transparentColor = transparentColor; } +void GdiNES::roomChanged(byte *roomptr, uint32 IM00_offs, byte transparentColor) { + decodeNESGfx(roomptr); + _transparentColor = transparentColor; +} #pragma mark - #pragma mark --- Virtual Screens --- @@ -1435,6 +1436,19 @@ int Gdi::getZPlanes(const byte *ptr, const byte *zplane_list[9], bool bmapImage) return numzbuf; } +void Gdi::prepareDrawBitmap(const byte *ptr, int x, int y, const int width, const int height) { + if (_objectMode && _vm->_game.version <= 1) { + decodeC64Gfx(ptr, _C64.objectMap, (width / 8) * (height / 8) * 3); + } +} + +void GdiNES::prepareDrawBitmap(const byte *ptr, int x, int y, const int width, const int height) { + if (_objectMode) { + decodeNESObject(ptr, x, y, width, height); + } +} + + /** * Draw a bitmap onto a virtual screen. This is main drawing method for room backgrounds * and objects, used throughout all SCUMM versions. @@ -1457,14 +1471,8 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int wi const bool lightsOn = _vm->isLightOn(); _objectMode = (flag & dbObjectMode) == dbObjectMode; - - if (_objectMode && _vm->_game.version <= 1) { - if (_vm->_game.platform == Common::kPlatformNES) { - decodeNESObject(ptr, x, y, width, height); - } else { - decodeC64Gfx(ptr, _C64.objectMap, (width / 8) * (height / 8) * 3); - } - } + + prepareDrawBitmap(ptr, x, y, width, height); CHECK_HEAP; if (_vm->_game.features & GF_SMALL_HEADER) { @@ -1540,6 +1548,10 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int wi transpStrip = drawStrip(dstPtr, vs, x, y, width, height, stripnr, smap_ptr); + // COMI and HE games only uses flag value + if (_vm->_game.version == 8 || _vm->_game.heversion >= 60) + transpStrip = true; + CHECK_HEAP; if (vs->hasTwoBuffers) { byte *frontBuf = (byte *)vs->pixels + y * vs->pitch + x * 8; @@ -1550,21 +1562,17 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int wi } CHECK_HEAP; - // COMI and HE games only uses flag value - if (_vm->_game.version == 8 || _vm->_game.heversion >= 60) - transpStrip = true; - decodeMask(x, y, width, height, stripnr, numzbuf, zplane_list, transpStrip, flag, tmsk_ptr); -#if 0 +#if 1 // HACK: blit mask(s) onto normal screen. Useful to debug masking - for (i = 0; i < numzbuf; i++) { + for (int i = 0; i < numzbuf; i++) { byte *dst1, *dst2; - dst1 = dst2 = (byte *)vs->pixels + y * vs->pitch + x) * 8; + dst1 = dst2 = (byte *)vs->pixels + y * vs->pitch + x * 8; if (vs->hasTwoBuffers) dst2 = vs->backBuf + y * vs->pitch + x * 8; - mask_ptr = getMaskBuffer(x, y, i); + byte *mask_ptr = getMaskBuffer(x, y, i); for (int h = 0; h < height; h++) { int maskbits = *mask_ptr; @@ -1584,15 +1592,10 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int wi bool Gdi::drawStrip(byte *dstPtr, VirtScreen *vs, int x, int y, const int width, const int height, int stripnr, const byte *smap_ptr) { - byte *mask_ptr; bool transpStrip = false; if (_vm->_game.version <= 1) { - if (_vm->_game.platform == Common::kPlatformNES) { - mask_ptr = getMaskBuffer(x, y, 1); - drawStripNES(dstPtr, mask_ptr, vs->pitch, stripnr, y, height); - } - else if (_objectMode) + if (_objectMode) drawStripC64Object(dstPtr, vs->pitch, stripnr, width, height); else drawStripC64Background(dstPtr, vs->pitch, stripnr, height); @@ -1633,11 +1636,7 @@ void Gdi::decodeMask(int x, int y, const int width, const int height, if (_vm->_game.version <= 1) { mask_ptr = getMaskBuffer(x, y, 1); - if (_vm->_game.platform == Common::kPlatformNES) { - drawStripNESMask(mask_ptr, stripnr, y, height); - } else { - drawStripC64Mask(mask_ptr, stripnr, width, height); - } + drawStripC64Mask(mask_ptr, stripnr, width, height); } else if (_vm->_game.version == 2) { // Do nothing here for V2 games - zplane was already handled. } else if (flag & dbDrawMaskOnAll) { @@ -1709,6 +1708,21 @@ void Gdi::decodeMask(int x, int y, const int width, const int height, } } +bool GdiNES::drawStrip(byte *dstPtr, VirtScreen *vs, int x, int y, const int width, const int height, + int stripnr, const byte *smap_ptr) { + byte *mask_ptr = getMaskBuffer(x, y, 1); + drawStripNES(dstPtr, mask_ptr, vs->pitch, stripnr, y, height); + + return false; +} + +void GdiNES::decodeMask(int x, int y, const int width, const int height, + int stripnr, int numzbuf, const byte *zplane_list[9], + bool transpStrip, byte flag, const byte *tmsk_ptr) { + byte *mask_ptr = getMaskBuffer(x, y, 1); + drawStripNESMask(mask_ptr, stripnr, y, height); +} + #ifndef DISABLE_HE /** * Draw a bitmap onto a virtual screen. This is main drawing method for room backgrounds @@ -2146,7 +2160,7 @@ void Gdi::decompressMaskImgOr(byte *dst, const byte *src, int height) const { } } -void decodeNESTileData(const byte *src, byte *dest) { +static void decodeNESTileData(const byte *src, byte *dest) { int len = READ_LE_UINT16(src); src += 2; const byte *end = src + len; src++; // skip number-of-tiles byte, assume it is correct @@ -2170,6 +2184,7 @@ static const int v1MMNEScostTables[2][6] = { { 25, 27, 29, 31, 33, 35}, { 26, 28, 30, 32, 34, 36} }; + void ScummEngine::NES_loadCostumeSet(int n) { int i; _NESCostumeSet = n; @@ -2191,7 +2206,7 @@ void ScummEngine::NES_loadCostumeSet(int n) { } -void Gdi::decodeNESGfx(const byte *room) { +void GdiNES::decodeNESGfx(const byte *room) { const byte *gdata = room + READ_LE_UINT16(room + 0x0A); int tileset = *gdata++; int width = READ_LE_UINT16(room + 0x04); @@ -2267,7 +2282,7 @@ void Gdi::decodeNESGfx(const byte *room) { memcpy(_NES.masktableObj, _NES.masktable, 16*8); } -void Gdi::decodeNESObject(const byte *ptr, int xpos, int ypos, int width, int height) { +void GdiNES::decodeNESObject(const byte *ptr, int xpos, int ypos, int width, int height) { int x, y; _NES.objX = xpos; @@ -2331,8 +2346,7 @@ void Gdi::decodeNESObject(const byte *ptr, int xpos, int ypos, int width, int he lmask = *ptr++; rmask = *ptr++; - y = 0; - do { + for (y = 0; y < height; ++y) { byte *dest = &_NES.masktableObj[y + ypos][mx]; *dest = (*dest & lmask) | *ptr++; dest++; @@ -2343,11 +2357,10 @@ void Gdi::decodeNESObject(const byte *ptr, int xpos, int ypos, int width, int he *dest = *ptr++; dest++; } - y++; - } while (y < height); + } } -void Gdi::drawStripNES(byte *dst, byte *mask, int dstPitch, int stripnr, int top, int height) { +void GdiNES::drawStripNES(byte *dst, byte *mask, int dstPitch, int stripnr, int top, int height) { top /= 8; height /= 8; int x = stripnr + 2; // NES version has a 2 tile gap on each edge @@ -2374,7 +2387,7 @@ void Gdi::drawStripNES(byte *dst, byte *mask, int dstPitch, int stripnr, int top } } -void Gdi::drawStripNESMask(byte *dst, int stripnr, int top, int height) const { +void GdiNES::drawStripNESMask(byte *dst, int stripnr, int top, int height) const { top /= 8; height /= 8; int x = stripnr; // masks, unlike room graphics, should NOT be adjusted diff --git a/engines/scumm/gfx.h b/engines/scumm/gfx.h index 8663acf99a..415e40c6bc 100644 --- a/engines/scumm/gfx.h +++ b/engines/scumm/gfx.h @@ -190,6 +190,7 @@ struct StripTable; #define CHARSET_MASK_TRANSPARENCY 253 class Gdi { +protected: ScummEngine *_vm; public: @@ -197,9 +198,6 @@ public: int _imgBufOffs[8]; int32 _numStrips; - Gdi(ScummEngine *vm); - virtual ~Gdi(); - protected: byte _paletteMod; byte *_roomPalette; @@ -219,14 +217,6 @@ protected: byte maskMap[4096], maskChar[4096]; } _C64; - struct { - byte nametable[16][64], nametableObj[16][64]; - byte attributes[64], attributesObj[64]; - byte masktable[16][8], masktableObj[16][8]; - int objX; - bool hasmask; - } _NES; - /** For V2 games, we cache offsets into the room graphics, to speed up things. */ StripTable *_roomStrips; @@ -236,7 +226,6 @@ protected: void drawStripEGA(byte *dst, int dstPitch, const byte *src, int height) const; void drawStripC64Object(byte *dst, int dstPitch, int stripnr, int width, int height); void drawStripC64Background(byte *dst, int dstPitch, int stripnr, int height); - void drawStripNES(byte *dst, byte *mask, int dstPitch, int stripnr, int top, int height); void drawStripComplex(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const; void drawStripBasicH(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const; @@ -253,7 +242,6 @@ protected: /* Mask decompressors */ void drawStripC64Mask(byte *dst, int stripnr, int width, int height) const; - void drawStripNESMask(byte *dst, int stripnr, int top, int height) const; void decompressTMSK(byte *dst, const byte *tmsk, const byte *src, int height) const; void decompressMaskImgOr(byte *dst, const byte *src, int height) const; void decompressMaskImg(byte *dst, const byte *src, int height) const; @@ -275,17 +263,18 @@ protected: int stripnr, int numzbuf, const byte *zplane_list[9], bool transpStrip, byte flag, const byte *tmsk_ptr); + virtual void prepareDrawBitmap(const byte *ptr, int x, int y, const int width, const int height); + public: - void init(); - void roomChanged(byte *roomptr, uint32 IM00_offs, byte transparentColor); + Gdi(ScummEngine *vm); + virtual ~Gdi(); + + virtual void init(); + virtual void roomChanged(byte *roomptr, uint32 IM00_offs, byte transparentColor); void drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int width, const int height, int stripnr, int numstrip, byte flag); - void decodeNESGfx(const byte *room); - void decodeNESObject(const byte *ptr, int xpos, int ypos, int width, int height); - - #ifndef DISABLE_HE void drawBMAPBg(const byte *ptr, VirtScreen *vs); void drawBMAPObject(const byte *ptr, VirtScreen *vs, int obj, int x, int y, int w, int h); @@ -304,6 +293,40 @@ public: }; }; +class GdiNES : public Gdi { +protected: + //ScummEngine *_vm; + + struct { + byte nametable[16][64], nametableObj[16][64]; + byte attributes[64], attributesObj[64]; + byte masktable[16][8], masktableObj[16][8]; + int objX; + bool hasmask; + } _NES; + + void decodeNESGfx(const byte *room); + void decodeNESObject(const byte *ptr, int xpos, int ypos, int width, int height); + + void drawStripNES(byte *dst, byte *mask, int dstPitch, int stripnr, int top, int height); + void drawStripNESMask(byte *dst, int stripnr, int top, int height) const; + + virtual bool drawStrip(byte *dstPtr, VirtScreen *vs, + int x, int y, const int width, const int height, + int stripnr, const byte *smap_ptr); + + virtual void decodeMask(int x, int y, const int width, const int height, + int stripnr, int numzbuf, const byte *zplane_list[9], + bool transpStrip, byte flag, const byte *tmsk_ptr); + + virtual void prepareDrawBitmap(const byte *ptr, int x, int y, const int width, const int height); + +public: + GdiNES(ScummEngine *vm); + + virtual void roomChanged(byte *roomptr, uint32 IM00_offs, byte transparentColor); +}; + } // End of namespace Scumm diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index ef258efbf4..c82bd30fcb 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -87,7 +87,11 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) _currentScript(0xFF), // Let debug() work on init stage _pauseDialog(0), _mainMenuDialog(0), _versionDialog(0) { - _gdi = new Gdi(this); + if (_game.platform == Common::kPlatformNES) { + _gdi = new GdiNES(this); + } else { + _gdi = new Gdi(this); + } _res = new ResourceManager(this); // Copy MD5 checksum |