GP32 Problems with the Palette


Still Fresh
Mar 26, 2003
I started to make some very simple programming things with my GP32. Now I have a problem which is very very annoying.

I also have read the Palette tutorial by Gamepark but it didn't helped me much. I open a normal RGB Image in Photoshop. Convert it to indexed colours (256) and save the image as a BMP and also the palette as an .act-file.
Now I compile my little programm, which actually only displays this image. After testing on the real hardware I got a muxed up palette. Every colour is different as I thought!

I read that many people are using Paintshop Pro for saving the palette file. Could it be that Photoshop creates the wrong palette file?

BTW, I'm using a Mac for programming. I have the developer tools installed from Mr.Spiv.
Did you load the new palette into your program and tell it to use that instead of the default one?
Unfortunatly that tutorial doesn't cover the topic of loading the palette into your GP32 program.
No, I didn't loaded the palette, that's a very good point;-)

I looked at some sources I found and the API Doc and found out that the palette must be an array.
Something like this:

static long palSnow[] = {

Now I have another problem (proably I'm too stupid for that), that I don't know how to convert my 'act'-file to an array like this... Probably someone of you can help me with that.

Furthermore also when I have generated such an array, how are the pixels in the image matched to each entry within the palette array? I haven't found many GP32 specific (re)sources on the net for that particular problem...

Update: I found two tools which should do the job... but both don't work for me as expected:-(

Gamepark Dev Tool : converts my image but I couldn't find anything concerning the palette for this image. I saw menu item 'Palette Utility' but it's greyed out.

GP32 Converter 1.3 from Edorul doesn't run on my machine win98+2k, because I'm missing a language dll for Visual Basic. And even when I try to install the dll I get more error messages saying that something isn't registered the right way.
BTW this little seems to have more potential as the Gamepark one.

When someone here know something about this whole stuff... would be very nice from you to give me a helping hand.
Here's some code that might help you. I'm just going to cut/paste from my .c files, so it might not be pretty or commented, but if you can read it, I think it'll help you do what you want to do.

readBMP256("Splash.bmp", graphmem, SplashPal, 320*240);
h_pal = GpPaletteCreate(256, SplashPal);
if ( !h_pal )
Quit("GpPaletteCreate error!");
//palette change


int readBMP256(char *filename, byte* buffer, GP_PALETTEENTRY *GPpalette, unsigned long bufferSize)
RGBQUAD BMPpalette[256];
int i, j;
int iFileHandle = 0;
char message[50];
unsigned long width, height, bpp;
byte garbage[16];

iFileHandle = OpenRead(filename);
if (iFileHandle == 0)
return -1;

//Read the header from the file
Read(iFileHandle, (void *)&tFileHeader, sizeof (BITMAPFILEHEADER));

//Are we looking at a BMP?
if (tFileHeader.bfType[0] != 0x42 && tFileHeader.bfType[1] != 0x4D)
PauseMessage("Not a BMP file!");
return -1;

//Read the BITMAPINFOHEADER from the file
Read(iFileHandle, (void *)&tInfoHeader, sizeof (BITMAPINFOHEADER));

width = tInfoHeader.biWidth[2]
| (tInfoHeader.biWidth[3] << 8)
| (tInfoHeader.biWidth[0] << 16)
| (tInfoHeader.biWidth[1] << 24);
height = tInfoHeader.biHeight[2]
| (tInfoHeader.biHeight[3] << 8)
| (tInfoHeader.biHeight[0] << 16)
| (tInfoHeader.biHeight[1] << 24);
bpp = tInfoHeader.biBitCount;

/*gm_sprintf(message, "width = %d", width);
gm_sprintf(message, "height = %d", height);

//We aren't going to process any BMP's except a 256 color BMP
if (bpp != 1)
gm_sprintf(message, "bpp= 0x%x", bpp);
return -1;

//Read in all 256 colors from the BMP file
i = Read(iFileHandle, (void *)BMPpalette, sizeof (RGBQUAD) * 256);
if(i != sizeof (RGBQUAD) * 256)
gm_sprintf(message, "read %d bytes", i);
return -1;

for ( i=0; i<256; i++)
//gm_sprintf(message, "i=%d r=%d g=%d b=%d rsv=%d", i, BMPpalette.rgbRed, BMPpalette.rgbGreen, BMPpalette.rgbBlue, BMPpalette.rgbReserved);
GPpalette = ((BMPpalette.rgbRed>>3)<<11) | ((BMPpalette.rgbGreen>>3)<<6) | ((BMPpalette.rgbBlue>>3)<<1) | 1;

/*if(bufferSize == 0)
buffer = gp_mem_func.malloc(width * height * bpp);
else*/ if(bufferSize < (width * height * bpp))
gm_sprintf(message, "bufferSize < %d", (width * height * bpp));
return -1;

ReadSeek(iFileHandle, 0x0436, SEEK_SET);
for(j = height-1; j >= 0; j--)
i = Read(iFileHandle, (void *)&buffer[j*width], width * bpp);
if(width < 16)
Read(iFileHandle, (void *)garbage, 16-width);
if(i != width * bpp)
PauseMessage("i != width * bpp");

return i*height;
typedef struct tagBITMAPFILEHEADER
byte bfType[2];
byte bfSize[4];
byte bfReserved1[2];
byte bfReserved2[2];
//byte bfOffBits[4];

typedef struct tagBITMAPINFOHEADER
byte biSize[4];
byte biWidth[4];
byte biHeight[4];
short int biPlanes;
short int biBitCount;
byte biCompression[4];
byte biSizeImage[4];
byte biXPelsPerMeter[4];
byte biYPelsPerMeter[4];
byte biClrUsed[4];
byte biClrImportant[4];

typedef struct tagRGBQUAD
byte rgbRed;
byte rgbReserved;
byte rgbBlue;
byte rgbGreen;