fceux/branches/sdl2/output/luaScripts/m_utils.lua

234 lines
5.5 KiB
Lua

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