Example #1
0
 public void Start()
 {
     player         = player ?? new AudioSourcePool();
     clipRegister   = clipRegister ?? new ClipRegister();
     entitySpawner  = entitySpawner ?? new EntitySpawner();
     luaInterpreter = luaInterpreter ?? new LuaInterpreter();
 }
Example #2
0
        /// <summary>
        /// Load a game from path and run it.
        /// All paths are considered to be inside pico8/games folder
        /// </summary>
        /// <param name="path">The path to read cart from.</param>
        /// <param name="interpreter">The interpreter to use.<see cref="ILuaInterpreter"/></param>
        public void LoadGame(string path, ILuaInterpreter interpreter)
        {
            // Verify if all conditions to run a game are met.
            if (graphics.screenColorData == null)
            {
                throw new ArgumentNullException("Pico8 must have a reference to the screenColorData array to fill it with pico8's screen data.");
            }
            if (graphics.screenColorData.Length != 128 * 128)
            {
                throw new ArgumentException($"screenColorData array must be of length 16.384 (128 * 128), but is of length {graphics.screenColorData.Length}.");
            }

            loadedGame = new Game();

            loadedGame.path        = path;
            loadedGame.cartridge   = new Cartridge(path);
            loadedGame.interpreter = interpreter;
            loadedGame.cartdata_id = "";
            loadedGame.cartdata    = new Int32[64];

            InitAPI(ref loadedGame.interpreter);

            memory.LoadCartridgeData(loadedGame.cartridge.rom);

            audio.Init();

            loadedGame.interpreter.RunScript(loadedGame.cartridge.gameCode);

            timeStart = DateTime.Now;

            loadedGame.interpreter.CallIfDefined("_init");
        }
Example #3
0
 public bool TryFetch(out ILuaInterpreter fill)
 {
     fill = luaInterpreter;
     return(!(fill is null));
 }
Example #4
0
 public void Set(ILuaInterpreter toSet) => luaInterpreter   = toSet;
