Elevator Guide to Grit

Post Reply
WinterMute
Site Admin
Posts: 1986
Joined: Tue Aug 09, 2005 3:21 am
Location: UK
Contact:

Elevator Guide to Grit

Post by WinterMute » Mon Dec 10, 2007 4:59 am

This brief guide covers using Grit to process a 256color png into palette, map & tile data for a DS game. Hopefully there's enough information here for you to figure out the rest on your own, if not, feel free to ask questions.

The standard arm9 template supplied now has rules for converting images in a folder called 'gfx' using grit. This is a fairly simple procedure.

First copy the arm9 template found in devkitPro\examples\nds\templates - on my set up I just copied the arm9 folder from c:\devkitPro\examples\nds\templates to c:\projects\nds.

Then give the folder a new name, I renamed it as 256colorTilemap - that way I have some idea of what it is later when I'm looking through the code.

Make a new folder in there called gfx and copy your 256x256 256color bitmap in there.

Now double click the .pnproj file in the template folder to load the project in Programmer's Notepad 2. We're going to create a .grit file so that grit knows what format to convert the image to - this is a simple text file containing command line arguments for grit. I've commented the options here so you know what they are, the lines beginning with # are ignored by the tool. I'm using a file called tilemap.png so this text file is saved as tilemap.grit

Code: Select all

#-------------------------------------------------------
# graphics in tile format
#-------------------------------------------------------
-gt

#-------------------------------------------------------
# tile reduction by tiles, palette and hflip/vflip
#-------------------------------------------------------
-mRtpf

#-------------------------------------------------------
# graphics bit depth is 8 (256 color)
#-------------------------------------------------------
-gB8

#-------------------------------------------------------
# map layout standard bg format
#-------------------------------------------------------
-mLs
A full list of the commands that grit understands can be found at http://www.coranac.com/man/grit/html/

Now we need to write some code to display the image so open up the main.c file and edit it to suit. I ended up with this

Code: Select all

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

	Simple tilemap demo
	-- WinterMute

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

#include "tilemap.h"

//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------

	// enable the main screen with background 0 active
	videoSetMode(MODE_0_2D | DISPLAY_BG0_ACTIVE);

	// map bank A for use with the background
	vramSetBankA(VRAM_A_MAIN_BG);
 
	// enable background 0 in 256 color mode with a 256x256 map
	// BG_TILE_BASE changes the offset where tile data is stored
	// BG_MAP_BASE gives the offset to the map data
	BGCTRL[0] = BG_TILE_BASE(0) | BG_MAP_BASE(4) | BG_COLOR_256 | TEXTBG_SIZE_256x256;

	// use dma to copy the tile, map and palette data to VRAM
	// CHAR_BASE_BLOCK gives us the actual address of the tile data
	// SCREEN_BASE_BLOCK does the same thing for maps
	// these should match the BG_TILE_BASE and BG_MAP base numbers above
	dmaCopy(tilemapPal,BG_PALETTE,tilemapPalLen);
	dmaCopy(tilemapTiles,(void *)CHAR_BASE_BLOCK(0),tilemapTilesLen);
	dmaCopy(tilemapMap,(void *)SCREEN_BASE_BLOCK(4),tilemapMapLen);

	// finally, hang around in an infinite loop
	// using swiWaitForVBlank here puts the DS into a low power loop
	while(1) {
		swiWaitForVBlank();
	}

	return 0;
}
The header file "tilemap.h" is generated by grit and can be found in the build folder. The names are generated from the filename of the bmp so, for a tiled image like this we end up with a few variables defined.

<filename>Pal - address of the palette data
<filename>PalLen - size of the palette data in bytes
<filename>Tiles - address of the tile data
<filename>TilesLen - size of he tile data in bytes
<filename>Map - address of the map data
<filename>MapLen - size of the map in bytes

If you want to use image extensions other than .png then there are a couple of sections in the Makefile you'll need to look at.

Firstly the directories that get searched for image files is defined at the top of the file, change this to use a different folder name or add additional folders.

Code: Select all

GRAPHICS	:=	gfx
Further down the file you'll see the code which searches for png files

Code: Select all

PNGFILES	:=	$(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png)))
Add a new line like this for each image extension you want to use, for instance adding .bmp files would be done as follows

Code: Select all

BMPFILES	:=	$(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.bmp)))
Then you need to specify the object files in the OFILES variable

Code: Select all

export OFILES	:=	$(addsuffix .o,$(BINFILES)) \
					$(PNGFILES:.png=.o) \
					$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
This is a simple matter of adding a translation for .bmp, like so

Code: Select all

export OFILES	:=	$(addsuffix .o,$(BINFILES)) \
					$(PNGFILES:.png=.o) \
					$(BMPFILES:.bmp=.o) \
					$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
