Language…
16 users online:  Atari2.0, DanMario24YT, derv82, drkrdnk, eltiolavara9, h.carrell, Isikoro, masl, Maw, MorrieTheMagpie, Red2010, Serena, Shomi, sinseiga, sparksplit-smw, steelsburg - Guests: 287 - Bots: 327
Users: 64,795 (2,375 active)
Latest user: mathew

Trying to read all tiles on a level

I'm trying to read all 'walkable' tiles and other tiles from the game inside a LUA script.

So basically I want to be able to find the 'tile' (Or whatever indicates if a block can be stood on by mario or not) at say X 1 and Y 1.

Following this thread, I wrote code that looks like this:

Code
function getTileAtLocation(x, y)
	return memory.readbyte(0x1C800 + bit.band(x, 0xF, AND) + bit.lshift(y, 4) + (bit.band(x, 0x1FF0, AND) * 27))
end


It seems to give me reasonable values, however I compared them to the players Location found using memory addresses (0x94, 0x96) and it does not seem to make sense. For example, it says a tile is below & above the player when it should just be below, like at the beginning of Yoshi's island 2.

Sethbling's code (mentioned in the linked post) works, but I cannot understand it. For example, it adds 8 to X, and multiplies & divides the values by 16 (Maybe tiles are 16 in length?) I also cannot find 1C8 memory address in the SMW memory map:

Code
function getTile(dx, dy)
	x = math.floor((dx+8)/16)
	y = math.floor((dy)/16)
	
	local byteToReadAddress = 0x1C800 + math.floor(x/0x10)*0x1B0 + y*0x10 + x%0x10
	
	return memory.readbyte(byteToReadAddress)
end

-- How the function is used, create an overlay 'map', which is what I want to do eventually
programView = 6
for dx=-programView*16, programView*16, 16 do
  for dy=-programView*16, programView*16, 16 do
    tile = getTile(dx, dy)
  end
end


Again SethBling's code works, and the values seem right based on Mario position, assuming Mario is 32 [pixels?] tall, a block 15 high is below him, and none above as expected. But I don't feel comfortable using it in my project without understanding the calculation. Why multiply the X (a decimal value) by 1B0, then add the Y value and then add x %0x10?
Hey! I have a utility script for SMW, it has a tile map feature, give a try.

Search for the "get_map16_value" function, it has the math i use for both horizontal and vertical levels.

As for the math SethBling used, the +8 to X is just to get a centered position of Mario, and dividing by 16 is because tiles are 16 pixels wide. In the RAM map you need to look for $7EC800 and $7FC800.
Glitch hunter, RAM eater, pseudo-TASer.
Scripts, documentations, and misc: SMW stuff on Github, YI stuff on Github, The Flintstones stuff on Github
Stuff and me: YouTube, Twitter
Originally posted by BrunoValads
Hey! I have a utility script for SMW, it has a tile map feature, give a try.

Search for the "get_map16_value" function, it has the math i use for both horizontal and vertical levels.

As for the math SethBling used, the +8 to X is just to get a centered position of Mario, and dividing by 16 is because tiles are 16 pixels wide. In the RAM map you need to look for $7EC800 and $7FC800.


Thanks for the reply! Your code will prove useful for what I'm trying to do.

Given the code snippet:
Code
num_id = 16*27*floor(num_x/16) + 16*num_y + num_x%16


Why do you multiply by 27?

Also why is 'kind' multiplied by 256?
Code
kind = 256*u8(0x1c800 + num_id) + u8(0xc800 + num_id)