gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Beginners > Sprite Palettes @ 4bpp

#130252 - biubid_boy - Fri Jun 01, 2007 2:55 pm

Hello everyone.

I was reading through the TONC section on loading sprites when I noticed that the author used a technique to allow easy access to charblocks by making an array of tiles. (bottom of this page). So, I tried to do the same to the object palette ram and cut it into 16 palettes, thinking I could simplify things further. So here is my current (unworking) code:

Code:

typedef struct {u32 data[8 ];} palette_4bpp;
typedef palette_4bpp obj_pal_mem_4bpp[16];
#define obj_pal_4bpp  ((obj_pal_mem_4bpp*)0x5000000)


And...

Code:

memcpy(&obj_pal_4bpp[n], palette, 32);


Funnily enough, if I use palette entry zero with this code, it works fine, but as soon as go any further, there is no object displayed. This leads me to believe that I have the size of the palette_4bpp struct wrong, but I can figure out why it is wrong. Can anyone lighten things for for me?

Thanks,
Biubid_boy.[/code]

#130255 - Miked0801 - Fri Jun 01, 2007 3:56 pm

Look at it in no$gba or vboy and see if the palettes are loading and if it's a sprite issue. The code looks okay to me.

#130262 - Cearn - Fri Jun 01, 2007 5:38 pm

Three things:

Your palette_4bpp struct is composed of 8 words, for 32 bytes in total. Then you make a type obj_pal_mem_4bpp that's 16 of these palette_4bpp's : each obj_pal_mem_4bpp is 16*32 bytes long. It's essentially a whole 256-color palette long, and obj_pal_4bpp[i] would point to the i'th 256-color palette, rather than the 16-color palettes.

Second, the object palette starts at 0500:0200, not 0500:0000.

Third, there are already definitions like the ones you seek in tonclib :). In particular, these ones:
Code:
// === tonc_types.h ===

typedef u16 PALBANK[16];


// === tonc_memmap.h ===

//! Background palette matrix.
/*! pal_bg_bank[y]      = bank y                ( COLOR[ ] )
*   pal_bg_bank[y][x]   = color color y*16+x    ( COLOR )
*/
#define pal_bg_bank     ((PALBANK*)0x05000000)


//! Object palette matrix.
/*! pal_obj_bank[y]     = bank y                ( COLOR[ ] )
*   pal_obj_bank[y][x]  = color y*16+x          ( COLOR )
*/
#define pal_obj_bank    ((PALBANK*)0x05000200)


The thing to remember here is that a pointer to an array typedef (like PALBANK, is essentially a matrix, which is exactly what you want in this case. Now that I think about it, I think that if you add alignment attributes to the typedef, you can fast-copy a palette bank with an assignment:

Code:
typedef u16 PALBANK[16] ALIGN(4);
#define pal_obj_bank    ((PALBANK*)0x05000000)

pal_obj_bank[n]= (PALBANK*)palette;  // copies 16 colors via ldmia/stmia

Note: this'll work even without the alignment flags, but it'd just memcpy() internally for it, which should be quite a bit slower for only 32 bytes.

#130309 - biubid_boy - Sat Jun 02, 2007 2:20 am

Thanks to your code, I got it working! But I had to change certain things...

Firstly, I think that last piece of code you wrote should be:
Code:

typedef u16 PALBANK[16] ALIGN(4);
#define pal_obj_bank    ((PALBANK*)0x05000200) //<- obj_pal instead of bg_pal


I had some trouble with 'incompatible types in assignment' when I tried:
Code:

pal_obj_bank[n]= (PALBANK*)palette;  // copies 16 colors via ldmia/stmia

In the end I used:
Code:

memcpy(&obj_pal_4bpp[pal_count], palette, 32);

Which seemed to work well.

And also, I had to change your definition of ALIGN(n) from TONC. I changed:
Code:

#define ALIGN(_n)   __attribute__(aligned(_n)))

From the bitmaps page in TONC to:
Code:

#define ALIGN(_n)   __attribute__ ((aligned(_n))) //<- extra bracket before align


Then I had a perfect compile!

Are these all valid changes or am I over complicating things for myself?
Thanks for all the help so far,
Biubid_boy.

#130341 - Cearn - Sat Jun 02, 2007 11:02 am

biubid_boy wrote:
Thanks to your code, I got it working! But I had to change certain things...

Firstly, I think that last piece of code you wrote should be:
Code:

typedef u16 PALBANK[16] ALIGN(4);
#define pal_obj_bank    ((PALBANK*)0x05000200) //<- obj_pal instead of bg_pal

I think there's like a rule on this somewhere: if you correct someone on a typo, you're gonna make the same mistake yourself. 0x05000200 for the object palette, yes.

biubid_boy wrote:
I had some trouble with 'incompatible types in assignment' when I tried:
Code:
pal_obj_bank[n]= (PALBANK*)palette;  // copies 16 colors via ldmia/stmia


Code:
pal_obj_bank[n]= *(PALBANK*)palette;
There should have been a dereference there.


biubid_boy wrote:
And also, I had to change your definition of ALIGN(n) from TONC. I changed:
Code:

#define ALIGN(_n)   __attribute__(aligned(_n)))

From the bitmaps page in TONC to:
Code:

#define ALIGN(_n)   __attribute__ ((aligned(_n))) //<- extra bracket before align
I wonder how that mistake got there. Anyway, fixed. Thanks.