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.

Coding > text background tile set

#4521 - Ninj4D4n - Wed Apr 02, 2003 3:19 pm

Hey all

I have no problem working with rotational backgrounds, but some stuff with text backgrounds is giving me trouble.

I'm currently trying to render a full screen image as a background. The problem is that the image when broken up into tiles, is made of 600 different tiles. This means there's too many to load into a character base block for use with a rot background (max 256 right?).

Well, i've seen it stated (and by the indexing in text backgrounds), that a text background can handle up to 1024 tiles.
So my questions are:
1) Wouldn't 1024 tiles fill all four character base blocks leaving no room to put a map into a screen base block?
2) If i want to use all 600 tiles, do i just load them up, in order, into character 2 character base blocks. Then i can just index to them with 0-599?
3) Is there any other issues i should be aware of?

Thanks in advance,
Ninj4D4n

#4526 - Quirky - Wed Apr 02, 2003 4:26 pm

1024 tiles would fill:

1024 * 8 *8 = 65536 bytes.

If you have your character (tile) base at 0x6000000 (char base 0 out of a possible 0-3) and your screen (map) base at 31 (of 31, or 0x600F800 in memory terms) then you have 0xF800 bytes of tile data to use up for tiles - or 63488 bytes in decimal. Therefore with your 1024 tiles, the last few would blitz your map data.

So the maximum realistic number of tiles you could get away with (256 colours) is 992. I reckon anyway.

If you use 4 bits per pixel, you can double that quantity.

#4537 - Ninj4D4n - Wed Apr 02, 2003 8:02 pm

Thanks Quirky, thought i had made a calculation error.

So now if want to use the tile data:
Say i stored 992 tiles like you said, with my map in the last SBB. Now my background should be set to character base block 0, screen base block 31, and my availbe index range is 0-991?

--Ninj4D4n

#4546 - peebrain - Thu Apr 03, 2003 12:10 am

Umm... it has 1024 so you can address 1024 tiles while in 16-color mode. I'm pretty sure that in 256-color mode you can only use 512 tiles (0, 2, 4, 6, 8, ..., 1020, 1022)... Or maybe I'm thinking of sprites?

~Sean
_________________
http://www.pbwhere.com

#4547 - tepples - Thu Apr 03, 2003 12:52 am

peebrain wrote:
in 256-color mode you can only use 512 tiles (0, 2, 4, 6, 8, ..., 1020, 1022)... Or maybe I'm thinking of sprites?

That's sprites.

In 16-color text mode, a background can address up to 1024 tiles spanning 32 KB, or two of the four pattern tables. A full-screen image including the map will just barely fit in 20 KB.

In 256-color text mode, a background can address up to 1024 tiles spanning 64 KB, or all four pattern tables.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#4560 - Ninj4D4n - Thu Apr 03, 2003 2:24 pm

Hey, thanks alot for all the the comments guys, it really cleared some stuff up for me, but for some reason i'm still getting an error in my image. Here's the code i'm using:

[code]
#ifndef INTRO_H
#define INTRO_H

#include "Ninja/NinjaBGPalette.h"
#include "Ninja/NinjaTiles.h"
#include "Ninja/ForestMap.h"


void Intro1(void)
{
SetMode(MODE_0 | OBJ_MAP_1D);

//setup background info
Background Back1;
Back1.number = 0;
Back1.colorMode = BG_COLOR_256;
Back1.size = TEXTBG_SIZE_256x256;
Back1.charBaseBlock = 0;
Back1.screenBaseBlock = 29;
Back1.x_scroll = 0;
Back1.y_scroll = 0;

LoadBGPalette((u16*)NinjaBGPalette);
LoadTileData(0, (u16*)NinjaTilesData, NinjaTiles_WIDTH, NinjaTiles_HEIGHT);
LoadTextMapData(29, (u16*)ForestMap, 32, 32);

REG_BG0HOFS = Back1.x_scroll;
REG_BG0VOFS = Back1.y_scroll;
EnableBackground(&Back1);
int x;

while(1)
{
if(!(*KEYS & KEY_UP)) //if the up key is pressed
{
Back1.y_scroll++;
}
if(!(*KEYS & KEY_DOWN)) //if the up down is pressed
{
Back1.y_scroll--;
}
if(!(*KEYS & KEY_LEFT)) //if the up left is pressed
{
Back1.x_scroll--;
}
if(!(*KEYS & KEY_RIGHT)) //if the up left is pressed
{
Back1.x_scroll++;
}

WaitForVsync();
for(x = 0; x < 10000; x++)
{}

REG_BG0HOFS = Back1.x_scroll;
REG_BG0VOFS = Back1.y_scroll;
}
}
[/code]

