Skip navigation
Welcome, Guest! Please Login or Join

Loading...

Nerdy Nights week 4 Color Palettes, Sprites, second app

Aug 8, 2012 at 10:15:18 PM
SomewhatEvil (15)

< Crack Trooper >
Posts: 149 - Joined: 08/08/2012
Illinois
Profile
Okay, I guess I just got confused when it said that it should look like Mario's hat. I guess I assumed the sample code was intending to also use the same colors as used in game, but I probably should have noticed that wasn't the case looking through the source.

Thanks for your help =)

Feb 16, 2013 at 9:28:05 PM
Samarth (0)
avatar
(Samarth Godara) < Tourian Tourist >
Posts: 22 - Joined: 02/15/2013
India
Profile
ok, question, why did u set the color palletes? wat will be the use of the colors your stored in the memory from $3F10?

Feb 16, 2013 at 9:33:42 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
I think he set the palette just to show how the data is transferred. But the pallet entries at 0x3000 are the background, and 0x3010 are sprites. 16 bytes. Not all the bytes are there. Keep the background color the same for each 4th entry as writes are mirrored down (3010 goes to 3000 entry.) and will screw up if not written right.

Feb 16, 2013 at 10:45:42 PM
Samarth (0)
avatar
(Samarth Godara) < Tourian Tourist >
Posts: 22 - Joined: 02/15/2013
India
Profile
but this is in the code sprite.asm :-



LoadPalettes:
LDA $2002 ; read PPU status to reset the high/low latch
LDA #$3F
STA $2006 ; write the high byte of $3F00 address
LDA #$00
STA $2006 ; write the low byte of $3F00 address
LDX #$00
LoadPalettesLoop:
LDA palette, x ;load palette byte
STA $2007 ;write to PPU
INX ;set index to next byte
CPX #$20
BNE LoadPalettesLoop ;if x = $20, 32 bytes copied, all done



that means palletes are loaded to $3F00, but i couldn't figure out, where is this data getting used in?

Feb 16, 2013 at 11:48:01 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
The data is loaded through the PPU $2007 register after wiriting $3f00 to PPUAddr because the data goes to the PPU, The CPU doesn't access the pallet RAM directly, it does it through the PPU. But the LDA palette,X loads the data from the array pointed to by the pallet label. Then, the STA $2007 store it to the PPU with then puts it to the area that the PPUAddr ($2006 register) points to.

Feb 17, 2013 at 2:01:29 AM
Samarth (0)
avatar
(Samarth Godara) < Tourian Tourist >
Posts: 22 - Joined: 02/15/2013
India
Profile
yup, i agree with that, but i am confused, about the use of storing that data into PPU ram, what happens of the stored data after $3F00? where are they loaded on screen? or where is the color seen on the screen? these colors are those which are included in background and sprites, but what is this data


.bank 1
.org $E000
palette:
.db $0F,$31,$32,$33,$0F,$35,$36,$37,$0F,$39,$3A,$3B,$0F,$3D,$3E,$0F
.db $0F,$1C,$15,$14,$0F,$02,$38,$3C,$0F,$1C,$15,$14,$0F,$02,$38,$3C

helping the sprite to color up?

because the sprite data [in mario.chr] is

0 0 0 0 0 0 1 1
0 0 0 0 1 1 1 1
0 0 0 1 1 1 1 1
0 0 0 1 1 1 0 0
0 0 1 0 0 1 0 0
0 0 1 0 0 1 1 0
0 1 1 0 0 1 1 0

0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 1 1 1 1 1
0 0 1 1 1 1 1 1
0 0 1 1 1 1 1 1
0 1 1 1 1 1 1 1

in the first 16 bytes, now how does the color from the palettes gets filled in sprite?

[question is - we have the shape of the sprite in mario.chr, and the colors in color palette, my question is how to choose color? ]

Feb 17, 2013 at 2:30:27 AM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
The data is put together and the put together data makes each pixel 2 bits. That's 4 different pixel values, which are then displayed as colors. 16 entries for $3000 (4 palettes of 3 colors+the universal color.), and 16 entries for $3010 (4 palettes of 3 colors, value 00 is transparent.) It uses 16 bytes per tile, and 2 bits per pixel. The palette for sprites is selected by OAM bits on the 2nd byte of OAM ($201,205,etc.), and the background color pallets are selected by attribute memory at the end of the nametable. Then it pulls the tile, and uses each of the 2 bits to pull the color. Sprite pixel 0 (00) is transparent. And the background tile color $00 is always pulled from $3000, also called the "universal" background color.

Feb 17, 2013 at 10:12:45 AM
Samarth (0)
avatar
(Samarth Godara) < Tourian Tourist >
Posts: 22 - Joined: 02/15/2013
India
Profile
i am heartly sorry sir, but i cann't understand wat you mean, can you expalin with detail? i think this is the thing which i wanted to hear...

