在 Windows 上编译带 ICU 的 Boost::Regex

找遍了文档和文章,没有能直接解决问题的,就将我的方法记录下来好了。以及,明天周例行检查过了的话,优先把 CGSS 反向系列的剩下两篇写完。但是心好急啊,还没开始动工论文!

Boost 的 Boost::Regex 默认是不带 ICU 支持的。在这种情况下,它只能用来处理多字节字符串(MBCS)的正则表达式操作,而这个字符串是和系统的区域信息(locale)相关的。同样是简体中文区域,Windows 的字符集是 GBK,OSX 和 Linux 的字符集是 UTF-8。如果不给这个库增加其他字符集的支持,那它基本上就对多字节字符(汉字、喃字、假名等等)无能为力了,毕竟在表示“ASCII 以外的字符”这一个概念时不同编码方案码是不一样的。不过好在 Boost 的设计者很清楚这一项需求,在 boost/regex/icu.hpp 中定义了两个额外的正则表达式结构:wregex(处理宽字符)和 u32regex(处理 UTF-8、UTF-16 和 UTF-32),不过内部要依赖于 ICU。考虑到我准备使用 UTF-8 作为字符串的编码基础,必须要用上 ICU;而要用 ICU,就必须自己编译 Boost。

注意,接下来的部分过程只适用于 Windows,因为 Linux 一般是预置了 ICU 的,只需要简单指定就好,bjam 会自动完成设置。

查看更多

分享到 评论

杂记

杂记。

查看更多

分享到 评论

坦塔罗斯之苦痛

4日上午回到学校。一直到晚上都疼!虽然感觉上是腹胀吃不了东西,但是实际饿,低血糖

心神不宁,什么都做不了,翻译啊代码啊论文啊什么的。

查看更多

分享到 评论

雷吉欧斯中的一段告白台词

又有一些文章啦,但都只处于列了提纲的状态,放假回来再补完。(<ゝω・)☆

(05-11:什么?我之前没说过什么话吧?)


总体来说,这动画看着就是掉智商的。据说把小说又改乱了——不过说真的,异世界开挂这种东西套路还是太多,个人并不怎么喜欢,就是小说也离我太遥远。

一句话概括:满级高手来新手村洗点,见证小白买外挂到续费失败全过程。

于是就把这当做吃饭时不用动脑的东西看了。看完之后除了吐槽各种不合理(吐槽我就输了)之外,就注意了一段台词,EP18 20:56。

查看更多

分享到 评论

为 NGUI 设置动态字体

Unity3D 工程中,UI 用的是 NGUI。在 3D 程序中,文字绘制并不像 GDI 的字体光栅化那么直接,除了 DirectWrite/Direct2D 这种结合 GDI 的,其他大多都是手工管理 sprite font。一般的字体应用方法,主要是静态和动态两种,区别就在于是读取缓存的贴图还是运行时生成贴图。

我开始是看着网上的教程,用 BMFont 生成了静态贴图——但是由于目标字符集是 Shift-JIS,这个量实在是很大,贴图的量看起来十分吓人。然后我才发现,新版本的 NGUI 是支持使用 TTF 作为源生成动态字体的。不过系统字体都是 TTC,要转换为 TTF。鉴于许多教程中提到的 TTCTools 不能用(这是 16 位应用程序,64 位系统不带 WOW16),于是找到了两种方法:UniteTTC,和 AiFont。我用的是后者,导出了其中一个字形(TTC 可以包含多种字形,比如常规、斜体、粗体、粗斜体、半宽)的 TTF,能正常绘制文字。

分享到 评论

为 Unity3D for Android 编译 SQLite 3

作为 CGSS 反向的成果聚合部分的一个环节,Unity3D 的 SQLite 插件是必经之路。在 Asset Store 里,不过15刀的价格对于其功能而言还是有点高。研究了一晚上,最后结合 NDK 将 SQLite 3 编译到了 Android 环境上,整合到 Unity3D 中是第二天的事了。

查看更多

分享到 评论

软件工程中的“忒修斯之船”

