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 > Problems reinitialising tile memory

#17823 - GunterPete - Mon Mar 15, 2004 2:50 pm

Hi there,

I've written a CLevel class, allowing me to gather all the information for each level of a Mode7 game. The game looks like this:
[Images not permitted - Click here to view it]

This CLevel class includes a pointer to the tile data, to the map data (sky and floor), the levels palette and a pallete used for a copper bar effect to be loaded into the transparent colour every HBlank.

Here are the member variables:

Code:

private:
   const u16* m_ppalBackground;   //Pointer to levels pallette
   const u16* m_pbmpMapTiles;      //Pointer to levels map tiles
   const u8* m_pmapFloor;         //Pointer to levels floor map
   const u8* m_pmapSky;         //Pointer to levels sky map
   const u16* m_ppalCopper;      //Pointer to pallete used for copper bar effect

   FIXED m_gravity;            //FIXED :16 value of acceleration due to gravity


A method of the class is loadLvlIntoMemory, which loads all this information into the relevant areas of GBA memory:
Code:

//Loads the map information into memory which includes:
//  Load level palletes (map and copper bar)
//   Level Tile Data (Char base block(0))
//   Bg 1 (Text) map data,  Sky (Screen Base Block(30))
//   Bg 2 (Rotation) map data, Floor (Screen Base Block(31))
//   Gravity, fixed :16 into gGrav;
//
void CLevel::loadLvlIntoMemory(void)
{
   /* Load in the palette data */
   //Load in background pallete
   DMA_Copy(3,(void*)m_ppalBackground,(void*)BGPaletteMem,256,DMA_16NOW);
   //Load in the copper barpallete
   DMA_Copy(3,(void*)m_ppalCopper,(void*)gpalCopper,160,DMA_16NOW);


   /* Load in the tile data */
   //Level tiles
   DMA_Copy(3,(void*)m_pbmpMapTiles,(void*)CharBaseBlock(0),8190,DMA_16NOW);

   /* Load in the text background data */
   //Temporary pointers to map data
   u16* bg1map =(u16*)ScreenBaseBlock(30);

   int x=0,y=0; //iterating vars
   for(y = 0; y < 32; y++) //loop through all 32x32 tiles
   {
      for(x = 0; x < 32; x++)
      {
         //*** BG 1 Sky
         //First tile (Hiword)
         bg1map[x + y*32] = m_pmapSky[x + y*32];
      }
   }

   /* Load in the rotation background data */
   //Temporary pointer to map data
   u16* bg2map =(u16*)ScreenBaseBlock(31);
   for(y = 0; y < 32; y++) //loop through all 32x32 tiles
   {
      for(x = 0; x < 16; x++)
      {
         //*** BG 2 Floor
         //First tile (Hiword)
         bg2map[x + (y*16)] = (u16) (
            ((u8)m_pmapFloor[(x*2) + y*32])
         //Next tile (Loword)
            +((u8)m_pmapFloor[(x*2)+1 + y*32]<<8)
         );
      }
   }   


}


This seems to work fine the first time it is called. However whenever I try and switch levels, the map information is loaded in, but the tile and palette information isn't. Do I somehow need to clear the memory before reinitialising it? Am I just doing something genuinely very stupid? (this isn't at all unlikely).

The full project can be found at http://tbhl.theonering.net/petegunter/downloads/Jetpack.zip if anyones willing to take a look for me. In this code, level 1 is loaded when you hit L, and level 2 is (not :P) loaded when you hit R.

Kind regards,
-Pete Gunter

#17825 - poslundc - Mon Mar 15, 2004 3:14 pm

That's a neat little game you got there.

Anyway, I'm not certain what your problem is, but I notice that you're using the DMA to copy in the stuff that won't copy, and iterating over loops to copy the stuff that will. Try copying the stuff manually, without using the DMA, and see if it will work. If it does, you know you need to fix your DMA function.

Dan.

#17827 - GunterPete - Mon Mar 15, 2004 4:37 pm

Thanks for taking the time for looking at my code, and for the kind words.

