Language:
None specified     Change language:
Pastebin: 92238
Author: not qfox
Subject: smb script (not by me)
Created: 2008-07-22 17:29:00
Download and save
Toggle line numbers
1local debug = false 
2 
3-- Min & Max Y-coords for the screen. 
4local FirstSLine = 8 
5local LastSLine = 231 
6-- Utilities 
7local function clampV(v, vmin, vmax) return (v < vmin and vmin or (v <= vmax and v or vmax)) end 
8local function clampX(x) return clampV(x, 0, 255) end 
9local function clampY(y) return clampV(y, FirstSLine, LastSLine) - FirstSLine end 
10 
11local function crosshair(x, y, color) 
12        gui.drawpixel(clampX(x-1), clampY(y-1), color) 
13        gui.drawpixel(clampX(x-1), clampY(y+1), color) 
14        gui.drawpixel(clampX(x  ), clampY(y  ), color) 
15        gui.drawpixel(clampX(x+1), clampY(y-1), color) 
16        gui.drawpixel(clampX(x+1), clampY(y+1), color) 
17end 
18 
19while true do 
20 
21        while true do 
22                -- Get Mario's coords with respect to the top (right under the statusbar) of the left edge of the level/room. 
23                -- Lower 8 bits first... 
24                local x_abs = memory.readbyte(0x86) 
25                local y_abs = memory.readbyte(0xCE) - 0x20; 
26                local x_off = memory.readbyte(0x071C) -- Horizontal scroll offset 
27                local y_off = -0x20                   -- Correction for the statusbar's height 
28                -- In the game's tiny brain, the world is two screenfuls big. 
29                -- That is, levels and rooms are divided into 0x100-pixel-wide pages, with two in RAM at a time. 
30                local p_abs = memory.readbyte(0x6D) 
31                local p_off = (x_abs >= x_off and p_abs or p_abs - 1) 
32                x_abs = x_abs + 0x100* p_abs 
33                x_off = x_off + 0x100* p_off 
34                -- Determine Mario's "size" for purposes of player-tile collision checks 
35                local size 
36                if memory.readbyte(0x0714) ~= 0 or memory.readbyte(0x0754) ~= 0 then 
37                        size = 2 
38                elseif memory.readbyte(0x0704) ~= 0 then 
39                        size = 1 
40                else 
41                        size = 0 
42                end 
43                -- This determines an offset into tables: 
44                -- size -> offset table: $E3AD (just a "7*_ lookup" table) 
45                -- x-coords: $E3B0 
46                -- y-coords: $E3CC 
47                local xc = { 0x08, 0x03, 0x0c, 0x02, 0x02, 0x0d, 0x0d, 
48                             0x08, 0x03, 0x0c, 0x02, 0x02, 0x0d, 0x0d, 
49                             0x08, 0x03, 0x0c, 0x02, 0x02, 0x0d, 0x0d, 
50                             0x08, 0x00, 0x10, 0x04, 0x14, 0x04, 0x04 } 
51                local yc = { 0x04, 0x20, 0x20, 0x08, 0x18, 0x08, 0x18, 
52                             0x02, 0x20, 0x20, 0x08, 0x18, 0x08, 0x18, 
53                             0x12, 0x20, 0x20, 0x18, 0x18, 0x18, 0x18, 
54                             0x18, 0x14, 0x14, 0x06, 0x06, 0x08, 0x10 } 
55 
56                -- Draw the 6 sample points 
57                local pt 
58                for pt = 0, 6 do 
59                        local x = x_abs + xc[7*size + pt +1] - x_off 
60                        local y = y_abs + yc[7*size + pt +1] - y_off 
61                        crosshair(x, y, "#7F007F") 
62                end 
63 
64                -- Now for the blocks themselves. 
65                local page, pageptr, mincol, maxcol, row, col 
66                -- For boundary-drawing 
67                local solidOnLeft = { } 
68                local solidBelow = false 
69                local poleBelow = false -- for flagpoles or vines 
70                local id, x0, y0, x1, y1, greenBoxed, purpleBoxed 
71 
72                for page = p_off, p_off+1 do 
73                        -- Location of the page's tile data. 
74                        -- pageptr = memory.readbyte(0x9BDD+(page%2)) + 0x100* memory.readbyte(0x9BDF+(page%2)) 
75                        pageptr = (page % 2 == 0 and 0x0500 or 0x05D0) 
76                        local mincol = clampV(0x0 + math.floor(x_off / 0x10) - 0x10* page, 0x0, 0xF) 
77                        local maxcol = clampV(0xF + math.ceil (x_off / 0x10) - 0x10* page, 0x0, 0xF) 
78 
79                        for col = mincol, maxcol do 
80                                for row = 0xC, 0x0, -1 do 
81 
82                                        id = memory.readbyte(pageptr + 0x10*row + col) 
83                                        x0 = 0x00 - x_off + 0x10* col + 0x100* page 
84                                        x1 = 0x0F - x_off + 0x10* col + 0x100* page 
85                                        y0 = 0x00 - y_off + 0x10* row 
86                                        y1 = 0x0F - y_off + 0x10* row 
87                                        -- OK, we have a bounding box and a tile ID. 
88                                        -- One way to learn about the tileset is to draw every (non-empty) tile's ID: 
89                                        if id ~= 0 and debug then 
90                                                gui.drawbox(clampX(x0), clampY(y0), clampX(x1), clampY(y1), "green") 
91                                                gui.text(clampX((x0+x1-19)/2), clampY((y0+y1-9)/2), string.format("%02X", id)) 
92                                        end 
93                                        -- Instead, let's draw info an AI player would want to have... 
94                                        -- Our checks will differ from what the game engine literally does, but will functionally be the same. 
95                                        greenBoxed = false 
96                                        purpleBoxed = false 
97 
98                                        -- Classify bricks: 
99                                        if id == 0x51 or id == 0x52 or id == 0x53 then 
100                                                crosshair(x0+8, y0+8, "white") 
101                                        elseif id == 0x55 or id == 0x5A or id == 0xC1 then 
102                                                gui.text(clampX(x0+0), clampY(y0+3), "+") 
103                                        elseif id == 0x56 or id == 0x5B then 
104                                                gui.text(clampX(x0+0), clampY(y0+3), "@") 
105                                        elseif id == 0x57 or id == 0x5C then 
106                                                gui.text(clampX(x0+0), clampY(y0+3), "*") 
107                                        elseif id == 0x58 or id == 0x5D or id == 0x5F or id == 0xC0 or id == 0xC2 or id == 0xC3 then 
108                                                -- (The last two are free-floating coins, not coin bricks.) 
109                                                -- Draw a fake cent-sign: 
110                                                gui.text(clampX(x0+0), clampY(y0+3), "C") 
111                                                gui.drawline(clampX(x0+7), clampY(y0 + 4), clampX(x0+7), clampY(y1-4), "white") 
112                                        elseif id == 0x59 or id == 0x5E or id == 0x60 then 
113                                                gui.text(clampX(x0+0), clampY(y0+3), "$") 
114                                        -- Pipes: 
115                                        elseif id == 0x10 then -- Opening up, left side 
116                                                gui.drawline(clampX(x1), clampY(y0 - 0x20), clampX(x1), clampY(y1 - 0x10), "green") 
117                                                gui.drawline(clampX(x0), clampY(y0 - 0x10), clampX(x1), clampY(y1 - 0x10), "green") 
118                                        elseif id == 0x11 then -- Opening up, right side 
119                                                gui.drawline(clampX(x0), clampY(y0 - 0x20), clampX(x0), clampY(y1 - 0x10), "green") 
120                                                gui.drawline(clampX(x1), clampY(y0 - 0x10), clampX(x0), clampY(y1 - 0x10), "green") 
121                                        elseif id == 0x1C then -- Opening left, top side 
122                                                gui.drawline(clampX(x0 - 0x20), clampY(y1), clampX(x1 - 0x10), clampY(y1), "green") 
123                                                gui.drawline(clampX(x0 - 0x10), clampY(y0), clampX(x1 - 0x10), clampY(y1), "green") 
124                                        elseif id == 0x1F then -- Opening left, bottom side 
125                                                gui.drawline(clampX(x0 - 0x20), clampY(y0), clampX(x1 - 0x10), clampY(y0), "green") 
126                                                gui.drawline(clampX(x0 - 0x10), clampY(y1), clampX(x1 - 0x10), clampY(y0), "green") 
127                                        elseif id == 0x6B then -- Opening left, top side 
128                                                gui.drawline(clampX(x0 - 0x20), clampY(y1), clampX(x1 - 0x10), clampY(y1), "green") 
129                                                gui.drawline(clampX(x0 - 0x10), clampY(y0), clampX(x1 - 0x10), clampY(y1), "green") 
130                                        elseif id == 0x6C then -- Opening left, bottom side 
131                                                gui.drawline(clampX(x0 - 0x20), clampY(y0), clampX(x1 - 0x10), clampY(y0), "green") 
132                                                gui.drawline(clampX(x0 - 0x10), clampY(y1), clampX(x1 - 0x10), clampY(y0), "green") 
133                                        elseif id == 0xC5 then -- Axe: 
134                                                gui.drawbox(clampX(x0), clampY(y0), clampX(x1), clampY(y1), "green") 
135                                                greenBoxed = true 
136                                        elseif id == 0x64 then -- Cannon barrel--dangerous! 
137                                                gui.drawline(clampX(x0+1), clampY(y0+8), clampX(x1-1), clampY(y0+8), "red") 
138                                        end 
139 
140                                        if id == 0x24 or id == 0x25 or id == 0x26 then -- flagpole shaft/top or vine 
141                                                gui.drawline(clampX(x0), clampY(y0), clampX(x0), clampY(y1+1), "green") 
142                                                gui.drawline(clampX(x1), clampY(y0), clampX(x1), clampY(y1+1), "green") 
143                                                if not poleBelow then gui.drawline(clampX(x0), clampY(y1), clampX(x1), clampY(y1), "green") end 
144                                                poleBelow = true 
145                                                greenBoxed = true 
146                                        else 
147                                                if     poleBelow then gui.drawline(clampX(x0), clampY(y1), clampX(x1), clampY(y1), "green") end 
148                                                poleBelow = false 
149                                        end 
150 
151                                        if id == 0x67 or id == 0x68 then -- Springboard 
152                                                if memory.readbyte(0x070E) ~= 0 then -- With Mario on top! 
153                                                        local foot_level = y_abs - y_off + 0x20 
154                                                        y0 = math.max(y0, foot_level) 
155                                                        gui.drawline(clampX(x0), clampY(foot_level), clampX(x1), clampY(foot_level), "#CF00CF") 
156                                                elseif id == 0x67 then -- Upper half 
157                                                        gui.drawline(clampX(x0), clampY(y0), clampX(x1), clampY(y0), "#CF00CF") 
158                                                end 
159                                                if id == 0x68 then -- Lower half 
160                                                        gui.drawline(clampX(x0), clampY(y1), clampX(x1), clampY(y1), "#CF00CF") 
161                                                end 
162                                                if y0 <= y1 then 
163                                                        gui.drawline(clampX(x0), clampY(y0), clampX(x0), clampY(y1+1), "#CF00CF") 
164                                                        gui.drawline(clampX(x1), clampY(y0), clampX(x1), clampY(y1+1), "#CF00CF") 
165                                                end 
166                                                purpleBoxed = true 
167                                        end 
168 
169                                        -- Edge detection: 
170                                        local drawBottomEdge, drawLeftEdge 
171                                        local hiddenBox = (id == 0x5F or id == 0x60) 
172                                        -- Empty space and coins are hollow; also ignore already-boxed tiles. Hidden boxes are only solid on the bottom. 
173                                        if id == 0x00 or id == 0xC2 or id == 0xC3 or greenBoxed or purpleBoxed or hiddenBox then 
174                                                drawBottomEdge = solidBelow 
175                                                drawLeftEdge   = solidOnLeft[row] 
176                                                solidBelow = false 
177                                                solidOnLeft[row] = false 
178                                        -- Everything else is solid on all sides. 
179                                        else 
180                                                drawBottomEdge = not solidBelow 
181                                                drawLeftEdge   = not solidOnLeft[row] 
182                                                solidBelow = true 
183                                                solidOnLeft[row] = true 
184                                        end 
185 
186                                        if drawBottomEdge or hiddenBox then gui.drawline(clampX(x0  ), clampY(y1  ), clampX(x1  ), clampY(y1  ), "blue") end 
187                                        if drawBottomEdge              then gui.drawline(clampX(x0  ), clampY(y1+1), clampX(x1  ), clampY(y1+1), "blue") end 
188                                        if drawLeftEdge                then gui.drawline(clampX(x0-1), clampY(y0  ), clampX(x0-1), clampY(y1+1), "blue") 
189                                                                            gui.drawline(clampX(x0  ), clampY(y0  ), clampX(x0  ), clampY(y1+1), "blue") end 
190                                end 
191                                if  poleBelow then gui.drawline(clampX(x0), clampY(-y_off), clampX(x1), clampY(-y_off), "green") end 
192                                if solidBelow then gui.drawline(clampX(x0), clampY(-y_off), clampX(x1), clampY(-y_off), "blue" ) end 
193                                solidBelow = false 
194                                poleBelow = false 
195                        end 
196                end 
197                FCEU.frameadvance() 
198        end 
199end 
Download and save
Toggle line numbers
Thread:
[92238] smb script (not by me) by not qfox at 2008-07-22 17:29:00
Tip: Click the line numbers to toggle highliting on that line.

Paste followup:

Language:
Author:
Subject: