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.

Patater's Introduction to Nintendo DS Programming > Sprites problem...

#170376 - Nanashi - Sun Sep 20, 2009 7:45 am

Code:

#include <nds.h>

#include "starField.h"
#include "splash.h"
#include "man.h"
#include "woman.h"

#define FRAMES_PER_ANIMATION 3

/* Select a low priority DMA channel to perform our background copying. */
static const int DMA_CHANNEL = 3;

void initVideo() {
    /*
     *  Map VRAM to display a background on the main and sub screens.
     *
     *  The vramSetMainBanks function takes four arguments, one for each of the
     *  major VRAM banks. We can use it as shorthand for assigning values to
     *  each of the VRAM bank's control registers.
     *
     *  We map banks A and B to main screen  background memory. This gives us
     *  256KB, which is a healthy amount for 16-bit graphics.
     *
     *  We map bank C to sub screen background memory.
     *
     *  We map bank D to LCD. This setting is generally used for when we aren't
     *  using a particular bank.
     */
    vramSetMainBanks(VRAM_A_MAIN_BG_0x06000000,
                     VRAM_B_MAIN_BG_0x06020000,
                     VRAM_C_SUB_BG_0x06200000,
                     VRAM_D_LCD);
   vramSetBankE(VRAM_E_MAIN_SPRITE);
   vramSetBankF(VRAM_F_MAIN_SPRITE);
   

    /*  Set the video mode on the main screen. */
    videoSetMode(MODE_5_2D | // Set the graphics mode to Mode 5
                 DISPLAY_BG2_ACTIVE | // Enable BG2 for display
                 DISPLAY_BG3_ACTIVE); //Enable BG3 for display

    /*  Set the video mode on the sub screen. */
    videoSetModeSub(MODE_5_2D | // Set the graphics mode to Mode 5
                    DISPLAY_BG3_ACTIVE); // Enable BG3 for display
}

void initBackgrounds() {
    /*  Set up affine background 3 on main as a 16-bit color background. */
    REG_BG3CNT = BG_BMP16_256x256 |
                 BG_BMP_BASE(0) | // The starting place in memory
                 BG_PRIORITY(3); // A low priority

    /*  Set the affine transformation matrix for the main screen background 3
     *  to be the identity matrix.
     */
    REG_BG3PA = 1 << 8;
    REG_BG3PB = 0;
    REG_BG3PC = 0;
    REG_BG3PD = 1 << 8;

    /*  Place main screen background 3 at the origin (upper left of the
     *  screen).
     */
    REG_BG3X = 0;
    REG_BG3Y = 0;

    /*  Set up affine background 2 on main as a 16-bit color background. */
    REG_BG2CNT = BG_BMP16_128x128 |
                 BG_BMP_BASE(8) | // The starting place in memory
                 BG_PRIORITY(2);  // A higher priority

    /*  Set the affine transformation matrix for the main screen background 3
     *  to be the identity matrix.
     */
    REG_BG2PA = 1 << 8;
    REG_BG2PB = 0;
    REG_BG2PC = 0;
    REG_BG2PD = 1 << 8;

    /*  Place main screen background 2 in an interesting place. */
    REG_BG2X = -(SCREEN_WIDTH / 2 - 32) << 8;
    REG_BG2Y = -32 << 8;

    /*  Set up affine background 3 on the sub screen as a 16-bit color
     *  background.
     */
    REG_BG3CNT_SUB = BG_BMP16_256x256 |
                     BG_BMP_BASE(0) | // The starting place in memory
                     BG_PRIORITY(3); // A low priority

    /*  Set the affine transformation matrix for the sub screen background 3
     *  to be the identity matrix.
     */
    REG_BG3PA_SUB = 1 << 8;
    REG_BG3PB_SUB = 0;
    REG_BG3PC_SUB = 0;
    REG_BG3PD_SUB = 1 << 8;

    /*
     *  Place main screen background 3 at the origin (upper left of the screen)
     */
    REG_BG3X_SUB = 0;
    REG_BG3Y_SUB = 0;
}

void displayStarField() {
    dmaCopyHalfWords(DMA_CHANNEL,
                     starFieldBitmap, /* This variable is generated for us by
                                       * grit. */
                     (uint16 *)BG_BMP_RAM(0), /* Our address for main
                                               * background 3 */
                     starFieldBitmapLen); /* This length (in bytes) is generated
                                           * from grit. */
}



void displaySplash() {
    dmaCopyHalfWords(DMA_CHANNEL,
                     splashBitmap, /* This variable is generated for us by
                                    * grit. */
                     (uint16 *)BG_BMP_RAM_SUB(0), /* Our address for sub
                                                   * background 3 */
                     splashBitmapLen); /* This length (in bytes) is generated
                                        * from grit. */
}


//---------------------------------------------------------------------
// The man sprite
// he needs a single pointer to sprite memory
// and a reference to his frame graphics so they
// can be loaded as needed
//---------------------------------------------------------------------
typedef struct
{
   int x;
   int y;

   u16* sprite_gfx_mem;
   u8*  frame_gfx;

   int state;
   int anim_frame;
}Man;

