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 > 2 sprites color error

#150998 - Cave Johnson - Sat Feb 16, 2008 6:00 pm

So far in my simple game, ive created 2 sprites, but when i run the game, depending on their priorities, one sprite takes the place of the other and the colors become all gray. After working on this problem for a week, i think i have narrowed the problem down to a snippet of my main.cpp.

dopefish is the sprite
fish is the class
ak47 is the sprite
gun is the class

Heres the code:

void initSprites(tOAM * oam, SpriteInfo *spriteInfo)
{

static const int BYTES_PER_16_COLOR_TILE = 32;
static const int COLORS_PER_PALETTE = 16;
static const int BOUNDARY_VALUE = 32;

static const int OFFSET_MULTIPLIER = BOUNDARY_VALUE /
sizeof(SPRITE_GFX[0]);
int nextAvailableTileIdx = 0;

static const int DOPEFISH_OAM_ID = 1;
assert(DOPEFISH_OAM_ID < SPRITE_COUNT);
SpriteInfo * dopefishInfo = &spriteInfo[DOPEFISH_OAM_ID];
SpriteEntry * dopefish = &oam->spriteBuffer[DOPEFISH_OAM_ID];

dopefishInfo->oamId = DOPEFISH_OAM_ID;
dopefishInfo->width = 32;
dopefishInfo->height = 32;
dopefishInfo->angle = 462;
dopefishInfo->entry = dopefish;

dopefish->posY = 112.5;
assert(!dopefish->isRotoscale || (dopefishInfo->oamId < MATRIX_COUNT));
dopefish->rsDouble = false;
dopefish->objMode = OBJMODE_NORMAL;
dopefish->isMosaic = false;
dopefish->colMode = OBJCOLOR_16;
dopefish->objShape = OBJSHAPE_SQUARE;

dopefish->posX = 112.5;
dopefish->rsMatrixIdx = ATTR1_ROTDATA(spriteInfo->oamId);
dopefish->objSize = OBJSIZE_32;

dopefish->tileIdx = nextAvailableTileIdx;
nextAvailableTileIdx += dopefishTilesLen / BYTES_PER_16_COLOR_TILE;
dopefish->objPriority = OBJPRIORITY_1;
dopefish->objPal = dopefishInfo->oamId;

rotateSprite(&oam->matrixBuffer[spriteInfo->oamId],
dopefishInfo->angle);

static const int AK47_OAM_ID = 0;
assert(AK47_OAM_ID < SPRITE_COUNT);
SpriteInfo * ak47Info = &spriteInfo[AK47_OAM_ID];
SpriteEntry * ak47 = &oam->spriteBuffer[AK47_OAM_ID];

ak47Info->oamId = AK47_OAM_ID;
ak47Info->width = 32;
ak47Info->height = 32;
ak47Info->angle = 462;
ak47Info->entry = ak47;
//i placed the ak47 in the middle of nowhere just to see if i could get
//both sprites working
ak47->posY = 50;
ak47->isRotoscale = false;
assert(!ak47->isRotoscale || (ak47Info->oamId < MATRIX_COUNT));
ak47->isHidden = false;
ak47->objMode = OBJMODE_NORMAL;
ak47->isMosaic = false;
ak47->colMode = OBJCOLOR_16;
ak47->objShape = OBJSHAPE_SQUARE;

ak47->posX = 50;
ak47->objSize = OBJSIZE_32;

ak47->tileIdx = nextAvailableTileIdx;
nextAvailableTileIdx += ak47TilesLen / BYTES_PER_16_COLOR_TILE;
ak47->objPriority = OBJPRIORITY_0;
ak47->objPal = ak47Info->oamId;

rotateSprite(&oam->matrixBuffer[spriteInfo->oamId],
ak47Info->angle);

dmaCopyHalfWords(SPRITE_DMA_CHANNEL,
dopefishPal,
&SPRITE_PALETTE[spriteInfo->oamId * COLORS_PER_PALETTE],
dopefishPalLen);
dmaCopyHalfWords(SPRITE_DMA_CHANNEL,
dopefishTiles,
&SPRITE_GFX[dopefish->tileIdx * OFFSET_MULTIPLIER],
dopefishTilesLen);

dmaCopyHalfWords(SPRITE_DMA_CHANNEL,
ak47Pal,
&SPRITE_PALETTE[spriteInfo->oamId * COLORS_PER_PALETTE],
ak47PalLen);

dmaCopyHalfWords(SPRITE_DMA_CHANNEL,
ak47Tiles,
&SPRITE_GFX[ak47->tileIdx * OFFSET_MULTIPLIER],
ak47TilesLen);
}

