Page 1 of 2

Background problem

Posted: Sat Oct 16, 2010 9:44 am
by solano
I have been following the tutorials @ http://www.dev-scene.com and an having problems with the tutorial about the background.

The code I have is this

Code: Select all

#include <nds.h>
#include <stdio.h>
#include <nds/arm9/background.h>

#include "cirno_bin.h"
 
typedef struct
{
	char signature[2];
	unsigned int fileSize;
	unsigned int reserved;
	unsigned int offset;
}__attribute__ ((packed)) BmpHeader;
 
typedef struct
{
	unsigned int headerSize;
	unsigned int width;
	unsigned int height;
	unsigned short planeCount;
	unsigned short bitDepth;
	unsigned int compression;
	unsigned int compressedImageSize;
	unsigned int horizontalResolution;
	unsigned int verticalResolution;
	unsigned int numColors;
	unsigned int importantColors;
	
}__attribute__ ((packed)) BmpImageInfo;

typedef struct
{
	unsigned char blue;
	unsigned char green;
	unsigned char red;
	unsigned char reserved;
}__attribute__ ((packed)) Rgb;
 
typedef struct
{
	BmpHeader header;
	BmpImageInfo info;
	Rgb colors[256];
	unsigned short image[1];
}__attribute__ ((packed)) BmpFile;

//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------
	
	int iy,ix,i;
	
	BmpFile* bmp = (BmpFile*)cirno_bin;
	
	consoleDemoInit();
	
	//printf("%c%c\n", bmp->header.signature[0], bmp->header.signature[1]);
	//printf("bit depth: %i\n", bmp->info.bitDepth);
	//printf("width:     %i\n", bmp->info.width);
	//printf("height:    %i\n", bmp->info.height);
	
	//copy the palette	
	for(i = 0; i < 256; i++)
	{
		Background_palette[i] = RGB15(bmp->colors[i].red >> 3, bmp->colors[i].green >> 3, bmp->colors[i].blue >> 3);
	}
	//copy the image
	for(iy = 0; iy < bmp->info.height; iy++)
	{
		for(ix = 0; ix < bmp->info.width / 2; ix++)
			video_buffer[iy * 128 + ix] = bmp->image[(bmp->info.height - 1 - iy) * ((bmp->info.width + 3) & ~3) / 2  + ix];
	}

	
	while(1){
		swiWaitForVBlank();
	}
 
	return 0;
}


But I'm getting these errors:
C:\devkitPro\examples\nds\Projects\background_test>make
main.cpp
arm-eabi-g++ -MMD -MP -MF /c/devkitPro/examples/nds/Projects/background_test/bui
ld/main.d -g -Wall -O2 -fomit-frame-pointer -ffast-math -mthumb -mthumb-interwor
k -march=armv5te -mtune=arm946e-s -iquote /c/devkitPro/examples/nds/Projects/bac
kground_test/include -I/c/devkitPro/libnds/include -I/c/devkitPro/examples/nds/P
rojects/background_test/build -DARM9 -fno-rtti -fno-exceptions -c /c/devkitPro/e
xamples/nds/Projects/background_test/source/main.cpp -o main.o
c:/devkitPro/examples/nds/Projects/background_test/source/main.cpp: In function
'int main()':
c:/devkitPro/examples/nds/Projects/background_test/source/main.cpp:65:3: error:
'Background_palette' was not declared in this scope
c:/devkitPro/examples/nds/Projects/background_test/source/main.cpp:68:29: warnin
g: comparison between signed and unsigned integer expressions
c:/devkitPro/examples/nds/Projects/background_test/source/main.cpp:70:38: warnin
g: comparison between signed and unsigned integer expressions
c:/devkitPro/examples/nds/Projects/background_test/source/main.cpp:71:4: error:
'video_buffer' was not declared in this scope
make[1]: *** [main.o] Error 1
make: *** [build] Error 2

C:\devkitPro\examples\nds\Projects\background_test>
Any ideas what I'm doing wrong?

Re: Background problem

Posted: Sat Oct 16, 2010 3:39 pm
by zeromus
which tutorial? be specific. i.e. url

Re: Background problem

Posted: Sat Oct 16, 2010 11:38 pm
by coreyh2
I'd recommend looking at the examples here
C:\devkitPro\examples\nds\Graphics\Backgrounds

They are more current then any tutorials on the web. libnds has changed often. References to actual hardware are usually still true but the libraries are often different.

I copied the default examples somewhere else and then messed with them to see how things work.

Re: Background problem

Posted: Sun Oct 17, 2010 1:42 pm
by solano
@zeromus
http://www.dev-scene.com/NDS/Tutorials_Day_3 Background struct
@corey2
when i use the decode i compile with no problems,but when i run it in the emulator(no$gba) it says it need gba bios.Is that because something's wrong with the compiler or is it of the emulator
I used the code from the example.

EDIT: The emulator was the problem
Now I have a new problem

Code: Select all

