Windows now compiles with directx; separated out ur and entity methods
This commit is contained in:
parent
45a1b2dfb3
commit
a57aaeb5d5
12
Makefile
12
Makefile
|
@ -1,6 +1,6 @@
|
|||
MAKEFLAGS = --jobs=4
|
||||
UNAME != uname
|
||||
nMAKEDIR != pwd
|
||||
MAKEDIR != pwd
|
||||
|
||||
# Options
|
||||
# DBG --- build with debugging symbols and logging
|
||||
|
@ -71,7 +71,7 @@ ARCH = x64
|
|||
ifeq ($(OS), Windows_NT)
|
||||
LDFLAGS += -mwin32 -static
|
||||
CFLAGS += -mwin32
|
||||
LDLIBS += mingw32 kernel32 opengl32 user32 shell32 dxgi gdi32 ws2_32 ole32 winmm setupapi m
|
||||
LDLIBS += mingw32 kernel32 d3d11 user32 shell32 dxgi gdi32 ws2_32 ole32 winmm setupapi m
|
||||
EXT = .exe
|
||||
PLAT = w64
|
||||
PKGCMD = cd $(BIN); zip -q -r $(MAKEDIR)/$(DISTDIR)/$(DIST) . -x \*.a ./obj/\*
|
||||
|
@ -142,11 +142,12 @@ SHADERS = $(shell ls source/shaders/*.sglsl)
|
|||
SHADERS := $(patsubst %.sglsl, %.sglsl.h, $(SHADERS))
|
||||
|
||||
install: $(BIN)/$(NAME)
|
||||
cp $(BIN)/$(NAME) $(DESTDIR)
|
||||
cp -f $(BIN)/$(NAME) $(DESTDIR)
|
||||
|
||||
$(BIN)/$(NAME): $(BIN)/libengine.a $(BIN)/libquickjs.a $(BIN)/libcdb.a
|
||||
@echo Linking $(NAME)
|
||||
$(LD) $^ $(LDFLAGS) -L$(BIN) $(LDLIBS) -o $@
|
||||
cp $(BIN)/$(NAME) .
|
||||
@echo Finished build
|
||||
|
||||
$(DISTDIR)/$(DIST): $(BIN)/$(NAME)
|
||||
|
@ -207,6 +208,11 @@ jso: tools/jso.c $(BIN)/libquickjs.a
|
|||
@echo Making $@ from $<
|
||||
./jso $< > $@
|
||||
|
||||
WINCC = x86_64-w64-mingw32-gcc
|
||||
.PHONY: crosswin
|
||||
crosswin:
|
||||
make CC=$(WINCC) OS=Windows_NT
|
||||
|
||||
clean:
|
||||
@echo Cleaning project
|
||||
@rm -rf bin dist
|
||||
|
|
15
docs/game.md
15
docs/game.md
|
@ -42,7 +42,7 @@ In edit mode, there are no running scripts; only editing them.
|
|||
There are two distinct items in the Primum Machina: the Entity, and the Component. Components give qualities to Entities. An Entity is any real, tangible thing in the universe, and so every entity has a position. Components do not necessarily have a position; they can be things like the image that draws where the entity is located, and colliders that allow the entity to respond with the world.
|
||||
|
||||
### Components
|
||||
The most "bare metal" are the components. These are essentially hooks into the engine that tell it how to do particular things. For example, to render a sprite, Javascript does no rendering, but rather tells the engine to create an image and render it in a particular spot.
|
||||
The most "bare metal" are the components. These are essentially hooks into the engine that tell it how to do particular things. For example, to render a sprite, Javascript does no rendering, but rather tells the engine to create an image and render it in a particular spot. Javascript does the accounting to make or destroy the sprite as needed - but besides that initial startup, no scripting is done.
|
||||
|
||||
Components are rendered in an "ECS" style. To work, components must be installed on an entity. They have no meaning outside of a physical object in the world.
|
||||
|
||||
|
@ -62,7 +62,7 @@ All objects follow the prototyping model of inheritence. This makes it trivial t
|
|||
|
||||
Components cannot be prototyped. They are fundamentally tied to the entity they are bound to.
|
||||
|
||||
Entities can be prototyped out. What this means is that, when you select an object in the game, you can either make a "subtype" of it, where changes to the object trickle down to the created one, or a "sidetype" of it, which is a total duplicate of the object.
|
||||
Entities can be prototyped out. What this means is that, when you select an object in the game, you can either make a "subtype" of it, where changes to the object trickle down to the created one, or a "sidetype" of it, which is a total duplicate of the object. Javascript handled creating entites with components that have your saved values.
|
||||
|
||||
entity.clone(parent) -> create a subtyped version of the entity
|
||||
entity.dup(parent) -> create a copy of the entity.
|
||||
|
@ -79,6 +79,17 @@ Only first Ur-types can have components. Every inherited thing after it can only
|
|||
|
||||
Ur-types also remember the list of entities that compose the given Ur.
|
||||
|
||||
Visually it looks like this:
|
||||
|
||||
Ur-ur, the thing all Ur-types derive from
|
||||
- Ur-type 1, defined in script, with components
|
||||
- Variant 1, same component combination but different values
|
||||
- Variant 2, other different values
|
||||
- Variant 2A, overwritten values from Variant 2
|
||||
- Ur-type 2
|
||||
|
||||
All ur-types and variants can be created in the world, where they become a true blue ENTITY. Entities can be under entities infinitely.
|
||||
|
||||
### Loading traits
|
||||
Traits are defined by code and a data file. When an Ur-type is extended with a trait, the code is run, and then the data file contains modifications and
|
||||
|
||||
|
|
|
@ -24,6 +24,11 @@ Object.defineProperty(Object.prototype, 'getOwnPropertyDescriptors', {
|
|||
}
|
||||
});
|
||||
|
||||
Object.defHidden = function(obj, prop)
|
||||
{
|
||||
Object.defineProperty(obj, prop, {enumerable:false, writable:true});
|
||||
}
|
||||
|
||||
Object.defineProperty(Object.prototype, 'obscure', {
|
||||
value: function(name) {
|
||||
Object.defineProperty(this, name, { enumerable: false });
|
||||
|
|
|
@ -762,7 +762,15 @@ editor.inputs['C-d'] = function() {
|
|||
};
|
||||
editor.inputs['C-d'].doc = "Duplicate all selected objects.";
|
||||
|
||||
editor.inputs.f3 = function() { editor.selectlist.forEach(x => Log.say(JSON.stringify(x,null,2))); };
|
||||
editor.inputs.f3 = function() {
|
||||
Log.say("Selected JSON ...");
|
||||
editor.selectlist.forEach(x => Log.say(JSON.stringify(x,null,2)));
|
||||
Log.say("UR JSON ...");
|
||||
for (var key of Object.keys(editor.selectlist[0].ur.type))
|
||||
Log.say(key);
|
||||
|
||||
editor.selectlist.forEach(x => Log.say(JSON.stringify(x.ur.type,null,2)));
|
||||
};
|
||||
|
||||
editor.inputs['C-m'] = function() {
|
||||
if (editor.sel_comp) {
|
||||
|
@ -1922,3 +1930,4 @@ if (IO.exists("editor.config"))
|
|||
editor.clear_level();
|
||||
editor.camera = Game.camera;
|
||||
Game.stop();
|
||||
Game.editor_mode(false);
|
||||
|
|
|
@ -510,7 +510,7 @@ var Game = {
|
|||
sys_cmd(4);
|
||||
},
|
||||
|
||||
render() { sys_cmd(10); },
|
||||
editor_mode(m) { sys_cmd(10, m); },
|
||||
|
||||
playing() { return sys_cmd(5); },
|
||||
paused() { return sys_cmd(6); },
|
||||
|
@ -554,6 +554,13 @@ gameobject.make_parentable(Primum);
|
|||
Primum.tag = "PRIMUM";
|
||||
Primum.selectable = false;
|
||||
Primum.ur = { tag: "Primum" };
|
||||
Primum.spawn = function(ur) {
|
||||
if (typeof ur === 'string')
|
||||
ur = prototypes.get_ur(ur);
|
||||
|
||||
return ur.type.make(this);
|
||||
};
|
||||
|
||||
/* Reparent this object to a new one */
|
||||
World.reparent = function(parent) { Log.warn("Cannot reparent the Primum."); }
|
||||
World.unparent = function() { Log.warn("The Primum has no parent, always."); }
|
||||
|
|
|
@ -15,13 +15,7 @@ var gameobject = {
|
|||
save: true,
|
||||
selectable: true,
|
||||
|
||||
spawn(ur) {
|
||||
if (typeof ur === 'string')
|
||||
ur = prototypes.get_ur(ur);
|
||||
|
||||
return ur.type.make(this);
|
||||
},
|
||||
|
||||
/* Make a duplicate of this exact object */
|
||||
clone(name, ext) {
|
||||
var obj = Object.create(this);
|
||||
complete_assign(obj, ext);
|
||||
|
@ -113,37 +107,12 @@ var gameobject = {
|
|||
|
||||
gizmo: "", /* Path to an image to draw for this gameobject */
|
||||
|
||||
/* Bounding box of the object in world dimensions */
|
||||
/* Bounding box of the ur, if it were to be spawned */
|
||||
boundingbox() {
|
||||
var boxes = [];
|
||||
boxes.push({t:0, r:0,b:0,l:0});
|
||||
|
||||
for (var key in this.components) {
|
||||
if ('boundingbox' in this.components[key])
|
||||
boxes.push(this.components[key].boundingbox());
|
||||
}
|
||||
|
||||
if (boxes.empty) return cwh2bb([0,0], [0,0]);
|
||||
|
||||
var bb = boxes[0];
|
||||
|
||||
boxes.forEach(function(x) {
|
||||
bb = bb_expand(bb, x);
|
||||
});
|
||||
|
||||
var cwh = bb2cwh(bb);
|
||||
|
||||
if (!bb) return;
|
||||
|
||||
if (this.flipx) cwh.c.x *= -1;
|
||||
if (this.flipy) cwh.c.y *= -1;
|
||||
|
||||
cwh.c = cwh.c.add(this.pos);
|
||||
bb = cwh2bb(cwh.c, cwh.wh);
|
||||
|
||||
return bb ? bb : cwh2bb([0,0], [0,0]);
|
||||
},
|
||||
|
||||
|
||||
width() {
|
||||
var bb = this.boundingbox();
|
||||
return bb.r - bb.l;
|
||||
|
@ -204,7 +173,8 @@ var gameobject = {
|
|||
make(level) {
|
||||
level ??= Primum;
|
||||
var obj = Object.create(this);
|
||||
this.instances.push(obj);
|
||||
// this.instances.push(obj);
|
||||
// obj.ur = this;
|
||||
obj.toString = function() {
|
||||
if (obj.ur)
|
||||
return obj.ur.tag;
|
||||
|
@ -272,6 +242,45 @@ var gameobject = {
|
|||
sync() { },
|
||||
dirty() { return false; },
|
||||
|
||||
spawn(ur) {
|
||||
if (typeof ur === 'string')
|
||||
ur = prototypes.get_ur(ur);
|
||||
|
||||
return ur.type.make(this);
|
||||
},
|
||||
|
||||
|
||||
/* Bounding box of the object in world dimensions */
|
||||
boundingbox() {
|
||||
var boxes = [];
|
||||
boxes.push({t:0, r:0,b:0,l:0});
|
||||
|
||||
for (var key in this.components) {
|
||||
if ('boundingbox' in this.components[key])
|
||||
boxes.push(this.components[key].boundingbox());
|
||||
}
|
||||
|
||||
if (boxes.empty) return cwh2bb([0,0], [0,0]);
|
||||
|
||||
var bb = boxes[0];
|
||||
|
||||
boxes.forEach(function(x) {
|
||||
bb = bb_expand(bb, x);
|
||||
});
|
||||
|
||||
var cwh = bb2cwh(bb);
|
||||
|
||||
if (!bb) return;
|
||||
|
||||
if (this.flipx) cwh.c.x *= -1;
|
||||
if (this.flipy) cwh.c.y *= -1;
|
||||
|
||||
cwh.c = cwh.c.add(this.pos);
|
||||
bb = cwh2bb(cwh.c, cwh.wh);
|
||||
|
||||
return bb ? bb : cwh2bb([0,0], [0,0]);
|
||||
},
|
||||
|
||||
dup(diff) {
|
||||
var dup = Primum.spawn(this.ur);
|
||||
Object.assign(dup, this);
|
||||
|
@ -312,7 +321,9 @@ var gameobject = {
|
|||
down() { return [0,-1].rotate(Math.deg2rad(this.angle));},
|
||||
right() { return [1,0].rotate(Math.deg2rad(this.angle));},
|
||||
left() { return [-1,0].rotate(Math.deg2rad(this.angle));},
|
||||
|
||||
|
||||
/* Given an ur-type, spawn one attached to us */
|
||||
|
||||
toJSON() {
|
||||
var ret = {};
|
||||
for (var key in this) {
|
||||
|
@ -371,6 +382,7 @@ var gameobject = {
|
|||
|
||||
gameobject.make_parentable = function(obj) {
|
||||
var objects = [];
|
||||
Object.defHidden(obj, 'level');
|
||||
|
||||
obj.remove_child = function(child) {
|
||||
objects.remove(child);
|
||||
|
@ -434,19 +446,20 @@ prototypes.from_file = function(file)
|
|||
return;
|
||||
}
|
||||
|
||||
var newobj = gameobject.clone(file, {});
|
||||
var newur = gameobject.clone(file, {});
|
||||
var script = IO.slurp(file);
|
||||
|
||||
newobj.$ = {};
|
||||
Object.defHidden(newur, '$');
|
||||
newur.$ = {};
|
||||
var json = {};
|
||||
if (IO.exists(file.name() + ".json")) {
|
||||
json = JSON.parse(IO.slurp(file.name() + ".json"));
|
||||
Object.assign(newobj.$, json.$);
|
||||
Object.assign(newur.$, json.$);
|
||||
delete json.$;
|
||||
}
|
||||
|
||||
compile_env(`var self = this; var $ = self.$; ${script}`, newobj, file);
|
||||
dainty_assign(newobj, json);
|
||||
compile_env(`var self = this; var $ = self.$; ${script}`, newur, file);
|
||||
dainty_assign(newur, json);
|
||||
|
||||
file = file.replaceAll('/', '.');
|
||||
var path = file.name().split('.');
|
||||
|
@ -457,12 +470,13 @@ prototypes.from_file = function(file)
|
|||
return base;
|
||||
};
|
||||
var a = nested_access(ur, path);
|
||||
|
||||
Object.defHidden(a, 'instances');
|
||||
a.instances = [];
|
||||
a.tag = file.name();
|
||||
prototypes.list.push(a.tag);
|
||||
a.type = newobj;
|
||||
a.type = newur;
|
||||
a.instances = [];
|
||||
newobj.ur = a;
|
||||
// newur.ur = a;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
|
|
@ -1249,7 +1249,7 @@ JSValue duk_sys_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *ar
|
|||
break;
|
||||
|
||||
case 10:
|
||||
render_dirty = 1;
|
||||
editor_mode = js2bool(argv[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -430,15 +430,6 @@ void full_2d_pass(struct window *window)
|
|||
//////////// 2D projection
|
||||
cpVect pos = cam_pos();
|
||||
|
||||
#if defined SOKOL_GLCORE33 || defined SOKOL_GLES3
|
||||
projection = HMM_Orthographic_RH_ZO(
|
||||
pos.x - zoom * window->rwidth / 2,
|
||||
pos.x + zoom * window->rwidth / 2,
|
||||
pos.y + zoom * window->rheight / 2,
|
||||
pos.y - zoom * window->rheight / 2, -1.f, 1.f);
|
||||
|
||||
hudproj = HMM_Orthographic_RH_ZO(0, window->width, window->height, 0, -1.f, 1.f);
|
||||
#else
|
||||
projection = HMM_Orthographic_LH_ZO(
|
||||
pos.x - zoom * window->rwidth / 2,
|
||||
pos.x + zoom * window->rwidth / 2,
|
||||
|
@ -446,7 +437,6 @@ void full_2d_pass(struct window *window)
|
|||
pos.y + zoom * window->rheight / 2, -1.f, 1.f);
|
||||
|
||||
hudproj = HMM_Orthographic_LH_ZO(0, window->rwidth, 0, window->rheight, -1.f, 1.f);
|
||||
#endif
|
||||
|
||||
sprite_draw_all();
|
||||
call_draw();
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#elif __EMSCRIPTEN__
|
||||
#define SOKOL_GLES3
|
||||
#elif __WIN32
|
||||
#define SOKOL_GLCORE33
|
||||
#define SOKOL_D3D11
|
||||
#define SOKOL_WIN32_FORCE_MAIN
|
||||
#elif __APPLE__
|
||||
#define SOKOL_METAL
|
||||
|
|
|
@ -58,7 +58,6 @@ static struct d_prof prof_input;
|
|||
static struct d_prof prof_physics;
|
||||
|
||||
double physlag = 0;
|
||||
int render_dirty = 0;
|
||||
|
||||
double physMS = 1 / 60.f;
|
||||
|
||||
|
@ -74,6 +73,8 @@ static float timescale = 1.f;
|
|||
|
||||
static int sim_play = SIM_PLAY;
|
||||
|
||||
static int editor_mode = 0;
|
||||
|
||||
#ifdef __TINYC__
|
||||
int backtrace(void **buffer, int size) {
|
||||
extern uint64_t *__libc_stack_end;
|
||||
|
@ -168,25 +169,21 @@ static void process_frame()
|
|||
prof(&prof_physics);
|
||||
}
|
||||
|
||||
if (sim_play == SIM_STEP) {
|
||||
if (sim_play == SIM_STEP)
|
||||
sim_pause();
|
||||
render_dirty = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (sim_play == SIM_PLAY || render_dirty) {
|
||||
prof_start(&prof_draw);
|
||||
window_render(&mainwin);
|
||||
prof(&prof_draw);
|
||||
render_dirty = 0;
|
||||
}
|
||||
prof_start(&prof_draw);
|
||||
window_render(&mainwin);
|
||||
prof(&prof_draw);
|
||||
|
||||
|
||||
gameobjects_cleanup();
|
||||
}
|
||||
|
||||
void c_frame()
|
||||
{
|
||||
if (sim_play != SIM_PLAY) return;
|
||||
if (editor_mode) return;
|
||||
process_frame();
|
||||
}
|
||||
|
||||
|
@ -196,8 +193,6 @@ void c_clean() {
|
|||
|
||||
void c_event(const sapp_event *e)
|
||||
{
|
||||
render_dirty = 1;
|
||||
|
||||
#ifndef NO_EDITOR
|
||||
snk_handle_event(e);
|
||||
#endif
|
||||
|
@ -260,7 +255,7 @@ void c_event(const sapp_event *e)
|
|||
break;
|
||||
}
|
||||
|
||||
if (sim_play != SIM_PLAY)
|
||||
if (editor_mode)
|
||||
process_frame();
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,5 @@ extern double appTime;
|
|||
extern double renderMS;
|
||||
extern double physMS;
|
||||
extern double updateMS;
|
||||
extern int render_dirty;
|
||||
|
||||
extern int editor_mode;
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue