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 > Text backgrounds in Mode 0-1 are not working

#54040 - blacksun - Thu Sep 15, 2005 2:47 am

I currently am working on the Tile Bitmap modes. As of now, I have 2 256x256 256 color backgrounds I am working with. I can display them perfectly in Mode 2 with them both as Rotational bitmaps. However, when I try to load in the bitmaps into either 0 or 1 their data becomes messed up.

The only thing i've read to change is the size of the bitmap between Text and Rotation. I have also read that Text tile maps comprises 16-bit numbers while the rotational backgrounds store 8-bit numbers. Don't know how that fits in I'm just scratching my head.

Well here is the code that will display the backgrounds:

Code:
SetMode(MODE_1 | OBJ_ENABLE | OBJ_MAP_1D);

   //Let us set up the backgroud two structure and enable the background

   bg2.number = 0;            //background number 0-3
   bg2.charBaseBlock = 0;                  //tile data position (right at the start of the available memory on 16Kb boundary)
   bg2.screenBaseBlock = 28;      //map data position on 2Kb boundary
   bg2.colorMode = BG_COLOR_256;           //256-colour background
   bg2.size = TEXTBG_SIZE_256x256;          //size of map
   bg2.mosaic = 0;                         //not enabled
   bg2.x_scroll = 120;         //scrolling variables
   bg2.y_scroll = 80;

   bg0.number = 1;
   bg0.charBaseBlock = 0;
   bg0.screenBaseBlock = 31;
   bg0.colorMode = BG_COLOR_256;
   bg0.size = TEXTBG_SIZE_256x256;
   bg0.mosaic = 0;
   bg0.x_scroll = 120;
   bg0.y_scroll = 80;
   
   bg3.number = 2;
   bg3.charBaseBlock = 0;
   bg3.screenBaseBlock = 20;
   bg3.colorMode = BG_COLOR_256;
   bg3.size = ROTBG_SIZE_128x128;
   bg3.mosaic = 0;
   bg3.x_scroll = 120;
   bg3.y_scroll = 80;

   //Point to correct tile and map data, update the Background and Display registers accordingly
        EnableBackground(&bg2);
      EnableBackground(&bg0);
      EnableBackground(&bg3);


   for(loop = 0; loop < 256; loop++)
      BGPaletteMem[loop] = tilesetPalette[loop];     //load the background palette into memory

   for(loop = 0; loop < 32*32/2; loop++)  //load tile image data
   {
      bg2.tileData[loop] = tilesetData[loop];
      bg0.tileData[loop] = tilesetData[loop];
      bg3.tileData[loop] = tilesetData[loop];

   }

   //load the map image data
   temp = (u16*)background1;
   temp2 = (u16*)background2;
   temp3 = (u16*)test;

   //load the 2 text backgrounds.  256x256 with 256 color
   for(loop = 0; loop < 32*32/2; loop++) //32x32 tiles /2 because 16 bit copy
   {
      bg2.mapData[loop] = temp2[loop];
      bg0.mapData[loop] = temp[loop];
   }

   //Load a 128x128 256 color rotational background
   for(loop = 0; loop < 16*16/2; loop++)
      bg3.mapData[loop] = temp3[loop];


And here is the code for the EnableBackgrounds:
Code:
void EnableBackground(Bg* bg)
{
   u16 temp;

   bg->tileData = (u16*)CharBaseBlock(bg->charBaseBlock);
   bg->mapData = (u16*)ScreenBaseBlock(bg->screenBaseBlock);
   temp = bg->size | (bg->charBaseBlock<<CHAR_SHIFT) | (bg->screenBaseBlock<<SCREEN_SHIFT)
      | bg->colorMode | bg->mosaic | bg->wraparound;

   switch(bg->number)
   {
   case 0:
      {
         REG_BG0CNT = temp;
         REG_DISPCNT |= BG0_ENABLE;
      }break;
   case 1:
      {
         REG_BG1CNT = temp;
         REG_DISPCNT |= BG1_ENABLE;
      }break;
   case 2:
      {
         REG_BG2CNT = temp;
         REG_DISPCNT |= BG2_ENABLE;
      }break;
   case 3:
      {
         REG_BG3CNT = temp;
         REG_DISPCNT |= BG3_ENABLE;
      }break;

   default:break;

   }
}


