2024-02-25 17:31:48 -06:00
|
|
|
os.cwd.doc = "Get the absolute path of the current working directory.";
|
|
|
|
os.env.doc = "Return the value of the environment variable v.";
|
2023-10-09 18:10:10 -05:00
|
|
|
|
2023-12-20 09:19:04 -06:00
|
|
|
var Resources = {};
|
|
|
|
Resources.images = ["png", "jpg", "jpeg", "gif"];
|
|
|
|
Resources.sounds = ["wav", "mp3", "flac"];
|
|
|
|
Resources.scripts = "js";
|
|
|
|
Resources.is_image = function(path) {
|
|
|
|
var ext = path.ext();
|
|
|
|
return Resources.images.any(x => x === ext);
|
|
|
|
}
|
2024-02-23 16:05:30 -06:00
|
|
|
|
2023-12-20 09:19:04 -06:00
|
|
|
Resources.is_sound = function(path) {
|
|
|
|
var ext = path.ext();
|
|
|
|
return Resources.sounds.any(x => x === ext);
|
|
|
|
}
|
|
|
|
|
2023-12-27 17:28:10 -06:00
|
|
|
Resources.is_animation = function(path)
|
|
|
|
{
|
|
|
|
if (path.ext() === 'gif' && Resources.gif.frames(path) > 1) return true;
|
2024-01-01 14:48:58 -06:00
|
|
|
if (path.ext() === 'ase') return true;
|
|
|
|
|
|
|
|
return false;
|
2023-12-27 17:28:10 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
Resources.texture = {};
|
|
|
|
Resources.texture.dimensions = function(path) { return cmd(64,path); }
|
|
|
|
|
|
|
|
Resources.gif = {};
|
|
|
|
Resources.gif.frames = function(path) { return cmd(139,path); }
|
|
|
|
|
2024-02-25 17:31:48 -06:00
|
|
|
Resources.replstrs = function(path)
|
|
|
|
{
|
|
|
|
var script = io.slurp(path);
|
|
|
|
var regexp = /"[^"\s]*?\.[^"\s]+?"/g;
|
|
|
|
var stem = path.dir();
|
|
|
|
|
|
|
|
script = script.replace(regexp,function(str) {
|
|
|
|
if (str[1] === "/")
|
|
|
|
return str.rm(1);
|
|
|
|
|
|
|
|
if (str[1] === "@")
|
|
|
|
return str.rm(1).splice(1, "playerpath/");
|
|
|
|
|
|
|
|
return str.splice(1, stem + "/");
|
|
|
|
});
|
|
|
|
|
|
|
|
return script;
|
|
|
|
}
|
|
|
|
|
|
|
|
var console = {
|
2023-09-07 16:46:35 -05:00
|
|
|
set level(x) { cmd(92,x); },
|
|
|
|
get level() { return cmd(93); },
|
|
|
|
print(msg, lvl) {
|
|
|
|
var lg;
|
|
|
|
if (typeof msg === 'object') {
|
|
|
|
lg = JSON.stringify(msg, null, 2);
|
|
|
|
} else {
|
|
|
|
lg = msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
var stack = (new Error()).stack;
|
|
|
|
var n = stack.next('\n',0)+1;
|
|
|
|
n = stack.next('\n', n)+1;
|
|
|
|
var nnn = stack.slice(n);
|
|
|
|
var fmatch = nnn.match(/\(.*\:/);
|
|
|
|
var file = fmatch ? fmatch[0].shift(1).shift(-1) : "nofile";
|
|
|
|
var lmatch = nnn.match(/\:\d*\)/);
|
|
|
|
var line = lmatch ? lmatch[0].shift(1).shift(-1) : "0";
|
|
|
|
|
2023-09-27 09:37:20 -05:00
|
|
|
yughlog(lvl, lg, file, line);
|
2023-09-07 16:46:35 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
info(msg) {
|
|
|
|
this.print(msg, 0);
|
|
|
|
},
|
|
|
|
|
|
|
|
warn(msg) {
|
|
|
|
this.print(msg, 1);
|
|
|
|
},
|
|
|
|
|
|
|
|
error(msg) {
|
|
|
|
this.print(msg, 2);
|
|
|
|
this.stack(1);
|
|
|
|
},
|
|
|
|
|
|
|
|
critical(msg) {
|
|
|
|
this.print(msg,3);
|
|
|
|
this.stack(1);
|
|
|
|
},
|
|
|
|
|
|
|
|
write(msg) {
|
2023-09-27 12:36:32 -05:00
|
|
|
if (typeof msg === 'object')
|
|
|
|
msg = JSON.stringify(msg,null,2);
|
|
|
|
|
2023-09-07 16:46:35 -05:00
|
|
|
cmd(91,msg);
|
|
|
|
},
|
|
|
|
|
2024-02-25 17:31:48 -06:00
|
|
|
log(msg) { console.say(time.text(time.now(), 'yyyy-m-dd hh:nn:ss') + " " + str); },
|
|
|
|
say(msg) { console.write(msg + '\n'); },
|
2024-02-23 16:05:30 -06:00
|
|
|
repl(msg) { cmd(142, msg + '\n'); },
|
2023-10-09 18:10:10 -05:00
|
|
|
|
2023-09-07 16:46:35 -05:00
|
|
|
stack(skip = 0) {
|
2023-12-22 07:14:44 -06:00
|
|
|
var err = new Error();
|
|
|
|
var stack = err.stack;
|
2023-09-07 16:46:35 -05:00
|
|
|
var n = stack.next('\n',0)+1;
|
|
|
|
for (var i = 0; i < skip; i++)
|
|
|
|
n = stack.next('\n', n)+1;
|
2024-02-25 17:31:48 -06:00
|
|
|
console.write(err.name);
|
|
|
|
console.write(err.message);
|
|
|
|
console.write(err.stack);
|
|
|
|
// console.write(stack);
|
2023-09-07 16:46:35 -05:00
|
|
|
},
|
2023-10-23 08:08:11 -05:00
|
|
|
|
|
|
|
clear() {
|
|
|
|
cmd(146);
|
|
|
|
},
|
2024-02-25 17:31:48 -06:00
|
|
|
|
|
|
|
assert(assertion, msg, obj) {
|
|
|
|
if (!assertion) {
|
|
|
|
console.error(msg);
|
|
|
|
console.stack();
|
|
|
|
}
|
|
|
|
},
|
2023-10-23 08:08:11 -05:00
|
|
|
};
|
|
|
|
|
2024-02-25 17:31:48 -06:00
|
|
|
var say = function(msg) {
|
|
|
|
console.say(msg);
|
|
|
|
}
|
|
|
|
say.doc = "Print to std out with an appended newline.";
|
|
|
|
|
|
|
|
console.doc = {
|
2023-10-23 08:08:11 -05:00
|
|
|
level: "Set level to output logging to console.",
|
|
|
|
info: "Output info level message.",
|
|
|
|
warn: "Output warn level message.",
|
|
|
|
error: "Output error level message, and print stacktrace.",
|
|
|
|
critical: "Output critical level message, and exit game immediately.",
|
|
|
|
write: "Write raw text to console.",
|
|
|
|
say: "Write raw text to console, plus a newline.",
|
|
|
|
stack: "Output a stacktrace to console.",
|
|
|
|
console: "Output directly to in game console.",
|
|
|
|
clear: "Clear console."
|
2023-09-07 16:46:35 -05:00
|
|
|
};
|
|
|
|
|
2023-11-17 15:16:13 -06:00
|
|
|
/*
|
2024-02-25 17:31:48 -06:00
|
|
|
io path rules. Starts with, meaning:
|
2024-02-27 10:09:15 -06:00
|
|
|
"@": user path
|
|
|
|
"/": game path
|
2023-11-17 15:16:13 -06:00
|
|
|
*/
|
|
|
|
|
2024-02-27 10:09:15 -06:00
|
|
|
io.mixin({
|
2023-09-13 01:08:32 -05:00
|
|
|
extensions(ext) {
|
2024-02-25 17:31:48 -06:00
|
|
|
var paths = io.ls();
|
2023-09-13 01:08:32 -05:00
|
|
|
paths = paths.filter(function(str) { return str.ext() === ext; });
|
|
|
|
return paths;
|
|
|
|
},
|
2024-02-23 16:05:30 -06:00
|
|
|
compile(script) {
|
|
|
|
return cmd(260, script);
|
|
|
|
},
|
|
|
|
run_bytecode(byte_file) {
|
|
|
|
return cmd(261, byte_file);
|
|
|
|
},
|
2024-02-27 10:09:15 -06:00
|
|
|
|
2023-09-13 01:08:32 -05:00
|
|
|
glob(pat) {
|
2024-02-25 17:31:48 -06:00
|
|
|
var paths = io.ls();
|
2023-09-13 01:08:32 -05:00
|
|
|
pat = pat.replaceAll(/([\[\]\(\)\^\$\.\|\+])/g, "\\$1");
|
|
|
|
pat = pat.replaceAll('**', '.*');
|
|
|
|
pat = pat.replaceAll(/[^\.]\*/g, '[^\\/]*');
|
|
|
|
pat = pat.replaceAll('?', '.');
|
|
|
|
|
|
|
|
var regex = new RegExp("^"+pat+"$", "");
|
|
|
|
return paths.filter(str => str.match(regex));
|
|
|
|
},
|
2024-02-27 10:09:15 -06:00
|
|
|
});
|
2023-09-07 16:46:35 -05:00
|
|
|
|
2024-02-25 17:31:48 -06:00
|
|
|
io.doc = {
|
2023-10-23 08:08:11 -05:00
|
|
|
doc: "Functions for filesystem input/output commands.",
|
|
|
|
exists: "Returns true if a file exists.",
|
|
|
|
slurp: "Returns the contents of given file as a string.",
|
2024-02-23 16:05:30 -06:00
|
|
|
slurpbytes: "Return the contents of a file as a byte array.",
|
2023-10-23 08:08:11 -05:00
|
|
|
slurpwrite: "Write a given string to a given file.",
|
2024-02-23 16:05:30 -06:00
|
|
|
cp: "Copy file f1 to f2.",
|
|
|
|
mv: "Rename file f1 to f2.",
|
|
|
|
rm: "Remove file f.",
|
|
|
|
mkdir: "Make dir.",
|
2023-10-23 08:08:11 -05:00
|
|
|
ls: "List contents of the game directory.",
|
|
|
|
glob: "Glob files in game directory.",
|
|
|
|
};
|
|
|
|
|
2023-09-07 16:46:35 -05:00
|
|
|
var Cmdline = {};
|
|
|
|
|
|
|
|
Cmdline.cmds = [];
|
2024-02-23 16:05:30 -06:00
|
|
|
Cmdline.orders = {};
|
2023-09-07 16:46:35 -05:00
|
|
|
Cmdline.register_cmd = function(flag, fn, doc) {
|
|
|
|
Cmdline.cmds.push({
|
|
|
|
flag: flag,
|
|
|
|
fn: fn,
|
|
|
|
doc: doc
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2024-02-23 16:05:30 -06:00
|
|
|
Cmdline.register_order = function(order, fn, doc, usage) {
|
|
|
|
Cmdline.orders[order] = fn;
|
|
|
|
fn.doc = doc;
|
|
|
|
usage ??= "";
|
|
|
|
fn.usage = `${order} ${usage}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
Cmdline.register_order("edit", function() {
|
2024-02-25 17:31:48 -06:00
|
|
|
if (!io.exists(".prosperon")) {
|
|
|
|
say("No game to edit. Try making one with 'prosperon init'.");
|
|
|
|
return;
|
2024-02-23 16:05:30 -06:00
|
|
|
}
|
2024-02-25 17:31:48 -06:00
|
|
|
|
2024-02-23 16:05:30 -06:00
|
|
|
Game.engine_start(function() {
|
2024-02-27 10:09:15 -06:00
|
|
|
global.mixin(use("scripts/editor.js"));
|
|
|
|
use("editorconfig.js");
|
2024-02-23 16:05:30 -06:00
|
|
|
editor.enter_editor();
|
|
|
|
});
|
|
|
|
}, "Edit the project in this folder. Give it the name of an UR to edit that specific object.", "?UR?");
|
|
|
|
|
2024-02-25 17:31:48 -06:00
|
|
|
Cmdline.register_order("init", function() {
|
|
|
|
if (io.exists(".prosperon")) {
|
|
|
|
say("Already a game here.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(io.ls().length === 0)) {
|
|
|
|
say("Directory is not empty. Make an empty one and init there.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
io.mkdir(".prosperon");
|
|
|
|
var project = {};
|
|
|
|
project.version = prosperon.version;
|
|
|
|
project.revision = prosperon.revision;
|
|
|
|
io.slurpwrite(".prosperon/project", json.encode(project));
|
|
|
|
|
|
|
|
}, "Turn the directory into a Prosperon game.");
|
|
|
|
|
2024-02-29 13:54:33 -06:00
|
|
|
Cmdline.register_order("debug", function() {
|
|
|
|
Cmdline.orders.play();
|
|
|
|
}, "Play the game with debugging enabled.");
|
|
|
|
|
2024-02-23 16:05:30 -06:00
|
|
|
Cmdline.register_order("play", function() {
|
2024-02-25 17:31:48 -06:00
|
|
|
if (!io.exists(".prosperon/project")) {
|
|
|
|
say("No game to play. Try making one with 'prosperon init'.");
|
|
|
|
return;
|
2024-02-23 16:05:30 -06:00
|
|
|
}
|
2024-02-25 17:31:48 -06:00
|
|
|
|
|
|
|
var project = json.decode(io.slurp(".prosperon/project"));
|
|
|
|
|
2024-02-23 16:05:30 -06:00
|
|
|
Game.engine_start(function() {
|
2024-02-29 13:54:33 -06:00
|
|
|
global.mixin("config.js");
|
|
|
|
global.mixin("game.js");
|
2024-02-25 17:31:48 -06:00
|
|
|
if (project.icon) Window.icon(project.icon);
|
|
|
|
if (project.title) Window.title(project.title);
|
2024-02-23 16:05:30 -06:00
|
|
|
});
|
|
|
|
}, "Play the game present in this folder.");
|
|
|
|
|
|
|
|
Cmdline.register_order("pack", function(str) {
|
|
|
|
var packname;
|
|
|
|
if (str.length === 0)
|
|
|
|
packname = "test.cdb";
|
|
|
|
else if (str.length > 1) {
|
2024-02-25 17:31:48 -06:00
|
|
|
console.warn("Give me a single filename for the pack.");
|
2024-02-23 16:05:30 -06:00
|
|
|
return;
|
|
|
|
} else
|
|
|
|
packname = str[0];
|
|
|
|
|
|
|
|
say(`Packing into ${packname}`);
|
|
|
|
|
|
|
|
cmd(124, packname);
|
|
|
|
}, "Pack the game into the given name.", "NAME");
|
|
|
|
|
|
|
|
Cmdline.register_order("unpack", function() {
|
|
|
|
say("Unpacking not implemented.");
|
|
|
|
}, "Unpack this binary's contents into this folder for editing.");
|
|
|
|
|
|
|
|
Cmdline.register_order("build", function() {
|
|
|
|
say("Building not implemented.");
|
|
|
|
}, "Build static assets for this project.");
|
|
|
|
|
|
|
|
Cmdline.register_order("api", function(obj) {
|
2024-02-25 17:31:48 -06:00
|
|
|
if (!obj[0]) {
|
2024-02-23 16:05:30 -06:00
|
|
|
Cmdline.print_order("api");
|
2024-02-25 17:31:48 -06:00
|
|
|
return;
|
|
|
|
}
|
2024-02-23 16:05:30 -06:00
|
|
|
|
|
|
|
load("scripts/editor.js");
|
2024-02-25 17:31:48 -06:00
|
|
|
var api = Debug.api.print_doc(obj[0]);
|
2024-02-23 16:05:30 -06:00
|
|
|
if (!api)
|
|
|
|
return;
|
|
|
|
|
|
|
|
say(api);
|
|
|
|
}, "Print the API for an object as markdown. Give it a file to save the output to.", "OBJECT");
|
|
|
|
|
|
|
|
Cmdline.register_order("compile", function(argv) {
|
|
|
|
for (var file of argv) {
|
2024-02-25 17:31:48 -06:00
|
|
|
var comp = io.compile(file);
|
|
|
|
io.slurpwrite(file + "c", comp);
|
2024-02-23 16:05:30 -06:00
|
|
|
}
|
|
|
|
}, "Compile one or more provided files into bytecode.", "FILE ...");
|
|
|
|
|
|
|
|
Cmdline.register_order("input", function(pawn) {
|
|
|
|
load("scripts/editor.js");
|
|
|
|
say(`## Input for ${pawn}`);
|
2024-02-25 17:31:48 -06:00
|
|
|
eval(`say(input.print_md_kbm(${pawn}));`);
|
2024-02-23 16:05:30 -06:00
|
|
|
}, "Print input documentation for a given object as markdown. Give it a file to save the output to", "OBJECT ?FILE?");
|
|
|
|
|
|
|
|
Cmdline.register_order("run", function(script) {
|
|
|
|
script = script.join(" ");
|
|
|
|
if (!script) {
|
|
|
|
say("Need something to run.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-02-25 17:31:48 -06:00
|
|
|
if (io.exists(script))
|
2024-02-23 16:05:30 -06:00
|
|
|
try {
|
2024-02-25 17:31:48 -06:00
|
|
|
if (script.endswith("c"))
|
2024-02-23 16:05:30 -06:00
|
|
|
cmd(261, script);
|
|
|
|
else
|
2024-02-25 17:31:48 -06:00
|
|
|
load(script);
|
2024-02-23 16:05:30 -06:00
|
|
|
} catch(e) { }
|
|
|
|
else {
|
|
|
|
var ret = eval(script);
|
|
|
|
if (ret) say(ret);
|
|
|
|
}
|
|
|
|
}, "Run a given script. SCRIPT can be the script itself, or a file containing the script", "SCRIPT");
|
|
|
|
|
2024-02-25 17:31:48 -06:00
|
|
|
Cmdline.orders.script = Cmdline.orders.run;
|
|
|
|
|
2024-02-23 16:05:30 -06:00
|
|
|
Cmdline.print_order = function(fn)
|
|
|
|
{
|
|
|
|
if (typeof fn === 'string')
|
|
|
|
fn = Cmdline.orders[fn];
|
|
|
|
|
|
|
|
if (!fn) return;
|
|
|
|
say(`Usage: prosperon ${fn.usage}`);
|
|
|
|
say(fn.doc);
|
|
|
|
}
|
|
|
|
|
|
|
|
Cmdline.register_order("help", function(order) {
|
|
|
|
|
|
|
|
if (!Object.empty(order)) {
|
|
|
|
var orfn = Cmdline.orders[order];
|
|
|
|
|
|
|
|
if (!orfn) {
|
|
|
|
console.warn(`No command named ${order}.`);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Cmdline.print_order(orfn);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Cmdline.print_order("help");
|
|
|
|
|
|
|
|
for (var cmd of Object.keys(Cmdline.orders).sort())
|
|
|
|
say(cmd);
|
|
|
|
|
|
|
|
Cmdline.orders.version();
|
|
|
|
}, "Give help with a specific command.", "TOPIC");
|
|
|
|
|
|
|
|
Cmdline.register_order("version", function() {
|
|
|
|
say(`Prosperon version ${prosperon.version} [${prosperon.revision}]`);
|
|
|
|
}, "Display Prosperon info.");
|
|
|
|
|
2023-09-07 16:46:35 -05:00
|
|
|
function cmd_args(cmdargs)
|
|
|
|
{
|
|
|
|
var play = false;
|
2024-02-23 16:05:30 -06:00
|
|
|
var cmds = cmdargs.split(/\s+/).slice(1);
|
|
|
|
|
|
|
|
if (cmds.length === 0)
|
|
|
|
cmds[0] = "play";
|
|
|
|
else if (!Cmdline.orders[cmds[0]]) {
|
|
|
|
console.warn(`Command ${cmds[0]} not found.`);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Cmdline.orders[cmds[0]](cmds.slice(1));
|
2023-09-07 16:46:35 -05:00
|
|
|
}
|
|
|
|
|
2024-02-25 17:31:48 -06:00
|
|
|
Cmdline.register_order("clean", function(argv) {
|
|
|
|
say("Cleaning not implemented.");
|
|
|
|
}, "Clean up a given object file.", "JSON ...");
|
2023-10-26 11:48:02 -05:00
|
|
|
|
2024-02-25 17:31:48 -06:00
|
|
|
Cmdline.register_cmd("l", function(n) {
|
|
|
|
console.level = n;
|
|
|
|
}, "Set log level.");
|
2024-02-27 10:09:15 -06:00
|
|
|
|
|
|
|
return {
|
|
|
|
console,
|
|
|
|
Resources,
|
|
|
|
say,
|
|
|
|
io,
|
|
|
|
Cmdline,
|
|
|
|
cmd_args
|
|
|
|
};
|