Ticket #8240: 2byte_charset.2.diff
File 2byte_charset.2.diff, 16.0 KB (added by , 21 years ago) |
---|
-
scumm/charset.cpp
RCS file: /cvsroot/scummvm/scummvm/scumm/charset.cpp,v retrieving revision 2.38 diff -u -r2.38 charset.cpp
23 23 #include "scumm.h" 24 24 #include "nut_renderer.h" 25 25 26 bool _2byte_pos_hack; 27 28 int 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 42 bool Scumm::checkCJKLanguage() 43 { 44 return (_language == KO_KOR || _language == JA_JPN || _language == ZH_TWN); 45 } 46 26 47 CharsetRenderer::CharsetRenderer(Scumm *vm) { 27 48 28 49 _nextLeft = 0; … … 79 100 80 101 // do spacing for variable width old-style font 81 102 int CharsetRendererClassic::getCharWidth(byte chr) { 103 if(chr >= 0x80 && _CJKMode) 104 return 6; 82 105 int spacing = 0; 83 106 84 107 int offs = READ_LE_UINT32(_fontPtr + chr * 4 + 4); … … 628 651 int offsX, offsY; 629 652 int d; 630 653 VirtScreen *vs; 654 int is2byte = 0; 631 655 632 656 _vm->checkRange(_vm->_maxCharsets - 1, 1, _curId, "Printing with bad charset %d"); 633 657 … … 640 664 _bpp = *_fontPtr; 641 665 _vm->_charsetColorMap[1] = _color; 642 666 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! 644 670 645 671 if (!charOffs) 646 672 return; … … 649 675 650 676 _charPtr = _fontPtr + charOffs; 651 677 652 width = _charPtr[0];678 if(is2byte) width = _charPtr[0] - 1; else width = _charPtr[0]; //HACK!!! 653 679 height = _charPtr[1]; 654 680 if (_firstChar) { 655 681 _str.left = 0; … … 714 740 byte *mask = _vm->getMaskBuffer(_left, drawTop, 0); 715 741 byte *dst = vs->screenPtr + vs->xstart + drawTop * _vm->_screenWidth + _left; 716 742 743 byte *back = dst; 717 744 if (_blitAlso) { 718 byte *back = dst;719 745 dst = _vm->getResourceAddress(rtBuffer, vs->number + 5) 720 746 + vs->xstart + drawTop * _vm->_screenWidth + _left; 747 } 721 748 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 722 757 drawBits(vs, dst, mask, drawTop, width, height); 723 758 759 if (_blitAlso) { 724 760 int h = height; 725 761 do { 726 762 memcpy(back, dst, width); 727 763 back += _vm->_screenWidth; 728 764 dst += _vm->_screenWidth; 729 765 } while (--h); 730 } else {731 drawBits(vs, dst, mask, drawTop, width, height);732 766 } 733 767 734 768 _left += width; … … 752 786 bits = *_charPtr++; 753 787 numbits = 8; 754 788 755 y = 0;756 757 789 for (y = 0; y < height && y + drawTop < vs->height; y++) { 758 790 maskmask = revBitMask[_left & 7]; 759 791 maskpos = 0; … … 785 817 } 786 818 } 787 819 820 void 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 788 863 CharsetRendererNut::CharsetRendererNut(Scumm *vm) 789 864 : CharsetRenderer(vm) { 790 865 _current = 0; … … 839 914 int width = _current->getCharWidth(chr); 840 915 int height = _current->getCharHeight(chr); 841 916 917 if(chr >= 256 && _CJKMode) 918 width = 16; 919 842 920 _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); 844 925 _vm->updateDirtyRect(0, _left, _left + width, _top, _top + height, 0); 845 926 846 927 _left += width; … … 849 930 850 931 if (_top + height > _str.bottom) 851 932 _str.bottom = _top + height; 933 934 _2byte_pos_hack = false; 852 935 } 853 936 -
scumm/charset.h
RCS file: /cvsroot/scummvm/scummvm/scumm/charset.h,v retrieving revision 2.17 diff -u -r2.17 charset.h
90 90 byte *_charPtr; 91 91 92 92 int getCharWidth(byte chr); 93 void draw2byte(VirtScreen *vs, byte *dst, byte *mask, int drawTop, int width, int height); 93 94 void drawBits(VirtScreen *vs, byte *dst, byte *mask, int drawTop, int width, int height); 94 95 95 96 public: -
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
22 22 #include "scumm.h" 23 23 #include "nut_renderer.h" 24 24 25 extern int get2byteIndex(int idx); 26 27 25 28 NutRenderer::NutRenderer(Scumm *vm) { 26 29 _vm = vm; 27 30 _initialized = false; … … 133 136 return 0; 134 137 } 135 138 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; 137 143 } 138 144 139 145 int32 NutRenderer::getCharHeight(byte c) { … … 143 149 return 0; 144 150 } 145 151 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); 147 156 } 148 157 149 158 int32 NutRenderer::getStringWidth(const byte *string) { … … 237 246 238 247 x -= offsetX[i]; 239 248 y -= offsetY[i]; 249 } 250 } 251 252 void 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; 240 302 } 241 303 } -
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
41 41 ~NutRenderer(); 42 42 43 43 bool loadFont(const char *filename, const char *dir); 44 void draw2byte(int c, int32 x, int32 y, byte color, bool useMask); 44 45 void drawChar(byte c, int32 x, int32 y, byte color, bool useMask); 45 46 // void drawString(const char *string, int32 x, int32 y, byte color, int32 mode); 46 47 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
1064 1064 1065 1065 void loadLanguageBundle(); 1066 1066 public: 1067 bool checkCJKLanguage(); 1067 1068 void translateText(const byte *text, byte *trans_buff); // Used by class ScummDialog 1068 1069 protected: 1069 1070 … … 1197 1198 1198 1199 // This is a constant lookup table of reverse bit masks 1199 1200 extern const byte revBitMask[8]; 1201 1202 //nasty hacks 1203 extern bool _CJKMode; 1204 extern int _gid; 1205 extern char *_2byte; 1206 extern int _2byte_height; 1207 extern int _2byte_width; 1208 extern bool _2byte_pos_hack; 1200 1209 1201 1210 /* Direction conversion functions (between old dir and new dir format) */ 1202 1211 int 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
56 56 Scumm *g_scumm = 0; 57 57 ScummDebugger *g_debugger; 58 58 59 int _gid; 60 char *_2byte; 61 int _2byte_width; 62 int _2byte_height; 63 bool _CJKMode; 64 59 65 extern NewGui *g_gui; 60 66 extern uint16 _debugLevel; 61 67 … … 636 642 _saveLoadCompatible = false; 637 643 } 638 644 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 639 692 _audioNames = NULL; 640 693 } 641 694 … … 643 696 { 644 697 delete [] _actors; 645 698 699 delete _2byte; 646 700 delete _charset; 647 701 delete _pauseDialog; 648 702 delete _optionsDialog; -
scumm/string.cpp
RCS file: /cvsroot/scummvm/scummvm/scumm/string.cpp,v retrieving revision 1.130 diff -u -r1.130 string.cpp
242 242 if (c != 0xFF) { 243 243 _charset->_left = _charset->_nextLeft; 244 244 _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 } 245 250 if (_features & GF_AFTER_V2 || _features & GF_AFTER_V3) { 246 251 _charset->printChar(c); 247 252 } else if (_features & GF_AFTER_V6) { … … 429 434 if (_string[a].no_talk_anim == 0) 430 435 _charset->_blitAlso = true; 431 436 } 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); 433 444 _charset->_blitAlso = false; 434 445 } 435 446 } … … 731 742 if (c != 0 && c != 0xFF) { 732 743 _charset->_left = _charset->_nextLeft; 733 744 _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); 735 749 _charset->_nextLeft = _charset->_left; 736 750 _charset->_nextTop = _charset->_top; 737 751 } -
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
27 27 28 28 #include "smush_font.h" 29 29 30 extern int get2byteIndex(int idx); 31 30 32 SmushFont::SmushFont(bool use_original_colors, bool new_colors) : 31 33 _nbChars(0), 32 34 _color(-1), … … 105 107 } 106 108 107 109 int SmushFont::getCharWidth(byte v) { 110 if(v >= 0x80 && _CJKMode) 111 return get2byteCharWidth(); 112 108 113 if(v >= _nbChars) 109 114 error("invalid character in SmushFont::charWidth : %d (%d)", v, _nbChars); 110 115 … … 112 117 } 113 118 114 119 int SmushFont::getCharHeight(byte v) { 120 if(v >= 0x80 && _CJKMode) 121 return get2byteCharHeight(); 122 115 123 if(v >= _nbChars) 116 124 error("invalid character in SmushFont::charHeight : %d (%d)", v, _nbChars); 117 125 … … 219 227 return w; 220 228 } 221 229 230 int SmushFont::get2byteCharWidth() { 231 if(_gid == GID_CMI) 232 return 8; 233 if(_gid == GID_DIG) 234 return 6; 235 return 0; 236 } 237 int SmushFont::get2byteCharHeight() { 238 if(_gid == GID_CMI) 239 return 16; 240 if(_gid == GID_DIG) 241 return 10; 242 return 0; 243 } 244 245 int 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 222 295 static char **split(char *str, char sep) { 223 296 char **ret = new char *[62]; 224 297 int n = 0; … … 243 316 } 244 317 245 318 void 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 } 248 326 } 249 327 250 328 void 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
46 46 47 47 protected: 48 48 49 int get2byteCharWidth(); 50 int get2byteCharHeight(); 49 51 int getCharWidth(byte c); 50 52 int getStringWidth(char *str); 51 53 int getCharHeight(byte c); 52 54 int getStringHeight(char *str); 55 int draw2byte(byte *buffer, int dst_width, int x, int y, byte fst, byte snd); 53 56 int drawChar(byte *buffer, int dst_width, int x, int y, byte chr); 54 57 void drawSubstring(char *str, byte *buffer, int dst_width, int x, int y); 55 58 void decodeCodec(byte *dst, byte *src, int length);