Ticket #8598: nut-allocate3.diff

File nut-allocate3.diff, 11.6 KB (added by eriktorbjorn, 14 years ago)

Updated patch against current SVN

  • engines/scumm/smush/smush_player.cpp

     
    10421042                        _sf[1] = new SmushFont(_vm, true, false);
    10431043                        _sf[2] = new SmushFont(_vm, true, false);
    10441044                        _sf[3] = new SmushFont(_vm, true, false);
    1045                         _sf[0]->loadFont("scummfnt.nut");
    1046                         _sf[1]->loadFont("techfnt.nut");
    1047                         _sf[2]->loadFont("titlfnt.nut");
    1048                         _sf[3]->loadFont("specfnt.nut");
     1045                        _sf[0]->loadFont("scummfnt.nut", false);
     1046                        _sf[1]->loadFont("techfnt.nut", false);
     1047                        _sf[2]->loadFont("titlfnt.nut", false);
     1048                        _sf[3]->loadFont("specfnt.nut", false);
    10491049                }
    10501050        } else if (_vm->_game.id == GID_DIG) {
    10511051                if (!(_vm->_game.features & GF_DEMO)) {
    10521052                        for (i = 0; i < 4; i++) {
    10531053                                sprintf(file_font, "font%d.nut", i);
    10541054                                _sf[i] = new SmushFont(_vm, i != 0, false);
    1055                                 _sf[i]->loadFont(file_font);
     1055                                _sf[i]->loadFont(file_font, false);
    10561056                        }
    10571057                }
    10581058        } else if (_vm->_game.id == GID_CMI) {
     
    10611061                                break;
    10621062                        sprintf(file_font, "font%d.nut", i);
    10631063                        _sf[i] = new SmushFont(_vm, false, true);
    1064                         _sf[i]->loadFont(file_font);
     1064                        _sf[i]->loadFont(file_font, false);
    10651065                }
    10661066        } else {
    10671067                error("SmushPlayer::setupAnim() Unknown font setup for game");
  • engines/scumm/charset.cpp

     
    16091609                        break;
    16101610                sprintf(fontname, "font%d.nut", i);
    16111611                _fr[i] = new NutRenderer(_vm);
    1612                 if (!(_fr[i]->loadFont(fontname))) {
     1612                if (!(_fr[i]->loadFont(fontname, true))) {
    16131613                        delete _fr[i];
    16141614                        _fr[i] = NULL;
    16151615                }
  • engines/scumm/nut_renderer.cpp

     
    3030NutRenderer::NutRenderer(ScummEngine *vm) :
    3131        _vm(vm),
    3232        _loaded(false),
    33         _numChars(0) {
     33        _numChars(0),
     34        _decodedData(0) {
    3435        memset(_chars, 0, sizeof(_chars));
    3536}
    3637
    3738NutRenderer::~NutRenderer() {
    38         for (int i = 0; i < _numChars; i++) {
    39                 delete []_chars[i].src;
     39        delete [] _decodedData;
     40}
     41
     42void NutRenderer::codec1(bool bitmap, byte *dst, const byte *src, int width, int height, int pitch) {
     43        byte val, code;
     44        int32 length;
     45        int h = height, size_line;
     46
     47        for (h = 0; h < height; h++) {
     48                size_line = READ_LE_UINT16(src);
     49                src += 2;
     50                byte bit = 0x80;
     51                byte *dstPtrNext = dst + pitch;
     52                while (size_line > 0) {
     53                        code = *src++;
     54                        size_line--;
     55                        length = (code >> 1) + 1;
     56                        if (code & 1) {
     57                                val = *src++;
     58                                size_line--;
     59                                if (bitmap) {
     60                                        for (int i = 0; i < length; i++) {
     61                                                if (val)
     62                                                        *dst |= bit;
     63                                                bit >>= 1;
     64                                                if (!bit) {
     65                                                        bit = 0x80;
     66                                                        dst++;
     67                                                }
     68                                        }
     69                                } else {
     70                                        if (val)
     71                                                memset(dst, val, length);
     72                                        dst += length;
     73                                }
     74                        } else {
     75                                size_line -= length;
     76                                while (length--) {
     77                                        val = *src++;
     78                                        if (bitmap) {
     79                                                if (val)
     80                                                        *dst |= bit;
     81                                                bit >>= 1;
     82                                                if (!bit) {
     83                                                        bit = 0x80;
     84                                                        dst++;
     85                                                }
     86                                        } else {
     87                                                if (val)
     88                                                        *dst = val;
     89                                                dst++;
     90                                        }
     91                                }
     92                        }
     93                }
     94                dst = dstPtrNext;
    4095        }
    4196}
    4297
    43 void smush_decode_codec1(byte *dst, const byte *src, int left, int top, int width, int height, int pitch);
    44 
    45 static void smush_decode_codec21(byte *dst, const byte *src, int width, int height, int pitch) {
     98void NutRenderer::codec21(bool bitmap, byte *dst, const byte *src, int width, int height, int pitch) {
    4699        while (height--) {
    47                 uint8 *dstPtrNext = dst + pitch;
    48                 const uint8 *srcPtrNext = src + 2 + READ_LE_UINT16(src); src += 2;
     100                byte *dstPtrNext = dst + pitch;
     101                const byte *srcPtrNext = src + 2 + READ_LE_UINT16(src);
     102                src += 2;
    49103                int len = width;
     104                byte bit = 0x80;
    50105                do {
     106                        int i;
    51107                        int offs = READ_LE_UINT16(src); src += 2;
    52                         dst += offs;
     108                        if (bitmap) {
     109                                for (i = 0; i < offs; i++) {
     110                                        bit >>= 1;
     111                                        if (!bit) {
     112                                                bit = 0x80;
     113                                                dst++;
     114                                        }
     115                                }
     116                        } else {
     117                                dst += offs;
     118                        }
    53119                        len -= offs;
    54120                        if (len <= 0) {
    55121                                break;
     
    63129                        //  src bytes equal to 255 are replaced by 0 in dst
    64130                        //  src bytes equal to 1 are replaced by a color passed as an argument in the original function
    65131                        //  other src bytes values are copied as-is
    66                         memcpy(dst, src, w); dst += w; src += w;
     132                        if (bitmap) {
     133                                for (i = 0; i < w; i++) {
     134                                        if (src[i])
     135                                                *dst |= bit;
     136                                        bit >>= 1;
     137                                        if (!bit) {
     138                                                bit = 0x80;
     139                                                dst++;
     140                                        }
     141                                }
     142                        } else {
     143                                memcpy(dst, src, w);
     144                                dst += w;
     145                        }
     146                        src += w;
    67147                } while (len > 0);
    68148                dst = dstPtrNext;
    69149                src = srcPtrNext;
    70150        }
    71151}
    72152
    73 bool NutRenderer::loadFont(const char *filename) {
     153bool NutRenderer::loadFont(const char *filename, bool bitmap) {
    74154        if (_loaded) {
    75155                debug(0, "NutRenderer::loadFont() Font already loaded, ok, loading...");
    76156        }
    77157
     158        _bitmapFont = bitmap;
     159
    78160        ScummFile file;
    79161        _vm->openFile(file, filename);
    80162        if (!file.isOpen()) {
     
    89171        }
    90172
    91173        uint32 length = file.readUint32BE();
    92         byte *dataSrc = (byte *)malloc(length);
     174        byte *dataSrc = new byte[length];
    93175        file.read(dataSrc, length);
    94176        file.close();
    95177
     
    99181                return false;
    100182        }
    101183
     184        // We pre-decode the font, which may seem wasteful at first. Actually,
     185        // the memory needed for just the decoded glyphs is smaller than the
     186        // whole of the undecoded font file.
     187
    102188        _numChars = READ_LE_UINT16(dataSrc + 10);
    103189        assert(_numChars <= ARRAYSIZE(_chars));
     190
    104191        uint32 offset = 0;
     192        uint32 decodedLength = 0;
    105193        for (int l = 0; l < _numChars; l++) {
     194                offset += READ_BE_UINT32(dataSrc + offset + 4) + 16;
     195                int width = READ_LE_UINT16(dataSrc + offset + 14);
     196                int height = READ_LE_UINT16(dataSrc + offset + 16);
     197                if (_bitmapFont) {
     198                        decodedLength += (((width + 7) / 8) * height);
     199                } else {
     200                        decodedLength += (width * height);
     201                }
     202        }
     203
     204        // If characters have transparency, then bytes just get skipped and
     205        // so there may appear some garbage. That's why we have to fill it
     206        // with zeroes first.
     207
     208        _decodedData = new byte[decodedLength];
     209        memset(_decodedData, 0, decodedLength);
     210
     211        byte *decodedPtr = _decodedData;
     212
     213        offset = 0;
     214        for (int l = 0; l < _numChars; l++) {
    106215                offset += READ_BE_UINT32(dataSrc + offset + 4) + 8;
    107216                if (READ_BE_UINT32(dataSrc + offset) != 'FRME') {
    108217                        error("NutRenderer::loadFont(%s) there is no FRME chunk %d (offset %x)", filename, l, offset);
     
    114223                        break;
    115224                }
    116225                int codec = READ_LE_UINT16(dataSrc + offset + 8);
    117                 _chars[l].xoffs = READ_LE_UINT16(dataSrc + offset + 10);
    118                 _chars[l].yoffs = READ_LE_UINT16(dataSrc + offset + 12);
     226                // _chars[l].xoffs = READ_LE_UINT16(dataSrc + offset + 10);
     227                // _chars[l].yoffs = READ_LE_UINT16(dataSrc + offset + 12);
    119228                _chars[l].width = READ_LE_UINT16(dataSrc + offset + 14);
    120229                _chars[l].height = READ_LE_UINT16(dataSrc + offset + 16);
    121                 const int srcSize = _chars[l].width * _chars[l].height;
    122                 _chars[l].src = new byte[srcSize];
    123                 // If characters have transparency, then bytes just get skipped and
    124                 // so there may appear some garbage. That's why we have to fill it
    125                 // with zeroes first.
    126                 memset(_chars[l].src, 0, srcSize);
     230                _chars[l].src = decodedPtr;
    127231
     232                int pitch;
     233
     234                if (_bitmapFont) {
     235                        pitch = (_chars[l].width + 7) / 8;
     236                } else {
     237                        pitch = _chars[l].width;
     238                }
     239
     240                decodedPtr += (pitch * _chars[l].height);
     241
    128242                const uint8 *fobjptr = dataSrc + offset + 22;
    129243                switch (codec) {
    130244                case 1:
    131                         smush_decode_codec1(_chars[l].src, fobjptr, 0, 0, _chars[l].width, _chars[l].height, _chars[l].width);
     245                        codec1(_bitmapFont, _chars[l].src, fobjptr, _chars[l].width, _chars[l].height, pitch);
    132246                        break;
    133247                case 21:
    134248                case 44:
    135                         smush_decode_codec21(_chars[l].src, fobjptr, _chars[l].width, _chars[l].height, _chars[l].width);
     249                        codec21(_bitmapFont, _chars[l].src, fobjptr, _chars[l].width, _chars[l].height, pitch);
    136250                        break;
    137251                default:
    138252                        error("NutRenderer::loadFont: unknown codec: %d", codec);
    139253                }
    140254        }
    141255
    142         free(dataSrc);
     256        delete [] dataSrc;
    143257        _loaded = true;
    144258        return true;
    145259}
     
    210324}
    211325
    212326void NutRenderer::drawFrame(byte *dst, int c, int x, int y) {
    213         const int width = MIN(_chars[c].width, _vm->_screenWidth - x);
    214         const int height = MIN(_chars[c].height, _vm->_screenHeight - y);
     327        assert(!_bitmapFont);
     328
     329        const int width = MIN((int)_chars[c].width, _vm->_screenWidth - x);
     330        const int height = MIN((int)_chars[c].height, _vm->_screenHeight - y);
    215331        const byte *src = _chars[c].src;
    216332        const int srcPitch = _chars[c].width;
    217333        byte bits = 0;
     
    243359
    244360void NutRenderer::drawChar(const Graphics::Surface &s, byte c, int x, int y, byte color) {
    245361        byte *dst = (byte *)s.pixels + y * s.pitch + x;
    246         const int width = MIN(_chars[c].width, s.w - x);
    247         const int height = MIN(_chars[c].height, s.h - y);
     362        const int width = MIN((int)_chars[c].width, s.w - x);
     363        const int height = MIN((int)_chars[c].height, s.h - y);
    248364        const byte *src = _chars[c].src;
    249         const int srcPitch = _chars[c].width;
     365        int srcPitch;
    250366
     367        if (_bitmapFont) {
     368                srcPitch = (_chars[c].width + 7) / 8;
     369        } else {
     370                srcPitch = _chars[c].width;
     371        }
     372
    251373        const int minX = x < 0 ? -x : 0;
    252374        const int minY = y < 0 ? -y : 0;
    253375
     
    261383        }
    262384
    263385        for (int ty = minY; ty < height; ty++) {
    264                 for (int tx = minX; tx < width; tx++) {
    265                         if (src[tx] != 0) {
    266                                 dst[tx] = color;
     386                int tx;
     387
     388                for (tx = minX; tx < width; tx++) {
     389                        if (_bitmapFont) {
     390                                if (src[tx / 8] & (0x80 >> (tx % 8))) {
     391                                        dst[tx] = color;
     392                                }
     393                        } else {
     394                                if (src[tx] != 0) {
     395                                        dst[tx] = color;
     396                                }
    267397                        }
    268398                }
    269399                src += srcPitch;
  • engines/scumm/insane/insane.cpp

     
    6666                readFileToMem("minedriv.flu", &_smush_minedrivFlu);
    6767                readFileToMem("minefite.flu", &_smush_minefiteFlu);
    6868                _smush_bensgoggNut = new NutRenderer(_vm);
    69                 _smush_bensgoggNut->loadFont("bensgogg.nut");
     69                _smush_bensgoggNut->loadFont("bensgogg.nut", false);
    7070                _smush_bencutNut = new NutRenderer(_vm);
    71                 _smush_bencutNut->loadFont("bencut.nut");
     71                _smush_bencutNut->loadFont("bencut.nut", false);
    7272        }
    7373
    7474        _smush_iconsNut = new NutRenderer(_vm);
    75         _smush_iconsNut->loadFont("icons.nut");
     75        _smush_iconsNut->loadFont("icons.nut", false);
    7676        _smush_icons2Nut = new NutRenderer(_vm);
    77         _smush_icons2Nut->loadFont("icons2.nut");
     77        _smush_icons2Nut->loadFont("icons2.nut", false);
    7878}
    7979
    8080Insane::~Insane(void) {
  • engines/scumm/nut_renderer.h

     
    3333protected:
    3434        ScummEngine *_vm;
    3535        bool _loaded;
     36        bool _bitmapFont;
    3637        int _numChars;
     38        byte *_decodedData;
    3739        struct {
    38                 int xoffs;
    39                 int yoffs;
    40                 int width;
    41                 int height;
     40                uint16 width;
     41                uint16 height;
    4242                byte *src;
    4343        } _chars[256];
    4444
     45        static void codec1(bool bitmap, byte *dst, const byte *src, int width, int height, int pitch);
     46        static void codec21(bool bitmap, byte *dst, const byte *src, int width, int height, int pitch);
     47
    4548        void drawChar(const Graphics::Surface &s, byte c, int x, int y, byte color);
    4649        void draw2byte(const Graphics::Surface &s, int c, int x, int y, byte color);
    4750
     
    5053        virtual ~NutRenderer();
    5154        int getNumChars() const { return _numChars; }
    5255
    53         bool loadFont(const char *filename);
     56        bool loadFont(const char *filename, bool bitmap);
    5457
    5558        void drawFrame(byte *dst, int c, int x, int y);
    5659        void drawShadowChar(const Graphics::Surface &s, int c, int x, int y, byte color, bool showShadow);