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 > I must be missing something.

#34570 - microlith - Fri Jan 21, 2005 7:57 pm

Well, I got my VS6 problems solved and can now generate binaries problem free.

The problem now lies in my binaries, as they simply don't work. I'm missing something and don't know what.

http://www.side-7.us/misc/test.cpp

The code above works for the most part. It copies palette data and sprite data into their appropriate memory spaces without trouble.

The OAM entries, however, are not getting set and/or copied properly. Despite my settings in the attribute fields I get a blank screen (in both emulators and on actual hardware) and VisualBoyAdvance's OAM viewer shows an alternating mishmash of 256 and 16 color entries, all 8x8.

My objective first is to simply get 4 red sprites to display in a row, simply getting sprites to display short of copying the tutorials out there one-for-one seems impossible.

Am I missing something really obvious or missing the mark by a lot.

Specs:
GCC version 3.0.2 DevKit Advance
Visual Studio 6
Pern Project Headers
VisualBoyAdvance 1.7.1
EZF Advance cart + USB Link Cable
GBA SP with custom paint job.

#34693 - Cearn - Mon Jan 24, 2005 11:16 am

What exactly are the definitions for OBJ_SpriteMem and OAMMem? I can't find OBJ_SpriteMem in any of Pern's files. If you've pointed it to the 0x06014000 then never mind, but if it's pointing to 0x06010000, then you might have a mismatch between your sprite attribute and where your graphics are.
In gba.h, OAMMem is defined as
Code:
#define OAMMem        ((u32*)0x7000000)

which is a u32 pointer, not u16. Meaning that copying the attributes will will be very funky indeed. For example, sprite[0] contains
Code:
sprite[0]= { 0x2042, 0x4002, 0x0200, 0x0000 };

Copying this to OAMMem (as a u32*) will result in
Code:
{ 0x2042, 0x0000, 0x4002, 0x0000 }    // OAM[0]
{ 0x0200, 0x0000, 0x0000, 0x0000 }    // OAM[1]

When using loops to copy, ALWAYS be sure that the source and destination are of equal types.

Speaking of types, since the GBA is a 32bit machine, using int/u32 will be faster than short/u16. Compare the following copying routines.
Code:

// copy a data array of N bytes
u8 data[N]= { blah, blah, blah };

int ii;
short jj;
u16 *dst16, *src16;
u32 *dst32, *src32;

dst16= (u16*)0x06000000;
src16= (u16*)data;
dst32= (u32*)0x06000000;
src32= (u32*)data;

// u32 data, int loop index
for(ii=0; ii < N>>2; ii++)
    dst32[ii]= src32[ii];

// u16 data, int loop index
for(ii=0; ii < N>>1; ii++)
    dst16[ii]= src16[ii];

// u16 data, short loop index
for(jj=0; jj < N>>1; jj++)
    dst16[jj]= src32[jj];

Under normal circumstances, the int/u32[] case will be 80% faster than int/u16[], simply because you have twice as many loop iterations to go through. int/u16[] will be 20% faster than short/u16[] because of the extra instructions needed to make sure the short stays short. So you can pretty much double the speed of your copying routines by changing the type alone. (There are even faster ways, but those are a little more involved.)