Example #5
0
        /// <summary>
        /// Initializes the PICO-8 API.
        /// </summary>
        /// <param name="interpreter">The interpreter to use when adding the functions. <see cref="ILuaInterpreter"/></param>
        private void InitAPI(ref ILuaInterpreter interpreter)
        {
            //
            // First, flatten out the API so that outside C# calls don't need to do something like pico8.graphics.print()
            // to call functions.
            //

            Flip = graphics.Flip;

            // Music
            Music = audio.Music;
            Sfx   = audio.Sfx;

            Print = graphics.Print;

            // Math
            Max     = Math.Max;
            Min     = Math.Min;
            Mid     = ((x, y, z) => Math.Max(Math.Min(Math.Max(x, y), z), Math.Min(x, y)));
            Floor   = Math.Floor;
            Ceiling = Math.Ceiling;
            Cos     = (x => Math.Cos(2 * x * Math.PI));
            Sin     = (x => - Math.Sin(2 * x * Math.PI));
            Atan2   = ((dx, dy) => 1 - Math.Atan2(dy, dx) / (2 * Math.PI));
            Sqrt    = Math.Sqrt;
            Abs     = Math.Abs;
            Band    = (x, y) => util.FixedToFloat(util.FloatToFixed(x) & util.FloatToFixed(y));
            Bor     = (x, y) => util.FixedToFloat(util.FloatToFixed(x) | util.FloatToFixed(y));
            Bxor    = (x, y) => util.FixedToFloat(util.FloatToFixed(x) ^ util.FloatToFixed(y));
            Bnot    = x => util.FixedToFloat(~util.FloatToFixed(x));
            Shl     = (x, n) => util.FixedToFloat(util.FloatToFixed(x) << n);
            Shr     = (x, n) => util.FixedToFloat(util.FloatToFixed(x) >> n);
            Lshr    = (x, n) => util.FixedToFloat((int)((uint)util.FloatToFixed(x)) >> n); // Does Not Work I think

            // Graphics
            Line     = graphics.Line;
            Rect     = graphics.Rect;
            Rectfill = graphics.Rectfill;
            Circ     = graphics.Circ;
            Circfill = graphics.CircFill;
            Pset     = graphics.Pset;
            Pget     = graphics.Pget;
            Sset     = graphics.Sset;
            Sget     = graphics.Sget;
            Palt     = graphics.Palt;
            Pal      = graphics.Pal;
            Clip     = graphics.Clip;
            Spr      = graphics.Spr;
            Sspr     = graphics.Sspr;
            Map      = graphics.Map;
            Mget     = memory.Mget;
            Mset     = memory.Mset;
            Fillp    = memory.Fillp;

            // Memory related
            Cls    = memory.Cls;
            Peek   = memory.Peek;
            Poke   = memory.Poke;
            Peek2  = memory.Peek2;
            Poke2  = memory.Poke2;
            Peek4  = memory.Peek4;
            Poke4  = memory.Poke4;
            Fget   = memory.Fget;
            Fset   = memory.Fset;
            Camera = memory.Camera;
            Memcpy = memory.Memcpy;
            Memset = memory.Memset;
            Color  = memory.Color;

            //
            // Now, fill the lua API properly.
            //

            // Graphics
            interpreter.AddFunction("line", Line);
            interpreter.AddFunction("rect", Rect);
            interpreter.AddFunction("rectfill", Rectfill);
            interpreter.AddFunction("circ", Circ);
            interpreter.AddFunction("circfill", Circfill);
            interpreter.AddFunction("pset", Pset);
            interpreter.AddFunction("pget", Pget);
            interpreter.AddFunction("sset", Sset);
            interpreter.AddFunction("sget", Sget);
            interpreter.AddFunction("palt", Palt);
            interpreter.AddFunction("pal", Pal);
            interpreter.AddFunction("clip", Clip);
            interpreter.AddFunction("spr", Spr);
            interpreter.AddFunction("sspr", Sspr);
            interpreter.AddFunction("map", Map);
            interpreter.AddFunction("mget", Mget);
            interpreter.AddFunction("mset", Mset);
            interpreter.AddFunction("fillp", Fillp);

            // Memory related
            interpreter.AddFunction("cls", Cls);
            interpreter.AddFunction("peek", Peek);
            interpreter.AddFunction("poke", Poke);
            interpreter.AddFunction("peek2", Peek2);
            interpreter.AddFunction("poke2", Poke2);
            interpreter.AddFunction("peek4", Peek4);
            interpreter.AddFunction("poke4", Poke4);
            interpreter.AddFunction("fget", Fget);
            interpreter.AddFunction("fset", Fset);
            interpreter.AddFunction("camera", Camera);
            interpreter.AddFunction("memcpy", Memcpy);
            interpreter.AddFunction("memset", Memset);
            interpreter.AddFunction("reload", (Func <int, int, int, string, object>)Reload);
            interpreter.AddFunction("cstore", (Func <int, int, int, string, object>)Cstore);
            interpreter.AddFunction("cartdata", (Func <string, object>)Cartdata);
            interpreter.AddFunction("dget", (Func <int, object>)Dget);
            interpreter.AddFunction("dset", (Func <int, double, object>)Dset);
            interpreter.AddFunction("color", Color);

            // Math
            interpreter.AddFunction("max", Max);
            interpreter.AddFunction("min", Min);
            interpreter.AddFunction("mid", Mid);
            interpreter.AddFunction("flr", Floor);
            interpreter.AddFunction("ceil", Ceiling);
            interpreter.AddFunction("cos", Cos);
            interpreter.AddFunction("sin", Sin);
            interpreter.AddFunction("atan2", Atan2);
            interpreter.AddFunction("sqrt", Sqrt);
            interpreter.AddFunction("abs", Abs);
            interpreter.AddFunction("rnd", (Func <double?, double>)Rnd);
            interpreter.AddFunction("srand", (Func <int, object>)Srand);
            interpreter.AddFunction("band", Band);
            interpreter.AddFunction("bor", Bor);
            interpreter.AddFunction("bxor", Bxor);
            interpreter.AddFunction("bnot", Bnot);
            interpreter.AddFunction("shl", Shl);
            interpreter.AddFunction("shr", Shr);
            interpreter.AddFunction("lshr", Lshr); // Does Not Work I think

            // Controls
            interpreter.AddFunction("btn", (Func <int?, int?, object>)Btn);
            interpreter.AddFunction("btnp", (Func <int?, int?, object>)Btnp);

            interpreter.AddFunction("flip", Flip);

            // Music
            interpreter.AddFunction("music", Music);
            interpreter.AddFunction("sfx", Sfx);

            // Misc
            interpreter.AddFunction("time", (Func <double>)Time);

            interpreter.AddFunction("print", Print);
            interpreter.AddFunction("printh", (Func <object, object>)Printh);

            interpreter.AddFunction("menuitem", (Func <int, string, object, object>)Menuitem);
            interpreter.AddFunction("import", (Func <string, bool, object>)Import);
            interpreter.AddFunction("export", (Func <string, object>)Export);

            interpreter.RunScript(@"
                function all(collection)
                   if (collection == nil) then return function() end end
                   local index = 0
                   local count = #collection
                   return function ()
                      index = index + 1
                      if index <= count
                      then
                         return collection[index]
                      end
                   end
                end

                function tostr(x)
                    if type(x) == ""number"" then return tostring(math.floor(x*10000)/10000) end
                    return tostring(x)
                end

                function tonum(x)
                    return tonumber(x)
                end

                function add(t,v)
                    if t == nil then return end
                    table.insert(t,v)
                end

                function del(t,v)
                    if t == nil then return end
                    for i = 0,#t do
                        if t[i] == v then
                            table.remove(t,i)
                            return
                        end
                    end
                end

                function foreach(t,f)
                    for e in all(t) do
                        f(e)
                    end
                end

                function string:split(sep)
                   local sep, fields = sep or "":"", {}
                   local pattern = string.format(""([^%s]+)"", sep)
                   self: gsub(pattern, function(c) fields[#fields+1] = c end)
                   return fields
                end

                function b(s)
                    local o = 0
                    local n = s:split('.')
                    for d in n[1]:gmatch('[01]') do
                        o = o*2 + tonumber(d)
                    end
                    if n[2] then
                        div = 2
                        for d in n[2]:gmatch('[01]') do
                            o = o + tonumber(d) / div
                            div = div * 2
                        end
                    end

                    return o
                end

                t = type
                function type(f)
                    if not f then
                        return 'nil'
                    end
                    return t(f)
                end

                cocreate = coroutine.create
                coresume = coroutine.resume
                costatus = coroutine.status
                yield = coroutine.yield
                sub = string.sub
                ");
        }