晚上洗衣服的时候刚好碰到一个同学,他说关于他们实验室正在写的软件,如果有什么不懂的能不能来问我。我了解到,他们做的是一个软件的二次开发,于是就对他说:“二次开发最难的不是在你写的东西上,而是在如何对接和使用宿主已有的功能。”我说他们写东西不难的意思是他们仅是一般本科生的水平,实干的是一些类似查询零件信息存入数据库之类的相对简单的活,作为毕业前的一次训练,正是所谓“不掌握核心技术”。我说,二次开发的一种策略是,先写一个最简单的,往工具栏上加入一个按钮,按下之后弹出“hello world”对话框,接下来函数啊属性啊什么的都好办。这个 hello world 确定了三点:

  1. 你的插件(或者类似物)能被正确加载;
  2. 这个插件提供了最基础的输出,一个按钮(显示的信息可用于调试);
  3. 这个插件能和用户进行交互。

然后再在它的基础上开始写功能。就好像,要车,先造出一辆手推车,车架不散,轮子能滚。要加速?装上发动机。要省力?加上轮胎。这样一点一点改进,时间足够最终能造出跑车。怕就怕开始选个方轮子就直接开始造跑车了。

这方法比起测试驱动来说真的是老土多了,不过仍然能给他们上一课。不过今天的重点不在这里,我想的问题是,忒修斯之船的争辩是不是这种“框架式”(包括测试驱动)开发的思想基础呢?

忒修斯之船的悖论产生自人对“整体”、“部分”,以及在第二问中加上的“时间”,这些要素的认知是不统一的。部分有机组合成的整体,是大于部分之和的,大于的部分就是人为赋予的“含义”,比如纪念意义。就拿工业产品而言,具有互换性的产品对于不同人来说还是不一样的,用工具用久了就产生了熟悉感甚至感情,这部分是不属于互换性的、使用中添加的“含义”。忒修斯之船之所以是一艘特定的船,是因为这个问题的提问者已经假设了它的独一无二性。

回到软件工程中。软件的标准之一,来自于算法,是可复现性——给定输入,环境相同,算法不变,输出就不变。在测试进程的眼里,整个程序由测试用例组成,这些用例只有“通过”和“不通过”两种状态。而不管用例内的代码是如何组织的、存在何等的关联,对于测试进程而言它们仍然是独立的用例。在这样的一个设定中,“程序”这个整体是由各个“用例”部分简单列出的,关系是整体等于部分之和。有了无关性保证,只要所有的部分不缺失(测试通过),就可以认为整体是完整的。

所以,当我按下按钮弹出“hello world”的时候,我就可以认为鼠标事件响应是没问题的了。之后无论这个处理函数内写了什么功能,和“可以响应”这个结果都无关。这是我挂在嘴边的“功能上等价”的内涵,也就是一些时候我看到或者做了非常抽象的功能实现,就认为这个结果已经表明最后很可能成功。他们总是将思维局限在当前这个“快照”(snapshot)上,而不是后面代表的设计上,所以不理解简单的示例的意义在哪。

分享到 评论

Windows 10 10586.218 更新的灾难

收到了 10586.218 更新后我第一时间安装了。第二天早上起来,提示安装失败。我以为和前面的几个更新差不多,安装几次就好了,就再安装了几次。最后的确是没报告错误了,但是一进入系统我就发现了异常:风扇呜呜转得飞快。

查看更多

分享到 评论

从一次失误中注意到的 System.Media.SoundPlayer 流读取

kawashima 主体完工之后我转向了 C# 的实现。自然,接口风格就要用 Stream 的风格啦。我已经做好了 kawashima 的流式封装,接着来做纯 C# 版的。虽说过程中遇到了各种坑,但是最后基本上都过去了,实现了文件从 HCA 到 WAV 的解码(固定逻辑)。写了流式封装之后要进行测试,最好的测试方式就是用 System.Media.SoundPlayer,它的一个构造重载接受一个 System.IO.Stream 类型的流,从中读取 WAV 数据,进而调用系统 API 播放。P/Invoke 版的就是这么测试的。