What am i doing wrong? Thanks.


Last edited by Cave Johnson on Tue Feb 19, 2008 3:36 pm; edited 2 times in total

#151087 - Cave Johnson - Mon Feb 18, 2008 7:12 pm

After messing with the code, i finally got both of the sprites in the game, and the fish sprite is colored correctly, while the gun is all black. from my messing around it seems that this is do to oam 1 only containing the color black and not being palleted, does this make sense to anyone, and if so, how do i fix it?

#151100 - Cearn - Mon Feb 18, 2008 11:46 pm

Cave Johnson wrote:
Code:
void initSprites(tOAM * oam, SpriteInfo *spriteInfo)
{
    [[ other stuff omitted for clarity ]]

    static const int DOPEFISH_OAM_ID = 0;
   
    dopefishInfo->oamId = DOPEFISH_OAM_ID;
    dopefish->objPal = dopefishInfo->oamId;

    static const int AK47_OAM_ID = 0;
 
    SpriteInfo * ak47Info = &spriteInfo[AK47_OAM_ID];
    SpriteEntry * ak47 = &oam->spriteBuffer[AK47_OAM_ID];

    ak47Info->oamId = AK47_OAM_ID;
    ak47->objPal = ak47Info->oamId;

    dmaCopyHalfWords(SPRITE_DMA_CHANNEL, dopefishPal, &SPRITE_PALETTE[spriteInfo->oamId * COLORS_PER_PALETTE], dopefishPalLen);


dmaCopyHalfWords(SPRITE_DMA_CHANNEL, ak47Pal, &SPRITE_PALETTE[spriteInfo->oamId * COLORS_PER_PALETTE], ak47PalLen);

}


What am i doing wrong? Thanks.

The object use the same OAM ID, so one hides the other (but I guess you already figured that part out). Unless you forced grit to use 16 colors exactly, the palettes used are likely to be 256 colors in length, so even with different oamIds later palettes may override others. To be sure, check which colors are actually in the palette and where.

Also, [code]-tags makes code keep its formatting.

#151130 - Cave Johnson - Tue Feb 19, 2008 3:45 pm

Ya im sorry that was my fault, i had changed their oam ids and forgot to fix the code in the origional post. Right now the spirte in oam 0(gun) is working fine and the colors perfect, but the fish in oam 1 is all black. I thought i had used 16 color palettes, did i do the grit file wrong

-W3

-p

-gt

-gB4

You also said to "check which colors are actually in the palette and where," but being a massive noob, i have no idea how to do that, and google is not helping at all. Thanks for putting up with me.

#151140 - Cearn - Tue Feb 19, 2008 6:07 pm

Cave Johnson wrote:
Ya im sorry that was my fault, i had changed their oam ids and forgot to fix the code in the origional post. Right now the spirte in oam 0(gun) is working fine and the colors perfect, but the fish in oam 1 is all black. I thought i had used 16 color palettes, did i do the grit file wrong

-W3

-p

-gt

-gB4
The number of colors that are exported is independent of the bitdepth of the graphics (this is more suitable if you have a single sprite sheet using multiple 16-color palettes). If you want 16 colors exactly, use -pn 16, with an optional -ps if the colors you want don't start at 0. Alternatively, simply copy 16 colors regardless of how long the exported palette is.

