--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;