Any help would be appreciated because while Mode 2 works fine, would like to find out how to use all BG in mode 0 and 1.

#54046 - tepples - Thu Sep 15, 2005 4:35 am

First off, mode 1 uses backgrounds 0 (text), 1 (text), and 2 (rotation), not 2, 0, and 3.

How are you generating/declaring the arrays background1, background2, and test ?

(EDIT: Mode number corrected. I apologize for the confusion caused by my error. Can anyone give me tips to help me make my brain's operation as repeatable as that of silicon?)
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.


Last edited by tepples on Thu Sep 15, 2005 6:41 pm; edited 1 time in total

#54066 - Cearn - Thu Sep 15, 2005 8:54 am

tepples wrote:
First off, mode 0 uses backgrounds 0 (text), 1 (text), and 2 (rotation), not 2, 0, and 3.
?

mode 1 uses backgrounds 0 (text), 1 (text), and 2 (rotation); in mode 0 all bgs are text. Also, why the bg-structs are named bg2, bg0 and bg3 here, their bg numbers are 0, 1 and 2 respectively, so that should be ok. (you might want to make those match, though)

What's probably not ok is what you do with the background's data. Text backgrounds are indeed 16bit / screen entry, while rotational bgs use 8bit. This means that you cannot simply use data prepared for a rot bg directly for a text bg.

Text bg's screen entry:
Code:
bit 0-9   : tile index
bit 10    : horizontal flip
bit 11    : vertical flip
bit 12-15 : 16 color palette

Rot bg screen entry:
Code:
bit 0-7   : tile index

Now, if your map data starts with, say, 0x0102, for a rot bg this will be interpreted as two separate screen entries, using tiles 2 and 1. For a text bg, this is just a single screen entry, using tile 0x102.

It's probably a good idea export your original map to a text bg format and use that, but if you really want to use the existing (rot bg) data, here's a way:
Code:
int ii;      // loop variable. NEVER, EVER, EVER USE u8 OR u16 FOR LOOP VARIABLES.
u8 *src= (u8*)background1;    // assuming 256x256 map (32x32 tiles)
u16 *dst= (u16*)bg0.mapData;
for(ii=0; ii<32*32; ii++)
    dst[ii]= src[ii];

A single (8bit) screen entry will be put as a tile index into the (16bit) destination, and you have a text map. Doesn't quite work when you go to even larger maps though, because of the screen-block thing for text bgs.

#54097 - blacksun - Thu Sep 15, 2005 5:28 pm

Sorry for the naming confusion, it was easier to just change the value for the background instead of the name. But I am just using 0, 1 and 2 in mode 1.

I think the problem is the way I am making my backgrounds. I am using GBA Map Editor Beta 4 from Warder 1. The program only exports in Rotational Background format, meaning each entry is only 8 bits.

I guess I need to find a map editor that exports into Text Background Format. If anyone knows of a good one please let me know. I used the code from Cearn and it works. Although will I be losing information by converting from Rot Background data to Text Background data?

#54126 - tepples - Thu Sep 15, 2005 6:43 pm

blacksun wrote:
I guess I need to find a map editor that exports into Text Background Format.

While you're waiting for the answer to this question, you can use rotational background map data with a text background. Try accessing it as a u8 instead of a u16. I wanted to see the declarations for the map data arrays so that I could find the best way to explain how to do this in the context of the map data that you are working with.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#54173 - blacksun - Fri Sep 16, 2005 2:07 am

Ya using u8 instead of u16 works fine.

Here is one of the backgrounds from the map editor.

Code:
const u8 background1[ 32 * 32 ] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ...
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ...
.
.
.


That is a 256x256 256 color background. Each entry is only 8 bits