如何在Commodore 64中改变内核SCNKEY例程行为

10
我正在尝试使用Commodore 64的内核例程实现游戏控制。下面的代码可以工作,但有一个例外。每个按键都被计为单个输入,例如:如果您一直按住按钮,则没有效果。您必须松开并再次按下才能进行移动。如何更改此行为?简单地说,我想重复按键操作,只要按键保持按下状态即可。
    GETIN  =  $FFE4
    SCNKEY =  $FF9F

keyScan:
    jsr SCNKEY  ;get key
    jsr GETIN   ;put key in A

    cmp #65
    beq left

    cmp #68
    beq right

    jmp keyScan 

一个很棒的问题适合放在 http://retrocomputing.stackexchange.com/ 上。 - Nick Westgate
2个回答

10

SCNKEY对于需要同时输入多个按键的游戏不适用。它是无状态的,仅返回当前按下的“一个”键 - 即如果有两个键被按下,它只会告诉你一个,并且官方并不保证是哪个键。最好的做法是在SCNKEY报告其他按键被按下或没有按键被按下之前,认为一个键仍然被按下,但第二个同时按下的键可能被忽略或替换第一个键。

如果你的程序不符合只有“一个”按键被按下的正统做法,那么你就得自己解决硬件问题。Codebase64提供了一些示例代码;我的简要版本是(已正确设置CIA,但它很可能已经适当配置):

  1. 向DC00写入一个字节,其中包含每行您想要同时扫描的0;
  2. 从DC01读取一个字节,并检查其顶部四位以找出选定行中哪些键被按下。

通用例程需要逐个测试每一行,以避免阴影效应 - 假设您存储了DC00中的位3和4中的0,以同时读取第4行和第5行,而您得到的结果顶部位清除,那么您将不知道v还是n还是两者都被按下,只知道至少一个键被按下。

在上面相同链接的底部可以看到英语键盘上的行和列表格;它们是物理键位布局的结果,因此其他语言的键盘也会像它们的键盘一样有所不同。如果你正在编写一个游戏,你更关心键位的布局而不是它们的符号,那么你就不必担心语言问题。


1
这类似于ZX Spectrum,有些游戏使用多行"阴影"来控制游戏,可以通过同一组按键控制键盘的多个行(例如"k/l"与"o/p"的操作方式相同.. (实际键盘布局不太确定,可能我记错了)。 对于某些游戏(如打砖块),几乎整个键盘都可以用作左/右方向键。 :D - Ped7g

3

是的,C64没有键重复功能(就像我现在输入的这个编辑器一样)。

通常解决这个问题的方法是轮询内存位置197,它保存当前的键盘扫描码。要尝试一下,请运行以下命令: 10 printpeek(197):goto10

你可以看到197的值变化了,并且实际上保持着它的值。当然,键值不是ascii,甚至不是petscii,但你可以尝试找出那些你感兴趣的键的扫描码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接