然而此次测试中发现一个奇怪的现象。新的 HcaAudioStream 支持从 HCA 到 WAV 的文件的解码,而且经过散列对比,这个文件和原始的 hca 生成的完全一致,SoundPlayer 也能播放,说明从流到流的解码应该是没问题。但是这个类直接传入 SoundPlayer,就会在一段时间后(我用一个属性验证过,解码结束了)抛出 InvalidOperationException,错误说明是“波形头已损坏”。对此我觉得很奇怪,文件能播放,直接传数据流为什么就不行呢?挖掘了一番,在 .NET Framework 中找到了一个错误。

不过,剧情再次反转,原来是我忘记使用了 offset 参数,而这个参数的作用……下文详细讲解。

总之这次给了我一个机会研究 SoundPlayer 的缓冲实现原理。

查看更多

分享到 评论

HackPKU 2016 结束

简记。

查看更多

分享到 评论

SharpDX Direct3D 填坑:DataStream 和 Cubemap

填上两个坑:DataStream 使用不当的内存泄漏和在 SharpDX 中使用 cubemap

查看更多

分享到 评论

在 //BULID/ 2016 上宣布的 Visual Studio 和 .NET 更新

简要选了几点介绍。

查看更多

分享到 评论

CGSS 核心反向过程实录 | 六、获取密钥

索引

2017年5月追记:

我探索这些的目的,是以一个玩家的身份,让 CGSS 变得更好玩。私下里我类比过普罗米修斯,将天火——谱面的制作和玩的能力从“天上”分一点出来。其实,修改 CGSS 去作弊是很简单的,无论是客户端还是 MITM。但是我不会去作弊,也不希望这系列文章的读者们将文章内容用在歪门邪道上,不希望去作弊、破坏平衡性。玩过 LLSIFSB69GF(note)Arcaea 之后,我仍然认为 CGSS 的综合指标(游戏性、操作体验、曲目等等)是行业内翘楚,Cy这次比较用心。那么作弊还有什么意思嘛!对了,我不氪金,不冲分,只是闲暇时间来两局,玩得舒心。

当然,まゆさまが見ています。

查看更多

分享到 评论

CGSS 核心反向过程实录 | 五、C# 代码反向

索引

2017年5月追记:

我探索这些的目的,是以一个玩家的身份,让 CGSS 变得更好玩。私下里我类比过普罗米修斯,将天火——谱面的制作和玩的能力从“天上”分一点出来。其实,修改 CGSS 去作弊是很简单的,无论是客户端还是 MITM。但是我不会去作弊,也不希望这系列文章的读者们将文章内容用在歪门邪道上,不希望去作弊、破坏平衡性。玩过 LLSIFSB69GF(note)Arcaea 之后,我仍然认为 CGSS 的综合指标(游戏性、操作体验、曲目等等)是行业内翘楚,Cy这次比较用心。那么作弊还有什么意思嘛!对了,我不氪金,不冲分,只是闲暇时间来两局,玩得舒心。

当然,まゆさまが見ています。

查看更多

分享到 评论

CGSS 核心反向过程实录 | 四、Java 代码反向

索引

唉!从17日开始写了几句话到现在,拖了13天,这病得治。

28日在博客园的本周回顾中找到了这样的一篇个人足迹。如果真的遇到这样的对手,我很荣幸。

2017年5月追记:

我探索这些的目的,是以一个玩家的身份,让 CGSS 变得更好玩。私下里我类比过普罗米修斯,将天火——谱面的制作和玩的能力从“天上”分一点出来。其实,修改 CGSS 去作弊是很简单的,无论是客户端还是 MITM。但是我不会去作弊,也不希望这系列文章的读者们将文章内容用在歪门邪道上,不希望去作弊、破坏平衡性。玩过 LLSIFSB69GF(note)Arcaea 之后,我仍然认为 CGSS 的综合指标(游戏性、操作体验、曲目等等)是行业内翘楚,Cy这次比较用心。那么作弊还有什么意思嘛!对了,我不氪金,不冲分,只是闲暇时间来两局,玩得舒心。

