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 > sprites and tilebackgrounds

#17772 - wox - Sun Mar 14, 2004 5:06 pm

Hi!

I can get my background to show properly, but when I try to load a sprite into Oam, the tiles at the top of the map gets screwed up
I checked tutorial4 from the pern project and it's the same problem
both in visualboy advance and in mappy...

Anyone who have had the same problem?

thanks for any help

Code:

int main()
{
   int index = 0;
   u16 loop;
   u16* temp;

   //compute my Look up tables
   for(loop = 0; loop < 360; loop++)
   {
      SIN[loop] = (FIXED)(sin(RADIAN(loop)) * 256);  //sin and cos are computed and cast to fixed                     //fixed
      COS[loop] = (FIXED)(cos(RADIAN(loop)) * 256);
   }

   SetMode(MODE_1 | OBJ_ENABLE | OBJ_MAP_1D);


   bg2.number = 2;            //background number 0-3
   bg2.charBaseBlock = 3;
   bg2.screenBaseBlock = 23;
   bg2.colorMode = BG_COLOR_256;
   bg2.size = ROTBG_SIZE_128x128;
   bg2.mosiac = 0;
   bg2.x_scroll = 120;
   bg2.y_scroll = 80;

   //This call enables the background with the suplied attributes and when it returns
   //bg2.mapdata and tiledata will be valid pointers to the correct place
   //for the map and tile data in VRAM
   
   EnableBackground(&bg2);

   
   //Now let us copy in the background tile palette
   for(loop = 0; loop < 256; loop++)
      BGPaletteMem[loop] =tilesPalette[loop];
   //now for the actual tile graphics created by pcx2sprite
   for(loop = 0; loop < tiles_WIDTH * tiles_HEIGHT /2; loop++)
      bg2.tileData[loop] =tilesData[loop];


   //now for the map a temp variable is necessary because the map editor saves it as a
   //u8 array.  The map data was padded to 64x64 tiles even though our map is not quite
   //that big.
   temp = (u16*)test; 
   for(loop = 0; loop < 32*32/2; loop++) //64x64 tiles /2 because 16 bit copy
      bg2.mapData[loop] = temp[loop];

   
   RotateBackground(&bg2,angle,119,79,zoom);




   for(loop = 0; loop < 256; loop++)          //load the palette into memory
      OBJPaletteMem[loop] = block_redPalette[loop];

   InitializeSprites();                       //set all sprites off screen (stops artifact)

    sprites[0].attribute0 = COLOR_256 | SQUARE | 50;   //setup sprite info, 256 colour, shape and y-coord
    sprites[0].attribute1 = SIZE_16 | 50;            //size 16x16 and x-coord
    sprites[0].attribute2 = 0;                      //pointer to tile where sprite starts

    for(loop = 0; loop < 128; loop++)               //load sprite image data
    {
         OAMData[loop] = block_redData[loop];
    }

   InitializeSprites();

   while(1)
   {
      WaitForVsync();      
      CopyOAM();
      UpdateBackground(&bg2); //makes any changes to the bg struct get copied inot the apropriate registers
   }   

   return 0;
}



/// all the background functions

void UpdateBackground(Bg* bg)
{
   switch(bg->number)
   {
   case 0:
      REG_BG0HOFS = bg->x_scroll;
      REG_BG0VOFS = bg->y_scroll;
      break;
   case 1:
      REG_BG1HOFS = bg->x_scroll;
      REG_BG1VOFS = bg->y_scroll;
      break;
   case 2:
      if(!(REG_DISPCNT & MODE_0))//it is a rot background
      {
         REG_BG2X = bg->DX;
         REG_BG2Y = bg->DY;
         
         REG_BG2PA = bg->PA;
         REG_BG2PB = bg->PB;
         REG_BG2PC = bg->PC;
         REG_BG2PD = bg->PD;
      }
      else  //it is a text background
      {
         REG_BG2HOFS = bg->x_scroll;
         REG_BG2VOFS = bg->y_scroll;
      }
      break;
   case 3:
      if(!(REG_DISPCNT & MODE_0))//it is a rot background
      {
         REG_BG3X = bg->DX;
         REG_BG3Y = bg->DY;
         
         REG_BG3PA = bg->PA;
         REG_BG3PB = bg->PB;
         REG_BG3PC = bg->PC;
         REG_BG3PD = bg->PD;
      }
      else //it is a text background
      {
         REG_BG3HOFS = bg->x_scroll;
         REG_BG3VOFS = bg->y_scroll;
      }
      break;
   default: break;
   }
}





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->mosiac;

   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;
   
   }
}





