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.

Beginners > Priorities using 4 bgs & Sprites in Mode 0

#34586 - arock99 - Sat Jan 22, 2005 12:03 am

Hi,
First of all thanks for the help i had displaying custom bgs...
I have another issue and this time around i did more looking around but either i didnt understand what i read (most likely) or i just didnt find exactly what i was looking for. I want to display things in the following order:
bg0
bg1 over bg0
bg2 over bg1
sprites over bg2
bg3 over sprites

everything works fine except my sprite is showing up over all my backgrounds...
here is the source code...keep in mind im not using anything exciting graphic-wise...i figured i'd want to learn the basics before worrying about artsy stuff :) Thanks in advance!

u8 i, x, y;
u8 Bg0ScreenBlock = 19, Bg1ScreenBlock = 20, Bg2ScreenBlock = 24, Bg3ScreenBlock = 28;
u16* Bg0Screen = (u16*)ScreenBaseBlock(Bg0ScreenBlock);
u16* Bg1Screen = (u16*)ScreenBaseBlock(Bg1ScreenBlock);
u16* Bg2Screen = (u16*)ScreenBaseBlock(Bg2ScreenBlock);
u16* Bg3Screen = (u16*)ScreenBaseBlock(Bg3ScreenBlock);
u8* CharBB = (u8*) CharBaseBlock(0);
//Priority 0 = Displays on top of all Backgrounds
//Priority 3 = Displays under all Backgrounds
REG_BG0CNT = BG_COLOR256 | TEXTBG_SIZE_256x256 | (Bg0ScreenBlock << SCREEN_SHIFT) | (0 << CHAR_SHIFT) | 3;
REG_BG1CNT = BG_COLOR256 | TEXTBG_SIZE_512x512 | (Bg1ScreenBlock << SCREEN_SHIFT) | (0 << CHAR_SHIFT) | 2;
REG_BG2CNT = BG_COLOR256 | TEXTBG_SIZE_512x512 | (Bg2ScreenBlock << SCREEN_SHIFT) | (0 << CHAR_SHIFT) | 1;
REG_BG3CNT = BG_COLOR256 | TEXTBG_SIZE_512x512 | (Bg3ScreenBlock << SCREEN_SHIFT) | (0 << CHAR_SHIFT) | 0;
REG_BLDMOD = BIT1 | BIT6 | BIT0 | BIT12;
SetMode(MODE_0 | BG0_ENABLE | BG1_ENABLE | BG2_ENABLE | BG3_ENABLE | OBJ_ENABLE | OBJ_MAP_1D);

//create an array of 128 sprites equal to OAM
Sprite sprites[128];

//move all sprites offscreen to hide them
for(i = 0; i < 128; i++) {
sprites[i].attribute0 = 160;
sprites[i].attribute1 = 240;
sprites[i].attribute2 = PRIORITY(1);//Goes in front of backgrounds 0,1, and 2 but behind background 3
}
u8 curr;
u8 sky[2048];//32 8x8 tiles
u8 currTileData;
u8 currTile;

//Blue Shade
BGPaletteMem[0] = RGB16(0, 0, 0);
for (curr=1; curr<33; curr++) {
BGPaletteMem[curr] = RGB16(curr, curr, 31);
}
BGPaletteMem[0x33] = RGB16(31, 0, 0);//red
BGPaletteMem[0x34] = RGB16(31, 31, 0);//Yellow

//Green Shade
OBJPaletteMem[0] = RGB16(0, 0, 0);
for (curr=1; curr<33; curr++) {
OBJPaletteMem[curr] = RGB16(curr, 31, curr);
}

//Create Pac-Man
u8 pacMan[] = {
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00
};
//OAMMem
DMAFastCopy((void*)pacMan, (void *)OAMData, 64, DMA_16NOW);

u8 transparentBlock[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
DMAFastCopy((void*)transparentBlock, (void *)CharBB, 64, DMA_16NOW);

for (currTile = 0; currTile<32; currTile++) {
for (currTileData = 0; currTileData<64; currTileData++) {
sky[(currTile*64)+currTileData] = currTile+1;
}
}
DMAFastCopy((void*)sky, (void *)CharBB+64, 2048, DMA_16NOW);

u8 triangle[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x31,
0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x31, 0x31,
0x00, 0x00, 0x00, 0x00, 0x31, 0x31, 0x31, 0x31,
0x00, 0x00, 0x00, 0x31, 0x31, 0x31, 0x31, 0x31,
0x00, 0x00, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
0x00, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
};
DMAFastCopy((void*)triangle, (void *)CharBB+2112, 64, DMA_16NOW);
u8 square[] = {
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,
0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,
0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,
0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,
0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,
0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33
};
DMAFastCopy((void*)square, (void *)CharBB+2176, 64, DMA_16NOW);
u8 cross[] = {
0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34,
0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00,
0x00, 0x00, 0x34, 0x00, 0x00, 0x34, 0x00, 0x00,
0x00, 0x00, 0x00, 0x34, 0x34, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x34, 0x34, 0x00, 0x00, 0x00,
0x00, 0x00, 0x34, 0x00, 0x00, 0x34, 0x00, 0x00,
0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00,
0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34
};
DMAFastCopy((void*)cross, (void *)CharBB+2240, 64, DMA_16NOW);

u8 currY;
for (currY=0; currY<32; currY++) {
for (curr=0; curr<32; curr++) {
Bg0Screen[curr+(currY*32)] = currY+1;
}
}
for (currY=0; currY<32; currY++) {
for (curr=0; curr<32; curr++) {
Bg1Screen[curr+(currY*32)] = 33;//triangle
}
}
for (currY=0; currY<32; currY++) {
for (curr=0; curr<32; curr++) {
Bg2Screen[curr+(currY*32)] = 34;//red square
}
}
for (currY=0; currY<32; currY++) {
for (curr=0; curr<32; curr++) {
Bg3Screen[curr+(currY*32)] = 35;//green cross
}
}

//setup the first sprite
u8 xSprite1 = 10, ySprite1 = 10;
sprites[0].attribute0 = COLOR_256 | ySprite1;
sprites[0].attribute1 = SIZE_64 | xSprite1;
sprites[0].attribute2 = 0;//first entry in the OAM 256 sprite array

u8 xBg0 = 0, yBg0 = 0;//start x,y position of screen in map 0
u8 xBg1 = 0, yBg1 = 0;
u8 xBg2 = 0, yBg2 = 0;
u8 xBg3 = 0, yBg3 = 0;
while(1) {
while(REG_VCOUNT < 160); //wait for the start of VBLANK

//D-pad moves background
if(!(BUTTONS & BUTTON_LEFT)) {
if (xBg1>0) {
xBg1--;
}
if (xBg2>1) {
xBg2-=2;
}
if (xBg3>3) {
xBg3-=4;
}
}
if(!(BUTTONS & BUTTON_RIGHT)) {
xBg1++;
xBg2+=2;
xBg3+=4;
}
if(!(BUTTONS & BUTTON_UP)) {
if (yBg1>0) {
yBg1--;
}
if (yBg2>1) {
yBg2-=2;
}
if (yBg3>3) {
yBg3-=4;
}
}
if(!(BUTTONS & BUTTON_DOWN)) {
yBg1++;
yBg2+=2;
yBg3+=4;
}

REG_BG0HOFS = xBg0; //x position of start of background 0
REG_BG0VOFS = yBg0; //y position of start of background 0
REG_BG1HOFS = xBg1; //x position of start of background 1
REG_BG1VOFS = yBg1; //y position of start of background 1
REG_BG2HOFS = xBg2; //x position of start of background 2
REG_BG2VOFS = yBg2; //y position of start of background 2
REG_BG3HOFS = xBg3; //x position of start of background 3
REG_BG3VOFS = yBg3; //y position of start of background 3

//Update Sprite Memory
//Change it later on so that it i only update the sprite memory when sprites change
//There are up to 128 sprites total
DMAFastCopy((void*)sprites, (void *)OAMMem, 512, DMA_16NOW);//512=128*4

while(REG_VCOUNT > 160); //wait for end of VBLANK
}

#34595 - Celeryface - Sat Jan 22, 2005 1:45 am

arock99 wrote:
Hi,
First of all thanks for the help i had displaying custom bgs...
I have another issue and this time around i did more looking around but either i didnt understand what i read (most likely) or i just didnt find exactly what i was looking for. I want to display things in the following order:
bg0
bg1 over bg0
bg2 over bg1
sprites over bg2
bg3 over sprites


I believe your sprite/background priority question is answered on the CowBite Spec :)

