Page 1 of 1

sprite animation goes wrong!

Posted: Wed Feb 11, 2009 8:48 pm
by Tomdev
hello everyone

yeah i know i post a lot, but i can't get this work. i'm now threee days stuck and it isn't going right. the problem: every time my sprite animation has to restart i get garbage on the screen

my code:

Code: Select all

#include <nds.h>
#include "test.h"
#include "sprite.h"
s32 teller; //  a counter
u16* gfx2;
u8*  frame_gfx;
int frame;

void animateMan()
{
frame = (teller / 8);
u8* offset = frame_gfx + frame * 512;
dmaCopy(offset, gfx2, 512);
X_SetSprite(1, 1, 1, 1, 1);
}

void initMan()
{
gfx2 = oamAllocateGfx(&oamMain, SpriteSize_32x32, SpriteColorFormat_16Color);
frame_gfx = (u8*)testTiles;

}
         
int main(int argc, char **argv){

   videoSetMode(MODE_0_2D);
   vramSetBankA(VRAM_A_MAIN_SPRITE);
   oamInit(&oamMain, SpriteMapping_1D_32, false);
   X_LoadpalSprite(testPal, testPalLen, 1, 16, 1); // load the pallette
   initMan();
   
   while(1) {
   
 // counter one up
if(teller==80){ teller = 0; animateMan(); }
if(teller!=80){ teller++; animateMan(); oamUpdate(&oamMain);}

X_VBL(); // instead of swi_waitvbl
   }

   return 0;
}

Re: sprite animation goes wrong!

Posted: Thu Feb 12, 2009 9:21 am
by WinterMute
Show the code for your X_VBL function too.

Something more like this should work a little better. Waiting for VBL before you update sprite VRAM will ensure that you're not changing it during draw time which may cause on screen artifacts.

Code: Select all


// counter one up

teller++;
if (teller==80) teller = 0;

swiWaitForVBlank();

animateMan();
oamUpdate(&oamMain);

That looks like you should have 7 animation frames, is that the case?

Re: sprite animation goes wrong!

Posted: Thu Feb 12, 2009 4:11 pm
by Tomdev
X_Vbl is nothing special:

Code: Select all

void X_VBL(void){
   touchRead(&touch);
   swiWaitForVBlank();
}
and i have 8 frames so i should have if(teller == 90)?

edit:

your way doesn't work for me, does someone have an example for this?

Re: sprite animation goes wrong!

Posted: Thu Feb 12, 2009 10:23 pm
by Sylus101
The bottom line is that if you're getting garbage where your sprite was after a certain frame point, whatever code updates the graphics is pointing into a memory location where you don't have any graphics loaded or you've gone beyond your array and are picking up crap out of main memory.

I'd change frame = (teller / 8); to frame = (teller >> 3); just for a minor speed increase as division isn't handled well by the DS.

If you have 8 frames in your graphic, this code triggers 10 times and that would be why you're getting garbage. Change the 80 to 64 because when it reaches 64 is when you want to go back to frame 0.

Re: sprite animation goes wrong!

Posted: Fri Feb 13, 2009 7:21 am
by Tomdev
a thousand thanks, so stupid

Re: sprite animation goes wrong!

Posted: Sun Feb 15, 2009 12:39 pm
by WinterMute
Sylus101 wrote: I'd change frame = (teller / 8); to frame = (teller >> 3); just for a minor speed increase as division isn't handled well by the DS.
Actually the compiler is more than clever enough to replace divisions and multiplications by powers of two with the equivalent shifts. It's definitely worth knowing the equivalent shifts but sometimes it makes for more readable code if you leave the original divisions & let the compiler optimise.
If you have 8 frames in your graphic, this code triggers 10 times and that would be why you're getting garbage. Change the 80 to 64 because when it reaches 64 is when you want to go back to frame 0.
Oops, I'm not sure how I missed that at all :p

This does bring up a situation where the compiler won't be as clever though. For this case you can get rid of the comparison and use a binary AND.

Code: Select all

teller = ( teller + 1 ) & 63;