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.

Coding > creating a custom palette by code

#22112 - SiN - Sun Jun 13, 2004 3:54 pm

hi guys,

right then, im a bit of a gba n00b, but not a coding n00b ... have a good 9 years of experience behind me. However, ive never been good with all the low-level stuff which is y im having a bit of trouble with the gba. heres the problem ...

... im in the lucky position to kno EXACTLY what colours i want in my palette, in what order i want them, and which colours are gonna be used in my image. the problem is that i dont seem to quite understand the image/palette format.

heres an image i got from the gbajunkie tutorial (obviously ive cut it down)

Code:

const u16 junkieData[] = {
                    0x81AC, 0x81AC, 0x81AC, 0xAC81, 0xAC81, 0xACAC, 0x8181, 0x8181, 0x8181, 0x81AC,
                    0x8181, 0x8181, 0x81AC, 0xACAC, 0xACAC, 0xACAC, 0x8181, 0x81AC, 0xAC81, 0x8181,
                    0x81AC, 0xAC81, 0x8181, 0x81AC, 0xAC81, 0xAC81, 0x81AC, 0x8181, 0x8181, 0xAC81,
                   ..................
                    0xD7D7, 0xD7AC, 0xD7D7, 0xD7AC, 0xD7D7, 0xD7D7, 0xD7AC, 0xACD7, 0xD7D7, 0xD7D7,
                    0xACD7, 0xD7D7, 0xACD7, 0xD7D7, 0xD7AC, 0xD7D7, 0xD7AC, 0xACD7, 0xD7D7, 0xD7D7,
                    0xD7AC, 0xD7D7, 0xD7D7, 0xD7D7, 0xD7D7, 0xD7D7, 0xACD7, 0xD7D7, 0xACD7, 0xD7D7,};

const u16 junkiePalette[] = {
                    0x0000, 0x1800, 0x3000, 0x4C00, 0x6400, 0x7C00, 0x0006, 0x1806, 0x3006, 0x4C06,
                    0x6406, 0x7C06, 0x000C, 0x180C, 0x300C, 0x4C0C, 0x640C, 0x7C0C, 0x0013, 0x1813,
                    0x3013, 0x4C13, 0x6413, 0x7C13, 0x0019, 0x1819, 0x3019, 0x4C19, 0x6419, 0x7C19,
                    0x03FF, 0x1BFF, 0x33FF, 0x4FFF, 0x67FF, 0x7FFF, 0x0000, 0x0000, 0x0000, 0x0000,
                   ..................
                    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
                    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
                    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
                    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,};


first off, i kno that all the numbers are in hex, and i can read&write hex no prob. however, i dont understand why the "x" is there ... what is it for? im guessing its an operator or something ... its not important, but it would be nice to kno.

the second array "junkiePalette", i figure holds the pallete :) ... and the numbers range from 0-32767, since each component has a 32 colour range. but im not quite sure HOW the # is generated ... any1 care to explain what the formula is? i figure its r*g*b, but im not sure.

finally and most importantly, i cant figure out what is stored in the first array ... naturally its the image itself, but i figured the numbers would be between 0-255 (so each represents a colour from the palette) ... its not ... the numbers are WAY out there ... i kno it stores the image, but i dont kno what format its in. could some1 explain?


any help is appreciated.

SiN

#22114 - ProblemBaby - Sun Jun 13, 2004 4:15 pm

1.
if you mean this '0x' before every hexnumber
this is for the compilator to know that it is a hex number

2.
#define RGB(Red, Green, Blue) ((Red) | ((Green)<<5) | ((Blue)<<10))
here is a macro to get the color you want

3.
if it is a 256-color image every pixel takes one byte right
but the array is a word.. so two pixels is stored in each word
in this order

Word1: Pixel2 : Pixel1
Word2: Pixel4 : Pixel3

if it is a 16-color image it is 4 pixels per word

hope it helped and that you understand my english:D

#22115 - Lord Graga - Sun Jun 13, 2004 4:21 pm

1) 0x tells the compiler the value is in hex. 81 in hex and 81 in decimals isn't the same, as you know.

2) GBA LCD is BGR. Values in a palette is generated like this:

#define RGB16(r,g,b) ((r)+(g<<5)+(b<<10))

i.e, the GBA uses 16-bit colors, where bit 0-4 is red, 5-9 is green, and 10-14 is blue.

3) Tiles are kept in 8x8 chunks. in 256 color mode, one byte (8bit) is one dot. 0x0181 would mean first dot = 0x01, second dot = 0x81.


Tell me if there's anything about that you don't understand, and I'll tell you more.


Many of use would appreciate if you used proper english words.

#22116 - Abscissa - Sun Jun 13, 2004 4:36 pm

In C/C++, all hexadecimal numbers are prefixed with '0x'. This tells the compiler that the number is hex. If you were to just type 20, it would literally be decimal 20, not decimal 32. If you were to type 3F, you would get a syntax error since 'F' is not a valid digit in decimal. Basically, if you write '0x17' that means hexadecimal 17, if you write '17' that means decimal 17.

Colors are determined like this: In a 16-bit number, bits 0-4 are the red component, bits 5-9 are the green component, bits 10-14 are the blue component, and bit 15 is not used. So, the individual bits are layed out like this:

bit 15 X B B B B B G G G G G R R R R R bit 0

Each of the red, green, and blue components are 5-bits, so they range from 0 to 31. It's difficult to write a color like this directy in hexadecimal, but you can write a macro to generate a color from RGB components like this:

Code:
#define RGB(r,g,b)  ((r) + ((g)<<5) + ((b)<<10))
u16 purple = RGB(31, 0, 31);


This is also explained at www.thepernproject.com in Day 2 of the GBA Tutorial.

As far as how the numbers in Data relate to the numbers in Palette, you are correct that each number in Data refers to that position in Palette (ie If the Data for a pixel is 7, then the color is whatever color is in Palette[7]). The reason that the numbers in junkieData appear to be from 0-65535, is because each of the 16-bit numbers in junkieData are actually two pixels, not one. Let me explain: There are 256 entries in a palette, and they range from 0-255. This is 8-bits. So in hexadecimal they range 0x00 to 0xFF, not 0x0000 to 0xFFFF like you correctly noticed. Look at the first entry in junkieData - it's 0x81AC. This is not the first pixel, it's the first TWO pixels. The first pixel is 0x81, the second is 0xAC. Now, it might make more sense to say "const u8 junkieData[]={0x81, 0xAC...", but the portions of the GBA's memory that store graphics can only be accessed 16-bits at a time (and not 8-bits at a time), so it's more convinient for junkieData to use u16 even though it's slightly misleading.

#22118 - CATS - Sun Jun 13, 2004 5:31 pm

in the image array, each element is two pixels, so 0x81AC is two pixels, first is colour 81, second is colour AC.

The GBA likes to plot two pixels at once in 256 colour bitmapped mode for some obscure reason, so storing it like this makes it easier.