查看“逆向:程序研究/AT1/字体例程”的源代码
←
逆向:程序研究/AT1/字体例程
跳转到导航
跳转到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
AT1的字体例程目前仅研究了主显示用的主字体,对于其他(战斗字体)不甚了解。即使是主字体,目前也仅跟踪到一个缓冲区,对更细节的显示部分并不了解。 AT1的主字体,是24*24,4bpp的灰度位图字体。显示时,字体例程会对其缩放。 == 取字例程 == 主取字例程,首先将编码和一个缓存区中的编码数组(int32)里的编码比较。如果没有取到,那么就调用另一取字例程,从字库中取字,复制到缓冲区中。 经后续分析,根据该例程名字(FontMake),可猜测:为了和FontDisp(Tim类图片字体显示例程)适应,这里实际上是将文字画进了一个内存中的“TIM文件”,然后再调用的FontDisp显示。 从字库取字的例程大约工作方式如下: <pre> index = get_index(encode) ptr = texture_base + 24 * 24 * 0.5 * index # 24*24, 4bpp copy_to_cache(ptr) </pre> get_index是一个函数,它在字库描述字符串中比对传入的编码encode,并返回比对成功时的字库索引。 textrue_base是字库基址。这个基址会因字体的变化而变化。 === 字库索引获取例程(Debug:FontMakeGetFontListPosition) === ==== ABI ==== ===== 参数 ===== a0: 要查询之编码 a1: 要查询之字体编号 gptr_1(char * fontlist[10]): 字体描述字符串(FontList)指针列表 ===== 动作 ===== 返回v0: 查找到的文本编码在字体描述字符串中的索引(以二字节组为单位)。 ==== 伪代码 ==== <pre> ptr = texture_description i := 0 while *ptr <> 0 if *ptr = (encoding & 0xff00) >> 8: ptr += 1 if *ptr = encoding & 0xff: return i else: ptr += 1 end; else: ptr += 2 endif; endwhile; </pre> encoding是传入的要获取的字符编码。 texture_description是字库描述字符串的基址。 == 字体选择器 == 通过内部控制或控制符FD(D是一个十进制数字,如F0、F1等),可以改变字体。每个字体有独立的字库描述字符串,和字库地址。分别以两个数组存储(一般挨在一起)。 需要注意,每个Font对应一个自己的缓冲区。代码分析发现,GUST如果本来设计了两个字体,那么大概率会事先初始化两份缓冲区(在全局变量中)。否则其他缓冲区(画布)皆不存在。在AT1中,即使设定了第二个字体,由于缺乏缓冲区并不能成功画出第二字体。 == Debug:FontMakeSet == 预览代码内存13AB54。研究不足。其检查缓冲区并调用无名例程(上取字例程)。 该例程对字体的使用情况进行计数。'''推测'''在从缓冲区删除字体时会根据此计数器动作。 == Debug:FontDisp == 研究不足,预览代码内存13C11C。根据AT显示逻辑,该代码在文本显示时每次渲染循环皆调用。其a0作用未明,且所指结构体使用位置较广。破坏该结构体数据会引发渲染异常(全屏)、DMA错误等多种错误,并使游戏(和模拟器)崩溃。 a1指向一字体显示控制结构体。调控包括文字颜色、文字底色等多种参数。结构体已经探明的结构参数如下: <pre> +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0x000 str_ptr | ukn... ... 0x100 ukn... |w |h | ukn... </pre> 其中,str_ptr是指向要显示的字符串的地址。 其中,w是字体宽度(单字),h是字体高度(单字),对话框的典型值是0x120,美版的值是0x100。这个值的单位依然是未知的。 == 其他 == Debug: * FontDispSetXY 13C3F8 * FontDispCountLine 13C8E4 * FontDispTagExec 13D1E8 控制符执行?
返回
逆向:程序研究/AT1/字体例程
。
导航菜单
个人工具
创建账号
登录
命名空间
逆向
讨论
大陆简体
查看
阅读
查看源代码
查看历史
更多
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
工具
链入页面
相关更改
特殊页面
页面信息