or can you post any website which contains the detailed information of the stuff you said?

wat i understand is that the 16 byte data are 2 images of a tile, i.e. a pixel can be


pixel 1:

I tile II tile
0 0
0 1
1 0
1 1

and the result will contain the 2 bit of the color

but i dont understand the line
"The palette for sprites is selected by OAM bits on the 2nd byte of OAM ($201,205,etc.), "

because $0201 is the place to put the tile number to pick up the pattern from.

Feb 17, 2013 at 2:28:42 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
Okay, I used the wrong address. $202 has the pallet selection for sprites. Look at the last 2 bits on the attributes byte. It's clearly outlines in the first post with the meaning of the attribute bit. Look under SPRITES and then SPRITE DATA.

And the nametables you'll get to later. Basically it works the same way. 2 bits per tile group select the pallet they'll use.

Feb 18, 2013 at 1:30:12 AM
Samarth (0)
avatar
(Samarth Godara) < Tourian Tourist >
Posts: 22 - Joined: 02/15/2013
India
Profile
ok, the other 2 bits are the 2 l.s.b. of the 3rd byte of the sprite attribute bytes...

thanks dude, i think i got your point, thank you for you time it helped me a lot...

Mar 28, 2014 at 12:13:12 AM
Mega Mario Man (58)
avatar
(Tim ) < Kraid Killer >
Posts: 2314 - Joined: 02/13/2014
Nebraska
Profile
Originally posted by: KHAN Games
$xx,$00,$00,$00, $xx,$00,$00,$00, $xx,$00,$00,$00, $xx,$00,$00,$00 ;sprites
$xx,$00,$00,$00, $xx,$00,$00,$00, $xx,$00,$00,$00, $xx,$00,$00,$00 ;background


