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 > sprite initialization

#14133 - plasma - Wed Dec 31, 2003 2:37 am

If a game has several levels like Megaman, do all the sprites have to be copied into OAM and set offscreen? If there are, say, 80 sprites in one level and 20 sprites within another, can they be copied separately at different times?

#14135 - XeroxBoy - Wed Dec 31, 2003 3:06 am

Definitely - you can even copy new sprites in during a level!

=D

#14137 - plasma - Wed Dec 31, 2003 3:23 am

well then, o great Xerox Boy (no sarcasm), can you tell me how?
_________________
ΩΠΣ

#14138 - XeroxBoy - Wed Dec 31, 2003 3:30 am

That depends on the structure of your code/level data, of course, but generally all you need to do is store a list of the enemies in your level, and as you move your character and they become visible, you reserve them a spot in OAM, copy their graphics/palette into VRAM (using DMA, preferably), and then properly set their OAM attributes. Of course, you should generally be using a shadow OAM, but whatever.

And, uh, thanks for the (undeserved) flattery :P

If anything above doesn't make sense, check out The PERN Project tutorials.

#14141 - plasma - Wed Dec 31, 2003 3:43 am

Thanks a great many stuffed pizzas. I've already been to dovoto's site, but he hasn't updated it in a while so it doesnt help much. All I ask now is how to implement a shadow OAM.
_________________
ΩΠΣ

#14142 - XeroxBoy - Wed Dec 31, 2003 4:02 am

This actually is in PERN's tutorials, but I could see how you might miss it (especially since he doesn't use the same lingo as I do).

A shadow OAM is just an alternate version of the OAM, stored in memory. Instead of modifying the actual OAM, you make your modifications to the shadow version, then at the end of your game loop, you DMA it over the real OAM.

As dovoto does it:

Code:

u16* OAM = (u16*)0x7000000; //this is actual OAM memory
OAMentry sprites[128]; //this is my array of sprites

//.... you'd modify sprites whenever you want to make changes to OAM

// At the end of your game loop, you'd then call the following function

//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];

}

#14144 - crossraleigh - Wed Dec 31, 2003 4:19 am

You should look at Rafael Baptista's Gameboy Advance Resource Management (printer friendly version) article for a more indepth explanation. Also, the SGADE library quite cleanly implements shadow OAM in SoSpriteManager.c.

As a side note, I think it's worth mentioning the benefit of putting shadow OAM in IWRAM. DMA from IWRAM is only 2-3 cycles per word. I actually picked that trick up from dovoto himself one day on #gbadev.

#14145 - XeroxBoy - Wed Dec 31, 2003 4:27 am

Correct me if I'm wrong, but the given example would but the shadow OAM into IWRAM, wouldn't it? Unless otherwise specified, variables are placed into IWRAM, and constants are placed into ROM.

#14147 - crossraleigh - Wed Dec 31, 2003 4:54 am

Well, I don't like getting too conversational on a board used so much as a reference; this information about IWRAM is widely available.

At any rate, the answer is: No, variables are placed in external work RAM by default. Internal work ram is a 32kb area embedded in the CPU. It has a 32 bit bus while EWRAM and ROM only have a 16 bit bus. To place a variable in IWRAM, declare it something like this:
Code:
int foo __attribute__ ((section (".iwram")));


Also, the example you gave doesn't use DMA at all. It just loops through and copies each entry.

#14148 - XeroxBoy - Wed Dec 31, 2003 5:04 am

In my linkscript, at least, all variables - local and global - are placed in IWRAM. I'm not alone, either, as evidenced in this thread.

Yeah, I probably should've shown an example with DMA. Apologies all around.

#14149 - plasma - Wed Dec 31, 2003 5:23 am

what version of linkscript do you have?

#14150 - XeroxBoy - Wed Dec 31, 2003 5:38 am

I'm fairly certain it's the one that comes included with DevKitAdvance-r5-beta3.

I can't verify this, however, as it appears Sourceforge is down. Terribly sorry.

In any case, it's easy to find out where your compiler is stashing your variables - create a simple program that merely creates two variables (a global and a local), assigns them a value, and then loops infinitely. Without too much difficulty, you should be able to locate the two variables in Visual Boy Advance's memory viewer.

#14151 - sajiimori - Wed Dec 31, 2003 5:38 am

The lnkscript included with DevKit Advance puts variables in IWRAM by default. A few common ways of using EWRAM are:

1) Insert a special tag to tell the compiler where to put a particular variable.

2) Use malloc.

3) Make a struct to contain all the data and recast the base address of EWRAM as an instance of the struct. Don't combine this method with any other.

#14154 - Paul Shirley - Wed Dec 31, 2003 5:52 am

removed

Last edited by Paul Shirley on Sun Mar 28, 2004 9:26 pm; edited 2 times in total

#14157 - crossraleigh - Wed Dec 31, 2003 6:02 am

My sincerest apologies. I feel quite the jerk. An nm of my code shows all my non-const data in IWRAM, even without the attribute. I will try to be more careful before going headlong in spreading such disinformation.