Ticket #1581: restoreCharsetBg.patch

File restoreCharsetBg.patch, 4.2 KB (added by fingolfin, 20 years ago)

Modify CharsetRenderer::restoreCharsetBg

  • gfx.cpp

    RCS file: /cvsroot/scummvm/scummvm/scumm/gfx.cpp,v
    retrieving revision 2.271
    diff -u -d -r2.271 gfx.cpp
     
    544544
    545545void ScummEngine::restoreBG(Common::Rect rect, byte backColor) {
    546546        VirtScreen *vs;
    547         byte *backbuff;
     547        byte *screenBuf;
    548548
    549549        if (rect.top < 0)
    550550                rect.top = 0;
     
    567567
    568568        markRectAsDirty(vs->number, rect, USAGE_BIT_RESTORED);
    569569
    570         int offset = rect.top * vs->width + vs->xstart + rect.left;
    571         backbuff = vs->screenPtr + offset;
     570        const int offset = rect.top * vs->width + vs->xstart + rect.left;
     571        screenBuf = vs->screenPtr + offset;
    572572
    573573        int height = rect.height();
    574574        int width = rect.width();
    575575
    576576        if (vs->hasTwoBuffers && _currentRoom != 0 && isLightOn()) {
    577                 blit(backbuff, vs->backBuf + offset, width, height);
     577                blit(screenBuf, vs->backBuf + offset, width, height);
    578578                if (vs->number == kMainVirtScreen && _charset->_hasMask && height) {
    579579                        byte *mask;
    580580
     
    600600                }
    601601        } else {
    602602                while (height--) {
    603                         memset(backbuff, backColor, width);
    604                         backbuff += vs->width;
     603                        memset(screenBuf, backColor, width);
     604                        screenBuf += vs->width;
    605605                }
    606606        }
    607607}
    608608
    609609void CharsetRenderer::restoreCharsetBg() {
     610        _nextLeft = _vm->_string[0].xpos;
     611        _nextTop = _vm->_string[0].ypos;
     612
    610613        if (_hasMask) {
    611                 // Restore background on the whole text area. To do this, we simply
    612                 // pass a large rect to restoreBG, and then rely on it clipping that
    613                 // rect. Also, restoreBG() will use findVirtScreen(rect.top) to
    614                 // determine the virtual screen on which to operate. This is fine
    615                 // for us, since we pass in rect.top, so in older games, the text
    616                 // display area is used; in newer games, the main virtscreen gets
    617                 // restored. That's exactly what we need.
    618                 //
    619                 // Of course this will break down if one of the older games (with
    620                 // multiple virtual screens in use) draw text outside the text virtual
    621                 // screen (verbs are excluded, they are handled in a special fashion).
    622                 // But I have no indication that this does ever happen.
    623                 _vm->restoreBG(Common::Rect(5000, 5000));
    624614                _hasMask = false;
    625615                _str.left = -1;
    626616                _left = -1;
    627         }
    628617
    629         _nextLeft = _vm->_string[0].xpos;
    630         _nextTop = _vm->_string[0].ypos;
     618                // Restore background on the whole text area. This code is based on
     619                // restoreBG(), but was changed to only restore those parts which are
     620                // currently covered by the charset mask.
     621                VirtScreen *vs = _vm->findVirtScreen(0);
     622                assert(vs);
     623               
     624                _vm->markRectAsDirty(vs->number, Common::Rect(vs->width, vs->height), USAGE_BIT_RESTORED);
     625       
     626                const byte *backBuf = vs->backBuf + vs->xstart;
     627                byte *screenBuf = vs->screenPtr + vs->xstart;
     628       
     629                if (vs->hasTwoBuffers && _vm->_currentRoom != 0 && _vm->isLightOn()) {
     630                        if (vs->number == kMainVirtScreen) {
     631                                // Restore from back buffer, but only those parts which are
     632                                // currently covered by the charset mask. In addition, we
     633                                // clean out the charset mask
     634
     635                                byte *mask = _vm->getMaskBuffer(0, 0, 0);
     636                                const int mask_width = _vm->gdi._numStrips;
     637                                assert(vs->width == 8 * _vm->gdi._numStrips);
     638                               
     639                                int height = vs->height;
     640                                while (height--) {
     641                                        for (int w = 0; w < mask_width; ++w) {
     642                                                const byte maskbits = mask[w];
     643                                                if (maskbits) {
     644                                                        const byte *src = backBuf + w*8;
     645                                                        byte *dst = screenBuf + w*8;
     646                                                        if (maskbits & 0x80)
     647                                                                dst[0] = src[0];
     648                                                        if (maskbits & 0x40)
     649                                                                dst[1] = src[1];
     650                                                        if (maskbits & 0x20)
     651                                                                dst[2] = src[2];
     652                                                        if (maskbits & 0x10)
     653                                                                dst[3] = src[3];
     654                                                        if (maskbits & 0x08)
     655                                                                dst[4] = src[4];
     656                                                        if (maskbits & 0x04)
     657                                                                dst[5] = src[5];
     658                                                        if (maskbits & 0x02)
     659                                                                dst[6] = src[6];
     660                                                        if (maskbits & 0x01)
     661                                                                dst[7] = src[7];
     662
     663                                                        mask[w] = 0;
     664                                                }
     665                                        }
     666                                        screenBuf += vs->width;
     667                                        backBuf += vs->width;
     668                                        mask += _vm->gdi._numStrips;
     669                                }
     670                        } else {
     671                                // Restore from back buffer
     672                                _vm->blit(screenBuf, backBuf, vs->width, vs->height);
     673                        }
     674                } else {
     675                        // Clear area
     676                        memset(screenBuf, 0, vs->height * vs->width);
     677                }
     678        }
    631679}
    632680
    633681void CharsetRenderer::clearCharsetMask() {