diff --git a/source/engine/font.c b/source/engine/font.c index e3e16c9..d296ce5 100644 --- a/source/engine/font.c +++ b/source/engine/font.c @@ -10,6 +10,8 @@ #include #include "log.h" +#include "openglrender.h" + #include static uint32_t VBO = 0; @@ -181,9 +183,11 @@ void renderText(const char *text, mfloat_t pos[2], float scale, mfloat_t color[3 shader_use(shader); shader_setvec3(shader, "textColor", color); + cpVect campos = cam_pos(); + mfloat_t cursor[2] = { 0.f }; - cursor[0] = pos[0]; - cursor[1] = pos[1]; + cursor[0] = pos[0] + campos.x; + cursor[1] = pos[1] + campos.y; glActiveTexture(GL_TEXTURE0); glBindVertexArray(VAO); diff --git a/source/engine/gameobject.c b/source/engine/gameobject.c index 60083ac..198eba4 100644 --- a/source/engine/gameobject.c +++ b/source/engine/gameobject.c @@ -44,8 +44,10 @@ static void gameobject_setpickcolor(struct gameobject *go) go->editor.color[2] = b; } -struct gameobject *MakeGameobject() +int MakeGameobject() { + if (gameobjects == NULL) arrsetcap(gameobjects, 100); + YughInfo("Making new gameobject"); struct gameobject go = { .editor.id = arrlen(gameobjects), @@ -62,7 +64,7 @@ struct gameobject *MakeGameobject() arrput(gameobjects, go); - return &arrlast(gameobjects); + return arrlen(gameobjects)-1; } void gameobject_addcomponent(struct gameobject *go, struct component *c) @@ -131,7 +133,7 @@ int gameobject_makefromprefab(char *path) return; } - struct gameobject *new = MakeGameobject(); + struct gameobject *new = get_gameobject_from_id(MakeGameobject()); fread(new, sizeof(*new), 1, fprefab); new->components = NULL; @@ -217,8 +219,8 @@ void toggleprefab(struct gameobject *go) void gameobject_move(struct gameobject *go, float xs, float ys) { cpVect p = cpBodyGetPosition(go->body); - p.x += xs * deltaT; - p.y += ys * deltaT; + p.x += xs; + p.y += ys; cpBodySetPosition(go->body, p); phys2d_reindex_body(go->body); @@ -325,4 +327,35 @@ void gameobject_draw_debugs() { if (c->draw_debug) c->draw_debug(c->data); } } -} \ No newline at end of file +} + + +static struct {struct gameobject go; cpVect pos; float angle; } *saveobjects = NULL; + +void gameobject_saveall() { + arrfree(saveobjects); + arrsetlen(saveobjects, arrlen(gameobjects)); + + for (int i = 0; i < arrlen(gameobjects); i++) { + saveobjects[i].go = gameobjects[i]; + saveobjects[i].pos = cpBodyGetPosition(gameobjects[i].body); + saveobjects[i].angle = cpBodyGetAngle(gameobjects[i].body); + } +} + +void gameobject_loadall() { + YughInfo("N gameobjects: %d, N saved: %d", arrlen(gameobjects), arrlen(saveobjects)); + for (int i = 0; i < arrlen(saveobjects); i++) { + gameobjects[i] = saveobjects[i].go; + cpBodySetPosition(gameobjects[i].body, saveobjects[i].pos); + cpBodySetAngle(gameobjects[i].body, saveobjects[i].angle); + cpBodySetVelocity(gameobjects[i].body, cpvzero); + cpBodySetAngularVelocity(gameobjects[i].body, 0.f); + } + + arrfree(saveobjects); +} + +int gameobjects_saved() { + return arrlen(saveobjects); +} diff --git a/source/engine/gameobject.h b/source/engine/gameobject.h index 375410f..5a131d2 100644 --- a/source/engine/gameobject.h +++ b/source/engine/gameobject.h @@ -43,7 +43,7 @@ struct gameobject { extern struct gameobject *gameobjects; -struct gameobject *MakeGameobject(); +int MakeGameobject(); void init_gameobjects(); void gameobject_delete(int id); void clear_gameobjects(); @@ -76,4 +76,8 @@ void gameobject_draw_debugs(); void object_gui(struct gameobject *go); +void gameobject_saveall(); +void gameobject_loadall(); +int gameobjects_saved(); + #endif diff --git a/source/engine/input.c b/source/engine/input.c index 75f1bbb..0083e0c 100644 --- a/source/engine/input.c +++ b/source/engine/input.c @@ -45,8 +45,6 @@ void input_init() { glfwSetCursorPosCallback(mainwin->window, cursor_pos_cb); glfwSetScrollCallback(mainwin->window, scroll_cb); - - } void call_input_signal(char *signal) { @@ -54,40 +52,15 @@ void call_input_signal(char *signal) { script_eval_w_env(signal, pawns[i]); } -void call_input_down(int *key) { - const char *keyname = glfwGetKeyName(*key, 0); - char keystr[50] = {'\0'}; - snprintf(keystr, 50, "input_%s_down", keyname); - call_input_signal(keystr); -} - -/* This is called once every frame - or more if we want it more! */ -void input_poll(double wait) -{ - ychange = 0; - xchange = 0; - mouseWheelX = 0; - mouseWheelY = 0; - - glfwWaitEventsTimeout(wait); - - - //editor_input(&e); - for (int i = 0; i < arrlen(downkeys); i++) - call_input_down(&downkeys[i]); -} - -void win_key_callback(GLFWwindow *w, int key, int scancode, int action, int mods) -{ - char keystr[50] = {'\0'}; - strcat(keystr, "input_"); +const char *keyname_extd(int key, int scancode) { + char keybuf[50]; const char *kkey = glfwGetKeyName(key, scancode); - if (!kkey) { - char keybuf[10]; - if (key > 289 && key < 302) { + if (kkey) return kkey; + + if (key > 289 && key < 302) { sprintf(keybuf, "f%d", key-289); - strcat(keystr, keybuf); + return keybuf; } else { switch(key) { case GLFW_KEY_ENTER: @@ -143,20 +116,43 @@ void win_key_callback(GLFWwindow *w, int key, int scancode, int action, int mods break; } - if (kkey) - strcat(keystr, kkey); - else - YughWarn("Could not get key string for key %d, scancode %d.", key, scancode); + if (kkey) return kkey; + } + return "NULL"; +} - } else { - strcat(keystr, kkey); - } +void call_input_down(int *key) { + char keystr[50] = {'\0'}; + snprintf(keystr, 50, "input_%s_down", keyname_extd(*key, 0)); + call_input_signal(keystr); +} + +/* This is called once every frame - or more if we want it more! */ +void input_poll(double wait) +{ + ychange = 0; + xchange = 0; + mouseWheelX = 0; + mouseWheelY = 0; + + glfwWaitEventsTimeout(wait); + + + //editor_input(&e); + for (int i = 0; i < arrlen(downkeys); i++) + call_input_down(&downkeys[i]); +} + +void win_key_callback(GLFWwindow *w, int key, int scancode, int action, int mods) +{ + char keystr[50] = {'\0'}; + const char *kkey = keyname_extd(key, scancode); switch (action) { case GLFW_PRESS: - strcat(keystr, "_pressed"); + snprintf(keystr, 50, "input_%s_pressed", kkey); int found = 0; @@ -170,7 +166,7 @@ void win_key_callback(GLFWwindow *w, int key, int scancode, int action, int mods break; case GLFW_RELEASE: - strcat(keystr, "_released"); + snprintf(keystr, 50, "input_%s_released", kkey); for (int i = 0; i < arrlen(downkeys); i++) { if (downkeys[i] == key) { @@ -182,7 +178,7 @@ void win_key_callback(GLFWwindow *w, int key, int scancode, int action, int mods break; case GLFW_REPEAT: - strcat(keystr, "_rep"); + snprintf(keystr, 50, "input_%s_rep", kkey); break; } diff --git a/source/engine/mrbffi.c b/source/engine/mrbffi.c index 7a69042..d51f63e 100644 --- a/source/engine/mrbffi.c +++ b/source/engine/mrbffi.c @@ -90,6 +90,14 @@ s7_pointer s7_settings_cmd(s7_scheme *sc, s7_pointer args) { case 3: debug_draw_phys(val); break; + + case 4: + set_timescale(val); + break; + + case 5: + add_zoom(val); + break; } return args; @@ -202,6 +210,9 @@ s7_pointer s7_sys_cmd(s7_scheme *sc, s7_pointer args) { case 6: return s7_make_boolean(sc, sim_paused()); + case 7: + return s7_make_integer(sc, MakeGameobject()); + } return args; @@ -337,6 +348,17 @@ s7_pointer s7_phys_set(s7_scheme *sc, s7_pointer args) { phys2d_set_gravity(x, y); } +s7_pointer s7_int_cmd(s7_scheme *sc, s7_pointer args) { + int cmd = s7_integer(s7_car(args)); + int val = s7_integer(s7_cadr(args)); + + switch (cmd) { + case 0: + set_cam_body(get_gameobject_from_id(val)->body); + break; + } +} + #define S7_FUNC(NAME, ARGS) s7_define_function(s7, #NAME, s7_ ##NAME, ARGS, 0, 0, "") void ffi_load() { @@ -362,5 +384,6 @@ void ffi_load() { S7_FUNC(phys_cmd, 3); S7_FUNC(phys_q, 2); S7_FUNC(phys_set, 3); + S7_FUNC(int_cmd, 2); } diff --git a/source/engine/openglrender.c b/source/engine/openglrender.c index f866467..d5b8666 100644 --- a/source/engine/openglrender.c +++ b/source/engine/openglrender.c @@ -12,6 +12,8 @@ #include "log.h" #include "datastream.h" + + int renderMode = 0; static GLuint UBO; @@ -107,7 +109,18 @@ void openglInit() } -static struct mCamera mcamera = {0}; +static cpBody *camera = NULL; +void set_cam_body(cpBody *body) { + camera = body; +} + +cpVect cam_pos() { + return camera ? cpBodyGetPosition(camera) : cpvzero; +} + +static float zoom = 1.f; +void add_zoom(float val) { zoom = val; } + void openglRender(struct window *window) { glClear(GL_COLOR_BUFFER_BIT); @@ -116,10 +129,12 @@ void openglRender(struct window *window) //////////// 2D projection mfloat_t projection[16] = { 0.f }; - mat4_ortho(projection, mcamera.transform.position[0], - window->width + mcamera.transform.position[0], - mcamera.transform.position[1], - window->height + mcamera.transform.position[1], -1.f, 1.f); + cpVect pos = cam_pos(); + mat4_ortho(projection, pos.x, + window->width*zoom + pos.x, + pos.y, + window->height*zoom + pos.y, -1.f, 1.f); + glBindBuffer(GL_UNIFORM_BUFFER, projUBO); glBufferSubData(GL_UNIFORM_BUFFER, 0, 64, projection); @@ -130,7 +145,6 @@ void openglRender(struct window *window) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); ////// TEXT && GUI - //script_call_sym(window->gui_cb); call_gui(); //// DEBUG diff --git a/source/engine/openglrender.h b/source/engine/openglrender.h index 41ea6ad..287cc17 100644 --- a/source/engine/openglrender.h +++ b/source/engine/openglrender.h @@ -28,6 +28,8 @@ extern GLuint debugColorPickBO; extern struct gameobject *selectedobject; +#include + enum RenderMode { LIT, UNLIT, @@ -46,4 +48,8 @@ void debug_draw_phys(int draw); void BindUniformBlock(GLuint shaderID, const char *bufferName, GLuint bufferBind); +void set_cam_body(cpBody *body); +cpVect cam_pos(); +void add_zoom(float val); + #endif diff --git a/source/engine/script.c b/source/engine/script.c index bc7839c..f15bdeb 100644 --- a/source/engine/script.c +++ b/source/engine/script.c @@ -108,9 +108,9 @@ void register_update(s7_pointer sym) { arrput(updates, sym); } -void call_updates() { +void call_updates(double dt) { for (int i = 0; i < arrlen(updates); i++) - script_call_sym(updates[i]); + s7_call(s7, updates[i], s7_cons(s7, s7_make_real(s7, dt), s7_nil(s7))); } void register_gui(s7_pointer sym) { @@ -126,7 +126,7 @@ void register_physics(s7_pointer sym) { arrput(physics, sym); } -void call_physics() { +void call_physics(double dt) { for (int i = 0; i < arrlen(physics); i++) - script_call_sym(physics[i]); + s7_call(s7, physics[i], s7_cons(s7, s7_make_real(s7, dt), s7_nil(s7))); } \ No newline at end of file diff --git a/source/engine/script.h b/source/engine/script.h index ad54e4c..5042e17 100644 --- a/source/engine/script.h +++ b/source/engine/script.h @@ -15,12 +15,12 @@ int script_has_sym(s7_pointer sym); void script_eval_w_env(const char *s, s7_pointer env); void register_update(s7_pointer sym); -void call_updates(); +void call_updates(double dt); void register_gui(s7_pointer sym); void call_gui(); void register_physics(s7_pointer sym); -void call_physics(); +void call_physics(double dt); #endif diff --git a/source/engine/transform.h b/source/engine/transform.h index 8845fea..f56d55a 100644 --- a/source/engine/transform.h +++ b/source/engine/transform.h @@ -10,11 +10,9 @@ struct mTransform { }; -struct mTransform MakeTransform(mfloat_t pos[3], mfloat_t rotation[3], - float scale); +struct mTransform MakeTransform(mfloat_t pos[3], mfloat_t rotation[3], float scale); -mfloat_t *trans_forward(mfloat_t * res, - const struct mTransform *const trans); +mfloat_t *trans_forward(mfloat_t * res, const struct mTransform *const trans); mfloat_t *trans_back(mfloat_t * res, const struct mTransform *trans); mfloat_t *trans_up(mfloat_t * res, const struct mTransform *trans); mfloat_t *trans_down(mfloat_t * res, const struct mTransform *trans); diff --git a/source/engine/yugine.c b/source/engine/yugine.c index 6be8b25..cff39c0 100644 --- a/source/engine/yugine.c +++ b/source/engine/yugine.c @@ -38,6 +38,8 @@ static int ed = 1; static int sim_play = 0; static double lastTick; +static float timescale = 1.f; + void seghandle(int sig) { #ifdef __linux__ void *ents[512]; @@ -164,11 +166,13 @@ int main(int argc, char **args) { if (sim_play) { physlag += elapsed; - call_updates(); - if (physlag >= physMS) { + call_updates(elapsed * timescale); + + while (physlag >= physMS) { physlag -= physMS; - phys2d_update(physMS); - call_physics(); + phys2d_update(physMS * timescale); + call_physics(physMS * timescale); + if (sim_play == 2) sim_pause(); } } @@ -191,8 +195,13 @@ int main(int argc, char **args) { int sim_playing() { return sim_play; } +int sim_paused() { return (!sim_play && gameobjects_saved()); } + void sim_start() { /* Save starting state of everything */ + if (!gameobjects_saved()) + gameobject_saveall(); + sim_play = 1; } @@ -200,15 +209,18 @@ void sim_pause() { sim_play = 0; } -int sim_paused() { - return sim_play; -} - void sim_stop() { /* Revert starting state of everything from sim_start */ sim_play = 0; + gameobject_loadall(); } void sim_step() { + if (sim_paused()) { + sim_play = 2; + } +} +void set_timescale(float val) { + timescale = val; } \ No newline at end of file diff --git a/source/engine/yugine.h b/source/engine/yugine.h index cf62ea2..582b678 100644 --- a/source/engine/yugine.h +++ b/source/engine/yugine.h @@ -7,6 +7,7 @@ void sim_start(); void sim_pause(); void sim_stop(); void sim_step(); +void set_timescale(float val); #endif \ No newline at end of file diff --git a/source/scripts/engine.scm b/source/scripts/engine.scm index 52b64ca..ff07f61 100644 --- a/source/scripts/engine.scm +++ b/source/scripts/engine.scm @@ -38,6 +38,7 @@ (define (set_fps fps) (settings_cmd 0 (/ 1 fps))) (define (set_update fps) (settings_cmd 1 (/ 1 fps))) (define (set_phys fps) (settings_cmd 2 (/ 1 fps))) +(define (zoom! amt) (settings_cmd 5 amt)) (define (win_fulltoggle w) (win_cmd w 0)) (define (win_fullscreen w) (win_cmd w 1)) @@ -46,6 +47,7 @@ (define (load_level s) (gen_cmd 0 s)) (define (load_prefab s) (gen_cmd 1 s)) +(define (newobject) (sys_cmd 7)) (define (quit) (sys_cmd 0)) (define (exit) (quit)) @@ -63,7 +65,10 @@ ((gui) 1)) ,f)))) (define-macro (update . expr) - `(registertype update ,@expr)) + (let ((f (gensym))) + `(begin + (define (,f dt) (begin . ,expr)) + (register 0 ,f)))) (define-macro (gui . expr) `(registertype gui ,@expr)) @@ -94,6 +99,7 @@ (define (b2i val) (if (eq? val #f) 0 1)) (define (dbg_draw_phys val) (settings_cmd 3 (b2i val))) +(define (timescale! val) (settings_cmd 4 val)) (define (sim_play) (sys_cmd 1)) (define (sim_stop) (sys_cmd 2)) (define (sim_pause) (sys_cmd 3)) @@ -101,6 +107,8 @@ (define (sim_play?) (sys_cmd 5)) (define (sim_pause?) (sys_cmd 6)) +(define (camera! body) (int_cmd 0 body)) + (define (bodytype? body) (phys_q body 0)) (define-macro (register-phys type body . expr) @@ -126,3 +134,15 @@ ,@lets) ,@expr (curlet)))) + +(define-macro (input key . expr) + `(define (,(symbol "input_" (symbol->string key))) (begin . ,expr))) + +(define-macro (+= var amt) + `(set! ,var (+ ,var ,amt))) + +(define-macro (-= var amt) + `(set! ,var (- ,var ,amt))) + +(define (attach-script script object) + (let-set! script 'body object))