用于BBC Micro的躁狂矿工2021

2021-04-18 18:11:08

最近完全拆卸的躁狂矿工[https://github.com/tobylobster/manicminer]它似乎不可抗拒,改善它。我在下面写了一些笔记。

第一份工作是将代码收集到一个源文件中,因为原始文件被拆分在彼此来回调用的多个文件上。我还添加了一个短的加载程序,在执行前加载和复制内存。我的口头禅是为了让游戏始终跑步,因为它的方式太容易引入这个过程中的错误,所以拥有一个正在运行的游戏意味着我找到并更快地修复它们。

我可以看到没有多少内存,所以我开始为空间做出各种优化。我删除了潜在的拷贝保护代码,删除了冗余延迟循环,缩短了绘制标题屏幕的代码(在我在那里时添加一个更好的Penrose三角形)。

现在我有一点记忆玩。我开始优化速度,从剧情例程开始。其中一个绘制播放器和垂直移动的监护人的一个绘图例程,因此我通过使用表查找来计算每个字符行的屏幕地址。情节例程也有一个'模式'表示像素如何与屏幕结合,我也提高了处理此操作的性能。

在几个地方(包括曲线)中,在重复添加的循环中实现了常数因子的计算。我修复了这些来使用更有效的代码。在几个位置,可以删除使用CMP#0:

lda somevaluecmp#0; < - 冗余。 LDA指令相应地将z标志设置为qublequallame

接下来,我优化了从播放器周围的屏幕内存拷贝的例程到缓存并再次返回。其他优化的小示例,这里是' SA例程逆转字节中的比特顺序(来自原始代码) ):

Reversbits STA BytetoreVerse Ldy#0 LDX#0reversbitsloop LDA BytetoreVerse Clc Rol Sta BytetoreVerse Bcs BittetoreVerse BCS Bitt TXA ClcontinuereVerseBits ror税收iny cpy#8 bne reversebitroproop rtsbitset txa sec jmp continuereversetbits

顺便说一下,这里没有写的是诋毁1984年的原创作品,这在世界上仍然是互联网,源码控制,快速可靠的存储媒体,广泛的信息和关于内部工作的社区的卓越成就BBC Micro等。这一切都突出了我们今天所拥有的好处。

现在是时候替换对速度最大影响的例程:OSByte 135.这读取了当前文本光标位置的字符并将像素解码为其ASCII值。我用自己的副本将呼叫替换为OS例程,但此新版本仅对检查字符32(空格)和用户定义的字符(128-160)感兴趣。通过限制要测试的字符范围并且还硬件到模式1中的读取像素,制造了显着的速度。

这为程序添加了更多代码,因此我通过将公共代码移动到子程序中来找到空间,例如,移动文本光标,设置文本颜色,检查是否按下键等。

然后返回优化速度,这次动画输送机。沿其长度多次复制相同的精灵,因此此绘图现在基本上是一个简单的记忆复制例程。以前这是通过重复的OSWRCH调用来实现的。

通过这些速度改进,我想让玩家角色闪烁。在更新屏幕上的播放器(已经计算出新播放器位置)时,代码首先从缓存中恢复屏幕背景(旧播放器位置周围的6个字符单元格),将传送带动画一步,记录(副本)新屏幕背景在新的播放器位置进入缓存中,然后在新位置绘制播放器。所有这一切都需要在电子枪之间通过当前播放器位置在屏幕上的时间和之前返回到新播放器位置之前的时间。

我设置了一个中断屏幕上的每个第三个字符行的计时器,随着电子束到达每个第三个字符行,递增柜台。在主要程序中,即将如上所述更新玩家,我看这个计数器。如果我估计更新代码将无法及时完成(在电子枪在屏幕上达到播放器的位置之前)然后我等到计数器(因此电子枪)通过了播放器并且安全继续更新是安全的玩家。这是正确的,但完全值得这一点。

原始代码使用了一个事件(与垂直同步定时)更新音乐和一些声音效果。我现在使用我的新计时器基于定时器中断来完成相同的作业。

通过将&#39放置更多的空间;脚和#39; Sprite进入(以前未使用)的打印机缓冲区。我还缩短了将当前级别的精灵复制到用户定义的字符,以$ 0C00- $ 0CFF缩短。

现在有些游戏:与频谱原件相比,矿工威利在BBC版本(每帧2个像素)较慢,因此我恢复了正确的下降速度。原始BBC版本的空气速度快得多,因此我使空中耗尽率更接近频谱版本。

尤金'当拍摄最后一个键时,巢穴朝着出口落到了出口。这在原来的BBC版本中太快了,所以我' ve让他跌倒到现在的出口速度达到频谱版本。

我在屏幕底部绘制空气杆,而不是在侧面,这使得显示器看起来更加平衡并匹配频谱版本。这确实可以使用更多屏幕内存,因为需要一个字符行需要可见,但是我' ve恢复了足够的内存来做到这一点。我还使用我的中断例程来更改屏幕的底部三个字符行的调色板,允许在空中栏中使用不同的颜色和与主播放区域相比分数文本。在水平结束时排出空气更紧密地匹配频谱版本的外观,时序和得分。声音和视觉效果也被调整。

时间改进另一个特征:音乐。我改变了短暂的短暂的哔哔声让人让人想起镜子上的刺激性,并扩展它以发挥更完整的调整。有些笔记被重音(略胜于多)。虽然这很微妙,但我认为它有助于整体经验。我以更快的速度重复调整的主要部分,然后播放CODA。我仍然使用一个频道仅用于音乐。这意味着'跳跃'和#39;钥匙'声音效果可以居住在两个单独的频道上,而不是互相切割。

为使用Osbyte 135使用Osbyte 135的(最多)五个键进行动画的代码,但我现在将这些信息存储在一个单独的数组中以避免需要。我一次只动画一个钥匙进一步提高性能。

我已经写了一个第二绘图例程(Cellplot),以在屏幕上的字符位置绘制,这用于水平监护人,闪烁的出口,循环键等。这替换了常规播放期间的所有OSWRCH呼叫以获得进一步的性能提升。

频谱和BBC的图形定义之间存在若干差异,我希望将它们恢复到适当的频谱版本。我修复了退出(例如,矿石炼油厂的头骨和交叉骨架出口;高层森林出口;和孔居退出)。我从BBC中缺少的频谱版本中添加了电话亭退出。

我添加了更多'尖峰'与频谱版本相对应(例如2级' s尖峰,第二种类型的蜘蛛精灵等)。我修复了香蕉,苹果,金钱收藏品,平台定义,墙壁(包括添加缺少图形),开关,基座等。其中一些是微妙的,但我以为我' d搞定。值得庆幸的是,玩家和监护人精灵已经完美映衬。

我修复了房间标题,使其与游戏区域的底部单元格重叠。

到这个时候,中央洞穴(只有一个监护人的级别相对简单)运行太快(!)所以我添加了一些代码来规范时间。我将游戏速度设置为比频谱版本更快的游戏速度,因为这总是对我来说略微慢。在我的优化结束时,所有级别都以非常大的调节速度运行。

墙壁是'填写'根据现在的光谱(例如,在中央洞穴中,它们是黄色和红色的,而是黄色和黑色)

通过将大量变量移动到Zero Page,恢复了更多内存。每次访问任何变量时,它们现在都使用一个更少的字节。进一步的变量移动到第一页。我通过&#39节省了更多的内存; printfollowingmessage&#39 ;:

与代码内联的消息意味着文本的地址不需要存储在任何地方。

我将初始化代码移动到0400美元。此代码仅在启动时执行一次,因此初始化完成后,可以重复使用内存(在我们的情况下缓存当前级别的垂直精灵定义)。

标题屏幕的外观已经过,现在也显示了高分。

围绕这一点的某个地方我通过将它们与原始频谱版本进行比较来确保它们具有正确的颜色和图形来查看。这也涉及添加能力为在级别中设置条带和单个项目的单个颜色。我们仍然受到游乐区中只有四种颜色的限制,但我们在那里做得很好。这将是我发现更多调整的几次过去的第一个,例如十六洞穴'屏幕右侧的布局出现了一个错误的右侧的右侧太远了。这现在是固定的。校正播放器开始位置(例如,再次16级),并且水平监护人现在具有正确的起始位置和范围以匹配频谱。

我在添加了基于真正的像素的碰撞代码时,但它太复杂,大而且慢。所以我妥协了。我现在用八角形盒子碰撞 - 各个守护者的角落切断到更大或更小的程度。这在实践中被证明是非常擅长的,并且肯定是对原始BBC版本(框碰撞)的改进。

对于主兼容性,问题是BBC Micrope将用户定义的字符价格为0C00到0亿美元,但主设备并未。它在另一个内存中灰烬。因此,当0C00至0美元的内存时,内存已更改(在级别开始时),我调用操作系统来定义每个角色'正式'在游戏过程中,这太慢了,但在级别开始罚款。

我重新实现了第19和20级的流星和能量字段,以使用蜂窝电话而不是OSWRCH并使代码更短。

屏幕上的游戏现在说'游戏超过' 和颜色循环它与光谱类似。 在最后一分钟,我意识到跳跃的形状与光谱微妙地不同,所以我修复了这一点。