enum SpriteState {W_UP = 0, W_RIGHT = 1, W_DOWN = 2, W_LEFT = 3};

//---------------------------------------------------------------------
// Screen dimentions
//---------------------------------------------------------------------
enum {SCREEN_TOP = 0, SCREEN_BOTTOM = 192, SCREEN_LEFT = 0, SCREEN_RIGHT = 256};

void animateMan(Man *sprite)
{
   int frame = sprite->anim_frame + sprite->state * FRAMES_PER_ANIMATION;

   u8* offset = sprite->frame_gfx + frame * 32*32;

   dmaCopy(offset, sprite->sprite_gfx_mem, 32*32);
}

//---------------------------------------------------------------------
// Initializing a man requires little work, allocate room for one frame
// and set the frame gfx pointer
//---------------------------------------------------------------------
void initMan(Man *sprite, u8* gfx)
{
   sprite->sprite_gfx_mem = oamAllocateGfx(&oamMain, SpriteSize_32x32, SpriteColorFormat_256Color);
   
   sprite->frame_gfx = (u8*)gfx;
}
void displayHero()
{
dmaCopy(manPal, SPRITE_PALETTE, 512);
dmaCopy(womanPal, SPRITE_PALETTE, 512);

}
typedef struct
{
   int x;
   int y;

   u16* sprite_gfx_mem[12];
   int gfx_frame;

   int state;
   int anim_frame;


}Woman;

void animateWoman(Woman *sprite)
{
   sprite->gfx_frame = sprite->anim_frame + sprite->state * FRAMES_PER_ANIMATION;
}

//---------------------------------------------------------------------
// Initializing a woman requires us to load all of her graphics frames
// into memory
//---------------------------------------------------------------------
void initWoman(Woman *sprite, u8* gfx)
{
   int i;

   for(i = 0; i < 12; i++)
   {
      sprite->sprite_gfx_mem[i] = oamAllocateGfx(&oamSub, SpriteSize_32x32, SpriteColorFormat_256Color);
      dmaCopy(gfx, sprite->sprite_gfx_mem[i], 32*32);
      gfx += 32*32;
   }
}




int main()
{
   Man man = {0,0};
   Woman woman = {20,20};
   
    /*  Turn on the 2D graphics core. */
    powerOn(POWER_ALL_2D);

    /*  Configure the VRAM and background control registers. */
    lcdMainOnBottom(); // Place the main screen on the bottom physical screen
    initVideo();
    initBackgrounds();
   displayStarField();
    displaySplash();

   oamInit(&oamMain, SpriteMapping_1D_128, false);
   
   initWoman(&woman, (u8*)womanTiles);
   
   initMan(&man, (u8*)manTiles);
   displayHero();
   man.state = W_DOWN;
   woman.state = W_DOWN;
   while(1)
   {
      scanKeys();

      int keys = keysHeld();

      if(keys)
      {
         if(keys & KEY_UP)
         {
            if(man.y >= SCREEN_TOP) man.y--;
            

            man.state =  W_UP;
         }
         if(keys & KEY_LEFT)
         {
            if(man.x >= SCREEN_LEFT) man.x--;
            

            man.state =  W_LEFT;
         }
         if(keys & KEY_RIGHT)
         {
            if(man.x <= SCREEN_RIGHT -32) man.x++;
            

            man.state = W_RIGHT;
         }
         if(keys & KEY_DOWN)
         {
            if(man.y <= SCREEN_BOTTOM -32) man.y++;
         

            man.state =  W_DOWN;
         }
      
         man.anim_frame++;
         woman.anim_frame++;
         if(man.anim_frame >= FRAMES_PER_ANIMATION) man.anim_frame = 0;
         if(woman.anim_frame >= FRAMES_PER_ANIMATION) woman.anim_frame = 0;
         

      }

      animateMan(&man);
      animateWoman(&woman);

      





      //-----------------------------------------------------------------
      // Set oam attributes, notice the only difference is in the sprite
      // graphics memory pointer argument.  The man only has one pointer
      // while the women has an array of pointers
      //-----------------------------------------------------------------
      oamSet(&oamMain, 0, man.x, man.y, 0, 0, SpriteSize_32x32, SpriteColorFormat_256Color,
         man.sprite_gfx_mem, -1, false, false, false, false, false);
      oamSet(&oamMain, 1, woman.x, woman.y, 0, 0, SpriteSize_32x32, SpriteColorFormat_256Color,
         woman.sprite_gfx_mem[woman.gfx_frame], -1, false, false, false, false, false);

      
      swiWaitForVBlank();

      oamUpdate(&oamMain);
      
   }


 
   

    return 0;
}


Ok here is the problem i have a function to display my two heroes
called displayHero but when i load my heroes in the same screen they becoming like the first hero and they loose the colors anyone can help or tell me whats the problem??:S:SS:SS

[/code]