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.

C/C++ > Tiling Code has me Stumped.

#35006 - kareemjg - Sat Jan 29, 2005 7:29 am

Okay I've been dreading sending this post.. I've been going over this for about two days and while my mistakes have taught me a lot in that time I still have not managed to solve my problem. The main premise is i'm building an rpg engine for learning sake and I've been doing some hard core disecting of the various turtoial sources. Now my problem lies in my displaying the map onto the screen. Which normally should be a easy task. I have verifed the tiles are in the right memory locations along with the maps. I can see the information in the right address via VBA so I think the problems lies with the code that I have displaying the map memory register.

Code:


int main()
 {
        
   //Looping variables
   int loop,x,y;
   
   //Background 0
   REG_BG0CNT = BIT02 | BIT07;


   //Mode 0, BG0
   SetMode(MODE_0 | BG0_ENABLE);
         
   //Load the palette into background palette memory      
   for (loop = 0; loop < MaxPalColor; loop++)
      theScreenPalette[loop] = map_demo000PAL[loop];

   //Load the tiles into background memory ***HRMM
   for (loop = 0; loop < 272; loop++)
      theTileMemory[loop] = map_demo000TILE[loop];

   //Load the map into the VideoBuffer
   for (y=0;y<32;y++)
   {
      for (x=0;x<32;x++)
      {
         theVideoBuffer[y*32+x]=map_demo000[y*32+x];
         
      
      }
   }
 
  }//end main



Here are my header references in case you are wondering

#define REG_BG0CNT (*(volatile u16*)0x4000008)

#define BGPaletteMem ((volatile u8*)0x5000000)
static u16* theScreenPalette = (u16*)BGPaletteMem;

#define BGTileMem ((u16*)0x6004000)
static u16* theTileMemory = (u16*)BGTileMem;

#define VideoBuffer ((volatile u16*)0x6000000)

---
Now from what I see on the VBA my tiles are loading in properly, and my map seems to be there also but the tiles are not right. I included a picture of what I'm seeing also a link to the full zip code that includes the tiles files with rom. Thanks for taking the time to look at this. I'm thinking the problem is at my tile loop. The loop is 272 because that is the number in my tiles array.. plus it shows up good when viewing tiles in VBA. I was trying to avoid having to ask for guidance on something that should be so routine.

http://www.khova.com/prjsite/downloads/RPGEngine012905.zip
http://www.khova.com/prjsite/downloads/RPGEngine.png
http://www.khova.com/prjsite/downloads/RPGEngine.elf

Thanks
-kareem

#35020 - Cearn - Sat Jan 29, 2005 2:34 pm

The tiles are 16-color tiles, while you have your background set up for 256 color tiles. Not setting bit7 of REG_BG0CNT should produce better results. It might be better to use named constants for this stuff rather than raw bit-numbers, that way it's easier to see what you're actualy doing.
Even after switching to 16-color mode I still get a strange picture, though, but this appears to be because the map data itself uses palette 0 for some tiles and palette 1 for others. If that was supposed to happen, then nevermind.

It's probably not a good idea to let GBA programs end, by the way, since there's no operating system to fall back on. That's why you'll often see "while(1);" at the end of main() in demos.

I also got a slew of compiler warnings because theTileMemory and others were 'defined but never used'
Code:

#define BGPaletteMem ((volatile u8*)0x5000000)
static u16* theScreenPalette = (u16*)BGPaletteMem;

#define BGTileMem ((u16*)0x6004000)
static u16* theTileMemory = (u16*)BGTileMem;

is not a good way of doing things, especially in header files. Because of the static keyword, theScreenPalette and theTileMemory variables will appear in every file that includes gba.h. Not only is this a waste of memory (or at least it should be, but apparently GCC will optimize this out), it is also pointless and potentially dangerous. It is dangerous because, since they're non-const, you can change these pointers. And even if you intended to allow this, they will be changed on a file-by-file basis. It is also pointless because the defines themselves already are the pointers that you're looking for. Well, except for the BGPaletteMem one, which should have been defined as a u16* pointer in the first place.