Cave Johnson wrote:
You also said to "check which colors are actually in the palette and where," but being a massive noob, i have no idea how to do that, and google is not helping at all. Thanks for putting up with me.

Open the binary in an emulator that has a palette viewer (DesmuMe and no$gba-debug should do the trick). You can also draw a create a 16x16 256-color sprite that displays all the colors:

Code:

// Use these graphics for a 16x16@8 object to display the full object palette.
const u8 palTiles[16*16]= {
   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
   0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
   0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
   0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
   0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
   0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
   0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
   0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
   
   0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
   0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
   0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
   0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
   0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
   0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
   0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
   0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
   
   0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
   0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
   0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
   0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
   0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
   0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
   0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
   0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
   
   0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
   0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
   0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
   0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
   0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
   0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
   0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
   0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
};

#151146 - Cave Johnson - Tue Feb 19, 2008 8:49 pm

The palette viewer explained alot. It seems that it is only registering the colors from the gun sprite, but not any from the fish sprite. How do i fix this? I would think that it has something to do with my grit file, but none of the methods you suggested work, although i am probably doing them wrong. Do you have anyother suggestions, and please explain anything as clearly and in as basic terms as possible, because once again, im a total noob at this stuff. Thanks.

#151148 - Dwedit - Tue Feb 19, 2008 10:14 pm

Code:

dmaCopyHalfWords(SPRITE_DMA_CHANNEL, dopefishPal, &SPRITE_PALETTE[spriteInfo->oamId * COLORS_PER_PALETTE], dopefishPalLen);
dmaCopyHalfWords(SPRITE_DMA_CHANNEL, ak47Pal, &SPRITE_PALETTE[spriteInfo->oamId * COLORS_PER_PALETTE], ak47PalLen);


I see that you overwrote the same palette memory location twice. spriteInfo->oamId doesn't change, so you're overwriting the same memory inside the GBA's palette. (at least that's what I'm guessing SPRITE_PALETTE is)
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#151180 - Cave Johnson - Wed Feb 20, 2008 4:04 pm

"I see that you overwrote the same palette memory location twice. spriteInfo->oamId doesn't change, so you're overwriting the same memory inside the GBA's palette. (at least that's what I'm guessing SPRITE_PALETTE is)" I understand what your saying, and i think that my proglem is that the palette is being overwritten, so i changed

spriteInfo->oamId * COLORS_PER_PALETTE],

to

dopefishInfo->oamId * COLORS_PER_PALETTE],

and

spriteInfo->oamId * COLORS_PER_PALETTE],

to

ak47Info->oamId * COLORS_PER_PALETTE],

No dice, i still get an all black fish sprite. Is this even what you meant? Thanks.

#151182 - Cearn - Wed Feb 20, 2008 4:46 pm

Yeah, that should be better. Strange that it doesn't work then; are you sure the oamId's of dopefishInfo and ak47Info are different?

  • Fill the whole palette with an obnoxiously obvious color (pure green will work). This will show you how many colors are copied over.
  • Load one palette instead of both. See which colors are now in the palette and where.
  • Repeat the procedure for the other palette.

This tells you with certainty if the problem was the copy or the palettes themselves. It should also indicate what would happen when both copies are active.

#151194 - Cave Johnson - Wed Feb 20, 2008 8:17 pm

Im not sure if i did it right, but this is what i did.

Commented out fish.
Ran it in desmume.
Looked at the palette.
Repeated only with gun commented out.

Either way, this did show me that in the palette viewer, the colors for fish were in the second line, while the colors for gun were in the first line, and i assume this means that they are not overwriting eachother. But when i look at the palette with both sprites in it, the second line that normally contained the fish's colors, were all black. What does this mean? Thanks.

#151342 - Cave Johnson - Sat Feb 23, 2008 8:52 pm

Hizzah!! After changing some of the spriteInfo into dopefishinfo or ak47info respectivly, the problem was fixed. Thanks everyone for helping me. Tepples your still a god.