#93413 - TheRain - Wed Jul 19, 2006 12:47 am
Hey guys, I'm trying to load in one big sprite bin file with multiple 32x32 sprites and I was wondering... how should one copy this into VRAM space and how does one assign them individually to sprites in OAM?
#93437 - TheRain - Wed Jul 19, 2006 4:08 am
or where can I find information on working with sprites besides the C++ tutorial (since I'm working in C)?
#93449 - TheRain - Wed Jul 19, 2006 5:05 am
ok, I've figured out that I needed to set DISPLAY_SPR_2D_BMP_256 to get the 256x256 sprite map to map correctly... also I figured out that setting
sprites[1].attribute[2] = ATTR2_ALPHA(1)| 128;
that 128 moves down to the 32x32 square below the first 32x32 square... so I'm guessing I'd go in 128 incriments to get to each one after that...
However, I can't seem to figure out how to get to the 32x32 square immediately right to the first 32x32 square.. This way of addressing these squares isn't making much sense to me... I just kept experimenting to get this far.
Any hints?
I figured that if there are 8 in each colum and incrimenting 128 gets me to square two.... then incrimenting to square nine, or by 1024 would get me over to column 2... but this does not seem to be the case.
#93459 - Valmond - Wed Jul 19, 2006 7:36 am
If the sprite data makes you wonder, it's organised in 8x8 blocks
something like this :
1 2 3 4
5 6 7 8
9 ...
where each number is a 8x8 block then.
There are converters though if you don't want to write your own one.
HTH
/Valmond
#93460 - TheRain - Wed Jul 19, 2006 8:17 am
i'm using 32 x 32 blocks though.... I just figured it out though. thanks for that info, I'm not really sure what it means but hopefully I'll understand you soon. here's what I've got goin....
256x256 pixel bitmap with 16bit color, divided into 64 32x32 pixel sprites. loading the bmp converted to bin file, I wanted to be able to map any sprite entry to any of those 64 32x32 sprites... like a 2-dimensional array.
Luckily, there is a mode for this- DISPLAY_SPR_2D_BMP_256
which is used like
Code: |
videoSetMode( MODE_5_2D |
DISPLAY_SPR_ACTIVE | //turn on sprites
DISPLAY_BG3_ACTIVE | //turn on background 3
DISPLAY_SPR_2D_BMP_256 //2D BMP 256x256 sprite map
);
|
then the sprite entry looks something like this:
Code: |
sprites[0].attribute[0] = ATTR0_BMP | ATTR0_ROTSCALE_DOUBLE | 10; //bitmap mode sprite at y=10
sprites[0].attribute[1] = ATTR1_SIZE_32 | 20; //32x32 sprite placed at x=20
sprites[0].attribute[2] = ATTR2_ALPHA(1)| SPRITE_LOCATION; // where location is a value that will reference a 32x32 space in the 256x256 bitmap
|
now, what I figured out is that iterating through 32x32 blocks horizontally, you must multiply the block number by 4... and iterating through 32x32 block vertically, you must multiply the block number by 128.... so in the code above, SPRITE_LOCATION can be replaced with an equation and x and y variables like so
Code: |
sprites[0].attribute[2] = ATTR2_ALPHA(1)| ((x*4)+(y*128));
|
Now if I have a 256x256 bitmap of 32x32 sprites like the following
[Images not permitted - Click here to view it]
x = 4 and y = 0 will get me to the number 5
x = 0 and y = 1 will get me to the number 9
x= 1 and y=1 will get me to the number 10
and so on.
#93463 - TheRain - Wed Jul 19, 2006 9:02 am
Valmond wrote: |
If the sprite data makes you wonder, it's organised in 8x8 blocks
|
Oh! now i get what you're saying... and now the math above that I did makes more sense since if it was 8x8 sprites... i wouldn't have to times x by 4 anymore ;) Somehow this was really not making sense to me before.
#93507 - Valmond - Wed Jul 19, 2006 4:35 pm
So did it work out ?
/Valmond
#93509 - iainprice - Wed Jul 19, 2006 4:41 pm
So how did you modify the code to convert to 8x8?
#93513 - TheRain - Wed Jul 19, 2006 4:59 pm
yes, it's working... thanks again for the info also!
to iainprice....
I didn't modify the code to convert to 8x8.. what I was having trouble understanding toward the end there is how the coordinate system worked that was used to select which 32x32 square was shown in the sprite from the 256x256 map.
Code: |
int SPRITE_LOCATION;
sprites[0].attribute[2] = ATTR2_ALPHA(1)| SPRITE_LOCATION;
|
basically, if you have a 2D bitmap of sprites.... increasing SPRITE_LOCATION from 0 to 1 will move you 8 pixels over on the x axis of your sprite map.... regardless of if you are using 8x8, 16x16, 32x32 or whatever pixel sprites. Once you've iterated through the top row and reached 32, you will have moved to the next 8 pixel wide row down. In a 32x32 map, in order to get to the next row down, you would have to move 128 steps..... because 32 divided by 8 is 4... and 32 steps times 4 is 128.
#93571 - iainprice - Wed Jul 19, 2006 10:51 pm
Cheers
#93713 - iainprice - Thu Jul 20, 2006 9:19 pm
Actually I'm still having a problem or two....the images are loading wrong...
I have a 256*256 pixel bmp with 256 colours. Converted to h file...
[code]
for(i = 0; i < 256; i++)
SPRITE_PALETTE[i] = spritesPal[i];
for(i = 0; i< 32*16*64; i++)//64 sprites?
SPRITE_GFX[i] = spritesTiles[i];
sprites[e_call_pet_s].oam = &OAMCopySub[e_call_pet_s];
sprites[i].oam->attribute[0] = ATTR0_COLOR_256 | ATTR0_SQUARE | ATTR0_BMP;
sprites[e_call_pet_s].oam->attribute[1] = ATTR1_SIZE_32|e_call_pet_s;
sprites[e_call_pet_s].oam->attribute[2] = ATTR2_ALPHA(1);
sprites[e_call_pet_s].x = 111<<8;
sprites[e_call_pet_s].y = 98<<8;
sprites[e_call_pet_s].gfxID = 0;[/code]
where e_call_pet_s is an enumerated type with value 0 for the first sprite.
#93716 - TheRain - Thu Jul 20, 2006 9:39 pm
What data type is your tile data stored under? it may need to be type casted... also, can you explain more about the result you are getting?
#93726 - iainprice - Thu Jul 20, 2006 10:14 pm
[code]
const unsigned short spritesTiles[32768]=
{
0xFDFD,0xFDFD,0xFDFD,0xFDFD,0xFDFD,0xFDFD,0xFDFD,0xFBFD,
[/code]
The sprites just seem to be the first row of eight across the top then a row eight high of white, then the next row eight high......
[/code]
#93728 - TheRain - Thu Jul 20, 2006 10:27 pm
iainprice wrote: |
I have a 256*256 pixel bmp with 256 colours. Converted to h file...
for(i = 0; i< 32*16*64; i++)//64 sprites?
SPRITE_GFX[i] = spritesTiles[i];
|
to initialize SPRITE_GFX to your 256x256 space... you will want to do a for loop like this, i believe:
Code: |
for(i=0; i<256*256;i++)
SPRITE_GFX[i] = spritesTiles[i];
|
then the data type of the sprites will determine what gets copied... since you are in 256 color mode with your sprite, you probably would consider SPRITE_GFX as a u8* ?? I'm not totally sure about that, it may also be a u16* regardless of what your sprite mode is set to.... so then whatever your spriteTiles data type is, you'll want to type cast it to whatever SPRITE_GFX data type is in your code for copying the data here... see the bitmap sprite example in the libnds examples to get an idea.
#93729 - iainprice - Thu Jul 20, 2006 10:34 pm
No change.
I have had a single 32*32 sprite working but am trying to convert to 256*256.
What does ATTR2_ALPHA do?
Also
sprites[i].oam->attribute[0] = ATTR0_COLOR_256 | ATTR0_SQUARE | ATTR0_BMP;
is different to the 32*32 code I used.....
#93732 - TheRain - Thu Jul 20, 2006 10:43 pm
it appears, to me, that your data is 8 bit data being represented in pairs as 16 bit words...
It appears that there are 32768 entries of these words.... and so if SPRITE_GFX is a u16* maybe you should try this:
Code: |
for(i=0; i<256*128;i++) // 258 * 128 = 32768
SPRITE_GFX[i] = spritesTiles[i];
|
And if that doesn't work, maybe try type casting ((u16*)spriteTiles)[i].
Last edited by TheRain on Thu Jul 20, 2006 10:48 pm; edited 1 time in total
#93735 - TheRain - Thu Jul 20, 2006 10:47 pm
"What does ATTR2_ALPHA do? "
setting attr2_alpha to 1 makes it so that alpha bits are recognized and transparency is set accordingly.
#93740 - iainprice - Thu Jul 20, 2006 11:01 pm
Actually... I get 32 wide, 8 high correct, then the next row of 8 is from x=128 pixels, y=0. It was just that the area was white on my bmp.
For the 256*256 it gets the first 32*32 sprite using:
32*8 skip skip skip 32*8 skip skip skip
32*8 skip skip skip 32*8 skip skip skip
#93762 - TheRain - Fri Jul 21, 2006 2:08 am
TheRain wrote: |
"What does ATTR2_ALPHA do? "
setting attr2_alpha to 1 makes it so that alpha bits are recognized and transparency is set accordingly. |
Actually, I think this works with the alpha blending modes not the alpha bit... because I tried turning it off and it didn't turn off the recognition of my alpha bits.
#93847 - iainprice - Fri Jul 21, 2006 5:32 pm
I think I'm having problems with:
sprites[e_call_pet_s].oam = &OAMCopySub[e_call_pet_s];
because I was copying 32*32 into 32*32... now I have 256*256 and I need just 32*32 of it.
How do I do that?
#93854 - TheRain - Fri Jul 21, 2006 5:54 pm
iainprice wrote: |
I think I'm having problems with:
sprites[e_call_pet_s].oam = &OAMCopySub[e_call_pet_s];
because I was copying 32*32 into 32*32... now I have 256*256 and I need just 32*32 of it.
How do I do that? |
That is just copying attributes... not pixel data. It looks like your code is initializing each sprite individually anyway, so you may not need to do the OAM copy routine.
But... I think your problem may be in the format of your pixel data. What tool did you use to convert your image?
It looks as though your image is in tile format... try making a regular bitmap format one... even though your sprites are organized into square blocks, it's read into the buffer as one large 256x256 bitmap... not as tiles.
#93880 - iainprice - Fri Jul 21, 2006 7:57 pm
I re-exported the 256*256 as it was tiled, now it is bmp - I use usenti.
I copy the data using:
dmaCopy(spritesBitmap, SPRITE_GFX, 256*256);
I then use the data:
sprites[e_call_pet_s].oam = &OAMCopySub[e_call_pet_s];
sprites[e_call_pet_s].oam->attribute[1] = ATTR1_SIZE_32;
sprites[e_call_pet_s].oam->attribute[2] = ATTR2_ALPHA(1)|e_call_pet_s;
sprites[e_call_pet_s].x = 111<<8;
sprites[e_call_pet_s].y = 98<<8;
sprites[e_call_pet_s].gfxID = 0;
and enable the sprite with:
sprites[i].oam->attribute[0] = ATTR0_BMP | ATTR0_SQUARE;
previously it was not BMP but 256 tiled...
now the sprites are just mashed up... :(
Not having fun any more....
#93906 - TheRain - Fri Jul 21, 2006 10:37 pm
smashed up... as in... maybe your rotational properties are wrong? or smashed up as in data is not formatted correctly...
btw... I did this with a 256 color bitmap last night, exported from usenti as a bitmap in a .c file... so you should be close.
#93991 - iainprice - Sat Jul 22, 2006 10:39 am
You mentioned rotational properties.....
The one difference I have to your code is that you use:
sprites[0].attribute[0] = ATTR0_BMP | ATTR0_ROTSCALE_DOUBLE | 10; //bitmap mode sprite at y=10
and I use:
sprites[0].attribute[0] = ATTR0_BMP | ATTR0_SQAURE;
My code gives mixed up 32*32 sprites, yours gives 64*64 purple boxes......
#94064 - TheRain - Sat Jul 22, 2006 8:28 pm
here's what my properties look like (in C, not C++) for a 256 color sprite.
Code: |
sprites[0].attribute[0] = ATTR0_COLOR_256| 80; // 256 color placed at Y=80
sprites[0].attribute[1] = ATTR1_SIZE_32 | 96; // 32x32 sprite placed at X=96
sprites[0].attribute[2] = ATTR2_ALPHA(1)|0; // choose first sprite location from bitmap.
|
#94075 - iainprice - Sat Jul 22, 2006 9:54 pm
TheRain,
I decided to start from scratch using the bitmap example from ndslib. I was previously using a different sprite structure.
Most of it is working but the sprites displayed are still messed up.
Is there any chance you could send me a text file with all the sprite stuff... definitions, bmp.c file, everything?
Sorry to be such a pain but this is really annoying me now....
Thanks.
#94117 - TheRain - Sun Jul 23, 2006 3:05 am
here is a tile mode 256x256, 256 Color, 32x32 tile size demo I made up just now...
in usenti, to get the tiles to align properly you must set up some special tile properties.
In the GBA export screen, under tile groups check the "cstm" box and enter 16x16 ...
http://www.collinmeyermusic.com/SpritesPrice.zip
in the demo I am providing here, use the A and B buttons to scroll through the horizontal axis... you'll notice once you scroll through to the end of the first horizontal row you will drop down on the y axis some, but not quite large enough to get to the next row... you'll have to play with it a little to figure out what the actual values should be.
good luck!
#94125 - Turambar - Sun Jul 23, 2006 4:19 am
I think you forgot to include guiset1.h.
#94128 - TheRain - Sun Jul 23, 2006 4:54 am
Turambar wrote: |
I think you forgot to include guiset1.h. |
i meant to alter it to not use it... should be good now.
testing it a bit more, I think there's some bugs with this solution too... i haven't found a good solution.
#94156 - iainprice - Sun Jul 23, 2006 1:16 pm
Thank you for all your help.
I have just about got everything sorted now.
I had converted my code to bmp and usenti to bmp.... now I have converted back to tiles AND use 16*16 for the cstm setting.
I still need to sort out different sprites on the main and sub screens but I can sort that.
Thanks again for all your help.....