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 > sprite animation speed

#44014 - chrissieboy - Sun May 29, 2005 11:34 am

Hi im busy with a platform game. I got my sprite animated now, but the problem is it goes toooo fast! Anyone knows something like a timer or somthing to put in ? because my animation is 6 frames and i think it shows 60 frames in a second.

This is the code, anyone know a solution??? HELP

Code:

//////////////////////////////////////////////////////////////////////

#include <NDS/NDS.h>
#include <NDS/ARM9/rand.h>

#include "spr1pal.h"
//#include "ballpalette2.h"
#include "spr1img.h"
#include "spr2img.h"
#include "spr3img.h"
#include "spr4img.h"
#include "spr5img.h"
#include "spr6img.h"

//////////////////////////////////////////////////////////////////////
#define NUM_SPRITES 128   

sSpriteEntry OAMCopySub[128];

//////////////////////////////////////////////////////////////////////

//simple sprite struct
typedef struct
{
   int x,y;   //location
   int dx, dy;   //speed
   sSpriteEntry* oam;   
   //int gfxID; //graphics lovation
   u16 curFrame;   //Animation frame
}Sprite;

///////////////////////////////////////////////////////////////////////

void MoveSprite(Sprite* sp)
{
   int x = sp->x >> 8;
   int y = sp->y >> 8;

   sp->oam->attribute[1] &= 0xFE00;
   sp->oam->attribute[1] |= (x & 0x01FF);
 
   sp->oam->attribute[0] &= 0xFF00;
   sp->oam->attribute[0] |= (y & 0x00FF);

}
///////////////////////////////////////////////////////////////////////
void initOAM(void)
{
   int i;

   for(i = 0; i < 128; i++)
   {
      OAMCopySub[i].attribute[0] = ATTR0_DISABLED;
   }   
}

//////////////////////////////////////////////////////////////////////
void updateOAM(void)
{
   int i;
   
   for(i = 0; i < 128 * sizeof(sSpriteEntry) / 4 ; i++)
   {
      ((uint32*)OAM_SUB)[i] = ((uint32*)OAMCopySub)[i];
   }
}

/////////////////////////////////////////////////////////////

void irqVBlank(void)
{   
    IF = IF;
}

///////////////// C code entry (main())/////////////////////
int main(void)
{
   
   /////////variables
   uint16* back = VRAM_A;
   uint16* front = VRAM_B;

   Sprite sprites[NUM_SPRITES];

   int i;
   int a;
   int screen = 1;

   
   
   ///////////////set up/////////////
   //enable the cache
//   CP15_ITCMEnableDefault();

   //turn on the power to the system
   powerON(POWER_ALL);

   //set main display to render directly from the frame buffer
   videoSetMode(MODE_FB1);
   
   //set up the sub display
   videoSetModeSub(MODE_0_2D |
               DISPLAY_SPR_1D_LAYOUT |
               DISPLAY_SPR_ACTIVE |
               DISPLAY_BG0_ACTIVE |
               DISPLAY_BG1_ACTIVE );
   
   //vram banks are somewhat complex
   vramSetMainBanks(VRAM_A_LCD, VRAM_B_LCD, VRAM_C_SUB_BG, VRAM_D_SUB_SPRITE);
   
   //irqs are nice..ndslib comes with a very unoptomized default handler
   irqInitHandler(irqDefaultHandler);
   irqSet(IRQ_VBLANK, irqVBlank);
   
   /////////////Init the sprites ///////////
   for(i = 0; i < 256; i++)
      SPRITE_PALETTE_SUB[i] = ((u16*)spr1pal)[i];
   //for(i = 512; i < 1024; i++)
      //SPRITE_PALETTE_SUB[i] = ((u16*)ballpalette2)[i];

// sprite animation

   for(i=0*512; i<1*512; i++) { SPRITE_GFX_SUB[i] = ((u16*)spr1img)[i-(0*512)]; }
   for(i=1*512; i<2*512; i++) { SPRITE_GFX_SUB[i] = ((u16*)spr2img)[i-(1*512)]; }
   for(i=2*512; i<3*512; i++) { SPRITE_GFX_SUB[i] = ((u16*)spr3img)[i-(2*512)]; }
   for(i=3*512; i<4*512; i++) { SPRITE_GFX_SUB[i] = ((u16*)spr4img)[i-(3*512)]; }
   for(i=4*512; i<5*512; i++) { SPRITE_GFX_SUB[i] = ((u16*)spr5img)[i-(4*512)]; }
   for(i=5*512; i<6*512; i++) { SPRITE_GFX_SUB[i] = ((u16*)spr6img)[i-(5*512)]; }

   
   
   
   //turn of sprites
   initOAM();


      //spriteplace and speed
      sprites[0].x = 100<<8;
      sprites[0].y = 150<<8;
      sprites[0].dx = 0;
      sprites[0].dy = 0;
   sprites[0].curFrame = 0;
      sprites[0].oam = &OAMCopySub[0];
      
   
      //set up our sprite OAM entry attributes
      sprites[0].oam->attribute[0] = ATTR0_COLOR_256 | ATTR0_SQUARE; 
      sprites[0].oam->attribute[1] = ATTR1_SIZE_32;
      sprites[0].oam->attribute[2] = 0;





   while (1)
   {

      
      //move the sprites
      uint16 keysPressed = READ_KEYS;
            if(keysPressed & KEY_LEFT) { sprites[0].x = sprites[0].x-1; }
            if(keysPressed & KEY_RIGHT) { sprites[0].x = sprites[0].x+1; }
           
                                               
                           

                           
                           
           
           
           
           
           
           
         sprites[0].x += sprites[0].dx;
         //sprites[i].y += sprites[i].dy;
         
         
         //Animate sprite
         if (sprites[0].curFrame<6) { sprites[0].curFrame++;  }
         else { sprites[0].curFrame = 0; }
         
         
         
/*         //check for collision with the screen boundries
         if(sprites[0].x < (1<<8) || sprites[0].x > (231 << 8))
            sprites[0].dx = -sprites[0].dx;
         if(sprites[0].y < (1<<8) || sprites[0].y > (164 << 8))
            sprites[0].dy = -sprites[0].dy;
   */      
         //reposition the sprites
         sprites[0].oam->attribute[2] = int((sprites[0].curFrame/3))*32;
         MoveSprite(&sprites[0]);

      

//      swiWaitForVBlank();
      
      updateOAM();

      //flip screens
      if(screen)
      {
         videoSetMode(MODE_FB1);
         front = VRAM_B;
         back = VRAM_A;
         screen = 0;
      }
      else
      {
         videoSetMode(MODE_FB0);   
         front = VRAM_A;
         back = VRAM_B;
         screen = 1;
      }
   }   
   return 0;
}

//////////////////////////////////////////////////////////////////////

#44017 - abigsmurf - Sun May 29, 2005 12:42 pm

you could just make the animation 60fps and fill in the gaps with pointers (ie have 10 identical frames in a row) . Not sure if that would fill up memory though...

#44034 - dagamer34 - Sun May 29, 2005 6:40 pm

The easy and cheap way to do it is to make a counter that counts to 10, and when it reaches 10, it THEN changes the frame. Easy and cheap, but not very efficient when it comes to multiple animations running at the same time(not only that, your code gets really cluttered)

Make a class (or at least a struct) and set up functions that do the work for you. Don't reinvent the wheel every time you have to use it.
_________________
Little kids and Playstation 2's don't mix. :(