#include <nds.h>
#include <maxmod9.h>
#include <stdio.h>

#include "soundbank.h"
#include "soundbank_bin.h"
#include "backgroundBottom.h"
#include "backgroundTop.h"
#include "reimu.h"

int main() {

	int x = 0,y = 0;
	
	 vramSetMainBanks(VRAM_A_MAIN_BG_0x06000000,
                     VRAM_B_MAIN_BG_0x06020000,
                     VRAM_C_SUB_BG_0x06200000,
                     VRAM_D_LCD);

    vramSetBankE(VRAM_E_MAIN_SPRITE);

	
	videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE); //sub bg 0 will be used to print text
	videoSetModeSub(MODE_5_2D | DISPLAY_BG3_ACTIVE); 

	
	bgInit(3, BgType_Bmp16, BgSize_B16_256x256, 0,0);
	bgInitSub(3, BgType_Bmp16, BgSize_B16_256x256, 0,0);
	
	decompress(backgroundTopBitmap, BG_GFX,  LZ77Vram);
	decompress(backgroundBottomBitmap, BG_GFX_SUB,  LZ77Vram);
	
	//consoleDemoInit();

	mmInitDefaultMem((mm_addr)soundbank_bin);
	
	// load the module
	mmLoad( MOD_BGM1 );

	// Start playing module
	mmStart( MOD_BGM1, MM_PLAY_LOOP );
	
	oamInit(&oamSub, SpriteMapping_Bmp_1D_128, false); //initialize the oam
	u16* gfx = oamAllocateGfx(&oamSub, SpriteSize_64x64,SpriteColorFormat_256Color);//make room for the sprite
	dmaCopy(reimuTiles,gfx, reimuTilesLen);//copy the sprite
	dmaCopy(reimuPal, SPRITE_PALETTE, reimuPalLen); //copy the sprites palette oamEnable(&oamMain);
	oamSet(&oamSub,0,x,y,0,0,SpriteSize_64x64,SpriteColorFormat_256Color,gfx,0,false,false,false,false,false);

	while(1){
		oamUpdate(&oamSub);
		swiWaitForVBlank();
	}
}
With that code the backgrounds are showing and the music is playing.But the sprite isn't showing.( I want it to show on the bottom screen )
When I change the code a little:

Code: Select all

oamInit(&oamMain, SpriteMapping_Bmp_1D_128, false); //initialize the oam
u16* gfx = oamAllocateGfx(&oamMain, SpriteSize_64x64,SpriteColorFormat_256Color);//make room for the sprite
dmaCopy(reimuTiles,gfx, reimuTilesLen);//copy the sprite
dmaCopy(reimuPal, SPRITE_PALETTE, reimuPalLen); //copy the sprites palette oamEnable(&oamMain);
oamSet(&oamMain,0,x,y,0,0,SpriteSize_64x64,SpriteColorFormat_256Color,gfx,0,false,false,false,false,false);

............

oamUpdate(&oamMain);
The sprite is showing but split in two 32x64 part which are displayed next to each other .(In the top screen )
Now I think the video modes are the problem.Can anybody point out my mistakes?

Re: Background problem

Posted: Mon Oct 18, 2010 9:30 pm
by zeromus
the first one doesnt work because you didnt give any vram to SUB OBJ. theres no way you can display any sprites without vram.

in the second piece of code you have changed it to MAIN OBJ, to which you have given vram E; so there is some hope of it working.

without more details (such as the source data you used for the sprite and the grit command used to compile it) we cannot determine anything more. i recommend uploading your project somewhere for folks to take a look at.

Re: Background problem

Posted: Mon Oct 18, 2010 10:11 pm
by solano
Background is all fixed and the sprite but now I have a couple of more problems
First using this code

Code: Select all

oamInit(&oamMain, SpriteMapping_Bmp_1D_128, false); //initialize the oam
	u16* gfx = oamAllocateGfx(&oamMain, SpriteSize_64x64,SpriteColorFormat_256Color);//make room for the sprite
	dmaCopy(reimuTiles,gfx, reimuTilesLen);//copy the sprite
	dmaCopy(reimuPal, SPRITE_PALETTE, reimuPalLen); //copy the sprites palette oamEnable(&oamMain);

	oamSet(&oamMain,0,x,y,0,0,SpriteSize_64x64,SpriteColorFormat_256Color,gfx,0,false,false,false,false,false);
I display one sprite but how can I display more that one sprite?I remember reading about some oamTable.Can some1 explain to me how that works.
Second I use this code for key input

Code: Select all

scanKeys();
		int held = keysHeld();
		if(held & KEY_LEFT){
			if(x >= 2){
				x -= 2;
			}
		}
		else if(held & KEY_RIGHT){
			if(x + 29 <= SCREEN_WIDTH){
				x += 2;
			}
		}
		else if(held & KEY_DOWN){
			if(y + 47 <= SCREEN_HEIGHT){
				y += 2;
			}
		}
		else if(held & KEY_UP){
			if(y >= 2){
				y -= 2;
			}
		}
