diff --git a/Makefile b/Makefile index ac5382c..492b2e6 100755 --- a/Makefile +++ b/Makefile @@ -87,7 +87,7 @@ else endif endif -CPPFLAGS += -DHAVE_CEIL -DCP_USE_CGTYPES=0 -DCP_USE_DOUBLES=0 -DHAVE_FLOOR -DHAVE_FMOD -DHAVE_LRINT -DHAVE_LRINTF $(includeflag) -MD $(WARNING_FLAGS) -I. -DVER=\"$(VER)\" -DCOM=\"$(COM)\" -DINFO=\"$(INFO)\" #-DENABLE_SINC_MEDIUM_CONVERTER -DENABLE_SINC_FAST_CONVERTER -DCP_COLLISION_TYPE_TYPE=uintptr_t -DCP_BITMASK_TYPE=uintptr_t +CPPFLAGS += -DHAVE_CEIL -DCP_USE_CGTYPES=0 -DCP_USE_DOUBLES=0 -DHAVE_FLOOR -DHAVE_FMOD -DHAVE_LRINT -DHAVE_LRINTF $(includeflag) -MD $(WARNING_FLAGS) -I. -DVER=\"$(SEM)\" -DCOM=\"$(COM)\" -DINFO=\"$(INFO)\" #-DENABLE_SINC_MEDIUM_CONVERTER -DENABLE_SINC_FAST_CONVERTER -DCP_COLLISION_TYPE_TYPE=uintptr_t -DCP_BITMASK_TYPE=uintptr_t CPPFLAGS += -D_FILE_OFFSET_BITS=64 # for tinycdb @@ -181,9 +181,8 @@ endif WARNING_FLAGS = -Wno-incompatible-function-pointer-types -Wno-incompatible-pointer-types NAME = primum$(EXT) -SEM = 0.3.0 -COM != fossil describe -VER = $(SEM) +SEM != git describe --tags --abbrev=0 +COM != git rev-parse --short HEAD LDLIBS := $(addprefix -l, $(LDLIBS)) LDPATHS := $(addprefix -L, $(LDPATHS)) diff --git a/scripts/base.js b/scripts/base.js index 90c5f63..26e78f5 100644 --- a/scripts/base.js +++ b/scripts/base.js @@ -1512,22 +1512,15 @@ var Vector = { return [v.x/len, v.y/len]; }, - project(a, b) { - return cmd(85, a, b); - }, - - dot(a, b) { - return cmd(88,a,b); - }, + project(a, b) { return cmd(85, a, b);}, + dot(a, b) { return vector.dot(a,b); }, random() { var vec = [Math.random()-0.5, Math.random()-0.5]; return Vector.norm(vec); }, - angle(v) { - return Math.rad2turn(Math.atan2(v.y, v.x)); - }, + angle(v) { return Math.rad2turn(Math.atan2(v.y, v.x)); }, rotate(v,angle) { var r = Vector.length(v); diff --git a/scripts/camera2d.jso b/scripts/camera2d.jso index d8ac3b1..3e1db37 100644 --- a/scripts/camera2d.jso +++ b/scripts/camera2d.jso @@ -6,23 +6,23 @@ this.realzoom = function() { return cmd(135); }; this.right = function() { - return this.pos.x + (Window.rendersize.x/2); + return this.pos.x + (window.rendersize.x/2); } this.left = function() { - return this.pos.x - (Window.rendersize.x/2); + return this.pos.x - (window.rendersize.x/2); } this.mixin({ get zoom() { -// var z = Game.native.y / Window.dimensions.y; +// var z = game.native.y / window.dimensions.y; return cmd(135);///z; }, set zoom(x) { x = Math.clamp(x,0.1,10); -// var z = Game.native.y / Window.dimensions.y; +// var z = game.native.y / window.dimensions.y; // z *= x; cmd(62,x); }, diff --git a/scripts/components.js b/scripts/components.js index 35201b8..a08c2b0 100644 --- a/scripts/components.js +++ b/scripts/components.js @@ -109,7 +109,7 @@ Object.mixin(cmd(268,true), { p = Resources.find_image(p); if (!p) return; if (p === this.path) return; - this.tex = cmd(269,p); + this.tex = texture.find(p); var anim = SpriteAnim.make(p); if (!anim) return; this.anim = anim; diff --git a/scripts/debug.js b/scripts/debug.js index 429bf90..45428f1 100644 --- a/scripts/debug.js +++ b/scripts/debug.js @@ -12,7 +12,7 @@ var Debug = { draw_grid(width, span, color) { color = color ? color : Color.green; - cmd(47, width, span, color); + render.grid(width,span,color); }, coordinate(pos, size, color) { GUI.text(JSON.stringify(pos.map(p=>Math.round(p))), pos, size, color); }, @@ -28,17 +28,8 @@ var Debug = { GUI.text(n, pos.add([0,4]), 1, color); }, - phys_drawing: false, - draw_phys(on) { - this.phys_drawing = on; - cmd(4, this.phys_drawing); - }, - - draw_obj_phys(obj) { - cmd(82, obj.body); - }, - - gameobject(go) { cmd(15, go.body); }, + draw_phys: false, + draw_obj_phys(obj) { debug.draw_gameobject(obj.body); }, draw_bb: false, draw_gizmos: false, @@ -46,19 +37,19 @@ var Debug = { draw() { if (this.draw_bb) - Game.all_objects(function(x) { Debug.boundingbox(x.boundingbox(), Color.Debug.boundingbox.alpha(0.05)); }); + game.all_objects(function(x) { Debug.boundingbox(x.boundingbox(), Color.Debug.boundingbox.alpha(0.05)); }); if (sim.paused()) GUI.text("PAUSED", [0,0],1); if (this.draw_gizmos) - Game.all_objects(function(x) { + game.all_objects(function(x) { if (!x.icon) return; - GUI.image(x.icon, Window.world2screen(x.pos)); + GUI.image(x.icon, window.world2screen(x.pos)); }); if (this.draw_names) - Game.all_objects(function(x) { - GUI.text(x, Window.world2screen(x.pos).add([0,32]), 1, Color.Debug.names); + game.all_objects(function(x) { + GUI.text(x, window.world2screen(x.pos).add([0,32]), 1, Color.Debug.names); }); if (Debug.Options.gif.rec) { @@ -145,8 +136,6 @@ Object.assign(profile, { secs() { return this.now()/1000000000; }, }); - - performance.test = { barecall() { performance(0); }, unpack_num(n) { performance(1,n); }, @@ -160,14 +149,12 @@ performance.test = { performance.test.call_fn_n.doc = "Calls fn1 n times, and then fn2."; -//performance.cpu.doc = `Output the time it takes to do a given function n number of times. Provide 'q' as "ns", "us", or "ms" to output the time taken in the requested resolution.`; - /* These controls are available during editing, and during play of debug builds */ Debug.inputs = {}; -Debug.inputs.f1 = function () { Debug.draw_phys(!Debug.phys_drawing); }; +Debug.inputs.f1 = function () { Debug.draw_phys = !Debug.draw_phys; }; Debug.inputs.f1.doc = "Draw physics debugging aids."; -//Debug.inputs.f3 = function() { Debug.draw_bb = !Debug.draw_bb; }; -//Debug.inputs.f3.doc = "Toggle drawing bounding boxes."; +Debug.inputs.f3 = function() { Debug.draw_bb = !Debug.draw_bb; }; +Debug.inputs.f3.doc = "Toggle drawing bounding boxes."; Debug.inputs.f4 = function() { Debug.draw_names = !Debug.draw_names; Debug.draw_gizmos = !Debug.draw_gizmos; @@ -189,7 +176,7 @@ Debug.Options.gif = { var w = this.w; var h = this.h; if (!this.stretch) { - var win = Window.height / Window.width; + var win = window.height / window.width; var gif = h/w; if (gif > win) h = w * win; diff --git a/scripts/editor.js b/scripts/editor.js index 1c6b55b..8441deb 100644 --- a/scripts/editor.js +++ b/scripts/editor.js @@ -3,8 +3,8 @@ selectable */ -Window.mode = Window.modetypes.full; -Game.loadurs(); +window.mode = window.modetypes.full; +game.loadurs(); player[0].control(Debug); Register.gui.register(Debug.draw, Debug); @@ -171,8 +171,8 @@ var editor = { zoom_to_bb(bb) { var cwh = bbox.tocwh(bb); - var xscale = cwh.wh.x / Window.width; - var yscale = cwh.wh.y / Window.height; + var xscale = cwh.wh.x / window.width; + var yscale = cwh.wh.y / window.height; var zoom = yscale > xscale ? yscale : xscale; @@ -237,7 +237,7 @@ var editor = { this.selectlist = []; editor.camera = world.spawn("scripts/camera2d.jso"); editor.camera._ed.selectable = false; - Game.view_camera(editor.camera); + game.view_camera(editor.camera); }, end_debug() { @@ -377,7 +377,7 @@ var editor = { x.gizmo(); }); - render.line(bbox.topoints(bbox.fromcwh([0,0],[Game.width,Game.height])).wrapped(1), Color.green); + render.line(bbox.topoints(bbox.fromcwh([0,0],[game.width,game.height])).wrapped(1), Color.green); /* Draw selection box */ if (this.sel_start) { @@ -399,7 +399,7 @@ var editor = { gui() { /* Clean out killed objects */ this.selectlist = this.selectlist.filter(function(x) { return x.alive; }); - GUI.text([0,0], Window.world2screen([0,0])); + GUI.text([0,0], window.world2screen([0,0])); GUI.text("WORKING LAYER: " + this.working_layer, [0,520]); GUI.text("MODE: " + this.edit_mode, [0,500]); @@ -490,22 +490,22 @@ var editor = { }); Debug.draw_grid(1, editor.grid_size, Color.Editor.grid.alpha(0.3)); - var startgrid = Window.screen2world([-20,0]).map(function(x) { return Math.snap(x, editor.grid_size); }); - var endgrid = Window.screen2world([Window.width, Window.height]); + var startgrid = window.screen2world([-20,0]).map(function(x) { return Math.snap(x, editor.grid_size); }); + var endgrid = window.screen2world([window.width, window.height]); - var w_step = Math.round(editor.ruler_mark_px/Window.width * (endgrid.x-startgrid.x)/editor.grid_size)*editor.grid_size; + var w_step = Math.round(editor.ruler_mark_px/window.width * (endgrid.x-startgrid.x)/editor.grid_size)*editor.grid_size; if (w_step === 0) w_step = editor.grid_size; - var h_step = Math.round(editor.ruler_mark_px/Window.height * (endgrid.y-startgrid.y)/editor.grid_size)*editor.grid_size; + var h_step = Math.round(editor.ruler_mark_px/window.height * (endgrid.y-startgrid.y)/editor.grid_size)*editor.grid_size; if (h_step === 0) h_step = editor.grid_size; while(startgrid[0] <= endgrid[0]) { - GUI.text(startgrid[0], [Window.world2screen([startgrid[0], 0])[0],0]); + GUI.text(startgrid[0], [window.world2screen([startgrid[0], 0])[0],0]); startgrid[0] += w_step; } while(startgrid[1] <= endgrid[1]) { - GUI.text(startgrid[1], [0, Window.world2screen([0, startgrid[1]])[1]]); + GUI.text(startgrid[1], [0, window.world2screen([0, startgrid[1]])[1]]); startgrid[1] += h_step; } @@ -663,10 +663,7 @@ editor.inputs.drop = function(str) { img[0].path = str; } -editor.inputs.f9 = function() { - console.warn("CAPTURING"); - cmd(173, "capture.bmp", 0, 0, 500, 500); -} +editor.inputs.f9 = function() { os.capture( "capture.bmp", 0, 0, 500, 500); } editor.inputs.release_post = function() { editor.snapshot(); @@ -918,7 +915,7 @@ editor.inputs['C-s'] = function() { return; - Game.all_objects(function(x) { + game.all_objects(function(x) { if (typeof x !== 'object') return; if (!('_ed' in x)) return; if (x._ed.dirty) return; @@ -1160,12 +1157,12 @@ editor.inputs.mouse.move = function(pos, dpos) if (editor.z_start) editor.camera.zoom -= dpos.y/500; else if (editor.joystart) - editor.camera.pos = editor.camera.pos.sub(Game.camera.dir_view2world(dpos)); + editor.camera.pos = editor.camera.pos.sub(game.camera.dir_view2world(dpos)); } editor.grabselect?.forEach(function(x) { if (!x) return; - x.move(Game.camera.dir_view2world(dpos)); + x.move(game.camera.dir_view2world(dpos)); x.sync(); }); @@ -1196,7 +1193,7 @@ editor.inputs.mouse.move = function(pos, dpos) editor.inputs.mouse.scroll = function(scroll) { scroll.y *= -1; - editor.camera.move(Game.camera.dir_view2world(scroll.scale(-3))); + editor.camera.move(game.camera.dir_view2world(scroll.scale(-3))); } editor.inputs.mouse['C-scroll'] = function(scroll) @@ -1416,7 +1413,7 @@ var inputpanel = { toString() { return this.title; }, value: "", on: false, - pos:[100,Window.height-50], + pos:[100,window.height-50], wh:[350,600], anchor: [0,1], padding:[5,-15], @@ -1779,16 +1776,8 @@ var objectexplorer = Object.copy(inputpanel, { switch (typeof val) { case 'object': if (val) { - if (Array.isArray(val)) { -// this.obj[key] = Nuke.pprop(key,val); - break; - } - -// Nuke.newline(2); items.push(Mum.text({str:name})); items.push(Mum.text({str:val.toString(), action: this.goto_obj.bind(val)})); - } else { -// this.obj[key] = Nuke.pprop(key,val); } break; @@ -1798,28 +1787,13 @@ var objectexplorer = Object.copy(inputpanel, { break; default: - if (!hidden) {// && Object.getOwnPropertyDescriptor(this.obj, key).writable) { -// this.obj[key] = Nuke.pprop(key, this.obj[key]); - -/* if (key in this.obj.__proto__) { - if (Nuke.button("delete " + key)) { - if ("_"+key in this.obj) - delete this.obj["_"+key]; - else - delete this.obj[key]; - } - }*/ - } - else { - items.push(Mum.text({str:name})); - items.push(Mum.text({str:val.toString()})); - } + items.push(Mum.text({str:name})); + items.push(Mum.text({str:val.toString()})); break; } }); items.push(Mum.text({str:"Properties that can be pulled in ..."})); -// Nuke.newline(3); var pullprops = []; for (var key in this.obj.__proto__) { if (!this.obj.hasOwn(key)) { @@ -1832,7 +1806,6 @@ var objectexplorer = Object.copy(inputpanel, { pullprops.forEach(function(key) { items.push(Mum.text({str:key})); -// this.obj[key] = this.obj[key]; }); return items; @@ -1841,18 +1814,6 @@ var objectexplorer = Object.copy(inputpanel, { }); -var helppanel = Object.copy(inputpanel, { - title: "help", - - start() { - this.helptext = slurp("editor.adoc"); - }, - - guibody() { - Nuke.label(this.helptext); - }, -}); - var openlevelpanel = Object.copy(inputpanel, { title: "open entity", action() { @@ -2014,19 +1975,6 @@ function tab_complete(val, list) { return ret ? ret : val; } -var texgui = Object.copy(inputpanel, { - get path() { return this._path; }, - set path(x) { - this._path = x; - this.title = "texture " + x; - }, - - guibody() { - Nuke.label("texture"); - Nuke.img(this.path); - }, -}); - var entitylistpanel = Object.copy(inputpanel, { title: "Level object list", level: {}, @@ -2071,8 +2019,8 @@ if (io.exists("editor.config")) /* This is the editor level & camera - NOT the currently edited level, but a level to hold editor things */ sim.pause(); -Window.editor = true; -Debug.draw_phys(true); +window.editor = true; +Debug.draw_phys = true; return { editor diff --git a/scripts/engine.js b/scripts/engine.js index 8ecb397..8cf4fd7 100644 --- a/scripts/engine.js +++ b/scripts/engine.js @@ -12,16 +12,18 @@ Object.assign(console, { var caller = (new Error()).stack.split('\n')[2]; if (caller) { - var m = caller.match(/\((.*)\:/)[1]; + var md = caller.match(/\((.*)\:/); + var m = md ? md[1] : "SCRIPT"; if (m) file = m; - m = caller.match(/\:(\d*)\)/)[1]; + md = caller.match(/\:(\d*)\)/); + m = md ? md[1] : 0; if (m) line = m; } console.rec(lvl, msg, file, line); }, - spam(msg) { console.pprint(msg,0); }, + spam(msg) { console.pprint (msg,0); }, debug(msg) { console.pprint(msg,1); }, info(msg) { console.pprint(msg, 2); }, warn(msg) { console.pprint(msg, 3); }, @@ -56,6 +58,8 @@ console.doc = { clear: "Clear console." }; +console.stdout_lvl = 1; + globalThis.global = globalThis; function use(file) @@ -129,13 +133,10 @@ function feval_env(file, env) function load_env(file,env) { env ??= global; -// var script = io.slurp(file); var script = io.slurp(file); eval_env(script, env, file); -// cmd(16, file, env); -// var script = io.slurp(file); -// cmd(123, script, env, file); } + load_env.doc = `Load a given file with 'env' as **this**. Does not add to the global namespace.`; var load = use; @@ -162,6 +163,13 @@ var sim = { var physlag = 0; var timescale = 1; +var gggstart = game.engine_start; +game.engine_start = function(s) { + gggstart(process); + world_start(); + s(); +} + function process() { var dt = profile.secs() - frame_t; @@ -183,19 +191,13 @@ function process() prosperon.phys2d_step(physMS*timescale); prosperon.physupdate(physMS*timescale); } + prosperon.window_render(); } -global.Game = { - engine_start(fn) { - console.info("Starting rendering and sound ..."); - cmd(257, fn, process); - }, - - object_count() { - return cmd(214); - }, +game.timescale = 1; +Object.assign(game, { all_objects(fn) { /* Wind down from Primum */ }, @@ -214,39 +216,17 @@ global.Game = { find_tag(tag){ }, +}); - wait_fns: [], - - wait_exec(fn) { - if (!phys_stepping()) - fn(); - else - this.wait_fns.push(fn); - }, - - exec() { - this.wait_fns.forEach(function(x) { x(); }); - - this.wait_fns = []; - }, -}; - -Game.gc = function() { cmd(259); } -Game.gc.doc = "Force the garbage collector to run."; - -Game.doc = {}; -Game.doc.object = "Returns the entity belonging to a given id."; -Game.doc.quit = "Immediately quit the game."; -Game.doc.pause = "Pause game simulation."; -Game.doc.stop = "Stop game simulation. This does the same thing as 'pause', and if the game is a debug build, starts its editor."; -Game.doc.play = "Resume or start game simulation."; -Game.doc.editor_mode = "Set to true for the game to only update on input; otherwise the game updates every frame."; -Game.doc.dt = "Current frame dt."; -Game.doc.view_camera = "Set the camera for the current view."; -Game.doc.camera = "Current camera."; - -prosperon.version = cmd(255); -prosperon.revision = cmd(256); +game.doc = {}; +game.doc.object = "Returns the entity belonging to a given id."; +game.doc.pause = "Pause game simulation."; +game.doc.stop = "Stop game simulation. This does the same thing as 'pause', and if the game is a debug build, starts its editor."; +game.doc.play = "Resume or start game simulation."; +game.doc.editor_mode = "Set to true for the game to only update on input; otherwise the game updates every frame."; +game.doc.dt = "Current frame dt."; +game.doc.view_camera = "Set the camera for the current view."; +game.doc.camera = "Current camera."; prosperon.semver = {}; prosperon.semver.valid = function(v, range) @@ -362,9 +342,13 @@ var Register = { if (typeof obj === 'object') fn = fn.bind(obj); fns.push(fn); - return function() { fns.remove(fn); }; + return function() { + console.info(`removed from ${name}.`); + fns.remove(fn); + }; } prosperon[name] = function(...args) { fns.forEach(x => x(...args)); } + prosperon[name].fns = fns; n.clear = function() { fns = []; } Register[name] = n; @@ -405,7 +389,7 @@ var Event = { }, }; -Window.modetypes = { +window.modetypes = { stretch: 0, // stretch to fill window keep: 1, // keep exact dimensions width: 2, // keep width @@ -414,39 +398,36 @@ Window.modetypes = { full: 5 // expand out beyond window }; -Window.size = [640, 480]; +window.size = [640, 480]; -Window.screen2world = function(screenpos) { - if (Game.camera) - return Game.camera.view2world(screenpos); +window.screen2world = function(screenpos) { + if (game.camera) + return game.camera.view2world(screenpos); return screenpos; } -Window.world2screen = function(worldpos) { - return Game.camera.world2view(worldpos); +window.world2screen = function(worldpos) { + return game.camera.world2view(worldpos); } -Window.icon = function(path) { cmd(90, path); }; -Window.icon.doc = "Set the icon of the window using the PNG image at path."; - +window.set_icon.doc = "Set the icon of the window using the PNG image at path."; global.mixin("scripts/spline.js"); global.mixin("scripts/components.js"); -Window.doc = {}; -Window.doc.width = "Width of the game window."; -Window.doc.height = "Height of the game window."; -Window.doc.dimensions = "Window width and height packaged in an array [width,height]"; -Window.doc.title = "Name in the title bar of the window."; -Window.doc.boundingbox = "Boundingbox of the window, with top and right being its height and width."; - -Register.update.register(Game.exec, Game); +window.doc = {}; +window.doc.width = "Width of the game window."; +window.doc.height = "Height of the game window."; +window.doc.dimensions = "Window width and height packaged in an array [width,height]"; +window.doc.title = "Name in the title bar of the window."; +window.doc.boundingbox = "Boundingbox of the window, with top and right being its height and width."; global.mixin("scripts/actor.js"); global.mixin("scripts/entity.js"); function world_start() { + console.info("START WORLD"); globalThis.world = Object.create(gameobject); world.objects = {}; world.check_dirty = function() {}; @@ -466,16 +447,16 @@ function world_start() { cmd(113,gameobject.body, gameobject); Object.hide(gameobject, 'timescale'); var cam = world.spawn("scripts/camera2d.jso"); - Game.view_camera(cam); + game.view_camera(cam); } global.mixin("scripts/physics.js"); -Game.view_camera = function(cam) +game.view_camera = function(cam) { - Game.camera = cam; - cmd(61, Game.camera.body); + game.camera = cam; + cmd(61, game.camera.body); } -Window.title = `Prosperon v${prosperon.version}`; -Window.size = [500,500]; +window.title = `Prosperon v${prosperon.version}`; +window.size = [500,500]; diff --git a/scripts/entity.js b/scripts/entity.js index f515839..e8fb8ca 100644 --- a/scripts/entity.js +++ b/scripts/entity.js @@ -260,7 +260,7 @@ var gameobject = { sgscale(x) { if (typeof x === 'number') x = [x, x]; - cmd(36, this.body, x) + physics.sgscale(this.body, x) }, phys_material() { @@ -276,7 +276,7 @@ var gameobject = { set_body(2, this.body, x); this.objects.forEach((o, i) => o.set_worldpos(this.this2world(poses[i]))); }, - screenpos() { return Window.world2screen(this.worldpos()); }, + screenpos() { return window.world2screen(this.worldpos()); }, worldangle() { return Math.rad2turn(q_body(2, this.body)); }, sworldangle(x) { set_body(0, this.body, Math.turn2rad(x)); }, @@ -437,8 +437,8 @@ var gameobject = { shove_at(vec, at) { set_body(14, this.body, vec, at); }, world2this(pos) { return cmd(70, this.body, pos); }, this2world(pos) { return cmd(71, this.body, pos); }, - this2screen(pos) { return Window.world2screen(this.this2world(pos)); }, - screen2this(pos) { return this.world2this(Window.screen2world(pos)); }, + this2screen(pos) { return window.world2screen(this.this2world(pos)); }, + screen2this(pos) { return this.world2this(window.screen2world(pos)); }, dir_world2this(dir) { return cmd(160, this.body, dir); }, dir_this2world(dir) { return cmd(161, this.body, dir); }, @@ -598,6 +598,7 @@ var gameobject = { if (this.__kill) return; this.__kill = true; + console.info(`killing ${this.toString()}`); this.timers.forEach(t => t()); this.timers = []; Event.rm_obj(this); @@ -815,7 +816,7 @@ function file2fqn(file) { return ur[fqn]; } -Game.loadurs = function() { +game.loadurs = function() { ur = {}; ur._list = []; /* FIND ALL URS IN A PROJECT */ diff --git a/scripts/gui.js b/scripts/gui.js index 3e10457..ab31af7 100644 --- a/scripts/gui.js +++ b/scripts/gui.js @@ -2,6 +2,8 @@ GUI functions take screen space coordinates */ +gui.scissor_win = function() { gui.scissor(0,0,window.width,window.height); } + var GUI = { text(str, pos, size, color, wrap, anchor, cursor) { size ??= 1; @@ -27,12 +29,6 @@ var GUI = { return bb; }, - - scissor(x,y,w,h) { - cmd(140,x,y,w,h); - }, - - scissor_win() { cmd(140,0,0,Window.width,Window.height); }, image(path,pos,color) { color ??= Color.black; @@ -197,7 +193,7 @@ Mum.text = Mum.extend({ this.height = this.wh.y; var aa = [0,1].sub(params.anchor); var pos = cursor.add(params.wh.scale(aa)).add(params.offset); - cmd(263, params.font); + gui.font_set(params.font); ui_text(params.str, pos, params.font_size, params.color, this.width, params.caret); }, @@ -236,8 +232,8 @@ Mum.window = Mum.extend({ var p = cursor.sub(this.wh.scale(this.anchor)).add(this.padding); GUI.window(p,this.wh, this.color); this.bb = bbox.blwh(p, this.wh); - GUI.flush(); - GUI.scissor(p.x,p.y,this.wh.x,this.wh.y); + gui.flush(); + gui.scissor(p.x,p.y,this.wh.x,this.wh.y); this.max_width = this.width; if (this.selectable) GUI.controls.check_bb(this); var pos = [this.bb.l, this.bb.t].add(this.padding); @@ -245,8 +241,8 @@ Mum.window = Mum.extend({ if (item.hide) return; item.draw(pos.slice(),this); }, this); - GUI.flush(); - GUI.scissor_win(); + gui.flush(); + gui.scissor_win(); }, }); @@ -303,8 +299,6 @@ GUI.window = function(pos, wh, color) render.box(p,wh,color); } -GUI.flush = function() { cmd(141); }; - Mum.debug_colors = { bounds: Color.red.slice(), margin: Color.blue.slice(), diff --git a/scripts/input.js b/scripts/input.js index dd86b71..fb9bde2 100644 --- a/scripts/input.js +++ b/scripts/input.js @@ -128,15 +128,15 @@ prosperon.mouseup = function(b){ var Mouse = { screenpos() { return mousepos.slice(); }, - worldpos() { return Window.screen2world(mousepos); }, - disabled() { cmd(46, 1); }, - normal() { cmd(46, 0);}, + worldpos() { return window.screen2world(mousepos); }, + disabled() { input.mouse_mode(1); }, + normal() { input.mouse_mode(0); }, mode(m) { if (Mouse.custom[m]) - cmd(97, Mouse.custom[m]); + input.cursor_img(Mouse.custom[m]); else - cmd(17, m); + input.mouse_cursor(m); }, set_custom_cursor(img, mode) { @@ -144,7 +144,7 @@ var Mouse = { if (!img) delete Mouse.custom[mode]; else { - cmd(97, img); + input.cursor_img(img); Mouse.custom[mode] = img; } }, @@ -182,8 +182,6 @@ var Keys = { }, }; -var input = {}; - input.state2str = function(state) { if (typeof state === 'string') return state; switch (state) { @@ -236,13 +234,6 @@ input.action = { actions: [], }; -input.keyboard_show = function(show) -{ - cmd(250,show); -} - -input.keyboard_shown = function() { return cmd(248); } - /* May be a human player; may be an AI player */ var Player = { players: [], diff --git a/scripts/physics.js b/scripts/physics.js index 5cb102e..814b6a8 100644 --- a/scripts/physics.js +++ b/scripts/physics.js @@ -10,7 +10,7 @@ var HIT = { */ -var physics = { +Object.assign(physics, { dynamic: 0, kinematic: 1, static: 2, @@ -36,7 +36,7 @@ var physics = { if (!Array.isArray(pos)) return [0,0]; return pos.reduce((a,i) => a.add(i)).map(g => g/pos.length); }, -}; +}); physics.doc = {}; physics.doc.pos_query = "Returns any object colliding with the given point."; @@ -53,7 +53,7 @@ physics.collision = { }, sync() { for (var i = 0; i < this.num; i++) - cmd(76,i,this.types[i]); + physics.set_cat_mask(i,this.types[i]); }, }; diff --git a/scripts/render.js b/scripts/render.js index 8d7c9eb..43eb96d 100644 --- a/scripts/render.js +++ b/scripts/render.js @@ -1,9 +1,3 @@ -var render = { - normal() { cmd(67);}, - wireframe() { cmd(68); }, - pass() { }, -}; - render.doc = { doc: "Functions for rendering modes.", normal: "Final render with all lighting.", @@ -50,18 +44,15 @@ render.device.doc = `Device resolutions given as [x,y,inches diagonal].`; render.point = function(pos,size,color) { color ??= Color.blue; render.circle(pos,size,color); - }; - +}; + +var tmpline = render.line; render.line = function(points, color, thickness) { thickness ??= 1; color ??= Color.white; - cmd(83, points, color, thickness); + tmpline(points,color,thickness); }; -render.poly = function(points, color) { cmd_points(0,points,color); }; - -render.circle = function(pos, radius, color) { cmd(115, pos, radius, color); }; - render.cross = function(pos, size, color) { color ??= Color.red; var a = [ diff --git a/scripts/std.js b/scripts/std.js index 7b56e51..a6112d4 100644 --- a/scripts/std.js +++ b/scripts/std.js @@ -6,11 +6,10 @@ if (os.sys() === 'windows') else os.user = os.env("USER"); - var appy = {}; appy.inputs = {}; if (os.sys() === 'macos') { - appy.inputs['S-q'] = function() { Game.quit(); }; + appy.inputs['S-q'] = os.quit; appy.inputs['S-h'] = function() { }; } @@ -35,7 +34,7 @@ var otherpath = { } os.prefpath = function() { - return otherpath[os.sys()] + "/" + (Game.title ? Game.title : "Untitled Prosperon Game"); + return otherpath[os.sys()] + "/" + (game.title ? game.title : "Untitled Prosperon Game"); } var projectfile = ".prosperon/project.json"; @@ -191,12 +190,6 @@ io.mixin({ paths = paths.filter(function(str) { return str.ext() === ext; }); return paths; }, - compile(script) { - return cmd(260, script); - }, - run_bytecode(byte_file) { - return cmd(261, byte_file); - }, glob(pat) { var paths = io.ls('.'); @@ -250,7 +243,7 @@ Cmdline.register_order("edit", function() { return; } - Game.engine_start(function() { + game.engine_start(function() { global.mixin("scripts/editor.js"); use("editorconfig.js"); editor.enter_editor(); @@ -258,16 +251,17 @@ Cmdline.register_order("edit", function() { }, "Edit the project in this folder. Give it the name of an UR to edit that specific object.", "?UR?"); Cmdline.register_order("init", function() { + say('top of init'); if (io.exists(projectfile)) { say("Already a game here."); return; } - + say('top of ls'); if (!(io.ls().length === 0)) { say("Directory is not empty. Make an empty one and init there."); return; } - + say('top of mkdir'); io.mkdir(".prosperon"); var project = {}; project.version = prosperon.version; @@ -284,7 +278,7 @@ Cmdline.register_order("play", function(argv) { if (argv[0]) io.chdir(argv[0]); - Game.loadurs(); + game.loadurs(); if (!io.exists(projectfile)) { say("No game to play. Try making one with 'prosperon init'."); @@ -292,18 +286,18 @@ Cmdline.register_order("play", function(argv) { } var project = json.decode(io.slurp(projectfile)); - Game.title = project.title; - Window.mode = Window.modetypes.expand; + game.title = project.title; + window.mode = window.modetypes.expand; global.mixin("config.js"); - if (project.title) Window.title = project.title; + if (project.title) window.title = project.title; - if (Window.rendersize.equal([0,0])) Window.rendersize = Window.size; - console.info(`Starting game with window size ${Window.size} and render ${Window.rendersize}.`); + if (window.rendersize.equal([0,0])) window.rendersize = window.size; + console.info(`Starting game with window size ${window.size} and render ${window.rendersize}.`); - Game.engine_start(function() { + game.engine_start(function() { global.mixin("scripts/sound.js"); global.game = actor.spawn("game.js"); - if (project.icon) Window.icon(project.icon); + if (project.icon) window.set_icon(project.icon); }); }, "Play the game present in this folder."); @@ -319,7 +313,7 @@ Cmdline.register_order("pack", function(str) { say(`Packing into ${packname}`); - cmd(124, packname); + io.pack_engine(packname);n io.chmod(packname, 666); }, "Pack the game into the given name.", "NAME"); @@ -340,7 +334,7 @@ Cmdline.register_order("qoa", function(argv) { for (var file of argv) { if (!sounds.includes(file.ext())) continue; say(`converting ${file}`); - cmd(262,file); + io.save_qoa(file); } }, "Convert file(s) to qoa."); @@ -359,7 +353,7 @@ Cmdline.register_order("about", function(argv) { }, "Get information about this game."); Cmdline.register_order("ur", function(argv) { - Game.loadurs(); + game.loadurs(); for (var i of ur._list.sort()) say(i); }, "Get information about the ur types in your game."); @@ -457,7 +451,7 @@ Cmdline.register_order("run", function(script) { if (io.exists(script)) try { if (script.endswith("c")) - cmd(261, script); + io.run_bytecode(script); else load(script); } catch(e) { } diff --git a/source/engine/debug/log.c b/source/engine/debug/log.c index 50bf6b9..0188a88 100644 --- a/source/engine/debug/log.c +++ b/source/engine/debug/log.c @@ -40,10 +40,16 @@ int stdout_lvl = LOG_ERROR; void log_init() { #ifndef NDEBUG - logout = fopen(".prosperon/log.txt", "w"); - writeout = fopen(".prosperon/transcript.txt", "w"); - dump = fopen(".prosperon/quickjs.txt", "w"); - quickjs_set_dumpout(dump); + if (!fexists(".prosperon")) + logout = writeout = dump = stdout; + else { + logout = fopen(".prosperon/log.txt", "w"); + writeout = fopen(".prosperon/transcript.txt", "w"); + dump = fopen(".prosperon/quickjs.txt", "w"); + quickjs_set_dumpout(dump); + } + + quickjs_set_dumpout(dump); #endif } diff --git a/source/engine/gameobject.c b/source/engine/gameobject.c index e39efcc..3d55aa5 100644 --- a/source/engine/gameobject.c +++ b/source/engine/gameobject.c @@ -233,9 +233,3 @@ void gameobject_draw_debug(gameobject *go) { cpVect pos = cpBodyGetPosition(go->body); cpBodyEachShape(go->body, body_draw_shapes_dbg, NULL); } - -void gameobject_draw_debugs() -{ - for (int i = 0; i < arrlen(gameobjects); i++) - gameobject_draw_debug(gameobjects[i]); -} diff --git a/source/engine/gameobject.h b/source/engine/gameobject.h index 04d9236..7c97442 100644 --- a/source/engine/gameobject.h +++ b/source/engine/gameobject.h @@ -96,5 +96,4 @@ void go_shape_apply(cpBody *body, cpShape *shape, gameobject *go); gameobject *pos2gameobject(HMM_Vec2 pos, float give); void gameobject_draw_debug(gameobject *go); -void gameobject_draw_debugs(); #endif diff --git a/source/engine/jsffi.c b/source/engine/jsffi.c index d8a554a..0e3b623 100644 --- a/source/engine/jsffi.c +++ b/source/engine/jsffi.c @@ -218,7 +218,7 @@ int js_arrlen(JSValue v) { return len; } -char *js_nota_decode(JSValue *tmp, char *nota) +char *js_do_nota_decode(JSValue *tmp, char *nota) { int type = nota_type(nota); JSValue ret2; @@ -240,7 +240,7 @@ char *js_nota_decode(JSValue *tmp, char *nota) nota = nota_read_array(&n, nota); *tmp = JS_NewArray(js); for (int i = 0; i < n; i++) { - nota = js_nota_decode(&ret2, nota); + nota = js_do_nota_decode(&ret2, nota); JS_SetPropertyInt64(js, *tmp, i, ret2); } break; @@ -249,7 +249,7 @@ char *js_nota_decode(JSValue *tmp, char *nota) *tmp = JS_NewObject(js); for (int i = 0; i < n; i++) { nota = nota_read_text(&str, nota); - nota = js_nota_decode(&ret2, nota); + nota = js_do_nota_decode(&ret2, nota); JS_SetPropertyStr(js, *tmp, str, ret2); free(str); } @@ -274,7 +274,7 @@ char *js_nota_decode(JSValue *tmp, char *nota) return nota; } -char *js_nota_encode(JSValue v, char *nota) +char *js_do_nota_encode(JSValue v, char *nota) { int tag = JS_VALUE_GET_TAG(v); char *str = NULL; @@ -304,7 +304,7 @@ char *js_nota_encode(JSValue v, char *nota) int n = js_arrlen(v); nota = nota_write_array(n, nota); for (int i = 0; i < n; i++) - nota = js_nota_encode(js_arridx(v, i), nota); + nota = js_do_nota_encode(js_arridx(v, i), nota); return nota; } n = JS_GetOwnPropertyNames(js, &ptab, &plen, v, JS_GPN_ENUM_ONLY | JS_GPN_STRING_MASK); @@ -318,7 +318,7 @@ char *js_nota_encode(JSValue v, char *nota) nota = nota_write_text(str, nota); JS_FreeCString(js, str); - nota = js_nota_encode(val, nota); + nota = js_do_nota_encode(val, nota); JS_FreeValue(js,val); } js_free(js, ptab); @@ -655,18 +655,6 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) size_t plen = 0; switch (cmd) { - case 4: - debug_draw_phys(JS_ToBool(js, argv[1])); - break; - - case 15: - gameobject_draw_debug(js2gameobject(argv[1])); - break; - - case 17: - sapp_set_mouse_cursor(js2int(argv[1])); - break; - case 18: shape_set_sensor(js2ptr(argv[1]), JS_ToBool(js, argv[2])); break; @@ -683,29 +671,11 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) ret = JS_NewBool(js, shape_is_enabled(js2ptr(argv[1]))); break; - case 36: - js2gameobject(argv[1])->scale.XY = js2vec2(argv[2]); - gameobject_apply(js2gameobject(argv[1])); - cpSpaceReindexShapesForBody(space, js2gameobject(argv[1])->body); - break; - case 44: go = pos2gameobject(js2vec2(argv[1]), js2number(argv[2])); ret = go ? JS_DupValue(js,go->ref) : JS_UNDEFINED; break; - case 46: - set_mouse_mode(js2int(argv[1])); - break; - - case 47: - draw_grid(js2number(argv[1]), js2number(argv[2]), js2color(argv[3])); - break; - - case 51: - draw_cppoint(js2vec2(argv[1]), js2number(argv[2]), js2color(argv[3])); - break; - case 52: ids = phys2d_query_box(js2vec2(argv[1]), js2vec2(argv[2])); ret = gos2ref(ids); @@ -734,14 +704,6 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) ret = vec22js(tex_get_dimensions(texture_from_file(str))); break; - case 67: - opengl_rendermode(LIT); - break; - - case 68: - opengl_rendermode(WIREFRAME); - break; - case 70: ret = vec22js(world2go(js2gameobject(argv[1]), js2vec2(argv[2]))); break; @@ -750,20 +712,12 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) ret = vec22js(go2world(js2gameobject(argv[1]), js2vec2(argv[2]))); break; - case 76: - set_cat_mask(js2int(argv[1]), js2bitmask(argv[2])); - break; - case 80: ids = phys2d_query_shape(js2ptr(argv[1])); ret = gos2ref(ids); arrfree(ids); break; - case 82: - gameobject_draw_debug(js2gameobject(argv[1])); - break; - case 83: v1 = js2cpvec2arr(argv[1]); draw_edge(v1, js_arrlen(argv[1]), js2color(argv[2]), js2number(argv[3]), 0, js2color(argv[2]), 10); @@ -779,20 +733,6 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) ret = ints2js(intids); arrfree(intids); break; - - case 88: - ret = number2js(HMM_DotV2(js2vec2(argv[1]), js2vec2(argv[2]))); - break; - - case 90: - str = JS_ToCString(js, argv[1]); - window_set_icon(str); - break; - - case 97: - str = js2str(argv[1]); - cursor_img(str); - break; case 103: ret = vec22js(js2gameobject(argv[1])->scale.XY); @@ -806,31 +746,17 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) js2gameobject(argv[1])->ref = argv[2]; break; - case 115: - draw_circle(js2vec2(argv[1]), js2number(argv[2]), js2number(argv[2]), js2color(argv[3]), -1); - break; - case 118: str = JS_ToCString(js,argv[1]); ret = bb2js(text_bb(str, js2number(argv[2]), js2number(argv[3]), 1.0)); break; - case 119: - str = JS_ToCString(js, argv[1]); - ret = JS_NewInt64(js, file_mod_secs(str)); - break; - case 123: str = JS_ToCString(js, argv[1]); str2 = JS_ToCString(js, argv[3]); ret = eval_script_env(str, argv[2], str2); break; - case 124: - str = JS_ToCString(js, argv[1]); - pack_engine(str); - break; - case 131: gif_rec_start(js2int(argv[1]), js2int(argv[2]), js2int(argv[3]), js2int(argv[4])); break; @@ -856,14 +782,6 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) ret = JS_NewInt64(js, gif_nframes(str)); break; - case 140: - sg_apply_scissor_rectf(js2number(argv[1]), js2number(argv[2]), js2number(argv[3]), js2number(argv[4]), 0); - break; - - case 141: - text_flush(&hudproj); - break; - case 149: ((struct drawmodel *)js2ptr(argv[1]))->model = GetExistingModel(js2str(argv[2])); break; @@ -883,14 +801,6 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) ret = vec22js(mat_t_dir(t_go2world(js2gameobject(argv[1])), js2vec2(argv[2]))); break; - case 173: - str = js2str(argv[1]); - capture_screen(js2number(argv[2]), js2number(argv[3]), js2number(argv[4]), js2number(argv[5]), str); - break; - case 174: - str = js2str(argv[1]); - ds_openvideo(str); - break; case 177: plugin_node(js2dsp_node(argv[1]), js2dsp_node(argv[2])); break; @@ -959,9 +869,6 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) case 213: free_drawmodel(js2ptr(argv[1])); break; - case 214: - ret = int2js(go_count()); - break; case 221: ret = constraint2js(constraint_make(cpPivotJointNew(js2gameobject(argv[1])->body, js2gameobject(argv[2])->body,js2vec2(argv[3]).cp))); @@ -998,20 +905,6 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) ret = constraint2js(constraint_make(cpSimpleMotorNew(js2body(argv[1]), js2body(argv[2]), js2number(argv[3])))); break; - case 234: - ret = emitter2js(make_emitter()); - break; - case 248: - ret = bool2js(sapp_keyboard_shown()); - break; - case 249: - str = JS_ToCString(js,argv[2]); - js2emitter(argv[1])->texture = texture_from_file(str); - break; - case 250: - sapp_show_keyboard(js2bool(argv[1])); - break; - case 253: ret = warp_gravity2js(warp_gravity_make()); break; @@ -1019,48 +912,12 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) ret = warp_damp2js(warp_damp_make()); break; - case 255: - ret = str2js(VER); - break; - - case 256: - ret = str2js(COM); - break; - case 257: - engine_start(argv[1], argv[2]); - break; - - case 259: - script_gc(); - break; - case 260: - str = js2str(argv[1]); - d1 = script_compile(str, &plen); - ret = JS_NewArrayBufferCopy(js, d1, plen); - break; - case 261: - str = js2str(argv[1]); - d1 = slurp_file(str, &plen); - return script_run_bytecode(d1, plen); - break; - case 262: - str = js2str(argv[1]); - save_qoa(str); - break; - case 263: - str = js2str(argv[1]); - font_set(str); - break; case 268: if (js2bool(argv[1])) ret = JS_GetClassProto(js, js_sprite_id); else ret = sprite2js(sprite_make()); break; - case 269: - str = js2str(argv[1]); - ret = texture2js(texture_from_file(str)); - break; } if (str) JS_FreeCString(js, str); @@ -1323,6 +1180,14 @@ JSValue ID##_get_##ENTRY (JSContext *js, JSValue this) { \ return n->ENTRY; \ } \ + +#define DEF_FN_STR(NAME) JSValue js_##NAME (JSContext *js, JSValueConst this, int argc, JSValue *argv) { \ + char *str = js2str(argv[0]); \ + NAME (str); \ + JS_FreeCString(js,str); \ + return JS_UNDEFINED; \ +} \ + GETSET_PAIR(warp_gravity, strength, number) GETSET_PAIR(warp_gravity, decay, number) GETSET_PAIR(warp_gravity, spherical, bool) @@ -1333,6 +1198,8 @@ GETSET_PAIR(warp_gravity, planar_force, vec3) #define MIST_FUNC_DEF(TYPE, FN, LEN) MIST_CFUNC_DEF(#FN, LEN, js_##TYPE##_##FN) +#define MIST_FN_STR(NAME) MIST_CFUNC_DEF(#NAME, 1, js_##NAME) + #define MIST_CGETSET_DEF(name, fgetter, fsetter) { name, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } } #define CGETSET_ADD(ID, ENTRY) MIST_CGETSET_DEF(#ENTRY, ID##_get_##ENTRY, ID##_set_##ENTRY) @@ -1371,6 +1238,7 @@ GETSET_PAIR(emitter, die_after_collision, bool) GETSET_PAIR(emitter, persist, number) GETSET_PAIR(emitter, persist_var, number) GETSET_PAIR(emitter, warp_mask, bitmask) +GETSET_PAIR(emitter, texture, texture) JSValue js_emitter_start (JSContext *js, JSValue this, int argc, JSValue *argv) { @@ -1429,10 +1297,100 @@ JSValue js_os_sys(JSContext *js, JSValueConst this, int argc, JSValue *argv) JSValue js_os_quit(JSContext *js, JSValueConst this) { quit(); return JS_UNDEFINED; } JSValue js_os_reindex_static(JSContext *js, JSValueConst this) { cpSpaceReindexStatic(space); return JS_UNDEFINED; } +#define RETUN return JS_UNDEFINED + +JSValue js_os_gc(JSContext *js, JSValueConst this) { script_gc(); RETUN; } + +JSValue js_os_capture(JSContext *js, JSValueConst this, int argc, JSValue *argv) { + char *str = js2str(argv[0]); + capture_screen(js2number(argv[1]), js2number(argv[2]), js2number(argv[4]), js2number(argv[5]), str); + JS_FreeCString(js,str); + RETUN; +} + static const JSCFunctionListEntry js_os_funcs[] = { MIST_FUNC_DEF(os, cwd, 0), MIST_FUNC_DEF(os, env, 1), - MIST_FUNC_DEF(os, sys, 0) + MIST_FUNC_DEF(os, sys, 0), + MIST_FUNC_DEF(os, quit, 0), + MIST_FUNC_DEF(os, reindex_static, 0), + MIST_FUNC_DEF(os, gc, 0), + MIST_FUNC_DEF(os, capture, 5), +}; + +JSValue js_render_normal(JSContext *js, JSValueConst this) { opengl_rendermode(LIT); RETUN; } +JSValue js_render_wireframe(JSContext *js, JSValueConst this) { opengl_rendermode(WIREFRAME); RETUN; } +JSValue js_render_grid(JSContext *js, JSValueConst this, int argc, JSValue *argv) { draw_grid(js2number(argv[0]), js2number(argv[1]), js2color(argv[2])); RETUN; } +JSValue js_render_point(JSContext *js, JSValueConst this, int argc, JSValue *argv) { draw_cppoint(js2vec2(argv[0]), js2number(argv[1]), js2color(argv[2])); RETUN;} +JSValue js_render_circle(JSContext *js, JSValueConst this, int argc, JSValue *argv) { draw_circle(js2vec2(argv[0]), js2number(argv[1]), js2number(argv[2]), js2color(argv[3]), -1); RETUN; } +JSValue js_render_poly(JSContext *js, JSValueConst this, int argc, JSValue *argv) { + int n = js_arrlen(argv[0]); + HMM_Vec2 points[n]; + for (int i = 0; i < n; i++) + points[i] = js2vec2(js_arridx(argv[0], i)); + draw_poly(points, n, js2color(argv[1])); + RETUN; +} +JSValue js_render_line(JSContext *js, JSValueConst this, int argc, JSValue *argv) { + void *v1 = js2cpvec2arr(argv[0]); + draw_edge(v1, js_arrlen(argv[0]), js2color(argv[1]), js2number(argv[2]), 0, js2color(argv[1]), 10); + RETUN; +} + +static const JSCFunctionListEntry js_render_funcs[] = { + MIST_FUNC_DEF(render, normal, 0), + MIST_FUNC_DEF(render, wireframe, 0), + MIST_FUNC_DEF(render, grid, 3), + MIST_FUNC_DEF(render, point, 3), + MIST_FUNC_DEF(render, circle, 3), + MIST_FUNC_DEF(render, poly, 2), + MIST_FUNC_DEF(render, line, 3), +}; + +JSValue js_gui_flush(JSContext *js, JSValueConst this) { text_flush(&hudproj); RETUN; } +JSValue js_gui_scissor(JSContext *js, JSValueConst this, int argc, JSValue *argv) { + sg_apply_scissor_rectf(js2number(argv[0]), js2number(argv[1]), js2number(argv[2]), js2number(argv[3]), 0); + RETUN; +} + +DEF_FN_STR(font_set) + +static const JSCFunctionListEntry js_gui_funcs[] = { + MIST_FUNC_DEF(gui, flush, 0), + MIST_FUNC_DEF(gui, scissor, 4), + MIST_FN_STR(font_set), +}; + +JSValue js_vector_dot(JSContext *js, JSValueConst this, int argc, JSValue *argv) { return number2js(HMM_DotV2(js2vec2(argv[0]), js2vec2(argv[1]))) ; }; + +static const JSCFunctionListEntry js_vector_funcs[] = { + MIST_FUNC_DEF(vector,dot,2), +}; + +JSValue js_game_engine_start(JSContext *js, JSValueConst this, int argc, JSValue *argv) { + engine_start(argv[0]); + RETUN; +} +JSValue js_game_object_count(JSContext *js, JSValueConst this) { return number2js(go_count()); } + +static const JSCFunctionListEntry js_game_funcs[] = { + MIST_FUNC_DEF(game, engine_start, 2), + MIST_FUNC_DEF(game, object_count, 0) +}; + +JSValue js_input_show_keyboard(JSContext *js, JSValueConst this, int argc, JSValue *argv) { sapp_show_keyboard(js2bool(argv[0])); RETUN; } +JSValue js_input_keyboard_shown(JSContext *js, JSValueConst this) { return bool2js(sapp_keyboard_shown()); } +JSValue js_input_mouse_mode(JSContext *js, JSValueConst this, int argc, JSValue *argv) { set_mouse_mode(js2int(argv[0])); RETUN; } +JSValue js_input_mouse_cursor(JSContext *js, JSValueConst this, int argc, JSValue *argv) { sapp_set_mouse_cursor(js2int(argv[0])); RETUN; } + +DEF_FN_STR(cursor_img) + +static const JSCFunctionListEntry js_input_funcs[] = { + MIST_FUNC_DEF(input, show_keyboard, 1), + MIST_FUNC_DEF(input, keyboard_shown, 0), + MIST_FUNC_DEF(input, mouse_mode, 1), + MIST_FUNC_DEF(input, mouse_cursor, 1), + MIST_FN_STR(cursor_img) }; #define GETSET_GLOBAL(ENTRY, TYPE) \ @@ -1641,18 +1599,65 @@ JSValue js_io_chmod(JSContext *js, JSValueConst this, int argc, JSValue *argv) return JS_UNDEFINED; } + +DEF_FN_STR(save_qoa) + +JSValue js_io_compile(JSContext *js, JSValueConst this, int argc, JSValue *argv) { + size_t len; + char *str = js2str(argv[0]); + void *d = script_compile(str, &len); + JSValue ret = JS_NewArrayBufferCopy(js,d,len); + JS_FreeCString(js,str); + free(d); + return ret; +} + +JSValue js_io_run_bytecode(JSContext *js, JSValueConst this, int argc, JSValue *argv) { + size_t len; + char *str = js2str(argv[0]); + void *d = slurp_file(str, &len); + JSValue ret = script_run_bytecode(d, len); + JS_FreeCString(js,str); + free(d); + return ret; +} + +DEF_FN_STR(pack_engine) + static const JSCFunctionListEntry js_io_funcs[] = { - MIST_CFUNC_DEF("exists", 1, js_io_exists), - MIST_CFUNC_DEF("ls", 0, js_io_ls), - MIST_CFUNC_DEF("cp", 2, js_io_cp), - MIST_CFUNC_DEF("mv", 2, js_io_mv), - MIST_CFUNC_DEF("rm", 1, js_io_rm), - MIST_CFUNC_DEF("chdir", 1, js_io_chdir), - MIST_CFUNC_DEF("mkdir", 1, js_io_mkdir), - MIST_CFUNC_DEF("chmod", 2, js_io_chmod), - MIST_CFUNC_DEF("slurp", 1, js_io_slurp), - MIST_CFUNC_DEF("slurpbytes", 1, js_io_slurpbytes), - MIST_CFUNC_DEF("slurpwrite", 2, js_io_slurpwrite), + MIST_FUNC_DEF(io, exists,1), + MIST_FUNC_DEF(io, ls, 0), + MIST_FUNC_DEF(io, cp, 2), + MIST_FUNC_DEF(io, mv, 2), + MIST_FUNC_DEF(io, rm, 1), + MIST_FUNC_DEF(io, chdir, 1), + MIST_FUNC_DEF(io, mkdir, 1), + MIST_FUNC_DEF(io, chmod, 2), + MIST_FUNC_DEF(io, slurp, 1), + MIST_FUNC_DEF(io, slurpbytes, 1), + MIST_FUNC_DEF(io, slurpwrite, 2), + MIST_FN_STR(save_qoa), + MIST_FN_STR(pack_engine) +}; + +JSValue js_debug_draw_gameobject(JSContext *js, JSValueConst this, int argc, JSValue *argv) { gameobject_draw_debug(js2gameobject(argv[0])); RETUN; } + +static const JSCFunctionListEntry js_debug_funcs[] = { + MIST_FUNC_DEF(debug, draw_gameobject, 1) +}; + +JSValue js_physics_sgscale(JSContext *js, JSValueConst this, int argc, JSValue *argv) { + js2gameobject(argv[0])->scale.xy = js2vec2(argv[1]); + gameobject_apply(js2gameobject(argv[0])); + cpSpaceReindexShapesForBody(space, js2gameobject(argv[0])->body); + RETUN; +} + +JSValue js_physics_set_cat_mask(JSContext *js, JSValueConst this, int argc, JSValue *argv) { set_cat_mask(js2int(argv[0]), js2bitmask(argv[1])); RETUN; } + +static const JSCFunctionListEntry js_physics_funcs[] = { + MIST_FUNC_DEF(physics, sgscale, 2), + MIST_FUNC_DEF(physics, set_cat_mask, 2) }; static const JSCFunctionListEntry js_emitter_funcs[] = { @@ -1674,9 +1679,10 @@ static const JSCFunctionListEntry js_emitter_funcs[] = { CGETSET_ADD(emitter, persist), CGETSET_ADD(emitter, persist_var), CGETSET_ADD(emitter, warp_mask), - MIST_CFUNC_DEF("start", 0, js_emitter_start), - MIST_CFUNC_DEF("stop", 0, js_emitter_stop), - MIST_CFUNC_DEF("emit", 1, js_emitter_emit) + MIST_FUNC_DEF(emitter, start, 0), + MIST_FUNC_DEF(emitter, stop, 0), + MIST_FUNC_DEF(emitter, emit, 1), + CGETSET_ADD(emitter, texture), }; GETSET_PAIR(dsp_node, pass, bool) @@ -1701,8 +1707,8 @@ static const JSCFunctionListEntry js_dsp_node_funcs[] = { CGETSET_ADD(dsp_node, off), CGETSET_ADD(dsp_node, gain), CGETSET_ADD(dsp_node, pan), - MIST_CFUNC_DEF("plugin", 1, js_dsp_node_plugin), - MIST_CFUNC_DEF("unplug", 0, js_dsp_node_unplug) + MIST_FUNC_DEF(dsp_node, plugin, 1), + MIST_FUNC_DEF(dsp_node, unplug, 0), }; GETSET_PAIR(sound, loop, bool) @@ -1756,12 +1762,22 @@ static JSValue window_get_title(JSContext *js, JSValueConst this, JSValue v) return str2js(js2window(this)->title); } +DEF_FN_STR(set_icon) + +JSValue js_window_icon(JSContext *js, JSValueConst this, int argc, JSValue *argv) { + char *str = js2str(argv[0]); + set_icon(str); + JS_FreeCString(js,str); + RETUN; +} + static const JSCFunctionListEntry js_window_funcs[] = { CGETSET_ADD(window, size), CGETSET_ADD(window, rendersize), CGETSET_ADD(window, mode), CGETSET_ADD(window, fullscreen), CGETSET_ADD(window, title), + MIST_FN_STR(set_icon), }; #define GETSET_PAIR_BODY(ID, ENTRY, TYPE) \ @@ -1797,7 +1813,6 @@ static const JSCFunctionListEntry js_gameobject_funcs[] = { CGETSET_ADD(gameobject,maxangularvelocity), CGETSET_ADD(gameobject,layer), CGETSET_ADD(gameobject,warp_filter), - CGETSET_ADD(gameobject,scale), CGETSET_ADD(gameobject,drawlayer) }; @@ -1827,20 +1842,27 @@ static const JSCFunctionListEntry js_sprite_funcs[] = { }; #define GETFN(ID, ENTRY, TYPE) \ -JSValue ID##_get_##ENTRY (JSContext *js, JSValue this, JSValue val) {\ +JSValue js_##ID##_##ENTRY (JSContext *js, JSValue this, JSValue val) {\ return TYPE##2js(js2##ID (this)->ENTRY); \ } \ GETFN(texture,width,number) GETFN(texture,height,number) -JSValue texture_get_path(JSContext *js, JSValue this, JSValue val) +JSValue js_texture_path(JSContext *js, JSValue this, JSValue val) { return str2js(tex_get_path(js2texture(this))); } +JSValue js_texture_find(JSContext *js, JSValue this, int argc, JSValue *argv) { + char *str = js2str(argv[0]); + JSValue ret = texture2js(texture_from_file(str)); + JS_FreeCString(js,str); + return ret; +} static const JSCFunctionListEntry js_texture_funcs[] = { - MIST_CFUNC_DEF("width", 0, texture_get_width), - MIST_CFUNC_DEF("height", 0, texture_get_height), - MIST_CFUNC_DEF("path", 0, texture_get_path) + MIST_FUNC_DEF(texture, width, 0), + MIST_FUNC_DEF(texture, height, 0), + MIST_FUNC_DEF(texture, path, 0), + MIST_FUNC_DEF(texture, find, 1), }; JSValue constraint_set_max_force (JSContext *js, JSValue this, JSValue val) { @@ -1902,25 +1924,6 @@ JSValue duk_inflate_cpv(JSContext *js, JSValueConst this, int argc, JSValueConst return arr; } -JSValue duk_cmd_points(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) -{ - int n = js_arrlen(argv[1]); - HMM_Vec2 points[n]; - - for (int i = 0; i < n; i++) - points[i] = js2vec2(js_arridx(argv[1], i)); - - int cmd = js2int(argv[0]); - - switch(cmd) { - case 0: - draw_poly(points, n, js2color(argv[2])); - break; - } - - return JS_UNDEFINED; -} - const char *STRTEST = "TEST STRING"; JSValue duk_performance(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) @@ -1954,31 +1957,31 @@ JSValue duk_performance(JSContext *js, JSValueConst this, int argc, JSValueConst return JS_UNDEFINED; } -JSValue nota_encode(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) +JSValue js_nota_encode(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) { if (argc < 1) return JS_UNDEFINED; JSValue obj = argv[0]; char nota[1024*1024]; // 1MB - char *e = js_nota_encode(obj, nota); + char *e = js_do_nota_encode(obj, nota); return JS_NewArrayBufferCopy(js, nota, e-nota); } -JSValue nota_decode(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) +JSValue js_nota_decode(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) { if (argc < 1) return JS_UNDEFINED; size_t len; char *nota = JS_GetArrayBuffer(js, &len, argv[0]); JSValue ret; - js_nota_decode(&ret, nota); + js_do_nota_decode(&ret, nota); return ret; } -static const JSCFunctionListEntry nota_funcs[] = { - MIST_CFUNC_DEF("encode", 1, nota_encode), - MIST_CFUNC_DEF("decode", 1, nota_decode) +static const JSCFunctionListEntry js_nota_funcs[] = { + MIST_FUNC_DEF(nota, encode, 1), + MIST_FUNC_DEF(nota, decode, 1) }; #define DUK_FUNC(NAME, ARGS) JS_SetPropertyStr(js, globalThis, #NAME, JS_NewCFunction(js, duk_##NAME, #NAME, ARGS)); @@ -1986,10 +1989,6 @@ static const JSCFunctionListEntry nota_funcs[] = { void ffi_load() { globalThis = JS_GetGlobalObject(js); - JSValue nota = JS_NewObject(js); - JS_SetPropertyFunctionList(js, nota, nota_funcs, countof(nota_funcs)); - JS_SetPropertyStr(js, globalThis, "nota", nota); - DUK_FUNC(make_gameobject, 0) DUK_FUNC(set_body, 3) DUK_FUNC(q_body, 2) @@ -2001,7 +2000,6 @@ void ffi_load() { DUK_FUNC(make_edge2d, 3) DUK_FUNC(cmd_edge2d, 6) DUK_FUNC(make_model,2); - DUK_FUNC(cmd_points, 5); DUK_FUNC(cmd, 6) DUK_FUNC(register_collide, 6) @@ -2028,13 +2026,24 @@ void ffi_load() { QJSCLASSPREP_FUNCS(window); QJSGLOBALCLASS(os); + QJSGLOBALCLASS(nota); + QJSGLOBALCLASS(input); QJSGLOBALCLASS(io); QJSGLOBALCLASS(prosperon); QJSGLOBALCLASS(time); QJSGLOBALCLASS(console); QJSGLOBALCLASS(profile); - - JS_SetPropertyStr(js, globalThis, "Window", window2js(&mainwin)); + QJSGLOBALCLASS(game); + QJSGLOBALCLASS(gui); + QJSGLOBALCLASS(debug); + QJSGLOBALCLASS(render); + QJSGLOBALCLASS(physics); + QJSGLOBALCLASS(vector); + + JS_SetPropertyStr(js, prosperon, "version", str2js(VER)); + JS_SetPropertyStr(js, prosperon, "revision", str2js(COM)); + JS_SetPropertyStr(js, globalThis, "window", window2js(&mainwin)); + JS_SetPropertyStr(js, globalThis, "texture", JS_DupValue(js,texture_proto)); JS_FreeValue(js,globalThis); } diff --git a/source/engine/render.c b/source/engine/render.c index 22339e8..0003613 100644 --- a/source/engine/render.c +++ b/source/engine/render.c @@ -143,7 +143,6 @@ float gridOpacity = 0.3f; // Debug render modes bool renderGizmos = false; bool showGrid = true; -bool debugDrawPhysics = false; bool renderNav = false; // Lighting effect flags @@ -158,10 +157,6 @@ char objectName[200] = {'\0'}; // object name buffer sg_image ddimg; -void debug_draw_phys(int draw) { - debugDrawPhysics = draw; -} - void opengl_rendermode(enum RenderMode r) { renderMode = r; } @@ -436,17 +431,12 @@ void full_2d_pass(struct window *window) pos.y + zoom * usesize.y / 2, -10000.f, 10000.f); hudproj = HMM_Orthographic_LH_ZO(0, usesize.x, 0, usesize.y, -1.f, 1.f); - + sprite_draw_all(); model_draw_all(); - script_evalf("prosperon.draw();"); emitters_draw(); - - //// DEBUG - if (debugDrawPhysics) { - gameobject_draw_debugs(); - script_evalf("prosperon.debug();"); - } + + script_evalf("prosperon.draw();"); debug_flush(&projection); text_flush(&projection); diff --git a/source/engine/render.h b/source/engine/render.h index deb021a..ac8dd01 100644 --- a/source/engine/render.h +++ b/source/engine/render.h @@ -59,8 +59,6 @@ void openglInit3d(struct window *window); void openglRender3d(struct window *window, camera3d *camera); void capture_screen(int x, int y, int w, int h, const char *path); -void debug_draw_phys(int draw); - void set_cam_body(cpBody *body); cpVect cam_pos(); float cam_zoom(); diff --git a/source/engine/steamffi.cpp b/source/engine/steamffi.cpp deleted file mode 100644 index 025f9f2..0000000 --- a/source/engine/steamffi.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "steamffi.h" - -#ifdef STEAM -#include "steam/steam_api_flat.h" -void steaminit() -{ - SteamAPI_Init(); -} -#endif diff --git a/source/engine/steamffi.h b/source/engine/steamffi.h deleted file mode 100644 index a7a695c..0000000 --- a/source/engine/steamffi.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef STEAMFFI -#define STEAMFFI - -#ifdef __cplusplus -extern "C"{ -#endif - -void steaminit(); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/source/engine/window.c b/source/engine/window.c index 963efb7..4bcc283 100644 --- a/source/engine/window.c +++ b/source/engine/window.c @@ -58,7 +58,7 @@ void window_suspended(int s) script_evalf("prosperon.suspended(%d);", s); } -void window_set_icon(const char *png) { +void set_icon(const char *png) { icon = texture_from_file(png); window_seticon(&mainwin, icon); } diff --git a/source/engine/window.h b/source/engine/window.h index a08121e..ac1b730 100644 --- a/source/engine/window.h +++ b/source/engine/window.h @@ -38,7 +38,7 @@ void window_apply(window *w); void window_free(window *w); void window_setfullscreen(window *w, int f); -void window_set_icon(const char *png); +void set_icon(const char *png); void window_seticon(struct window *w, struct texture *icon); void window_render(struct window *w); diff --git a/source/engine/yugine.c b/source/engine/yugine.c index ad07492..7323107 100644 --- a/source/engine/yugine.c +++ b/source/engine/yugine.c @@ -25,15 +25,6 @@ #include #include - -#ifdef STEAM -#include "steamffi.h" -#endif - -#ifdef DISCORD -#include "discord.h" -#endif - #include "string.h" #include "render.h" @@ -61,19 +52,15 @@ static int sim_play = SIM_PLAY; static int argc; static char **args; -static JSValue c_init_fn; static JSValue c_process_fn; void c_init() { mainwin.start = 1; window_resize(sapp_width(), sapp_height()); - script_evalf("world_start();"); +// script_evalf("world_start();"); render_init(); - window_set_icon("icons/moon.gif"); + set_icon("icons/moon.gif"); particle_init(); - - if (!JS_IsUndefined(c_init_fn)) - script_call_sym(c_init_fn,0,NULL); } void c_frame() { script_call_sym(c_process_fn,0,NULL); } @@ -209,7 +196,6 @@ static sapp_desc start_desc = { int main(int argc, char **argv) { #ifndef NDEBUG log_init(); - signal(SIGSEGV, seghandle); signal(SIGABRT, seghandle); signal(SIGFPE, seghandle); @@ -244,9 +230,8 @@ int main(int argc, char **argv) { return 0; } -void engine_start(JSValue fn, JSValue procfn) +void engine_start(JSValue procfn) { - c_init_fn = fn; c_process_fn = procfn; sound_init(); diff --git a/source/engine/yugine.h b/source/engine/yugine.h index 4df9297..3aa0c85 100644 --- a/source/engine/yugine.h +++ b/source/engine/yugine.h @@ -5,7 +5,7 @@ double apptime(); void print_stacktrace(); -void engine_start(JSValue fn, JSValue proc_fn); /* fn runs after the engine starts */ +void engine_start(JSValue proc_fn); /* fn runs after the engine starts */ void quit();