Dynamically modify a Map

SGDK only sub forum

Moderator: Stef

Post Reply
cloudstrifer
Very interested
Posts: 118
Joined: Mon Feb 19, 2018 7:31 pm

Dynamically modify a Map

Post by cloudstrifer » Thu Mar 31, 2022 1:06 pm

Hi.

How can modify a Map?
I want to add tiles on plan A and scroll it, but when I add a tile it disapear after scroll.
I need to modify bga Map.

Code: Select all

		Map *bgb;
		Map *bga;
		ind = TILE_USERINDEX;

		KLog_S1("ind", ind);
		bgBaseTileIndex[BG_A] = ind;
		VDP_loadTileSet(&bga_tileset, ind, CPU);
		ind += bga_tileset.numTile;	

		KLog_S1("ind2", ind);
		bgBaseTileIndex[BG_B] = ind;
		VDP_loadTileSet(&bgb_tileset, ind, CPU);
		ind += bgb_tileset.numTile;
		
		//Want to modify bga MAP bellow
		bga = MAP_create(&bga_map, BG_A, TILE_ATTR_FULL(0, FALSE, FALSE, FALSE, bgBaseTileIndex[BG_A]));
		bgb = MAP_create(&bgb_map, BG_B, TILE_ATTR_FULL(0, FALSE, FALSE, FALSE, bgBaseTileIndex[BG_B]));
		
		MAP_scrollTo(bga, 0, 0);		
		SYS_doVBlankProcess();//Needed
		MAP_scrollTo(bgb, 0, 0);
		
		
		//ADD 2 x 2 tile
		VDP_loadTileSet(barrel_tile.tileset, ind, DMA_QUEUE);
		mapA = unpackTileMap(barrel_tile.tilemap, NULL);
		VDP_setTileMapEx(BG_A, mapA, TILE_ATTR_FULL(PAL2, FALSE, FALSE, FALSE, ind), 16, 16, 0, 0, 2, 2, DMA_QUEUE);	
		ind += barrel_tile.tileset->numTile;
		MEM_free(mapA);
		
Last edited by cloudstrifer on Thu Apr 07, 2022 3:38 pm, edited 1 time in total.

cloudstrifer
Very interested
Posts: 118
Joined: Mon Feb 19, 2018 7:31 pm

Re: Dynamically modify a Map

Post by cloudstrifer » Sat Apr 02, 2022 2:49 am

Trying VDP_setMapEx :)
Last edited by cloudstrifer on Thu Apr 07, 2022 3:38 pm, edited 1 time in total.

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Dinamicaly modify a Map

Post by Stef » Sun Apr 03, 2022 4:12 pm

MAP_xxx methods aren't made for dynamic maps. If you need to modify map then indeed you will need to handle it by yourself and use lower level methods as VDP_setTileMapEx(..) :)

cloudstrifer
Very interested
Posts: 118
Joined: Mon Feb 19, 2018 7:31 pm

Re: Dynamically modify a Map

Post by cloudstrifer » Tue Apr 05, 2022 1:43 pm

Nice, I'm trying but without success.
Now using VDP_setTileMapEx, VDP_setTileMapColumnEx and VDP_setTileMapRowEx methods, from Sonic old demos.

Loading tileMap to RAM, but I don't know how to change bga TileMap.

Code: Select all

	bga = unpackTileMap(bga_image.tilemap, NULL);
	// init scrolling
	updateCameraPosition();
	updateVDPScroll();
	
	VDP_loadTileSet(barrel_tile.tileset, ind, DMA_QUEUE);
	mapA = unpackTileMap(barrel_tile.tilemap, NULL);
	VDP_setTileMapEx(BG_A, mapA, TILE_ATTR_FULL(PAL2, FALSE, FALSE, FALSE, ind), 16, 16, 0, 0, 2, 2, DMA_QUEUE);
	ind += barrel_tile.tileset->numTile;
	MEM_free(mapA);
Same result, it loads the tiles I want, but when screen scroll, it disapear and don't appears again.
Can you give me some examples?
I have search this on samples and I can't find.

Thank you Stef.

cloudstrifer
Very interested
Posts: 118
Joined: Mon Feb 19, 2018 7:31 pm

Re: Dynamically modify a Map

Post by cloudstrifer » Mon Apr 18, 2022 2:53 pm

Stef wrote:
Sun Apr 03, 2022 4:12 pm
MAP_xxx methods aren't made for dynamic maps. If you need to modify map then indeed you will need to handle it by yourself and use lower level methods as VDP_setTileMapEx(..) :)
Please.
Can you give me a litle help?

I don't know if I am on correct way.
Works baddly, as it loads 2x2 tile, its pops up on screen when you is coming from bottom or right.

Based on Sonic sample.

Code: Select all

