--Used for scripts written by Miau such as Gradius-BulletHell --[[ A Compilation of general-purpose functions. -]] M_UTILS_VERSION = 0 --initialization if(FCEU) then EMU = FCEU elseif(snes9x) then EMU = snes9x elseif(gens) then EMU = gens end if(EMU == nil) then error("Unsupported environment. This script runs on Lua-capable emulators only - FCEUX, Snes9x or Gens.") end --[[ m_require "require" with version checking Similar to the approach in Xk's x_functions.lua, but supports loading and automatic version checking of "compatible" modules, too. A central version checking function does have its advantages. A compatible module looks like this: if(REQUIRED_MODULE_VERSION==0) then --global variable = the second parameter of m_require error("This module isn't backwards compatible to version 0.") end module("modulename") MODULE_VERSION = 3 function test() end return _M using it in your code: m_require("modulefile.lua",3) --second parameter being > MODULE_VERSION would raise an error modulename.test() -]] function m_require(module,requiredver) if(module==nil or module=="m_utils") then if(M_UTILS_VERSION>=requiredver) then return true else error("\n\nThis script requires m_utils version "..requiredver..".\n".. "Your m_utils.lua is version "..M_UTILS_VERSION.."\n".. "Check http://morphcat.de/lua/ for a newer version.") end else --give the module the possibility to be backwards compatible --not very elegant, but there seems to be no other way using require REQUIRED_MODULE_VERSION = requiredver local ret = require(module) if(requiredver==nil) then --got no version checking to do return ret elseif(ret==nil or ret==false) then error("Could not load module "..module.." or module invalid.") elseif(type(ret)~="table") then error("Invalid module "..module..", doesn't return itself.") elseif(ret.MODULE_VERSION==nil) then error("Invalid module "..module..", missing version information.") elseif(ret.MODULE_VERSION < requiredver) then error("\n\nThis script requires "..module.." version "..requiredver..".\n".. "Your "..module.." module is version "..ret.MODULE_VERSION..".\n".. "If it's one of miau's Lua modules check\n".. "http://morphcat.de/lua/ for a newer version.\n") else return ret end end end --drawing functions with bounds checking function bcbox(x1,y1,x2,y2,color1) if(x1>=0 and y1>=0 and x2<=255 and y2<=255) then gui.drawbox(x1, y1, x2, y2, color1, 0) end end function bcpixel(x,y,color) if(x>=0 and y>=0 and x<=255 and y<=255) then gui.drawpixel(x,y,color) end end function bcline(x1,y1,x2,y2,color) if(x1>=0 and y1>=0 and x2<=255 and y2<=255 and x2>=0 and y2>=0 and x1<=255 and y1<=255) then gui.drawline(x1, y1, x2, y2, color) end end --bc + clipping, just make sure x2,y2 is the point that will most likely leave the screen first function bcline2(x1,y1,x2,y2,color) if(x1>=0 and y1>=0 and x1<=255 and y1<=255) then if(x2>255 or y2>255 or x2<0 or y2<0) then local vx,vy=getvdir(x1,y1,x2,y2) --TODO: replace brute force-y method with line intersection formula if(math.abs(vx)==1 or math.abs(vy)==1) then local x=x1 local y=y1 while(x<254 and x>1 and y<254 and y>1) do x = x + vx y = y + vy end x = math.floor(x) y = math.floor(y) --logf(" ("..x1..","..y1..")-("..x..","..y..")\r\n") gui.drawline(x1,y1,x,y,color) end else gui.drawline(x1,y1,x2,y2,color) end end end function bctext(x,y,text) if(x>=0 and y>=0 and x<=255 and y<=255) then --make sure the text is always visible or else... possible memory leaks(?) and crashes on FCEUX <= 2.0.3 local len=string.len(text)*8+1 if(x+len > 255) then x = 255-len end if(x < 0) then x = 0 end if(y > 222) then --NTSC y=222 end gui.text(x, y, text) end end function getdistance(x1,y1,x2,y2) return math.floor(math.sqrt((x1-x2)^2+(y1-y2)^2)) end --returns direction vector of a line function getvdir(srcx,srcy,destx,desty) local x1 = srcx local x2 = destx local y1 = srcy local y2 = desty local xc = x2-x1 local yc = y2-y1 if(math.abs(xc)>math.abs(yc)) then yc = yc/math.abs(xc) xc = xc/math.abs(xc) elseif(math.abs(yc)>math.abs(xc)) then xc = xc/math.abs(yc) yc = yc/math.abs(yc) else if(xc<0) then xc=-1 elseif(xc>0) then xc=1 else xc=0 end if(yc<0) then yc=-1 elseif(yc>0) then yc=1 else yc=0 end end return xc,yc end local m_cursor = { {1,0,0,0,0,0,0,0}, {1,1,0,0,0,0,0,0}, {1,2,1,0,0,0,0,0}, {1,2,2,1,0,0,0,0}, {1,2,2,2,1,0,0,0}, {1,2,2,2,2,1,0,0}, {1,2,2,2,2,2,1,0}, {1,2,1,1,1,1,1,1}, {1,1,0,0,0,0,0,0}, {1,0,0,0,0,0,0,0}, } function drawcursor(px,py,col1,col2) if(px>0 and py>0 and px<256-8 and py<256-10) then for y=1,10 do if(m_cursor[y]) then for x=1,8 do if(m_cursor[y][x]==1) then gui.drawpixel(px+x,py+y,col1) elseif(m_cursor[y][x]==2) then gui.drawpixel(px+x,py+y,col2) end end end end end end --debug functions function logf(s) local fo = io.open("E:/emu/nes/fceux-2.0.4.win32-unofficial/lua/log.txt", "ab") if(fo~=nil) then fo:write(s) fo:close() return true end end function logtable(a) for i,v in pairs(a) do if(type(v)=="table") then printarrrec(v) else if(v==false) then v="false" elseif(v==true) then v="true" end logf(i.." = "..v.."\r\n") end end end