Finally you need to specify a Makefile rule which tells make how to construct the object file from the image. You'll see the current rule for .png

Code: Select all

#---------------------------------------------------------------------------------
# This rule creates assembly source files using grit
# grit takes an image file and a .grit describing how the file is to be processed
# add additional rules like this for each image extension
# you use in the graphics folders 
#---------------------------------------------------------------------------------
%.s %.h	: %.png %.grit
#---------------------------------------------------------------------------------
	grit $< -fts -o$*
So we just need to copy the rule section and change .png to .bmp

Code: Select all

#---------------------------------------------------------------------------------
%.s %.h	: %.bmp %.grit
#---------------------------------------------------------------------------------
	grit $< -fts -o$*

It's worth reviewing the material in TONC, http://coranac.com/tonc/text/regbg.htm covers tiled backgrounds in some detail. The documentation there is all for GBA but the DS implements a superset of the GBA hardware so it's still well worth reading.

The complete project for this little example is available at https://github.com/devkitPro/nds-exampl ... lorTilemap and will be in the supplied nds examples when we do a release.
Help keep devkitPro toolchains free, Donate today

Personal Blog

User avatar
vuurrobin
Posts: 219
Joined: Fri Jul 11, 2008 8:49 pm
Location: The Netherlands
Contact:

Re: Elevator Guide to Grit

Post by vuurrobin » Mon Feb 16, 2009 10:58 pm

hello

I'm trying to get this to work, but I'm having some troubles.

first I updated the code so it worked with the current libnds, and this was the result:

Code: Select all

#include <nds.h>

#include "beerguy.h"

int main()
{
    powerOn(POWER_ALL_2D);

    // enable the main screen with background 0 active
    videoSetMode(MODE_0_2D | DISPLAY_BG0_ACTIVE);

    // map bank A for use with the background
    vramSetBankA(VRAM_A_MAIN_BG_0x06000000);

    // enable background 0 in 256 color mode with a 256x256 map
    // BG_TILE_BASE changes the offset where tile data is stored
    // BG_MAP_BASE gives the offset to the map data
    //BGCTRL[0]
    REG_BG0CNT = BG_TILE_BASE(0) | BG_MAP_BASE(4) | BG_COLOR_256 | BG_32x32; //| TEXTBG_SIZE_256x256;



    // use dma to copy the tile, map and palette data to VRAM
    // CHAR_BASE_BLOCK gives us the actual address of the tile data
    // SCREEN_BASE_BLOCK does the same thing for maps
    // these should match the BG_TILE_BASE and BG_MAP base numbers above
    dmaCopy(beerguyPal, BG_PALETTE, beerguyPalLen);
    dmaCopy(beerguyTiles, (void *)CHAR_BASE_BLOCK(0), beerguyTilesLen);
    dmaCopy(beerguyMap, (void *)SCREEN_BASE_BLOCK(4), beerguyMapLen);

    return 0;
}
next I took a picture which I had from another project, added the grit rule file (without any modifications), and modified the makefile I had so it would work with bmp files (only the png part was in the makefile). I compiled the project without any problems. but when I tried running the program on no$gba and on hardware, a small part of the image got corrupted.

here is the original image:
Image

and here is the result (created with no$gba screenshot option):
Image

seeing as more than half of the image shows up normal, I doubt the problem is in the code. I think it has something to do with grit, but I have no idea what. I already try'd disabling tile reduction, but the problem is still there (the color changed from yelow to blue tho).

can someone help me?

also, the link to the project doesn't work anymore.

nyarla
Posts: 2
Joined: Sun Jan 25, 2009 1:23 am

Re: Elevator Guide to Grit

Post by nyarla » Sun Mar 08, 2009 9:33 am

It looks like it might be because something is loaded in memory overlapping part of the image, not a problem with image conversion.. I think the corruption is the actual map data showing up as graphics.

Try changing BG_MAP_BASE and SCREEN_BASE_BLOCK to a different value, and see if the corrupt area moves around maybe..

Tron
Posts: 15
Joined: Wed Jan 20, 2010 1:01 pm
Location: USA
Contact:

Re: Elevator Guide to Grit

Post by Tron » Wed May 12, 2010 5:36 am


WinterMute
Site Admin
Posts: 1986
Joined: Tue Aug 09, 2005 3:21 am
Location: UK
Contact:

Re: Elevator Guide to Grit

Post by WinterMute » Fri Aug 18, 2017 2:45 pm

Tron wrote:The link, http://devkitpro.sourceforge.net/256colorTilemap.zip is broken, FYI.
Just been tidying things up several years later. I've added this to the examples repo now and adjusted link in the OP.
Help keep devkitPro toolchains free, Donate today

Personal Blog

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest