9

我正在尝试使用 Commodore 64 中的内核例程来实现游戏控制。

下面的代码有一个例外。每个按键都算作单个输入。eg: 一直按住按钮没有效果。每次移动都必须释放并再次按下。我怎样才能改变这种行为?只要按住键,我只想重复动作。

    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 
4

2 回答 2

10

SCNKEY不适用于需要多个同时按键输入的游戏。它是无状态的,只返回现在按下的“the”键——即,如果按下了两个,它只会告诉你一个,并且官方不保证是哪个。您可以做的最好的事情是考虑一个键仍然被按下,直到SCNKEY报告有其他东西被按下或没有被按下,但是关于第二个同时按键是否被忽略或替换第一个的可能性是偶数。

如果您的程序不符合只有被按下的“那个”键的正统观念,那么您将不得不自己敲击硬件。Codebase64提供了一些示例代码;我的摘要版本是(正确设置了 CIA,尽管它可能已经正确配置):

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

一个通用例程需要单独测试每一行以避免阴影——假设您要求通过将 0 存储到 DC00 的第 3 位和第 4 位来同时读取第 4 行和第 5 行,并且您得到的结果的最高位是清晰的,您不会知道是否按下了 v 或 n 或两者都被按下,只有其中至少一个被按下。

有关英语键盘上的行和列的表格,请参见与上述相同链接的最底部;它们是物理按键布局的结果,因此其他语言的键盘差异也会如此之大。如果您正在编写游戏,并且您对按键的布局比对它们的符号更感兴趣,那么您不必担心语言。

于 2016-12-21T14:46:32.600 回答
3

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

解决这个问题的典型方法是轮询内存位置 197,它保存当前的键盘扫描代码。要试用它,请运行: 10 printpeek(197):goto10

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

于 2017-08-25T07:30:26.467 回答