How can I check if two keys are pressed at the same time.For example up and right.
And last how can I make the sprite go from one screen to another.I mean lets say I have a sprite at the bottom.I start moving up and when I reach the top part of the sprite start appearing at the top until the whole sprite is at the top screen.
Thank you for your time.

Re: Background problem

Posted: Tue Oct 19, 2010 4:21 pm
by zeromus
call oamSet(&oamMain,1, ...

and so on up to 127

Your question about keys is disturbing. If you can't answer that yourself, you need to seriously reconsider your choice of hobbies. But I'll give you a hint: investigate the LOGICAL AND ( && )

To make sprites go from one screen to another, you just have to be clever. Put the sprite on both screens if it is straddling them. Load it up on each of MAIN and SUB engines.

Re: Background problem

Posted: Tue Oct 19, 2010 9:27 pm
by solano
What I meant by displaying more that one sprite is for example in my game I have the character sprite.She can shoot bullets .The bullets have a sprite.And there are enemies which have their own sprites.So 3 sprites in total.How to load them and display them on the screen is my question.

Code: Select all

oamInit(&oamMain, SpriteMapping_Bmp_1D_128, false); //initialize the oam

dmaCopy(reimuTiles,&SPRITE_GFX[0], reimuTilesLen);//copy the sprite
dmaCopy(reimuPal, SPRITE_PALETTE, reimuPalLen); //copy the sprites palette 
	
dmaCopy(danmakuReimuTiles,&SPRITE_GFX[1], danmakuReimuTilesLen);//copy the sprite
dmaCopy(danmakuReimuPal, SPRITE_PALETTE, danmakuReimuPalLen); //copy the sprites palette 

oamSet(&oamMain,0,x,y,0,0,SpriteSize_64x64,SpriteColorFormat_256Color,&SPRITE_GFX[0],0,false,false,false,false,false);
oamSet(&oamMain,1,x + 64,y + 64,0,0,SpriteSize_64x64,SpriteColorFormat_256Color,&SPRITE_GFX[1],0,false,false,false,false,false); 
This is what I tried.But what im getting is a mix of the two sprites(reimu and danmakuReimu) with the pallete of the second sprite.

Image

Sorry to be a bother but I'm still new and don't know left from right.And haven't have much experience in programming( still learning C++ in school ( 1 month ) all i've written are simple console programs/games and have some knowledge in opengl. Before that used Game Maker for 2 years ^^ )

Re: Background problem

Posted: Tue Oct 19, 2010 10:33 pm
by zeromus
well, you did tell the second palette to copy to SPRITE_PALETTE which is the same place you copied the first sprite's palette--so it ends up overwriting it.

there is only one palette. you need to make sure that you make 256 color sprites that share the same palette. anything else is trickier in code.

SPRITE_GFX[1] doesn't work. you may think it makes sense since it seems like the space for the second sprite, but thats not how it works. all youre doing is putting the second block of graphics slightly later in memory (2 bytes later). that isnt enough room for the sprite, not by far.

you need to be using oamAllocateGfx() to get the pointers where you should copy the data for your sprites. look at the animate_simple example, or virtually any other of the sprite examples...

Re: Background problem

Posted: Wed Oct 20, 2010 6:05 pm
by solano
What other options are available for the palette.
Can I use SpriteEntry in some way.What other options are there.

Did a little research and found something.The sprite_extended_palettes example.

Code: Select all

vramSetBankF(VRAM_F_LCD);
	
for(i = 0;i < 256; i++){
	VRAM_F_EXT_SPR_PALETTE[0][i] = reimuPal[i];// want to copy the palette but doesnt work because it expects rgb15 value
	VRAM_F_EXT_SPR_PALETTE[1][i] = danmakuReimuPal[i];//and I dont know how to convert it
}
	
vramSetBankF(VRAM_F_SPRITE_EXT_PALETTE);

....

oamSet(...,1,SpriteSize_16x16,SpriteColorFormat_256Color,...);// the one should be the palette index VRAM_F_EXT_SPR_PALETTE[1]
But it doesn't work.The sprite are all in black.

Then I tried this:

Code: Select all

dmaCopy(danmakuReimuPal,VRAM_F_EXT_SPR_PALETTE[1],danmakuReimuPalLen);
....
oamSet(&oamMain,1,danmaku.x,danmaku.y,0,1,SpriteSize_16x16,SpriteColorFormat_256Color,danmaku.sprite_gfx_mem,0,false,false,false,false,false);
Sprites are still black :(

EDIT:
All fixed.Didn't set the last argument of oamInit to true
And the conversion was pretty easy.

Code: Select all

for(i = 0;i < 256; i++){
		VRAM_F_EXT_SPR_PALETTE[0][i] = reimuPal[i];
		VRAM_F_EXT_SPR_PALETTE[1][i] = danmakuReimuPal[i];
}
//No need for it :D