前提知识:

任天堂游戏系统的画面分辨率是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行列绘制控制程序的更多相关文章

  1. 【SMB源码解析系列】——003.SMB游戏基本框架

    前面有了解到RESET中断相关代码,结尾处通过一句jmp进入了无限循环,之后CPU将会在每一帧PUU进入VBlank状态时,接收NMI中断信号, 跳转至NMI代码处继续执行,直到遇见RTI指令时又返回 ...

  2. 【SMB源码解析系列】——001.JumpEngine函数

    在SMB的源码中大概有不到20处看起来很奇怪的指令,它的格式是通过jsr指令调用一个名为JumpEngine的函数,其后并不是跟随某些后续的逻辑指令,而是通过.dw定义了一系列16位地址. 我们可以看 ...

  3. 【SMB源码解析系列】——002.RESET中断

    跟随代码结尾处的中断向量,我们可以看到RESET中断所在地址为Start标签处. 这部分代码比较简单,从字面便可基本理解. 1.(682~683)状态寄存器设置,sei指令用于禁用IRQ中断,SMB中 ...

  4. 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新

    本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...

  5. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  6. 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新

    上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...

  7. Cwinux源码解析系列

      Cwinux源码解析系列

  8. 【安卓网络请求开源框架Volley源码解析系列】定制自己的Request请求及Volley框架源码剖析

    通过前面的学习我们已经掌握了Volley的基本用法,没看过的建议大家先去阅读我的博文[安卓网络请求开源框架Volley源码解析系列]初识Volley及其基本用法.如StringRequest用来请求一 ...

  9. TiKV 源码解析系列文章(三)Prometheus(上)

    本文为 TiKV 源码解析系列的第三篇,继续为大家介绍 TiKV 依赖的周边库 rust-prometheus,本篇主要介绍基础知识以及最基本的几个指标的内部工作机制,下篇会介绍一些高级功能的实现原理 ...

随机推荐

  1. Tensorflow 模型线上部署

    获取源码,请移步笔者的github: tensorflow-serving-tutorial 由于python的灵活性和完备的生态库,使得其成为实现.验证ML算法的不二之选.但是工业界要将模型部署到生 ...

  2. webstorm tslint配置

    webstorm设置 settings >> TypeScript >> TSLint, 勾选 Enable ,选取 tslint包路径...npm\node_modules\ ...

  3. Ansible Facts 变量详解

    Ansible Facts 变量详解与使用案例 主机规划 添加用户账号 说明: 1. 运维人员使用的登录账号: 2. 所有的业务都放在 /app/ 下「yun用户的家目录」,避免业务数据乱放: 3. ...

  4. 21.SpringCloud实战项目-后台题目类型功能(网关、跨域、路由问题一文搞定)

    SpringCloud实战项目全套学习教程连载中 PassJava 学习教程 简介 PassJava-Learning项目是PassJava(佳必过)项目的学习教程.对架构.业务.技术要点进行讲解. ...

  5. 关于go的init函数

    亲测,如果加载一个包,如果一个包里的每个文件,均含有init函数,那么均会执行. 目前来看,init的执行顺序,是文件名称的自然排序进行执行的. 并且只是所加载包里的go文件的init函数执行,对于包 ...

  6. 大数据作业之利用MapRedeuce实现简单的数据操作

    Map/Reduce编程作业 现有student.txt和student_score.txt.将两个文件上传到hdfs上.使用Map/Reduce框架完成下面的题目 student.txt 20160 ...

  7. 全球数字高程数据(DEM)详解,还有地形晕渲、等高线等干货

    1 基本概念 DEM是数字高程模型的英文简称(Digital Elevation Model),是研究分析地形.流域.地物识别的重要原始资料.由于DEM 数据能够反映一定分辨率的局部地形特征,因此通过 ...

  8. MySQL基础知识和常用命令总结

    说明:以下内容是阅读书籍<<MySQL必知必会>>的摘要和总结 检索数据 排序检索数据 过滤数据 使用通配符过滤 使用正则表达式进行搜索 创建计算字段 使用数据处理函数 汇总数 ...

  9. MarkDown排版测试

    1.标题设置 标题(大标题) 标题(小标题) 标题(一级标题) 标题( 二级标题) 标题(三级标题) 标题(四级标题) 备注:大标题与一级标题一样,小标题与二级标题一样,"#"前无 ...

  10. QtConcurrent::run() 只能运行参数个数不超过5的函数

    有时不得不看源码 qtconcurrentrun.h template <typename T, typename Param1, typename Arg1, typename Param2, ...