Problems(Bug) using 16x16 sprites

Post Reply
seven
Posts: 7
Joined: Tue Aug 04, 2009 10:53 am
Contact:

Problems(Bug) using 16x16 sprites

Post by seven » Thu Nov 12, 2009 4:03 pm

Hello,

is there a known bug/problem using 16x16 sprites ?
i am trying to use 16x16 sprites on my project and i found myself having the following problem :

if for example i am trying to display more than one 16x16 sprites on the screen is being displayed the first allocated sprite as many times as the number of sprites that i am trying to display .

i have even tried this on the example "bitmap_sprites" from "Graphics/Sprites/bitmap_sprites/" .

note that i am using SpriteColorFormat_Bmp format, so if you change in that tutorial example the sprites size from 32x32 to 16x16 and the format for all to SpriteColorFormat_Bmp you will see 3 red sprites instead of the 1red, 1green, 1blue ..

does anyone know anything about this ?

i should mention that this problem i have only when i am using 16x16 or 8x16 etc .. not for 32x32 ..

Thanks.
Last edited by seven on Thu Nov 12, 2009 4:26 pm, edited 1 time in total.

seven
Posts: 7
Joined: Tue Aug 04, 2009 10:53 am
Contact:

Re: Problems(Bug) using 16x16 sprites

Post by seven » Thu Nov 12, 2009 4:04 pm

here would be the code from here :http://www.devkitpro.org/libnds/a00007.html#a9 (but modified for 16x16 - if anyone is interested to check it out):

Code: Select all

#include <nds.h>
#include <stdio.h>

//a simple sprite structure
//it is generally preferred to separate your game object
//from OAM
typedef struct 
{
   u16* gfx;
   SpriteSize size;
   SpriteColorFormat format;
   int rotationIndex;
   int paletteAlpha;
   int x;
   int y;
}MySprite;

int main() {
    //three sprites of differing color format
   MySprite sprites[] = {
      {0, SpriteSize_16x16, SpriteColorFormat_Bmp, -1, 15, 20, 15},
      {0, SpriteSize_16x16, SpriteColorFormat_Bmp, -1, 15, 20, 80},
      {0, SpriteSize_16x16, SpriteColorFormat_Bmp, -1, 15, 20, 136}
   };

   videoSetModeSub(MODE_0_2D);

   consoleDemoInit();
   
   //initialize the sub sprite engine with 1D mapping 128 byte boundary
   //and no external palette support
   oamInit(&oamSub, SpriteMapping_Bmp_1D_128, false);

   vramSetBankD(VRAM_D_SUB_SPRITE);
   
   //allocate some space for the sprite graphics
   for(int i = 0; i < 3; i++)
      sprites[i].gfx = oamAllocateGfx(&oamSub, sprites[i].size, sprites[i].format);
   
    dmaFillHalfWords(ARGB16(1,31,0,0), sprites[0].gfx, 16*16*2);
   dmaFillHalfWords(ARGB16(1,0,31,0), sprites[1].gfx, 16*16*2);
   dmaFillHalfWords(ARGB16(1,0,0,31), sprites[2].gfx, 16*16*2);

   //set index 1 to blue...this will be the 256 color sprite
   SPRITE_PALETTE_SUB[1] = RGB15(0,31,0);
   //set index 17 to green...this will be the 16 color sprite
   SPRITE_PALETTE_SUB[16 + 1] = RGB15(0,0,31);

   while(1) {
      for(int i = 0; i < 3; i++) {
         oamSet(
            &oamSub, //sub display
            i,       //oam entry to set
            sprites[i].x, sprites[i].y, //position
            0, //priority
            sprites[i].paletteAlpha, //palette for 16 color sprite or alpha for bmp sprite
            sprites[i].size,
            sprites[i].format,
            sprites[i].gfx,
            sprites[i].rotationIndex,
            true, //double the size of rotated sprites
            false, //don't hide the sprite
            false, false, //vflip, hflip
            false //apply mosaic
         );
      }
      swiWaitForVBlank();
      //send the updates to the hardware
      oamUpdate(&oamSub);
   }
   return 0;
}

Sylus101
Posts: 179
Joined: Wed Dec 24, 2008 5:08 am

