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.

Graphics > 8x8 tiles acting funny

#49609 - paladine - Sun Jul 31, 2005 10:00 pm

I am using mode 0 and 3 backgrounds for display. BG0 is my main map display, BG1 is used for text and BG2 is used as a window to show the text. I am coding the graphics for the window manually since it's just a few pixels to display. I am experience some weird color/palette problems when display some of my tiles. Here is an example of a tile -
Code:

static const u16 leftside[16] = {
  0x2341,0x1111,
  0x2341,0x1111,
  0x2341,0x1111,
  0x2341,0x1111,
  0x2341,0x1111,
  0x2341,0x1111,
  0x2341,0x1111,
  0x2341,0x1111,
};


I have a topside and leftside variable. The top is topside, the bottom is topside with a vertical flip, the left side is leftside, and the right side is leftside with a horizontal flip. The top and bottom displays work perfectly. However the colors/palettes don't match up for the left hand side. My palette is as follows , 1->blue, 2->white, 3->gray,4->darker gray. So the left side should appear as white->gray->darker gray->blue. But what I see on screen is blue->darker gray->gray->white->blue->blue->blue->blue... which doesn't really make any sense to me.
The strange thing is I can redefine the array as 0x2222 and it appears totally white. I can even set it to 0x2222,0x0000 ... and it appears white on the left half and blue on the right. However when I use 0x2341,0x1111 it never works correctly! Very strange! A long shot perhaps, any suggestions? I can post more code if it'll help.
Code:

void EnterTalkMode(const char *pText)
{
  volatile u16 empty;
  int i;
  u16 *screenBase = SCREEN_BASE_BLOCK(15);
  u16 *charBase   = CHAR_BASE_BLOCK(1);
  u16 *palette = BG_PALETTE_INDEX(14);
  // -----------------------------------------------------------------------------
  // set palette
  palette[0] = 0;
  palette[1] = RGB(0,0,31);   // blue
  palette[2] = RGB(30,31,30); // off-white
  palette[3] = RGB(24,24,24); // slightly gray
  palette[4] = RGB(12,14,14); // slightly darker
  // -----------------------------------------------------------------------------
  // create first tile of transparency
  empty = 0;
  DMACopy((u16*)&empty,charBase,16,DMA_16NOW | DMA_SOURCE_FIXED);
  // create second tile of blue
  empty = 0x1111;
  DMACopy((u16*)&empty,charBase+16,16,DMA_16NOW | DMA_SOURCE_FIXED);
  // create third tile of upper row
  DMACopy(toprow,charBase+32,16,DMA_16NOW);
  // create fourth tile of left sides
  DMACopy(leftside,charBase+48,16,DMA_16NOW);
  // create fifth tile of corners
  DMACopy(upperleftcorner,charBase+64,16,DMA_16NOW);
  // -----------------------------------------------------------------------------
  // now fill with blue, clear middle section
  empty = (14 << TILE_PALETTE_SHIFT) | 1;
  DMACopy((u16*)&empty,screenBase+32,32*8,DMA_16NOW | DMA_SOURCE_FIXED);
  // clear all tiles (set to the first tile which will be transparent)
  empty = (14 << TILE_PALETTE_SHIFT);
  DMACopy((u16*)&empty,screenBase+(32*10),32*22,DMA_16NOW | DMA_SOURCE_FIXED); 
  // fill top row is tile 2 (third tile)
  empty = (14 << TILE_PALETTE_SHIFT) | 2;
  DMACopy((u16*)&empty,screenBase,32,DMA_16NOW | DMA_SOURCE_FIXED);
  // bottom row is tile 2, vertical flip
  empty = (14 << TILE_PALETTE_SHIFT) | TILE_VERTICAL_FLIP | 2;
  DMACopy((u16*)&empty,screenBase+32*9,32,DMA_16NOW | DMA_SOURCE_FIXED);
  // left side is tile 3 (fourth tile)
  for (i=0;i<32*10;i+=32)
  {
    screenBase[i] = (14 << TILE_PALETTE_SHIFT) | 3;
    screenBase[i+29] = (14 << TILE_PALETTE_SHIFT) | (TILE_HORIZONTAL_FLIP) | 3;
  }
  // do the corners
  screenBase[0] = (14 << TILE_PALETTE_SHIFT) | 4;
 
 
 
  // ok now create the NEXT background which is used for the text
  screenBase = SCREEN_BASE_BLOCK(23);
  charBase = CHAR_BASE_BLOCK(2);
  palette = BG_PALETTE_INDEX(15);
  // fill palette
  palette[0] = 0;
  palette[1] = RGB(31,31,31); // this is the text color
  // clear all tiles (set to the first tile which will be transparent)
  empty = (15 << TILE_PALETTE_SHIFT);
  DMACopy((u16*)&empty,screenBase,(256/8)*(256/8),DMA_16NOW | DMA_SOURCE_FIXED);
  // set some tiles
  DrawParagraph(screenBase,pText);
  // set one tile to something
  // create first tile of transparency
  empty = 0;
  DMACopy((u16*)&empty,charBase,16,DMA_16NOW | DMA_SOURCE_FIXED);
  // copy font tiles
  DMACopy(font.imageData,charBase+16,sizeof(font.imageData)/2,DMA_16NOW);
       
   
  REG_BG2CNT = 0 | (1 << TILE_DATA_SHIFT) | (15 << TILE_MAP_SHIFT) | TEXTBG_SIZE_256_256;
  REG_BG1CNT = 0 | (2 << TILE_DATA_SHIFT) | (23 << TILE_MAP_SHIFT) | TEXTBG_SIZE_256_256;
  REG_DISPCNT |= BG1_ENABLE | BG2_ENABLE;
 
 
  // scroll to 0,0
  REG_BG1HOFS = 0;
  REG_BG1VOFS = 0;
  REG_BG2HOFS = 0;
  REG_BG2VOFS = 0;
  // set the mode now
  pLastMode = g_pMode;
  g_pMode = &talkingMode;
}

#49657 - Cearn - Mon Aug 01, 2005 9:23 am

The GBA is little-endian in both bit and byte formats, so lower nybbles represent leftmost pixels. In other words:
Code:
// pixel order:
u16 0x3210, 0x7654
With that in mind getting the pixels as 1,4,3,2,1,1,1,1,1 makes perfect sense. So what you probably want is 0x1432, 0x1111. Or you could use u32 as the type, which is fully mirrored and use 0x11111432.

#49670 - paladine - Mon Aug 01, 2005 2:53 pm

Ugh. Now it sounds so simple! My graphic tools output in byte format so that's why I've never run into it before. Thanks for the tip!