354 lines
10 KiB
Lua
354 lines
10 KiB
Lua
--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;
|
|
|