代码之家  ›  专栏  ›  技术社区  ›  Jeffrey Kern

NES编程-名称表?

  •  12
  • Jeffrey Kern  · 技术社区  · 15 年前

    我想知道NES是如何显示它的图形化肌肉的。我在网上研究了一些东西,并通读了一遍,但我想知道最后一件事:名字表。

    基本上,从我读到的内容来看,NES名称表中的每个8x8块都指向模式表中的一个位置,该位置保存图形内存。此外,名称表还具有属性表,该属性表为每个16x16块设置特定的调色板。它们像这样连接在一起:

    (假设16 8x8块) 名称表,其中b c d=指向sprite数据的指针:

    ABBB
    CDCC
    DDDD
    DDDD
    

    属性表,其中1 2 3=指向调色板数据的指针,其中<引用值位于左侧,^上方,'左侧和上方:

    1<2<
    ^'^'
    3<3<
    ^'^'
    

    因此,在上面的例子中,这些块的颜色是这样的

    1A 1B 2B 2B
    
    1C 1D 2C 2C
    
    3D 3D 3D 3D
    
    3D 3D 3D 3D
    

    现在,如果我把它放在固定屏幕上,效果会很好!因为NES的分辨率是256x240像素。现在,如何调整这些表以进行滚动?

    因为名称表0可以滚动到名称表1中,如果继续滚动,名称表0将再次换行。我得到的。但我不知道如何滚动属性表。从我在网上读到的内容来看,它为其分配属性的16x16块将导致屏幕边缘瓷砖上的颜色变形(如在SMB3中从左向右滚动时所见,反之亦然)。

    我担心的是,我知道如何滚动名称表,但是如何滚动属性表?对于intsance,如果我在屏幕的左侧有一个绿色块,将屏幕向右移动理论上应该会导致右侧的瓷砖也是绿色的,直到它们移动到更多的帧中,它们将恢复到正常的颜色。

    ~~~~编辑: 我想指出的是,我知道扫描线,X和Y。这个想法在我的脑海里闪过。

    假设我的年龄在10岁左右。这意味着我要在我的名字表中水平地读取10个值。这意味着我的第一列已经脱离屏幕,因为它的像素宽度只有8。但是,颜色属性保持不变,因为它的宽度为16。

    假设整个列的“颜色”属性为绿色,那么假设对用户来说,屏幕左侧的前6个像素将为绿色,屏幕上最右边的10个像素也应为绿色,我是否正确? 那么,我的假设是正确的吗,根据屏幕,左边?

    5 回复  |  直到 12 年前
        1
  •  2
  •   Michael Dorgan    15 年前

    This site 我相信你已经非常非常非常熟悉了。首先,我会说我从未为NES编程,但我对所有曾经发布的Gameboy硬件都非常有经验,并且NES与GB/DMG共享许多奇怪之处。我敢打赌,你要么要做以下几件事中的一件:

    1. 不要滚动属性表。确保你的水平沿你移动的方向都有相似的色块。我想很多第一代游戏都是这样的。

    2. 继续并允许有限的属性滚动-只需确保发生更改的区域是部分颜色共享的,或者是足够的备用,这样更改就不会被注意到。

    3. 拿出旧的skool atari 2600计时器,在hblank更新结束时,写一封信注册$2006,以完成所需的颜色交换,等待几次tics,然后在hblank返回期间恢复,以便下一行的左边缘不受影响。我有一种感觉,这是最常用的解决方案,但没有一个真正好的模拟器和耐心,这将是一个痛苦的屁股。它还将占用您的总体CPU使用量,因为您必须在多个扫描行的中断中等待,以完成您的效果。

    我希望我能给你一个更具体的答案,但希望这能有所帮助。感谢上帝,GB/DMG有一个稍微高级一点的滚动系统。:)

        2
  •  1
  •   mvanbem    15 年前

    《超级马里奥兄弟3》和《柯比历险记》都会在你滚动屏幕时在屏幕边缘显示彩色人工制品。我相信两款游戏都设置了空白屏幕左侧8个像素的位,所以0-8个像素会影响到任何一帧。

    如果我没记错的话,Kirby的冒险总是试图把那些颜色有问题的列放在屏幕的侧面,这样滚动起来就不那么引人注目了。我不认为不切换到垂直镜像就可以避免这些工件,这会带来自身的困难。

    免责声明:我写了5年的NES代码。

        3
  •  1
  •   alex    12 年前

    每个名称表都有自己的属性表,因此在从一个名称表滚动到另一个名称表时不应该有图形化的工件。如果你的游戏同时垂直和水平滚动,那么你所指的颜色问题实际上只是一个问题。您只有两个名称表,因此滚动两种方式都需要您将可见的屏幕拆掉。对于这个问题有各种各样的解决办法,可以在这篇Nesdev文章中找到一个很好的总结:

    http://nesdev.parodius.com/bbs/viewtopic.php?p=58509#58509

        4
  •  0
  •   FWishbringer    15 年前

    这个网站可能会有所帮助。 http://www.games4nintendo.com/nes/faq.php#4

    (搜索“2005/2006美元是怎么回事?”开始在那个区域阅读。)

    它基本上看起来是不可能达到完美的像素,但是那些将是你可能需要去寻找的位。

    希望我能得到更多的帮助。

        5
  •  0
  •   BenW    12 年前

    每个名称表都有自己的属性表。如果将游戏世界限制为两个屏幕,则只需编写一次名称表和属性表。当你试图让世界比两个屏幕大的时候,最困难的部分就来了。SuperMarioBros.1做到了这一点,它向右滚动,根据需要进行环绕,并在该列出现之前一次呈现一级一列的块(16像素)。我不知道如何有效地编码(记住,你只有一毫秒的vblank时间)。