#35026 - kareemjg - Sat Jan 29, 2005 3:28 pm

Thanks Cearn for taking a look at it for me. I feel kinda ashamed about my sloppy coding but it was points well worth mentioning. Also thanks on the BIT help because I really was having a hell of a time. I think the problem was due to a miscaluation of Cowbites formula but now for the light of me I cant figure out what I was thinking. Just to make sure I understand this. BIT 2 = 0004 hex = 4 decmial = 0100 in binary. And

Code:

F E D C  B A 9 8  7 6 5 4  3 2 1 0
Z Z V M  M M M M  A C X X  S S P P



so that would put us at the S where
Starting address of character tile data
Address = 0x6000000 + S * 0x4000

So really S = 1 the binary digit. I was doing my math all wrong thinking that the formula evaulated as (0x6000000 + S) * x4000 so my S would then be one. But in reality the multi is suppose to be done first where it makes sense now that S is one.

Really thanks so much.

-kareem

-Microsoft SpellChecker taught me how not to spell.

#35043 - sajiimori - Sat Jan 29, 2005 7:55 pm

Quote:
Not only is this a waste of memory (or at least it should be, but apparently GCC will optimize this out), it is also pointless and potentially dangerous.
This caught my eye. Do you mean GCC should not perform the optimization?

#35055 - Touchstone - Sat Jan 29, 2005 10:54 pm

sajiimori wrote:
Quote:
Not only is this a waste of memory (or at least it should be, but apparently GCC will optimize this out), it is also pointless and potentially dangerous.

This caught my eye. Do you mean GCC should not perform the optimization?

That's not how I interpret his writing. To me it's sounds more like he is a bit surprised, but I don't think he says anything about what the compiler should or should not do.

Btw, how come you ask?
_________________
You can't beat our meat

#35059 - Cearn - Sat Jan 29, 2005 11:17 pm

sajiimori wrote:
Quote:
Not only is this a waste of memory (or at least it should be, but apparently GCC will optimize this out), it is also pointless and potentially dangerous.
This caught my eye. Do you mean GCC should not perform the optimization?

Fair enough, I can't quote chapter and verse about this, but I did expect the thing to be just another global variable with it's own symbol, memory location and everything. But when I checked the map file I couldn't find it. I should have realized that it wouldn't create a symbol, because that's the point of having something static, but I didn't. <carl>Moo, moo moo</carl>.

I've take a closer look at things, and this is what appears to be going on:
The static variable does create its own variable in each file, but only if it is also used in each file. Since none of the data CPP files use those static variables, no space is allocated for them. If I add a function that does use, say, theTileMemory, then I do indeed get another definition of that variable in that file too.
At least I that would happen if I compile the files separately. In this particular case, all the files are #included into main.cpp (I recall a few threads saying that this is a bad practice, but I can't find those anymore, sorry), so in the end it's just one big file that's being compiled anyway, and there would be only one definition of each static.
(Incidentally, const variables in cpp files are considered static unless preceded by an extern declaration of said variable. A nice little inconsistency with regular C.)

So in the end it's a little of both. If the static variable is defined (or #included, which is basically the same thing) in multiple files and compiled separately, then it will have a memory location in each of the files that actually uses it too.

#35339 - ImInABand - Thu Feb 03, 2005 7:29 am

i learned tile mode in roughly 4 hours, from scratch. the only prior knowledge i had was bitmap modes, some sprite tricks, basic programming, and a fw other nifty things i had picked up.

i pretty much stared at TONC's walkthrough, and modified it to something i understood. instead of using the for() call to do my mapping, i used the memcpy() command, and a few other things. use it just like you would for implementing sprite data, just make sure youre putting the correct data in the correct address.

i know memcpy isnt the best way to go, but it works for me.

the link to TONC is as follows:

http://user.chem.tue.nl/jakvijn/tonc/toc.htm


but as far as everything goes, yeah you just needed to declare it as 16 colors, the map is a bit messed up, i tried messing with the map offsets if it produces a map that makes a bit more sense, but i think it was just the map that you programmed that was a bit messed up.