From 24f1e23c47b897381b00cbefb3187326421bbde7 Mon Sep 17 00:00:00 2001 From: adelikat Date: Sun, 29 Mar 2009 22:47:19 +0000 Subject: [PATCH] Added a lot of luaScripts by XKeeper --- .../luaScripts/BugsBunnyBirthdayBlowout.lua | 210 ++++++ .../Excitingbike-speedometeronly.lua | 90 +++ output/luaScripts/Excitingbike.lua | 221 +++++++ output/luaScripts/Galaxian.lua | 186 ++++++ output/luaScripts/Machrider.lua | 266 ++++++++ output/luaScripts/SMB-AreaScrambler.lua | 97 +++ output/luaScripts/SMB-Jetpack.lua | 353 ++++++++++ output/luaScripts/SMB-Mouse.lua | 573 ++++++++++++++++ output/luaScripts/SMB-Snow.lua | 245 +++++++ output/luaScripts/vnb.lua | 613 ++++++++++++++++++ output/luaScripts/x_functions.lua | 101 ++- output/luaScripts/x_interface.lua | 116 ++++ output/luaScripts/x_smb1enemylist.lua | 44 ++ 13 files changed, 3108 insertions(+), 7 deletions(-) create mode 100644 output/luaScripts/BugsBunnyBirthdayBlowout.lua create mode 100644 output/luaScripts/Excitingbike-speedometeronly.lua create mode 100644 output/luaScripts/Excitingbike.lua create mode 100644 output/luaScripts/Galaxian.lua create mode 100644 output/luaScripts/Machrider.lua create mode 100644 output/luaScripts/SMB-AreaScrambler.lua create mode 100644 output/luaScripts/SMB-Jetpack.lua create mode 100644 output/luaScripts/SMB-Mouse.lua create mode 100644 output/luaScripts/SMB-Snow.lua create mode 100644 output/luaScripts/vnb.lua create mode 100644 output/luaScripts/x_interface.lua create mode 100644 output/luaScripts/x_smb1enemylist.lua diff --git a/output/luaScripts/BugsBunnyBirthdayBlowout.lua b/output/luaScripts/BugsBunnyBirthdayBlowout.lua new file mode 100644 index 00000000..59cff15b --- /dev/null +++ b/output/luaScripts/BugsBunnyBirthdayBlowout.lua @@ -0,0 +1,210 @@ +--Bugs Bunny Birthday Blowout +--Written by XKeeper +--Creates Lag and Sprite counters as well as Camera position + +-- ************************************************************************************ +-- ************************************************************************************ +-- ************************************************************************************ + +function box(x1,y1,x2,y2,color) + if (x1 >= 0 and x1 <= 255 and x2 >= 0 and x2 <= 255 and y1 >= 0 and y1 <= 244 and y2 >= 0 and y2 <= 244) then + gui.drawbox(x1,y1,x2,y2,color); + end; +end; + + + +-- ************************************************************************************ +-- ************************************************************************************ +-- ************************************************************************************ + +function filledbox(x1,y1,x2,y2,color) + for i = 0, math.abs(y1 - y2) do + line(x1,y1 + i,x2,y1 + i,color); + end; +end; + + + + +-- ************************************************************************************ +-- ************************************************************************************ +-- ************************************************************************************ + +function lifebar(x, y, sx, sy, a1, a2, oncolor, offcolor, noborder) + -- this function will have the effect of drawing an HP bar + -- keep in mind xs and ys are 2px larger to account for borders + + x1 = x; + x2 = x + sx + 4; + y1 = y; + y2 = y + sy + 4; + w = math.floor(a1 / math.max(1, a1, a2) * sx); + if not a2 then w = 0 end; + + if (noborder) then + box(x1 + 1, y1 + 1, x2 - 1, y2 - 1, "#000000"); + else + box(x1 + 1, y1 + 1, x2 - 1, y2 - 1, "#ffffff"); + box(x1 , y1 , x2 , y2 , "#000000"); + end; + + if (w < sx) then + filledbox(x1 + w + 2, y1 + 2, x2 - 2, y2 - 2, offcolor); + end; + + if (w > 0) then + filledbox(x1 + 2, y1 + 2, x1 + 2 + w, y2 - 2, oncolor); + end; + +end; + + + + + + +-- ************************************************************************************ +-- ************************************************************************************ +-- ************************************************************************************ + +function line(x1,y1,x2,y2,color) + if (x1 >= 0 and x1 <= 255 and x2 >= 0 and x2 <= 255 and y1 >= 0 and y1 <= 244 and y2 >= 0 and y2 <= 244) then + local success = pcall(function() gui.drawline(x1,y1,x2,y2,color) end); + if not success then + text(60, 224, "ERROR: ".. x1 ..",".. y1 .." ".. x2 ..",".. y2); + end; + end; +end; + +function text(x,y,str) + if (x >= 0 and x <= 255 and y >= 0 and y <= 240) then + gui.text(x,y,str); + end; +end; + +function pixel(x,y,color) + if (x >= 0 and x <= 255 and y >= 0 and y <= 240) then + gui.drawpixel(x,y,color); + end; +end; + + + +function drawpos(cx, cy, ex, ey, n) + sx = ex - cx; + sy = ey - cy; + + num = ""; + if n then + num = string.format("%02X", n); + end; + + if sx >= 0 and sx <= 255 and sy >= 0 and sy <= 244 then + line(sx, sy, sx + 16, sy + 0, "#ff0000"); + line(sx, sy, sx + 0, sy + 16, "#ff0000"); + text(sx, sy, num); + + elseif sx < 0 and sy >= 0 and sy <= 244 then + line(0, sy, 16, sy, "#ff0000"); + text(4, sy, num); + + elseif sx > 255 and sy >= 0 and sy <= 244 then + line(239, sy, 255, sy, "#ff0000"); + text(243, sy, num); + + elseif sy < 0 and sx >= 0 and sx <= 256 then + line(sx, 8, sx, 24, "#ff0000"); + text(sx, 8, num); + + elseif sy > 244 and sx >= 0 and sx <= 256 then + line(sx, 212, sx, 244, "#ff0000"); + text(sx, 216, num); + + end; + + +end; + + +lagdetectorold = 0; +timer = 0; +lagframes = 0; +lastlag = 0; + +while (true) do + + timer = timer + 1; + + lagdetector = memory.readbyte(0x00f5); +-- if lagdetector == lagdetectorold then + if AND(lagdetector, 0x20) == 0x20 then +-- if lagdetector == 0x0C then + lagframes = lagframes + 1; + else + if lagframes ~= 0 then + lastlag = lagframes; + end; + lagframes = 0; + lagdetectorold = lagdetector; + end; + memory.writebyte(0x00f5, OR(lagdetector, 0x20)); + + playerx = memory.readbyte(0x0432) + memory.readbyte(0x0433) * 0x100; + playery = memory.readbyte(0x0435) + memory.readbyte(0x0436) * 0x100; + + screenx = memory.readbyte(0x0456) + memory.readbyte(0x0457) * 0x100; + screeny = memory.readbyte(0x0458) + memory.readbyte(0x0459) * 0x100; + + text( 8, 8, string.format("%04X, %04X", playerx, playery)); + text( 8, 16, string.format("%04X, %04X", screenx, screeny)); + + drawpos(screenx, screeny, playerx, playery); + + + tmp = 0; + for i = 0, 0xb do + + offset = 0x7680 + i * 0x20; + + enemyt = memory.readbyte(offset); + enemyx = memory.readbyte(offset + 2) + memory.readbyte(offset + 3) * 0x100; + enemyy = memory.readbyte(offset + 4) + memory.readbyte(offset + 5) * 0x100; + + if enemyt ~= 0xff then +-- text(160, 8 + 8 * tmp, string.format("%02X: %02X <%04X, %04X>", i, enemyt, enemyx, enemyy)); + drawpos(screenx, screeny, enemyx, enemyy, i); + tmp = tmp + 1; + end + end; + + + text(142, 192, string.format("%02d lag frames", lastlag)); + text(142, 216, string.format("%02d active sprites", tmp)); + +-- box(2, 208, 2 + 8 * lastlag, 210, "#ff4444"); +-- box(2, 209, 2 + 8 * lastlag, 211, "#ff4444"); +-- box(2, 212, 2 + 8 * tmp, 213, "#4444ff"); +-- box(2, 214, 2 + 8 * tmp, 215, "#4444ff"); + + lifebar(144, 200, 100, 4, lastlag, 8, "#ffcc22", "#000000"); + lifebar(144, 208, 100, 4, tmp, 12, "#4488ff", "#000000"); + + FCEU.frameadvance(); + +end; + + + + + + + + + + + + + + + diff --git a/output/luaScripts/Excitingbike-speedometeronly.lua b/output/luaScripts/Excitingbike-speedometeronly.lua new file mode 100644 index 00000000..16d24b72 --- /dev/null +++ b/output/luaScripts/Excitingbike-speedometeronly.lua @@ -0,0 +1,90 @@ +--Exciting Bike - Speedometer +--Written by XKeeper +--Shows the speedometer (obviously) + +require("x_functions"); + +if not x_requires then + -- Sanity check. If they require a newer version, let them know. + timer = 1; + while (true) do + timer = timer + 1; + for i = 0, 32 do + gui.drawbox( 6, 28 + i, 250, 92 - i, "#000000"); + end; + gui.text( 10, 32, string.format("This Lua script requires the x_functions library.")); + gui.text( 53, 42, string.format("It appears you do not have it.")); + gui.text( 39, 58, "Please get the x_functions library at"); + gui.text( 14, 69, "http://xkeeper.shacknet.nu/"); + gui.text(114, 78, "emu/nes/lua/x_functions.lua"); + + warningboxcolor = string.format("%02X", math.floor(math.abs(30 - math.fmod(timer, 60)) / 30 * 0xFF)); + gui.drawbox(7, 29, 249, 91, "#ff" .. warningboxcolor .. warningboxcolor); + + FCEU.frameadvance(); + end; + +else + x_requires(4); +end; + + + +function gameloop() + + + + +end; + + +gui.register(gameloop); + + +barcolors = {}; +barcolors[0] = "#000000"; +barcolors[1] = "#880000"; +barcolors[2] = "#ff0000"; +barcolors[3] = "#eeee00"; +barcolors[4] = "#00ff00"; +barcolors[5] = "#00ffff"; +barcolors[6] = "#0000ff"; +barcolors[7] = "#ff00ff"; +barcolors[8] = "#ffffff"; +barcolors[9] = "#123456"; + +lastvalue = {}; +justblinked = {}; +lastzero = {}; +timer = 0; +speed = 0; + +while (true) do + + timer = timer + 1; + lastvalue['speed'] = speed; + + + speed = memory.readbyte(0x0094) * 0x100 + memory.readbyte(0x0090); + positionx = memory.readbyte(0x0050) * 0x100 + memory.readbyte(0x0394); + timerspeed = 3 - memory.readbyte(0x004c); + timerslant = math.max(0, memory.readbyte(0x0026) - 1); + + if memory.readbyte(0x0303) ~= 0x8E then + text(255, 181, "Didn't advance this frame"); + end; + + speedadj1 = math.fmod(speed, 0x100); + speedadj2 = math.fmod(math.floor(speed / 0x100), #barcolors + 1); + speedadj3 = math.fmod(speedadj2 + 1, #barcolors + 1); + + lifebar( 61, 11, 100, 4, speedadj1, 0x100, barcolors[speedadj3], barcolors[speedadj2], "#000000", "#ffffff"); + + text( 0, 4 + 6, string.format("Speed: %4X", speed)); + text( 1, 4 + 14, string.format("S.Chg: %4d", speed - lastvalue['speed'])); + + text( 20, 222, " 2009 Xkeeper - http://jul.rustedlogic.net/ "); + line( 21, 231, 232, 231, "#000000"); + + FCEU.frameadvance(); +end; \ No newline at end of file diff --git a/output/luaScripts/Excitingbike.lua b/output/luaScripts/Excitingbike.lua new file mode 100644 index 00000000..a6868ac9 --- /dev/null +++ b/output/luaScripts/Excitingbike.lua @@ -0,0 +1,221 @@ +--Exicitebike +--Written by XKeeper +--Shows various stats including a RAM map & speed + +require("x_functions"); + +if not x_requires then + -- Sanity check. If they require a newer version, let them know. + timer = 1; + while (true) do + timer = timer + 1; + for i = 0, 32 do + gui.drawbox( 6, 28 + i, 250, 92 - i, "#000000"); + end; + gui.text( 10, 32, string.format("This Lua script requires the x_functions library.")); + gui.text( 53, 42, string.format("It appears you do not have it.")); + gui.text( 39, 58, "Please get the x_functions library at"); + gui.text( 14, 69, "http://xkeeper.shacknet.nu/"); + gui.text(114, 78, "emu/nes/lua/x_functions.lua"); + + warningboxcolor = string.format("%02X", math.floor(math.abs(30 - math.fmod(timer, 60)) / 30 * 0xFF)); + gui.drawbox(7, 29, 249, 91, "#ff" .. warningboxcolor .. warningboxcolor); + + FCEU.frameadvance(); + end; + +else + x_requires(4); +end; + + + +function gameloop() + + + + +end; + + +gui.register(gameloop); + + +barcolors = {}; +barcolors[0] = "#000000"; +barcolors[1] = "#880000"; +barcolors[2] = "#ff0000"; +barcolors[3] = "#eeee00"; +barcolors[4] = "#00ff00"; +barcolors[5] = "#00ffff"; +barcolors[6] = "#0000ff"; +barcolors[7] = "#ff00ff"; +barcolors[8] = "#ffffff"; +barcolors[9] = "#123456"; + +lastvalue = {}; +justblinked = {}; +lastzero = {}; +timer = 0; +speed = 0; + +while (true) do + + timer = timer + 1; + lastvalue['speed'] = speed; + + + speed = memory.readbyte(0x0094) * 0x100 + memory.readbyte(0x0090); + positionx = memory.readbyte(0x0050) * 0x100 + memory.readbyte(0x0394); + timerspeed = 3 - memory.readbyte(0x004c); + timerslant = math.max(0, memory.readbyte(0x0026) - 1); + + if memory.readbyte(0x0303) ~= 0x8E then + text(255, 181, "Didn't advance this frame"); + end; + + speedadj1 = math.fmod(speed, 0x100); + speedadj2 = math.fmod(math.floor(speed / 0x100), #barcolors + 1); + speedadj3 = math.fmod(speedadj2 + 1, #barcolors + 1); + + lifebar( 61, 11, 100, 4, speedadj1, 0x100, barcolors[speedadj3], barcolors[speedadj2], "#000000", "#ffffff"); + + text(198, 9, string.format("Speed %2d", timerspeed)); + text(196, 17, string.format(" Slant %2d", timerslant)); + box( 186, 10, 198, 18, "#000000"); + box( 186, 18, 198, 26, "#000000"); + + if timerspeed == 0 then + filledbox(187, 11, 197, 17, "#00ff00"); + if memory.readbyte(0x00B0) ~= 0 then + temp = "->"; + else + temp = "(B)"; + end; + text( 0, 50, string.format("Hold %s to maintain speed", temp)); + else + filledbox(187, 11, 197, 17, "#880000"); + end; + if timerslant <= 1 then + filledbox(187, 19, 197, 25, "#00ff00"); + text( 0, 58, string.format("Use < + > to modify angle")); + else + filledbox(187, 19, 197, 25, "#880000"); + end; + + + + text( 0, 4 + 6, string.format("Speed: %4X", speed)); + text( 1, 4 + 14, string.format("S.Chg: %4d", speed - lastvalue['speed'])); + + + + value = memory.readbyte(0x0064); + lifebar( 1, 1, 240, 6, value, 0xFF, "#ffffff", "#111144", false, "#000000"); + tp = math.floor(value / 255 * 240) + 4; + text(tp, 1, string.format("%02X", value)); + + + drawerpos = memory.readbyte(0x00e8); + screenpos = memory.readbyte(0x00eb); + + for x = 0, 0x3F do + for y = 0, 5 do + offset = y * 0x40 + x + 0x400; + value = memory.readbyte(offset); + color = string.format("#%02x%02x%02x", value, value, value); + x = math.fmod(x - screenpos, 0x40); + while (x < 0) do + x = x + 0x40; + end; + box(x * 3 + 8, y * 3 + 28, x * 3 + 9, y * 3 + 30, color); + box(x * 3 + 9, y * 3 + 28, x * 3 +10, y * 3 + 30, color); +-- pixel(x * 3 + 9, y * 3 + 28, color); + end; + end; + + drawerpos = drawerpos - screenpos; + while (drawerpos < 0) do + drawerpos = drawerpos + 0x40; + end; + + box(math.fmod(drawerpos, 0x40) * 3 + 7, 27, math.fmod(drawerpos, 0x40) * 3 + 11, 5 * 3 + 31, "#dd0000"); +-- box(math.fmod(screenpos, 0x40) * 3 + 7, 25, math.fmod(screenpos, 0x40) * 3 + 11, 5 * 3 + 31, "#00ff00"); + box(math.fmod(0, 0x40) * 3 + 7, 27, math.fmod(0, 0x40) * 3 + 11, 5 * 3 + 31, "#00ff00"); + + for i = 0, 5 do + offset = 0x00e8 + i; + if not lastzero[offset] then + lastzero[offset] = {}; + end; + + + value = memory.readbyte(offset); + + if lastvalue[offset] and lastvalue[offset] ~= value then + if not justblinked[offset] then + color = "#ffffff"; + else + color = "#dd0000"; + end; + justblinked[offset] = true; + else + color = "#dd0000"; + justblinked[offset] = false; + end; + + lifebar( 3, 190 + i * 8, 240, 6, value, 240, color, "#111144", false, "#000000"); + tp = math.floor(value / 240 * 240) + 4; + text(tp, 190 + i * 8, string.format("%02X", value)); + + if lastzero[offset]['time'] then + text(165, 190 + i * 8, string.format("%7sa %4df", string.format("%.2f", (lastzero[offset]['total'] / lastzero[offset]['samples'])), lastzero[offset]['time'])); + end; + if value == 0 and not lastzero[offset]['uhoh'] then + if lastzero[offset]['fr'] then + lastzero[offset]['time'] = timer - lastzero[offset]['fr']; + if lastzero[offset]['total'] then + lastzero[offset]['total'] = lastzero[offset]['total'] + lastzero[offset]['time']; + lastzero[offset]['samples'] = lastzero[offset]['samples'] + 1; + else + lastzero[offset]['total'] = lastzero[offset]['time']; + lastzero[offset]['samples'] = 1; + end; + end; + lastzero[offset]['fr'] = timer; + lastzero[offset]['uhoh'] = true; + elseif value ~= 0 then + lastzero[offset]['uhoh'] = false; + end; + + lastvalue[offset] = value; + + end; + + + +--[[ + startoffset = 0x5E0; + s = 0x120; + xs = 0x40; + ys = math.floor(s / xs); + for x = 0, xs - 1 do + for y = 0, ys - 1 do + offset = y * xs + x + startoffset; + value = memory.readbyte(offset); + if value == 0x40 then + color = "clear"; + else + value = math.fmod(value * 0x10, 0x100); + color = string.format("#%02x%02x%02x", value, value, value); + end; + + box(x * 3 + 8, y * 3 + 64, x * 3 + 10, y * 3 + 66, color); + pixel(x * 3 + 9, y * 3 + 65, color); + end; + end; + +]] + + FCEU.frameadvance(); +end; \ No newline at end of file diff --git a/output/luaScripts/Galaxian.lua b/output/luaScripts/Galaxian.lua new file mode 100644 index 00000000..d832166e --- /dev/null +++ b/output/luaScripts/Galaxian.lua @@ -0,0 +1,186 @@ +--Galaxian +--Written by XKeeper +--Accesses the Music Player Easter Egg and displays the songs & information + +require "x_functions"; +require "x_interface"; + +if not x_requires then + -- Sanity check. If they require a newer version, let them know. + timer = 1; + while (true) do + timer = timer + 1; + for i = 0, 32 do + gui.drawbox( 6, 28 + i, 250, 92 - i, "#000000"); + end; + gui.text( 10, 32, string.format("This Lua script requires the x_functions library.")); + gui.text( 53, 42, string.format("It appears you do not have it.")); + gui.text( 39, 58, "Please get the x_functions library at"); + gui.text( 14, 69, "http://xkeeper.shacknet.nu:5/"); + gui.text(114, 78, "emu/nes/lua/x_functions.lua"); + + warningboxcolor = string.format("%02X", math.floor(math.abs(30 - math.fmod(timer, 60)) / 30 * 0xFF)); + gui.drawbox(7, 29, 249, 91, "#ff" .. warningboxcolor .. warningboxcolor); + + FCEU.frameadvance(); + end; + +else + x_requires(6); +end; + +function musicplayer() + resets = memory.readbyte(0x0115); + song = memory.readbyte(0x0002); + songlua = math.max(1, math.floor(resets / 45)); + speed = memory.readbyte(0x0004); + speedde = memory.readbyte(0x0104); -- it's really an AND. But the only two values used are 0F and 07, so this modulous works. + pos = memory.readbyte(0x0000); + note = memory.readbyte(0x0001); + offsetb = song * 0x0100 + 0x4010 - 1; + offset = song * 0x0100 + pos - 1 + 0x4010; + note1 = 0x10 - math.floor(note / 0x10); + note2 = math.fmod(note, 0x10); + if note1 == 0x10 then note1 = 0 end; + + + text( 35, 42, string.format("Song Position: %02X%02X", song, pos)); + text( 40, 50, string.format("ROM Offset: %04X", offset)); + text( 43, 58, string.format("Song Speed: %02X", speed)); + text(105, 66, string.format(" %02X", math.fmod(speedde, speed))); + + lifebar(186, 21, 64, 4, note1, 15, "#8888ff", "#000066", false, "#ffffff"); + lifebar(186, 29, 64, 4, note2, 15, "#8888ff", "#000066", false, "#ffffff"); + text(178, 20, string.format("%X\n%X", note1, note2)); + + lifebar( 44, 67, 64, 4, math.fmod(speedde, speed), speed, "#8888ff", "#000066", false, "#ffffff"); + + if control.button(75, 90, 84, 1, "Toggle hex viewer") then + hexmap = not hexmap; + end; + + if hexmap then + songdata = {}; + songdata2 = {}; + for i = 0x00, 0xFF do + if i >= songs[songlua]['st'] and i <= songs[songlua]['en'] or true then + o = string.format("%02X", rom.readbyte(offsetb + i)); + else + o = ""; + end; + x = math.fmod(i, 0x10); + y = math.floor(i / 0x70); + if not songdata2[x] then + songdata2[x] = {}; + end; + if not songdata2[x][y] then + songdata2[x][y] = o; + -- songdata2[x][y] = string.format("%02X", y); + else + songdata2[x][y] = songdata2[x][y] .."\n".. o; + end; + end; + + for x = 0, 0x0F do + text(29 + x * 14, 100 + 8 * 0, songdata2[x][0]); + text(29 + x * 14, 100 + 8 * 7, songdata2[x][1]); + text(29 + x * 14, 100 + 8 * 14, songdata2[x][2]); + end; + + oboxx = 29 + math.fmod(pos, 0x10) * 14; + oboxy = 100 + 8 * math.floor(pos / 0x10); + c = "#ff0000"; + if math.fmod(timer, 4) < 2 then + c = "#FFFFFF"; + end; + box(oboxx, oboxy + 0, oboxx + 14, oboxy + 10, c); + end; + + if pos >= songs[songlua]['en'] then --and pos == 0xFE then + if not songs[songlua]['xx'] then + memory.writebyte(0x0104, 0xFF); +-- text(50, 50, "LOCK"); + else + memory.writebyte(0x0115, songs[songs[songlua]['xx']]['rv']); + memory.writebyte(0x0002, songs[songs[songlua]['xx']]['sv']); + memory.writebyte(0x0004, songs[songs[songlua]['xx']]['sp']); + memory.writebyte(0x0000, songs[songs[songlua]['xx']]['st']); + end; + end; + + for id, val in pairs(songs) do + if id == songlua then + c = "#8888ff"; + if math.fmod(timer, 4) < 2 then + c = "#FFFFFF"; + end; + else + c = nil; + end; + if control.button(195, 33 + 11 * id, 57, 1, string.format("Play song %d", id), c, true) then +-- resetrequired = true; +-- memory.register(0x0104, nil); + memory.writebyte(0x0115, val['rv']); + memory.writebyte(0x0002, val['sv']); + memory.writebyte(0x0004, val['sp']); + memory.writebyte(0x0000, val['st']); + end; + end; + + if resetrequired then + text(50, 85, "Please soft-reset game."); + if movie.framecount() == 0 then + resetrequired = false; + end; + end; +end; + + +songs = { + -- resets song `id` speed start end + { rv = 0x2E, sv = 0x1B, sp = 0x0F, st = 0x00, en = 0xC6 }, + { rv = 0x5A, sv = 0x18, sp = 0x07, st = 0x00, en = 0xC2 }, + { rv = 0x87, sv = 0x06, sp = 0x0F, st = 0x00, en = 0x7F }, + { rv = 0xB4, sv = 0x16, sp = 0x0F, st = 0x50, en = 0xAF }, + { rv = 0xE1, sv = 0x1A, sp = 0x0F, st = 0x80, en = 0xF8, xx = 0x01 }, + }; +timer = 0; +hexmap = true; + +while true do + + timer = timer + 1; + input.update(); + + if memory.readbyte(0x0101) == 1 then + musicplayer(); + + else + filledbox(23, 49, 233, 130, "#000000"); + text( 25, 50, "Normally you'd have to do something insane"); + text( 52, 58, "like push RESET 45 times and"); + text( 56, 66, "hold A+B on P2's controller."); + + text( 28, 82, "Lucky for you, though, we borrowed this."); + text( 73, 90, "Feel free to use it."); + + text( 73, 119, "(Yeah, we've got that)"); + + timer2 = math.fmod(timer, 60); + if timer2 >= 30 then timer2 = 60 - timer2; end; + timer2 = math.floor((timer2 / 30) * 255); + c = string.format("#%02X%02XFF", timer2, timer2); + + if control.button(110, 106, 37, 1, " EASY ", c, "#ffffff") then + memory.writebyte(0x0101, 0x01); + memory.writebyte(0x0115, songs[2]['rv']); + memory.writebyte(0x0002, songs[2]['sv']); + memory.writebyte(0x0004, songs[2]['sp']); + memory.writebyte(0x0000, songs[2]['st']); + FCEU.softreset(); +-- text(1, 1, 'woohoo'); + end; + end; + FCEU.frameadvance(); + +end; diff --git a/output/luaScripts/Machrider.lua b/output/luaScripts/Machrider.lua new file mode 100644 index 00000000..53d56812 --- /dev/null +++ b/output/luaScripts/Machrider.lua @@ -0,0 +1,266 @@ +--Machrider - Speedometer +--Written by XKeeper + +require("x_functions"); + +if not x_requires then + -- Sanity check. If they require a newer version, let them know. + timer = 1; + while (true) do + timer = timer + 1; + for i = 0, 32 do + gui.drawbox( 6, 28 + i, 250, 92 - i, "#000000"); + end; + gui.text( 10, 32, string.format("This Lua script requires the x_functions library.")); + gui.text( 53, 42, string.format("It appears you do not have it.")); + gui.text( 39, 58, "Please get the x_functions library at"); + gui.text( 14, 69, "http://xkeeper.shacknet.nu/"); + gui.text(114, 78, "emu/nes/lua/x_functions.lua"); + + warningboxcolor = string.format("%02X", math.floor(math.abs(30 - math.fmod(timer, 60)) / 30 * 0xFF)); + gui.drawbox(7, 29, 249, 91, "#ff" .. warningboxcolor .. warningboxcolor); + + FCEU.frameadvance(); + end; + +else + x_requires(4); +end; + + +function savereplay(filename, replaydata) + + stringout = ""; + + f = io.open(filename, "w"); + for k, v in pairs(replaydata) do + stringout = string.format("%d:%d:%d\n", k, v['speed'], v['gear']); + f:write(stringout); + end; + + f:close(); + + return true; + +end; + + + +olddist = 0; +lastcount = 0; +counter = 0; +altunittype = true; +waittimer = 0; +autoshift = true; -- auto-handle shifting? for the lazy people +speedgraph = {}; +timer = 0; +graphlen = 240; +graphheight = 100; +maxspeed = 500; +dorecording = false; + +while true do + + joydata = joypad.read(1); + if joydata['select'] and not joydatas then + altunittype = not altunittype; + joydatas = true; + + elseif joydata['up'] and joydata['B'] and not joydatas and dorecording then + savereplay("machriderspeed.xrp", speedgraph); + joydatas = true; + saved = true; + + elseif not joydata['select'] then + joydatas = false; + end; + + if saved and dorecording then + text(100, 140, "Saved data!"); + end; + + speedlow = memory.readbyte(0x0040); + speedhigh = memory.readbyte(0x0041); + speed = speedhigh * 0x100 + speedlow; + rpmlow = memory.readbyte(0x0042); + rpmhigh = memory.readbyte(0x0043); + rpm = rpmhigh * 0x100 + rpmlow; + gear = memory.readbyte(0x0032); + + + if autoshift and waittimer <= 0 then + if gear < 2 then + memory.writebyte(0x0032, 2); +-- waittimer = 6; + elseif speed <= 250 and gear > 2 then + memory.writebyte(0x0032, math.max(gear - 1, 2)); +-- waittimer = 6; + elseif speed >= 255 and gear < 3 then + memory.writebyte(0x0032, math.min(gear + 1, 3)); +-- waittimer = 6; + end; + end; + waittimer = waittimer - 1; + + if dorecording then + timer = timer + 1; + speedgraph[timer] = {speed = speed, gear = gear}; + if timer > graphlen then + temp = timer - graphlen - 1; + -- speedgraph[temp] = nil; + end; + + + for i = timer - graphlen, timer do + if speedgraph[i] then + xp = ((i + 3) - timer) + graphlen; + yp = graphheight - (speedgraph[i]['speed'] / maxspeed) * graphheight; + + if (speedgraph[i]['gear'] == 0) then + c = "blue"; + elseif (speedgraph[i]['gear'] == 1) then + c = "green"; + elseif (speedgraph[i]['gear'] == 2) then + c = "#cccc00"; + elseif (speedgraph[i]['gear'] == 3) then + c = "red"; + else + c = "gray"; + end; + + -- pixel(((i + 3) - timer) + 60, 50 - speedgraph[i], "#ffffff"); + line(xp, 10, xp, graphheight + 10, "#000000"); + line(xp, yp + 10, xp, graphheight + 10, c); + pixel(xp, yp + 10, "#ffffff"); + + -- pixel(((i + 3) - timer) + 60, 50 - speedgraph[i], "#ffffff"); + end; + end; + end; + +--[[ + dist = math.fmod(memory.readbyte(0x0062), 0x20); + text( 8, 15, string.format("%02X %4dfr/mv", dist, lastcount)); + if dist > olddist then + lastcount = counter; + counter = 0; + end; + olddist = dist; + counter = counter + 1; + + lifebar( 8, 8, 0x1F * 5, 3, dist, 0x1F, "#ffffff", "#0000FF", "#000000", "#ffffff"); +--]] + + barwidth = 100; + segmentwidth = 2; + pct = speed / maxspeed * 100; + + if altunittype then + speedadjust = (65535 / 60 / 60 / 60) * speed; -- rough approximation of km/h + text(barwidth * segmentwidth - 2, 221, string.format(" %3.1dkm/h", speedadjust)); + else + text(barwidth * segmentwidth - 2, 221, string.format(" %3d", speed)); + end; + + box(2, 221, barwidth * segmentwidth + 2, 230, "#000000"); + box(2, 222, barwidth * segmentwidth + 2, 229, "#000000"); + box(2, 223, barwidth * segmentwidth + 2, 228, "#000000"); + box(2, 224, barwidth * segmentwidth + 2, 227, "#000000"); + box(2, 225, barwidth * segmentwidth + 2, 226, "#000000"); + lastseg = false; + + if pct > 0 then + for bl = 1, math.min(maxspeed - 1, speed) do + + pct = bl / maxspeed; + segment = math.floor(pct * barwidth); + if segment ~= lastseg then + + if pct < 0.50 then + val = math.floor(pct * 2 * 0xFF); + segcolor = string.format("#%02XFF00", val); + + elseif pct < 0.90 then + val = math.floor(0xFF - (pct - 0.5) * 100/40 * 0xFF); + segcolor = string.format("#FF%02X00", val); + + elseif bl < maxspeed then + val = math.floor((pct - 0.90) * 10 * 0xFF); + segcolor = string.format("#FF%02X%02X", val, val); + + else + segcolor = "#ffffff"; + end; + + + yb = math.max(math.min(3, (pct * 100 - 50)), 0); + -- box(segment * segmentwidth + 3, 225 - yb, segment * segmentwidth + 3 + (segmentwidth - 2), 229, segcolor); + box(segment * segmentwidth + 3, 225 - yb, segment * segmentwidth + 3, 229, segcolor); + -- box(bl * 3 + 3, 218, bl * 3 + 4, 225, segcolor); + -- line(bl * 3 + 4, 218, bl * 3 + 4, 225, segcolor); + end; + lastseg = segment; + end; + end; + + + + maxrpm = 0x7F; + barwidth = 104; + segmentwidth = 1; + pct = rpmhigh / maxrpm * 100; + + line(2, 220, (barwidth + 2) * segmentwidth + 2, 220, "#000000"); + + if autoshift then + text( 2, 203, string.format("AUTO %1d", gear + 1)); + else + text( 2, 203, string.format("Manual %1d", gear + 1)); + end; + if altunittype then + text( 2, 211, string.format("%5dRPM", math.min(9999, rpm * .25))); + else + text( 2, 211, string.format("%5dRPM", rpm)); + end; + + rpmhigh = math.min(maxrpm + 10, rpmhigh); + lastseg = false; + + if pct > 0 then + for bl = 1, rpmhigh do + + pct = bl / maxrpm; + segment = math.floor(pct * barwidth); + if segment ~= lastseg then + if pct < 0.70 then + val = math.floor(pct * (100/70) * 0xFF); + segcolor = string.format("#%02XFF00", val); + + elseif pct < 0.90 then + val = math.floor(0xFF - (pct - 0.7) * 100/20 * 0xFF); + segcolor = string.format("#FF%02X00", val); + + elseif bl < maxrpm then + val = math.floor((pct - 0.90) * 10 * 0xFF); + segcolor = string.format("#FF%02X%02X", val, val); + + else + segcolor = "#ffffff"; + end; + + yb = math.floor(math.max(math.min(4, segment - 99), 0) / 2); + -- box(segment * segmentwidth + 3, 225 - yb, segment * segmentwidth + 3 + (segmentwidth - 2), 229, segcolor); + segment = math.min(segment, barwidth); + box(segment * segmentwidth + 3, 221, segment * segmentwidth + 3, 223 - yb, segcolor); + -- box(bl * 3 + 3, 218, bl * 3 + 4, 225, segcolor); + -- line(bl * 3 + 4, 218, bl * 3 + 4, 225, segcolor); + end; + lastseg = seg; + end; + end; + + + + + FCEU.frameadvance(); +end; \ No newline at end of file diff --git a/output/luaScripts/SMB-AreaScrambler.lua b/output/luaScripts/SMB-AreaScrambler.lua new file mode 100644 index 00000000..aaf82875 --- /dev/null +++ b/output/luaScripts/SMB-AreaScrambler.lua @@ -0,0 +1,97 @@ +--SMB area scrambler +--Randomly changes the level contents. Doesn't garuantee a winnable level (nor does it guarantee it won't crash the game) +--Written by XKeeper + +require("x_functions"); + +if not x_requires then + -- Sanity check. If they require a newer version, let them know. + timer = 1; + while (true) do + timer = timer + 1; + for i = 0, 32 do + gui.drawbox( 6, 28 + i, 250, 92 - i, "#000000"); + end; + gui.text( 10, 32, string.format("This Lua script requires the x_functions library.")); + gui.text( 53, 42, string.format("It appears you do not have it.")); + gui.text( 39, 58, "Please get the x_functions library at"); + gui.text( 14, 69, "http://xkeeper.shacknet.nu/"); + gui.text(114, 78, "emu/nes/lua/x_functions.lua"); + + warningboxcolor = string.format("%02X", math.floor(math.abs(30 - math.fmod(timer, 60)) / 30 * 0xFF)); + gui.drawbox(7, 29, 249, 91, "#ff" .. warningboxcolor .. warningboxcolor); + + FCEU.frameadvance(); + end; + +else + x_requires(4); +end; + + + + + +function areascrambler() +end; + + +function gameloop() + + joyin = joypad.read(1); + if joyin['select'] then + memory.writebyte(0x00e7, math.random(0, 0xFF)); + memory.writebyte(0x00e8, math.random(0, 0xFF)); + memory.writebyte(0x00e9, math.random(0, 0xFF)); + memory.writebyte(0x00ea, math.random(0, 0xFF)); + memory.writebyte(0x0750, math.random(0, 0xFF)); + end; + + if joyin['up'] then + memory.writebyte(0x009F, -5); + memory.writebyte(0x07F8, 3); + memory.writebyte(0x0722, 0xFF) + end; + + screenpage = memory.readbyte(0x071a); + screenxpos = memory.readbyte(0x071c); + + arealow = memory.readbyte(0x00e7); + areahigh = memory.readbyte(0x00e8); + + enemylow = memory.readbyte(0x00e9); + enemyhigh = memory.readbyte(0x00ea); + + unknown = memory.readbyte(0x0750); + + + text( 6, 30, string.format("Position: %02X %02X", screenpage, screenxpos)); + text( 19, 38, string.format("Area: %02X %02X", areahigh, arealow)); + text( 13, 46, string.format("Enemy: %02X %02X", enemyhigh, enemylow)); + text( 13, 54, string.format("?: %02X", unknown)); +end; + + +function areascramble() + memory.writebyte(0x00e7, math.random(0, 0xFF)); + memory.writebyte(0x00e8, math.random(0, 0xFF)); +end; + +function enemyscramble() + memory.writebyte(0x00e9, math.random(0, 0xFF)); + memory.writebyte(0x00ea, math.random(0, 0xFF)); +end; + + +gui.register(gameloop); +memory.register(0x00e8, areascramble); +memory.register(0x00ea, enemyscramble); + + + +while (true) do + + memory.writebyte(0x079F, 2); + FCEU.frameadvance(); +end; + diff --git a/output/luaScripts/SMB-Jetpack.lua b/output/luaScripts/SMB-Jetpack.lua new file mode 100644 index 00000000..b29c54f0 --- /dev/null +++ b/output/luaScripts/SMB-Jetpack.lua @@ -0,0 +1,353 @@ +--Super Mario Bros. - Jetpack +--Written by XKeeper +--A fun script that gives mario a "Jetback" + +require("x_functions"); + +if not x_requires then + -- Sanity check. If they require a newer version, let them know. + timer = 1; + while (true) do + timer = timer + 1; + for i = 0, 32 do + gui.drawbox( 6, 28 + i, 250, 92 - i, "#000000"); + end; + gui.text( 10, 32, string.format("This Lua script requires the x_functions library.")); + gui.text( 53, 42, string.format("It appears you do not have it.")); + gui.text( 39, 58, "Please get the x_functions library at"); + gui.text( 14, 69, "http://xkeeper.shacknet.nu/"); + gui.text(114, 78, "emu/nes/lua/x_functions.lua"); + + warningboxcolor = string.format("%02X", math.floor(math.abs(30 - math.fmod(timer, 60)) / 30 * 0xFF)); + gui.drawbox(7, 29, 249, 91, "#ff" .. warningboxcolor .. warningboxcolor); + + FCEU.frameadvance(); + end; + +else + x_requires(4); +end; + + + +function doballs() + + count = 0; + for k, v in pairs(balls) do + + v['x'] = v['x'] + v['xs']; + v['y'] = v['y'] + v['ys']; + v['ys'] = v['ys'] - 0.1; + v['life'] = v['life'] - 1; + + if v['x'] < 0 or v['x'] > 254 or v['y'] < 0 or v['y'] > 243 or v['life'] < 0 then + balls[k] = nil; + else + balls[k] = v; +-- pixel(v['x'], v['y'], "#FFFFFF"); + colkey = math.ceil(255 * (5 - math.max(math.min(5, (v['life'] / 15)), 0)) / 5); + + if v['c'] >= 0 then + color = string.format("#%02X%02X%02X", v['c'], v['c'], v['c']); +-- color = string.format("#%02X%02X%02X", v['c'] * .8, v['c'] * .5, v['c'] * 0); + else + color = string.format("#%02X0000", v['c'] * -1 , 0, 0); + end; + + if v['life'] > 45 then + box(v['x'], v['y'], v['x'] + 1, v['y'] + 1, color); + else + pixel(v['x'], v['y'], color); + end; + count = count + 1; + end; + end; + +-- lifebar( 2, 140, 249, 10, spower, 400, "#ffffff", "#000044", "#bbbbff"); + return count; + +end; + + + +function nojumping() + memory.writebyte(0x000a, AND(memory.readbyte(0x000a), 0x7F)); + + return true; +end; + +function nomoving() + joyput = joypad.read(1); + if (joyput['left'] or joyput['right']) then + memory.writebyte(0x000c, 0); + end; + + return true; +end; + + +function areascrambler() + memory.writebyte(0x00e7, math.random(0, 0xFF)); + memory.writebyte(0x00e8, math.random(0, 0xFF)); +end; + +function enemyscrambler() + memory.writebyte(0x00e9, math.random(0, 0xFF)); + memory.writebyte(0x00ea, math.random(0, 0xFF)); +end; + + +--[[ +memory.register(0x00e8, areascrambler); +memory.register(0x00ea, enemyscrambler); +--]] + +-- gui.register(gameloop); +memory.register(0x000a, nojumping); +memory.register(0x000c, nomoving); + +testcount = 0; +balls = {}; +z = 0; +timer = 0; +jmax = 500; +jlife = 500; -- jmax; +refillrate = 0.020; +msgdisp = 300; +rechargerate = 0; +while (true) do + timer = timer + 1; + + + if timer < msgdisp then + yo = (((math.max(0, (timer + 60) - msgdisp))) ^ 2) / 50; + text(20, 50 - yo, "2009 Xkeeper - http://jul.rustedlogic.net/"); + text(49, 64 - yo, "A: Jetpack Left/Right: Move"); + text(53, 72 - yo, " B button: Turbo boost! "); + end; + + invincible = false; + if memory.readbyte(0x079F) >= 1 then + cyclepos = math.abs(15 - math.fmod(timer, 30)) / 15; + warningboxcolor = string.format("%02X", math.floor(cyclepos * 0xFF)); + barcolor = "#" .. warningboxcolor .. warningboxcolor .."ff"; + warningboxcolor = string.format("%02X", math.floor(cyclepos * 0x80) + 0x7F); + barcolor2 = "#0000" .. warningboxcolor; + warningboxcolor = string.format("%02X", math.floor(cyclepos * 0x40)); + barcolor3 = "#0000" .. warningboxcolor; +-- barcolor3 = "#000000"; + + jlife = math.min(jmax, jlife + (jmax - jlife) / 25 + 0.25); + rechargerate = -0.025; + invincible = true; + elseif jlife <= jmax * 0.25 then + cyclepos = math.abs(15 - math.fmod(timer, 30)) / 15; + warningboxcolor = string.format("%02X", math.floor(cyclepos * 0xFF)); + barcolor = "#ff" .. warningboxcolor .. warningboxcolor; + warningboxcolor = string.format("%02X", math.floor(cyclepos * 0x80) + 0x7F); + barcolor2 = "#" .. warningboxcolor .. "0000"; + warningboxcolor = string.format("%02X", math.floor(cyclepos * 0x40)); + barcolor3 = "#" .. warningboxcolor .. "0000"; +-- barcolor3 = "#000000"; + else + barcolor = "#ffffff"; + barcolor2 = "#ff4444"; + barcolor3 = "#000000"; + end; + lifebar(5, 8, 240, 2, jlife, jmax, barcolor, barcolor3, "#000000", barcolor2); + textx = math.max(4, math.min(math.floor(jlife/ jmax * 240) - 4, 229)); + if jlife == jmax then + textx = 223; + end; + text(textx, 13, string.format("%2.1d%%", math.min(jlife/ jmax * 100))); + +--[[ + bxp = math.sin(timer / 120) * 64 + 127; + byp = math.cos(timer / 120) * 64 + 127; + for i = 0, 0 do + balls[z] = {x = bxp + math.random(-100, 200) / 100, y = byp + math.random(-4, 4), xs = math.random(-100, 100) / 50, ys = math.random(-100, 100) / 100, life = math.random(60, 120), c = math.random(128, 255)}; + z = z + 1; + end; +]] + + + doballs(); + + + marioxspeed = memory.readbytesigned(0x0057); + marioyspeed = memory.readbytesigned(0x009F); + marioxpos = memory.readbyte(0x4AC); + marioypos = memory.readbyte(0x4AD); + +-- lifebar(5, 2, 240, 2, marioxspeed + 0x40, 0x80, "#8888ff", "#000000"); + + joyput = joypad.read(1); + if joyput['up'] then + memory.writebyte(0x07F8, 3); + end; + if joyput['A'] and jlife >= 3 then + + rechargerate = 0; + memory.writebyte(0x009F, math.max(-3, marioyspeed - 1)); +-- memory.writebyte(0x009F, -3); + if not invincible then jlife = math.max(0, jlife - 3); end; + for i = 0, 10 do + balls[z] = {x = marioxpos + 5, y = marioypos + 7, xs = math.random(-70, 70) / 100, ys = math.random(100, 300) / 100, life = math.random(30, 60), c = math.random(128, 255)}; + z = z + 1; + end; + end; + if (joyput['left'] or joyput['right']) then + + speedchange = 1; + speedmax = 0x28; + if joyput['B'] and jlife > 0 then + rechargerate = 0; + if not invincible then jlife = math.max(0, jlife - 1); end; + speedchange = 5; + speedmax = 0x40; + end; + + if joyput['left'] then + memory.writebyte(0x0033, 2); + memory.writebyte(0x0045, 2); + if marioxspeed > (speedmax * -1) then + memory.writebyte(0x0057, math.max(-0x40, marioxspeed - speedchange)); + end; + for i = 0, 10 do + balls[z] = {x = marioxpos + 7, y = marioypos + 7, xs = math.random(300, 400) / 100, ys = math.random(-10, 20) / 100, life = math.random(5, 5 + speedchange * 10), c = math.random(128, 255)}; + z = z + 1; + end; + else + + memory.writebyte(0x0033, 1); + memory.writebyte(0x0045, 1); + if marioxspeed < speedmax then + memory.writebyte(0x0057, math.min(0x40, marioxspeed + speedchange)); + end; + for i = 0, 10 do + balls[z] = {x = marioxpos + 7, y = marioypos + 7, xs = math.random(-400, -300) / 100, ys = math.random(-10, 20) / 100, life = math.random(5, 5 + speedchange * 10), c = math.random(128, 255)}; + z = z + 1; + end; + end; + end; + if not ((joyput['B'] and (joyput['left'] or joyput['right'])) or joyput['A']) then + + rechargerate = rechargerate + refillrate; + jlife = math.min(jmax, jlife + rechargerate); + + end; + + + + + + screenpage = memory.readbyte(0x071a); + screenxpos = memory.readbyte(0x071c); + + arealow = memory.readbyte(0x00e7); + areahigh = memory.readbyte(0x00e8); + + enemylow = memory.readbyte(0x00e9); + enemyhigh = memory.readbyte(0x00ea); + + +-- text( 10, 24, string.format("Screen position: %02X.%02X", screenpage, screenxpos)); +-- text(169, 24, string.format("Area: %02X %02X", areahigh, arealow)); +-- text(163, 32, string.format("Enemy: %02X %02X", enemyhigh, enemylow)); + + +--[[ + text( 4, 217, string.format("Memory writes: %04d", testcount)); + if testcount > 1500 or testcount < 200 then + cyclepos = math.abs(15 - math.fmod(timer, 30)) / 15; + warningboxcolor = string.format("%02X", math.floor(cyclepos * 0xFF)); + barcolor = "#ff" .. warningboxcolor .. warningboxcolor; + warningboxcolor = string.format("%02X", math.floor(cyclepos * 0x80) + 0x7F); + barcolor2 = "#" .. warningboxcolor .. "0000"; + warningboxcolor = string.format("%02X", math.floor(cyclepos * 0x40)); + barcolor3 = "#" .. warningboxcolor .. "0000"; +-- barcolor3 = "#000000"; + else + barcolor = "#ffffff"; + barcolor2 = "#ff4444"; + barcolor3 = "#000000"; + end; + lifebar(5, 226, 240, 2, testcount, 2500, barcolor, barcolor3, "#000000", barcolor2); + +--]] + +-- memory.writebyte(0x00e7, math.random(0, 0xFF)); +-- memory.writebyte(0x00e8, math.random(0, 0xFF)); +-- memory.writebyte(0x00e9, math.random(0, 0xFF)); +-- memory.writebyte(0x00ea, math.random(0, 0xFF)); + + testcount = 0; + +--[[ + marioxspeed2 = math.abs(marioxspeed); + + box(2, 217, 0x40 * 3 + 5, 226, "#000000"); + box(2, 218, 0x40 * 3 + 5, 225, "#000000"); + box(2, 219, 0x40 * 3 + 5, 224, "#000000"); + box(2, 220, 0x40 * 3 + 5, 223, "#000000"); + box(2, 221, 0x40 * 3 + 5, 222, "#000000"); + + if marioxspeed2 > 0 then + for bl = 0, marioxspeed2 do + + if bl < 0x20 then + segcolor = string.format("#%02XFF00", math.floor(bl / 0x20 * 0xFF)); + else + segcolor = string.format("#FF%02X00", math.max(0, math.floor((0x40 - bl) / 0x20 * 0xFF))); + end; + + box(bl * 3 + 3, 218, bl * 3 + 4, 225, segcolor); +-- line(bl * 3 + 4, 218, bl * 3 + 4, 225, segcolor); + end; + end; + + --]] + + maxspeed = 0x40; + marioxspeed = memory.readbytesigned(0x0057); + marioxspeed2 = math.abs(marioxspeed); + + + text(maxspeed * 3 + 2, 221, string.format(" %2d", marioxspeed2)); + + box(5, 221, maxspeed * 3 + 5, 230, "#000000"); + box(5, 222, maxspeed * 3 + 5, 229, "#000000"); + box(5, 223, maxspeed * 3 + 5, 228, "#000000"); + box(5, 224, maxspeed * 3 + 5, 227, "#000000"); + box(5, 225, maxspeed * 3 + 5, 226, "#000000"); + + if marioxspeed2 > 0 then + for bl = 1, marioxspeed2 do + + pct = bl / maxspeed; + if pct < 0.50 then + val = math.floor(pct * 2 * 0xFF); + segcolor = string.format("#%02XFF00", val); + + elseif pct < 0.90 then + val = math.floor(0xFF - (pct - 0.5) * 100/40 * 0xFF); + segcolor = string.format("#FF%02X00", val); + + elseif bl < maxspeed then + val = math.floor((pct - 0.90) * 10 * 0xFF); + segcolor = string.format("#FF%02X%02X", val, val); + + else + segcolor = "#ffffff"; + end; + + yb = math.max(math.min(3, (bl - 0x28)), 0); + box(bl * 3 + 3, 225 - yb, bl * 3 + 4, 229, segcolor); +-- box(bl * 3 + 3, 218, bl * 3 + 4, 225, segcolor); +-- line(bl * 3 + 4, 218, bl * 3 + 4, 225, segcolor); + end; + end; + + FCEU.frameadvance(); +end; + diff --git a/output/luaScripts/SMB-Mouse.lua b/output/luaScripts/SMB-Mouse.lua new file mode 100644 index 00000000..8cc31403 --- /dev/null +++ b/output/luaScripts/SMB-Mouse.lua @@ -0,0 +1,573 @@ +--Super Mario Bros. - Drag and Drop +--Written by XKeeper +--Allows you to use the mouse to pick up enemies and movie them around! + +debugmodes = { + enabled = false; -- CHANGE THIS AT YOUR PERIL + showenemydata = false; + drawmouse = false; + locktimer = false; + invincible = false; + ver = "03/29 15:00:00"; + }; + +control = {}; -- must come first. + -- basically, will contain all the "interface" things, + -- buttons, menus, etc. + -- Easier to organize, I guess. + +require "x_functions"; +require "x_interface"; +if debugmodes['enabled'] and false then + require "x_smb1enemylist"; -- used for summoning and other things... not finished +end; + +if not x_requires then + -- Sanity check. If they require a newer version, let them know. + timer = 1; + while (true) do + timer = timer + 1; + for i = 0, 32 do + gui.drawbox( 6, 28 + i, 250, 92 - i, "#000000"); + end; + gui.text( 10, 32, string.format("This Lua script requires the x_functions library.")); + gui.text( 53, 42, string.format("It appears you do not have it.")); + gui.text( 39, 58, "Please get the x_functions library at"); + gui.text( 14, 69, "http://xkeeper.shacknet.nu:5/"); + gui.text(114, 78, "emu/nes/lua/x_functions.lua"); + + warningboxcolor = string.format("%02X", math.floor(math.abs(30 - math.fmod(timer, 60)) / 30 * 0xFF)); + gui.drawbox(7, 29, 249, 91, "#ff" .. warningboxcolor .. warningboxcolor); + + FCEU.frameadvance(); + end; + +else + x_requires(6); +end; + + +-- **************************************************************************** +-- * drawmouse(xpos, ypos, click) +-- * Draws a crude mouse pointer at the location; mostly good for screenshots and debugging. +-- **************************************************************************** +function drawmouse(x, y, click) + + if click then + fill = "#cccccc"; + else + fill = "#ffffff"; + end; + + y = y + 1; + + for i = 0, 6 do + if i ~= 6 then + line(x + i, y + i, x + i, y + 8 - math.floor(i / 2), fill); + pixel(x + i, y + 8 - math.floor(i / 2), "#000000"); + end; + pixel(x + i, y + i - 1, "#000000"); + end; + pixel(x + 1, y + 0, "#000000"); + + line(x , y , x , y + 9, "#000000"); +-- line(x + 1, y + 1, x + 6 , y + 6, "#000000"); +-- line(x , y + 11, x + 7 , y + 7, "#000000"); + +end; + + +-- **************************************************************************** +-- * smbpx2ram( screen-x, screen-y ) +-- * Returns the offset that represents the tile under screenx/screeny. +-- **************************************************************************** +function smbpx2ram(px, py) + + local py = math.floor(py) - 0x20; + local px = math.floor(px); + if px < 0 or px > 400 or py < 0x00 or py > (240 - 0x20) then + return false; + end; + + local oy = math.floor(py / 0x10); + local ox = math.fmod(math.floor((px + smbdata['screenpos']) / 0x10), 0x20); + + offset = 0x500 + math.fmod(oy * 0x10 + math.floor(ox / 0x10) * 0xC0 + math.fmod(ox, 0xD0), 0x1A0); + return offset; + +end; + + +-- **************************************************************************** +-- * smbram2px( memory offset ) +-- * Gives the current top-left pixel of the tile the offset represents. +-- **************************************************************************** +function smbram2px(offset) + + offset = offset - 0x500; + if offset < 0 or offset >= 0x1A0 then + return false; + end; + + local px = (math.fmod(offset, 0x10) + math.floor(offset / 0xD0) * 0x10) * 0x10; + px = px - math.fmod(smbdata['screenpos'], 0x200); + if px < 0 then + px = px + 0x200; + end; + + local py = math.floor(math.fmod(offset, 0xD0) / 0x10); + returnval = {x = px, y = py}; + return returnval; + +end; + + +-- **************************************************************************** +-- * smbmoveenemy( Enemy number, xpos, ypos, x accell, y accell ) +-- * moves enemies to given point. auto-sets facing direction, as well +-- **************************************************************************** +function smbmoveenemy(n, x, y, ax, ay) + + local x1 = math.fmod(x, 0x100); + local x2 = math.floor(x / 0x100); + local y1 = math.fmod(y, 0x100); + local y2 = math.floor(y / 0x100); + local ax = math.max(-128, math.min(ax, 0x7F)); + local ay = math.max(-128, math.min(ay, 0x7F)); + + memory.writebyte(0x006D + n, x2); + memory.writebyte(0x0086 + n, x1); + memory.writebyte(0x00B5 + n, y2); + memory.writebyte(0x00CE + n, y1); + memory.writebyte(0x0057 + n, ax); + memory.writebyte(0x009F + n, ay); + + if ax > 0 then + memory.writebyte(0x0045 + n, 1); + elseif ax < 0 then + memory.writebyte(0x0045 + n, 2); + end; + +end; + + +-- **************************************************************************** +-- * inputaverage() +-- * Mouse movement averages (something unique to this...). +-- **************************************************************************** +function inputaverage() + + local tempx = 0; + local tempy = 0; + for temp = 1, 2 do + tempx = tempx + avgmove[temp]['xmouse']; + tempy = tempy + avgmove[temp]['ymouse']; + avgmove[temp] = avgmove[temp + 1]; + end; + avgmove[3]['xmouse'] = inpt['xmouse'] - last['xmouse']; + avgmove[3]['ymouse'] = inpt['ymouse'] - last['ymouse']; + avgmove['calc']['xmouse'] = (tempx + avgmove[3]['xmouse']) / 3; + avgmove['calc']['ymouse'] = (tempy + avgmove[3]['ymouse']) / 3; + +end; + + +-- **************************************************************************** +-- * tileview() +-- * This does all the "what tile is here" shit for you (me) +-- **************************************************************************** +function tileview () + local ramval = smbpx2ram(inpt['xmouse'], inpt['ymouse']); + if ramval then + local ret = smbram2px(ramval); + local c = "#ffffff"; + if math.fmod(timer, 4) < 2 then + c = "#cccccc"; + end; + if ret then + local tx1 = math.max(0, ret['x'] - 1); + local tx2 = math.min(0xFF, ret['x'] + 0x10); + local ty1 = math.max(ret['y'] * 0x10 + 0x1F, 0); + local ty2 = math.min(244, ret['y'] * 0x10 + 0x30); + box(tx1, ty1, tx2, ty2, c); + end; + + local textx = inpt['xmouse'] + 10; + local texty = inpt['ymouse'] - 4; + + if textx > 229 then + textx = textx - 42; + end; + texty = math.min(214, texty); + + text(textx, texty, string.format("%04X", ramval)); + text(textx, texty + 8, string.format(" %02X ", memory.readbyte(ramval))); + end; +end; + + +-- **************************************************************************** +-- * Generic test function, really. Does nothing of use. +-- * Incidentally, most of the times this shows up, it doesn't +-- **************************************************************************** +function test(arg) + + text(50, 100, "IT WORKS"); + +end; + + +-- **************************************************************************** +-- * spawnsetup(arg) +-- * Prepares spawning of an enemy. +-- * Perhaps should create a dialog box in the middle of the screen?.. +-- **************************************************************************** +function spawnsetup(args) + + if mode ~= 2 then + spawndata['lmode'] = mode; + mode = 2; + spawndata['enum'] = 0x00; + spawndata['ename'] = "Green Koopa"; + spawndata['etype'] = 0; + spawndata['exs'] = 16; + spawndata['eys'] = 24; + -- etype: + --- 0: normal enemy (one slot) + --- 1: big enemy (two slots, takes latter but fills both) + --- 2: powerup (takes slot 6) + end; +end; + + +-- **************************************************************************** +-- * spawnsetup(arg) +-- * Prepares spawning of an enemy. +-- * Perhaps should create a dialog box in the middle of the screen?.. +-- **************************************************************************** +function spawnenemy(args) + + local c = "#ffffff"; + if math.fmod(timer, 4) < 2 then + c = "#888888"; + end; + + local freespace = 0; + + if debugmodes['showenemydata'] then + for i = 1, 6 do + text(8, 8 + 8 * i, string.format("%d %02X", i, memory.readbyte(0x000E+i))); + end; + end; + for i = 1, 6 do + if ((spawndata['etype'] <= 1 and i <= 5) or (spawndata['etype'] == 2 and i == 6)) and memory.readbyte(0x000E+i) == 0 then + if debugmodes['showenemydata'] then + text(8, 8 + 8 * i, string.format("%d %02X *", i, memory.readbyte(0x000E+i))); + end; + if (spawndata['etype'] == 1 and memory.readbyte(0x000E + i - 1) == 0) or spawndata['etype'] ~= 1 then + freespace = i; + break; + end; + end; + end; + + if freespace > 0 then + box(inpt['xmouse'] - (spawndata['exs'] / 2), inpt['ymouse'] - (spawndata['eys'] / 2), inpt['xmouse'] + (spawndata['exs'] / 2), inpt['ymouse'] + (spawndata['eys'] / 2), c); + text(70, 31, string.format("Summon [%s]", spawndata['ename'])); + if debugmodes['showenemydata'] then + text(70, 39, string.format("Enemy slot [%X]", freespace)); + end; + local mx = smbdata['screenpos'] + inpt['xmouse']; + local my = 0x100 + inpt['ymouse']; + if inpt['leftclick'] and not last['leftclick'] then + memory.writebyte(0x000E + freespace, 1); + memory.writebyte(0x0015 + freespace, spawndata['enum']); + memory.writebyte(0x0499 + freespace, 3); + smbmoveenemy(freespace, mx - (spawndata['exs'] / 2), my - (spawndata['eys'] / 2), -1, 0); + mode = spawndata['lmode']; + end; + + else + text(70, 31, string.format("Can't summon (too many enemies)!")); + + end; + +end; + + +-- **************************************************************************** +-- * modechange(arg) +-- * changes current mode (used in menu). +-- * also changes menu text to reflect new mode. +-- **************************************************************************** +function modechange(args) + + mode = args[1]; + if args[1] == 0 then + mainmenu['menu']['m001_mode']['menu']['m001_tiles']['marked'] = 1; + mainmenu['menu']['m001_mode']['menu']['m002_enemy']['marked'] = 0; + else + mainmenu['menu']['m001_mode']['menu']['m001_tiles']['marked'] = 0; + mainmenu['menu']['m001_mode']['menu']['m002_enemy']['marked'] = 1; + end; +end; + + +-- **************************************************************************** +-- * debugmode(arg) +-- * changes debugmode flags +-- * useful for on-the-fly checking, I guess +-- **************************************************************************** +function debugmode(args) + + if debugmodes[args[2]] == false then + debugmodes[args[2]] = true; + mainmenu['menu']['m999_debug']['menu'][args[1]]['marked'] = 1; + else + debugmodes[args[2]] = false; + mainmenu['menu']['m999_debug']['menu'][args[1]]['marked'] = 0; + end; +end; + + + + + +mainmenu = { + test = 1; + life = 0; + width = 54; + menu = { + m001_mode = { + label = "Mode", + life = 0; + width = 50; + menu = { + m001_tiles = { + label = " Objects", + action = modechange, + args = {0}, + marked = 0; + }, + m002_enemy = { + label = " Sprites", + action = modechange, + args = {1}, + marked = 1; + }, + }, + }, + m002_summon = { + label = "Summon", + action = spawnsetup, + args = {1}, + }, + }, +}; + +if debugmodes['enabled'] then + mainmenu['menu']['m999_debug'] = { + label = "Debug", + life = 0; + width = 90; + menu = { + m000_showmouse = { + label = " Draw mouse", + action = debugmode, + marked = debugmodes['drawmouse'] and 1 or 0; + args = {"m000_showmouse", "drawmouse"}, + }, + m001_enemydata = { + label = " Show enemy data", + action = debugmode, + marked = debugmodes['showenemydata'] and 1 or 0; + args = {"m001_enemydata", "showenemydata"}, + }, + m002_locktimer = { + label = " Lock timer", + action = debugmode, + marked = debugmodes['locktimer'] and 1 or 0; + args = {"m002_locktimer", "locktimer"}, + }, + m003_invincible = { + label = " Invincibility", + action = debugmode, + marked = debugmodes['invincible'] and 1 or 0; + args = {"m003_invincible", "invincible"}, + }, + }, + }; +end; + + + + +smbdata = {screenpos = 0}; +mode = 1; +enemyhold = {}; +avgmove = { + { xmouse = 0, ymouse = 0 }, + { xmouse = 0, ymouse = 0 }, + { xmouse = 0, ymouse = 0 }, + calc = {} + }; +spawndata = {}; + +while (true) do + + + input.update(); -- updates mouse position + inputaverage(); -- average movement (for throwing) + + smbdata['screenposold'] = smbdata['screenpos']; + smbdata['screenpos'] = memory.readbyte(0x071a) * 0x100 + memory.readbyte(0x071c); + smbdata['screenposchg'] = smbdata['screenpos'] - smbdata['screenposold']; + smbdata['rendercol'] = memory.readbyte(0x06A0); + if smbdata['screenposchg'] < 0 then + smbdata['screenposchg'] = 0; + end; + timer = timer + 1; + + + if debugmodes['enabled'] then + if control.button( 234, 15, 19, 2, "SET\n999") then + memory.writebyte(0x07F8, 0x09); + memory.writebyte(0x07F9, 0x09); + memory.writebyte(0x07FA, 0x09); + end; + + if debugmodes['locktimer'] then + memory.writebyte(0x0787, 0x1F); + end; + + if debugmodes['invincible'] then + memory.writebyte(0x079E, 0x02); + end; + end; + + + if mode == 0 then + tileview(); + elseif mode == 2 then + + spawnenemy(); + + + else + if debugmodes['showenemydata'] then + text(0, 25 + 0, string.format("E# XPOS YPOS XREL YREL XA YA TY HB")); + end; + + for i=1,6 do + if (memory.readbyte(0x000E+i) ~= 0) then --and memory.readbyte(0x04AC+(i*4)) ~= 0xFF) and (memory.readbyte(0x0015 + i) ~= 0x30 and memory.readbyte(0x0015 + i) ~= 0x31) then + if not enemyhold[i] or not inpt['leftclick'] then + enemyhold[i] = nil; +-- text(8, 50 + i * 8, "-"); + elseif enemyhold[i] then +-- text(8, 50 + i * 8, string.format("HOLD %04X %04X", smbdata['screenpos'] + inpt['xmouse'] - enemyhold[i]['xmouse'], inpt['ymouse'] + 0x100 - enemyhold[i]['ymouse'])); + smbmoveenemy(i, smbdata['screenpos'] + inpt['xmouse'] - enemyhold[i]['x'], inpt['ymouse'] + 0x100 - enemyhold[i]['y'], (avgmove['calc']['xmouse']) * 8, avgmove['calc']['ymouse'] / 2.5); + end; + + e2x1 = memory.readbyte(0x04AC+(i*4)); + e2y1 = memory.readbyte(0x04AC+(i*4)+1); + e2x2 = memory.readbyte(0x04AC+(i*4)+2); + e2y2 = memory.readbyte(0x04AC+(i*4)+3); +-- text(e2x1 - 5, e2y1 - 13, string.format("%02X", memory.readbyte(0x001E + i))); + + + + enemyxpos = memory.readbytesigned(0x006D + i) * 0x0100 + memory.readbyte(0x0086 + i); + enemyypos = memory.readbytesigned(0x00B5 + i) * 0x100 + memory.readbyte(0x00CE + i); + enemyxacc = memory.readbytesigned(0x0057 + i); + enemyyacc = memory.readbytesigned(0x009f + i); + enemyxposa = enemyxpos - smbdata['screenpos']; + enemyyposa = enemyypos - 0x100; + enemyyposa2 = math.fmod(enemyyposa + 0x10000, 0x100); + enemytype = memory.readbyte(0x0015 + i); + enemyhitbox = memory.readbyte(0x0499 + i); + + dead = ""; + if enemyyposa <= -72 + 32 and enemyyacc < -3 then + dead = "UP"; + end; + if math.abs(enemyxacc) >= 0x60 then + dead = dead .. "SIDE"; + end; + if dead ~= "" then + dead = " ".. dead; + end; + + if debugmodes['showenemydata'] then + line(enemyxposa, enemyyposa2, enemyxposa + 16, enemyyposa2, "#ffffff"); + text(enemyxposa, enemyyposa2, memory.readbyte(0x0045 + i)); + text(1, 25 + 8 * i, string.format("E%X %04X %04X %04X %04X %02X %02X %02X %02X %s", i, + AND(enemyxpos, 0xFFFF), + AND(enemyypos, 0xFFFF), + AND(enemyxposa, 0xFFFF), + AND(enemyyposa, 0xFFFF), + AND(enemyxacc, 0xFF), + AND(enemyyacc, 0xFF), + AND(enemytype, 0xFF), + AND(enemyhitbox, 0xFF), + "")); -- dead)); + end; + + if hitbox(inpt['xmouse'], inpt['ymouse'], inpt['xmouse'], inpt['ymouse'], e2x1, e2y1, e2x2, e2y2, "#ffffff", "#0000ff") then +-- if hitbox(inpt['xmouse'], inpt['ymouse'], inpt['xmouse'], inpt['ymouse'], enemyxposa, enemyyposa, enemyxposa + 0xF, enemyyposa + 0x17) then + +-- text(e2x1 - 5, e2y1 - 13, string.format("#%d %02X", i, memory.readbyte(0x0015 + i))); + + + if inpt['leftclick'] then + + if not enemyhold[i] then + enemyhold[i] = { x = inpt['xmouse'] - enemyxposa, y = inpt['ymouse'] - enemyyposa }; + end; + + +-- memory.writebyte(0x001F + i, 0xFF); +-- memory.writebyte(0x04AC + i, 0xFF); +-- memory.writebyte(0x000E + i, 0x00); + end; + end; + else + enemyhold[i] = nil; + + end; + end; + end; + + --[[ + zap = zapper.read(); + + box(zap['xmouse'] - 5, zap['ymouse'] - 5, zap['xmouse'] + 5, zap['ymouse'] + 5, "#ffffff"); + if zap['click'] == 1 then + box(zap['xmouse'] - 7, zap['ymouse'] - 7, zap['xmouse'] + 7, zap['ymouse'] + 7, "#ff0000"); + end; + line(zap['xmouse'] - 0, zap['ymouse'] - 9, zap['xmouse'] + 0, zap['ymouse'] + 9, "#ffffff"); + line(zap['xmouse'] - 9, zap['ymouse'] - 0, zap['xmouse'] + 9, zap['ymouse'] + 0, "#ffffff"); + ]] + + + + -- almost always + if control.button(78, 14, 54, 1, "
") then + mainmenu['life'] = 70; + end; + control.showmenu(78, 25, mainmenu); + + text( 20, 222, " 2009 Xkeeper - http://jul.rustedlogic.net/ "); + line( 21, 231, 232, 231, "#000000"); + + if debugmodes['enabled'] then + text( 41, 214, " Debug version - ".. debugmodes['ver'] .." "); + end; + + + -- always on top + if debugmodes['drawmouse'] then + drawmouse(inpt['xmouse'], inpt['ymouse'], inpt['leftclick']); + end; + FCEU.frameadvance(); + +end \ No newline at end of file diff --git a/output/luaScripts/SMB-Snow.lua b/output/luaScripts/SMB-Snow.lua new file mode 100644 index 00000000..56841324 --- /dev/null +++ b/output/luaScripts/SMB-Snow.lua @@ -0,0 +1,245 @@ +--Super Mario Bros. - It's Snowing! +--Written by XKeeper + + +require("x_functions"); + +if not x_requires then + -- Sanity check. If they require a newer version, let them know. + timer = 1; + while (true) do + timer = timer + 1; + for i = 0, 32 do + gui.drawbox( 6, 28 + i, 250, 92 - i, "#000000"); + end; + gui.text( 10, 32, string.format("This Lua script requires the x_functions library.")); + gui.text( 53, 42, string.format("It appears you do not have it.")); + gui.text( 39, 58, "Please get the x_functions library at"); + gui.text( 14, 69, "http://xkeeper.shacknet.nu/"); + gui.text(114, 78, "emu/nes/lua/x_functions.lua"); + + warningboxcolor = string.format("%02X", math.floor(math.abs(30 - math.fmod(timer, 60)) / 30 * 0xFF)); + gui.drawbox(7, 29, 249, 91, "#ff" .. warningboxcolor .. warningboxcolor); + + FCEU.frameadvance(); + end; + +else + x_requires(4); +end; + + +function smbpx2ram(px, py) + + py = math.floor(py) - 0x20; + px = math.floor(px); + +-- text(90, 16, string.format("PX[%4d] PY[%4d]", px, py)); + if px < 0 or px > 400 or py < 0x00 or py > (240 - 0x20) then + return false; + end; + + oy = math.floor(py / 0x10); + ox = math.fmod(math.floor((px + smbdata['screenpos']) / 0x10), 0x20); + +-- text(90, 16, string.format("CX[%4X] CY[%4X]", ox, oy)); + + offset = 0x500 + math.fmod(oy * 0x10 + math.floor(ox / 0x10) * 0xC0 + math.fmod(ox, 0xD0), 0x1A0); + return offset; + +end; + +function smbram2px(offset) + + offset = offset - 0x500; + if offset < 0 or offset >= 0x1A0 then + return false; + end; + + + px = (math.fmod(offset, 0x10) + math.floor(offset / 0xD0) * 0x10) * 0x10; + px = px - math.fmod(smbdata['screenpos'], 0x200); +-- text(8, 8, string.format("PX[%4d] OF[%4X]", px, offset)); + if px < 0 then + px = px + 0x200; + end; + + py = math.floor(math.fmod(offset, 0xD0) / 0x10); + returnval = {x = px, y = py}; + return returnval; + +end; + + +function doballs() + + count = 0; + for k, v in pairs(balls) do + + v['x'] = v['x'] + v['xs'] - smbdata['screenposchg']; + v['y'] = v['y'] + v['ys']; +-- v['ys'] = v['ys'] - 0.1; + v['life'] = v['life'] - 1; + + offset = smbpx2ram(v['x'], v['y']); + temp = 0; + if offset then + temp = memory.readbyte(offset); + end; + + + -- 354 so we can spawn them offscreen + if v['x'] < 0 or v['x'] > 512 or v['y'] < 0 or v['y'] > 243 or v['life'] < 0 or (temp > 0) then + balls[k] = nil; + else + balls[k] = v; + colkey = math.ceil(255 * (5 - math.max(math.min(5, (v['life'] / 15)), 0)) / 5); + + if v['c'] >= 0 then + color = string.format("#%02X%02X%02X", v['c'], v['c'], 255); +-- color = string.format("#%02X%02X%02X", v['c'] * .8, v['c'] * .5, v['c'] * 0); + else + color = string.format("#%02X0000", v['c'] * -1 , 0, 0); + end; + + if v['life'] > 400 then + box(v['x'] - 1, v['y'] - 1, v['x'] + 1, v['y'] + 1, color); + pixel(v['x'], v['y'], color); + elseif v['life'] > 200 then + box(v['x'], v['y'], v['x'] + 1, v['y'] + 1, color); + else + pixel(v['x'], v['y'], color); + end; + count = count + 1; + end; + end; + + return count; + +end; + + +balls = {}; +z = 0; +timer = 0; +smbdata = {screenpos = 0}; +while (true) do + + if + memory.readbyte(0x0301) == 0x3F and + memory.readbyte(0x0302) == 0x10 and + memory.readbyte(0x0303) == 0x04 and + memory.readbyte(0x0304) == 0x22 + then + memory.writebyte(0x0304, 0x0F); + end; + + smbdata['screenposold'] = smbdata['screenpos']; + smbdata['screenpos'] = memory.readbyte(0x071a) * 0x100 + memory.readbyte(0x071c); + smbdata['screenposchg'] = smbdata['screenpos'] - smbdata['screenposold']; + smbdata['rendercol'] = memory.readbyte(0x06A0); + if smbdata['screenposchg'] < 0 then + smbdata['screenposchg'] = 0; + end; + timer = timer + 1; + + + ballcount = doballs(); + + + for i = 0, 2 do + balls[z] = {x = math.random(0, 512), y = 0, xs = math.random(-50, 00) / 100, ys = math.random(100, 150) / 100, life = math.random(400, 700), c = math.random(200, 255)}; + z = z + 1; + end; + +-- lifebar(8, 8, 240, 2, ballcount, 1000, "#ffffff", "clear"); +--]] + +--[[ + for x = 0x00, 0x0F do + for y = 0x00, 0x0C do + box(x * 0x10 + 0, y * 0x10 + 0x20, x * 0x10 + 0x01, y * 0x10 + 0x21, "#FFFFFF"); + value = memory.readbyte(smbpx2ram(x * 0x10, y * 0x10 + 0x20)); + if value > 0 then + text(x * 0x10 + 0, y * 0x10 + 0x20, string.format("%02X", value)); + end; + end; + end; +]] + +-- text(8, 8, string.format("0x06A0 [%4X]", smbdata['rendercol'])); +--[[ + for i = 0, 5 do + ret = smbram2px(0x500 + i * 0x10 + i); + if ret then +-- text(8, 16, string.format("PX[%4d] PY[%4d]", ret['x'], ret['y'])); + box(ret['x'] + 0, ret['y'] * 0x10 + 0x20, ret['x'] + 0x0F, ret['y'] * 0x10 + 0x2F, "#FFFFFF"); + end; + end; +--]] +--[[ + box(19, 19, 0x20 * 2 + 20, 46, "#0000ff"); + box(18, 18, 0x20 * 2 + 21, 47, "#0000ff"); + for x = 0, 0x1F do + for y = 0, 0x0C do + offset = 0x500 + y * 0x10 + math.floor(x / 0x10) * 0xD0 + math.fmod(x, 0x10); + c = memory.readbyte(offset); + box(x * 2 + 20, y * 2 + 20, x * 2 + 21, y * 2 + 21, string.format("#%02X%02X%02X", c, c, c)); + end; + end; + + if math.fmod(timer, 2) < 1 then + temp = math.floor(math.fmod(smbdata['screenpos'], 0x200) / 8); + if temp < 0x20 then + box(temp + 20, 19, temp + 0x10 * 2 + 20, 46, "#ffffff"); + else + box(temp + 20, 19, 0x20 * 2 + 20, 46, "#ffffff"); + box(19, 19, (temp - 0x20) + 20, 46, "#ffffff"); + end; + + line(smbdata['rendercol'] * 2 + 20, 19, smbdata['rendercol'] * 2 + 20, 46, "#00ff00"); + end; + +--]] +--[[ + x = 0; + y = 0; + px = math.sin(timer / 60) * 100 + 127; + py = math.cos(timer / 60) * 90 + 100 + 0x20; + offset = smbpx2ram(px, py); + if offset then + offset = offset - 0x500; + x = math.floor(offset / 0xD0) * 0x10 + math.fmod(offset, 0x10); + y = math.floor(math.fmod(offset, 0xD0) / 0x10); + + x2 = math.fmod(smbdata['screenpos'] + x * 0x10, 0x100); + box( x2, y * 0x10 + 0x20, x2 + 0x0F, y * 0x10 + 0x2F, "#ffffff"); +-- line( 0, y * 0x10, 255, y * 0x10, "#ffffff"); + + box (px - 3, py - 3, px + 3, py + 3, "#ffffff"); + line(px - 6, py , px + 6, py , "#ffffff"); + line(px , py - 6, px , py + 6, "#ffffff"); + text(90, 24, string.format("Offset[%04X]", offset + 0x500)); + text(90, 32, string.format("OX[%4X] OY[%4X]", x, y)); + text(90, 40, string.format("SX[%4X]", x2)); + else + text(90, 24, "Offset failed"); + end; + + if math.fmod(timer, 2) < 1 then + temp = math.floor(math.fmod(smbdata['screenpos'], 0x200) / 8) + 20; + line(temp, 18, temp, 47, "#ffffff"); + box(20 + x * 2, 20 + y * 2, 21 + x * 2, 21 + y * 2, "#ffffff"); + + end; + +--]] + + + text( 20, 222, " 2009 Xkeeper - http://jul.rustedlogic.net/ "); + line( 21, 231, 232, 231, "#000000"); + + FCEU.frameadvance(); + +end; + diff --git a/output/luaScripts/vnb.lua b/output/luaScripts/vnb.lua new file mode 100644 index 00000000..f7791b0d --- /dev/null +++ b/output/luaScripts/vnb.lua @@ -0,0 +1,613 @@ + +-- Valkyrie no Bouken stuffs +-- This game sucks, don't play it +-- Lovingly based off of 4matsy's SMB code, and then mutilated and mamed as required +-- Xkeeper 2008, September 12th + + +require("x_functions"); +x_requires(4); + + + + + + +-- ************************************************************************************ +-- ************************************************************************************ +-- ************************************************************************************ + + + +function mapdot(x,y,color) + if (x >= 1 and x <= 254 and y >= 1 and y <= 239) then + gui.drawline(x - 1, y , x + 1, y , color); + gui.drawline(x , y - 1, x , y + 2, color); + end; +end; + + +-- ************************************************************************************ +-- ************************************************************************************ +-- ************************************************************************************ + +function doexp() + + totalexp = vnbnumber(0x00d5, 5); + growth = memory.readbyte(0x0111); + level = memory.readbyte(0x00b9); + nextlv = memory.readbyte(0x00bb); + prevexp = -1; + + if level ~= 0 then + + if nextlv < 0x14 then + nextexp = exptable[nextlv + 1]; + else + prevexp = math.floor(totalexp / 10000) * 10000; + nextexp = math.floor(totalexp / 10000) * 10000 + 10000; + end; + + if growth < 3 and prevexp == -1 then +-- prevexp = exptable[leveltable[growth][level] + 1]; + + end; + + expval = {}; + expval["level"] = level; + expval["next"] = nextexp - totalexp; + expval["prev"] = prevexp; + expval["pct"] = math.floor((totalexp - prevexp) / (nextexp - prevexp) * 100); + expval["exp"] = totalexp; + + if prevexp == -1 then + expval["pct"] = -1; + end; + + else + + expval = {}; + expval["level"] = 0; + expval["next"] = 0; + expval["prev"] = 0; + expval["pct"] = 0; + expval["exp"] = 0; + + end; + + return expval; +end; + + + + + +-- ************************************************************************************ +-- ************************************************************************************ +-- ************************************************************************************ + +function vnbnumber(offset, length) + val = 0; + + for i = 0, length do + inp = memory.readbyte(offset + (i)); + if (inp ~= 0x26) then val = val + inp * (10 ^ i); end; + end; + + return val; +end; + + + + + + +-- ************************************************************************************ +-- ************************************************************************************ +-- ************************************************************************************ + +function worldmap() + + herox = memory.readbyte(0x0080) + memory.readbyte(0x0081) * 256; -- hero's X position + heroy = memory.readbyte(0x0082) + memory.readbyte(0x0083) * 256; -- hero's current MP + + if mapstyle == 1 then + mapx = 8; + mapy = 9; + mapw = 60; + maph = 37; + elseif mapstyle == 2 or mapstyle == 3 then + + mapx = 8; + mapy = 34; + mapw = 240; + maph = 147; + + else + return nil; + end; + + if gamemode == 0x05 or gamemode == 0x01 or gamemode == 0x06 or gamemode == 0x08 then + + maphx = math.ceil(herox / 3840 * mapw); + maphy = math.ceil(heroy / 2352 * maph); + + +-- filledbox(mapx - 1, mapy - 1, mapx + mapw + 1, mapy + maph, "#000000"); + box(mapx - 1, mapy - 1, mapx + mapw + 1, mapy + maph, "#ffffff"); + + if mapstyle == 3 then + for i = 0, 0xFF do + + mappx = math.ceil((3840 / 16) * math.fmod(i, 0x10) / 3840 * mapw); + mappy = math.ceil((2352 / 16) * math.floor(i / 0x10) / 2352 * maph); + mappx2 = math.ceil((3840 / 16) * (math.fmod(i, 0x10) + 1) / 3840 * mapw) - 1; + mappy2 = math.ceil((2352 / 16) * (math.floor(i / 0x10) + 1) / 2352 * maph) - 1; + tmp = memory.readbyte(0x81E5 + i) * 2; + filledbox(mapx + mappx, mapy + mappy, mapx + mappx2, mapy + mappy2, string.format("#%02x%02x%02x", tmp, tmp, tmp)); + + end; + end; + + if math.fmod(timer, 60) >= 30 then + color = "#888888"; + else + color = "#bbbbbb"; + end; + + +-- line(mapx, mapy + maphy, mapx + mapw, mapy + maphy, "#cccccc"); +-- line(mapx + maphx, mapy, mapx + maphx, mapy + maph, "#cccccc"); + + mapdist = 51; + for i = 1, mappoints do + mappx = math.ceil(mapdots[i]["x"] / 3840 * mapw); + mappy = math.ceil(mapdots[i]["y"] / 2352 * maph); + mapdot(mapx + mappx, mapy + mappy, mapdots[i]["color"]); + if mapdots[i]["name"] then + mapdotdist = math.abs(mapdots[i]["x"] - herox) + math.abs(mapdots[i]["y"] - heroy); + if mapdotdist < mapdist then + mapdist = mapdotdist; + mapdistn = mapdots[i]["name"]; + end; + end; + end; + + if mapdist <= 50 then + text(90, 17, mapdistn); + end; + filledbox(mapx + maphx - 0, mapy + maphy - 0, mapx + maphx + 0, mapy + maphy + 0, "#ffffff"); + box(mapx + maphx - 1, mapy + maphy - 1, mapx + maphx + 1, mapy + maphy + 1, color); + +-- text(mapx + 0, mapy + maph + 2, string.format("%04d, %04d", herox, heroy)); + + + end; +end; + + + +-- ************************************************************************************ +-- ************************************************************************************ +-- ************************************************************************************ + +function gameloop() + + if gamemode == 0x01 and math.fmod(timer, 60) >= 30 then + text(105, 180, "< DEMO >"); + end; + + + herohp = memory.readbyte(0x00c0) + memory.readbyte(0x00c1) * 256; -- hero's current HP + heromp = memory.readbyte(0x00c2) + memory.readbyte(0x00c3) * 256; -- hero's current MP + heromaxhp = memory.readbyte(0x00c4) + memory.readbyte(0x00c5) * 256; -- hero's maximum HP + heromaxmp = memory.readbyte(0x00c6) + memory.readbyte(0x00c7) * 256; -- hero's maximum MP + money = vnbnumber(0x00d0, 4); + gametime = memory.readbyte(0x0031) * 0x3c + memory.readbyte(0x0030); -- game-time + gamehour = math.floor(gametime / 320); + gameminute = math.floor((gametime - 320 * gamehour) / 320 * 60); + expval = doexp(); + + worldmap(); + + filledbox(96, 194, 255, 244, "#000000"); + + text(191, 8, string.format("Time: %02d:%02d", gamehour, gameminute)); +-- text(188, 23, string.format("GameMode: %02x", gamemode)); + + text( 90, 194, string.format("HP %3d/%3d MP %3d/%3d", herohp, heromaxhp, heromp, heromaxmp)); + if expval["next"] > 0 then + text( 90, 218, string.format("Lv.%2d: %6d XP Next %6d", expval["level"], expval["exp"], expval["next"])); + else + text( 90, 218, string.format("Lv.%2d: %6d EXP", expval["level"], expval["exp"])); + end; + + + text(217, 202, string.format("ATK %2d", memory.readbyte(0x00e7))); + text(217, 210, string.format("$%5d", money)); + + + lifebar(191, 16, 60, 2, gamehour, 24, "#ffffff", "#777777", true); + lifebar(191, 20, 60, 0, gameminute, 60, "#cccccc", "#555555", true); + lifebar( 90, 202, 123, 4, herohp, heromaxhp, "#ffcc00", "#880000", true); + lifebar( 90, 208, 123, 3, heromp, heromaxmp, "#9999ff", "#0000dd", true); + + if expval["pct"] ~= -1 then + lifebar( 90, 226, 162, 2, expval["pct"], 100, "#ffffff", "#555555", true); + end; + + box(89, 194, 91, 244, "#000000"); + line(90, 194, 90, 244, "#000000"); + + + if not enemy then enemy = {} end; + + if gamemode == 0x05 or gamemode == 0x01 or gamemode == 0x06 then + for i = 0, 5 do + + offset = 0x500 + 0x10 * i; + + if not enemy[i] then + enemy[i] = {}; + end; + + if (memory.readbyte(offset) > 0) then + + if not enemy[i]["maxhp"] then enemy[i]["maxhp"] = 0 end; + + enemy[i]["t"] = memory.readbyte(offset); + enemy[i]["x"] = memory.readbyte(offset + 5); + enemy[i]["y"] = memory.readbyte(offset + 6); + enemy[i]["hp"] = memory.readbyte(offset + 15); + enemy[i]["maxhp"] = math.max(enemy[i]["maxhp"], enemy[i]["hp"]); + + enemy[i]["item"] = memory.readbyte(offset + 10); + + if enemy[i]["t"] > 1 then + text(enemy[i]["x"] - 9, enemy[i]["y"] - 16, enemy[i]["hp"] .."/".. enemy[i]["maxhp"]); + lifebar(enemy[i]["x"] - 5, enemy[i]["y"] - 8, 22, 0, enemy[i]["hp"], enemy[i]["maxhp"], "#ffcc00", "#dd0000", false); + else + if (enemy[i]["item"] == 0x1C) then + if enemy[i]["hp"] == 0 then enemy[i]["hp"] = 10 end; + if enemy[i]["hp"] == 9 then enemy[i]["hp"] = 99 end; + text(enemy[i]["x"] - 6 - math.min(math.floor(enemy[i]["hp"] / 10) * 2, 2), enemy[i]["y"] - 8, "$".. enemy[i]["hp"]); + else + box(enemy[i]["x"], enemy[i]["y"], enemy[i]["x"] + 15, enemy[i]["y"] + 15, "#ffffff"); + text(enemy[i]["x"] - string.len(itemlist[enemy[i]["item"]]) * 1.75 + 0, enemy[i]["y"] - 8, itemlist[enemy[i]["item"]]); + + end; + end; + + else + enemy[i] = {}; + + end; + end; + end; + + for i = 0, 7 do + offset = 0x0160 + 0x02 * i; + item = memory.readbyte(offset + 1); + uses = memory.readbyte(offset + 1); + xo = math.fmod(i, 4); + yo = math.floor(i / 4); + if (item > 0 and (uses > 0 and uses < 255)) then + text(xo * 12 + 8, 194 + yo * 16, uses); + end; + end; + + + + +--[[-- auto-regenerate HP + if (herohp < heromaxhp) and ((math.fmod(timer, 3) == 0) or true) then + herohp = herohp + 1; + memory.writebyte(0x00c0, math.fmod(herohp, 256)); + memory.writebyte(0x00c1, math.floor(herohp / 256)); + end; +--]]-- + + + +--[[ basically the Big Cheating Section. + + if not expbooster then expbooster = 0 end; + expbooster = expbooster + 1; + if expbooster >= 3 and gamemode == 0x06 then + expbooster = 0; + memory.writebyte(0x0d5, memory.readbyte(0x00d5) + 1); + + for i = 0,5 do + inp = memory.readbyte(0x00d5 + i); + if (inp == 0x0a) then + memory.writebyte(0x00d5 + (i + 1), memory.readbyte(0x00d5 + (i + 1)) + 1); + memory.writebyte(0x00d5 + i, 0); + + elseif (inp == 0x27) then + memory.writebyte(0x00d5 + i, 1); + + end; + end; + end; +]]-- +end; + + + + +-- ************************************************************************************ +-- ************************************************************************************ +-- ************************************************************************************ + +function charaselect() + asign = memory.readbyte(0x0110); + btype = memory.readbyte(0x0111); + +-- line( 92, 30, 92, 130, "#ffffff"); + + + filledbox( 13, 48, 96, 64, "#000000"); -- cover JP text + filledbox( 13, 80, 96, 96, "#000000"); -- cover JP text + filledbox( 13, 112, 96, 128, "#000000"); -- cover JP text + filledbox(160, 48, 231, 64, "#000000"); -- cover JP text + + text( 74, 24, " Create your character "); + + text( 15, 51, "Astrological sign:"); + text(158, 51, string.format("%s", asigns[asign])); + + text( 41, 83, "Blood type:"); +-- text(164, 83, string.format("%s (%X)", btypes[btype], btype)); + + text( 26, 115, "Clothing color:"); + + + asign2 = math.fmod(asign, 4); + if asign2 == 0 then + shp = 64; + smp = 32; + elseif asign2 == 1 then + shp = 48; + smp = 48; + elseif asign2 == 2 then + shp = 32; + smp = 64; + elseif asign2 == 3 then + shp = 33; + smp = 63; + end; + + strength = 10 + math.floor(shp / 32); + + text( 8, 135, "Starting HP: "); + text( 8, 143, "Starting MP: "); + text(167, 135, " ".. shp); + text(167, 143, " ".. smp); + lifebar( 68, 136, 100, 4, shp, 64, "#ffcc00", "#880000"); + lifebar( 68, 144, 100, 4, smp, 64, "#9999ff", "#0000dd"); + + text(194, 136, "Strength: ".. strength); + text(194, 146, "Magic:"); + if smp >= 60 then + text(204, 162, "Fireball"); + end; + if smp >= 40 then + text(204, 154, "Heal"); + end; + + + + graphx = 17; + graphy = 160; + + text(graphx - 10, graphy + 63, "Lv."); + + for i = 1, 12 do + thispointx = i * 15 + graphx; + line(thispointx, graphy, thispointx, graphy + 63, "#000088"); + text(thispointx - 4 - (string.len(string.format("%d", i)) - 1) * 3, graphy + 63, string.format("%d", i)); + end; + + + for i = 0, 7 do + lg = i * 3; + thispointy = graphy + 63 - (lg) * 3; + line(graphx + 15, thispointy, graphx + 180, thispointy, "#000088"); + + if exptable[lg] then + temp = string.format("%d", exptable[lg]); + text(graphx - 17, thispointy - 4, string.format("%5d", exptable[lg])); + end; + + end; + + line(graphx + 15, graphy , graphx + 15, graphy + 63, "#9999ff"); + line(graphx + 15, graphy + 63, graphx + 180, graphy + 63, "#9999ff"); + +-- filledbox(graphx + 19, graphy + 1, graphx + 73, graphy + 8, "#666666"); + text(graphx + 16, graphy - 1, "EXP Growth"); + + if btype <= 2 then + + lastpointx = graphx; + lastpointy = graphy + 180; + for i = 1, 12 do + thispointx = i * 15 + graphx; + thispointy = graphy + 63 - (leveltable[btype][i] * 3); + line(lastpointx, lastpointy, thispointx, thispointy, "#ffffff"); + lastpointx = thispointx; + lastpointy = thispointy; + end; + + else + +-- filledbox(graphx + 75, graphy + 27, graphx + 119, graphy + 35, "#666666"); + text(graphx + 74, graphy + 26, " Random "); + + + end; + + line(194, 145, 254, 145, "#000000"); + line( 8, 153, 192, 153, "#000000"); + +end; + + + + + +-- ************************************************************************************ +-- ************************************************************************************ +-- ************************************************************************************ + +function keyintercept() + tmp = memory.readbyte(0x0026); + + if AND(tmp, 0x04) == 0x04 then + mapstyle = math.fmod(mapstyle + 1, 3) + end; + +-- memory.writebyte(0x0026, AND(tmp, 0xFB)); +end; + +memory.register(0x0026, keyintercept); + + + + + + + + +timer = 0; +mapstyle = 1; -- 0 = hidden, 1 = mini, 2 = bigmap +gamemode = 0; + +itemlist = {}; +itemlist[0x01] = "Lantrn"; +itemlist[0x02] = "Lantrn2"; +itemlist[0x03] = "Potion"; +itemlist[0x04] = "Potion2"; +itemlist[0x05] = "Antidt"; +itemlist[0x06] = "Antidt2"; +itemlist[0x07] = "Key"; +itemlist[0x08] = "GoldKey"; +itemlist[0x09] = "Ax"; +itemlist[0x0a] = "Ax2"; +itemlist[0x0b] = "Sword"; +itemlist[0x0c] = "Sword2"; +itemlist[0x0d] = "PwSword"; +itemlist[0x0e] = "PwSword2"; +itemlist[0x0f] = "MsSword"; +itemlist[0x10] = "SandraSl"; +itemlist[0x11] = "Mantle"; +itemlist[0x12] = "Mantle2"; +itemlist[0x13] = "Helmet"; +itemlist[0x14] = "Helmet2"; +itemlist[0x15] = "Tent"; +itemlist[0x16] = "Tent2"; +itemlist[0x17] = "Tiara"; +itemlist[0x18] = "Whale"; +itemlist[0x19] = "CureAll"; +itemlist[0x1a] = "TimeKey"; +itemlist[0x1b] = "Ship"; +itemlist[0x1c] = "Cash"; + +exptable = { + 0, + 20, + 50, + 90, + 150, + 230, + 350, + 510, + 750, + 1100, + 1600, + 2200, + 3200, + 4400, + 6400, + 9000, + 12000, + 15000, + 20000, + 30000, + 40000, + 50000, + }; + +leveltable = {}; +leveltable[0] = { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x13, 0x14}; +leveltable[1] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x07, 0x0A, 0x0D, 0x10, 0x13, 0x14, 0x15}; +leveltable[2] = { 0x00, 0x03, 0x06, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13}; + +asigns = {}; +asigns[0x00] = "Aries"; +asigns[0x01] = "Taurus"; +asigns[0x02] = "Gemini"; +asigns[0x03] = "Cancer"; +asigns[0x04] = "Leo"; +asigns[0x05] = "Virgo"; +asigns[0x06] = "Libra"; +asigns[0x07] = "Scorpio"; +asigns[0x08] = "Sagittarius"; +asigns[0x09] = "Capricorn"; +asigns[0x0A] = "Aquarius"; +asigns[0x0B] = "Pisces"; + +btypes = {}; +btypes[0x00] = "A"; +btypes[0x01] = "B"; +btypes[0x02] = "O"; +btypes[0x03] = "AB"; + + +mapdots = {}; +mapdots[1] = {x = 996, y = 1888, color = "#4444ff"}; -- house +mapdots[2] = {x = 773, y = 989, color = "#4444ff"}; -- house + +mapdots[3] = {x = 266, y = 2263, color = "#00ff00"}; -- warp point +mapdots[4] = {x = 1800, y = 216, color = "#00ff00"}; -- warp point +mapdots[5] = {x = 776, y = 344, color = "#00ff00"}; -- warp point +mapdots[6] = {x = 2055, y = 2008, color = "#00ff00"}; -- warp point + +mapdots[7] = {x = 1863, y = 2045, color = "#dd0000", name = "South Pyramid"}; -- s.pyramid +mapdots[8] = {x = 1607, y = 381, color = "#dd0000", name = "North Pyramid"}; -- n.pyramid + + + +mappoints = table.maxn(mapdots); + +while (true) do + + + timer = timer +1; -- timer for script events + + gamemode = memory.readbyte(0x0029); -- game mode + + + if gamemode == 0x05 or gamemode == 0x01 or gamemode == 0x06 or gamemode == 0x08 then + gameloop(); + + elseif gamemode == 0x02 then + charaselect(); + else + +-- gametime = memory.readbyte(0x0031) * 0x3c + memory.readbyte(0x0030); -- game-time +-- gamehour = math.floor(gametime / 320); +-- gameminute = math.floor((gametime - 320 * gamehour) / 320 * 60); + + gametimer1 = memory.readbyte(0x0031); + gametimer2 = memory.readbyte(0x0030); + + text(190, 8, string.format("Timer: %02X %02X", gametimer1, gametimer2)); + text(189, 23, string.format("GameMode: %02x", gamemode)); + lifebar(191, 16, 60, 2, gametimer1, 0x80, "#ffffff", "#777777", true); + lifebar(191, 20, 60, 0, gametimer2, 0x3c, "#cccccc", "#555555", true); + end; + + FCEU.frameadvance(); + +end; diff --git a/output/luaScripts/x_functions.lua b/output/luaScripts/x_functions.lua index 955edc2a..a6d01c24 100644 --- a/output/luaScripts/x_functions.lua +++ b/output/luaScripts/x_functions.lua @@ -1,14 +1,15 @@ ---x_functions - various functions needed for scripts witten by Xkeeper ---Written by Xkeeper -x_func_version = 5; +x_func_version = 6; --[[ Minor version history: - v 5 ----------- + v5 ----------- - Added Bisqwit's 'clone table' function. - + + v6 ----------- + - added pairs by keys + - added hitbox functions @@ -50,7 +51,12 @@ end; -- Draws a rectangle from x1,y1 to x2, y2 function box(x1,y1,x2,y2,color) if (x1 >= 0 and x1 <= 255 and x2 >= 0 and x2 <= 255 and y1 >= 0 and y1 <= 244 and y2 >= 0 and y2 <= 244) then - gui.drawbox(x1,y1,x2,y2,color); +--[[ local success = pcall(function() gui.drawbox(x1,y1,x2,y2,color); end); + if not success then + text(60, 150, string.format("%3d %3d %3d %3d", x1, y1, x2, y2)); + FCEU.pause(); + end; +]] gui.drawbox(x1,y1,x2,y2,color); end; end; @@ -147,6 +153,87 @@ table.clone = function(table) return res end +spairs = function (t, f) + local a = {} + for n in pairs(t) do table.insert(a, n) end + table.sort(a, f) + local i = 0 -- iterator variable + local iter = function () -- iterator function + i = i + 1 + if a[i] == nil then return nil + else return a[i], t[a[i]] + end + end + return iter +end + + +-- **************************************************************************** +-- * hitbox( coords1, coords2, con, coff ) +-- * Checks if any point of coords1 is within coords2. +-- * con/coff determine what colors of box to draw. +-- **************************************************************************** +function hitbox(b1x1, b1y1, b1x2, b1y2, b2x1, b2y1, b2x2, b2y2, con, coff) + + if not b1x1 then + text(0, 8, "ERROR!!!!"); + return; + end; + + local noboxes = false; + if con == nil and coff == nil then + noboxes = true; + else + if coff == nil then + coff = "#00ff00" + end; + + if con == nil then + con = "#dd0000"; + end; + if coff == nil then + coff = "#00ff00" + end; + end; + + boxes = {{ + x = {b1x1, b1x2}, + y = {b1y1, b1y2}, + }, { + x = {b2x1, b2x2}, + y = {b2y1, b2y2}, + }}; + + hit = false; + + for xc = 1, 2 do + for yc = 1, 2 do + + if (boxes[1]['x'][xc] >= boxes[2]['x'][1]) and + (boxes[1]['y'][yc] >= boxes[2]['y'][1]) and + (boxes[1]['x'][xc] <= boxes[2]['x'][2]) and + (boxes[1]['y'][yc] <= boxes[2]['y'][2]) then + + hit = true; + -- TODO: make this break out of the for loop? might not be worth it + end; + end; + end; + + if hit == true then + if not noboxes then box(b2x1, b2y1, b2x2, b2y2, con); end; + return true; + else + if not noboxes then box(b2x1, b2y1, b2x2, b2y2, coff); end; + return false; + end; + + return true; + +end; + + + function x_requires(required) -- Sanity check. If they require a newer version, let them know. timer = 1; @@ -162,7 +249,7 @@ function x_requires(required) text( 10, 32, string.format("This Lua script requires version %02d or greater.", required)); text( 43, 42, string.format("Your x_functions.lua is version %02d.", x_func_version)); text( 29, 58, "Please check for an updated version at"); - text( 14, 69, "http://xkeeper.shacknet.nu/"); + text( 14, 69, "http://xkeeper.shacknet.nu:5/"); text(114, 78, "emu/nes/lua/x_functions.lua"); warningboxcolor = string.format("%02X", math.floor(math.abs(30 - math.fmod(timer, 60)) / 30 * 0xFF)); diff --git a/output/luaScripts/x_interface.lua b/output/luaScripts/x_interface.lua new file mode 100644 index 00000000..b2b333c9 --- /dev/null +++ b/output/luaScripts/x_interface.lua @@ -0,0 +1,116 @@ +-- **************************************************************************** +-- * +-- * FCEUX Lua GUI tools +-- * +-- **************************************************************************** + + +control = {}; + +last = {}; +inpt = { xmouse = 0, ymouse = 0 }; + +-- **************************************************************************** +-- * input.update() +-- * Updates input changes and calculates mouse movement averages. +-- **************************************************************************** +function input.update() + + last = table.clone(inpt); + inpt = input.get(); + +end; + + +-- **************************************************************************** +-- * control.button( xpos, ypos, width, height, t ) +-- * Draws a button that can have some effect. Not quite implemented yet! +-- * width/height are for the outline and more or less have to be set manually. +-- * since height is fixed, though, it's always a multiple. +-- * c disables hitbox checking and sets the outline to that color +-- **************************************************************************** +function control.button(x, y, w, h, t, c, sc) + local h = h * 8; + filledbox( x , y , x + w , y + h , "#000000"); + text(x - 1, y - 1, t); -- Yeah, for some reason... + + if c and not sc then + box( x - 1, y - 1, x + w + 1, y + h + 1, c); + elseif c then + return (hitbox(inpt['xmouse'], inpt['ymouse'], inpt['xmouse'], inpt['ymouse'], x - 1, y - 1, x + w + 1, y + h + 1, c, c) and (inpt['leftclick'] and not last['leftclick'])); + + elseif hitbox(inpt['xmouse'], inpt['ymouse'], inpt['xmouse'], inpt['ymouse'], x - 1, y - 1, x + w + 1, y + h + 1, "#6666ff", "#0000ff") and (inpt['leftclick'] and not last['leftclick']) then + box(x - 1, y - 1, x + w + 1, y + h + 1, "#ffffff"); -- for white-flash highlighting + return true; + end; + return false; + +end; + + + +-- **************************************************************************** +-- * control.showmenu( xpos, ypos, menutable ) +-- * Displays the given menu and takes action on it. Usually. +-- **************************************************************************** +function control.showmenu(x, y, menuinfo) + + + if menuinfo['life'] > 0 then + local temp = 0; + local i = 0; + local yscale = 11 - math.max(0, menuinfo['life'] - 60); +-- text(x, y - 11, string.format("Life: %3d", menuinfo['life'])); + + for k, v in spairs(menuinfo['menu']) do + + local buttoncolor = nil; + if v['menu'] and v['life'] > 0 then + buttoncolor = "#ffffff"; + end; + + buttonclicked = control.button(x, y + yscale * i, menuinfo['width'], 1, v['label'], buttoncolor, true); + if v['menu'] then + text(x + menuinfo['width'] - 6, y + yscale * i - 1, ">"); + end; + if v['marked'] == 1 then + text(x, y + yscale * i - 1, ">"); + end; + + -- is a selection, not a submenu + if buttonclicked and v['action'] then + v['action'](v['args']); + menuinfo['life'] = 0; + return -1; + + -- a submenu + elseif buttonclicked and v['menu'] then + v['life'] = 70; + end; + + if v['menu'] and v['life'] > 0 and temp >= 0 then + temp2 = control.showmenu(x + menuinfo['width'] + 3, y + yscale * i, v); + if temp2 >= 0 then + temp = math.max(temp, temp2); + else + temp = temp2; + end; + end; + + i = i + 1; + + end; + if temp >= 0 and hitbox(inpt['xmouse'], inpt['ymouse'], inpt['xmouse'], inpt['ymouse'], x, y, x + menuinfo['width'] + 2, y + i * yscale) then + menuinfo['life'] = math.max(menuinfo['life'] - 1, 60); + elseif temp == -1 or (menuinfo['life'] < 60 and inpt['leftclick'] and not last['leftclick']) then + menuinfo['life'] = 0; + return 0; + else + menuinfo['life'] = math.max(math.min(60, temp), menuinfo['life'] - 1); + end; + end; + + return menuinfo['life']; + +end; + diff --git a/output/luaScripts/x_smb1enemylist.lua b/output/luaScripts/x_smb1enemylist.lua new file mode 100644 index 00000000..661aa7e0 --- /dev/null +++ b/output/luaScripts/x_smb1enemylist.lua @@ -0,0 +1,44 @@ +-- temporary file because this will be huge. + +handles = {}; + +handles[ 1] = { x1 = 0, y1 = 0, x2 = 16, y2 = 24 }; -- Green & Red Koopa +handles[ 2] = { x1 = 0, y1 = 8, x2 = 16, y2 = 24 }; -- Goomba +handles[ 3] = { x1 = 0, y1 = 0, x2 = 16, y2 = 16 }; -- generic 16x16 +handles[ 4] = { x1 = 0, y1 = 0, x2 = 8, y2 = 8 }; -- generic 8x 8 + + +enemylist = {}; + +-- type: +-- Default (0): selectable, standard +-- + 0x01: requires special handling +-- + 0x02: can't be selected (dupe, whatever) +-- + 0x10: requires two spaces to summon +-- + 0x20: powerup +--[[ +enemylist[] = { id = 0x00, name = "Green Koopa", handle = 1, hitbox = 0x03, type = 0x00 }; +enemylist[] = { id = 0x01, name = "Red Koopa", handle = 1, hitbox = 0x03, type = 0x01 }; -- Will jitter back and forth if moved into air + +enemylist[] = { id = 0x06, name = "Goomba", handle = 2, hitbox = 0x09, type = 0x00 }; +enemylist[] = { id = 0x07, name = "Blooper", handle = 1, hitbox = 0x09, type = 0x01 }; -- Uhh? It just vanishes out of nowhere... + +enemylist[] = { id = 0x0A, name = "Gray Cheep-Cheep", handle = 2, hitbox = 0x09, type = 0x00 }; +enemylist[] = { id = 0x0B, name = "Red Cheep-Cheep", handle = 2, hitbox = 0x09, type = 0x00 }; + +enemylist[] = { id = 0x0D, name = "Pirahna Plant", handle = 1, hitbox = 0x09, type = 0x01 }; -- x speed is really y speed, main position needs hacked +enemylist[] = { id = 0x0E, name = "Green Paratroopa", handle = 1, hitbox = 0x03, type = 0x00 }; + +enemylist[] = { id = 0x14, name = "Flying Cheepcheep", handle = 2, hitbox = 0x09, type = 0x00 }; + + +enemylist[] = { id = 0x2E, name = "Mushroom", handle = 3, hitbox = 0x03, type = 0x20, powerupval = 0x00 }; +enemylist[] = { id = 0x2E, name = "Flower", handle = 3, hitbox = 0x03, type = 0x20, powerupval = 0x01 }; +enemylist[] = { id = 0x2E, name = "Starman", handle = 3, hitbox = 0x03, type = 0x20, powerupval = 0x02 }; +enemylist[] = { id = 0x2E, name = "1-up Mushroom", handle = 3, hitbox = 0x03, type = 0x20, powerupval = 0x03 }; +enemylist[] = { id = 0x30, name = "Flagpole flag", handle = 3, hitbox = -1, type = 0x20 }; +enemylist[] = { id = 0x31, name = "Castle flag", handle = 3, hitbox = -1, type = 0x00 }; +enemylist[] = { id = 0x32, name = "Springboard", handle = 1, hitbox = -1, type = 0x00 }; + + +]] \ No newline at end of file