snes :fe4 rom hack for the graphic and animate #2

今天从昨天那里开始继续读代码,由于今天有课,加上脑袋有点晕,所以笔记没做好,现在只能凭记忆写了。

看了篇有关DMA的文章:
For example, suppose I wanted to copy a 32 x 32 character
screen map (ie. $800 bytes) from location $18000 in ROM into
location $0000 of VRAM. I could do this using DMA channel 0
with the following code (A is 8-bits, X & Y are 16-bits).

    ldx.w #$0000    ; set VRAM pointer to $0000
    stx $2116
    lda #$01        ; control value for "normal" DMA
    sta $4300
    lda #$18        ; dma to $2118
    sta $4301
    ldx.w #$8000    ; source offset
    stx $4302
    lda #$01        ; source bank
    sta $4304
    ldx.w #$0800    ; number of bytes
    stx $4305
    lda #$01        ; enable DMA channel 0
    sta $420B

如果他不是just a example,即代码是正确的话,那么在rom中的地址应该是1d204开始的$78个字节的空间载入到$2118,而$2118就是Video port data,我把这段空间贴出来,由于这段data是直接输出到Video port data的,所以我猜想,可能采用的算法是这片文章说描述的图形处理储存方式:
SPRITE DOC
------------------------------------------------------------

if you haven't already obtained "yoshi doc", get it and read it before you
read this doc....


Part I - the bitplane representation of a 16 color 8x8 pixel tile
-----------------------------------------------------------------

sprites are made of tiles, in particular 4-bitplane tiles, 4-bitplane
tiles, means that the tiles are made of 4-bit color values, so this means
that the tiles can have a maximum of 16 colors.

in many graphics formats, this type of data would be stored as follows
(assuming a 8 pixel by 8 pixel tile)

                        $1 $0 $2 $8 $2 $4 $5
                        $2 $0 $6 $1 $f $e $1
                        $a $2 $2 $2 $6 $7 $0
                        $1 $0 $2 $8 $2 $4 $5
                        $1 $0 $2 $8 $2 $4 $5
                        $1 $0 $2 $8 $2 $4 $5
                        $1 $0 $2 $8 $2 $4 $5
                        $1 $0 $2 $8 $2 $4 $5

where each hex number represents a color, so pixel (0,0) would be color
number "1", and pixel (4,2) would be color "6"....this is <not> the case
on the super nintendo....for reasons having to do with the implementation
of the graphics engine, the super nintendo represents its image data in
the "bitplane" format, assuming and 8 pixel by 8 pixel tile with 16
colors, this data would have four bitplanes (0-3) of monochrome, binary
image data:


                        0 0 0 0 0 0 0 0
                        0 0 0 0 0 0 0 0 1
                        0 0 0 0 0 0 0 0 1 2
                        0 0 0 0 0 0 0 0 1 2 3
                        0 0 0 0 0 0 0 0 1 2 3
                        0 0 0 0 0 0 0 0 1 2 3
                        0 0 0 0 0 0 0 0 1 2 3
                        0 0 0 0 0 0 0 0 1 2 3
                          1 1 1 1 1 1 1 1 2 3
                            2 2 2 2 2 2 2 2 3
                              3 3 3 3 3 3 3 3


four monochrome 8x8 pixel images stacked on top of each other. if you
wanted pixel (4,2) to have the color "6" you would have to put a "1" in
bitplane one, and a "1" in bitplane two, with the bitplane zero and three
having "0"'s.  this is because the binary representation of "6" is "0110".

ok, so it is obviously possible to store each monochrome bitplane in 8
bytes, each byte representing a row in the bitplane. so a single tile
takes up 32 bytes (8 bytes per row * 8 rows * 4 bitplanes) of memory.


Part II - the way tiles are stored in vram for sprite data
---------------------------------------------------------

in vram you store a tile 16 bits at a time as follows:

                <-------2 bytes at a time------>
                <--1 byte wide-><--1 byte wide->

                [plane 0, row 0][plane 1, row 0]
                [plane 0, row 1][plane 1, row 1]
                [plane 0, row 2][plane 1, row 2]
                               ..
                               ..
                               ..
                [plane 0, row 7][plane 1, row 7]
                [plane 2, row 0][plane 2, row 0]
                [plane 2, row 1][plane 2, row 1]
                [plane 2, row 2][plane 2, row 2]
                               ..
                               ..
                               ..
                [plane 2, row 7][plane 2, row 7]


the super nintendo can have two different sizes of sprite on the screen
at one time, you can choose from the following combinations:
       
      [value]      [sprite size 0][sprite size 1]
        000           8x8 pixel     16x16 pixel
        001           8x8 pixel     32x32 pixel
        010           8x8 pixel     64x64 pixel
        011          16x16 pixel    32x32 pixel
        100          16x16 pixel    64x64 pixel
        101          32x32 pixel    64x64 pixel

