Added a lot of luaScripts by XKeeper
This commit is contained in:
parent
d2a3b310b3
commit
24f1e23c47
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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, "<Main Menu>") 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
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
|
@ -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:
|
Minor version history:
|
||||||
|
|
||||||
v 5 -----------
|
v5 -----------
|
||||||
- Added Bisqwit's 'clone table' function.
|
- 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
|
-- Draws a rectangle from x1,y1 to x2, y2
|
||||||
function box(x1,y1,x2,y2,color)
|
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
|
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;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -147,6 +153,87 @@ table.clone = function(table)
|
||||||
return res
|
return res
|
||||||
end
|
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)
|
function x_requires(required)
|
||||||
-- Sanity check. If they require a newer version, let them know.
|
-- Sanity check. If they require a newer version, let them know.
|
||||||
timer = 1;
|
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( 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( 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( 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");
|
text(114, 78, "emu/nes/lua/x_functions.lua");
|
||||||
|
|
||||||
warningboxcolor = string.format("%02X", math.floor(math.abs(30 - math.fmod(timer, 60)) / 30 * 0xFF));
|
warningboxcolor = string.format("%02X", math.floor(math.abs(30 - math.fmod(timer, 60)) / 30 * 0xFF));
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
||||||
|
|
||||||
|
]]
|
Loading…
Reference in New Issue