and:
[code]
#ifndef BGS
#define BG0_ENABLE 0x100
#define BG1_ENABLE 0x200
#define BG2_ENABLE 0x400
#define BG3_ENABLE 0x800
#define OBJ_ENABLE 0x1000
#endif


//Background defines -- BGCNT defines
#define BG_MOSAIC_ENABLE 0x40
#define BG_COLOR_256 0x80
#define BG_COLOR_16 0x0
//macros to point to mememory
#define CharBaseBlock(n) (((n)*0x4000)+0x6000000)
#define ScreenBaseBlock(n) (((n)*0x800)+0x6000000)

#define CHAR_SHIFT 2
#define SCREEN_SHIFT 8
#define TEXTBG_SIZE_256x256 0x0
#define TEXTBG_SIZE_256x512 0x8000
#define TEXTBG_SIZE_512x256 0x4000
#define TEXTBG_SIZE_512x512 0xC000

#define ROTBG_SIZE_128x128 0x0
#define ROTBG_SIZE_256x256 0x4000
#define ROTBG_SIZE_512x512 0x8000
#define ROTBG_SIZE_1024x1024 0xC000

#define WRAPAROUND 0x1


//structure for a background
class Background
{
public:
u16* tileData;
u16* mapData;
u8 mosaic;
u8 colorMode;
u8 number;
u16 size;
u8 charBaseBlock;
u8 screenBaseBlock;
u8 wraparound;
s16 x_scroll,y_scroll;

int angle;
int center_x, center_y;
FIXED zoom;

s32 DX,DY;
s16 PA,PB,PC,PD;
};

//load the background palette with colors
void LoadBGPalette(u16* colors)
{
int x;
for(x = 0; x < 256; x++)
BGPalette[x] = colors[x];
}

//loads tiles to character block CBB, needs width and height
//to load correct amount of data;
void LoadTileData(u16 CBB, u16* tiles, int tileWidth, int tileHeight)
{
int x;
u16* tempBlock = (u16*)CharBaseBlock(CBB);
for(x = 0; x < tileWidth*tileHeight/2 ; x++)
tempBlock[x] = tiles[x];
}

//Load a text map (wxh) to screen base block SBB
void LoadTextMapData(u8 SBB, u16* map, int Width, int Height)
{
int x;
u16* tempBlock = (u16*)ScreenBaseBlock(SBB);
for(x = 0; x < Width*Height; x++)
tempBlock[x] = map[x];
}

//load a rot map(wxh) to screen base block SBB;
void LoadRotMapData(u8 SBB, u8* map, int Width, int Height)
{
int x;
u16* tempBlock = (u16*)ScreenBaseBlock(SBB);
u16* tempMap = (u16*)map;
for(x = 0; x < Width*Height/2; x++)
tempBlock[x] = map[x];
}

//turns on a background
void EnableBackground(Background* bg)
{
u16 temp;

bg->tileData = (u16*)CharBaseBlock(bg->charBaseBlock);
bg->mapData = (u16*)ScreenBaseBlock(bg->screenBaseBlock);
temp = bg->size | (bg->charBaseBlock<<CHAR_SHIFT) | (bg->screenBaseBlock<<SCREEN_SHIFT)
| bg->colorMode | bg->mosaic | bg->wraparound | bg->number;

switch(bg->number)
{
case 0:
{
REG_BG0CNT = temp;
REG_DISPCNT |= BG0_ENABLE;
}break;
case 1:
{
REG_BG1CNT = temp;
REG_DISPCNT |= BG1_ENABLE;
}break;
case 2:
{
REG_BG2CNT = temp;
REG_DISPCNT |= BG2_ENABLE;
}break;
case 3:
{
REG_BG3CNT = temp;
REG_DISPCNT |= BG3_ENABLE;
}break;

default:break;

}
}
[/code]


Now my image loads, but it looks wrong. It appears to be shifted up by half the screen. and in the horizontal middle, it is split so that the right side is shifted up one tile square. If i scroll the background down, what's above what i can initially see is garbage. I've checked my palette, tile set, and map data over and over again, and it looks fine. The map uses 600 tiles arranged to cover the screen (any tile of the background that should be offscreen is just one of the 600).

I'll try and get a picture later today, i'm running out the door right now, but if anybody can see where i'm making a mistake that would be real helpful.

Thanks again for all the help
--Ninj4D4n