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 > Colors Off When Packing Data (RGB8 macro not working on PC)

#128963 - Karatorian - Thu May 17, 2007 3:55 am

As a simple venture into GBA coding, I wrote a simple image display program. The first version of this program simply loaded an image stored in a C header file. (I saved it from the Gimp, which has a built in .h exporter.) It worked as expected.

As a precursor experiment towards a more advanced image packing program, I made a small change for the next version. Rather than use the header directly, I wrote a quick hack to turn the header file into an assembly file. When I run this version, the colors are all wrong. I suspect I'm running into a problem involving the difference in endianess between the ARM (where the display code is run) and the Intel (where the packing code is run), but I'm not sure and I can't figure out how to compensate. (To tell the truth, I barely understand endianness.)

Here's the display code, which is almost the same as the version that used the C header.

Code:
// Really Simple Image Display
// Copyright 2007 Levi Aho
// All Rights Reserved

#include <gba.h>

short img_data[SCREEN_HEIGHT * SCREEN_WIDTH];

int main()
{
   int i = 0, x, y;
   
   SetMode(MODE_3 | BG2_ON);
   for (x = 0; x < SCREEN_HEIGHT; x++)
   {
      for (y = 0; y < SCREEN_WIDTH; y++)
      {
         MODE3_FB[x][y] = img_data[i++];
      }
   }
   while (1) {}
}


And here's the code for the image conversion hack. It's quick and dirty, and is not intended as finished code. It's simply a proof of concept sort of thing, but it doesn't work like it's supposed to. I tried various changes to attempt to fix it, but I couldn't get the colors to come out right, so I'm posting the original version.

Code:
// Really Simple Image Display
// Copyright 2007 Levi Aho
// All Rights Reserved

#include <stdio.h>
#include <gba_video.h>
#include "studio-karatorian.h"

int main()
{
   int i;
   char p[3];
   short d;
   
   printf(".global\timg_data\n");
   printf("img_data:\n");
   printf("\t.align\t4\n");
   
   for (i = 0; i < SCREEN_HEIGHT * SCREEN_WIDTH; i++)
   {
         HEADER_PIXEL(header_data, p);
         d = RGB8(p[0],p[1],p[2]);
         printf("\t.short\t0x%hX\n", d);
   }
   return 0;
}


I'm fairly sure that I need to change the last line in the loop to account for the endian difference, but I'm not sure how to do so. I know that it works for the most part as the image has the right shapes and stuff, only the colors are wrong. Can someone please help me out?

Edit: I did some more searching and investigating and discovered it has nothing to do with endianess. As it turns out, the ARM and the Intel are both little endian, so there is no conflict there.

What I have discovered is that the RGB8 macro from gba_video.h didn't behave correctly when used on the PC by the conversion program. As it turns out, I had declared my p array as a "char", instead of an "unsigned char", which it should have been. For some reason, such code worked fine on the GBA, but not on the PC. Does anyone know why?