我打算在我的新C64项目中使用多色字符模式的软件精灵。我的想法是使用叠加' bullet'精灵数据到平铺数据。
我认为我可以在地址' TILESET',精灵数据地址' SPRITE'中设置拼贴数据。我可以将这两个结合起来,准备一个动态计算背景的子弹字母并存储在地址中“超级显示”'
我编写了以下代码和循环计数来检查它是否可行。而且我认为不是。循环吃了219个循环。近四条光栅线。在此循环之前,我没有包含所需的其他必要计算。像计算目标地址一样。
如果我想在屏幕上显示16个子弹,则需要64个栅格或8个字符的行。所以我变得怀疑。这是正确的方法吗?或者还有其他更优化的方法来完成同样的工作吗?
cycles
---------
ldy #$07 4 x1 = 4
- LDA TILESET,x 3 x8 = 24
AND SPRITE,x 4 x8 = 32
STA SUPERIMPOSED,x 5 x8 = 40
dey 2 x8 = 16
cpy 4 x8 = 32
bne - 3 x8-1 = 71
----------
219 Cycle
我考虑在背景中重复模式。这样我就可以使用相同的子弹牌而无需重新计算。
答案 0 :(得分:7)
正如Jester建议的那样,作为第一次优化,只需重复lda
,and
,sta
和dey
八次。消除cpy
和bne
。那将立即节省103个周期。即使你想保持正式循环,请注意dey
设置零标志,这样你就不需要cpy
。
作为第二个优化,请考虑编译的精灵。您不必从sprite, x
执行读取操作,而是将这些值直接编码到您的例程中,为每个精灵创建一个独特的例程。那又减少了16个周期。
话虽这么说,你的lda
在对齐的表格中将是4个周期,而不是3.所以有8个你没有考虑到。意味着展开并专门用于精灵= 102个循环(省略了最终dey
)。
在不了解C64架构和/或其余代码的作用的情况下,如果从堆栈页面中摄取SUPERIMPOSED
的任何人都可以这样做,请考虑将输出写入堆栈而不是通过索引编址。只需使用适当的种子值加载s
,然后通过pha
存储新结果。这将为每个商店节省两个周期,但需要12个额外的设置和恢复周期。
根据这个想法,如果您对这些表的外观有自由,那么考虑切换它们的格式 - 而不是一个包含TILESET
的所有八个字节的表,使用八个表,每个表保存一个字节它的。这样就无需在循环中调整y
;只需在每次展开的迭代中使用不同的目标表。
假设TILESET
和SUPERIMPOSED
都可以是八个表格,可以帮助您:
LDA TILESET1, x
AND #<value>
STA SUPERIMPOSED1, x ; * 8
[... LDA TILESET2, x ...]
...总共88个周期。如果SUPERIMPOSED
是线性的,但在堆栈页面中则是:
TSX
TXA
LDX #newdest
TXS
TAX ; adds 10
LDA TILESET1, y
AND #<value>
PHA ; * 8
[... LDA TILESET2, y ...]
TXS ; adds 2
......这是84个周期。
迟到:
如果您愿意将x
中的索引预乘8,有效地将可索引范围减少到32个tile,那么您可以继续填充线性输出数组而不调整y,如下所示:
LDA TILESET, x
AND #<value1>
STA SUPERIMPOSED, x
LDA TILESET+1, x
AND #<value2>
STA SUPERIMPOSED+1, x
... etc ...
因此,您需要具有不同表基地址的该例程的八个副本仍然能够达到256个输出切片。假设你有20个精灵,它总共有20 * 8 = 160个精灵绘图程序副本,每个副本可能大约为100个字节,所以你花费大约16kb。
如果你的游戏在一种精灵上比在其他精灵上重得多 - 例如它通常是两三艘宇宙飞船相互射击成千上万的子弹 - 显然你可以非常有选择地进行优化并保持总体足迹。