Great suggestion. I tried as you said, and it's a vast improvement. The palette information and the map information is now being copied correctly. However now the tile information is corrupted (seems like random garbage). I'm probably just iterating it incorrectly, but I can't see where I'm going wrong.

Here's the new loadLvlIntoMemory() method:
Code:
//Loads the map information into memory which includes:
//  Load level palletes (map and copper bar)
//   Level Tile Data (Char base block(0))
//   Bg 1 (Text) map data,  Sky (Screen Base Block(30))
//   Bg 2 (Rotation) map data, Floor (Screen Base Block(31))
//   Gravity, fixed :16 into gGrav;
//
void CLevel::loadLvlIntoMemory(void)
{
   /* Load in the palette data */
   u8 p;
   //Load in background pallete
//   DMA_Copy(3,(u16*)m_ppalBackground,(u16*)BGPaletteMem,128,DMA_32NOW);
   for(p=0; p<128; p++)
      ((u32*)BGPaletteMem)[p] = ((u32*)m_ppalBackground)[p];

   //Load in the copper bar pallete
//   DMA_Copy(3,(u16*)m_ppalCopper,(u16*)gpalCopper,80,DMA_32NOW);
   for(p=0; p<80; p++)
      ((u32*)gpalCopper)[p]=((u32*)m_ppalCopper)[p];

   /* Load in the tile data */
   //Level tiles
   //There are 256 tiles, each represented by 64 bytes.
   //DMA_Copy(3,(void*)m_pbmpMapTiles,(void*)CharBaseBlock(0),4096,DMA_32NOW);
   u16 t;
   for(t=0; t<4096; t++)
      ((u32*)m_pbmpMapTiles)[t] = ((u32*)CharBaseBlock(0))[t];


   /* Load in the text background data */
   //Temporary pointers to map data
   u16* bg1map =(u16*)ScreenBaseBlock(30);

   u8 x=0,y=0; //iterating vars
   for(y = 0; y < 32; y++) //loop through all 32x32 tiles
   {
      for(x = 0; x < 32; x++)
      {
         //*** BG 1 Sky
         //First tile (Hiword)
         bg1map[x + y*32] = m_pmapSky[x + y*32];
      }
   }

   /* Load in the rotation background data */
   //Temporary pointer to map data
   u16* bg2map =(u16*)ScreenBaseBlock(31);
   for(y = 0; y < 32; y++) //loop through all 32x32 tiles
   {
      for(x = 0; x < 16; x++)
      {
         //*** BG 2 Floor
         //First tile (Hiword)
         bg2map[x + (y*16)] = (u16) (
            ((u8)m_pmapFloor[(x*2) + y*32])
         //Next tile (Loword)
            +((u8)m_pmapFloor[(x*2)+1 + y*32]<<8)
         );
      }
   }   


}


I really appreciate your help. This is my final year project, and the deadline's in 3 days. :S

Regards,
-Pete

#17830 - johnny_north - Mon Mar 15, 2004 5:08 pm

Pete-

I've had problems at times with the casting of raw or .o data myself say if I externed some raw tile data as u8 and then cast it as u16 for loading (it's been a while though, so I don't remember the details.)

At least, try casting the m_pbmpMapTiles and CharBaseBlock as u16* rather than u32* and use the for loop to load 16 bits at a time.

#17831 - XeroxBoy - Mon Mar 15, 2004 5:10 pm

Code:
for(t=0; t<4096; t++)
      ((u32*)m_pbmpMapTiles)[t] = ((u32*)CharBaseBlock(0))[t];


Shouldn't this be the other way around?

As in:

Code:
for(t=0; t<4096; t++)
      ((u32*)CharBaseBlock(0))[t] = ((u32*)m_pbmpMapTiles)[t];

#17832 - GunterPete - Mon Mar 15, 2004 5:17 pm

XeroxBoy I could kiss you. I did say it was highly likely I was doing something stupid, and I was right! Sorry for posting, I really should have noticed that myself. :P

Relevant changes are made and it works fine now. I reckon I'm going to leave it loading in the data manually, at least for the hand-in. It seems to run fast enough for demoing purposes.

Horay! The practical projects now finished. Now I'd better get the report done. Why can't the markers just read the comments. ;)

Thanks everyone,
-Pete