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.

DS development > bitmap sprite and attribute2 index

#139839 - ghuldan - Mon Sep 10, 2007 6:17 pm

Hi everyone,

I tried to display 35 bmp_sprites (32x32) with this code.
Sprites are filled correctly into VRAM :
- from tilenum 0 to 15 for sprite1
- from tilenum 16 to 31 for sprite2 etc etc ...

But i need to put (firstTilenum * 4) on oam attribute2 to make its displayed correctly.
And sprite index Attribute2 can only go from 0 to 1024 : so my 17th sprite overlap on first instead of the 65th

Code:
#include <PA9.h>

#include "gfx/all_gfx.h"
#include "gfx/all_gfx.c"


//Main...
int main(void){

   PA_Init(); //PAlib Init...
   PA_InitVBL(); //VBL Init...
   
   videoSetMode( MODE_0_2D |
                  DISPLAY_BG0_ACTIVE |
                  DISPLAY_SPR_ACTIVE |
                  DISPLAY_SPR_1D |
                  DISPLAY_SPR_1D_BMP |
                  DISPLAY_SPR_1D_SIZE_64
                );
                     
   unsigned short * gfx = (unsigned short*)malloc(sizeof(unsigned short) * 32 * 32);
                     
   int i, k, l, w = 7, h = 5;
   for(l = 0; l < h; l ++)
      for(k = 0; k < w; k ++) {
         PA_obj[0][k + w * l].atr0 = ATTR0_BMP | ATTR0_ROTSCALE | (l * 35 + 5);
         PA_obj[0][k + w * l].atr1 = ATTR1_SIZE_32 | (k * 35 + 5);
         PA_obj[0][k + w * l].atr2 = ATTR2_ALPHA(1) | PA_CreateGfx(0, gfx, OBJ_SIZE_32X32, 2) * 1;
            
         // red 32*32 square for 1d bitmap mode
         for(i = 0; i < 32 * 32; i++)
            gfx[i] = ship_Sprite[i];//RGB15(31 - 3*(k + w * l)/4, 3*(k + w * l)/4, 3*(k + w * l)/4) | (1 << 15);
            
         PA_UpdateGfx(0, PA_GetSpriteGfx(0, k + w * l), (void*)gfx);
      }

                     
   while(1){ // Infinite loop
      PA_WaitForVBL();
   }
   return 0;
}


I tried to change that thing "DISPLAY_SPR_1D_SIZE_64" to anything i could find but it doesnt do anything different.

#139866 - nce - Tue Sep 11, 2007 12:35 am

DISPLAY_SPR_1D_SIZE_64
tells that you will use 64Ko of memory and then map your atrib2 to enter just in this range

now you want to display 35 * 32 * 32 (*2 for the 16bit color) you are using 70Ko just too much

that means that you want to use the 128 Ko
that means
DISPLAY_SPR_1D_SIZE_128

and your atrib2 will be map on 128 Ko
You can try then to use (firstTilenum * 2)


PS: thinking about that normally you should succeed to put your first 32 sprite in the 64Ko memory that's means that normaly you shouldn't overlap at the 17th sprite..... There is probably something wrong in the first place. But I never used PAlib so I don't know what are the paremeters and what it return.
_________________
-jerome-

#139870 - ghuldan - Tue Sep 11, 2007 1:22 am

This is the PAlib initialisation :

Code:
videoSetMode(  MODE_0_2D |
      DISPLAY_SPR_ACTIVE |
      DISPLAY_SPR_1D |   
      DISPLAY_SPR_1D_SIZE_128 |
      DISPLAY_SPR_1D_BMP
                    );
videoSetModeSub(  MODE_0_2D |
      DISPLAY_SPR_ACTIVE |
      DISPLAY_SPR_1D |
      DISPLAY_SPR_1D_SIZE_128 |
      DISPLAY_SPR_1D_BMP
                    );

vramSetMainBanks(VRAM_A_MAIN_SPRITE,VRAM_B_MAIN_BG_0x06000000,VRAM_C_SUB_BG,VRAM_D_SUB_SPRITE);


