Ticket #8598: nut_no_shadow_hack.diff

File nut_no_shadow_hack.diff, 11.0 KB (added by cyxx, 14 years ago)

Possible patch to get rid of the shadow char hack

  • scumm/smush/smush_font.cpp

     
    3030namespace Scumm {
    3131
    3232SmushFont::SmushFont(ScummEngine *vm, const char *filename, bool use_original_colors, bool new_colors) :
    33         NutRenderer(vm, filename, false),
     33        NutRenderer(vm, filename),
    3434        _color(-1),
    3535        _new_colors(new_colors),
    3636        _original(use_original_colors) {
     
    7474                for (int j = 0; j < h; j++) {
    7575                        for (int i = 0; i < w; i++) {
    7676                                int8 value = *src++;
    77                                 if (value)
     77                                if (value != kDefaultTransparentColor)
    7878                                        dst[i] = value;
    7979                        }
    8080                        dst += dst_width;
     
    8989                                                dst[i] = 0xFF;
    9090                                        } else if (value == -31) {
    9191                                                dst[i] = 0;
    92                                         } else if (value) {
     92                                        } else if (value != kSmush44TransparentColor) {
    9393                                                dst[i] = value;
    9494                                        }
    9595                                }
     
    101101                                        int8 value = *src++;
    102102                                        if (value == 1) {
    103103                                                dst[i] = color;
    104                                         } else if (value) {
     104                                        } else if (value != kDefaultTransparentColor) {
    105105                                                dst[i] = 0;
    106106                                        }
    107107                                }
  • scumm/charset.cpp

     
    16211621        if (!_fr[id]) {
    16221622                char fontname[11];
    16231623                sprintf(fontname, "font%d.nut", id);
    1624                 _fr[id] = new NutRenderer(_vm, fontname, true);
     1624                _fr[id] = new NutRenderer(_vm, fontname);
    16251625        }
    16261626        _current = _fr[id];
    16271627        assert(_current);
     
    16501650        if (chr == '@')
    16511651                return;
    16521652
    1653         shadow.left = _left - 1;
    1654         shadow.top = _top - 1;
     1653        shadow.left = _left;
     1654        shadow.top = _top;
    16551655
    1656         // Note that the character is drawn with a shadow, so it is slightly
    1657         // larger than the advertised dimensions. See drawShadowChar() for
    1658         // details.
    1659 
    16601656        if (_firstChar) {
    16611657                _str.left = (shadow.left >= 0) ? shadow.left : 0;
    16621658                _str.top = (shadow.top >= 0) ? shadow.top : 0;
     
    16711667        if (chr >= 256 && _vm->_useCJKMode)
    16721668                width = _vm->_2byteWidth;
    16731669
    1674         shadow.right = _left + width + 2;
    1675         shadow.bottom = _top + height + 2;
     1670        shadow.right = _left + width;
     1671        shadow.bottom = _top + height;
    16761672
    16771673        Graphics::Surface s;
    16781674        if (!ignoreCharsetMask) {
     
    16901686                drawTop -= _vm->_screenTop;
    16911687        }
    16921688
    1693         _current->drawShadowChar(s, chr, _left, drawTop, _color, _curId != 3);
     1689        if (chr >= 256 && _vm->_useCJKMode)
     1690                _current->draw2byte(s, chr, _left, drawTop, _color);
     1691        else
     1692                _current->drawChar(s, (byte)chr, _left, drawTop, _color);
    16941693        _vm->markRectAsDirty(kMainVirtScreen, shadow);
    16951694
    16961695        if (_str.left > _left)
  • scumm/nut_renderer.cpp

     
    2727
    2828namespace Scumm {
    2929
    30 NutRenderer::NutRenderer(ScummEngine *vm, const char *filename, bool bitmap) :
     30NutRenderer::NutRenderer(ScummEngine *vm, const char *filename) :
    3131        _vm(vm),
    32         _bitmapFont(bitmap),
    3332        _numChars(0),
    3433        _decodedData(0) {
    3534        memset(_chars, 0, sizeof(_chars));
     
    5756                        if (code & 1) {
    5857                                val = *src++;
    5958                                size_line--;
    60                                 if (_bitmapFont) {
    61                                         for (int i = 0; i < length; i++) {
    62                                                 if (val)
    63                                                         *dst |= bit;
    64                                                 bit >>= 1;
    65                                                 if (!bit) {
    66                                                         bit = 0x80;
    67                                                         dst++;
    68                                                 }
    69                                         }
    70                                 } else {
    71                                         if (val)
    72                                                 memset(dst, val, length);
    73                                         dst += length;
    74                                 }
     59                                if (val)
     60                                        memset(dst, val, length);
     61                                dst += length;
    7562                        } else {
    7663                                size_line -= length;
    7764                                while (length--) {
    7865                                        val = *src++;
    79                                         if (_bitmapFont) {
    80                                                 if (val)
    81                                                         *dst |= bit;
    82                                                 bit >>= 1;
    83                                                 if (!bit) {
    84                                                         bit = 0x80;
    85                                                         dst++;
    86                                                 }
    87                                         } else {
    88                                                 if (val)
    89                                                         *dst = val;
    90                                                 dst++;
    91                                         }
     66                                        if (val)
     67                                                *dst = val;
     68                                        dst++;
    9269                                }
    9370                        }
    9471                }
     
    10683                do {
    10784                        int i;
    10885                        int offs = READ_LE_UINT16(src); src += 2;
    109                         if (_bitmapFont) {
    110                                 for (i = 0; i < offs; i++) {
    111                                         bit >>= 1;
    112                                         if (!bit) {
    113                                                 bit = 0x80;
    114                                                 dst++;
    115                                         }
    116                                 }
    117                         } else {
    118                                 dst += offs;
    119                         }
     86                        dst += offs;
    12087                        len -= offs;
    12188                        if (len <= 0) {
    12289                                break;
     
    13097                        //  src bytes equal to 255 are replaced by 0 in dst
    13198                        //  src bytes equal to 1 are replaced by a color passed as an argument in the original function
    13299                        //  other src bytes values are copied as-is
    133                         if (_bitmapFont) {
    134                                 for (i = 0; i < w; i++) {
    135                                         if (src[i])
    136                                                 *dst |= bit;
    137                                         bit >>= 1;
    138                                         if (!bit) {
    139                                                 bit = 0x80;
    140                                                 dst++;
    141                                         }
    142                                 }
    143                         } else {
    144                                 memcpy(dst, src, w);
    145                                 dst += w;
    146                         }
     100                        memcpy(dst, src, w);
     101                        dst += w;
    147102                        src += w;
    148103                } while (len > 0);
    149104                dst = dstPtrNext;
     
    185140                offset += READ_BE_UINT32(dataSrc + offset + 4) + 16;
    186141                int width = READ_LE_UINT16(dataSrc + offset + 14);
    187142                int height = READ_LE_UINT16(dataSrc + offset + 16);
    188                 if (_bitmapFont) {
    189                         decodedLength += (((width + 7) / 8) * height);
    190                 } else {
    191                         decodedLength += (width * height);
    192                 }
     143                decodedLength += (width * height);
    193144        }
    194145
    195         // If characters have transparency, then bytes just get skipped and
    196         // so there may appear some garbage. That's why we have to fill it
    197         // with zeroes first.
    198 
    199146        _decodedData = new byte[decodedLength];
    200         memset(_decodedData, 0, decodedLength);
    201 
    202147        byte *decodedPtr = _decodedData;
    203148
    204149        offset = 0;
     
    220165                _chars[l].height = READ_LE_UINT16(dataSrc + offset + 16);
    221166                _chars[l].src = decodedPtr;
    222167
    223                 int pitch;
     168                decodedPtr += (_chars[l].width * _chars[l].height);
    224169
    225                 if (_bitmapFont) {
    226                         pitch = (_chars[l].width + 7) / 8;
    227                 } else {
    228                         pitch = _chars[l].width;
    229                 }
     170                // If characters have transparency, then bytes just get skipped and
     171                // so there may appear some garbage. That's why we have to fill it
     172                // with a default color first.
     173                memset(_chars[l].src, (codec == 44) ? kSmush44TransparentColor : kDefaultTransparentColor, _chars[l].width * _chars[l].height);
    230174
    231                 decodedPtr += (pitch * _chars[l].height);
    232 
    233175                const uint8 *fobjptr = dataSrc + offset + 22;
    234176                switch (codec) {
    235177                case 1:
    236                         codec1(_chars[l].src, fobjptr, _chars[l].width, _chars[l].height, pitch);
     178                        codec1(_chars[l].src, fobjptr, _chars[l].width, _chars[l].height, _chars[l].width);
    237179                        break;
    238180                case 21:
    239181                case 44:
    240                         codec21(_chars[l].src, fobjptr, _chars[l].width, _chars[l].height, pitch);
     182                        codec21(_chars[l].src, fobjptr, _chars[l].width, _chars[l].height, _chars[l].width);
    241183                        break;
    242184                default:
    243185                        error("NutRenderer::loadFont: unknown codec: %d", codec);
     
    267209        return _chars[c].height;
    268210}
    269211
    270 void NutRenderer::drawShadowChar(const Graphics::Surface &s, int c, int x, int y, byte color, bool showShadow) {
    271 
    272         // We draw the character a total of 7 times: 6 times shifted and in black
    273         // for the shadow, and once in the right color and position. This way we
    274         // achieve the exact look as the original CMI had.
    275         // However, this is not how the original engine handled it. Char glyphs
    276         // were compressed with codec 44. In the decoding routine, transparent
    277         // pixels are skipped. Other pixels are just filled with the decoded color
    278         // which can be equal to 0 (==shadow), 1 (==char color) or another value
    279         // (255, 224) which is just copied as-is in the destination buffer.
    280 
    281         static const int offsetX[7] = { -1,  0, 1, 0, 1, 2, 0 };
    282         static const int offsetY[7] = {  0, -1, 0, 1, 2, 1, 0 };
    283         const int cTable[7] = { 0, 0, 0, 0, 0, 0, color };
    284         int i = 0;
    285 
    286         if (!showShadow)
    287                 i = 6;
    288 
    289         for (; i < 7; i++) {
    290                 x += offsetX[i];
    291                 y += offsetY[i];
    292                 color = cTable[i];
    293 
    294                 if (c >= 256 && _vm->_useCJKMode)
    295                         draw2byte(s, c, x, y, color);
    296                 else
    297                         drawChar(s, (byte)c, x, y, color);
    298 
    299                 x -= offsetX[i];
    300                 y -= offsetY[i];
    301         }
    302 }
    303 
    304212void NutRenderer::drawFrame(byte *dst, int c, int x, int y) {
    305         assert(!_bitmapFont);
    306 
    307213        const int width = MIN((int)_chars[c].width, _vm->_screenWidth - x);
    308214        const int height = MIN((int)_chars[c].height, _vm->_screenHeight - y);
    309215        const byte *src = _chars[c].src;
     
    340246        const int width = MIN((int)_chars[c].width, s.w - x);
    341247        const int height = MIN((int)_chars[c].height, s.h - y);
    342248        const byte *src = _chars[c].src;
    343         int srcPitch;
     249        int srcPitch = _chars[c].width;
    344250
    345         if (_bitmapFont) {
    346                 srcPitch = (_chars[c].width + 7) / 8;
    347         } else {
    348                 srcPitch = _chars[c].width;
    349         }
    350 
    351251        const int minX = x < 0 ? -x : 0;
    352252        const int minY = y < 0 ? -y : 0;
    353253
     
    361261        }
    362262
    363263        for (int ty = minY; ty < height; ty++) {
    364                 int tx;
    365 
    366                 for (tx = minX; tx < width; tx++) {
    367                         if (_bitmapFont) {
    368                                 if (src[tx / 8] & (0x80 >> (tx % 8))) {
     264                for (int tx = minX; tx < width; tx++) {
     265                        if (src[tx] != kSmush44TransparentColor) {
     266                                if (src[tx] == 1) {
    369267                                        dst[tx] = color;
     268                                } else {
     269                                        dst[tx] = src[tx];
    370270                                }
    371                         } else {
    372                                 if (src[tx] != 0) {
    373                                         dst[tx] = color;
    374                                 }
    375271                        }
    376272                }
    377273                src += srcPitch;
  • scumm/insane/insane.cpp

     
    6565                readFileToMem("toranch.flu", &_smush_toranchFlu);
    6666                readFileToMem("minedriv.flu", &_smush_minedrivFlu);
    6767                readFileToMem("minefite.flu", &_smush_minefiteFlu);
    68                 _smush_bensgoggNut = new NutRenderer(_vm, "bensgogg.nut", false);
    69                 _smush_bencutNut = new NutRenderer(_vm, "bencut.nut", false);
     68                _smush_bensgoggNut = new NutRenderer(_vm, "bensgogg.nut");
     69                _smush_bencutNut = new NutRenderer(_vm, "bencut.nut");
    7070        }
    7171
    72         _smush_iconsNut = new NutRenderer(_vm, "icons.nut", false);
    73         _smush_icons2Nut = new NutRenderer(_vm, "icons2.nut", false);
     72        _smush_iconsNut = new NutRenderer(_vm, "icons.nut");
     73        _smush_icons2Nut = new NutRenderer(_vm, "icons2.nut");
    7474}
    7575
    7676Insane::~Insane(void) {
  • scumm/nut_renderer.h

     
    3131
    3232class NutRenderer {
    3333protected:
     34
     35        enum {
     36                kDefaultTransparentColor = 0,
     37                kSmush44TransparentColor = 2
     38        };
     39
    3440        ScummEngine *_vm;
    35         bool _bitmapFont;
    3641        int _numChars;
    3742        byte *_decodedData;
    3843        struct {
     
    4449        void codec1(byte *dst, const byte *src, int width, int height, int pitch);
    4550        void codec21(byte *dst, const byte *src, int width, int height, int pitch);
    4651
    47         void drawChar(const Graphics::Surface &s, byte c, int x, int y, byte color);
    48         void draw2byte(const Graphics::Surface &s, int c, int x, int y, byte color);
    49 
    5052        void loadFont(const char *filename);
    5153
    5254public:
    53         NutRenderer(ScummEngine *vm, const char *filename, bool bitmap);
     55        NutRenderer(ScummEngine *vm, const char *filename);
    5456        virtual ~NutRenderer();
    5557        int getNumChars() const { return _numChars; }
    5658
    5759        void drawFrame(byte *dst, int c, int x, int y);
    58         void drawShadowChar(const Graphics::Surface &s, int c, int x, int y, byte color, bool showShadow);
     60        void drawChar(const Graphics::Surface &s, byte c, int x, int y, byte color);
     61        void draw2byte(const Graphics::Surface &s, int c, int x, int y, byte color);
    5962
    6063        int getCharWidth(byte c) const;
    6164        int getCharHeight(byte c) const;