Ticket #8240: 2byte_charset.2.diff

File 2byte_charset.2.diff, 16.0 KB (added by fingolfin, 21 years ago)

rev 3

  • scumm/charset.cpp

    RCS file: /cvsroot/scummvm/scummvm/scumm/charset.cpp,v
    retrieving revision 2.38
    diff -u -r2.38 charset.cpp
     
    2323#include "scumm.h"
    2424#include "nut_renderer.h"
    2525
     26bool _2byte_pos_hack;
     27
     28int get2byteIndex(int idx)
     29{
     30        /*
     31                switch(language)
     32                case korean:
     33                        return ( (idx % 256) - 0xb0) * 94 + (idx / 256) - 0xa1;
     34                case japanese:
     35                        ...
     36                case taiwan:
     37                        ...
     38        */
     39        return ( (idx % 256) - 0xb0) * 94 + (idx / 256) - 0xa1; // only for korean
     40}
     41
     42bool Scumm::checkCJKLanguage()
     43{
     44        return (_language == KO_KOR || _language == JA_JPN || _language == ZH_TWN);
     45}
     46
    2647CharsetRenderer::CharsetRenderer(Scumm *vm) {
    2748
    2849        _nextLeft = 0;
     
    79100
    80101// do spacing for variable width old-style font
    81102int CharsetRendererClassic::getCharWidth(byte chr) {
     103        if(chr >= 0x80 && _CJKMode)
     104                return 6;
    82105        int spacing = 0;
    83106
    84107        int offs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
     
    628651        int offsX, offsY;
    629652        int d;
    630653        VirtScreen *vs;
     654        int is2byte = 0;
    631655
    632656        _vm->checkRange(_vm->_maxCharsets - 1, 1, _curId, "Printing with bad charset %d");
    633657       
     
    640664        _bpp = *_fontPtr;
    641665        _vm->_charsetColorMap[1] = _color;
    642666
    643         uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
     667        is2byte = (chr >= 0x80 && _CJKMode) ? 1 : 0;
     668
     669        uint32 charOffs = READ_LE_UINT32(_fontPtr + (is2byte ? 0x0f : chr) * 4 + 4); //HACK!
    644670
    645671        if (!charOffs)
    646672                return;
     
    649675
    650676        _charPtr = _fontPtr + charOffs;
    651677
    652         width = _charPtr[0];
     678        if(is2byte) width = _charPtr[0] - 1; else width = _charPtr[0]; //HACK!!!
    653679        height = _charPtr[1];
    654680        if (_firstChar) {
    655681                _str.left = 0;
     
    714740        byte *mask = _vm->getMaskBuffer(_left, drawTop, 0);
    715741        byte *dst = vs->screenPtr + vs->xstart + drawTop * _vm->_screenWidth + _left;
    716742
     743        byte *back = dst;
    717744        if (_blitAlso) {
    718                 byte *back = dst;
    719745                dst = _vm->getResourceAddress(rtBuffer, vs->number + 5)
    720746                        + vs->xstart + drawTop * _vm->_screenWidth + _left;
     747        }
    721748
     749        if(is2byte) {
     750                width = _2byte_width;
     751                height = _2byte_height;
     752                _charPtr = (byte *)&_2byte[get2byteIndex(chr) * 18];
     753                _bpp = 1;
     754                draw2byte(vs, dst, mask, drawTop, width, height);
     755//              drawBits(vs, dst, mask, drawTop, width, height);
     756        } else
    722757                drawBits(vs, dst, mask, drawTop, width, height);
    723758
     759        if (_blitAlso) {
    724760                int h = height;
    725761                do {
    726762                        memcpy(back, dst, width);
    727763                        back += _vm->_screenWidth;
    728764                        dst += _vm->_screenWidth;
    729765                } while (--h);
    730         } else {
    731                 drawBits(vs, dst, mask, drawTop, width, height);
    732766        }
    733767       
    734768        _left += width;
     
    752786        bits = *_charPtr++;
    753787        numbits = 8;
    754788
    755         y = 0;
    756 
    757789        for (y = 0; y < height && y + drawTop < vs->height; y++) {
    758790                maskmask = revBitMask[_left & 7];
    759791                maskpos = 0;
     
    785817        }
    786818}
    787819
     820void CharsetRendererClassic::draw2byte(VirtScreen *vs, byte *dst, byte *mask, int drawTop, int width, int height) {
     821        byte maskmask;
     822        int y, x;
     823        int maskpos;
     824        //int color;
     825        byte numbits, bits;
     826        bool useMask = (vs->number == 0 && !_ignoreCharsetMask);
     827
     828        bits = *_charPtr++;
     829        numbits = 8;
     830
     831        for (y = 0; y < height && y + drawTop < vs->height; y++) {
     832                maskmask = revBitMask[_left & 7];
     833                maskpos = 0;
     834
     835                for (x = 0; x < width; x++) {
     836                        if(x && ((x % 8) == 0))
     837                                bits = *_charPtr++;
     838                        if (bits & revBitMask[x % 8]) {
     839                                *(dst + x + 1) = _vm->_charsetColorMap[0];
     840                                *(dst + x    ) = _vm->_charsetColorMap[1]; //FIXME?
     841                                if (useMask) {
     842                                        mask[maskpos] |= maskmask;
     843                                        if (maskmask == 1) {
     844                                                mask[maskpos + 1] |= 0x80;
     845                                        } else {
     846                                                mask[maskpos] |= (maskmask >> 1);
     847                                        }
     848                                }
     849                        }
     850                        maskmask >>= 1;
     851                        if (maskmask == 0) {
     852                                maskmask = 0x80;
     853                                maskpos++;
     854                        }
     855                }
     856
     857                bits = *_charPtr++;
     858                dst += _vm->_screenWidth;
     859                mask += _vm->gdi._numStrips;
     860        }
     861}
     862
    788863CharsetRendererNut::CharsetRendererNut(Scumm *vm)
    789864         : CharsetRenderer(vm) {
    790865        _current = 0;
     
    839914        int width = _current->getCharWidth(chr);
    840915        int height = _current->getCharHeight(chr);
    841916
     917        if(chr >= 256 && _CJKMode)
     918                width = 16;
     919
    842920        _hasMask = true;
    843         _current->drawChar((char)chr, _left, _top, _color, !_ignoreCharsetMask);
     921        if(chr >= 256 && _CJKMode)
     922                _current->draw2byte(chr, _left, _top + (_2byte_pos_hack ? 6 : 0), _color, !_ignoreCharsetMask);
     923        else
     924                _current->drawChar((char)chr, _left, _top, _color, !_ignoreCharsetMask);
    844925        _vm->updateDirtyRect(0, _left, _left + width, _top, _top + height, 0);
    845926
    846927        _left += width;
     
    849930
    850931        if (_top + height > _str.bottom)
    851932                _str.bottom = _top + height;
     933
     934        _2byte_pos_hack = false;
    852935}
    853936
  • scumm/charset.h

    RCS file: /cvsroot/scummvm/scummvm/scumm/charset.h,v
    retrieving revision 2.17
    diff -u -r2.17 charset.h
     
    9090        byte *_charPtr;
    9191
    9292        int getCharWidth(byte chr);
     93        void draw2byte(VirtScreen *vs, byte *dst, byte *mask, int drawTop, int width, int height);
    9394        void drawBits(VirtScreen *vs, byte *dst, byte *mask, int drawTop, int width, int height);
    9495
    9596public:
  • scumm/nut_renderer.cpp

    RCS file: /cvsroot/scummvm/scummvm/scumm/nut_renderer.cpp,v
    retrieving revision 1.25
    diff -u -r1.25 nut_renderer.cpp
     
    2222#include "scumm.h"
    2323#include "nut_renderer.h"
    2424
     25extern int get2byteIndex(int idx);
     26
     27
    2528NutRenderer::NutRenderer(Scumm *vm) {
    2629        _vm = vm;
    2730        _initialized = false;
     
    133136                return 0;
    134137        }
    135138
    136         return READ_LE_UINT16(_dataSrc + _offsets[c] + 6);
     139        if(c & 0x80 && _CJKMode)
     140                return 8;
     141        else
     142                return READ_LE_UINT16(_dataSrc + _offsets[c] + 6) + 2;
    137143}
    138144
    139145int32 NutRenderer::getCharHeight(byte c) {
     
    143149                return 0;
    144150        }
    145151
    146         return READ_LE_UINT16(_dataSrc + _offsets[c] + 8);
     152        if(c & 0x80 && _CJKMode)
     153                return 16;
     154        else
     155                return READ_LE_UINT16(_dataSrc + _offsets[c] + 8);
    147156}
    148157
    149158int32 NutRenderer::getStringWidth(const byte *string) {
     
    237246       
    238247                x -= offsetX[i];
    239248                y -= offsetY[i];
     249        }
     250}
     251
     252void NutRenderer::draw2byte(int c, int32 x, int32 y, byte color, bool useMask) {
     253        if (_loaded == false) {
     254                debug(2, "NutRenderer::draw2byte() Font is not loaded");
     255                return;
     256        }
     257
     258        int _2byteIndex = get2byteIndex(c);
     259        int width = _2byte_width;
     260        int height = _2byte_height;
     261        char *_2bPtr = &_2byte[_2byteIndex * (_2byte_height * 2)];
     262
     263        byte *dst, *mask = NULL;
     264        byte maskmask;
     265        int maskpos;
     266       
     267        dst = _vm->virtscr[0].screenPtr + y * _vm->_screenWidth + x + _vm->virtscr[0].xstart;
     268        mask = _vm->getResourceAddress(rtBuffer, 9)
     269                                        + (y * _vm->_screenWidth + x) / 8 + _vm->_screenStartStrip;
     270
     271        for (int ty = 0; ty < height; ty++) {
     272                maskmask = revBitMask[x & 7];
     273                maskpos = 0;
     274                for (int tx = 0; tx < width; tx++) {
     275                        if (x + tx < 0 || x + tx >= _vm->_screenWidth || y + ty < 0 || y + ty >= _vm->_screenHeight)
     276                                continue;
     277                        if(tx && ((tx % 8) == 0))
     278                                _2bPtr++;
     279                        if (*_2bPtr & revBitMask[tx % 8]) {
     280                                *(dst + tx + 1) = 0;
     281                                *(dst + tx) = color;
     282                                if (useMask) {
     283                                        mask[maskpos] |= maskmask;
     284                                        if (maskmask == 1) {
     285                                                mask[maskpos + 1] |= 0x80;
     286                                        } else {
     287                                                mask[maskpos] |= (maskmask >> 1);
     288                                        }
     289                                }
     290                        }
     291
     292                        maskmask >>= 1;
     293                        if (maskmask == 0) {
     294                                maskmask = 0x80;
     295                                maskpos++;
     296                        }
     297                }
     298
     299                _2bPtr++;
     300                dst += _vm->_screenWidth;
     301                mask += _vm->gdi._numStrips;
    240302        }
    241303}
  • scumm/nut_renderer.h

    RCS file: /cvsroot/scummvm/scummvm/scumm/nut_renderer.h,v
    retrieving revision 1.7
    diff -u -r1.7 nut_renderer.h
     
    4141        ~NutRenderer();
    4242
    4343        bool loadFont(const char *filename, const char *dir);
     44        void draw2byte(int c, int32 x, int32 y, byte color, bool useMask);
    4445        void drawChar(byte c, int32 x, int32 y, byte color, bool useMask);
    4546//      void drawString(const char *string, int32 x, int32 y, byte color, int32 mode);
    4647        int32 getCharWidth(byte c);
  • scumm/scumm.h

    RCS file: /cvsroot/scummvm/scummvm/scumm/scumm.h,v
    retrieving revision 1.238
    diff -u -r1.238 scumm.h
     
    10641064
    10651065        void loadLanguageBundle();
    10661066public:
     1067        bool checkCJKLanguage();
    10671068        void translateText(const byte *text, byte *trans_buff); // Used by class ScummDialog
    10681069protected:
    10691070
     
    11971198
    11981199// This is a constant lookup table of reverse bit masks
    11991200extern const byte revBitMask[8];
     1201
     1202//nasty hacks
     1203extern bool _CJKMode;
     1204extern int _gid;
     1205extern char *_2byte;
     1206extern int _2byte_height;
     1207extern int _2byte_width;
     1208extern bool _2byte_pos_hack;
    12001209
    12011210/* Direction conversion functions (between old dir and new dir format) */
    12021211int newDirToOldDir(int dir);
  • scumm/scummvm.cpp

    RCS file: /cvsroot/scummvm/scummvm/scumm/scummvm.cpp,v
    retrieving revision 2.204
    diff -u -r2.204 scummvm.cpp
     
    5656Scumm *g_scumm = 0;
    5757ScummDebugger *g_debugger;
    5858
     59int _gid;
     60char *_2byte;
     61int _2byte_width;
     62int _2byte_height;
     63bool _CJKMode;
     64
    5965extern NewGui *g_gui;
    6066extern uint16 _debugLevel;
    6167
     
    636642                _saveLoadCompatible = false;
    637643        }
    638644        loadLanguageBundle();
     645
     646        // Load CJK font
     647        if((_gameId == GID_DIG || _gameId == GID_CMI) && checkCJKLanguage()) {
     648                _gid = _gameId;
     649                File fp;
     650                const char *fontFile = NULL;
     651                _CJKMode = false;
     652                switch(_language) {
     653                case KO_KOR:
     654                        _CJKMode = true;
     655                        fontFile = "korean.fnt";
     656                        break;
     657                case JA_JPN:
     658                        _CJKMode = true;
     659                        fontFile = (_gameId == GID_DIG) ? "kanji16.fnt" : "japanese.fnt";
     660                        break;
     661                case ZH_TWN:
     662                        if(_gameId == GID_CMI) {
     663                                _CJKMode = true;
     664                                fontFile = "chinese.fnt";
     665                        }
     666                        break;
     667                }
     668                if(_CJKMode && fp.open(fontFile, getGameDataPath(), 1)) {
     669                        debug(2, "Loading CJK Font");
     670                        fp.seek(2,SEEK_CUR);
     671                        _2byte_width = fp.readByte(); //FIXME: is this correct?
     672                        _2byte_height = fp.readByte();
     673
     674                        int numChar = 0;
     675                        switch(_language) {
     676                        case KO_KOR:
     677                                numChar = 2350;
     678                                break;
     679                        case JA_JPN:
     680                                numChar = (_gameId == GID_DIG) ? 1 : 1; //FIXME
     681                                break;
     682                        case ZH_TWN:
     683                                numChar = 1; //FIXME
     684                                break;
     685                        }
     686                        _2byte = new char[2 * _2byte_height * numChar];
     687                        fp.read(_2byte, 2 * _2byte_height * numChar);
     688                        fp.close();
     689                }
     690        }
     691
    639692        _audioNames = NULL;
    640693}
    641694
     
    643696{
    644697        delete [] _actors;
    645698       
     699        delete _2byte;
    646700        delete _charset;
    647701        delete _pauseDialog;
    648702        delete _optionsDialog;
  • scumm/string.cpp

    RCS file: /cvsroot/scummvm/scummvm/scumm/string.cpp,v
    retrieving revision 1.130
    diff -u -r1.130 string.cpp
     
    242242                if (c != 0xFF) {
    243243                        _charset->_left = _charset->_nextLeft;
    244244                        _charset->_top = _charset->_nextTop;
     245                        if(c & 0x80 && _CJKMode) {
     246                                c += *buffer++ * 256;
     247                                if(_gameId == GID_CMI)
     248                                        _2byte_pos_hack = true; //HACK: ¿µ¹®°úÀÇ yÁÂÇ¥°¡ ¸ÂÁö ¾Ê´Ù.
     249                        }
    245250                        if (_features & GF_AFTER_V2 || _features & GF_AFTER_V3) {
    246251                                _charset->printChar(c);
    247252                        } else if (_features & GF_AFTER_V6) {
     
    429434                                if (_string[a].no_talk_anim == 0)
    430435                                        _charset->_blitAlso = true;
    431436                        }
    432                         _charset->printChar(chr);
     437                        if(chr >= 0x80 && _CJKMode) {
     438                                if(_gameId == GID_CMI)
     439                                        _2byte_pos_hack = true;
     440                                _charset->printChar(chr + (buf[i++] * 256));
     441                        }
     442                        else
     443                                _charset->printChar(chr);
    433444                        _charset->_blitAlso = false;
    434445                }
    435446        }
     
    731742                        if (c != 0 && c != 0xFF) {
    732743                                _charset->_left = _charset->_nextLeft;
    733744                                _charset->_top = _charset->_nextTop;
    734                                 _charset->printChar(c);
     745                                if(c >= 0x80 && _CJKMode)
     746                                        _charset->printChar(c + (*buf++ * 256));
     747                                else
     748                                        _charset->printChar(c);
    735749                                _charset->_nextLeft = _charset->_left;
    736750                                _charset->_nextTop = _charset->_top;
    737751                        }
  • scumm/smush/smush_font.cpp

    RCS file: /cvsroot/scummvm/scummvm/scumm/smush/smush_font.cpp,v
    retrieving revision 1.2
    diff -u -r1.2 smush_font.cpp
     
    2727
    2828#include "smush_font.h"
    2929
     30extern int get2byteIndex(int idx);
     31
    3032SmushFont::SmushFont(bool use_original_colors, bool new_colors) :
    3133        _nbChars(0),
    3234        _color(-1),
     
    105107}
    106108
    107109int SmushFont::getCharWidth(byte v) {
     110        if(v >= 0x80 && _CJKMode)
     111                return get2byteCharWidth();
     112
    108113        if(v >= _nbChars)
    109114                error("invalid character in SmushFont::charWidth : %d (%d)", v, _nbChars);
    110115
     
    112117}
    113118
    114119int SmushFont::getCharHeight(byte v) {
     120        if(v >= 0x80 && _CJKMode)
     121                return get2byteCharHeight();
     122
    115123        if(v >= _nbChars)
    116124                error("invalid character in SmushFont::charHeight : %d (%d)", v, _nbChars);
    117125
     
    219227        return w;
    220228}
    221229
     230int SmushFont::get2byteCharWidth() {
     231        if(_gid == GID_CMI)
     232                return 8;
     233        if(_gid == GID_DIG)
     234                return 6;
     235        return 0;
     236}
     237int SmushFont::get2byteCharHeight() {
     238        if(_gid == GID_CMI)
     239                return 16;
     240        if(_gid == GID_DIG)
     241                return 10;
     242        return 0;
     243}
     244
     245int SmushFont::draw2byte(byte *buffer, int dst_width, int x, int y, byte fst, byte snd) {
     246        int w = _2byte_width;
     247        int h = _2byte_height;
     248
     249        int _2byteIndex = get2byteIndex(fst + (snd * 256));
     250        char *_2bytePtr = &_2byte[_2byteIndex * (_2byte_height * 2)];
     251        char *pData = _2bytePtr;
     252        byte *dst = buffer + dst_width * (y + (_gid == GID_CMI ? 7 : 2)) + x;
     253
     254        if(_original) {
     255                for(int32 j = 0; j < h; j++) {
     256                        for(int32 i = 0; i < w; i++) {
     257                                char value = 1;//*src++;
     258                                if(value) dst[i] = value;
     259                        }
     260                        dst += dst_width;
     261                }
     262        } else {
     263                char color = (_color != -1) ? _color : 1;
     264                if (_new_colors == true) {
     265                        for(int j = 0; j < h; j++) {
     266                                for(int i = 0; i < w; i++) {
     267                                        if(i && ((i % 8) == 0))
     268                                                pData++;
     269                                        if (*pData & revBitMask[i % 8]) {
     270                                                dst[i + 1] = 0;
     271                                                dst[i] = 0xff; //FIXME
     272                                        }
     273                                }
     274                                pData++;
     275                                dst += dst_width;
     276                        }
     277                } else {
     278                        for(int j = 0; j < h; j++) {
     279                                for(int i = 0; i < w; i++) {
     280                                        if(i && ((i % 8) == 0))
     281                                                pData++;
     282                                        if (*pData & revBitMask[i % 8]) {
     283                                                dst[i + 1] = 0;
     284                                                dst[i] = color;
     285                                        }
     286                                }
     287                                pData++;
     288                                dst += dst_width;
     289                        }
     290                }
     291        }
     292        return w + 1;
     293}
     294
    222295static char **split(char *str, char sep) {
    223296        char **ret = new char *[62];
    224297        int n = 0;
     
    243316}
    244317
    245318void SmushFont::drawSubstring(char *str, byte *buffer, int dst_width, int x, int y) {
    246         for(int i = 0; str[i] != 0; i++)
    247                 x += drawChar(buffer, dst_width, x, y, str[i]);
     319        for(int i = 0; str[i] != 0; i++) {
     320                if((byte)str[i] >= 0x80 && _CJKMode) {
     321                        x += draw2byte(buffer, dst_width, x, y, str[i], str[i+1]);
     322                        i++;
     323                } else
     324                        x += drawChar(buffer, dst_width, x, y, str[i]);
     325        }
    248326}
    249327
    250328void SmushFont::drawStringAbsolute(char *str, byte *buffer, int dst_width, int x, int y) {
  • scumm/smush/smush_font.h

    RCS file: /cvsroot/scummvm/scummvm/scumm/smush/smush_font.h,v
    retrieving revision 1.2
    diff -u -r1.2 smush_font.h
     
    4646
    4747protected:
    4848
     49        int get2byteCharWidth();
     50        int get2byteCharHeight();
    4951        int getCharWidth(byte c);
    5052        int getStringWidth(char *str);
    5153        int getCharHeight(byte c);
    5254        int getStringHeight(char *str);
     55        int draw2byte(byte *buffer, int dst_width, int x, int y, byte fst, byte snd);
    5356        int drawChar(byte *buffer, int dst_width, int x, int y, byte chr);
    5457        void drawSubstring(char *str, byte *buffer, int dst_width, int x, int y);
    5558        void decodeCodec(byte *dst, byte *src, int length);