Atari 2600的游戏非常受约束。当沃伦罗宾特首先投球时,这是一个会成为冒险的想法,你会探索一个有很多房间的游戏,然后拿起物品来帮助你,他被否认,因为它不是可行的。这样做是有意义的。这是70年代末期;之前从未有过多个屏幕的游戏。这是在太空入侵者和PAC人的日子里,当一场比赛中的一切都是在玩家前面的时候,所以冒险能够在1980年终于发布时拥有30间房间的事实非常令人印象深刻。
冒险的开放屏幕。播放器控制点(罗宾特称为#39;男人')。
电视屏幕上显示的每个区域都有一个或多个障碍或墙壁,通过您无法通过。有一个或多个开口。从一个区域移动到邻近区域,移动"关闭"电视屏幕通过其中一个开口,相邻区域将在电视屏幕上显示。
拥有多个房间是完全创新的创新,以及冒险设施拥有30个的事实是革命性的。但是,大卫起重机和1983年发布的陷阱!所有这些都比冒险中的任何东西都更加精致(图形)。在本文中,我们'请谈谈这是如何完成的。
游戏超人有多个房间,在冒险之前发布,但实际上是基于冒险和#39; S代码。
但为了充分欣赏这样一个壮举的难度让' s注意atari的程序员面临的困难。控制台本身只有128个字节的RAM。那个' s 1024位。例如,如果在ASCII中编码,则这句话单独占用更多空间,更不用说它' s实际编码的UTF格式。足以说Atari上没有太大的空间。
但是,无论如何,禁止盒装本身提供足够的空间,对吧?好吧,有点。 Atari 2600箱在这一点上一般有4千字节的ROM,绝大多数必须致力于实际代码。如果我们忽略存储代码的需要,我们可以专用每房间16个字节,但当然我们可以' t忽略存储代码所需的空间。
Atari 2600的可寻址空间实际上只有2k。通过一种名为Bank交换的技术实现4K。
在没有存储太多数据的情况下使一个大型世界的方式是通过让一些代码为您生成它。
但是,这是最大的问题是,您通常需要保存生成的数据。这是流氓和MINECRAFT等游戏。他们随机生成世界,以便为玩家提供品种,但一旦生成的'生成的数据。 Atari的局限性不起这种奢侈品。
起重机以两种方式夸大了这一点。第一个是他代表了一个房间的途中,第二个是他在他生成这些陈述的方式。生成这些表示的方式实际上避免了存储在内存中当前房间的任何东西的需要,但是我们稍后会到达那个。首先,我们将研究当前房间的代表。
起重机使用单个字节来表示当前房间的布局。在任何特定的房间里,尤其可能看起来令人难以置信,但它实际上非常简单。
保持当前房间布局的字节被分成四个部分:
对象产生的前三个位控制。这两件事都很复杂,两者都由比特3至5控制。
首先,房间可以包含宝藏(如果位3至5的情况为101)。如果它确实包含宝藏,则不会出现由比特确定的通常项目,并且相应的宝藏将放入其位置。
其次,如果有鳄鱼(如果位3到5为100),则位0至2为010,011,110或111,导致允许玩家在Croc上摆动的vine。否则不会有藤蔓,强迫玩家跳上鳄鱼的头部来跨越。物品和宝藏的规则是
我总是先写下高位,所以' 100'将更准确地称为位5到3。
位6和7确定树的图案。这并不影响游戏玩法,但是给出了播放器的变化感。树形图案都非常相似,所以我在这里赢得了'如果你想看看他们自己是什么,你可以看看1,2,3和5的房间里的树木分别为11,10,00和01。
位7被重用以控制左侧或右侧是否绘制地下的墙壁。它并不控制在代码中的其他地方,但是如果有墙,但如果有墙,那么这个位为0,左边是左边的墙,这一点是一个1将墙放在右侧。
和#39; S单个字节如何确定当前房间的布局。但就像我提到的那样,只有当前的房间才能存储在内存中。这是如何成为可能的是房间的产生方式。
描述房间的字节由起重机称为多项式计数器的东西生成,但我们现在呼叫线性反馈移位寄存器或LFSR。
LFSR是通过采用二进制数来从种子生成伪随机数的方式,执行左或右一个,然后通过原始位的线性函数计算输入比特。通常,此功能是一系列XORS。
当玩家开始游戏时,房间字节将在十六进制中设置为C4(在十进制的二进制,196中的11000100中)。这是种子。当播放器向右移动一个房间时,字节向左移动,低位(位0)变为位3,4,5和7的XOR
在哪里' +'表示XOR,PRIME表示先前状态的一点。该模式具有作为最大长度LFSR的理想特性,这意味着它将产生8位的每个组合保存所有零。这允许世界陷入困境!拥有最多数量的房间以及任何给定的位数的平等可能性(再次保存,所有零)。
因此,当您在第一个房间后向右移动时,字节从11000100到10001001。所有位都移位,然后将位0设置为1,为1 = 0 + 0 + 0 + 1。
;房间' =室<< 1 | (Bit3 + Bit4 + Bit5 + Bit7)Loop_room:LDA室ASL房间ASL房间ASL ASL ASL EOR Room ASL ROL Room Dex BPL Loop_room
房间是描述当前房间的字节。在进入这是如何工作的之前,它很重要的是要注意最后两行,以及为什么这是一个循环。起重机想要它,这样如果捕捉哈利(陷阱中的英雄!)在地下,那么走过房间实际上将他运送到三个房间。如果前面的计算是N个' t负数,则DEX递减X寄存器和BPL分支,因此起重机通过将X寄存器设置为2,在调用此子程序之前将X寄存器设置为2,如果Harry在地下,请在调用此子程序之前。否则,X寄存器设置为0和#39;否循环。
更准确地说,房间是内存中的位置,其中描述了房间的字节。
所以它'为什么它' s循环。其余的代码是,作为Atari的汇编代码通常是致密的。这是一个大约6502个装配的文章,所以我赢得了太多细节,但基本上正在发生' s' asl(算术偏移左)命令将比特移动到正确的地方,以及EOR(独占或)命令是XOR-ING。最后,ROL(旋转)命令将房间字节转移到左侧,同时将携带位输入到位0.携带位是先前EOR' s和ASL的结果。所有这一切都会产生所需的行为。
如果我们希望看到这一点的每个房间,我们都可以使用以下6502个装配,通过上面的代码循环,直到字节返回到它开始的内容并存储每个生成的字节,以便在地址$ 00到$ ff(0到255)。
LDA#0;初始化地址偏移到0税定义房间$ 00定义种子$ C4 LDA #seed STA Room_room:;所有的LFSR内容ASL房间ASL房间ASL ASL ASL ASL ROL ROL ROOL LDA Room Inx;递增地址偏移sta $ 00,x;存储生成的byte cmp #seed;如果我们完成一个循环beq stop jmp loop_room;得到下一个房间字节停止:brk
但这并不是为了为什么起重机和#39;设计是如此天才。上述详细信息当你对的时候会发生什么,但是当你离开时,呢?回到你来的地方?描述房间的八个比特从未存储在内存中;只有当前的房间内存。陷阱如何!把手留在左边?好吧,使用此LFSR:
我' m与术语有点松散。技术上' lfsr'指寄存器采取行动,但这里是我' LL使用该术语来指代计算输入位的公式。
什么'特别的关于这个lfsr是它是前一个的反比力。每次剩下,这次LFSR都会撤消当您正确使用的LFSR完成的工作。从这里的we' ll将此LFSR称为左LFSR,以及前一个LFSR。
;房间' =房间>> 1 | ((Bit4 + Bit5 + Bit6 + Bit0)* 128)Loop_Room:LDA室ASL房间ASL ROR ROL ROL EOR ROOL LSR ROR ROR ROR ROR ROR ROOR BPL Loop_room
您可能会注意到此LFSR也标记为Loop_room。这是从拆卸,我们不知道最初称之为这段代码的起重机,但它很好,它们与他们共享相同的标签。这是因为分支命令(例如,BPL)最多只能将程序计数器偏移255,并且这两个标签被分开约1000个指令。跳跃更大的距离,您需要JMP或JSR命令,这些命令是无条件跳转。
让'据欣赏起重机拍了一下。他发现了一种可旋转和最大长度的LFSR。那些令人印象深刻的编程。但我赢了' t只是请你把我的话语拿到这两个lfsrs是反演,我' ll证明你。
考虑一系列八位B = B 7 B 6 B 5 B 4 B 3 B 2 B 1 B 0. WE' LL在施加右LFSR和B L之后使用B r表示B表示B留下LFSR。我们想要显示的是B RL = B LR = B.也就是说,我们希望展示应用右边的结果,然后左LFSR,或左侧,然后右侧,与无效相同。
正式,我们'重新显示的是,任一阶的两个函数的组成等于身份函数,这将使两个功能通过定义反转。
将此应用于B = B 7 B 6 B 5 B 4 B 3 B 2 B 1 B 0我们得到以下内容:
这建立了B RL = B的事实。显示B LR = B是相同的,因此留下读者的练习。 ∎
上面也可以用一些简单的代码来验证,所以如果您想尝试在这里''' ll做这项工作。还包括一个列出所有房间的函数。
那个'如何陷阱!建立它的世界。一种简单的表示与可逆的线性反馈移位寄存器组合。
您会将关于游戏的所有信息作为有影响力和流行的陷阱!将是普遍的,随时可用。不是这种情况。
游戏'使用LFSR是众所周知的,但据我所知,它是如何实施的,而不是在实际装配中详细介绍。但是当我发现大会的分析和评论版本时,LFSR给出的描述实际上是不正确的!至少,左LFSR的描述不正确。但它以相当明显的方式出现了错误,而且难以弄清楚正确的方式。
最初评论称,递减LFSR将XOR-ing与1位而不是0位。它现在是固定的。
更多涉及的是弄清楚字节如何实际翻译成世界。无处可见,不在任何谈话,任何网页,任何书籍或在评论中的源代码中,是描述了什么系列比特对应于房间内的模式的比赛。起初我试图经过大会,但为Atari写的大会是如此优化,言辞,并使用这么多技巧,对我来说显而易见的是,这将是太多麻烦的方式。
那我是怎么做到的?嗯,我写了一个小程序来生成LFSR的序列(与上面链接的JavaScript程序),我将其与房间进行比较。为位7进行这一点,它控制屏幕侧面的地下墙壁上绘制,很容易,而不是控制树木的比特6和7。但对于其他人来说,它相当乏味。这张地图是一个宝贵的资源。
我惊讶的是,据我所知,我是第一个细节的陷阱!呈现世界,但我也有点失望。如果你没有看到这个GDC谈论绝对应该保护你的游戏历史。与许多其他学科不同,软件历史并不完全保存,即使它应该是最容易的保护。我们拥有原始源代码的Atari,NES,Snes,ColeCovision,您将其命名为。拆卸是宝贵的,不要让我错了,但他们不是原来的。他们没有任何关于原始评论的信息。
也许如果我们'重新幸运的Activision和Atari和Nintendo在一个保险库中的所有原始代码,它们' ll自由地释放到公众身上,为人类的好处,但我没有屏住呼吸 。 能够努力保存他们可以努力的每个人都可以努力,'因为它不会保护它。