#115849 - philip - Fri Jan 19, 2007 4:23 pm
I want to have two 16 bit backgrounds on my main screen. I've been looking at the tutorial at: http://www.double.co.nz/nintendo_ds/nds_develop10.html
That example only covers one background, so I guess I can create two doing the following:
Code: |
videoSetMode(MODE_5_2D | DISPLAY_BG2_ACTIVE | DISPLAY_BG3_ACTIVE);
vramSetBankA(VRAM_A_MAIN_BG_0x6000000);
BG2_CR = BG_BMP16_256x256;
BG3_CR = BG_BMP16_256x256;
|
I would then set registers for scaling etc.
Except that there won't be enough memory to do two 16 bit backgrounds, so how do I allocate a second VRAM bank?
Also, what memory do I write to in order to draw to BG3? The example only writes to BG2 using the BG_GFX define.
#115851 - Lick - Fri Jan 19, 2007 4:55 pm
There are 5 questions you need to ask when using backgrounds:
1) Have you assigned enough videomemory with the memorybanks?
- Visit Dev-Scene.com for the VRAM tables and see if the memory is enough to hold your Background Types (check the table for memory usage of each type).
Use vramSetBankA/B/C/D/E/F/G/H/I to assign the videomemory. Check out the VRAM table for parameters for each of those functions. Example:
Code: |
vramSetBankB(VRAM_B_MAIN_BG_0x6020000); |
2) Did you set the right blockbase for the background-controlregister?
- Visit Dev-Scene.com for the parameters for the background-controlregisters.
If you're using multiple backgrounds, you need to use BG_TILE_BASE and BG_MAP_BASE (tiled backgrounds) or BG_BMP_BASE (bitmap backgrounds), to specify the offset in the BG_GFX. The offset is calculated in blocks. For example, the BG_GFX starts at 0x06000000, and you want a bitmap background that starts at 0x06000000 + offset, then you must specify that by using BGx_CR = ... | BG_BMP_BASE(block). block depends on the offset. Read more about blocks.
Code: |
BG0_CR = BG_BMP16_128x128 | BG_BMP_BASE(0) | BG_PRIORITY(0);
BG1_CR = BG_BMP16_128x128 | BG_BMP_BASE(16) | BG_PRIORITY(1); |
3) Did you write your data to the correct offset?
- Like I just said, the blockbase and offset have to point to the same location. If you set the block like BG_BMP_BASE(n), you can use BG_BMP_RAM(n) to get a pointer to the correct location. So write your data to BG_BMP_RAM(n), BG_TILE_RAM(n), BG_MAP_RAM(n).
Code: |
memcpy(BG_BMP_RAM(0), data_bin, data_bin_size);
memcpy(BG_BMP_RAM(16), data2_bin, data2_bin_size); |
4) Are the priorities set?
- If you enabled more than 1 background, then you have to worry about the priority (order) of the background.
Use BG_PRIORITY(n) to set a value of 0, 1, 2 or 3. Note that a priority of 0 (highest) will be drawn over a priority of 3 (lowest).
Code: |
BG0_CR = BG_BMP16_128x128 | BG_BMP_BASE(0) | BG_PRIORITY(0);
BG1_CR = BG_BMP16_128x128 | BG_BMP_BASE(16) | BG_PRIORITY(1); |
5) If you're using an Extended Rotation BG, don't forget to set transform variables!
Code: |
// Transforming the BG: default
BG3_XDX = (1<<8); // fixed point 8.8
BG3_XDY = 0;
BG3_YDX = 0;
BG3_YDY = (1<<8); // fixed point 8.8
// Positioning the BG: default
BG3_CX = 0; // negative value = positive offset
BG3_CY = 0; // so x(-10) will move it pixelx(10) |
[edit] Re-reading my own post, I found out that I suck at explaining! XD
_________________
http://licklick.wordpress.com
Last edited by Lick on Fri Jan 26, 2007 6:08 pm; edited 1 time in total
#116074 - philip - Sun Jan 21, 2007 6:33 pm
Lick wrote: |
There are 4 questions you need to ask when using backgrounds:
1) Have you assigned enough videomemory with the memorybanks?
|
So I would use the following for two 16bit backgrounds:
Code: |
vramSetBankA(VRAM_A_MAIN_BG_0x6000000);
vramSetBankB(VRAM_B_MAIN_BG_0x6020000);
|
Is that right?
Quote: |
2) Did you set the right blockbase for the background-controlregister?
- Visit Dev-Scene.com for the parameters for the background-controlregisters.
If you're using multiple backgrounds, you need to use BG_TILE_BASE and BG_MAP_BASE (tiled backgrounds) or BG_BMP_BASE (bitmap backgrounds), to specify the offset in the BG_GFX. The offset is calculated in blocks.
|
So I would use:
Code: |
BG2_CR = BG_BMP16_256x256 | BG_BMP_BASE(0) | BG_PRIORITY(0)
BG3_CR = BG_BMP16_256x256 | BG_BMP_BASE(64) | BG_PRIORITY(1)
|
Because the backgrounds are 128k in size?
Quote: |
3) Did you write your data to the correct offset?
- Like I just said, the blockbase and offset have to point to the same location. If you set the block like BG_BMP_BASE(n), you can use BG_BMP_RAM(n) to get a pointer to the correct location. So write your data to BG_BMP_RAM(n), BG_TILE_RAM(n), BG_MAP_RAM(n).
|
Right, so I just write data to address BG_BMP_RAM(64) to draw background 3?
Okay, I think I understand now. Thanks a lot, I'll give it a try!
#116158 - philip - Mon Jan 22, 2007 6:00 pm
Would I be right in assuming that if I used 8-bit backgrounds instead, I could make parts of them transparent by just clearing bit 15 in one of the palette colours, and using that colour to make areas transparent?
#116163 - Sausage Boy - Mon Jan 22, 2007 6:48 pm
No :P
Actually, transparency with 8-bit backgrounds work by setting a pixel to palette entry 0. No matter what you have in palette at 0, the pixel will be transparent. But, palette index 0 controls the background color, the color that shows up when no other pixels are shown.
_________________
"no offense, but this is the gayest game ever"
#116166 - Lick - Mon Jan 22, 2007 7:28 pm
philip wrote: |
Would I be right in assuming that if I used 8-bit backgrounds instead, I could make parts of them transparent by just clearing bit 15 in one of the palette colours, and using that colour to make areas transparent? |
In 8-bit backgrounds, each pixel is 1 byte (8bit) and contains an index to the background palette (BG_PALETTE). Like Sausage Boy said, BG_PALETTE[0] is transparent, so simply set the byte/pixel to 0. (You might still see a color, because BG_PALETTE[0] is also the 'no color' color. Like Sausage Boy said.)
In 16-bit backgrounds, each pixel is 2 bytes (16bit) and contains the color of that pixel. 1-5-5-5 is the number of bits for A-R-G-B (or A-B-G-R). So the bit at the left is the alpha bit; by setting it to 1 makes the pixel visible, setting it to 0 makes it invisible.
Code: |
1 | 00011 | 00011 | 00011 = visible
0 | 00011 | 00011 | 00011 = invisible
visible = (3<<10) | (3<<5) | 3 | (1<<15);
invisible = (3<<10) | (3<<5) | 3;
|
Some of the DS screens are ABGR. On the DS Lite, both screens are. On the regular DS, only the top screen is.
_________________
http://licklick.wordpress.com
#116177 - Sausage Boy - Mon Jan 22, 2007 10:28 pm
Note that the RGB/BGR stuff doesn't really affect your programming in any way. The pixels are stored the same way, it's just the little color dots in the lcd's that are arranged differently. The only time you need to care about this is if you're trying to do subpixel rendering.
_________________
"no offense, but this is the gayest game ever"
#116183 - Lick - Tue Jan 23, 2007 12:28 am
Sausage Boy wrote: |
Note that the RGB/BGR stuff doesn't really affect your programming in any way. The pixels are stored the same way, it's just the little color dots in the lcd's that are arranged differently. The only time you need to care about this is if you're trying to do subpixel rendering. |
Hmmm.. So the pixels on screen are BGR, but the values are still ARGB? I think I had that confused for quite a while until a second ago, hehe. Thanks Sausage Man.
_________________
http://licklick.wordpress.com
#116200 - tepples - Tue Jan 23, 2007 2:43 am
They're RGBA, little-endian.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#116244 - philip - Tue Jan 23, 2007 5:17 pm
Lick wrote: |
3) Did you write your data to the correct offset?
- Like I just said, the blockbase and offset have to point to the same location. If you set the block like BG_BMP_BASE(n), you can use BG_BMP_RAM(n) to get a pointer to the correct location. So write your data to BG_BMP_RAM(n), BG_TILE_RAM(n), BG_MAP_RAM(n).
|
The guide you linked to says each block is 2K, but in video.h, the BG_BMP_RAM() macros is defined thus:
Code: |
#define BG_BMP_RAM(base) (((base)*0x4000) + 0x06000000)
|
Which indicates they're actually 16K. Huh?
#116247 - Mr Snowflake - Tue Jan 23, 2007 5:39 pm
philip wrote: |
In 16-bit backgrounds, each pixel is 2 bytes (16bit) and contains the color of that pixel. 1-5-5-5 is the number of bits for A-R-G-B (or A-B-G-R). So the bit at the left is the alpha bit; by setting it to 1 makes the pixel visible, setting it to 0 makes it invisible.
Code: | 1 | 00011 | 00011 | 00011 = visible
0 | 00011 | 00011 | 00011 = invisible
visible = (3<<10) | (3<<5) | 3 | (1<<15);
invisible = (3<<10) | (3<<5) | 3;
|
|
I get this, but which converter proggie allows sets the correct alpha values? Or should I always do it myself?
_________________
http://www.mrsnowflake.be
#116252 - tepples - Tue Jan 23, 2007 6:04 pm
philip wrote: |
The guide you linked to says each block is 2K, but in video.h, the BG_BMP_RAM() macros is defined thus:
Code: |
#define BG_BMP_RAM(base) (((base)*0x4000) + 0x06000000)
|
Which indicates they're actually 16K. Huh? |
On at least the GBA in tile modes, each map block is 2 KiB, while each tile data block is 16 KiB. Extended rotation may screw with this rule of thumb.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#116317 - Lick - Wed Jan 24, 2007 11:14 am
The link was wrong about that. Whatever the libnds headers say about the 2D hardware, is probably right. So map blocks = 2 KiB, tile/bmp blocks = 16 KiB.
_________________
http://licklick.wordpress.com
#116336 - philip - Wed Jan 24, 2007 3:34 pm
Lick wrote: |
The link was wrong about that. Whatever the libnds headers say about the 2D hardware, is probably right. So map blocks = 2 KiB, tile/bmp blocks = 16 KiB. |
But when I set the background control registers, do I still deal with the blocks as 2k or 16k?
So is it:
Code: |
BG3_CR = BG_BMP16_256x256 | BG_BMP_BASE(64) | BG_PRIORITY(1)
|
or:
Code: |
BG3_CR = BG_BMP16_256x256 | BG_BMP_BASE(8) | BG_PRIORITY(1)
|
??
#116339 - philip - Wed Jan 24, 2007 4:05 pm
Answering my own question, it should be BG_BMP_BASE(8)
#116544 - Lick - Fri Jan 26, 2007 6:05 pm
5) If you're using an Extended Rotation BG, don't forget to set transform variables!
Code: |
// Transforming the BG: default
BG3_XDX = (1<<8); // fixed point 8.8
BG3_XDY = 0;
BG3_YDX = 0;
BG3_YDY = (1<<8); // fixed point 8.8
// Positioning the BG: default
BG3_CX = 0; // negative value = positive offset
BG3_CY = 0; // so x(-10) will move it pixelx(10) |
_________________
http://licklick.wordpress.com
#117225 - philip - Fri Feb 02, 2007 3:23 pm
Thanks everyone, I've got it working now. Cheers!
#117294 - JessTicular - Sat Feb 03, 2007 12:06 pm
Lick, thanks for the explination of the Palettes.
Even though it was only breif it made something in my mind click that until this point I simply didn't understand.
Cheers,
Jess.
_________________
Nintendo DS & Dominos :: DS Dominos
http://jt0.org