[solved] Text Backgrounds

spectre1989
Posts: 24
Joined: Tue Jun 23, 2009 7:19 pm

[solved] Text Backgrounds

Post by spectre1989 » Thu Jun 25, 2009 2:17 pm

OK a couple of questions, I think I'm getting a bit confused.

Am I right in thinking that the vram banks are kind of like slots, and you plug memory into the banks (like some background of some description), and then behind the scenes libnds tells the DS 2D engine to display that bank?

Anyway the main thing I'm asking, is how to create a custom font for printing. I was intending to create my own console class, and have a print function that would just take sprintf to produce the string and then run through character by character and copy the needed character tile onto the background. I assume for this I would use the first 96kb for the 256x192px screen, and then the remaining 32kb for the tiles? Is it only frame buffer mode in which I can set things pixel by pixel, or do I have to use memcpy or some such? Sorry I'm probably barking up many wrong trees here, but just trying to get my head around things, never programmed for a console in this way!

Cheers
Spec
Last edited by spectre1989 on Sat Jun 27, 2009 5:58 am, edited 1 time in total.

StevenH
Posts: 133
Joined: Sun Feb 22, 2009 7:59 pm

Re: Text Backgrounds

Post by StevenH » Thu Jun 25, 2009 3:11 pm

There's a few ways of doing what you are attempting to do:

1. Use grit to convert an 8x8 grid of tiles into a tile format that the libnds console uses - this is covered in the custom font example.
2. Write your own console application that outputs pixels in the shape of your font glyph on a bitmap or framebuffer mode.
3. Interface with the current iprintf code (i.e. write a printchar() function, and a couple of others) and use the console code that WinterMute and dovoto created.

I have, and still am, creating a new console for my own projects that uses the third option to create a console that can work in all 3 output modes - tile, bitmap and sprite. I'm still at the design phase for the new all-in-one console, but I did do a graphical console which you can download the source for from my blog : http://www.stevensprogsite.co.uk (click on the NDS Projects then the Graphical Console link)

An example screen:
Image

I've got some other graphical console stuff done as well, but I can not find the screen shots at the moment.

spectre1989
Posts: 24
Joined: Tue Jun 23, 2009 7:19 pm

Re: Text Backgrounds

Post by spectre1989 » Thu Jun 25, 2009 3:37 pm

Cheers for the info there, I didn't realise there was already a custom font example. 2 things I don't understand, what do the map and tile bases refer to? I read the tutorial on loading a bitmap file which involved loading the palette, which if I understand correctly is basically a table of 256 colours so a pixel in the bitmap can be stored with a single byte, however I'm unsure as to how the palettes and "map"s are used?

Edit: Found the tutorial on tiles and maps, if I have any questions after that then I'll post them, but for now consider it "solved".

spectre1989
Posts: 24
Joined: Tue Jun 23, 2009 7:19 pm

Re: Text Backgrounds

Post by spectre1989 » Thu Jun 25, 2009 6:24 pm

OK so I read the tiles tutorial, and now I get that maps are generally stored first and must fall within the first 64k of background memory, and the tile sets are stored second and must fall within the first 256k of memory, and a map is just a lookup table of tiles. What I don't understand is where in memory the background palette is stored?

RyouArashi
Posts: 29
Joined: Sun Mar 29, 2009 9:23 pm

Re: Text Backgrounds

Post by RyouArashi » Thu Jun 25, 2009 8:36 pm

For tiles it is 512K on Main BGs and 128K on Sub BGs.

