Answers to your coding questions... http://answers.drunkencoders.com A site about answers....not questions Tue, 06 Jan 2015 05:11:24 +0000 en-US hourly 1 http://wordpress.org/?v=4.1 How do I rotate a background Image?http://answers.drunkencoders.com/how-do-i-rotate-a-background-image/ http://answers.drunkencoders.com/how-do-i-rotate-a-background-image/#comments Tue, 27 Aug 2013 14:29:50 +0000 http://answers.drunkencoders.com/?p=314

/*---------------------------------------------------------------------------------

Rotate a bitmap 
---------------------------------------------------------------------------------*/
#include <nds.h>

#include "drunkenlogo.h"

//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------
	
	videoSetMode(MODE_5_2D);
	vramSetBankA(VRAM_A_MAIN_BG);

	int bg = bgInit(3, BgType_Bmp16, BgSize_B16_256x256, 0,0);
	dmaCopy(drunkenlogoBitmap, bgGetGfxPtr(bg), drunkenlogoBitmapLen); 

	bgSetCenter(bg, SCREEN_WIDTH/2, SCREEN_HEIGHT/2);
	bgScroll(bg, SCREEN_WIDTH/2, SCREEN_HEIGHT/2);

	while(1) 
	{
		swiWaitForVBlank();

		bgRotate(bg, 10);

		bgUpdate();
	}

}

Remember to call bgUpdate() once per frame when using rotations and scaling. You can set a specific angle with bgSetRotate().

]]>
http://answers.drunkencoders.com/how-do-i-rotate-a-background-image/feed/ 0
How do I print on both screens AND use the keyboard.http://answers.drunkencoders.com/how-do-i-print-on-both-screens-and-use-the-keyboard/ http://answers.drunkencoders.com/how-do-i-print-on-both-screens-and-use-the-keyboard/#comments Tue, 27 Aug 2013 14:08:08 +0000 http://answers.drunkencoders.com/?p=311

/*---------------------------------------------------------------------------------

	Printing on both screens with a keyboard

---------------------------------------------------------------------------------*/
#include <nds.h>
#include <stdio.h>

PrintConsole pcMain;
PrintConsole pcSub;

void keyUp(int c)
{
	consoleSelect(&pcSub);
	iprintf("%c", c);
}

//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------
	
	videoSetMode(MODE_0_2D);
	videoSetModeSub(MODE_0_2D);
	vramSetBankA(VRAM_A_MAIN_BG);
	vramSetBankC(VRAM_C_SUB_BG);

	//two print consoles
	consoleInit(&pcMain,0,BgType_Text4bpp, BgSize_T_256x256, 2,0,true,true);
	consoleInit(&pcSub,0,BgType_Text4bpp, BgSize_T_256x256, 2,0,false,true);
	
	//create a window for the sub display so it stays above the keyboard.
	consoleSetWindow(&pcSub, 0,0,32,8);

	//set up our keyboard.  I used mtheal's vram tool to figure out where to put everything
	Keyboard* kb = keyboardInit(0,1,BgType_Text4bpp, BgSize_T_256x256, 3,1,false,true);

	kb->OnKeyReleased = keyUp;

	keyboardShow();

	//prove the top screen works
	consoleSelect(&pcMain);
	iprintf("hello cruel world....");

	while(1) {

		keyboardUpdate();

		swiWaitForVBlank();
	}

}

Probably the most challenging aspect of this is setting up your background memory so your maps and your graphics dont overlap between the keyboard and the console. I used mtheall’s slick vram tool to figure it out:

http://mtheall.com/vram.html#T0=3&NT0=128&MB0=2&TB0=0&S0=0&T1=4&NT1=864&MB1=3&TB1=1&S1=2

]]>
http://answers.drunkencoders.com/how-do-i-print-on-both-screens-and-use-the-keyboard/feed/ 0
How do I display a 16-bit image on the screen?http://answers.drunkencoders.com/how-do-i-display-a-16-bit-image-on-the-screen/ http://answers.drunkencoders.com/how-do-i-display-a-16-bit-image-on-the-screen/#comments Sat, 24 Aug 2013 21:15:26 +0000 http://answers.drunkencoders.com/?p=300 Here is a very simple example on how to take an image stored as a .png file (or any of the supported file formats supported by grit) and put it on the screen. The first thing we need is a target image. For that let’s chose our standard Drunkencoder logo:

drunkenlogo

I cant tell you exactly how this was made but I am fairly certain there was some sort of paint program involved. Anyway, notice it is 256×256 png file which matches one of the allowed background sizes for the DS (this isn’t necessary it just makes the copy to video memory trivial and this demo is…well…trivial).

Next we need to convert our image into something the DS can understand and there are a few ways to make that happen. We could write it to an SD card file system or use the special file system supported by Nintendo DS roms called nitroFS and then try to parse the data as we load it. Or we could do it the easy way and run it through grit which is included with libnds and devkitPro.

To do this is very easy. Simply create a folder called “gfx” or “data” in your project directory and drop the png file into it. Next create a text file with a name that matches your image file but with an extension of .grit.

This file is how we tell grit what to do with our image….in this case we want it to create a binary array of pixel data we can just copy into video memory. Its pretty simple and we only need three options. First is -gT! this tells grit to ignore any transparency data in the image file and set all the pixels to visible (if you don’t use this there is a good change your image won’t render correctly or you will have to set the alpha bits of each pixel manually as you load them into video memory, using the alpha channel of an image is very useful but for now its likely just to confuse things so lets turn it off).

Then we do -gB16 and -gb which tells grit to produce 16 bit pixel bitmap data and to write that out as a straight binary file. There are a LOT of options for grit and we will explore many of them in these FAQs but your best bet is the grit readme or website to really get a feel for how it all works.

Your grit file should look something like the following:

# disable alpha and set opaque bit for all pixels
-gT!

# 16 bit bitmap
-gB16
-gb

The magic makefile included in the libnds example templates will automatically call grit on all the image files in your gfx directory using the options supplied in the grit file. This will produce a binary file and a header file for easy inclusion in your project.

Here is what the actual code for the demo looks like:

/*---------------------------------------------------------------------------------

Render a 16 bit per pixel bitmap to the screen

---------------------------------------------------------------------------------*/
#include <nds.h>
#include <drunkenlogo.h>

int main(void) {



	videoSetMode(MODE_5_2D);
	vramSetBankA(VRAM_A_MAIN_BG);

	int bg = bgInit(3, BgType_Bmp16, BgSize_B16_256x256, 0,0);
	dmaCopy(drunkenlogoBitmap, bgGetGfxPtr(bg), drunkenlogoBitmapLen); 

	while(1) 
	{
		swiWaitForVBlank();
	}

	return 0;
}

That “drunkenlogo.h” is the header file auto generated by grit. You can find it in your “build” directory after you call make. If you were to open it up you would see something like the following:

//{{BLOCK(drunkenlogo)

//======================================================================
//
//	drunkenlogo, 256x256@16, 
//	Alphabit on.
//	+ bitmap not compressed
//	Total size: 131072 = 131072
//
//	Time-stamp: 2013-08-24, 17:01:25
//	Exported by Cearn's GBA Image Transmogrifier, v0.8.10
//	( http://www.coranac.com/projects/#grit )
//
//======================================================================

#ifndef GRIT_DRUNKENLOGO_H
#define GRIT_DRUNKENLOGO_H

#define drunkenlogoBitmapLen 131072
extern const unsigned int drunkenlogoBitmap[32768];

#endif // GRIT_DRUNKENLOGO_H