I already tried with <DISPLAY_SPR_1D_SIZE_128> and <DISPLAY_SPR_1D_SIZE_256> : it does not chnge anything, i have to set attribute2 to x4.

#139880 - nce - Tue Sep 11, 2007 4:51 am

that means that the error si somewhere here I guess:
PA_CreateGfx(0, gfx, OBJ_SIZE_32X32, 2)

I don't know the parameters for that, but I guess that it's not copying the sprite in the correct place on the memory....

Could be something else, but if changing your memory type don't change your id type that means that something is moving the data somewhere to keep the id type constant ( and then left some white space between each sprite in memory )
_________________
-jerome-

#139900 - ghuldan - Tue Sep 11, 2007 11:14 am

here is the VRAM viewer of desmume :
[img=http://img374.imageshack.us/img374/9809/tileviewerdj2.th.png]

here is the sprites displayed, with PA_CreateGFX returned values :
[img=http://img205.imageshack.us/img205/5370/desmumeoo2.th.png]

here is the sprites displayed, with index X4 in OAMindex :
[img=http://img205.imageshack.us/img205/9671/desmumex4vm5.th.png]

#139957 - nce - Wed Sep 12, 2007 1:11 am

Ok I'm completly out of idea on this one ....

I can tell you what I do myself and you can check if something come to your mind.

I'm working only with 256colors sprite never tried 16bit, but I guess there is no difference here ( except you have to multiply by 2 your size )

so I'm taking a bank for the sprite ( my case bank D for subsprite 128Ko and bank E for main sprite 64Ko )

take the subsprite case :
1st sprite will be written at (bankD + 0) and attribute2 will receive 0
2nd sprite will be written at (bankD + (32*32)) and attribute 2 will receive (32*32 / 128) = 8 ( the 128 comes from the DISPLAY_SPR_1D_SIZE_128 )

the main screen I do the same except I divide by 64 of course....

The last guess I can do is this ATTR0_ROTSCALE doesn't double the size to do the rotation ? ( probably not, if my memory is good it exist also a ATT0_ROTSCALE_DOUBLE_SIZE or something like that )
_________________
-jerome-

#139997 - ghuldan - Wed Sep 12, 2007 2:10 pm

ATTR0_ROTSCALE does not double the size, ATT0_ROTSCALE_DOUBLE_SIZE does. But theorically it does not affect size of VRAM that is used.

However i removed ATTR0_ROTSCALE from initialization of my sprites ... and obtained some ugly results : the sprite seems to be displayed in 2d mode .....
[img=http://img255.imageshack.us/img255/4662/desmumewithoutrotox6.th.png]

This one is with the X4 on attr2 index
[img=http://img341.imageshack.us/img341/9135/desmumewithoutrotx4ly4.th.png]

Really weird, i tried too to display a real sprite instead of the red square, the thing that appears where the red square was is the whole new sprite, not a part of it.
[img=http://img259.imageshack.us/img259/3851/desmumewithoutrot2bl7.th.png]


Since DISPLAY_SPR_1D is the setting for indexed sprite mode
I think DISPLAY_SPR_1D_SIZE_128 is too, it would explain why it does not affect 16bits sprites.
Plus in libnds/../video.h i saw DISPLAY_SPR_1D_BMP_SIZE_128 and DISPLAY_SPR_1D_BMP_SIZE_256, and i saw a changement on 16bits sprites.


Here is my vramSetMainBanks setting
Code:
vramSetMainBanks(   VRAM_A_MAIN_SPRITE,        //A and B maped consecutivly as sprite memory
                        VRAM_B_MAIN_SPRITE,        //this gives us 256KB which is the max
                        VRAM_C_MAIN_BG_0x06000000, //map C to background memory
                        VRAM_D_LCD                 //not using D
                        );


could you tell me how must set the videoMode and how large are VRAM_A and VRAM_B ? Apparently there is 256kb for the sum ...

Ghuldan ... really most