Add 2d physics hooks

This commit is contained in:
John Alanbrook 2022-12-20 14:16:26 +00:00
parent 5ae72062a2
commit df907aec2b
9 changed files with 126 additions and 68 deletions

View file

@ -9,6 +9,9 @@
#include "gameobject.h" #include "gameobject.h"
#include <math.h> #include <math.h>
#include <chipmunk/chipmunk_unsafe.h> #include <chipmunk/chipmunk_unsafe.h>
#include "stb_ds.h"
#include "log.h"
cpBody *ballBody = NULL; cpBody *ballBody = NULL;
cpSpace *space = NULL; cpSpace *space = NULL;
@ -454,7 +457,22 @@ void phys2d_dbgdrawedge(struct phys2d_edge *edge)
float bd = sqrt(pow(b.x, 2.f) + pow(b.y, 2.f)); float bd = sqrt(pow(b.x, 2.f) + pow(b.y, 2.f));
float aa = atan2(a.y, a.x) + angle; float aa = atan2(a.y, a.x) + angle;
float ba = atan2(b.y, b.x) + angle; float ba = atan2(b.y, b.x) + angle;
draw_line(ad * cos(aa) + p.x, ad * sin(aa) + p.y, draw_line(ad * cos(aa) + p.x, ad * sin(aa) + p.y, bd * cos(ba) + p.x, bd * sin(ba) + p.y);
bd * cos(ba) + p.x, bd * sin(ba) + p.y);
} }
} }
s7_pointer *cbs;
static cpBool s7_phys_cb(cpArbiter *arb, cpSpace *space, void *data) {
s7_pointer *cb = data;
script_call_sym(*cb);
}
void phys2d_add_begin_handler(s7_pointer cb) {
arrput(cbs, cb);
cpCollisionHandler *handler = cpSpaceAddDefaultCollisionHandler(space);
handler->userData = &arrlast(cbs);
handler->beginFunc = s7_phys_cb;
YughInfo("Added a phys collider CB.");
}

View file

@ -2,7 +2,7 @@
#define TWODPHYSICS_H #define TWODPHYSICS_H
#include <chipmunk/chipmunk.h> #include <chipmunk/chipmunk.h>
#include "s7.h"
struct gameobject; struct gameobject;
@ -95,6 +95,8 @@ void phys2d_init();
void phys2d_update(float deltaT); void phys2d_update(float deltaT);
void phys2d_apply(); void phys2d_apply();
void phys2d_add_begin_handler(s7_pointer cb);
void shape_gui(struct phys2d_shape *shape); void shape_gui(struct phys2d_shape *shape);
#endif #endif

View file

@ -50,8 +50,9 @@ void mYughLog(int category, int priority, int line, const char *file, const char
fflush(logfile); fflush(logfile);
} }
snprintf(con+coni, CONSOLE_BUF-coni, "%s\n", buffer); int add = snprintf(con+coni, CONSOLE_BUF-coni, "%s\n", buffer);
coni += strlen(buffer); coni += add;
if (coni > CONSOLE_BUF) coni = CONSOLE_BUF;
snprintf(lastlog, ERROR_BUFFER, "%s", buffer); snprintf(lastlog, ERROR_BUFFER, "%s", buffer);

View file

@ -49,11 +49,16 @@ void input_init()
} }
void call_input_signal(char *signal) {
for (int i = 0; i < arrlen(pawns); i++)
script_eval_w_env(signal, pawns[i]);
}
void call_input_down(int *key) { void call_input_down(int *key) {
const char *keyname = glfwGetKeyName(*key, 0); const char *keyname = glfwGetKeyName(*key, 0);
char keystr[50] = {'\0'}; char keystr[50] = {'\0'};
snprintf(keystr, 50, "input_%s_down", keyname); snprintf(keystr, 50, "input_%s_down", keyname);
script_call(keystr); call_input_signal(keystr);
} }
/* This is called once every frame - or more if we want it more! */ /* This is called once every frame - or more if we want it more! */
@ -181,9 +186,7 @@ void win_key_callback(GLFWwindow *w, int key, int scancode, int action, int mods
} }
SCRIPTCALL: SCRIPTCALL:
for (int i = 0; i < arrlen(pawns); i++) call_input_signal(keystr);
script_eval_w_env(keystr, pawns[i]);
} }
void cursor_hide() void cursor_hide()

