【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,本篇主要介绍基础知识以及最基本的几个指标的内部工作机制,下篇会介绍一些高级功能的实现原理 ...
随机推荐
- MVC-路由解析
MVC程序入口 Global.asax.cs 执行Application_Start 方法 *默认路由 *静态路由,访问链接只需要域名加路由url固定值就行了 *替换控制器,或方法名, *正则路由 方 ...
- Oracle数据库排序后分页查询数据错误问题解决
一.问题描述:根据更新时间倒序排序然后分页查询数据,但是点击分页操作的时候,会出现数据重复看似没有操作的情况 二.问题错误原因分析 分页查询的SQL语句: select * FROM (select ...
- centos 7 安装更新php5.6
epel remi 什么的把我弄晕了 不深研这东西了,直接按步骤操作更新了. # yum install epel-release # rpm -ivh http://rpms.famillecol ...
- JDK 15 JAVA 15的新特性展望
目录 JEP 371: Hidden Classes JEP 372: 删除 Nashorn JavaScript Engine JEP 377: 新的垃圾回收器ZGC正式上线了 JEP 378: T ...
- 新版gitbook导出pdf
文章目录 gitbook自带的npm模块gitbook 使用vscode的插件Markdown PDF 使用CommandBox GitBook Exporter 最近想把自己写的一个gitbook转 ...
- Oracle把表记录恢复到指定时间节点
可以执行以下命令alter table 表名 enable row movement; --开启表行移动flashback table 表名 to timestamp to_timestamp('20 ...
- 如何装双系统win10下装Ubuntu
如何装双系统win10下装Ubuntu 第一步 制作启动盘 下载UItraISO软件.下载Ubuntu系统(地址:https://www.ubuntu.com/download).准备一个大于8g的U ...
- Flutter自己实现一个ProgressHUD
用惯了iOS的SVProgressHUD,但是在flutter pub上的并没有找到类似的实现,于是自己实现一个 主要实现四个基本功能 Loading显示 成功显示 错误显示 进度显示:环形进度条和文 ...
- nodejs中httpserver的安装和使用
首先来看一下官方的介绍: 大概意思是说:命令行HTTP服务器工具,用于提供本地文件,类似于python -mSimpleHTTPServe. 直白点的意思就是通过命令行启动的一个http服务器工具,它 ...
- jQuery里面click、this事件遇到(Django模型里for)相同的id名和class名想获取值
遇到的原型是这样的!下面我把它简化一下; click事件: 在浏览器里面只能获取横线上面的值,和下面的第一个值!! 这是因为id等级比class高,而且js要求id不能重复! 当 转载于:https: ...