The first color in each of the 16 4-byte sections (designated here with x's) is the transparent color. Usually these all need to be the same, but I think basically whatever you have the first value set at, it will automatically make the other 7 first-bytes that same value. So don't be surprised if you try to change that color and nothing happens.
Yup, just learned this tonight trying to program my game. Really threw a wrench into what I was doing. I was thinking I get 4 colors, but really, you get 3 and a bonus forth if it happens to be apart of the background.



-------------------------
Current Project
Isometric Survival Horror

Older Projects
Tailgate Party, Power Pad Demo, Happy Hour

Links
Store, Facebook, Twitter


Edited: 03/28/2014 at 12:13 AM by Mega Mario Man

Mar 28, 2014 at 12:23:33 AM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
Basically:

$3F00,$3F04,$3F08,$3F0C are the background palettes. Only $3F00 is used for rendering, it's the background color. Sprite entries with the %00 bottom bits mirror down to the BG palette entries. So, $3F10 mirrors to $3F00, $3F14 mirrors to $3F04, etc. So you have to write the BG color to $3F10 too, or you will get an incorrectly colored background. The other entries do nothing, though, so those don't matter unless you store 3 values there for whatever reason. But that is something not mentioned here AFAIK, but can be important/problematic.

Aug 7, 2014 at 10:17:26 PM
spoonybard (0)

< Cherub >
Posts: 5 - Joined: 08/07/2014
Profile
Hi, I have a question about the DMA part. First of all, I have looked for information about DMA in general and more specifically for the Nes. Let me tell you what I understand so far.

The "classical" way of communication between CPU and PPU is to write data at the $2000 - $2007 CPU address range : this range of memory can be called the "communication ports" between the CPU and the PPU. But there is another way to move data from the CPU memory to the PPU memory (quick thought : does it work both ways ? CPU mem <--> PPU mem) by using DMA. DMA is a faster way to copy data between the CPU and PPU memories because we do not send data byte by byte like the CPU would do : the exchange of data by DMA does not involve the CPU (I even think I've read that during DMA, the CPU is not working).

Now, in the code, you send the sprite data which is stored at $0200 - $02FF in the CPU RAM. We send the origin address $0200 by writing first the low byte $00 at the CPU address $2003 and the high byte $02 at the CPU address $4014 which triggers the "DMA data exchange".

But we didn't give any information about how many bytes we transfer and we didn't tell where to
store it in the PPU memory. Is the number of bytes fixed for each DMA transfer ? Is the DMA transfer only possible for the sprites data, in terms of hardware : the hardware is such that the PPU memory range target is only the sprite data memory range ?

Thanks in advance.


Edited: 08/07/2014 at 10:39 PM by spoonybard

Aug 8, 2014 at 2:43:15 AM
thefox (0)
avatar
(Kalle Immonen) < Meka Chicken >
Posts: 533 - Joined: 07/08/2008
Finland
Profile
Originally posted by: spoonybard

The "classical" way of communication between CPU and PPU is to write data at the $2000 - $2007 CPU address range : this range of memory can be called the "communication ports" between the CPU and the PPU. But there is another way to move data from the CPU memory to the PPU memory (quick thought : does it work both ways ? CPU mem <--> PPU mem) by using DMA.
It does not work both ways, only CPU => PPU.

Originally posted by: spoonybard

DMA is a faster way to copy data between the CPU and PPU memories because we do not send data byte by byte like the CPU would do : the exchange of data by DMA does not involve the CPU (I even think I've read that during DMA, the CPU is not working).
Yeah, normal CPU instructions are not executed while a DMA is active.

Originally posted by: spoonybard

Now, in the code, you send the sprite data which is stored at $0200 - $02FF in the CPU RAM. We send the origin address $0200 by writing first the low byte $00 at the CPU address $2003 and the high byte $02 at the CPU address $4014 which triggers the "DMA data exchange".
This is slightly incorrect. You can only control the source address at a 256 byte granularity. So if you write $02 to $4014, the transfer will always start from $200. Simply put, the source address is writtenByte*256. The register at $2003 sets the destination address (0..255) at the PPU side, not CPU.

Originally posted by: spoonybard

But we didn't give any information about how many bytes we transfer and we didn't tell where to
store it in the PPU memory. Is the number of bytes fixed for each DMA transfer ? Is the DMA transfer only possible for the sprites data, in terms of hardware : the hardware is such that the PPU memory range target is only the sprite data memory range ?
Yes, the number of bytes is fixed at 256. Yes, the DMA can only be used to transfer sprite (OAM) data.

If you write $02 to $4014, what actually happens during DMA is functionally exactly equivalent to the following code:

LDA $200
STA $2004
LDA $201
STA $2004
... (lines stripped) ...
LDA $2FE
STA $2004
LDA $2FF
STA $2004

The advantage of DMA is that it is 4 times faster than using code like above (it reads from $200 in a single cycle, then writes to $2004 in a single cycle, rinse and repeat, whereas LDA and STA would take 4 cycles each).

-------------------------
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi

Aug 8, 2014 at 4:48:10 AM
spoonybard (0)

< Cherub >
Posts: 5 - Joined: 08/07/2014
Profile
I'm confused. If I understand what you're saying, since we wrote $00 at $2003, the data sent by DMA will be stored at address $00 in the PPU RAM. In total we have copied 256 bytes from address $200 (CPU side) to address $00 (PPU side). But I thought this range ($00 - $FF) in the PPU memory was the pattern table #0 for the sprites : the bytes that represent the 8x8 tiles for the sprites. But if I follow the code, we are sending the 4 bytes for a sprite (we are in fact sending 256 bytes of data but the 252 other ones are zeros) describing the position on the X (byte 3) and Y (byte 0) axes, the tile index number (byte 1) and the attributes (byte 2).

I found in the link below

http://badderhacksnet.ipage.com/badderhacks/index.php?option...

,in the section II) Pattern Tables $[0000-1FFF], that this is the starting memory region for sprite patterns (followed by the background patterns). The range $0000 - $0FFF is said to be for the sprite tiles but the autor does not mention the 4 bytes that describe the [X,Y] position, the tile number and the attributes. She/he explains the graphical interpretation of 2 bytes to form a sprite/background 8x8 pixels tile, but not the organization of the memory in this region.

The first 256 bytes starting from $00 to $FF (the ones we sent using DMA) are then followed by 64 * 2 = 128 bytes of sprite pattern tiles ?

Aug 8, 2014 at 5:46:58 AM
thefox (0)
avatar
(Kalle Immonen) < Meka Chicken >
Posts: 533 - Joined: 07/08/2008
Finland
Profile
Originally posted by: spoonybard

I'm confused. If I understand what you're saying, since we wrote $00 at $2003, the data sent by DMA will be stored at address $00 in the PPU RAM. In total we have copied 256 bytes from address $200 (CPU side) to address $00 (PPU side). But I thought this range ($00 - $FF) in the PPU memory was the pattern table #0 for the sprites : the bytes that represent the 8x8 tiles for the sprites.
There's a separate 256 bytes of memory in the PPU for the sprites. This memory is completely separated from other PPU memory that is used for background/sprite tiles and nametables. The registers at $2003 and $2004 address the 256 byte sprite memory (only).

-------------------------
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi

Aug 8, 2014 at 6:07:58 AM
spoonybard (0)

< Cherub >
Posts: 5 - Joined: 08/07/2014
Profile
Ok and this 256 bytes long memory is called the SPR-RAM. Now I understand why the DMA only needs the origin of the memory in the PPU side : every DMA transfer copies 256 bytes starting from a specified byte in the CPU memory, to the SPR-RAM located in the PPU.

Thanks a lot, you really did help me there !


Edited: 08/08/2014 at 06:13 AM by spoonybard

Aug 8, 2014 at 7:48:24 AM
spoonybard (0)

< Cherub >
Posts: 5 - Joined: 08/07/2014
Profile
Now I have a question concerning the graphic data in the PPU memory. Following the source code, I clearly see that the CPU sends the two palettes for the background and the sprites, then the sprite data by DMA into the SPR-RAM. However, I don't see the part where the pattern tables, the name tables and their attribute tables are sent to the PPU memory. Is there a directive that does this job ?


Edited: 08/08/2014 at 07:52 AM by spoonybard

Aug 8, 2014 at 8:09:45 AM
thefox (0)
avatar
(Kalle Immonen) < Meka Chicken >
Posts: 533 - Joined: 07/08/2008
Finland
Profile
Originally posted by: spoonybard

Now I have a question concerning the graphic data in the PPU memory. Following the source code, I clearly see that the CPU sends the two palettes for the background and the sprites, then the sprite data by DMA into the SPR-RAM. However, I don't see the part where the pattern tables, the name tables and their attribute tables are sent to the PPU memory. Is there a directive that does this job ?
In this case the program uses CHR-ROM, so it doesn't need to transfer the pattern tables to PPU, they will be visible in PPU's memory space at $0000-1FFF by default. Some other program might use CHR-RAM, in which case $0000-1FFF would be RAM and the program would have to copy the data from CPU memory to PPU memory manually with $2006 and $2007 writes.

Since the program only displays sprites, it doesn't need to upload nametables (the write to $2001 only enables sprite rendering). Same goes for attribute tables, which are really just a part of the nametables. If it did use background rendering, it would have to upload the nametable through registers $2006 and $2007.

-------------------------
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi

Aug 8, 2014 at 8:21:27 AM
spoonybard (0)

< Cherub >
Posts: 5 - Joined: 08/07/2014
Profile
Ok thanks again for your help.

Aug 13, 2014 at 9:29:01 PM
lazerbeat (0)

< Cherub >
Posts: 5 - Joined: 04/12/2014
Profile

 
Sprite DMA

  LDA #$00
  STA $2003 ; set the low byte (00) of the RAM address
  LDA #$02
  STA $4014 ; set the high byte (02) of the RAM address, start the transfer
I have a question about this bit of the code. Sorry if I am being really really silly here, but I don't understand why we are writing $02 to $4014, I thought the PPU was $2000 - $2007 and $4000 - $4017 were audio and controller ports? What am I missing here?

Aug 14, 2014 at 1:11:27 AM
NESHomebrew (20)
avatar
(Brad Bateman - Strange Brew Games) < King Solomon >
Posts: 4218 - Joined: 04/28/2008
Saskatchewan
Profile
Originally posted by: lazerbeat


 
Sprite DMA

  LDA #$00
  STA $2003 ; set the low byte (00) of the RAM address
  LDA #$02
  STA $4014 ; set the high byte (02) of the RAM address, start the transfer
I have a question about this bit of the code. Sorry if I am being really really silly here, but I don't understand why we are writing $02 to $4014, I thought the PPU was $2000 - $2007 and $4000 - $4017 were audio and controller ports? What am I missing here?

$4014 is the OAM DMA register.  http://wiki.nesdev.com/w/index.ph...


Aug 14, 2014 at 6:29:00 AM
lazerbeat (0)

< Cherub >
Posts: 5 - Joined: 04/12/2014
Profile
Ah ok! Thanks very much, I understand more clearly now!

Oct 12, 2014 at 6:58:38 PM
NeLaxt (0)

< Cherub >
Posts: 1 - Joined: 10/12/2014
Profile
-edit-
oh wait never mind I didn't read it right


Edited: 10/12/2014 at 07:06 PM by NeLaxt

Dec 30, 2014 at 1:16:49 AM
Dredster (0)
avatar
(Dred ) < Tourian Tourist >
Posts: 24 - Joined: 03/05/2013
Arkansas
Profile
So, I tried to change the palete by changing the values in .db, but it just came up a black screen. Does the directives only use certain values in the palette based on the Chr rom ? Is this what is meant by High and low byte like the pallet is based off the value of high or low byte ?  Also, not sure if it is covered latter on, but how do I start making a sprite from ground up ? I downloaded Nindraw the learning curve is hard to use. I wanted to fool around with changing the color and sprite formation for learning purposes. I opened up the mario.chr file with textedit and just got some weird unicode. What is that code or should I use like tile molester to open that up and mess with it ?

-------------------------
Sorry guys, but I think I got the last copy of Buzz and Waldog from Retrozone.


Edited: 12/30/2014 at 01:19 AM by Dredster