I work primarily in Java and until I installed devkitARM and libnds just under a week ago haven't used C++ since an intro course in high school. Because of this my code may (more likely will) be riddled with language issues or just bad form, please don't hesitate to point them out because I won't learn if I keep doing the wrong thing!
Right now I'm working on learning how to work with sprites and the oam. I have successfully gotten sprites on screen, moved them around - even between screens! - and figured out how to manage multiple palettes (using 4bpp for this project because it seemed more straightforward. PLEASE correct me if I'm wrong).
Now I'm working on a simple implementation to really get a feel for how it all ties together, but I'm not really sure how a lot of stuff surrounding the oam works.
From what I understand, including an image file into the binary using grit gives you, among other things, a pointer filenameTiles to the image data in main memory. In cases where the image file contains multiple sprites, simple pointer arithmetic can lead you to the start of each sprite within the image. It is trivial to set up an array of pointers to sprites then, for example (again, assuming 16-color)
Code: Select all
u8 *imageFrames[2];
imageFrames[0] = (u8*) filenameTiles;
imageFrames[1] = (u8*) filenameTiles + 32;
I'm pretty sure that's all right. Now here's where I get fuzzy.
The main and sub display each have their own unique oam, and for a sprite to be drawn on either screen that screen's oam needs to know about it. If an object is to move between screens, it needs an entry in both oamMain and oamSub and any changes may require using oamSet on both. There are essentially two completely separate sprite objects that are carefully manipulated to give the player the illusion that they are one object on a single playing field. Is this true, or is there a way to only allocate image data once and then use it on both screens?
This next part is theory to me, I have yet to have a chance to test it: the index argument of oamSet is an identifier indicating which sprite is being set/reset. If you have fifteen identical "bullet" sprites on screen at once, they can all use the same pointer to image data (from oamAllocateGfx earlier) without issue, correct? To phrase it another way, the shared image data only needs to be allocated into oam memory once and then several instances of that image can be drawn, including with different palettes. This, however, may not give expected functionality for animations that rely on re-dmaCopying image data - all images using that pointer will animate together! If similar objects need to animate separately then it is necessary to allocate each frame into oam memory and then point each object to the frame it needs. This takes up more oam memory, which IIRC is limited (how much?)
So..first off, is that all right? Second off, if you run into a situation where you need more than 16 palettes or have more sprites than will fit in oam memory, how can that be handled? With 256-color sprites do they all share one palette (your 16 16-color palettes, I assume, so unless there's overlap in the colors you want you can't mix?) And finally, is it necessary to call oamSet every frame something changes or is there a way to just affect individual fields (in many cases, the only changes will be to position, and oamSet is a pretty unwieldly function due to the sheer number of arguments it takes)
Pardon all the questions here but I'm trying to wrap my brain around several things at once with mixed success...