-- Super Mario Bros. 2 USA - Grids & Contents (Unfinished) -- Super Mario Bros. 2 (U) (PRG0) [!].nes -- Written by QFox -- 31 July 2008 -- shows (proper!) grid and contents. disable grid by setting variable to false -- shows any non-air grid's tile-id -- Slow! Will be heavy on lighter systems local angrybirdo = false; -- makes birdo freak, but can skew other creatures with timing :) local drawgrid = true; -- draws a green grid local function box(x1,y1,x2,y2,color) -- gui.text(50,50,x1..","..y1.." "..x2..","..y2); if (x1 > 0 and x1 < 0xFF and x2 > 0 and x2 < 0xFF and y1 > 0 and y1 < 239 and y2 > 0 and y2 < 239) then gui.drawbox(x1,y1,x2,y2,color); end; end; local function text(x,y,str) if (x > 0 and x < 0xFF and y > 0 and y < 240) then gui.text(x,y,str); end; end; local function toHexStr(n) local meh = "%X"; return meh:format(n); end; while (true) do if (angrybirdo and memory.readbyte(0x0010) > 0x81) then memory.writebyte(0x0010, 0x6D); end; -- birdo fires eggs constantly :p -- px = horzizontal page of current level -- x = page x (relative to current page) -- rx = real x (relative to whole level) -- sx = screen x (relative to viewport) local playerpx = memory.readbyte(0x0014); local playerpy = memory.readbyte(0x001E); local playerx = memory.readbyte(0x0028); local playery = memory.readbyte(0x0032); local playerrx = (playerpx*0xFF)+playerx; local playerry = (playerpy*0xFF)+playery; local playerstate = memory.readbyte(0x0050); local screenoffsetx = memory.readbyte(0x04C0); local screenoffsety = memory.readbyte(0x00CB); local playersx = (playerx - screenoffsetx); if (playersx < 0) then playersx = playersx + 0xFF; end; local playersy = (playery - screenoffsety); if (playersy < 0) then playersy = playersy + 0xFF; end; if (playerstate ~= 0x07) then box(playersx, playersy, playersx+16, playersy+16, "green"); end; if (memory.readbyte(0x00D8) == 0) then -- not scrolling vertically -- show environment -- i have playerrx, which is my real position in this level -- i have the level, which is located at 0x6000 (the SRAM) -- each tile (denoted by one byte) is 16x16 pixels -- each screen is 15 tiles high and about 16 tiles wide -- to get the right column, we add our playerrx/16 to 0x6000 -- to be exact: -- 0x6000 + (math.floor(playerrx/16) * 0xF0) + math.mod(playerx,0x0F) local levelstart = 0x6000; -- start of level layout in RAM -- ok, here we have two choices. either this is a horizontal level or -- it is a vertical level. We have no real way of checking this, but -- luckily levels are either horizontal or vertical :) -- so there are three possibilities -- 1: you're in 0:0, no worries -- 2: you're in x:0, you're in a horizontal level -- 3: you're in 0:y, you're in a vertical level local addleftcrap = math.mod(screenoffsetx,16)*-1; -- works as padding to keep the grid aligned local leftsplitrx = (memory.readbyte(0x04BE)*0x100) + (screenoffsetx + addleftcrap); -- column start left. add addleftcrap to iterative stuff to build up local addtopcrap = math.mod(screenoffsety,15); -- works as padding to keep the grid aligned local columns = math.floor(leftsplitrx/16); -- column x of the level is on the left side of the screen if (drawgrid) then -- print grid? for i=0,15 do -- text(addleftcrap+(i*16)-1, 37, toHexStr(columns+i)); -- print colnumber in each column for j=0,17 do box(addleftcrap+(i*16), addtopcrap+(j*16), addleftcrap+(i*16)+16, addtopcrap+(j*16)+16, "green"); -- draw green box for each cell end; end; end; -- 42=mushroom if you go sub -- 45=small -- 44=big -- 49=subspace -- 6c=pow -- 4e=cherry local topsplitry = (screenoffsety); -- starting page (might flow into next page). if the number of columns -- is > 16, its a horizontal level, else its a vertical level. in either -- case, the other will not up this value. local levelpage = levelstart + ((math.floor(columns/16))*0xF0) + (memory.readbyte(0x00CA)*0x100) + topsplitry; local levelcol = math.mod(columns,16); -- this is our starting column --text(10,150,toHexStr(topsplitry).." "..toHexStr(levelcol).." "..toHexStr(levelpage+levelcol).." "..toHexStr(leftsplitrx)); for j=0,15 do -- 16 columns if (levelcol + j > 15) then -- go to next page levelpage = levelpage + 0xF0; levelcol = -j; end; for i=0,14 do -- 15 rows local tile = memory.readbyte(levelpage+(levelcol+j)+(i*0x10)); if (tile ~= 0x40) then text(-2+addleftcrap+(j*16),5+(i*16),toHexStr(tile)); end; end; end; end; -- not scrolling if -- print some generic stats text(2,10,"x:"..toHexStr(screenoffsetx)); text(2,25,"y: "..toHexStr(screenoffsety)); text(230,10,memory.readbyte(0x04C1)); text(100,10,"Page: "..playerpx..","..playerpy); text(playersx,playersy,playerrx.."\n"..playery); -- draw enemy info local startpx = 0x0015; local startpy = 0x001F; local startx = 0x0029; local starty = 0x0033; local drawn = 0x0051; local type = 0x0090; for i=0,9 do local estate = memory.readbyte(drawn+i); if (estate ~= 0) then local ex = memory.readbyte(startx+i); local epx = memory.readbyte(startpx+i); local ey = memory.readbyte(starty+i); local epy = memory.readbyte(startpy+i); local erx = (epx*0xFF)+ex; local ery = (epy*0xFF)+ey; local esx = (ex - screenoffsetx); if (esx < 0) then esx = esx + 0xFF; end; local esy = (ey - screenoffsety); if (esy < 0) then esy = esy + 0xFF; end; --text(10, 20+(16*i), i..": "..esx.." "..erx); -- show enemy position list -- show enemy information if ((erx > playerrx-127) and erx < (playerrx+120)) then --text(esx,esy,erx); -- show level x pos above enemy local wtf = "%X"; text(esx,esy,wtf:format(memory.readbyte(type+i))); -- show enemy code if (estate == 1 and i < 5) then box(esx, esy, esx+16, esy+16, "red"); else box(esx, esy, esx+16, esy+16, "blue"); end; end; end; end; -- enemy info FCEU.frameadvance(); end;