#40595 - wally - Wed Apr 20, 2005 7:40 pm
I was trying to use the smantouch program to learn how to program for the DS. So the first thing I tried was to change the pictures. So I tried to change the pacman from a 8x8 to a 64x64. However the graphics come up corrupted. When changing the sprite size what would I have to change in the main program? I don't understand the OAM changes.
#41247 - wally - Tue Apr 26, 2005 11:13 pm
OK I got the code to give me 5 sprites, however all five have the same image. What am I doing wrong? The code is below.
Thanks for all your help.
//Custom defines
#define REG_VCOUNT *(vu16*)0x4000006 //Our good old vblank counter
//System includes
#include <NDS/NDS.h>
#include <NDS/ARM9/rand.h>
//Artwork includes
#include "resources/pal.h"
#include "resources/pac0.h"
#include "resources/gh0.h"
#include "resources/bg.h"
//-------------------------------------------------------------------
//OAM globals
sSpriteEntry OAMCopy[128];
sSpriteEntry OAMCopySub[128];
//Sprite structure
typedef struct
{
int x,y; //location
int xSpeed, ySpeed; //speed
sSpriteEntry* oam;
}Sprite;
//-------------------------------------------------------------------
//Moves a sprite in OAM memory
void MoveSprite(Sprite* sp)
{
int x = sp->x >> 8;
int y = sp->y >> 8;
sp->oam->attribute[1] &= 0xFE00;
sp->oam->attribute[1] |= x;
sp->oam->attribute[0] &= 0xFF00;
sp->oam->attribute[0] |= y;
}
//-------------------------------------------------------------------
//Initializes the sprites
void NextSprite(Sprite* sp, int number)
{
sp->x += sp->xSpeed;
sp->y += sp->ySpeed;
if(sp->x < 256 || sp->x > 61440) { sp->xSpeed=-sp->xSpeed; }
if(sp->y < 256 || sp->y > 45056) { sp->ySpeed=-sp->ySpeed; }
}
//-------------------------------------------------------------------
//Initializes the sprites
void CreateSprite(Sprite* sp, int number)
{
sp->x = (rand() & (100<<8))+((number+number)<<8);
sp->y = (rand() & (100<<8))+((number+number)<<8);
sp->xSpeed = (rand() & (3<<6))+(1<<6);
sp->ySpeed = (rand() & (3<<6))+(1<<6);
sp->oam = &OAMCopy[number];
sp->oam->attribute[0] = ATTR0_COLOR_256 | ATTR0_SQUARE;
sp->oam->attribute[1] = ATTR1_SIZE_64;
sp->oam->attribute[2] = 0;
}
//-------------------------------------------------------------------
//Initialises OAM, moving all sprites offscreen
void initOAM(void)
{
int i;
for(i = 0; i < 128; i++)
{
OAMCopy[i].attribute[0] = ATTR0_DISABLED;
OAMCopySub[i].attribute[0] = ATTR0_DISABLED;
}
}
//-------------------------------------------------------------------
//Copies OAM buffer to actual OAM memory space
void updateOAM(void)
{
int i;
for(i = 0; i < 128 * sizeof(sSpriteEntry) / 4 ; i++)
{
((uint32*)OAM)[i] = ((uint32*)OAMCopy)[i];
((uint32*)OAM_SUB)[i] = ((uint32*)OAMCopySub)[i];
}
}
//-------------------------------------------------------------------
//Entry point- this is where we start!
int main(int argc, char ** argv) {
int i=0, colourComponent=0;
//turn on the power to the system
powerON(POWER_ALL);
videoSetMode( MODE_0_2D | DISPLAY_SPR_1D_LAYOUT | DISPLAY_SPR_ACTIVE | DISPLAY_BG0_ACTIVE );
videoSetModeSub( MODE_0_2D | DISPLAY_SPR_1D_LAYOUT | DISPLAY_SPR_ACTIVE | DISPLAY_BG0_ACTIVE );
/*
VRAM_A_CR = VRAM_ENABLE | VRAM_ARM9 | VRAM_CORE_A;
VRAM_B_CR = VRAM_ENABLE | VRAM_ARM9 | VRAM_CORE_A;
VRAM_C_CR = VRAM_ENABLE | VRAM_ARM9 | VRAM_CORE_B;
VRAM_D_CR = VRAM_ENABLE | VRAM_ARM9 | VRAM_CORE_B;
vramSetMainBanks(VRAM_A_MAIN_BG,VRAM_B_MAIN_SPRITE,VRAM_C_SUB_BG,VRAM_D_SUB_SPRITE);
*/
//Set screens to black initially
BG_PALETTE[0] = RGB15(0, 0, 0); //Main screen
BG_PALETTE[512] = RGB15(0, 0, 0); //Sub screen
Sprite sprites[128];
Sprite sprites_sub[128];
initOAM();
//Setup heads
CreateSprite(&sprites[0],0);
CreateSprite(&sprites[1],1);
CreateSprite(&sprites[2],2);
CreateSprite(&sprites[3],3);
CreateSprite(&sprites[4],4);
//Load palette and sprite data (main screen)
for(i=0; i<512; i++) { SPRITE_PALETTE[i] = palPalette[i]; }
for(i=0; i<8192; i++) { SPRITE_GFX[i] = pac0Data[i]; }
for(i=8193; i<16384; i++) { SPRITE_GFX[i] = pac1Data[i-8193]; }
for(i=16385; i<24576; i++) { SPRITE_GFX[i] = pac2Data[i-16385]; }
for(i=24577; i<32768; i++) { SPRITE_GFX[i] = pac3Data[i-24577]; }
for(i=32769; i<40960; i++) { SPRITE_GFX[i] = pac4Data[i-32769]; }
//Setup top screen
sprites_sub[0].x = 8;
sprites_sub[0].y = 8;
sprites_sub[0].xSpeed = (8<<8);
sprites_sub[0].ySpeed = (1<<8);
sprites_sub[0].oam = &OAMCopySub[0];
sprites_sub[0].oam->attribute[0] = ATTR0_COLOR_256 | ATTR0_SQUARE;
sprites_sub[0].oam->attribute[1] = ATTR1_SIZE_64;
sprites_sub[0].oam->attribute[2] = 0;
//Load palette and sprite data (sub screen)
for(i=0; i<512; i++) { SPRITE_PALETTE_SUB[i] = palPalette[i]; }
for(i=0; i<8192; i++) { SPRITE_GFX_SUB[i] = gh0Data[i]; }
//-------------------------------------------------------------------
//Main game loop
bool exitFlag = false;
while (!exitFlag)
{
//Pulse screen colours (disco time!)
if (colourComponent < 31) { colourComponent++; }
else { colourComponent = 0; }
PALETTE[0] = RGB15(colourComponent, 0, 0);
PALETTE[512] = RGB15(0, 0, 31-colourComponent);
//Move heads
NextSprite(&sprites[0],0);
NextSprite(&sprites[1],1);
NextSprite(&sprites[2],2);
NextSprite(&sprites[3],3);
NextSprite(&sprites[4],4);
MoveSprite(&sprites[0]);
MoveSprite(&sprites[1]);
MoveSprite(&sprites[2]);
MoveSprite(&sprites[3]);
MoveSprite(&sprites[4]);
//swiWaitForVBlank();
while(REG_VCOUNT != 190) {;}
updateOAM();
}
return 0;
}
#41249 - Ethos - Tue Apr 26, 2005 11:19 pm
attribute[2] = 0;
That is why
#41251 - wally - Tue Apr 26, 2005 11:22 pm
what exactly is attribute 2? I thought it was the order the images were placed.
#41253 - Ethos - Tue Apr 26, 2005 11:28 pm
I don't know DS 2D (no time, its all about the 3D).
But in GBA attribute 2 (bits 0-9) are the tile in memory you are trying to reference
#41550 - Pacifist - Fri Apr 29, 2005 4:25 pm
It's the memory offset between where Sprite memory starts and where the sprite you want to draw is.
0 is the first sprite. If your drawing 8x8 sprites then the second on is at 2x1 and the third is at 2x2. 2 is the number of bytes the sprite takes up (right?). An 8x8 sprites has 8*8 pixels = 64 bits / 32 bits per byte = 2 bytes.
16x16 sprites take up 8 bytes and your 64x64 sprites take up a whopping 128.
Therefore your sprites should be at
0*128, 1*128, 2*128 etc...
however it looks like you've loaded them into specific chunks of sprite memory instead of loading them sequentially. In this case the offset will be where you loaded them.
for(i=0; i<8192; i++) { SPRITE_GFX[i] = pac0Data[i]; }
for(i=8193; i<16384; i++) { SPRITE_GFX[i] = pac1Data[i-8193]; }
for(i=16385; i<24576; i++) { SPRITE_GFX[i] = pac2Data[i-16385]; }
for(i=24577; i<32768; i++) { SPRITE_GFX[i] = pac3Data[i-24577]; }
for(i=32769; i<40960; i++) { SPRITE_GFX[i] = pac4Data[i-32769]; }
so sprite one is at
sprites_sub[0].oam->attribute[2] = 0;
two is at
sprites_sub[1].oam->attribute[2] = 8193;
three is at
sprites_sub[2].oam->attribute[2] = 16385;
etc...
at least thats what *I* think is going on but I'm still pretty new to all this.
[/quote]
#41552 - wally - Fri Apr 29, 2005 4:43 pm
how would you load them sequentially?