//}}BLOCK(drunkenlogo)

]]>
http://answers.drunkencoders.com/how-do-i-display-a-16-bit-image-on-the-screen/feed/ 1
How do i combine a bitmap background with text?http://answers.drunkencoders.com/how-do-i-combine-a-bitmap-bacground-with-text/ http://answers.drunkencoders.com/how-do-i-combine-a-bitmap-bacground-with-text/#comments Sat, 24 Aug 2013 15:53:08 +0000 http://answers.drunkencoders.com/?p=289 Let’s just modify the libnds 16-bit bitmap demo included in libnds examples to allow text on the same screen. All we really need to do is set up the console for the main display using background layer 0 and move our bitmap graphics to make room for it by adjusting its map base offset (an offset of 1 moves the memory 16KB further into memory which is plenty of room for a font and a map layer for text).

#include <nds.h>
#include <drunkenlogo.h>

int main(void) {
	

	
	videoSetMode(MODE_5_2D);
	vramSetBankA(VRAM_A_MAIN_BG);
	
        int bg = bgInit(3, BgType_Bmp16, BgSize_B16_256x256, 1,0);
	decompress(drunkenlogoBitmap, bgGetGfxPtr(bg), LZ77Vram); //Displays/decompresses top image

	consoleInit(0,0, BgType_Text4bpp, BgSize_T_256x256, 4,0, true, true);
	iprintf("Hello there !");
	
       while(1) {
		swiWaitForVBlank();
	}
	return 0;
}

And we get:
16bitwithtext

]]>
http://answers.drunkencoders.com/how-do-i-combine-a-bitmap-bacground-with-text/feed/ 0
How do I draw to the screen as a 16 bit bitmap?http://answers.drunkencoders.com/how-do-i-draw-to-the-screen-as-a-16-bit-bitmap/ http://answers.drunkencoders.com/how-do-i-draw-to-the-screen-as-a-16-bit-bitmap/#comments Sat, 24 Aug 2013 03:21:48 +0000 http://answers.drunkencoders.com/?p=279

/*---------------------------------------------------------------------------------

	Basic template code for starting a DS app

---------------------------------------------------------------------------------*/
#include &lt;nds.h&gt;

//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------
	int x, y;

	//set the mode to allow for an extended rotation background
	videoSetMode(MODE_5_2D);
	videoSetModeSub(MODE_5_2D);

	//allocate a vram bank for each display
	vramSetBankA(VRAM_A_MAIN_BG);
	vramSetBankC(VRAM_C_SUB_BG);

	//create a background on each display
	int bgMain = bgInit(3, BgType_Bmp16, BgSize_B16_256x256, 0,0);
	int bgSub = bgInitSub(3, BgType_Bmp16, BgSize_B16_256x256, 0,0);

	u16* videoMemoryMain = bgGetGfxPtr(bgMain);
	u16* videoMemorySub = bgGetGfxPtr(bgSub);


	//initialize it with a color
	for(x = 0; x &lt; 256; x++)
		for(y = 0; y &lt; 256; y++)
		{
			videoMemoryMain[x + y * 256] = ARGB16(1, 31, 0, 0);
			videoMemorySub[x + y * 256] = ARGB16(1, 0, 0, 31);
		}

	while(1) 
	{
		swiWaitForVBlank();
	}

}

The only thing of note in the above that may not be clear from the code and cross referencing the libnds documentation is the macro ARGB16(). This takes an alpha value (1 for visible, 0 for transparent) and 5 bits of red green and blue to form the 16 bit color.

]]>
http://answers.drunkencoders.com/how-do-i-draw-to-the-screen-as-a-16-bit-bitmap/feed/ 5
What graphics modes does the DS support?http://answers.drunkencoders.com/what-graphics-modes-does-the-ds-support/ http://answers.drunkencoders.com/what-graphics-modes-does-the-ds-support/#comments Fri, 23 Aug 2013 20:35:43 +0000 http://answers.drunkencoders.com/?p=276 Background control is provided via an API or Direct register access. Usually these methods can be mixed. However, scrolling, scaling, and rotation will have unexpected results if API and Direct Register access is mixed. Effort is being directed at ensuring the API can access all hardware features without limitation.

The DS contains two separate hardware 2D cores responsible for rendering 2D backgrounds. The definitions below outline the libnds api for utilizing these backgrounds.
The background engine provides basic initialization and management of the 8 2D backgrounds available on the DS. Other than initialization and hardware limitations background control is identical on both main and sub screens.

The following modes of operation are allowed:

Main 2D engine
______________________________
|Mode | BG0 | BG1 | BG2 |BG3 | T = Text
| 0 | T | T | T | T | R = Rotation
| 1 | T | T | T | R | E = Extended Rotation
| 2 | T | T | R | R | L = Large Bitmap background
| 3 | T | T | T | E |
| 4 | T | T | R | E |
| 5 | T | T | E | E |
| 6 | | L | | |
—————————–
Sub 2D engine
______________________________
|Mode | BG0 | BG1 | BG2 |BG3 |
| 0 | T | T | T | T |
| 1 | T | T | T | R |
| 2 | T | T | R | R |
| 3 | T | T | T | E |
| 4 | T | T | R | E |
| 5 | T | T | E | E |
—————————–
On the main engine BG0 can be used as a 3D rendering surface.

]]>
http://answers.drunkencoders.com/what-graphics-modes-does-the-ds-support/feed/ 0
How do I XNA on windows 8 Metro?http://answers.drunkencoders.com/how-do-i-xna-on-windows-8-metro/ http://answers.drunkencoders.com/how-do-i-xna-on-windows-8-metro/#comments Tue, 13 Nov 2012 16:34:02 +0000 http://answers.drunkencoders.com/?p=261 I have been playing around with windows metro dev and since I have been a big fan of C# for quite a few years I thought it might be fun to put together a quick C# game for the app store….but it seems C# has been left out of the Direct X loop by MS this time around.

I found that rather dissapointing and went in search of options.

What I found was SharpDX and monogame.

Interestingly, these are rather easily cross platform. I did a windows, xbox, and android build with a hanfull of #ifdefs sprinkled about.

The result is my work in progress:

Feel free to post XNA or metro topics to the Questions thread.

]]>
http://answers.drunkencoders.com/how-do-i-xna-on-windows-8-metro/feed/ 1
How do I fake static with tiles?http://answers.drunkencoders.com/how-do-i-fake-static-with-tiles/ http://answers.drunkencoders.com/how-do-i-fake-static-with-tiles/#comments Mon, 08 Oct 2012 21:25:58 +0000 http://answers.drunkencoders.com/?p=244 Here is a simple way using 16 random tiles and a random palette:

/*---------------------------------------------------------------------------------

	Faking static

---------------------------------------------------------------------------------*/
#include &lt;nds.h&gt;
//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------
	int tileCount = 16;

	videoSetMode(MODE_0_2D);

	int bg = bgInit(0, BgType_Text8bpp, BgSize_B16_256x256, 0, 1);

	u16* tiles = bgGetGfxPtr(bg);
	u16* map = bgGetMapPtr(bg);

	//create 16 tiles filled with random colors
	for(int i = 0; i &lt; tileCount * 32; i++)
		tiles[i] = rand();

	//create a map filled with those random tiles
	for(int i = 0; i &lt; 32 * 32; i++)
		map[i] = rand() % tileCount;

	while(1) 
	{
		//create a random palette every frame
		for(int i = 0; i &lt; 256; i++)
		{
			//a grey scaled palette...could have used colors but this looks better
			int shade = rand() % 32;
			BG_PALETTE[i] = RGB15(shade, shade, shade);
		}
		swiWaitForVBlank();
	}

}

Here is a slightly more complex way using a single 16 color tile and some hblank tricks:

/*---------------------------------------------------------------------------------

	Faking static

---------------------------------------------------------------------------------*/
#include <nds.h>

