Sign in to follow this  

[GBA] Tiled mode not working correctly

This topic is 4280 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm working on a GBA project for school, and I have a problem which appears to be nasty. I made a 8x8 tile, pure green by black lines on the sides. I then used gfx2gba to convert it. It converted properly:
const unsigned char tiles_Tiles[64] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

The palette has 2 entries: 0x0000 and 0x0200(I'll leave it out for convenience). I then made a map of 512 entries that ONLY uses tile 1(I think you're imaginative enough to cough that one up :P). Now, I copied the code from the book you can find on JHarbour.com. It took this code as a start, as it would be much more convenient to use. I load all the data, but it appears to be copying the data incorrectly, as this is what I see when I run the game: As you can see, the tile appears to be shifted partially(If you look at the top left image). I tried a whole load of different things, but I'm out of ideas, so I'm wondering if someone could point me out what I am doing wrong:
#include <stdlib.h>
#include "dma.h"
#include "video.h"
#include "zelda.h"

//#include "tiles.map.c"
#include "tiles.raw.c"
#include "tiles.pal.c"

unsigned short *VideoBuffer;
unsigned short *Palette;

//scrolling registers for background 0
#define REG_BG0HOFS *(volatile unsigned short*)0x4000010
#define REG_BG0VOFS *(volatile unsigned short*)0x4000012

//background setup registers and data
#define REG_BG0CNT *(volatile unsigned short*)0x4000008
#define REG_BG1CNT *(volatile unsigned short*)0x400000A
#define REG_BG2CNT *(volatile unsigned short*)0x400000C
#define REG_BG3CNT *(volatile unsigned short*)0x400000E
#define BG_COLOR256 0x80
#define CHAR_SHIFT 2
#define SCREEN_SHIFT 8
#define WRAPAROUND 0x1
#define BG_MOSAIC_ENABLE 0x40

//background tile bitmap sizes
#define TEXTBG_SIZE_256x256 0x0
#define TEXTBG_SIZE_256x512 0x8000
#define TEXTBG_SIZE_512x256 0x4000
#define TEXTBG_SIZE_512x512 0xC000

//background memory offset macros
#define CharBaseBlock(n) (((n)*0x4000)+0x6000000)
#define ScreenBaseBlock(n) (((n)*0x800)+0x6000000)

//background mode identifiers
#define BG0_ENABLE 0x100
#define BG1_ENABLE 0x200
#define BG2_ENABLE 0x400
#define BG3_ENABLE 0x800

//video identifiers
#define BGPaletteMem ((unsigned short*)0x5000000)
#define SetMode(mode) REG_DISPCNT = (mode)

//vertical refresh register
#define REG_DISPSTAT *(volatile unsigned short*)0x4000004

//button identifiers
#define BUTTON_RIGHT 16
#define BUTTON_LEFT 32
#define BUTTON_UP 64
#define BUTTON_DOWN 128
#define BUTTONS (*(volatile unsigned int*)0x04000130)

// Registers used for rotation and scaling
#define REG_BG2X *(volatile unsigned int*)0x4000028
#define REG_BG2Y *(volatile unsigned int*)0x400002C
#define REG_BG2PA *(volatile unsigned short *)0x4000020
#define REG_BG2PB *(volatile unsigned short *)0x4000022
#define REG_BG2PC *(volatile unsigned short *)0x4000024
#define REG_BG2PD *(volatile unsigned short *)0x4000026

// registers for size and rotation
#define ROTBG_SIZE_128x128 0x0
#define ROTBG_SIZE_256x256 0x4000
#define ROTBG_SIZE_512x512 0x8000
#define ROTBG_SIZE_1024x1024 0xC000

void WaitVBlank(void)
{
	while((REG_DISPSTAT & 1));
}

const unsigned char tiles_Map[512] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2
};

int main(void)
{
	int x = 0, y = 0;
	int n;

	//create a pointer to background 0 tilemap buffer
	unsigned short* bg0map =(unsigned short*)ScreenBaseBlock(31);

	//set video mode 0 with background 0
	SetMode(0 | BG0_ENABLE);

	//set up background 0
	REG_BG0CNT = BG_COLOR256 | TEXTBG_SIZE_256x256 | (31 << SCREEN_SHIFT) | WRAPAROUND;

	//copy the palette into the background palette memory
	DMAFastCopy((void*)tiles_Palette, (void*)BGPaletteMem, 256, DMA_16NOW);

	//copy the tile images into the tile memory
	DMAFastCopy((void*)tiles_Tiles, (void*)CharBaseBlock(0), 64 / 4, DMA_32NOW);

	//copy the tile map into background 0
	DMAFastCopy((void*)tiles_Map, (void*)bg0map, 512, DMA_32NOW);

	//main game loop
	while(1)
	{
		//wait for vertical refresh
		WaitVBlank();

		//D-pad moves background
		if(!(BUTTONS & BUTTON_LEFT)) x--;
		if(!(BUTTONS & BUTTON_RIGHT)) x++;
		if(!(BUTTONS & BUTTON_UP)) y--;
		if(!(BUTTONS & BUTTON_DOWN)) y++;

		//use hardware background scrolling
		REG_BG0VOFS = y ;
		REG_BG0HOFS = x ;

		//wait for vertical refresh
		WaitVBlank();
		for(n = 0; n < 4000; n++);
	}

	return 0;
}

Toolmaker

Share this post


Link to post
Share on other sites
I'll take a look at your code at lunch (in an hour), but in case you see this before then: the screen seems to not be entirely full with the same tile. Do you also have an empty tile? Do you set the value of the screen entries to 0? One tile entry in the screen is 2byte normally (depending on mode), have you taken that into account?

If you're using an empty tile in addition to the one you described, could you clear the memory of the screen, and only set the first tile to use tiledata 1?

In VBA I think you can show memory addresses, can you show the contents of where the tiledata and screen data is stored? (I'm not sure where exactly, you'd have to look that up.

Edit:
I've taken a look at your code. The only error I could find is that for TextBG's you need 2 bytes two specify one tile (as I already mentioned), so you're actually only copy enough info for 256 tiles. If you change the type of tiles_Map to u16 that should be fixed (and of course upload the correct amount).

[Edited by - rick_appleton on March 28, 2006 8:58:46 AM]

Share this post


Link to post
Share on other sites

This topic is 4280 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this