View file

@ -75,7 +75,7 @@ s7_pointer s7_settings_cmd(s7_scheme *sc, s7_pointer args) {
s7_pointer s7_log(s7_scheme *sc, s7_pointer args) { s7_pointer s7_log(s7_scheme *sc, s7_pointer args) {
int lvl = s7_integer(s7_car(args)); int lvl = s7_integer(s7_car(args));
const char *msg = s7_string(s7_object_to_string(sc, s7_cadr(args), 0)); const char *msg = s7_string(s7_cadr(args));
const char *file = s7_string(s7_caddr(args)); const char *file = s7_string(s7_caddr(args));
int line = s7_integer(s7_cadddr(args)); int line = s7_integer(s7_cadddr(args));
mYughLog(1, lvl, line, file, msg); mYughLog(1, lvl, line, file, msg);
@ -193,11 +193,9 @@ s7_pointer s7_gui_hook(s7_scheme *sc, s7_pointer args) {
s7_pointer s7_register(s7_scheme *sc, s7_pointer args) { s7_pointer s7_register(s7_scheme *sc, s7_pointer args) {
int hook = s7_integer(s7_car(args)); int hook = s7_integer(s7_car(args));
s7_pointer expr = s7_cadr(args);
register_update(s7_cadr(args)); register_update(s7_cadr(args));
return expr; return args;
} }
s7_pointer s7_set_pawn(s7_scheme *sc, s7_pointer args) { s7_pointer s7_set_pawn(s7_scheme *sc, s7_pointer args) {
@ -230,12 +228,34 @@ s7_pointer s7_set_body(s7_scheme *sc, s7_pointer args) {
s7_pointer s7_set_body_pos(s7_scheme *sc, s7_pointer args) { s7_pointer s7_set_body_pos(s7_scheme *sc, s7_pointer args) {
int id = s7_integer(s7_car(args)); int id = s7_integer(s7_car(args));
double x = s7_real(s7_cadr(args)); int cmd = s7_integer(s7_cadr(args));
double y = s7_real(s7_caddr(args)); double x = s7_real(s7_caddr(args));
gameobject_setpos(get_gameobject_from_id(id), x, y); double y = s7_real(s7_cadddr(args));
switch (cmd) {
case 0:
gameobject_setpos(get_gameobject_from_id(id), x, y);
break;
case 1:
gameobject_move(get_gameobject_from_id(id), x, y);
break;
}
return args; return args;
} }
s7_pointer s7_phys_cmd(s7_scheme *sc, s7_pointer args) {
int cmd = s7_integer(s7_car(args));
s7_pointer env = s7_cadr(args);
switch(cmd) {
case 0:
phys2d_add_begin_handler(env);
break;
}
}
#define S7_FUNC(NAME, ARGS) s7_define_function(s7, #NAME, s7_ ##NAME, ARGS, 0, 0, "") #define S7_FUNC(NAME, ARGS) s7_define_function(s7, #NAME, s7_ ##NAME, ARGS, 0, 0, "")
void ffi_load() { void ffi_load() {
@ -256,6 +276,7 @@ void ffi_load() {
S7_FUNC(register, 2); S7_FUNC(register, 2);
S7_FUNC(set_pawn, 1); S7_FUNC(set_pawn, 1);
S7_FUNC(set_body, 3); S7_FUNC(set_body, 3);
S7_FUNC(set_body_pos, 3); S7_FUNC(set_body_pos, 4);
S7_FUNC(phys_cmd, 2);
} }

View file

@ -11,13 +11,36 @@ s7_scheme *s7 = NULL;
s7_pointer *updates; s7_pointer *updates;
static void my_print(s7_scheme *sc, uint8_t c, s7_pointer port) { static void null_port(s7_scheme *sc, uint8_t c, s7_pointer port) {
}
static void my_err(s7_scheme *sc, uint8_t c, s7_pointer port) {
static char buffer[1024]; static char buffer[1024];
static char *p = buffer; static char *p = buffer;
if (c != '\0' && p != &buffer[1023]) { if (c != '\n' && p != &buffer[1023]) {
*p = c; *p = c;
p++; p++;
} else { } else {
*p = '\0';
if (buffer[0] != '\n')
YughError(buffer);
p = buffer;
//YughInfo("File %s, line %d", s7_port_filename(sc, port), s7_port_line_number(sc, port));
int lost = s7_flush_output_port(sc, port);
}
}
static void my_print(s7_scheme *sc, uint8_t c, s7_pointer port) {
static char buffer[1024];
static char *p = buffer;
if (c != '\n' && p != &buffer[1023]) {
*p = c;
p++;
} else {
*p = '\0';
YughInfo(buffer); YughInfo(buffer);
p = buffer; p = buffer;
} }
@ -25,48 +48,20 @@ static void my_print(s7_scheme *sc, uint8_t c, s7_pointer port) {
void script_init() { void script_init() {
s7 = s7_init(); s7 = s7_init();
s7_set_current_error_port(s7, s7_open_output_string(s7)); s7_set_current_error_port(s7, s7_open_output_function(s7, my_err));
s7_set_current_output_port(s7, s7_open_output_function(s7, my_print)); s7_set_current_output_port(s7, s7_open_output_function(s7, my_print));
ffi_load(); ffi_load();
} }
void script_run(const char *script) { void script_run(const char *script) {
s7_pointer old_port = s7_set_current_error_port(s7, s7_open_output_string(s7));
int gc_loc = -1;
if (old_port != s7_nil(s7)) gc_loc = s7_gc_protect(s7, old_port);
s7_eval_c_string(s7, script); s7_eval_c_string(s7, script);
const char *errmsg = s7_get_output_string(s7, s7_current_error_port(s7));
if (errmsg && (*errmsg))
mYughLog(1, 2, 0, "script", "Scripting error: %s", errmsg);
s7_close_output_port(s7, s7_current_error_port(s7));
s7_set_current_error_port(s7, old_port);
if (gc_loc != -1) s7_gc_unprotect_at(s7, gc_loc);
} }
int script_dofile(const char *file) { int script_dofile(const char *file) {
/* static char fload[512];
snprintf(fload, 512, "(write (load \"%s\"))", file);
s7_eval_c_string(s7, fload);
*/
if (!s7_load(s7, file)) { if (!s7_load(s7, file)) {
YughError("Can't find file %s.", file); YughError("Can't find file %s.", file);
return 1; return 1;
} }
const char *errmsg = s7_get_output_string(s7, s7_current_error_port(s7));
if (errmsg && (*errmsg))
mYughLog(1, 2, 0, "script", "Scripting error: %s", errmsg);
return 0; return 0;
} }
@ -89,7 +84,10 @@ void script_call(const char *f) {
void script_eval_w_env(const char *s, s7_pointer env) { void script_eval_w_env(const char *s, s7_pointer env) {
char buffer[512]; char buffer[512];
snprintf(buffer, 512-1, "(%s)", s); snprintf(buffer, 512-1, "(%s)", s);
s7_set_current_error_port(s7, s7_open_output_function(s7, null_port));
s7_eval_c_string_with_environment(s7, buffer, env); s7_eval_c_string_with_environment(s7, buffer, env);
s7_set_current_error_port(s7, s7_open_output_function(s7, my_err));
} }
void script_call_sym(s7_pointer sym) void script_call_sym(s7_pointer sym)

View file

@ -12,6 +12,7 @@ void script_editor();
void script_call(const char *f); void script_call(const char *f);
void script_call_sym(s7_pointer sym); void script_call_sym(s7_pointer sym);
int script_has_sym(s7_pointer sym); 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 register_update(s7_pointer sym);
void call_updates(); void call_updates();

View file

@ -26,7 +26,7 @@ double renderlag = 0;
double physlag = 0; double physlag = 0;
double updatelag = 0; double updatelag = 0;
double renderMS = 1/60.f; double renderMS = 1/165.f;
double physMS = 1/120.f; double physMS = 1/120.f;
double updateMS = 1/60.f; double updateMS = 1/60.f;
@ -135,8 +135,6 @@ int main(int argc, char **args) {
renderMS = 1.0/vidmode->refreshRate; renderMS = 1.0/vidmode->refreshRate;
double framet = fmin(fmin(renderMS,physMS),updateMS);
script_dofile("scripts/engine.scm"); script_dofile("scripts/engine.scm");
script_dofile("config.scm"); script_dofile("config.scm");
@ -150,32 +148,36 @@ int main(int argc, char **args) {
openglInit(); openglInit();
renderMS = 0.033;
double lastTick; double lastTick;
while (!want_quit()) { while (!want_quit()) {
double elapsed; double elapsed = glfwGetTime() - lastTick;
elapsed = glfwGetTime() - lastTick; deltaT = elapsed;
lastTick = glfwGetTime(); lastTick = glfwGetTime();
//timer_update(lastTick);
timer_update(lastTick);
call_updates(); call_updates();
//renderlag += elapsed; renderlag += elapsed;
//physlag += elapsed; physlag += elapsed;
if (physlag >= physMS) {
physlag -= physMS;
phys2d_update(physMS);
}
if (renderlag >= renderMS) { if (renderlag >= renderMS) {
renderlag -= renderMS; renderlag -= renderMS;
window_renderall();
} }
window_renderall();
input_poll(renderMS- elapsed < 0 ? 0 : renderMS - elapsed); double wait = fmax(0, renderMS-elapsed);
input_poll(wait);
window_all_handle_events(); window_all_handle_events();
} }
return 0; return 0;

View file

@ -13,16 +13,21 @@
(define-macro (funcsrc func) (define-macro (funcsrc func)
`(funcinfo ,func 'source)) `(funcinfo ,func 'source))
(define (objects->string . objs)
(apply string-append (map (lambda (obj) (object->string obj #t)) objs)))
(define-macro (glog data lvl) (define-macro (glog data lvl)
`(log ,lvl ,data (port-filename (current-input-port)) (port-line-number (current-input-port)))) (let ((file (*function* (outlet (curlet)) 'file))
(line (*function* (outlet (curlet)) 'line)))
`(log ,lvl ,data ,file ,line)))
(define-macro (flog data lvl) (define-macro (flog data lvl)
`(log ,lvl ,data (funcinfo (*function*) 'file) (funcinfo (*function*) 'line))) `(log ,lvl ,data (funcinfo (*function*) 'file) (funcinfo (*function*) 'line)))
(define (loginfo data) (glog data 0)) (define (loginfo . data) (glog (objects->string data) 0))
(define (logwarn data) (glog data 1)) (define (logwarn . data) (glog (objects->string data) 1))
(define (logerr data) (glog data 2)) (define (logerr . data) (glog (objects->string data) 2))
(define (logcrit data) (glog data 3)) (define (logcrit . data) (glog (objects->string data) 3))
(define (set_fps fps) (settings_cmd 0 (/ 1 fps))) (define (set_fps fps) (settings_cmd 0 (/ 1 fps)))
(define (set_update fps) (settings_cmd 1 (/ 1 fps))) (define (set_update fps) (settings_cmd 1 (/ 1 fps)))
@ -68,4 +73,11 @@
(* deg 0.01745329252)) (* deg 0.01745329252))
(define (body_angle! body angle) (set_body body 0 angle)) (define (body_angle! body angle) (set_body body 0 angle))
(define (body_pos! body x y) (set_body_pos body x y)) (define (body_pos! body x y) (set_body_pos body 0 x y))
(define (body_move! body x y) (set_body_pos body 1 x y))
(define-macro (collide . expr)
(let ((f (gensym)))
`(begin
(define (,f) (begin . ,expr))
(phys_cmd 0 ,f))))