void hblank(void)
{
	REG_BG0HOFS = rand() & 0xFF;
	REG_BG0VOFS = rand() & 0xFF;
}
//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------
	videoSetMode(MODE_0_2D);

	int bg = bgInit(0, BgType_Text4bpp, BgSize_T_256x256, 0, 1);

	u16* tiles = bgGetGfxPtr(bg);
	u16* map = bgGetMapPtr(bg);

	irqEnable(IRQ_HBLANK);
	irqSet(IRQ_HBLANK, hblank);

	//create 1 tile filled with random colors
	for(int i = 0; i < 16; i++)
		tiles[i] = rand();

	//create a map filled with those random tiles (only bits we are setting are the 4 bits for palette and the two for h and v flip)
	for(int i = 0; i < 32 * 32; i++)
	{
		map[i] = rand() & (0x3F << 10);
	}
	while(1) 
	{
		//create a random palette every frame
		for(int i = 0; i < 256; i++)
		{
			//a grey scaled palette...could have used colors but this looks better
			int shade = rand() % 32;
			BG_PALETTE[i] = RGB15(shade, shade, shade);
		}
		swiWaitForVBlank();
	}

}

]]>
http://answers.drunkencoders.com/how-do-i-fake-static-with-tiles/feed/ 0
A simple windowing Demohttp://answers.drunkencoders.com/a-simple-windowing-demo/ http://answers.drunkencoders.com/a-simple-windowing-demo/#comments Sat, 25 Aug 2012 21:54:06 +0000 http://answers.drunkencoders.com/?p=195 Using the new windowing API to enable and display a window

First, as always, lets look at the full source for the demo. Notice that it sets up and displays our traditional drunkencoders logo, enables the window and finally lets us mess with its settings.

The DS has 3 hardware windows which can be used to mask parts of the screen. Two of them are simple rectangles, you give the DS the top, bottom, right, and left of the square and it creates a mask of that size. We can control what layers are rendered inside the window and which ones are rendered outside the window.

The other window is an Object Window and it uses a sprite object as the mask (basically any pixel in the sprite that is not zero becomes “in window”).

All that is required to use a window is first to turn it on, second to define if you want your layers or objects to appear inside the window or outside all windows, and finally define the top, left, bottom, and right positions of the window..

This brings us to our first bit of code to enable a window and set how that window effects our background.

If we did not set our background window options the background would neither show up inside nor outside the window and therefor would not be displayed. It is perfectly acceptable to have the bg show up inside multiple windows or outside all windows or both (just OR the window options together which you pass to bgWindowEnable).

We next set the starting x, y, and size of our window box:

Next is our main loop:

Inside this loop we alter the x and y with key presses so the window moves about, we adjust the size as well so we can shrink of grow it.

We also add a little feature that allows us to alter the window by pressing X and Y keys. Pressing Y tells the DS to display the part of the background that is outside all windows, pressing Y causes it to display only inside window 0. If you were to not call bgWindowDisable to turn off the unwanted option the background would simply end up being displayed both inside window 0 and outside all windows.

Finally, we set the bounds on our window based upon the settings we had altered above:

]]>
http://answers.drunkencoders.com/a-simple-windowing-demo/feed/ 3
What sort of sprite hardware does the DS have?http://answers.drunkencoders.com/what-sort-of-sprite-hardware-does-the-ds-have/ http://answers.drunkencoders.com/what-sort-of-sprite-hardware-does-the-ds-have/#comments Sat, 25 Aug 2012 19:48:16 +0000 http://answers.drunkencoders.com/?p=164 What follows is a very detailed look at the sprite hardware on the DS including memory and register layout and a listing of basic libnds functions dealing with sprites. This post is a bit technical and does not need to be understood before moving on to the sprite examples (in fact, an argument can be made that it is best to skip all but the overview until you have gotten a sprite or two to display).

Overview

Keep in mind the DS has two distinct 2D graphics cores which each handle one screen. The main engine and the sub engine have few differences. We will focus on the main engine in this discussion and point out any differences we encounter along the way. Recall, that the engines do not imply a specific physical screen as either engine can be used to control either the top or bottom screen.

