zoukankan      html  css  js  c++  java
  • 让vcmi支持英雄无敌3中文版

    Table of Contents

    1 Hack 日志

    • 8月22日开始动手修改改vcmi(英雄无敌3的开源游戏引擎)的源码, 让它支持简体中文版的游戏数据。
    • 8月25日,已经有一个可工作的修改版,但自己不满意。这个版本的原理是每次要显 示文本的时候,都用自己写的编码转换函数将字符串从GBK编码转为UTF8编码,从而 能正常地显示中文。但每次显式都转换,每秒游戏要10帧以上,每帧要显示的字符串 可以多达数十个,这样每秒要做数百次字符串转换,效率很低。虽然这样的计算量对 现代CPU来说不算啥,但心里觉得别扭。高效的做法应该是将游戏数据中的GBK编码的 字符串载入内存的时候只做一次编码转换,转换为UTF8编码。
    • 这时开始置疑PC游戏相关工作的意义,所以工作中断了。
    • 中断一个月后,觉得开始的事情没做完,心里别扭,就决定来个收场。于是9月27号, 开始做一个高效的修改。9月28日算大功告成。这个事可以告一段落了。

    以下是对源码所做的修改,和怎么编译安装,当时用英文做的记录,懒得再翻译回中文了。

    2 Changes

    1. client/CMessage.cpp

      in function CMessage::breakText(), line 153

                  // added by jiqingwu@gmail.com, 2013-08-28
                  // If the text[z] is less than 0, it is the first byte of a UTF8 Chinese word.
      #ifdef ZH_CN
                  else if (text[z] < 0){
                      z++;
                      z++;
                   lineLength += graphics->fonts[font]->getSymbolWidth(text[z]);
                  }
      #endif
      
    2. client/gui/Fonts.cpp

      in function CTrueTypeFont::getStringWidth(), line 255

          // added by jiqingwu@gmail.com, 2013-08-28
          // If we are handling simplified chinese, it is a UTF8 string
      #ifdef ZH_CN
          TTF_SizeUTF8(font.get(), data.c_str(), &width, NULL);
      #else
          TTF_SizeText(font.get(), data.c_str(), &width, NULL);
      #endif
      

      in function CTrueTypeFont::renderText(), line 279

           if (blended)
                  // added by jiqingwu@gmail.com, 2013-09-28 Sat
                  // If we are handling simplified chinese game data, it is a UTF8 string
      #ifdef ZH_CN
               rendered = TTF_RenderUTF8_Blended(font.get(), data.c_str(), color);
      #else
               rendered = TTF_RenderText_Blended(font.get(), data.c_str(), color);
      #endif
           else
                  // added by jiqingwu@gmail.com, 2013-09-28 Sat
                  // If we are handling simplified chinese game data, it is a UTF8 string
      #ifdef ZH_CN
               rendered = TTF_RenderUTF8_Solid(font.get(), data.c_str(), color);
      #else
               rendered = TTF_RenderText_Solid(font.get(), data.c_str(), color);
      #endif
      
    3. add lib/ConvertEncoding.cpp and lib/ConvertEncoding.h

      The content of ConvertEncoding.h is:

      char * convert_enc(char *src_enc, char *dest_enc, const char * src_string);
      

      The content of ConvertEncoding.cpp is:

      /*
       * ConvertEncoding.cpp, for vcmi using CJK(China/Japan/Korea) data.
       *
       * Authors: Wu Jiqing (jiqingwu@gmail.com)
       *
       * License: GNU General Public License v2.0 or later
       *
       */
      // added by jiqingwu(jiqingwu@gmail.com)
      // 2013-09-27 Fri
      #include <stdio.h>
      #include <iconv.h>
      #include <string.h>
      
      // added by jiqingwu@gmail.com, 2013-09-27 Fri
      char * convert_enc(char *src_enc, char *dest_enc, const char * src_string)
      {
      #define UTF8_STR_LEN 5000
      
          static char out_string[UTF8_STR_LEN], *sin, *sout;
          int  in_len, out_len, ret;
          iconv_t c_pt;
      
          if ((c_pt = iconv_open(dest_enc, src_enc)) == (iconv_t)-1)
          {
              printf("iconv open failed!
      ");
              return NULL;
          }
          // iconv(c_pt, NULL, NULL, NULL, NULL);
          in_len  = strlen(src_string) + 1;
          out_len = UTF8_STR_LEN;
          sin = (char *)src_string;
          sout = out_string;
          ret = iconv(c_pt, &sin, (size_t *)&in_len, &sout, (size_t *)&out_len);
          if (ret == -1)
          {
              return NULL;
          }
          iconv_close(c_pt);
          return out_string;
      }
      

      to link ConvertEncoding.o into library, add two lines into lib/CMakeLists.txt:

      set(lib_SRCS
              ...
              ConvertEncoding.cpp
      )
      
      set(lib_HEADERS
              ...
              ConvertEncoding.h
      )
      
    4. lib/CGeneralTextHandler.cpp,

      To include "ConvertEncoding.h"

      // added by jiqingwu(jiqingwu@gmail.com)
      // 2013-09-27 Fri
      #include "ConvertEncoding.h"
      

      in function CLegacyConfigParser::readString(), line 112

          // added by jiqingwu@gmail.com, 2013-09-27 Fri
          // convert gbk string to utf-8 string.
          // (For simplified Chinese game data, the string is GBK encoded)
      #ifdef ZH_CN
          char * utf8_str = convert_enc("GBK", "UTF8", ret.c_str());
          return std::string((const char*)utf8_str);
      #else
          return ret;
      #endif
      
    5. lib/filesystem/CBinaryReader.cpp,

      to include "ConvertEncoding.h":

      // added by <jiqingwu@gmail.com>, 2013-09-28 Sat
      #include "../ConvertEncoding.h"
      

      in function CBinaryReader::readString(), line 95

          // added by jiqingwu@gmail.com, 2013-08-22
          // If we are handling chinese data, convert gbk string to utf-8 string.
      #ifdef ZH_CN
          char * utf8_str = convert_enc("GBK", "UTF8", ret.c_str());
          return std::string((const char*)utf8_str);
      #else
          return ret;
      #endif
      

    3 Install by compiling

    1. add such a line into ./CMakeLists.txt to enable supporting Simplifed Chinese Game Data
      add_definitions(-DZH_CN)
      
    2. make a directory build under the source dir
      mkdir build
      
    3. create makefiles
      cd build
      cmake ..
      

      This may take a short while.

    4. compile
      make
      
    5. install (root privilege is needed)
      make install
      

      Check the directories of vcmi

      vcmiclient -v
      

      You will see the result like this:

      Starting... 
      VCMI 0.93
        data directory:    /usr/local/share/vcmi
        library directory: /usr/local/lib/vcmi
        path to server:    /usr/local/bin/vcmiserver
      

      Here, vcmi is installed under /usr/local

    6. Use the Data from the chinese version of Death of Shadow. Link the 'Data', 'Maps', 'Mp3' directories under /usr/local/share/vcmi like this (You need have root privilege):
      cd /usr/local/share/vcmi
      ln -s /Data/Dir/of/ChineseGame Data
      ln -s /Maps/Dir/of/ChineseGame Maps
      ln -s /Mp3/Dir/of/ChineseGame Mp3
      
    7. To show chinese characters in this game, you need put a true type font which supports Chinese into /usr/local/share/vcmi/Data.
      cp /chinese/font/path /usr/local/share/vcmi/Data
      

      Edit the /usr/local/share/vcmi/config/fonts.json, modify the truetype font section like this:

      "trueType":
      {
          "BIGFONT"  : { "file" : "ChineseFont.ttf", "size" : 22, "blend" : true},
          "CALLI10R" : { "file" : "ChineseFont.ttf", "size" : 10, "blend" : true},
          "CREDITS"  : { "file" : "ChineseFont.ttf", "size" : 28, "blend" : true},
          "HISCORE"  : { "file" : "ChineseFont.ttf", "size" : 13, "blend" : true},
          "MEDFONT"  : { "file" : "ChineseFont.ttf", "size" : 16, "blend" : true},
          "SMALFONT" : { "file" : "ChineseFont.ttf", "size" : 13, "blend" : true},
          "TIMES08R" : { "file" : "ChineseFont.ttf", "size" : 11, "blend" : true},
          "TINY"     : { "file" : "ChineseFont.ttf", "size" : 11, "blend" : true},
          "VERD10B"  : { "file" : "ChineseFont.ttf", "size" : 13, "blend" : true}
      }
      

      Where ChineseFont.ttf is your true type font.

    8. Play Game
      vcmiclient
      

    4 reply of Ivan

    (0004091) Ivan (developer) - 2013-10-20 13:09
    http://bugs.vcmi.eu/view.php?id=1420#c4091
    ----------------------------------------------------------------------
    Thanks. I'll take a look on this. I don't like idea of using ifdef's to enable
    some functionality but you've tracked every place that needs changes - that will
    help.
    

    Date: 2013-10-21T19:48+0800

    Author: Jiqing Wu

    Org version 7.9.3f with Emacs version 24

    Validate XHTML 1.0
  • 相关阅读:
    CentOS7 安装Docker 18.09.5
    CentOS7 安装Jenkins 2.164.2
    Python3从零开始爬取今日头条的新闻【一、开发环境搭建】
    Win10 安装Oracle11g2、配置PL/SQL Developer11环境
    IDEA 使用Mybatis效率飞起来的必备工具:MybatisCodeHelperPro 最新破解版,亲测可用!
    Navicat Premium 12 (64位)实现连接Oracle 11 (64位)
    VMware14 安装CentOS7 实现宿主机ping通虚拟机、虚拟机ping通宿主机、虚拟机能上网且能ping通百度
    Java中util.Date通过mybatis向数据库中datetime的操作!
    Java中try-catch-finally语句中return的执行顺序总结
    java中this用法总结
  • 原文地址:https://www.cnblogs.com/jiqingwu/p/let_vcmi_support_chinese.html
Copyright © 2011-2022 走看看