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.
Problems(Bug) using 16x16 sprites
Problems(Bug) using 16x16 sprites
Last edited by seven on Thu Nov 12, 2009 4:26 pm, edited 1 time in total.
Re: Problems(Bug) using 16x16 sprites
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;
}
Re: Problems(Bug) using 16x16 sprites
Looks like a bug in oamSet(). Adding this output:
The gfx pointers are all 512 bytes apart as they should be, but the gfx Index in OAM is 0 for all three sprites.
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);
Re: Problems(Bug) using 16x16 sprites
Any advice on how could i fix this ?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.
Thanks for reply.
Re: Problems(Bug) using 16x16 sprites
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.
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....
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;
I tested this out, and it does work. Note... this is a bit hackish I think....
Re: Problems(Bug) using 16x16 sprites
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...
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
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;
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
Re: Problems(Bug) using 16x16 sprites
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 .
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.
Dan.
Who is online
Users browsing this forum: Ahrefs [Bot] and 2 guests