Page 1 of 1

Dynamically modify a Map

Posted: Thu Mar 31, 2022 1:06 pm
by cloudstrifer
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);
		

Re: Dynamically modify a Map

Posted: Sat Apr 02, 2022 2:49 am
by cloudstrifer
Trying VDP_setMapEx :)

Re: Dinamicaly modify a Map

Posted: Sun Apr 03, 2022 4:12 pm
by Stef
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(..) :)

Re: Dynamically modify a Map

Posted: Tue Apr 05, 2022 1:43 pm
by cloudstrifer
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.

Re: Dynamically modify a Map

Posted: Mon Apr 18, 2022 2:53 pm
by cloudstrifer
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;
}

Re: Dynamically modify a Map

Posted: Tue Apr 19, 2022 9:06 am
by Stef
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.

Re: Dynamically modify a Map

Posted: Sat May 14, 2022 2:50 am
by vr3h
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.

Re: Dynamically modify a Map

Posted: Wed May 18, 2022 5:55 pm
by cloudstrifer
Thank you!