void RotateBackground(Bg* bg, int angle,int center_x, int center_y, FIXED zoom)
{
   center_y = (center_y * zoom)>>8;
   center_x = (center_x * zoom)>>8;
   
   bg->DX = ((bg->x_scroll<<8)-center_y*SIN[angle]-center_x*COS[angle]);
   bg->DY = ((bg->y_scroll<<8)-center_y*COS[angle]+center_x*SIN[angle]);
   
   bg->PA = (COS[angle]*zoom)>>8;  //cos&sin are LUTs that are .8 fixed numbers
   bg->PB = (SIN[angle]*zoom)>>8;  //zoom is also fixed
   bg->PC = (-SIN[angle]*zoom)>>8;
   bg->PD = (COS[angle]*zoom)>>8;
}






void InitializeSprites(void)
{
   int loop;
   for(loop = 0; loop < 128; loop++)
   {
      sprites[loop].attribute0 = 160;  //y to > 159
      sprites[loop].attribute1 = 240;  //x to > 239
   }
}

///Copy our sprite array to OAM
void CopyOAM(void)
{
   u16 loop;
   u16* temp;
   temp = (u16*)sprites;
   for(loop = 0; loop < 128*4; loop++)
   {
      OAM[loop] = temp[loop];
   }
}

void WaitForVsync(void)
{
   while(REG_VCOUNT<160);
}

#17814 - sajiimori - Mon Mar 15, 2004 5:26 am

Can you pare your code down to the smallest piece that has the problem?

#17874 - wox - Tue Mar 16, 2004 12:04 pm

ok the problem is in the rotation function
without it everything works ok, except I can't update the map
I don't know whats wrong with it, I reduced the code of that function to:

void RotateBackground(Bg* bg, int angle,int center_x, int center_y, FIXED zoom)
{
center_y = 79;
center_x = 119;

bg->DX = 0;
bg->DY = 0;

bg->PA = COS[0];
bg->PB = SIN[0];
bg->PC = -SIN[0];
bg->PD = COS[0];
}

just to try and minimize everything that could go wrong with it
now it just rotates 0 degrees around the centre of the screen, and don't scroll at all
still my background doesn't show properly

#17880 - poslundc - Tue Mar 16, 2004 2:31 pm

This is important: does the background show up properly if you don't call the RotateBackground() function?

Dan.

#17883 - wox - Tue Mar 16, 2004 3:41 pm

then there's no background at all
but if I also remove the UpdateBackground call in the while-loop everything works (I guess because UpdateBackground saves undefined values in the rotation registers)

#17892 - sajiimori - Tue Mar 16, 2004 6:30 pm

So you've determined that sprites have nothing to do with it? What does the screen actually look like?

I'm not sure of the intent of your new RotateBackground(). Why all the COS[0], SIN[0] and all that? Those seem like wrong values. Just put zeros if you want simplicity.

#17936 - wox - Wed Mar 17, 2004 6:51 pm

here's some pictures and the source code
http://medlem.spray.se/wox/

since I don't really need rotating backgrounds for my first gba game, I'm using plain textbackgrounds now...
just curious why it doesn't work
thanks for the replies btw