it is set in the upper three bits of address $2101....so to use 8x8 pixel
sprites, and 32x32 pixel sprites, you would load $2101 with the value
"001xxxxx" (where x is don't care)

the lower five bits of address $2101 are also very important, these bits
tell the super nintendo where in vram your sprites are located. the
lowest three bits are the "name base", and the fourth and fifth bits are the
"name". the "name" bits specify the upper 4k word of the sprite address,
and the "name base" specfies the offset. so if put you tile data in vram
$0000 you would set these bits all to zero.

suppose you want to have four 32 pixel by 32 pixel sprites; each would be 
composed of 16 tiles, each tile is numbered, tiles $0-$3f

                        [sprite 0]
                        0  1  2  3
                        4  5  6  7
                        8  9  a  b
                        c  d  e  f
       
                            ..         
                            ..

                        [sprite 3]
                        30 31 32 33
                        34 35 36 37
                        38 39 3a 3b
                        3c 3d 3e 3f
                       
in vram, these tiles, $0 through tile $3f would be store in an interlaced
fashion as follows:


$0  $1  $2  $3  $10 $11 $12 $13 $20 $21 $22 $23 $30 $31 $32 $33
$4  $5  $6  $7  $14 $15 $16 $17 $24 $25 $26 $27 $34 $35 $36 $37

do you see the pattern? you must store the first row (four tiles) of each
sprite, and then the second row, then the third, etc....

if you were dealing with 8x8 sprites, you would have to store the first
row of 16 sprites, then the second row of the 16 sprites, etc....

if you were dealing with 16x16 sprites, you have to store the first row
of 8 sprites, then the second, then the third, etc...

with 64x64, yep, you guessed it, the first row of two sprites, then the
second row, etc....



Part III  - setting up the OAM table for your sprites
-----------------------------------------------------

for each sprite in the sprite table (maximum of 128 sprites, numbered 0-127)
you must have four bytes of information, the first byte is the low 8 bits of
the horizontal position of the sprite, the second byte is the vertical
position of the sprite, the third byte is the "address" of the sprite...
it is not the actual vram address, it is the tile number, that is to say,
the physical vram address of the sprite can be obtained by the following:
multiply the sprite "address" by 32 (because each tile is 32 bytes) and add it
to the starting vram address that you set in the $2101 register.
this tile number points to the first tile in the sprite...the snes expects the
rest of tiles to follow in the order described in the previous section...
the next byte containes the 9th bit of the tile "address" and a few attributes

                                bit 0   = 9th bit
                                bit 1-3 = palette number
                                bit 4,5 = playfield priority
                                bit 6   = horizontal flip
                                bit 7   = horizonal flip

the palette number is not a 4 bit number, so obviously, you can only choose
between 8 of the 16 palettes....if you set these bits to all 0, you will be
selecting the eigth palette (palette 7), if you set them to "001" it is the
ninth palette etc...it was trial and error, and some <serious> frustration
before i figured this one out :)

to set these bytes in the OAM table, you must first setup the OAM "address"
on the 16 bit register $2102 (and $2103). again this is not a real address,
you use the 7 lowest bits of this address to select which sprite you
would like to set the data for (sprite 0 to sprite 127)

then you can write the four bytes discussed above to the register $2104, its
like the color register, auto incrementing...

so....what are all the other bits for??? (the remaining 9) well, i know about
only two others, the highest bit (bit 15) is a sprite priority bit, it is
basically the bit you set to "turn on" the sprite, and keep it being redrawn
on the screen...its a little more than this, but thats all i know about its
behavior.  so when you setup your table, (and periodically throughout the
sprites' display lifecycle) you must set this bit high....(for any sprite being
displayed)

there is another small table (32 bytes) that you must load into the OAM, these
consist of two bits for every sprite, one of the bits being the 9th horizontal
position bit, and the other is the size select bit (remember we can pick from
two different size sprites on the screen at once) the first bit is the
most significant horizontal location, and the second is the size toggle
bit...

to write this table the OAM, you must set the 9th bit of the "address" in $2103
to one....then write the bytes, again it is an auto incrementing register

make sure that you have enabled the sprites to be on a particular plane (see
the yoshi doc, on $212C....and make sure that you have set your palette
correctly (remember sprite palette 0 is the 8th palette!!!)

好像有点多……不过狼组的翻译了的,虽然我觉得他翻译的有很多错误,会产生很多误解。

关于OAM即使sprite,我从以下的内容推断,应该就是我所要的东西:
在程序段中,完成了DMA的操作之后,接下来的就是bg1~bg4的设置(bg4在fe4的战斗画面中没有用到)
而这些bg的水平和竖直偏移量和游戏中显示的大体一样,这些执行完了后,是一段spu的处理,应该是击中后的音效。接着就返回joypad的了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值