sprite animation goes wrong!

Post Reply
Tomdev
Posts: 82
Joined: Thu Jan 08, 2009 9:15 pm

sprite animation goes wrong!

Post by Tomdev » Wed Feb 11, 2009 8:48 pm

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;
}

WinterMute
Site Admin
Posts: 2003
Joined: Tue Aug 09, 2005 3:21 am
Location: UK
Contact:

Re: sprite animation goes wrong!

Post by WinterMute » Thu Feb 12, 2009 9:21 am

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?
Help keep devkitPro toolchains free, Donate today

Personal Blog

Tomdev
Posts: 82
Joined: Thu Jan 08, 2009 9:15 pm

Re: sprite animation goes wrong!

Post by Tomdev » Thu Feb 12, 2009 4:11 pm

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?

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

Re: sprite animation goes wrong!

Post by Sylus101 » Thu Feb 12, 2009 10:23 pm

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.
-Sylus "Not Stylus..." McFrederickson

Come visit my web site.

Tomdev
Posts: 82
Joined: Thu Jan 08, 2009 9:15 pm

Re: sprite animation goes wrong!

Post by Tomdev » Fri Feb 13, 2009 7:21 am

a thousand thanks, so stupid

WinterMute
Site Admin
Posts: 2003
Joined: Tue Aug 09, 2005 3:21 am
Location: UK
Contact:

Re: sprite animation goes wrong!

Post by WinterMute » Sun Feb 15, 2009 12:39 pm

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;
Help keep devkitPro toolchains free, Donate today

Personal Blog

Post Reply

Who is online

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