void updateMap(VDPPlane plane, TileMap *tileMap, s16 xt, s16 yt)
{
	s16 curPosX = mapMetaTilePosX[plane];
	s16 curPosY = mapMetaTilePosY[plane];
	s16 deltaX = xt - curPosX;
	s16 deltaY = yt - curPosY;

	u8 palleteBG = PAL0;

	// no update --> exit
	if ((deltaX == 0) && (deltaY == 0))
		return;

	SYS_disableInts();

	// many row/column updates ? --> better to do a full screen update
	if ((abs(deltaX * 2) + abs(deltaY)) > 20)
	{
		VDP_setTileMapEx(plane, tileMap, TILE_ATTR_FULL(palleteBG, FALSE, FALSE, FALSE, bgBaseTileIndex[plane]),
						 xt & 0x003F, yt & 0x001F, xt, yt, 42, 30, DMA_QUEUE);
	}
	else
	{
		if (indBarrel == 0)
		{
			VDP_loadTileSet(barrel_tile.tileset, ind, DMA_QUEUE);
			mapBarrel = unpackTileMap(barrel_tile.tilemap, NULL);
			indBarrel = ind;
			ind = barrel_tile.tileset->numTile;
		}

		if (xt <= 32)
		{
			if (deltaX > 0)
			{
				// need to update map column on right
				while (deltaX--)
				{
					VDP_setTileMapColumnEx(plane, tileMap, TILE_ATTR_FULL(palleteBG, FALSE, FALSE, FALSE, bgBaseTileIndex[plane]),
										   (curPosX + 42) & 0x3F, curPosX + 42, yt, 30, DMA_QUEUE);
					if (plane == BG_A)
					{
						for (u8 i = 0; i < 30; i++)
						{
							if (groundGrid[curPosX + 42][yt + i] == OBJECT_BARREL)
							{
								VDP_setTileMapEx(BG_A, mapBarrel, TILE_ATTR_FULL(PAL2, FALSE, FALSE, FALSE, indBarrel), curPosX + 42, yt + i, 0, 0, 2, 2, DMA_QUEUE);
							}
						}
					}

					curPosX++;
				}
			}
			else if (deltaX < 0)
			{
				// need to update map column on left
				while (deltaX++)
				{
					curPosX--;
					VDP_setTileMapColumnEx(plane, tileMap, TILE_ATTR_FULL(palleteBG, FALSE, FALSE, FALSE, bgBaseTileIndex[plane]),
										   curPosX & 0x3F, curPosX, yt, 30, DMA_QUEUE);

					if (plane == BG_A)
					{
						for (u8 i = 0; i < 30; i++)
						{
							if (groundGrid[curPosX][yt + i] == OBJECT_BARREL)
							{
								VDP_setTileMapEx(BG_A, mapBarrel, TILE_ATTR_FULL(PAL2, FALSE, FALSE, FALSE, indBarrel), curPosX, yt + i, 0, 0, 2, 2, DMA_QUEUE);
							}
						}
					}
				}
			}
		}

		if (deltaY > 0)
		{
			// need to update map row on bottom
			while (deltaY--)
			{
				VDP_setTileMapRowEx(plane, tileMap, TILE_ATTR_FULL(palleteBG, FALSE, FALSE, FALSE, bgBaseTileIndex[plane]),
									(curPosY + 30) & 0x1F, xt, curPosY + 30, 42, DMA_QUEUE);

				if (plane == BG_A)
				{
					for (u8 i = 0; i < 42; i++)
					{
						if (groundGrid[xt + i][curPosY + 30] == OBJECT_BARREL)
						{
							VDP_setTileMapEx(BG_A, mapBarrel, TILE_ATTR_FULL(PAL2, FALSE, FALSE, FALSE, indBarrel), xt + i, curPosY + 30, 0, 0, 2, 2, DMA_QUEUE);
						}
					}
				}

				curPosY++;
			}
		}
		else if (deltaY < 0)
		{
			// need to update map row on top
			while (deltaY++)
			{
				curPosY--;
				VDP_setTileMapRowEx(plane, tileMap, TILE_ATTR_FULL(palleteBG, FALSE, FALSE, FALSE, bgBaseTileIndex[plane]),
									curPosY & 0x1F, xt, curPosY, 42, DMA_QUEUE);

				if (plane == BG_A)
				{
					for (u8 i = 0; i < 42; i++)
					{
						if (groundGrid[xt + i][curPosY] == OBJECT_BARREL)
						{
							VDP_setTileMapEx(BG_A, mapBarrel, TILE_ATTR_FULL(PAL2, FALSE, FALSE, FALSE, indBarrel), xt + i, curPosY, 0, 0, 2, 2, DMA_QUEUE);
						}
					}
				}
			}
		}
	}

	SYS_enableInts();

	mapMetaTilePosX[plane] = xt;
	mapMetaTilePosY[plane] = yt;
}

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Dynamically modify a Map

Post by Stef » Tue Apr 19, 2022 9:06 am

To be honest i'm checking this forum less and less as most of the support is given through my discord server where lot of people can reply :
https://discord.gg/CeJtKmyT

The sonic example won't help much here as it's still based on a Map resource even with setTileMapEx(..)
The easiest way to deal with it is to use a plain TileMap than you store in RAM (can do it through the unpackTileMap(..) method) then change the content of the tilemap but really not something very straightforward to do with SGDK.

vr3h
Newbie
Posts: 1
Joined: Sat Mar 26, 2022 11:30 am

Re: Dynamically modify a Map

Post by vr3h » Sat May 14, 2022 2:50 am

VDP_SetTileMapXX functions shouldn't work if you use the map, because the Tile Map contains only the datas that will be drawn soon.
The Tile Map size is limited to formats 128x64, 64x64, 64x128 (or lower power of 2). Those formats are in tiles. So you cannot load large levels in the Tile Map and that's why you have to use the Map structure to do it.
To keep it simple, the Map structure is just an array of tile indices which are copied onto the Tile Map depending on the scroll you set. The Tile Map is as a window scrolling over the Map.
So, if you want to modify BG_A and keep your modifications after scrolling, you have to modify the Map data array. Maybe you can look at the Map structure (your Map pointer's members) if you can access and modify those datas.

Edit : otherwise, of it's not possible, you will have to write your own Map system.

cloudstrifer
Very interested
Posts: 118
Joined: Mon Feb 19, 2018 7:31 pm

Re: Dynamically modify a Map

Post by cloudstrifer » Wed May 18, 2022 5:55 pm

Thank you!

Post Reply