Edit: Also you can set the priority of a sprite by using the following shift in attribute 2:

priorityNum << 10

#34619 - arock99 - Sat Jan 22, 2005 6:38 pm

Celeryface wrote:
arock99 wrote:
Hi,
First of all thanks for the help i had displaying custom bgs...
I have another issue and this time around i did more looking around but either i didnt understand what i read (most likely) or i just didnt find exactly what i was looking for. I want to display things in the following order:
bg0
bg1 over bg0
bg2 over bg1
sprites over bg2
bg3 over sprites


I believe your sprite/background priority question is answered on the CowBite Spec :)

Edit: Also you can set the priority of a sprite by using the following shift in attribute 2:

priorityNum << 10


Hi,
I tried:
sprites[i].attribute2 = 1 << 10;
and it gives me the same result...
Which would make sense since PRIORITY(n) is declared as
#define PRIORITY(n) ((n) << 10)
Which would do the same thing...
im a bit too busy to get into reading the link you gave me from CowBite right at this moment but will look at it later and try to figure out what's going on. At least I know I was on the right path to begin with which is good to know :) Thanks!

#34620 - Celeryface - Sat Jan 22, 2005 7:36 pm

arock99 wrote:
Celeryface wrote:
arock99 wrote:
Hi,
First of all thanks for the help i had displaying custom bgs...
I have another issue and this time around i did more looking around but either i didnt understand what i read (most likely) or i just didnt find exactly what i was looking for. I want to display things in the following order:
bg0
bg1 over bg0
bg2 over bg1
sprites over bg2
bg3 over sprites


I believe your sprite/background priority question is answered on the CowBite Spec :)

Edit: Also you can set the priority of a sprite by using the following shift in attribute 2:

priorityNum << 10


Hi,
I tried:
sprites[i].attribute2 = 1 << 10;
and it gives me the same result...
Which would make sense since PRIORITY(n) is declared as
#define PRIORITY(n) ((n) << 10)
Which would do the same thing...
im a bit too busy to get into reading the link you gave me from CowBite right at this moment but will look at it later and try to figure out what's going on. At least I know I was on the right path to begin with which is good to know :) Thanks!


It looks like you might be overwriting your priority bit in attribute 2:


Code:

for(i = 0; i < 128; i++) {
sprites[i].attribute0 = 160;
sprites[i].attribute1 = 240;
sprites[i].attribute2 = PRIORITY(1);//Goes in front of backgrounds 0,1, and 2 but behind background 3
}

...

 //setup the first sprite
u8 xSprite1 = 10, ySprite1 = 10;
sprites[0].attribute0 = COLOR_256 | ySprite1;
sprites[0].attribute1 = SIZE_64 | xSprite1;
sprites[0].attribute2 = 0;//first entry in the OAM 256 sprite array


Try to set the priority again when you setup attribute2 for your first sprite. :)

#34622 - arock99 - Sat Jan 22, 2005 8:53 pm

Thanks again for the help...that was somewhat of a dumb mistake on my part....all these years of programming and suddenly i'm learning a new environment and i make mistakes i used to make long ago ;) I guess I concentrated so much on the "new" stuff I forgot to check the basis ;)

Works now!
Thanks

#34636 - Celeryface - Sun Jan 23, 2005 2:29 am

arock99 wrote:
Thanks again for the help...that was somewhat of a dumb mistake on my part....all these years of programming and suddenly i'm learning a new environment and i make mistakes i used to make long ago ;) I guess I concentrated so much on the "new" stuff I forgot to check the basis ;)

Works now!
Thanks


Yeah, the solutions to certain programming bugs -- where you know you're programming it the right way -- are normally the simplest things, like overwriting/not initialising a variable, that get overlooked.

Good luck on your project. :)