#151760 - doudou - Tue Mar 04, 2008 7:41 pm
I want to upgrade my game from using 16 colors backgrounds (4 layers for each screen) to 256 colors.
Does the DS have 4 256 colors palettes slots per screen? (or I have to split the 256 colors between my 4 layers).
Last edited by doudou on Sat Jul 05, 2008 7:13 pm; edited 1 time in total
#151770 - tepples - Tue Mar 04, 2008 8:39 pm
The GBA has one 256-color palette for the background and one for the sprites. The DS has one of each for each of the two 2D cores: one for main background, one for main sprites, one for sub background, and one for sub sprites. But the DS also has "extended palettes".
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#151776 - doudou - Tue Mar 04, 2008 9:50 pm
Thanks tepples.
Can you tell me more about "extended palettes" or refer me to a post that gives good info about it (just typing in the search gives a lot of junk)?
I already use 256 colors for the sprites in both screens. What I would like to do is use 256 colors per layer in both screens if possible. Otherwise, I will use 64 colors (or different setup) per layer.
#151804 - doudou - Wed Mar 05, 2008 2:30 am
The best I have so far on extended palettes is:
http://nocash.emubase.de/gbatek.htm#dsvideoextendedpalettes
If I could have some code sample of a proper way to use it, it would be appreciated.
I would also like to know if there are reasons that would prevent from using it (ex: slow access, complexity of use, etc.)
#151809 - M3d10n - Wed Mar 05, 2008 4:20 am
I never tried using them myself, but this is what I understand from GBATEK:
- Extended palettes allow 16 256 color palettes (just like the 16-color mode allows 16 16-color palettes)
- You use 16-bit map entries, setting bits 12-15 to select the palette per tile, just like in the 16/16-color mode
- You allocate your palettes in 4 "slots" of 8K (16 palettes) each.
- Each BG layer will use a different slot (BG 0 will use slot 0.
It doesn't sounds too complicated, and the only major differences to 16x16 palette mode is the slot stuff (and that you need to set the VRAM bank mode to LCD before writing your palettes to it).
From what I understand, you'll have 64 palettes written one after the other at the allocated VRAM bank. BG0 will use palettes 0-15, BG1 will use palettes 16-31, BG2 will use 32-47 and BG3 will use 48-64. Optionally, you can have BG0 use slot2 and BG1 use slot3.
The main issue, IMO, would be setting up an art pipeline to take full advantage of extended BG palettes (extended sprite palettes are easier to use in that regard). You can easily use unique 256 color palettes for each BG, but using 16 unique palettes for each BG is a lot harder.
Maybe a tool which takes a tilemap and uses quantization to calculate 16 optimal palettes for the whole image, taking the tiles in consideration.
#151854 - doudou - Thu Mar 06, 2008 12:38 am
Thanks, this should be really useful.
Just to confirm it's right, did somebody already try it?
#151867 - doudou - Thu Mar 06, 2008 2:17 am
I'm now having the same issue has many had on the forum. I works when there is no palette offset (bg 0) but otherwise, I only have black.
I tested on the subscreen, using VRAM_H. You can have a look at my code. I tried with bg 2, using palIndex = 32 according to M3d10n instructions.
Code: |
if(mScreen == kNDSTopScreen)
{
vramSetBankF(VRAM_F_LCD);
DMACopy16((void*) palette, VRAM_F + (palIndex * 256*2), 256); // Copy palette data ...
vramSetBankF(VRAM_F_BG_EXT_PALETTE);
}
else // bottom screen.
{
vramSetBankH(VRAM_H_LCD);
DMACopy16((void*) palette, VRAM_H + (palIndex * 256*2), 256); // Copy palette data ...
vramSetBankH(VRAM_H_SUB_BG_EXT_PALETTE);
}
|
#151870 - Cydrak - Thu Mar 06, 2008 5:27 am
VRAM_x constants are typed as uint16*. So you're adding a halfword, not a byte offset... are you sure you want the factor of 2?
#151957 - doudou - Fri Mar 07, 2008 12:41 am
You are absolutely right Cydrak. Thank you, it now works fine!
#152654 - doudou - Wed Mar 19, 2008 12:53 am
I had good results until I tried to use extended palettes in the top screen. To have the 32k required to store the 64x256 colors palettes, I use the VRAM slots F and G (16k each).
When I look the palette data in my DS emulator, I see that my palettes are loaded at Main EXT 0 and Main EXT 1 (palette 0), but I want to laod layer 2 and 3 palettes so I try for Main EXT 2 and Main EXT 3 (palette 0) with my palette indices at 32 and 48.
Code: |
if(mScreen == kNDSTopScreen)
{
if(palIndex < 32)
{
vramSetBankF(VRAM_F_LCD);
DMACopy16((void*) palette, VRAM_F + (palIndex * 256), 256);
vramSetBankF(VRAM_F_BG_EXT_PALETTE);
}
else
{
vramSetBankG(VRAM_G_LCD);
DMACopy16((void*) palette, VRAM_G + ((palIndex - 32) * 256), 256);
vramSetBankG(VRAM_G_BG_EXT_PALETTE);
}
} |
#152655 - Cydrak - Wed Mar 19, 2008 2:19 am
F and G will work, but the libnds default puts both in the same place (first 16k of the target). To do it properly, you need some offsets... check the prior topic on palette slots.
Other possibilities are using bank E (if you don't mind wasting half of it). Or you can try to map F or G alone at +16k. This is useful as BG0/BG1 have a flag to share the upper slots (DStek:DS BG modes, near bottom).
#152671 - TwentySeven - Wed Mar 19, 2008 5:22 am
Yeah I used bank F and the shared slots too. Who needs more then 16 palettes anyway!
#152713 - doudou - Wed Mar 19, 2008 11:21 pm
TwentySeven: it's not that I want more than 16 palettes, I actualy only need 4, my problem is about the auto-mapping of layers to palettes indices.
#152719 - Cydrak - Thu Mar 20, 2008 1:32 am
I threw up an example if that would help. It shows several useful bank setups, and how to make the sharing work.
Y: switch bank usage (E, F+G, F or G)
X: toggle BG0's palette (0 or 2)
A: toggle BG1's palette (1 or 3)
#152745 - TwentySeven - Thu Mar 20, 2008 10:30 am
http://liranuna.drunkencoders.com/nds-2d-tuts/lesson-3/
Specifically, bits 12,13,14,15 specify which extended palette slot to use per tile.
#152843 - doudou - Fri Mar 21, 2008 4:26 pm
It's now all working. Cydrak was right about the libnds issue about VRAM_G and VRAM_F being mapped at the same location. The following code fixes my issue:
Code: |
if(palIndex < 32)
{
vramSetBankF(VRAM_F_LCD);
DMACopy16((void*) palette, VRAM_F + (palIndex * 256), 256); // Copy palette data ...
vramSetBankF((VRAM_F_TYPE) (VRAM_F_BG_EXT_PALETTE | VRAM_OFFSET(0)));
}
else
{
vramSetBankF(VRAM_F_LCD);
DMACopy16((void*) palette, VRAM_F + ((palIndex - 32) * 256), 256); // Copy palette data ...
vramSetBankF((VRAM_F_TYPE) (VRAM_F_BG_EXT_PALETTE | VRAM_OFFSET(1)));
} |