From 661d29a01c56c38de9d64b003d9ac5c1f566bc57 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Mon, 9 Oct 2023 23:10:10 +0000 Subject: [PATCH] level saving --- scripts/base.js | 13 ++++--- scripts/components.js | 1 + scripts/diff.js | 4 +- scripts/editor.js | 77 +++++++++++++++++++++++---------------- scripts/engine.js | 4 +- scripts/entity.js | 58 ++++++++++++++++------------- scripts/std.js | 12 ++++++ source/engine/debug/log.c | 7 ++-- source/engine/debug/log.h | 2 +- source/engine/ffi.c | 14 +++++++ source/engine/font.c | 30 ++++++++------- source/engine/resources.c | 4 +- source/engine/resources.h | 2 +- source/shaders/text.sglsl | 1 - 14 files changed, 143 insertions(+), 86 deletions(-) diff --git a/scripts/base.js b/scripts/base.js index 9e061e6..12e7989 100644 --- a/scripts/base.js +++ b/scripts/base.js @@ -69,16 +69,19 @@ Object.deepfreeze = function(obj) /* Goes through each key and overwrites if it's present */ Object.dainty_assign = function(target, source) { - Object.keys(target).forEach(function(key) { - if (!(key in source)) return; + Object.keys(source).forEach(function(key) { + if (!(key in target)) return; + if (typeof source[key] === 'function') return; if (typeof target[key] === 'function') return; - if (Array.isArray(target[key])) + if (Array.isArray(source[key])) target[key] = deep_copy(source[key]); - else if (typeof target[key] === 'object') + else if (typeof source[key] === 'object') Object.dainty_assign(target[key], source[key]); - else + else { + Log.warn(`set key ${key}`); target[key] = source[key]; + } }); } diff --git a/scripts/components.js b/scripts/components.js index 2d37882..69e9643 100644 --- a/scripts/components.js +++ b/scripts/components.js @@ -57,6 +57,7 @@ component.sprite = Object.copy(component, { component.sprite.impl = { set path(x) { + Log.warn(x); cmd(12,this.id,prototypes.resani(this.gameobject.__proto__.toString(), x),this.rect); }, get path() { diff --git a/scripts/diff.js b/scripts/diff.js index fffb3aa..d37b7ca 100644 --- a/scripts/diff.js +++ b/scripts/diff.js @@ -87,6 +87,9 @@ function ediff(from,to) { var ret = {}; + if (!to) + return ediff(from,{}); + Object.entries(from).forEach(function([key,v]) { if (typeof v === 'function') return; if (typeof v === 'undefined') return; @@ -120,6 +123,5 @@ function ediff(from,to) ret[key] = v; }); - if (ret.empty) return undefined; return ret; } diff --git a/scripts/editor.js b/scripts/editor.js index f018cd0..2a2a772 100644 --- a/scripts/editor.js +++ b/scripts/editor.js @@ -19,12 +19,14 @@ var configs = { }; var editor = { + dbg_ur: "arena.level1", selectlist: [], grablist: [], scalelist: [], rotlist: [], camera: undefined, edit_level: undefined, /* The current level that is being edited */ + desktop: undefined, /* The editor desktop, where all editing objects live */ working_layer: 0, get cursor() { if (this.selectlist.length === 0 ) return Mouse.worldpos; @@ -192,16 +194,31 @@ var editor = { mousejoy: undefined, joystart: undefined, - stash: "", + stash: undefined, start_play_ed() { -// this.stash = this.edit_level.save(); -// this.edit_level.kill(); + this.stash = this.edit_level.level_obj(); + this.edit_level.kill(); // load_configs("game.config"); - Game.play(); - Player.players[0].uncontrol(this); - Player.players[0].control(limited_editor); - Register.unregister_obj(this); + Game.play(); + Player.players[0].uncontrol(this); + Player.players[0].control(limited_editor); + Register.unregister_obj(this); + Primum.spawn(this.dbg_ur); + }, + + enter_editor() { + Game.pause(); + Player.players[0].control(this); + Player.players[0].uncontrol(limited_editor); + Register.gui.register(editor.ed_gui, editor); + Debug.register_call(editor.ed_debug, editor); + Register.update.register(gui_controls.update, gui_controls); + Player.players[0].control(gui_controls); + }, + + end_debug() { + }, openpanel(panel, dontsteal) { @@ -350,10 +367,16 @@ var editor = { } this.edit_level = Primum.spawn(ur.arena); -// this.edit_level.toString = function() { return "desktop"; }; + this.desktop = this.edit_level; + if (this.stash) + editor.edit_level._ed.selectable = false; }, + load_desktop(d) { + + }, + _sel_comp: undefined, get sel_comp() { return this._sel_comp; }, set sel_comp(x) { @@ -737,16 +760,12 @@ editor.inputs.r.doc = "Rotate selected using the mouse while held down."; editor.inputs.r.released = function() { editor.rotlist = []; } -editor.inputs['C-p'] = function() { - if (!Game.playing()) { - editor.start_play_ed(); -// if (!Level.loadlevel("debug")) - Primum.spawn(ur.start); - } else { - Game.pause(); - } -}; -editor.inputs['C-p'].doc = "Start game from 'debug' if it exists; otherwise, from 'game'."; +editor.inputs.f5 = function() +{ + editor.start_play_ed(); +} + +editor.inputs.f5.doc = "Start game from 'debug' if it exists; otherwise, from 'game'."; editor.inputs['M-p'] = function() { if (Game.playing()) @@ -1548,7 +1567,7 @@ replpanel.inputs.tab = function() { }); if (keys.length > 1) - Log.say(keys.join(', ')); + Log.console(keys.join(', ')); }; replpanel.inputs['C-p'] = function() { @@ -1971,29 +1990,22 @@ limited_editor.inputs['M-p'] = function() limited_editor.inputs['C-q'] = function() { - Game.stop(); Sound.killall(); - Player.players[0].uncontrol(limited_editor); - Player.players[0].control(editor); - Register.gui.register(editor.ed_gui, editor); - Debug.register_call(editor.ed_debug, editor); + editor.enter_editor(); Primum.clear_all(); editor.load_json(editor.stash); Game.view_camera(editor.camera); } +limited_editor.inputs['M-q'] = function() +{ + editor.enter_editor(); +} + /* This is used for editing during a paused game */ var limited_editing = {}; limited_editing.inputs = {}; -Player.players[0].control(editor); -Register.gui.register(editor.ed_gui, editor); -Debug.register_call(editor.ed_debug, editor); - -Register.update.register(gui_controls.update, gui_controls); -Player.players[0].control(gui_controls); - - if (IO.exists("editor.config")) load_configs("editor.config"); @@ -2003,5 +2015,6 @@ editor.camera = Game.camera; Game.stop(); Game.editor_mode(true); +editor.enter_editor(); load("editorconfig.js"); diff --git a/scripts/engine.js b/scripts/engine.js index 0ed2163..0434c25 100644 --- a/scripts/engine.js +++ b/scripts/engine.js @@ -708,7 +708,7 @@ Register.update.register(Game.exec, Game); load("scripts/entity.js"); -var preprimum = {}; +var preprimum = Object.create(gameobject); preprimum.objects = {}; preprimum.worldpos = function() { return [0,0]; }; preprimum.worldangle = function() { return 0; }; @@ -716,7 +716,7 @@ preprimum.scale = 1; preprimum.gscale = function() { return 1; }; preprimum.pos = [0,0]; preprimum.angle = 0; -var World = gameobject.make(preprimum); +var World = preprimum.make(preprimum); var Primum = World; Primum.level = undefined; Primum.toString = function() { return "Primum"; }; diff --git a/scripts/entity.js b/scripts/entity.js index b636563..bc34aef 100644 --- a/scripts/entity.js +++ b/scripts/entity.js @@ -29,7 +29,7 @@ var gameobject = { var pct = x/this.scale; cmd(36, this.body, x); - this.objects.forEach(function(obj) { + this.objects?.forEach(function(obj) { obj.scale *= pct; obj.pos = obj.pos.scale(pct); }); @@ -234,6 +234,7 @@ var gameobject = { velocity:[0,0], angularvelocity:0, layer:0, + worldpos() { return [0,0]; }, save:true, selectable:true, @@ -280,7 +281,25 @@ var gameobject = { json_obj() { var d = ediff(this,this.__proto__); - if (!d) return {}; + d ??= {}; + + var objects = {}; + this.__proto__.objects ??= {}; + if (!Object.keys(this.objects).equal(Object.keys(this.__proto__.objects))) { + for (var o in this.objects) { + objects[o] = this.objects[o].transform_obj(); + objects[o].ur = this.objects[o].ur.toString(); + } + } else { + for (var o in this.objects) { + var obj = ediff(this.objects[o].transform_obj(), + this.__proto__.objects[o]); + if (obj) objects[o] = obj; + } + } + if (!objects.empty) + d.objects = objects; + delete d.pos; delete d.angle; delete d.velocity; @@ -295,28 +314,7 @@ var gameobject = { }, level_obj() { - var json = this.json_obj(); - - var objects = {}; - this.__proto__.objects ??= {}; - if (!Object.keys(this.objects).equal(Object.keys(this.__proto__.objects))) { - for (var o in this.objects) { - objects[o] = this.objects[o].transform_obj(); - objects[o].ur = this.objects[o].ur.toString(); - } - } else { - for (var o in this.objects) { - var obj = this.objects[o].json_obj(); - Object.assign(obj, ediff(this.objects[o].transform(), this.__proto__.objects[o])); - if (!obj.empty) - objects[o] = obj; - } - } - - if (!objects.empty) - json.objects = objects; - - return json; + return this.json_obj(); }, ur_obj() { @@ -433,9 +431,9 @@ var gameobject = { var newobj = obj.spawn(o.ur); if (!newobj) continue; obj.rename_obj(newobj.toString(), prop); - Object.assign(newobj,o); } } + Object.dainty_assign(obj, this); obj.components.forEach(function(x) { if ('sync' in x) x.sync(); }); @@ -447,6 +445,16 @@ var gameobject = { return obj; }, + make_objs(objs) { + for (var prop in objs) { + var o = objs[prop]; + var newobj = this.spawn(o.ur); + if (!newobj) continue; + this.rename_obj(newobj.toString(), prop); + Object.assign(newobj,o); + } + }, + rename_obj(name, newname) { if (!this.objects[name]) { Log.warn(`No object with name ${name}. Could not rename to ${newname}.`); diff --git a/scripts/std.js b/scripts/std.js index 9d019db..c5ab1c9 100644 --- a/scripts/std.js +++ b/scripts/std.js @@ -9,6 +9,14 @@ function fcompile_env(file, env) return compile_env(IO.slurp(file), env, file); } +var OS = { + get cwd() { return cmd(144); }, +}; +OS.exec = function(s) +{ + cmd(143, s); +} + var Log = { set level(x) { cmd(92,x); }, get level() { return cmd(93); }, @@ -62,6 +70,10 @@ var Log = { Log.write('\n'); }, + console(msg) { + cmd(142, msg + '\n'); + }, + stack(skip = 0) { var stack = (new Error()).stack; var n = stack.next('\n',0)+1; diff --git a/source/engine/debug/log.c b/source/engine/debug/log.c index 87d355d..d13e38a 100644 --- a/source/engine/debug/log.c +++ b/source/engine/debug/log.c @@ -28,12 +28,10 @@ FILE *logfile = NULL; #define ERROR_BUFFER 1024 #define CONSOLE_BUF 1024*1024 /* 5MB */ -char *lastlog; char *consolelog; void log_init() { - lastlog = malloc(ERROR_BUFFER+1); consolelog = malloc(CONSOLE_BUF+1); } @@ -77,8 +75,11 @@ void log_print(const char *str) fprintf(logfile, "%s", str); fflush(logfile); } +} - snprintf(lastlog, ERROR_BUFFER, "%s", str); +void console_print(const char *str) +{ + strncat(consolelog, str, CONSOLE_BUF); } void log_setfile(char *file) { diff --git a/source/engine/debug/log.h b/source/engine/debug/log.h index 6c73dd4..3b12fde 100644 --- a/source/engine/debug/log.h +++ b/source/engine/debug/log.h @@ -13,7 +13,6 @@ #define LOG_SCRIPT 1 #define LOG_RENDER 2 -extern char *lastlog; extern char *consolelog; extern int logLevel; @@ -39,5 +38,6 @@ void sg_logging(const char *tag, uint32_t lvl, uint32_t id, const char *msg, uin void log_setfile(char *file); void log_cat(FILE *f); void log_print(const char *str); +void console_print(const char *str); #endif diff --git a/source/engine/ffi.c b/source/engine/ffi.c index ec90d7b..b998851 100644 --- a/source/engine/ffi.c +++ b/source/engine/ffi.c @@ -1063,6 +1063,20 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) case 141: text_flush(&hudproj); break; + + case 142: + str = JS_ToCString(js, argv[1]); + console_print(str); + break; + + case 143: + str = JS_ToCString(js, argv[1]); + system(str); + break; + + case 144: + ret = str2js(DATA_PATH); + break; } if (str) diff --git a/source/engine/font.c b/source/engine/font.c index b5c1a7c..4427331 100644 --- a/source/engine/font.c +++ b/source/engine/font.c @@ -180,22 +180,25 @@ struct sFont *MakeFont(const char *fontfile, int height) { static int curchar = 0; +void draw_underline_cursor(HMM_Vec2 pos, float scale, struct rgba color) +{ + pos.Y -= 2; + sdrawCharacter(font->Characters['_'], pos, scale, color); +} + void draw_char_box(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color) { - cursor.Y -= 2; - sdrawCharacter(font->Characters['_'], cursor, scale, color); - return; cpVect wh; + color.a = 30; - wh.x = 8 * scale; - wh.y = 14; - cursor.X += wh.x / 2.f; - cursor.Y += wh.y / 2.f; + wh.x = c.Size[0] * scale + 2; + wh.y = c.Size[1] * scale + 2; + cursor.X += c.Bearing[0] * scale + 1; + cursor.Y -= (c.Bearing[1] * scale + 1); cpVect b; - b.x = cursor.X; - b.y = cursor.Y; - color.a = 30; + b.x = cursor.X + wh.x/2; + b.y = cursor.Y + wh.y/2; draw_box(b, wh, color); } @@ -219,6 +222,8 @@ void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgb if (curchar+1 >= max_chars) return; + struct rgba colorbox = {0,0,0,255}; + struct text_vert vert; float lsize = 1.0 / 1024.0; @@ -250,7 +255,7 @@ unsigned char *esc_color(unsigned char *c, struct rgba *color, struct rgba defc) { struct rgba d; if (!color) color = &d; - if (*c != '\e') c; + if (*c != '\e') return c; c++; if (*c != '[') return c; c++; @@ -273,7 +278,6 @@ unsigned char *esc_color(unsigned char *c, struct rgba *color, struct rgba defc) return c; } - struct boundingbox text_bb(const unsigned char *text, float scale, float lw, float tracking) { struct rgba dummy; @@ -323,7 +327,7 @@ struct boundingbox text_bb(const unsigned char *text, float scale, float lw, flo void check_caret(int caret, int l, HMM_Vec2 pos, float scale, struct rgba color) { if (caret == l) - draw_char_box(font->Characters[0], pos, scale, color); + draw_underline_cursor(pos,scale,color); } diff --git a/source/engine/resources.c b/source/engine/resources.c index 82d36bd..0d30c9f 100644 --- a/source/engine/resources.c +++ b/source/engine/resources.c @@ -30,8 +30,6 @@ char *PREF_PATH = NULL; char **prefabs; -int stemlen = 0; - static const char *cur_ext = NULL; struct dirent *c_dirent = NULL; @@ -42,6 +40,8 @@ const char *DB_NAME = "test.db"; static struct cdb corecdb; static struct cdb game_cdb; + + void resources_init() { DATA_PATH = malloc(MAXPATH); getcwd(DATA_PATH, MAXPATH); diff --git a/source/engine/resources.h b/source/engine/resources.h index 1898710..e1ea8be 100644 --- a/source/engine/resources.h +++ b/source/engine/resources.h @@ -3,7 +3,7 @@ #include -extern int stemlen; +extern char *DATA_PATH; void resources_init(); void fill_extensions(char *paths, const char *path, const char *ext); diff --git a/source/shaders/text.sglsl b/source/shaders/text.sglsl index 06ed8b3..2b00463 100644 --- a/source/shaders/text.sglsl +++ b/source/shaders/text.sglsl @@ -51,7 +51,6 @@ void main() } } } - discard; }