当然,まゆさまが見ています。

查看更多

分享到 评论

杂谈

本文分为几个部分:软件中的唯一性资源、技术进步和社会平等、Batman v Superman 影评。

乱想乱讲的,轻拍。

查看更多

分享到 评论

再谈透视投影

这是第三次将目光放到变换矩阵上。之前经历过初次提交修正,不过,剧本果然越来越精彩。

查看更多

分享到 评论

“川岛” HCA 解码库

首先指出,原版,也就是 HCA 的解码核心并不是我写的。原来的是一个解码命令行程序,将 HCA 解码为波形声音。我的工作是将其封装为一个动态库,期望“Write once, compile everywhere”。本文记录的是测试过程中填上的一些坑。

查看更多

分享到 评论

博客更新

春节开始,就没更新博客了。一方面……懒了点,另一方面……算了就是懒。分类有所更改,404 更智能了一点。

春节过后很高兴地,收到了首要目标的 conditional acceptance。这边算是解放了。

主要猛攻了 CGSS,取得了一定成果(咦这么论文式的措辞?),详见 CGSS 核心反向过程实录

暂时挂起的几篇文章:

  • 安利白箱及其后续
  • CGSS 和 LL 上手
  • 翻译风波
  • WordPress 建站指南(写给小白级别的入门,从选择域名到全站 HTTPS 一条龙。写到一半发现安全配置那里就得扯一长串了,还要解释 vim,一团乱麻。后来村长又不想自己建了,就暂挂了。)
分享到 评论

AlphaGo 与对机器智能的担忧

前记:3月8日的 Steam 更新添加了对 Vulkan 的 overlay 支持;3月12日 NVidia 驱动更新添加了 Vulkan API 支持。


举世瞩目的李世乭对阵 AlphaGo 的围棋之战在今天落下帷幕,最终李世乭以1:4落败。然后我在博客园新闻区看到了这样一篇:《为什么李世石的胜利让我喜极而泣》。下面的评论说“这事让好多文学分子高潮了”,认为这只是算法的胜利,计算机终究会为人类服务,那些担心都是无稽之谈。在这里讲一下我的看法。

如果机器具有了智能,判断对物种的好恶的能力,会展开对人类的“清洗”吗?从逻辑上来说,清洗是更好的选择。有文章提到过,光看人类自己,看看印第安人在美洲的经历,就知道黑暗森林法则实践起来是什么样子。如果它们还懂得沟通,获取它们群体内的最大利益,甚至会重演八国联军的事件。AlphaGo 是设计用来博弈的,正处于“不成熟的理性”的阶段,如果无法判断“整体”的概念,无法理解第零定律的话,就会出现曲别针的例子——所有人都做成曲别针,尝试劝阻的人也被做成曲别针。

等等,刚才不是假定了机器有了智能吗?但是退一步说,即使机器没有智能、只是按部就班行事,也会出现曲别针事故呢。看官知道第一个蠕虫病毒是怎么产生的吗?足够的功能,加上错误的参数。就执行的命令而言,并没有错误,只不过出现了人类不希望的结果。人并不希望比自己先进的生命体出现(同样,黑暗森林)。前面印第安人的例子已经是很仁慈了,因为还没产生生殖隔离,所以还有种群内的“怜悯”。

所以,认为不需要担心的,和担心的,两类人的出发点是不同的。前者从逻辑的角度看问题,而且很乐观地假设了机器总会在人类的控制之下;后者从人性(人类“生存”利益)的角度看问题,而且悲观地认为自律(有足够能力离开人自行活动)地机器有着胜于人类的能力。各位,不妨找一个平衡点吧。这就和养狼一样,给了机器强大的计算能力和与物质互动的工具,相当于给了它们獠牙。这方便了人们的生存,但是就是不知道什么时候会反咬一口——想避免这不幸的情况发生,请拔掉它们的牙,将它们限制在虚拟空间之内吧。

说得容易做起来难,好多人都已经半数字化了呢。

分享到 评论