public override void Init(LuaMachine machine) { base.Init(machine); machine.DoString(@" -- Locals local type = type local error = error local function expect( value, sExpectedType, index ) local sFoundType = type( value ) if sExpectedType and sFoundType ~= sExpectedType then error( ""Expected "" .. sExpectedType .. "" at argument #"" .. index .. "", got "" .. sFoundType, 3 ) end return value end -- System API methods local coroutine_yield = coroutine.yield local table_unpack = table.unpack function system.pullEvent( a, ... ) local tEvent if a ~= nil then tEvent = { coroutine_yield( ""terminate"", a, ... ) } else tEvent = { coroutine_yield() } end local sEvent = tEvent[1] if sEvent == ""terminate"" then error( ""Terminated"", 0 ) else return table_unpack( tEvent ) end end function system.pullEventRaw( ... ) return coroutine_yield( ... ) end local system_getDevice = system.getDevice local system_pullEvent = system.pullEvent function system.sleep( nSeconds ) expect( nSeconds, ""number"", 1 ) local clock = system_getDevice( ""clock"" ) if not clock then error( ""Error sleeping: No clock detected"", 2 ) end local nTimer = clock.startTimer( nSeconds ) while true do local sEvent, p1 = system_pullEvent( ""timer"" ) if p1 == nTimer then break end end end", "=SystemAPI.Init" ); }
public LuaCPUDevice(string description) { m_description = description; m_computer = null; m_isMainCPU = false; m_machine = null; m_mainRoutine = null; m_fileSystem = new FileSystem(); m_eventFilter = new HashSet <string>(); m_nextBootMount = new LuaObjectRef <LuaMount>(); }
public static void UnloadAll() { if (s_animMachine != null) { s_loadedAnims.Clear(); s_animMachine.Dispose(); s_animMachine = null; s_install_animation = null; s_call_animation = null; } }
private void Halt() { if (m_machine == null) { throw new InvalidOperationException(); } // Shutdown lua machine m_machine.Dispose(); m_machine = null; m_mainRoutine = null; m_eventFilter.Clear(); // Shutdown file system m_fileSystem.UnmountAll(); }
internal LuaCoroutine(LuaMachine machine, int id) { Machine = machine; ID = id; }
public override void Init(LuaMachine machine) { base.Init(machine); machine.DoString(@" -- Locals local type = type local error = error local function expect( value, sExpectedType, index ) local sFoundType = type( value ) if sExpectedType and sFoundType ~= sExpectedType then error( ""Expected "" .. sExpectedType .. "" at argument #"" .. index .. "", got "" .. sFoundType, 3 ) end return value end -- IO API local io_open = io.open local io_input = io.input local io_output = io.output local tostring = tostring local load = load function loadfile( sPath, sMode, _env ) if sPath ~= nil then expect( sPath, ""string"", 1 ) end local file, sChunkName if sPath then file = io_open( sPath ) sChunkName = ""@"" .. sPath else file = io_input() sChunkName = ""=stdin"" end if file then local sFile = file:read( ""a"" ) file:close() if _env ~= nil then return load( sFile, sChunkName, sMode, _env ) else return load( sFile, sChunkName, sMode ) end end return nil, ""File not found: "" .. sPath end local loadfile = loadfile function dofile( sPath ) if sPath ~= nil then expect( sPath, ""string"", 1 ) end local fnFile, sError = loadfile( sPath ) if fnFile then return fnFile() else error( sError, 2 ) end end local select = select function print( ... ) local nArgs = select( ""#"", ... ) local output = io_output() for n=1,nArgs do local arg = select( n, ... ) output:write( tostring(arg) ) if n<nArgs then output:write( ""\t"" ) end end output:write( ""\n"" ) end" , "=IOAPI.Init" ); }
private CPUUpdateResult ReallyBoot(LuaMount bootMount) { if (m_machine != null) { throw new InvalidOperationException(); } // Check if the system has any RAM if (m_computer.Memory.TotalMemory == 0) { m_computer.ErrorOutput.WriteLine("Error starting CPU: No RAM"); return(m_isMainCPU ? CPUUpdateResult.Shutdown : CPUUpdateResult.Continue); } // Mount the ROM m_fileSystem.Mount(bootMount, FilePath.Empty, FilePath.Empty, true); // Check if the boot path exists var bootPath = new FilePath("boot.lua"); if (!m_fileSystem.Exists(bootPath) || m_fileSystem.IsDir(bootPath)) { m_computer.ErrorOutput.WriteLine("Error starting CPU: ROM does not countain {0}", bootPath); m_fileSystem.UnmountAll(); return(m_isMainCPU ? CPUUpdateResult.Shutdown : CPUUpdateResult.Continue); } // Init lua machine m_machine = new LuaMachine(m_computer.Memory); m_machine.AllowByteCodeLoading = false; m_machine.EnforceTimeLimits = true; try { // Remove default APIs we don't want m_machine.RemoveUnsafeGlobals(); // Install basic APIs if (m_computer.Host != null) { m_machine.SetGlobal("_HOST", m_computer.Host); } InstallAPI(new IOAPI(m_computer, m_fileSystem)); InstallAPI(new OSAPI(m_computer, this, m_fileSystem)); InstallAPI(new PackageAPI(m_computer, m_fileSystem)); // Install custom APIs PreloadAPI(new SystemAPI(m_computer, this)); PreloadAPI(new FSAPI(m_computer, m_fileSystem)); } catch (LuaError e) { m_computer.ErrorOutput.WriteLine("Error starting CPU: {0}", e.Message); Halt(); return(m_isMainCPU ? CPUUpdateResult.Shutdown : CPUUpdateResult.Continue); } // Load the boot script try { string bootScript; using (var reader = m_fileSystem.OpenForRead(bootPath)) { bootScript = reader.ReadToEnd(); } var bootFunction = m_machine.LoadString(bootScript, "@" + bootPath); m_mainRoutine = m_machine.CreateCoroutine(bootFunction); m_eventFilter.Clear(); } catch (IOException e) { m_computer.ErrorOutput.WriteLine("Error loading {0}: {1}", bootPath, e.Message); Halt(); return(m_isMainCPU ? CPUUpdateResult.Shutdown : CPUUpdateResult.Continue); } catch (LuaError e) { m_computer.ErrorOutput.WriteLine("Error parsing {0}: {1}", bootPath, e.Message); Halt(); return(m_isMainCPU ? CPUUpdateResult.Shutdown : CPUUpdateResult.Continue); } // Start the boot script m_eventFilter.Clear(); return(Resume(LuaArgs.Empty)); }
public override void Init(LuaMachine machine) { base.Init(machine); machine.DoString(@" -- Locals local type = type local error = error local function expect( value, sExpectedType, index ) local sFoundType = type( value ) if sExpectedType and sFoundType ~= sExpectedType then error( ""Expected "" .. sExpectedType .. "" at argument #"" .. index .. "", got "" .. sFoundType, 3 ) end return value end -- Package API local package_preload = package.preload local package_searchpath = package.searchpath local package_loaded = package.loaded local package_searchers = package.searchers local pcall = pcall local loadfile = loadfile table.insert( package.searchers, function( sName ) -- Load from preload expect( sName, ""string"", 1 ) if package_preload[ sName ] ~= nil then return package_preload[ sName ] else return ""no field package.preload['"" .. sName .. ""']"" end end ) table.insert( package.searchers, function( sName ) -- Load from path expect( sName, ""string"", 1 ) if type( package.path ) ~= ""string"" then error( ""package.path must be a string"", 0 ) end local sPath, sError = package_searchpath( sName, package.path ) if sPath ~= nil then local fnFile, sError = loadfile( sPath ) if fnFile then return fnFile, sPath else return sError end else return sError end end ) local require_in_progress = {} function require( sName ) expect( sName, ""string"", 1 ) if package_loaded[ sName ] ~= nil then return package_loaded[ sName ] end if require_in_progress[ sName ] then error( ""loop detected requiring '"" .. sName .. ""'"", 2 ) end require_in_progress[ sName ] = true local ok, result = pcall( function() local sFullError = ""module '"" .. sName .. ""' not found:"" for n=1,#package_searchers do local fnSearcher = package_searchers[n] local fnLoader, sExtra = fnSearcher( sName ) if type(fnLoader) == ""function"" then local result = fnLoader( sName, sExtra ) if result ~= nil then package_loaded[ sName ] = result return result else package_loaded[ sName ] = true return true end elseif type(fnLoader) == ""string"" then sFullError = sFullError .. ""\n"" .. fnLoader end end error( sFullError, 0 ) end ) require_in_progress[ sName ] = false if ok then return result else error( result, 0 ) end end" , "=PackageAPI.Init" ); }
public ScriptController(LevelState state) { m_state = state; m_machine = new LuaMachine(); m_machine.AllowByteCodeLoading = false; m_machine.EnforceTimeLimits = true; m_machine.RemoveUnsafeGlobals(); m_activeCoroutines = new List <LuaCoroutine>(); // Install APIs and Globals m_machine.SetGlobal("io", new IOAPI(m_state).ToTable()); m_machine.SetGlobal("level", new LevelAPI(m_state).ToTable()); if (m_state is InGameState) { m_machine.SetGlobal("game", new GameAPI((InGameState)m_state).ToTable()); m_machine.SetGlobal("campaign", new CampaignAPI(m_state).ToTable()); m_machine.DoString(@"do local game_showDialogue = game.showDialogue function game.showDialogue( character, text, modal, returnImmediately ) -- Create dialog game_showDialogue( character, text, modal ) if modal ~= false and returnImmediately ~= true then while not game.isDialogueReadyToContinue() do yield() end end end local game_hideDialogue = game.hideDialogue function game.hideDialogue() -- Create dialog game_hideDialogue() while game.isDialogueVisible() do yield() end end end", "=ScriptController.ctor"); } else if (m_state is CutsceneState) { m_machine.SetGlobal("cutscene", new CutsceneAPI((CutsceneState)m_state).ToTable()); m_machine.SetGlobal("campaign", new CampaignAPI(m_state).ToTable()); } m_machine.SetGlobal("dofile", (LuaCFunction)DoFile); m_machine.DoString(@"do function expect( value, sExpectedType, nArg ) local sFoundType = type( value ) if sFoundType ~= sExpectedType then error( ""Expected "" .. sExpectedType .. "" at argument "" .. nArg .. "", got "" .. sFoundType, 3 ) end end local tResults = {} function require( s ) expect( s, ""string"", 1 ) if tResults[s] == nil then local ok, result = pcall( dofile, ""scripts/"" .. s .. "".lua"" ) if not ok then error( result, 0 ) elseif result == nil then tResults[s] = true else tResults[s] = result end end return tResults[s] end print = io.print yield = coroutine.yield function sleep( t ) expect( t, ""number"", 1 ) local l = io.getTime() + t repeat yield() until io.getTime() >= l end end", "=ScriptController.ctor"); // Start the main script m_scriptPath = m_state.Level.Info.ScriptPath; if (m_scriptPath != null) { if (Assets.Exists <LuaScript>(m_scriptPath)) { try { var script = LuaScript.Get(m_scriptPath); m_machine.DoString(script.Code, "@" + AssetPath.GetFileName(m_scriptPath)); } catch (LuaError e) { App.Log("Lua Error: {0}", e.Message); } } else { App.Log("Error: Script {0} not found", m_scriptPath); } } }
public void Dispose() { m_machine.Dispose(); m_machine = null; }
private static void Init() { if (s_animMachine == null) { s_animMachine = new LuaMachine(); s_animMachine.AllowByteCodeLoading = false; s_animMachine.EnforceTimeLimits = true; s_animMachine.RemoveUnsafeGlobals(); s_animMachine.SetGlobal("print", (LuaCFunction) delegate(LuaArgs args) { var output = new StringBuilder(); for (int i = 0; i < args.Length; ++i) { output.Append(args.ToString(i)); if (i < args.Length - 1) { output.Append(", "); } } App.UserLog(output.ToString()); return(LuaArgs.Empty); }); s_animMachine.SetGlobal("dofile", (LuaCFunction) delegate(LuaArgs args) { var path = args.GetString(0); if (Assets.Assets.Exists <LuaScript>(path)) { var script = LuaScript.Get(path); return(s_animMachine.DoString(script.Code, "@" + AssetPath.GetFileName(path))); } throw new LuaError("Script not found: " + path); }); s_animMachine.DoString( @"do function expect( value, sExpectedType, nArg ) local sFoundType = type( value ) if sFoundType ~= sExpectedType then error( ""Expected "" .. sExpectedType .. "" at argument "" .. nArg .. "", got "" .. sFoundType, 3 ) end end local tResults = {} function require( s ) expect( s, ""string"", 1 ) if tResults[s] == nil then local ok, result = pcall( dofile, ""scripts/"" .. s .. "".lua"" ) if not ok then error( result, 0 ) elseif result == nil then tResults[s] = true else tResults[s] = result end end return tResults[s] end abs = math.abs floor = math.floor ceil = math.ceil min = math.min max = math.max pow = math.pow sqrt = math.sqrt pi = math.pi function clamp( x, low, hi ) expect( x, ""number"", 1 ) expect( low, ""number"", 2 ) expect( hi, ""number"", 3 ) if x < low then return low elseif x > hi then return hi else return x end end local math_rad, math_deg = math.rad, math.deg local math_sin, math_cos, math_tan = math.sin, math.cos, math.tan local math_asin, math_acos, math_atan = math.asin, math.acos, math.atan function sin( x ) expect( x, ""number"", 1 ) return math_sin( math_rad( x ) ) end function cos( x ) expect( x, ""number"", 1 ) return math_cos( math_rad( x ) ) end function tan( x ) expect( x, ""number"", 1 ) return math_tan( math_rad( x ) ) end function asin( x ) expect( x, ""number"", 1 ) return math_deg( math_asin( x ) ) end function acos( x ) expect( x, ""number"", 1 ) return math_deg( math_acos( x ) ) end function atan( x ) expect( x, ""number"", 1 ) return math_deg( math_atan( x ) ) end function atan2( y, x ) expect( y, ""number"", 1 ) expect( x, ""number"", 2 ) return math_deg( math_atan( y, x ) ) end function ease( f ) expect( f, ""number"", 1 ) f = clamp( f, 0.0, 1.0 ) return (3 - 2*f) * f * f end function lerp( a, b, f ) expect( a, ""number"", 1 ) expect( b, ""number"", 2 ) expect( f, ""number"", 3 ) return a + (b-a) * f end function lerp3( x0, y0, z0, x1, y1, z1, f ) expect( x0, ""number"", 1 ) expect( y0, ""number"", 2 ) expect( z0, ""number"", 3 ) expect( x1, ""number"", 4 ) expect( y1, ""number"", 5 ) expect( z1, ""number"", 6 ) expect( f, ""number"", 7 ) return lerp(x0, x1, f), lerp(y0, y1, f), lerp(z0, z1, f) end function step( a, x ) expect( a, ""number"", 1 ) expect( x, ""number"", 2 ) return (x >= a) and 1 or 0 end function smoothstep( a, b, x ) expect( a, ""number"", 1 ) expect( b, ""number"", 2 ) expect( x, ""number"", 3 ) local f = clamp( (x - a) / (b - a), 0, 1 ) return ease(f) end function rot2D( x, y, a, xo, yo ) expect( x, ""number"", 1 ) expect( y, ""number"", 2 ) expect( a, ""number"", 3 ) if xo then expect( xo, ""number"", 4 ) end if yo then expect( yo, ""number"", 5 ) end xo = xo or 0 yo = yo or 0 local ar = -math_rad(a) local ca, sa = math_cos(ar), math_sin(ar) return xo + (x - xo) * ca - (y - yo) * sa, yo + (x - xo) * sa + (y - yo) * ca end function setpos( part, x, y, z ) expect( part, ""table"", 1 ) expect( x, ""number"", 2 ) expect( y, ""number"", 3 ) expect( z, ""number"", 4 ) part.x = x part.y = y part.z = z end function lookat( part, x, y, z ) expect( part, ""table"", 1 ) expect( x, ""number"", 2 ) expect( y, ""number"", 3 ) expect( z, ""number"", 4 ) local dx = x - part.x local dy = y - part.y local dz = z - part.z local dxz = sqrt( dx*dx + dz*dz ) part.ry = -atan2( dx, -dz ) part.rx = atan2( dy, dxz ) part.rz = 0 end local tAnimations = {} function install_animation( sAnimName, sAnimCode, sChunkName ) local tAnimEnv = {} setmetatable( tAnimEnv, { __index = _ENV } ) local fnAnim, sError = load( sAnimCode, sChunkName, ""t"", tAnimEnv ) if fnAnim then local ok, sError = pcall( fnAnim ) if ok then tAnimations[ sAnimName ] = tAnimEnv.animate else tAnimations[ sAnimName ] = nil error( sError, 0 ) end else tAnimations[ sAnimName ] = nil error( sError, 0 ) end end local tPart = {} function call_animation( sAnimName, sPartName, nTime ) tPart.name = sPartName tPart.hide = false tPart.x, tPart.y, tPart.z = 0,0,0 tPart.rx, tPart.ry, tPart.rz = 0,0,0 tPart.sx, tPart.sy, tPart.sz = 1,1,1 tPart.u, tPart.v = 0,0 tPart.su, tPart.sv = 1,1 tPart.r, tPart.g, tPart.b, tPart.a = 1,1,1,1 tPart.fov = nil local fnAnimate = tAnimations[sAnimName] if fnAnimate then fnAnimate( tPart, nTime ) end return tPart.hide, tPart.x, tPart.y, tPart.z, tPart.rx, tPart.ry, tPart.rz, tPart.sx, tPart.sy, tPart.sz, tPart.u, tPart.v, tPart.su, tPart.sv, tPart.r, tPart.g, tPart.b, tPart.a, tPart.fov end end", "=LuaAnimation.Init" ); s_install_animation = s_animMachine.GetGlobal("install_animation").GetFunction(); s_call_animation = s_animMachine.GetGlobal("call_animation").GetFunction(); } }
public virtual void Init(LuaMachine machine) { machine.SetGlobal(Name, GetMethodTable()); }
internal LuaFunction(LuaMachine machine, int id) { Machine = machine; ID = id; }