Re: Problems(Bug) using 16x16 sprites

Post by Sylus101 » Thu Nov 12, 2009 5:33 pm

Looks like a bug in oamSet(). Adding this output:

Code: Select all

consoleClear();
iprintf("%d %d %d\n", (int)sprites[0].gfx, (int)sprites[1].gfx, (int)sprites[2].gfx);
iprintf("%d %d %d", oamSub.oamMemory[0].gfxIndex, oamSub.oamMemory[1].gfxIndex, oamSub.oamMemory[2].gfxIndex);
The gfx pointers are all 512 bytes apart as they should be, but the gfx Index in OAM is 0 for all three sprites.
-Sylus "Not Stylus..." McFrederickson

Come visit my web site.

seven
Posts: 7
Joined: Tue Aug 04, 2009 10:53 am
Contact:

Re: Problems(Bug) using 16x16 sprites

Post by seven » Thu Nov 12, 2009 5:42 pm

Sylus101 wrote:The gfx pointers are all 512 bytes apart as they should be, but the gfx Index in OAM is 0 for all three sprites.
Any advice on how could i fix this ?
Thanks for reply.

Sylus101
Posts: 179
Joined: Wed Dec 24, 2008 5:08 am

Re: Problems(Bug) using 16x16 sprites

Post by Sylus101 » Thu Nov 12, 2009 8:03 pm

Are you planning on using bmp sprites? They're pretty uncommon due to the extra space they take up. 256 color paletted sprites are pretty well tested and shouldn't give you any issue.

I'm not sure looking at the oamSet() code... but you could specify the index value yourself like this after oamSet() to force it.

Code: Select all

oamSub.oamMemory[0].gfxIndex = 0; //This was already 0 so unnessesary...
oamSub.oamMemory[1].gfxIndex = 4;
oamSub.oamMemory[2].gfxIndex = 8;
Since the boundary is set at 128 in oamInit(), the index is multiplied by the boundary (number of bytes) to know where to look in VRAM for the gfx.

I tested this out, and it does work. Note... this is a bit hackish I think....
-Sylus "Not Stylus..." McFrederickson

Come visit my web site.

Discostew
Posts: 103
Joined: Sun Mar 08, 2009 7:24 pm

Re: Problems(Bug) using 16x16 sprites

Post by Discostew » Fri Nov 13, 2009 9:04 am

I'm pretty sure it has something to do with the OamSet function, specifically the portion that calculates the data in relation to BMP sprites...

Code: Select all

// In the libNDS source
		int sx = ((u32)gfxOffset >> 1) & ((1 << oam->gfxOffsetStep) - 1);
		int sy = (((u32)gfxOffset >> 1) >> oam->gfxOffsetStep) & 0xFF;
		oam->oamMemory[id].gfxIndex = (sx >> 3) | ((sy >> 3) << (oam->gfxOffsetStep - 3));
		oam->oamMemory[id].blendMode = format;
In your current case, using SpriteMapping_Bmp_1D_128 in oamInit would set oam->gfxOffsetStep to 7.
Each 16x16 bmp sprite takes up 512 bytes (0x200), so the 2nd sprite at 0x6600200 would get set up like this

sx = 0;
sy = 1;
oam->oamMemory[id].gfx = 0;

In fact, if you were to create a total of 12 16x16 bmp sprites one right after another, this method would force sprites 1 to 4 to look the same, which is the 1st. Sprites 5 to 8 would show what the 2nd was meant to be, and sprites 9 to 12 would show what the 3rd was meant to be.

EDIT:
Fixed the values in bold

seven
Posts: 7
Joined: Tue Aug 04, 2009 10:53 am
Contact:

Re: Problems(Bug) using 16x16 sprites

Post by seven » Fri Nov 13, 2009 11:00 am

yes, you are right, just that the 5-8 is actually displaying the 5th sprite, 8 to 12 the 8th sprite and so on ..

i tried the hack that Sylus's posted, which works for that particular example but doesn't really help my case as i am not using just 16x16 sprites but also 32x32 and 8x16 and so on .. but the 16x16 and 8x16 are the only ones which i have problems with and i haven't found a good solution on this yet .
Regards,
Dan.

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 2 guests