level saving

This commit is contained in:
John Alanbrook 2023-10-09 23:10:10 +00:00
parent 23782f9fac
commit 661d29a01c
14 changed files with 143 additions and 86 deletions

View file

@ -69,16 +69,19 @@ Object.deepfreeze = function(obj)
/* Goes through each key and overwrites if it's present */ /* Goes through each key and overwrites if it's present */
Object.dainty_assign = function(target, source) Object.dainty_assign = function(target, source)
{ {
Object.keys(target).forEach(function(key) { Object.keys(source).forEach(function(key) {
if (!(key in source)) return; if (!(key in target)) return;
if (typeof source[key] === 'function') return;
if (typeof target[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]); 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]); Object.dainty_assign(target[key], source[key]);
else else {
Log.warn(`set key ${key}`);
target[key] = source[key]; target[key] = source[key];
}
}); });
} }

View file

@ -57,6 +57,7 @@ component.sprite = Object.copy(component, {
component.sprite.impl = { component.sprite.impl = {
set path(x) { set path(x) {
Log.warn(x);
cmd(12,this.id,prototypes.resani(this.gameobject.__proto__.toString(), x),this.rect); cmd(12,this.id,prototypes.resani(this.gameobject.__proto__.toString(), x),this.rect);
}, },
get path() { get path() {

View file

@ -87,6 +87,9 @@ function ediff(from,to)
{ {
var ret = {}; var ret = {};
if (!to)
return ediff(from,{});
Object.entries(from).forEach(function([key,v]) { Object.entries(from).forEach(function([key,v]) {
if (typeof v === 'function') return; if (typeof v === 'function') return;
if (typeof v === 'undefined') return; if (typeof v === 'undefined') return;
@ -120,6 +123,5 @@ function ediff(from,to)
ret[key] = v; ret[key] = v;
}); });
if (ret.empty) return undefined;
return ret; return ret;
} }

View file

@ -19,12 +19,14 @@ var configs = {
}; };
var editor = { var editor = {
dbg_ur: "arena.level1",
selectlist: [], selectlist: [],
grablist: [], grablist: [],
scalelist: [], scalelist: [],
rotlist: [], rotlist: [],
camera: undefined, camera: undefined,
edit_level: undefined, /* The current level that is being edited */ edit_level: undefined, /* The current level that is being edited */
desktop: undefined, /* The editor desktop, where all editing objects live */
working_layer: 0, working_layer: 0,
get cursor() { get cursor() {
if (this.selectlist.length === 0 ) return Mouse.worldpos; if (this.selectlist.length === 0 ) return Mouse.worldpos;
@ -192,16 +194,31 @@ var editor = {
mousejoy: undefined, mousejoy: undefined,
joystart: undefined, joystart: undefined,
stash: "", stash: undefined,
start_play_ed() { start_play_ed() {
// this.stash = this.edit_level.save(); this.stash = this.edit_level.level_obj();
// this.edit_level.kill(); this.edit_level.kill();
// load_configs("game.config"); // load_configs("game.config");
Game.play(); Game.play();
Player.players[0].uncontrol(this); Player.players[0].uncontrol(this);
Player.players[0].control(limited_editor); Player.players[0].control(limited_editor);
Register.unregister_obj(this); 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) { openpanel(panel, dontsteal) {
@ -350,10 +367,16 @@ var editor = {
} }
this.edit_level = Primum.spawn(ur.arena); 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; editor.edit_level._ed.selectable = false;
}, },
load_desktop(d) {
},
_sel_comp: undefined, _sel_comp: undefined,
get sel_comp() { return this._sel_comp; }, get sel_comp() { return this._sel_comp; },
set sel_comp(x) { 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.r.released = function() { editor.rotlist = []; }
editor.inputs['C-p'] = function() { editor.inputs.f5 = function()
if (!Game.playing()) { {
editor.start_play_ed(); 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.doc = "Start game from 'debug' if it exists; otherwise, from 'game'.";
editor.inputs['M-p'] = function() { editor.inputs['M-p'] = function() {
if (Game.playing()) if (Game.playing())
@ -1548,7 +1567,7 @@ replpanel.inputs.tab = function() {
}); });
if (keys.length > 1) if (keys.length > 1)
Log.say(keys.join(', ')); Log.console(keys.join(', '));
}; };
replpanel.inputs['C-p'] = function() replpanel.inputs['C-p'] = function()
{ {
@ -1971,29 +1990,22 @@ limited_editor.inputs['M-p'] = function()
limited_editor.inputs['C-q'] = function() limited_editor.inputs['C-q'] = function()
{ {
Game.stop();
Sound.killall(); Sound.killall();
Player.players[0].uncontrol(limited_editor); editor.enter_editor();
Player.players[0].control(editor);
Register.gui.register(editor.ed_gui, editor);
Debug.register_call(editor.ed_debug, editor);
Primum.clear_all(); Primum.clear_all();
editor.load_json(editor.stash); editor.load_json(editor.stash);
Game.view_camera(editor.camera); Game.view_camera(editor.camera);
} }
limited_editor.inputs['M-q'] = function()
{
editor.enter_editor();
}
/* This is used for editing during a paused game */ /* This is used for editing during a paused game */
var limited_editing = {}; var limited_editing = {};
limited_editing.inputs = {}; 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")) if (IO.exists("editor.config"))
load_configs("editor.config"); load_configs("editor.config");
@ -2003,5 +2015,6 @@ editor.camera = Game.camera;
Game.stop(); Game.stop();
Game.editor_mode(true); Game.editor_mode(true);
editor.enter_editor();
load("editorconfig.js"); load("editorconfig.js");

View file

@ -708,7 +708,7 @@ Register.update.register(Game.exec, Game);
load("scripts/entity.js"); load("scripts/entity.js");
var preprimum = {}; var preprimum = Object.create(gameobject);
preprimum.objects = {}; preprimum.objects = {};
preprimum.worldpos = function() { return [0,0]; }; preprimum.worldpos = function() { return [0,0]; };
preprimum.worldangle = function() { return 0; }; preprimum.worldangle = function() { return 0; };
@ -716,7 +716,7 @@ preprimum.scale = 1;
preprimum.gscale = function() { return 1; }; preprimum.gscale = function() { return 1; };
preprimum.pos = [0,0]; preprimum.pos = [0,0];
preprimum.angle = 0; preprimum.angle = 0;
var World = gameobject.make(preprimum); var World = preprimum.make(preprimum);
var Primum = World; var Primum = World;
Primum.level = undefined; Primum.level = undefined;
Primum.toString = function() { return "Primum"; }; Primum.toString = function() { return "Primum"; };

View file

@ -29,7 +29,7 @@ var gameobject = {
var pct = x/this.scale; var pct = x/this.scale;
cmd(36, this.body, x); cmd(36, this.body, x);
this.objects.forEach(function(obj) { this.objects?.forEach(function(obj) {
obj.scale *= pct; obj.scale *= pct;
obj.pos = obj.pos.scale(pct); obj.pos = obj.pos.scale(pct);
}); });
@ -234,6 +234,7 @@ var gameobject = {
velocity:[0,0], velocity:[0,0],
angularvelocity:0, angularvelocity:0,
layer:0, layer:0,
worldpos() { return [0,0]; },
save:true, save:true,
selectable:true, selectable:true,
@ -280,7 +281,25 @@ var gameobject = {
json_obj() { json_obj() {
var d = ediff(this,this.__proto__); 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.pos;
delete d.angle; delete d.angle;
delete d.velocity; delete d.velocity;
@ -295,28 +314,7 @@ var gameobject = {
}, },
level_obj() { level_obj() {
var json = this.json_obj(); return 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;
}, },
ur_obj() { ur_obj() {
@ -433,9 +431,9 @@ var gameobject = {
var newobj = obj.spawn(o.ur); var newobj = obj.spawn(o.ur);
if (!newobj) continue; if (!newobj) continue;
obj.rename_obj(newobj.toString(), prop); obj.rename_obj(newobj.toString(), prop);
Object.assign(newobj,o);
} }
} }
Object.dainty_assign(obj, this); Object.dainty_assign(obj, this);
obj.components.forEach(function(x) { if ('sync' in x) x.sync(); }); obj.components.forEach(function(x) { if ('sync' in x) x.sync(); });
@ -447,6 +445,16 @@ var gameobject = {
return obj; 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) { rename_obj(name, newname) {
if (!this.objects[name]) { if (!this.objects[name]) {
Log.warn(`No object with name ${name}. Could not rename to ${newname}.`); Log.warn(`No object with name ${name}. Could not rename to ${newname}.`);

View file

@ -9,6 +9,14 @@ function fcompile_env(file, env)
return compile_env(IO.slurp(file), env, file); return compile_env(IO.slurp(file), env, file);
} }
var OS = {
get cwd() { return cmd(144); },
};
OS.exec = function(s)
{
cmd(143, s);
}
var Log = { var Log = {
set level(x) { cmd(92,x); }, set level(x) { cmd(92,x); },
get level() { return cmd(93); }, get level() { return cmd(93); },
@ -62,6 +70,10 @@ var Log = {
Log.write('\n'); Log.write('\n');
}, },
console(msg) {
cmd(142, msg + '\n');
},
stack(skip = 0) { stack(skip = 0) {
var stack = (new Error()).stack; var stack = (new Error()).stack;
var n = stack.next('\n',0)+1; var n = stack.next('\n',0)+1;

View file

@ -28,12 +28,10 @@ FILE *logfile = NULL;
#define ERROR_BUFFER 1024 #define ERROR_BUFFER 1024
#define CONSOLE_BUF 1024*1024 /* 5MB */ #define CONSOLE_BUF 1024*1024 /* 5MB */
char *lastlog;
char *consolelog; char *consolelog;
void log_init() void log_init()
{ {
lastlog = malloc(ERROR_BUFFER+1);
consolelog = malloc(CONSOLE_BUF+1); consolelog = malloc(CONSOLE_BUF+1);
} }
@ -77,8 +75,11 @@ void log_print(const char *str)
fprintf(logfile, "%s", str); fprintf(logfile, "%s", str);
fflush(logfile); fflush(logfile);
} }
}
snprintf(lastlog, ERROR_BUFFER, "%s", str); void console_print(const char *str)
{
strncat(consolelog, str, CONSOLE_BUF);
} }
void log_setfile(char *file) { void log_setfile(char *file) {

View file

@ -13,7 +13,6 @@
#define LOG_SCRIPT 1 #define LOG_SCRIPT 1
#define LOG_RENDER 2 #define LOG_RENDER 2
extern char *lastlog;
extern char *consolelog; extern char *consolelog;
extern int logLevel; 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_setfile(char *file);
void log_cat(FILE *f); void log_cat(FILE *f);
void log_print(const char *str); void log_print(const char *str);
void console_print(const char *str);
#endif #endif

View file

@ -1063,6 +1063,20 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
case 141: case 141:
text_flush(&hudproj); text_flush(&hudproj);
break; 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) if (str)

View file

@ -180,22 +180,25 @@ struct sFont *MakeFont(const char *fontfile, int height) {
static int curchar = 0; 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) 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; cpVect wh;
color.a = 30;
wh.x = 8 * scale; wh.x = c.Size[0] * scale + 2;
wh.y = 14; wh.y = c.Size[1] * scale + 2;
cursor.X += wh.x / 2.f; cursor.X += c.Bearing[0] * scale + 1;
cursor.Y += wh.y / 2.f; cursor.Y -= (c.Bearing[1] * scale + 1);
cpVect b; cpVect b;
b.x = cursor.X; b.x = cursor.X + wh.x/2;
b.y = cursor.Y; b.y = cursor.Y + wh.y/2;
color.a = 30;
draw_box(b, wh, color); 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) if (curchar+1 >= max_chars)
return; return;
struct rgba colorbox = {0,0,0,255};
struct text_vert vert; struct text_vert vert;
float lsize = 1.0 / 1024.0; 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; struct rgba d;
if (!color) color = &d; if (!color) color = &d;
if (*c != '\e') c; if (*c != '\e') return c;
c++; c++;
if (*c != '[') return c; if (*c != '[') return c;
c++; c++;
@ -273,7 +278,6 @@ unsigned char *esc_color(unsigned char *c, struct rgba *color, struct rgba defc)
return c; return c;
} }
struct boundingbox text_bb(const unsigned char *text, float scale, float lw, float tracking) struct boundingbox text_bb(const unsigned char *text, float scale, float lw, float tracking)
{ {
struct rgba dummy; 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) void check_caret(int caret, int l, HMM_Vec2 pos, float scale, struct rgba color)
{ {
if (caret == l) if (caret == l)
draw_char_box(font->Characters[0], pos, scale, color); draw_underline_cursor(pos,scale,color);
} }

View file

@ -30,8 +30,6 @@ char *PREF_PATH = NULL;
char **prefabs; char **prefabs;
int stemlen = 0;
static const char *cur_ext = NULL; static const char *cur_ext = NULL;
struct dirent *c_dirent = NULL; struct dirent *c_dirent = NULL;
@ -42,6 +40,8 @@ const char *DB_NAME = "test.db";
static struct cdb corecdb; static struct cdb corecdb;
static struct cdb game_cdb; static struct cdb game_cdb;
void resources_init() { void resources_init() {
DATA_PATH = malloc(MAXPATH); DATA_PATH = malloc(MAXPATH);
getcwd(DATA_PATH, MAXPATH); getcwd(DATA_PATH, MAXPATH);

View file

@ -3,7 +3,7 @@
#include <stdio.h> #include <stdio.h>
extern int stemlen; extern char *DATA_PATH;
void resources_init(); void resources_init();
void fill_extensions(char *paths, const char *path, const char *ext); void fill_extensions(char *paths, const char *path, const char *ext);

View file

@ -51,7 +51,6 @@ void main()
} }
} }
} }
discard; discard;
} }