让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 [email protected], 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 [email protected], 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 [email protected], 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 [email protected], 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 ([email protected])
     *
     * License: GNU General Public License v2.0 or later
     *
     */
    // added by jiqingwu([email protected])
    // 2013-09-27 Fri
    #include <stdio.h>
    #include <iconv.h>
    #include <string.h>
    
    // added by [email protected], 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!\n");
            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([email protected])
    // 2013-09-27 Fri
    #include "ConvertEncoding.h"
    

    in function CLegacyConfigParser::readString(), line 112

        // added by [email protected], 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 <[email protected]>, 2013-09-28 Sat
    #include "../ConvertEncoding.h"
    

    in function CBinaryReader::readString(), line 95

        // added by [email protected], 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

http://www.cnblogs.com/jiqingwu/p/let_vcmi_support_chinese.html

时间: 2025-01-12 12:58:07

让vcmi支持英雄无敌3中文版的相关文章

vcmi(魔法门英雄无敌3 - 开源复刻版) 源码编译

1 准备 HoMM3 gog.com CMake 官网 vcmi 源码 下载 QT5 with mingw 官网 Boost 源码1.55 下载 MSYS2 官网 2 安装 2.1 vcmi源码 目标路径 D:/vcmi/source/ 2.2 QT5 with mingw, 设置环境变量 set PATH=D:\Qt\Qt5.4.1\5.4\mingw491_32\bin;D:\Qt\Qt5.4.1\Tools\mingw491_32\bin;%PATH% 2.3 Boost 1.55 boo

英雄无敌3开源引擎vcmi的编译安装

vcmi是什么? vcmi 是经典的 SLG 英雄无敌3 的开源游戏引擎.原来的英雄无敌3只能在Windows上玩, 现在通过 vcmi,我们也可以在 Unix/Linux, 苹果等其它系统上玩了.目前手机和平 板上的英雄无敌3就是用的这个项目的成果. 而手机和平板上的英雄无敌2的出现,是因为另一个开源项目 fheroes2 . vcmi 和 fheroes2 的另一个好处就是降低了CPU的消耗,以前的Windows游戏估计 是为了获得及时的响应,都是100%地利用CPU,即使没什么需要计算的,

英雄无敌HoMM3-死亡阴影SOD-神之苏醒WOG-封神NABI-MOD等相关文件

英雄无敌HoMM3:死亡阴影SOD 英雄无敌3之死亡阴影(Heroes of Might and Magic III: Shadow of Death,简记为HoMM III: SOD)发行于1999年,网上随处可见资源和资料,"游戏之家"的帮助是最直观和详尽的.值得一提的是,贴吧"总上所述"将的"游戏之家"的内容整理成文件提供下载:http://pan.baidu.com/s/1i5Ne48P 英雄无敌HoMM3:神之苏醒WOG 神之苏醒(Wa

Problem A: 英雄无敌3(1)【dp/待补】

Problem A: 英雄无敌3(1) Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 86  Solved: 16[Submit][Status][Web Board] Description 大家知道在英雄无敌3中,每个城堡都需要钱来维持建设,现在有一座很奇怪的金矿,它在第i天只产生si 元的钱,而且如果你在第i天拿到si 元的钱,那么你将在 xi 内(包括第i天)拿不到钱,而在yi天内(包括第i天)一定要再次拿钱.现在有一个着急的玩家,他现在已

英雄无敌3地图的中英文对照

一直都很喜欢英雄无敌3,而且我觉得这个翻译真的很有水平,留一份存档在这里欣赏(红字表示翻译的特别好): A Viking We Shall Go 维京风暴! A Warm and Familiar Place 竞争上岗 Adventures of Jared Haret 胜利逃亡 All for One 臣服 And One for All 一统江山 Arrogance 傲气冲天 Ascension 即位 Back For Revenge 卷土重来 Barbarian Breakout 野蛮人的

前端攻略-从路人甲到英雄无敌

记得那年,我初学前端,遇见了很多的文章,在浩瀚的知识海洋里我手足无措,不知从何开始.己所不欲,勿施于人.这篇文章就会帮你去遨游前端学习的海洋,主要包含了在我之前的学习过程中整理的一些资源和一些感悟.我打算将整篇文章切分为两部分,第一部分重温HTML与CSS的基本知识,第二部分概括JavaScript.前端框架与设计模式. HTML 与 CSS基础 前端的领域里,任何东西都离不开HTML 与 CSS.HTML与CSS基本上控制了你看到的所有东西,HTML用来定义内容而CSS负责样式与布局. 首先从

linuxtoy.org资源

https://linuxtoy.org/archives.html Archives 在 Android 系统上安装 Debian Linux 与 R (2015-07-14) Pinos:实现摄像头共享 (2015-07-06) Firefox 40 Beta (2015-07-04) BookDrop: 通过 Dropbox 接收 Kindle 电子书 (2015-06-24) Linux Kernel 4.1 (2015-06-23) b2gdroid:在 Android 手机上一键切换

用游戏编辑器制作MOD脱颖而出

[导读] 立志成为游戏策划的你,和千千万万的游戏玩家的不同之处在哪? 是你玩过很多的游戏?别人也玩过 是你游戏打得比别人好?也许电子竞技更适合你 是你对游戏的理解比别人深,知道如何设计出更好玩的游戏?嗯,是的,可是怎么证明呢? Action speaks louder than words! 最好的证明就是拿出你自己制作的游戏MOD,这胜过一万字的文字简历.可做mod难吗?不难,需要的只是你的一刻红心(立志成为游戏设计师的决心),两手准备(选对工具,找对方法),假以时日,你就能做出自己的第一个m

转: GUI应用程序架构的十年变迁:MVC,MVP,MVVM,Unidirectional,Clean

十年前,Martin Fowler撰写了 GUI Architectures 一文,至今被奉为经典.本文所谈的所谓架构二字,核心即是对于对于富客户端的 代码组织/职责划分 .纵览这十年内的架构模式变迁,大概可以分为MV*与Unidirectional两大类,而Clean Architecture则是以严格的层次划分独辟蹊径.从笔者的认知来看,从MVC到MVP的变迁完成了对于View与Model的解耦合,改进了职责分配与可测试性.而从MVP到MVVM,添加了View与ViewModel之间的数据绑