To begin, each core is capable of controlling 128 independent sprite objects which share a common graphics and palette memory.

Each object can have a rotation, blend, or mosaic applied (although not strictly independently as we shall see).

Each sprite can be one of 3 color formats: 256-color paletted, 16-color paletted, or 16-bit direct color bitmap.

Each sprite can be one of the following pixel sizes:

SizeSquareWideTall
08×816×88×16
116×1632×88×32
264×6464×3232×64

Sprites can contain transparent pixels allowing sprites of any size or shape to be represented as long as they can fit inside one of the above boxes. If you need even larger sprites we will learn a few tricks to stretch them and combine them to create sprites of any size.

Memory Layout

Main Engine:
OAM Attributes (1KB): 0x07000000
Palette Memory (1KB): 0x05000200
Graphics Memory (256KB): 0x6400000
Extended Palette Memory: (Memory mapped so varies)

Sub Display
OAM Attributes (1KB): 0x07000400
Palette Memory (1KB): 0x05000400
Graphics Memory (128KB): 0x6600000
Extended Palette Memory: (Memory mapped so varies)

Object Attribute Memory:
Each core has what is known as Object Attribute Memory which contains the state for our 128 sprites. This state is stored in a set of 3 16-bit attributes (one set for each sprite) which control nearly every aspect of the sprite.

Attribute 0:

BitsDescription
0-7The Y coordinate of the top of the sprite
8The rotation scaling flag which determines if a scale/rotation is to be applied. The setting of this flag controls how several of the bits below are interpreted.
9Size double / hide sprite flag: When the rotation and scaling flag is set this flag will allow the sprite to double in size when a scaling or rotation is applied. When the rotation scaling flag is not set this bit will hide the sprite if set (very useful).
10-11Display mode: 0 is a normal paletted sprite, 1 is a blended sprite, 2 means the sprite is acting as an window mask, and 3 is used to specify a bitmap sprite.
12Mosaic flag: when set the mosaic will be applied
13Color depth: 0 = 16 color 1 = 256 color
14-15Object shape: 0 = Square, 1= Wide, 2 = Tall

Attribute 1:

BitsDescription
0-8The X coordinate of the top of the sprite (one more bit than Y as the screen is wider)
9-13Bits 9-13 are used to store the 5 bit index into the 32 possible rotation/scaling attributes to apply to the sprite. When the rotation and scaling flag is not set bits 9-11 are unused and bits 12 and 13 can be used to flip the sprite.
12When the rotation and scalling flag is NOT set this bit sets the horizontal flip flag, when set the sprite will be flipped horizontally. When the rotation scaling flag is set this bit is used as part of the rotation attribute selection
13When the rotation and scalling flag is NOT set this bit sets the vertical flip flag, when set the sprite will be flipped vertically. When the rotation scaling flag is set this bit is used as part of the rotation attribute selection
14-15Selects the object size (see table above)

Attribute 2:

BitsDescription
0-9Selects the offset of the start of the sprites graphics
10-11The sprite priority (what order it is drawn with respect to other sprites and backgrounds, two sprites with the same priority will be drawn in order of OAM number)
12-15Palette number when in 16-color mode or when using extended palettes in 256-color mode. These bits control the alpha blend when in bitmap mode.

Rotation and Scaling Attributes:
Following each set of 3 OAM attributes is a single 16-bit rotation and scale attribute. These 16-bit values are what is used to control the rotation and scale of a sprite. It actually takes 4 rotation attributes to describe the rotation and scale which means there are only 32 available rotations which can be applied (128 sets of oam attributes, 4 sets per set of rotation attributes, 128/4 = 32).

The layout in memory is as follows:

AddressDescription
Sprite 00x07000000Attribute 0
0x07000002Attribute 1
0x07000004Attribute 2
0x07000006Rotation 0 PA
Sprite 10x07000008Attribute 0
0x0700000AAttribute 1
0x0700000CAttribute 2
0x0700000ERotation 0 PB
Sprite 20x07000010Attribute 0
0x07000012Attribute 1
0x07000014Attribute 2
0x07000016Rotation 0 PC
Sprite 30x07000018Attribute 0
0x0700001AAttribute 1
0x0700001CAttribute 2
0x0700001ERotation 0 PD
Sprite 1260x070003F0Attribute 0
0x070003F2Attribute 1
0x070003F4Attribute 2
0x070003F6Rotation 31 PC
Sprite 1270x070003F8Attribute 0
0x070003FAAttribute 1
0x070003FCAttribute 2
0x070003FERotation 31 PD

As you may notice, each rotation attribute contains 4 values named PA, PB, PC, PD which form an affine matrix. For a complete and rather detailed description of this matrix please read the link above. Don’t pay much attention to any code presented in it, we are not going to use it as we have our own code for such things (although its perfectly fine for consumption of you so chose).

Paletted Sprites:
By selecting the appropriate bits in the attributes described above you can select either 16 color or 256 color palettes. A 16 color sprite uses half the graphics memory of a 256 color sprite which uses half the memory of a direct color bitmap sprite. By trading the number of colors for memory consumption we can make some smart decisions about the usage of DS graphics resources.

As we alluded to above, the sprite palettes are shared and we can control per sprite what color format it is in (sort of).

To display a sprite we simply load some colors into our palette then load the bitmap into sprite memory…unfortunately there is one small item left to discus and that is how the pixel data is actually stored.

Sprite pixel graphics, much like background graphics are constructed of tiles. What that means is that if you have a 16×16 sprite it is actually stored internally as 4 8×8 tiles. To translate your sprite from your graphics program to something the DS can understand we will need a tool. That tool is grit.

The tiles themselves can be stored in memory either linearly for each sprite (known as 1D mapping) or they can be stored in a 2D grid of 32×32 tiles in 16-color mode or 16×32 tiles in 256-color mode (2D mapping). There are few uses for 2D mapping and it makes it rather challenging to organize your graphics so we are pretty much going to let it go at that and stick to 1D mapping.

The offset from attribute 2 is used to specify where in memory the first tile of the sprite graphics reside. How we calculate that depends on another setting in the main video display control register. This setting determines the stride between starting tiles for sprites and can be 32 bytes, 64, 128 or 256. This setting allows you to reach all of sprite graphics memory by a single 9 bit offset stored in attribute 2. Location will be: Start of graphics memory + offset * stride.

Extended Palettes
You can enable extended palette memory for both backgrounds and sprites globally (for each engine). Once this is done you will have access to 16 256-color palettes for your sprite. Normal sprite palette memory will be ignored in this case. Extended palettes take a bit more work to set up and manipulate but it is enough for now to know we have to allocate a VRAM bank to them and we can only load palette data into that bank when it is unmapped.

Bitmap Sprites:
The DS also allows for direct color bitmap sprites. These are very useful not only because they allow the full range of color in your sprite but also because they allow you to specify an alpha blend value in the unused bits that normally specify the palette index to use. In this mode each pixel is a 15 bit color value with the most significant bit an alpha flag. This alpha flag is how you specify a transparent pixel (0 means transparent, 1 means draw it).

There is no palette so the only issue is how to store the sprite graphics data in memory. In bitmap mode sprite graphics are not tiled but stored as a linear bitmap. When in 1D mapping mode each sprite graphic is stored sequentially and the offset is simply offset * stride (where stride is 128 or 256).

In 2D mode the sprite graphics memory is treated as a single large bitmap that is 128 or 256 pixels wide. The offset gets split into a 5 bit X and a 4 bit Y value (or 4 bit X and 5 bit Y depending on the chosen stride). You specify the x and y of the top left corner of your sprite in the large bitmap (divided by 16).

That is it for our sprite technical overview. For a more in-depth look at these features be sure to check out the examples.

]]>
http://answers.drunkencoders.com/what-sort-of-sprite-hardware-does-the-ds-have/feed/ 0