Palettes are either stored at BG_PALETTE and BG_PALETTE_SUB (fixed, doesnt have to be mapped)
or separate VRAM banks if extended palettes are used (see http://www.dev-scene.com/NDS/NDS_Tutorials_VramTable). If extended palettes are used, every BG has its own palette, if not all BGs share the same palette.

spectre1989
Posts: 24
Joined: Tue Jun 23, 2009 7:19 pm

Re: Text Backgrounds

Post by spectre1989 » Thu Jun 25, 2009 9:56 pm

I thought each tile could map to a different palette for example? Or is that with extended palettes? Oh and how much memory is there to play with in BG_PALETTE?

RyouArashi
Posts: 29
Joined: Sun Mar 29, 2009 9:23 pm

Re: Text Backgrounds

Post by RyouArashi » Fri Jun 26, 2009 10:47 am

If you use extended palettes, each BG layer gets 16 palettes of 256 colors (4k colors total) to use. Each tile can be assigned one of these inside the map entry (theres a macro called something like TILE_PALETTE(n) which is or'd to the tile index).

The default palettes are 512 Bytes (256 x 16bit color entries) per screen and are used by all BG layers at once.

spectre1989
Posts: 24
Joined: Tue Jun 23, 2009 7:19 pm

Re: Text Backgrounds

Post by spectre1989 » Fri Jun 26, 2009 7:07 pm

OK I'm still failing pretty epicly at this. Here's my code:

Code: Select all

#ifndef _INTRO_H_
#define _INTRO_H_

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

#include "ContentLoader.h"

class Intro
{
	int m_hbg;
public:
	Intro()
	{
	}

	~Intro()
	{
	}

	void run(void)
	{
		// Set up top screen to display some text
		videoSetMode( MODE_0_2D );
		vramSetBankA( VRAM_A_MAIN_BG );
		m_hbg = bgInit( 0, BgType_Text8bpp, BgSize_T_256x256, 0,1);
		
		// Find the file
		FILE* fontFile = fopen("/fonts/font.bmp","rb");
		if(!fontFile)
		{
			consoleDemoInit();
			iprintf("Failed to open file\n");
		}

		// Load the bitmap
		BmpFile* bmp = ContentLoader::loadBitmap(fontFile);

		// Close file
		fclose(fontFile);

		//copy the palette	
		for(unsigned int i = 0; i < bmp->info.numColors; i++)
		{
			BG_PALETTE[i] = RGB15(bmp->colors[i].red >> 3, bmp->colors[i].green >> 3, bmp->colors[i].blue >> 3);
		}

		// copy image into tile memory
		swiCopy(bmp->image, BG_TILE_RAM(1), 96*64); // This happens to be a vertical strip of 96 8x8 characters

		// clear the memory
		delete[] bmp->colors;
		delete[] bmp->image;
		delete bmp;

		// Test
		u16* map = (u16*)BG_MAP_RAM(0);
		for(int i = 0; i < 32 * 32; i++)
			map[i] = 20;
	}
};

// And the contentloader.h code..
#ifndef _CONTENTLOADER_H_
#define _CONTENTLOADER_H_

#define PACKED_STRUCT __attribute__ ((packed))

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

typedef struct
{
	u8 red;
	u8 green;
	u8 blue;
	u8 reserved;
}PACKED_STRUCT RGB;

typedef struct
{
	char signature[2];
	unsigned int fileSize;
	unsigned int reserved;
	unsigned int offset;
}PACKED_STRUCT 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;
	
}PACKED_STRUCT BmpImageInfo;

typedef struct
{
	BmpHeader header;
	BmpImageInfo info;
	RGB *colors;
	u8 *image;
}PACKED_STRUCT BmpFile;

class ContentLoader
{
public:
	static BmpFile* loadBitmap(FILE* file)
	{
		BmpFile* bmp = new BmpFile;

		// Read header and info
		fread(&bmp->header, sizeof(BmpHeader), 1, file);
		fread(&bmp->info, sizeof(BmpImageInfo), 1, file);

		// Allocate and read colour palette
		bmp->colors = new RGB[bmp->info.numColors];
		fread(bmp->colors, sizeof(RGB), bmp->info.numColors, file);
		bmp->image = new u8[bmp->info.width*bmp->info.height];

		// Read image into a buffer
		u8* buff = new u8[bmp->info.width*bmp->info.height]; 
		if(bmp->info.bitDepth == 4)
		{
			u8 temp;
			for(int i = 0; i < bmp->info.width*bmp->info.height; ++i)
			{
				fread(&temp, sizeof(u8), 1, file);
				buff[i*2] = temp >> 4;
				buff[i*2 + 1] = (temp << 4) >> 4;
			}
		}
		else
		{
			fread(buff, sizeof(u8), bmp->info.width*bmp->info.height, file);
		}
		
		bmp->image = buff;
		
		return bmp;
	}
};

#endif
Aaaargh!

RyouArashi
Posts: 29
Joined: Sun Mar 29, 2009 9:23 pm

Re: Text Backgrounds

Post by RyouArashi » Fri Jun 26, 2009 10:05 pm

You cannot directly load a bitmap into a text background. A bitmap stores the image per pixel, while text backgrounds
use tiles of 8x8 pixels.

First, you have to use pagfx or grit (havent used the latter yet, pagfx works fine for me and is easy to use) to
convert your bitmaps into tile and map data and a palette holding the colors. Then you setup the background
(bgInit) and copy the tile and map data to the appropriate map and tile block (use bgGetGfxPtr(ID) and bgGetMapPtr(ID),
where ID is the value returned by bgInit). Then load your palette to BG_PALETTE and you should see your picture on the
screen.

Have a look at the \Graphics\all_in_one example for loading text backgrounds, e.g.

Code: Select all

	videoSetMode(MODE_0_2D);
	vramSetBankA(VRAM_A_MAIN_BG);
	
	int bg = bgInit(0, BgType_Text8bpp, BgSize_T_256x256, 0,1);
	
	dmaCopy(TextBackgroundsTiles, bgGetGfxPtr(bg), sizeof(TextBackgroundsTiles));
	dmaCopy(Layer256x256Map, bgGetMapPtr(bg),  Layer256x256MapLen);
	dmaCopy(TextBackgroundsPal, BG_PALETTE, sizeof(TextBackgroundsPal));
for a standard text BG (file basic.cpp in \all_in_one)

spectre1989
Posts: 24
Joined: Tue Jun 23, 2009 7:19 pm

Re: Text Backgrounds

Post by spectre1989 » Fri Jun 26, 2009 10:18 pm

The custom font example uses a font bitmap, which is actually the same font bitmap I'm trying to load here, only in that demo they use the console functions to load it, so it must be possible. The bitmap already contains the palette, and the image as 4 bits per pixel.

I'll try using dmacopy though...

Post Reply

Who is online

Users browsing this forum: Semrush [Bot] and 56 guests