【SMB源码解析系列】——004.AreaParserTaskControl行列绘制控制程序
前提知识:
任天堂游戏系统的画面分辨率是256*240像素,基本的显示单位是tile,包含8x8=64个像素
根据电视机的制式不同,NTSC制式只显示256*224,也就是32x28个tile,画面的第一行以及最下方一行的tile是不显示的
PAL制式完整显示32x30个,SMB是以NTSC制式开发的。
AreaParserTaskControl是一个比较核心的程序,其下关联的子程序树完成了几乎全部的的游戏画面绘制工作。
从截图中我们可以看到,这个函数主要是用来循环调用另一个处理程序AreaParserTaskHandler,由变量AreaParserTaskNum控制循环次数。
当AreaParserTaskNum等于0时,会将ColumnSets减一,表示绘制完成1列画面(这里的一列具有4个tile宽度,每行也是4个tile,实际上AreaParserTaskHandler就是绘制了一个4x4大小的tile区域)。
ColumnSets减一之后结果是负数的话就会被bpl指令识别,程序跳转至OutputCol,这里总共绘制了12列,也就是32+16=48个tile宽度的一屏半画面。
AreaParserTaskHandler中则是调用了名为AreaParserTasks的例程树,AreaParserTaskNum会在一开始被赋值为#$08,也就是说AreaParserTaskHandler会被调用8次。
(开头说到SMB是NTSC制式,只会看到28行的tile,4x7=28,至于第8次是为了什么会在后面提到)
我们可以从3050行看到,AreaParserTaskNum是被递减的,并且作为JumpEngine的入参,因此我们得知AreaParserTasks中的例程是从后向前调用的,树中的8个函数刚好每次循环调用一个。
AreaParserTaskNum中的值递减至0时,3052行的RenderAttributeTables最终被调用,从名字中可以看出来这是用来填充属性表的,
侧面说明执行一次AreaParserTasks就是绘制了一个属性表字节对应的4x4=16个tile的屏幕区域(关于属性表命名表之间的关联关系留待以后说明)。
SMB的地图数据是预先压缩好的,AreaParserCore程序用于将这些数据解压(通过ProcessAreaData函数),然后写入到MetatileBuffer(通过RenderSceneryTerrain函数)
第一次调用RenderAreaGraphics都会根据MetatileBuffer中的值,将绘制4x4的tile区域左上方的tile,第二次绘制左下,所以IncrementColumnPos函数会切换绘制目标到另一侧,
一次通过RenderAreaGraphics绘制右上,右下的tile,再次通过IncrementColumnPos切换绘制目标到左侧,待下一次tile绘制。
对以上的主要流程有了了解之后,我们再来详细说明AreaParserCore、RenderAreaGraphics、IncrementColumnPos的具体内容
【SMB源码解析系列】——004.AreaParserTaskControl行列绘制控制程序的更多相关文章
- 【SMB源码解析系列】——003.SMB游戏基本框架
前面有了解到RESET中断相关代码,结尾处通过一句jmp进入了无限循环,之后CPU将会在每一帧PUU进入VBlank状态时,接收NMI中断信号, 跳转至NMI代码处继续执行,直到遇见RTI指令时又返回 ...
- 【SMB源码解析系列】——001.JumpEngine函数
在SMB的源码中大概有不到20处看起来很奇怪的指令,它的格式是通过jsr指令调用一个名为JumpEngine的函数,其后并不是跟随某些后续的逻辑指令,而是通过.dw定义了一系列16位地址. 我们可以看 ...
- 【SMB源码解析系列】——002.RESET中断
跟随代码结尾处的中断向量,我们可以看到RESET中断所在地址为Start标签处. 这部分代码比较简单,从字面便可基本理解. 1.(682~683)状态寄存器设置,sei指令用于禁用IRQ中断,SMB中 ...
- 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新
本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
- 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新
上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...
- Cwinux源码解析系列
Cwinux源码解析系列
- 【安卓网络请求开源框架Volley源码解析系列】定制自己的Request请求及Volley框架源码剖析
通过前面的学习我们已经掌握了Volley的基本用法,没看过的建议大家先去阅读我的博文[安卓网络请求开源框架Volley源码解析系列]初识Volley及其基本用法.如StringRequest用来请求一 ...
- TiKV 源码解析系列文章(三)Prometheus(上)
本文为 TiKV 源码解析系列的第三篇,继续为大家介绍 TiKV 依赖的周边库 rust-prometheus,本篇主要介绍基础知识以及最基本的几个指标的内部工作机制,下篇会介绍一些高级功能的实现原理 ...
随机推荐
- mongodb connection refused because too many open connections: 819
Env Debian 9 # 使用通用二进制方式安装 # mongod --version db version v3.4.21-2.19 git version: 2e0631f5e0d868dd5 ...
- 使用 GoLand 启动 运行 Go 项目
来源:https://my.oschina.net/u/3744526/blog/3085468 在使用本博客经验之前 需配置好 GOPATH 跟 GOROOT 创建好本地工作路径之后,使用 GoLa ...
- Python爬虫之记录一次下载验证码的尝试
好久没有写过爬虫的文章了,今天在尝试着做验证码相关的研究时,遇到了验证码的收集问题. 一般,验证码的加载都有着比较复杂的算法和加密在里边,但是笔者今天碰到的验证码却比较幸运,有迹可循.在此,给 ...
- Spring Boot中使用Swagger CodeGen生成REST client
文章目录 什么是Open API规范定义文件呢? 生成Rest Client 在Spring Boot中使用 API Client 配置 使用Maven plugin 在线生成API Spring B ...
- 【Linux网络基础】上网原理流程
1. 局域网用户上网原理 上网过程说明: 确保物理设备和线路架构准备完毕,并且线路通讯状态良好 终端设备需要获取或配置上局域网(私有地址)地址,作为局域网网络标识 当终端设备想上网时,首先确认访问的地 ...
- CTO为何要微服务评估
为什么定义参考模型 之前我的工作,大部分时间都是聚焦在某个产品/团队,为他们提供微服务/DevOps的实施及指导.进入公司后,同时参与了多个产品团队的改造研讨.其中最大的不同在于: 在面对一个团队的时 ...
- MySQL根据业务场景归纳常用SQL语句
素材表数据:user[{"id":1,"name":"x"},{"id":2,"name":&quo ...
- windows服务程序的编写
服务编写https://blog.csdn.net/lanuage/article/details/77937407 #include <windows.h> #include <s ...
- centos6安装创建kvm虚拟机
的虚拟机名 virsh domid name # 显示虚拟机id号 virsh domuuid name ...
- 苹果系统通过brew安装sshpass
默认使用brew install sshpass会出现Warning: MD5 support is deprecated and will be removedin a future version ...