diff options
-rw-r--r-- | scumm/charset.cpp | 13 | ||||
-rw-r--r-- | scumm/charset.h | 2 | ||||
-rw-r--r-- | scumm/gfx.cpp | 107 | ||||
-rw-r--r-- | scumm/gfx.h | 11 | ||||
-rw-r--r-- | scumm/saveload.cpp | 18 | ||||
-rw-r--r-- | scumm/scumm.cpp | 29 | ||||
-rw-r--r-- | scumm/scumm.h | 2 |
7 files changed, 91 insertions, 91 deletions
diff --git a/scumm/charset.cpp b/scumm/charset.cpp index 458de41a13..9f1ddbc3c0 100644 --- a/scumm/charset.cpp +++ b/scumm/charset.cpp @@ -202,10 +202,21 @@ CharsetRenderer::CharsetRenderer(ScummEngine *vm) { _blitAlso = false; _firstChar = false; _disableOffsX = false; - _textSurface.pixels = 0; _vm = vm; _curId = 0; + + const int size = _vm->_screenWidth * _vm->_screenHeight; + _textSurface.pixels = malloc(size); + memset(_textSurface.pixels, CHARSET_MASK_TRANSPARENCY, size); + _textSurface.w = _vm->_screenWidth; + _textSurface.h = _vm->_screenHeight; + _textSurface.pitch = _vm->_screenWidth; + _textSurface.bytesPerPixel = 1; +} + +CharsetRenderer::~CharsetRenderer() { + free(_textSurface.pixels); } void CharsetRendererCommon::setCurID(byte id) { diff --git a/scumm/charset.h b/scumm/charset.h index c41f1051e6..a9be1dd231 100644 --- a/scumm/charset.h +++ b/scumm/charset.h @@ -88,7 +88,7 @@ protected: public: CharsetRenderer(ScummEngine *vm); - virtual ~CharsetRenderer() {} + virtual ~CharsetRenderer(); void restoreCharsetBg(); void clearCharsetMask(); diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp index 6ad0d3a753..4c4bfe9989 100644 --- a/scumm/gfx.cpp +++ b/scumm/gfx.cpp @@ -189,21 +189,66 @@ static const TransitionEffect transitionEffects[6] = { }; #endif -#pragma mark - -#pragma mark --- Virtual Screens --- -#pragma mark - - - -#define CHARSET_MASK_TRANSPARENCY 253 Gdi::Gdi(ScummEngine *vm) { memset(this, 0, sizeof(*this)); _vm = vm; _roomPalette = vm->_roomPalette; + _roomStrips = 0; if ((vm->_features & GF_AMIGA) && (vm->_version >= 4)) _roomPalette += 16; } +Gdi::~Gdi() { + free(_roomStrips); +} + +void Gdi::init() { + _numStrips = _vm->_screenWidth / 8; + + // Increase the number of screen strips by one; needed for smooth scrolling + if (_vm->_version >= 7) { + // We now have mostly working smooth scrolling code in place for V7+ games + // (i.e. The Dig, Full Throttle and COMI). It seems to work very well so far. + // One area which still may need some work are the AKOS codecs (except for + // codec 1, which I already updated): their masking code may need adjustments, + // similar to the treatment codec 1 received. + // + // To understand how we achieve smooth scrolling, first note that with it, the + // virtual screen strips don't match the display screen strips anymore. To + // overcome that problem, we simply use a screen pitch that is 8 pixel wider + // than the actual screen width, and always draw one strip more than needed to + // the backbuf (of course we have to treat the right border seperately). This + _numStrips += 1; + } +} + +void Gdi::roomChanged(byte *roomptr, uint32 IM00_offs) { + if (_vm->_version == 1) { + if (_vm->_features & GF_NES) { + 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; + } + } else if (_vm->_version == 2) { + _roomStrips = generateStripTable(roomptr + IM00_offs, _vm->_roomWidth, _vm->_roomHeight, _roomStrips); + } +} + + +#pragma mark - +#pragma mark --- Virtual Screens --- +#pragma mark - + + void ScummEngine::initScreens(int b, int h) { int i; int adj = 0; @@ -239,46 +284,6 @@ void ScummEngine::initScreens(int b, int h) { _screenH = h; gdi.init(); - - const int size = _screenWidth * _screenHeight; - free(_compositeBuf); - free(_charset->_textSurface.pixels); - free(_herculesBuf); - _compositeBuf = (byte *)malloc(size); - _charset->_textSurface.pixels = malloc(size); - memset(_compositeBuf, CHARSET_MASK_TRANSPARENCY, size); - memset(_charset->_textSurface.pixels, CHARSET_MASK_TRANSPARENCY, size); - - if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) { - _herculesBuf = (byte *)malloc(Common::kHercW * Common::kHercH); - memset(_herculesBuf, CHARSET_MASK_TRANSPARENCY, Common::kHercW * Common::kHercH); - } - - _charset->_textSurface.w = _screenWidth; - _charset->_textSurface.h = _screenHeight; - _charset->_textSurface.pitch = _screenWidth; - _charset->_textSurface.bytesPerPixel = 1; - -} - -void Gdi::init() { - _numStrips = _vm->_screenWidth / 8; - - // Increase the number of screen strips by one; needed for smooth scrolling - if (_vm->_version >= 7) { - // We now have mostly working smooth scrolling code in place for V7+ games - // (i.e. The Dig, Full Throttle and COMI). It seems to work very well so far. - // One area which still may need some work are the AKOS codecs (except for - // codec 1, which I already updated): their masking code may need adjustments, - // similar to the treatment codec 1 received. - // - // To understand how we achieve smooth scrolling, first note that with it, the - // virtual screen strips don't match the display screen strips anymore. To - // overcome that problem, we simply use a screen pitch that is 8 pixel wider - // than the actual screen width, and always draw one strip more than needed to - // the backbuf (of course we have to treat the right border seperately). This - _numStrips += 1; - } } void ScummEngine::initVirtScreen(VirtScreenNumber slot, int number, int top, int width, int height, bool twobufs, @@ -812,7 +817,7 @@ void ScummEngine::redrawBGStrip(int start, int num) { gdi._objectMode = false; gdi.drawBitmap(room + _IM00_offs, - &virtscr[0], s, 0, _roomWidth, virtscr[0].h, s, num, 0, _roomStrips); + &virtscr[0], s, 0, _roomWidth, virtscr[0].h, s, num, 0); } void ScummEngine::restoreBG(Common::Rect rect, byte backColor) { @@ -1137,8 +1142,8 @@ void ScummEngine::setShake(int mode) { #pragma mark - -void Gdi::drawBitmapV2Helper(const byte *ptr, VirtScreen *vs, int x, int y, const int width, const int height, int stripnr, int numstrip, StripTable *table) { - +void Gdi::drawBitmapV2Helper(const byte *ptr, VirtScreen *vs, int x, int y, const int width, const int height, int stripnr, int numstrip) { + StripTable *table = (_objectMode ? 0 : _roomStrips); const int left = (stripnr * 8); const int right = left + (numstrip * 8); byte *dst; @@ -1318,7 +1323,7 @@ int Gdi::getZPlanes(const byte *ptr, const byte *zplane_list[9], bool bmapImage) * and objects, used throughout all SCUMM versions. */ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int width, const int height, - int stripnr, int numstrip, byte flag, StripTable *table) { + int stripnr, int numstrip, byte flag) { assert(ptr); assert(height > 0); byte *dstPtr; @@ -1365,7 +1370,7 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int wi // differently from all other (newer) graphic formats for this reason. // if (_vm->_version == 2) - drawBitmapV2Helper(ptr, vs, x, y, width, height, stripnr, numstrip, table); + drawBitmapV2Helper(ptr, vs, x, y, width, height, stripnr, numstrip); sx = x - vs->xstart / 8; if (sx < 0) { diff --git a/scumm/gfx.h b/scumm/gfx.h index c1e70c005d..cde49b1ab1 100644 --- a/scumm/gfx.h +++ b/scumm/gfx.h @@ -199,6 +199,8 @@ struct BompDrawData { struct StripTable; +#define CHARSET_MASK_TRANSPARENCY 253 + class Gdi { friend class ScummEngine; // Mostly for the code in saveload.cpp ... ScummEngine *_vm; @@ -210,6 +212,7 @@ public: int32 _numStrips; Gdi(ScummEngine *vm); + ~Gdi(); protected: byte *_roomPalette; @@ -236,6 +239,9 @@ protected: int _NESObj_x; bool _NEShasmask; + /** For V2 games, we cache offsets into the room graphics, to speed up things. */ + StripTable *_roomStrips; + /* Bitmap decompressors */ bool decompressBitmap(byte *dst, int dstPitch, const byte *src, int numLinesToProcess); @@ -272,13 +278,14 @@ protected: int getZPlanes(const byte *smap_ptr, const byte *zplane_list[9], bool bmapImage) const; void drawBitmapV2Helper(const byte *ptr, VirtScreen *vs, int x, int y, const int width, const int height, - int stripnr, int numstrip, StripTable *table); + int stripnr, int numstrip); public: void init(); + void roomChanged(byte *roomptr, uint32 IM00_offs); void drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int width, const int height, - int stripnr, int numstrip, byte flag, StripTable *table = 0); + int stripnr, int numstrip, byte flag); StripTable *generateStripTable(const byte *src, int width, int height, StripTable *table) const; void decodeC64Gfx(const byte *src, byte *dst, int size) const; diff --git a/scumm/saveload.cpp b/scumm/saveload.cpp index 5d0a5daccb..de39f67cb6 100644 --- a/scumm/saveload.cpp +++ b/scumm/saveload.cpp @@ -284,22 +284,8 @@ bool ScummEngine::loadState(int slot, bool compat) { setupV1ActorTalkColor(); // Regenerate strip table (for V1/V2 games) - if (_version == 1) { - roomptr = getResourceAddress(rtRoom, _roomResource); - _IM00_offs = 0; - for (i = 0; i < 4; i++){ - gdi._C64.colors[i] = roomptr[6 + i]; - } - gdi.decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 10), gdi._C64.charMap, 2048); - gdi.decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 12), gdi._C64.picMap, roomptr[4] * roomptr[5]); - gdi.decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 14), gdi._C64.colorMap, roomptr[4] * roomptr[5]); - gdi.decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 16), gdi._C64.maskMap, roomptr[4] * roomptr[5]); - gdi.decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 18) + 2, gdi._C64.maskChar, READ_LE_UINT16(roomptr + READ_LE_UINT16(roomptr + 18))); - gdi._objectMode = true; - } else if (_version == 2) { - _roomStrips = gdi.generateStripTable(getResourceAddress(rtRoom, _roomResource) + _IM00_offs, - _roomWidth, _roomHeight, _roomStrips); - } + roomptr = getResourceAddress(rtRoom, _roomResource); + gdi.roomChanged(roomptr, _IM00_offs); if (!(_features & GF_NEW_CAMERA)) { camera._last.x = camera._cur.x; diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp index 28a8dc466d..308c627984 100644 --- a/scumm/scumm.cpp +++ b/scumm/scumm.cpp @@ -806,7 +806,6 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS _doEffect = false; memset(&_flashlight, 0, sizeof(_flashlight)); - _roomStrips = 0; _compositeBuf = 0; _herculesBuf = 0; _bompActorPalettePtr = NULL; @@ -1127,6 +1126,12 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS _screenHeight = 200; } + _compositeBuf = (byte *)malloc(_screenWidth * _screenHeight); + + if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) { + _herculesBuf = (byte *)malloc(Common::kHercW * Common::kHercH); + } + _midi = gs.midi; } @@ -1169,9 +1174,11 @@ ScummEngine::~ScummEngine() { free(_classData); free(_arraySlot); - free(_roomStrips); free(_languageIndex); + free(_compositeBuf); + free(_herculesBuf); + delete _debugger; } @@ -2304,24 +2311,9 @@ void ScummEngine::initRoomSubBlocks() { // Find the room image data // if (_version == 1) { - if (_features & GF_NES) { - gdi.decodeNESGfx(roomptr); - } else { - _IM00_offs = 0; - for (i = 0; i < 4; i++){ - gdi._C64.colors[i] = roomptr[6 + i]; - } - gdi.decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 10), gdi._C64.charMap, 2048); - gdi.decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 12), gdi._C64.picMap, roomptr[4] * roomptr[5]); - gdi.decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 14), gdi._C64.colorMap, roomptr[4] * roomptr[5]); - gdi.decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 16), gdi._C64.maskMap, roomptr[4] * roomptr[5]); - gdi.decodeC64Gfx(roomptr + READ_LE_UINT16(roomptr + 18) + 2, gdi._C64.maskChar, READ_LE_UINT16(roomptr + READ_LE_UINT16(roomptr + 18))); - gdi._objectMode = true; - } + _IM00_offs = 0; } else if (_features & GF_OLD_BUNDLE) { _IM00_offs = READ_LE_UINT16(roomptr + 0x0A); - if (_version == 2) - _roomStrips = gdi.generateStripTable(roomptr + _IM00_offs, _roomWidth, _roomHeight, _roomStrips); } else if (_version == 8) { _IM00_offs = getObjectImage(roomptr, 1) - roomptr; } else if (_features & GF_SMALL_HEADER) { @@ -2332,6 +2324,7 @@ void ScummEngine::initRoomSubBlocks() { } else { _IM00_offs = findResource(MKID('IM00'), findResource(MKID('RMIM'), roomptr)) - roomptr; } + gdi.roomChanged(roomptr, _IM00_offs); // // Look for an exit script diff --git a/scumm/scumm.h b/scumm/scumm.h index 7b324e3df7..69611abed4 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -891,8 +891,6 @@ protected: uint32 _CLUT_offs, _EPAL_offs; uint32 _IM00_offs, _PALS_offs; - StripTable *_roomStrips; - //ender: fullscreen bool _fullRedraw, _bgNeedsRedraw; bool _screenEffectFlag, _completeScreenRedraw; |