crash fixes; path rebasing for drag 'n' drop

This commit is contained in:
John Alanbrook 2023-12-22 17:50:03 +00:00
parent 606dfbea93
commit ccfd233207
21 changed files with 114 additions and 237 deletions

View file

@ -78,13 +78,15 @@ gameobject **clean_ids(gameobject **ids)
return ids;
}
void querylist(cpShape *shape, cpContactPointSet *points, gameobject **ids) { arrput(ids,shape2go(shape)); }
typedef struct querybox {
cpBB bb;
gameobject **ids;
} querybox;
void querylist(cpShape *shape, cpContactPointSet *points, querybox *qb) {
arrput(qb->ids, shape2go(shape));
}
void querylistbodies(cpBody *body, querybox *qb) {
if (cpBBContainsVect(qb->bb, cpBodyGetPosition(body)))
arrput(qb->ids,body2go(body));
@ -120,7 +122,7 @@ gameobject **phys2d_query_box(HMM_Vec2 pos, HMM_Vec2 wh) {
qb.bb = bbox;
qb.ids = NULL;
cpSpaceShapeQuery(space, box, querylist, qb.ids);
cpSpaceShapeQuery(space, box, querylist, &qb);
cpSpaceEachBody(space, querylistbodies, &qb);
cpShapeFree(box);
@ -205,6 +207,7 @@ struct phys2d_circle *Make2DCircle(gameobject *go) {
new->shape.debugdraw = phys2d_dbgdrawcircle;
new->shape.moi = phys2d_circle_moi;
new->shape.apply = phys2d_applycircle;
new->shape.free = NULL;
init_phys2dshape(&new->shape, go, new);
phys2d_applycircle(new);
@ -244,61 +247,6 @@ void phys2d_applycircle(struct phys2d_circle *circle) {
cpCircleShapeSetOffset(circle->shape.shape, HMM_MulV2(go->scale.XY, circle->offset).cp);
}
/************* BOX2D ************/
struct phys2d_box *Make2DBox(gameobject *go) {
struct phys2d_box *new = malloc(sizeof(struct phys2d_box));
new->t = (transform2d){
.pos = {0,0},
.angle = 0,
.scale = {0,0}
};
new->r = 0.f;
new->shape.go = go;
new->shape.apply = phys2d_applybox;
phys2d_applybox(new);
new->shape.debugdraw = phys2d_dbgdrawbox;
new->shape.moi = phys2d_box_moi;
return new;
}
float phys2d_box_moi(struct phys2d_box *box, float m) {
return cpMomentForBox(m, box->t.scale.x, box->t.scale.y);
}
void phys2d_boxdel(struct phys2d_box *box) {
phys2d_shape_del(&box->shape);
}
void phys2d_applybox(struct phys2d_box *box) {
phys2d_boxdel(box);
struct gameobject *go = box->shape.go;
cpTransform T = m3_to_cpt(transform2d2mat(box->t));
cpVect verts[4] = {{-0.5, -0.5}, {0.5, -0.5}, {0.5, 0.5}, {-0.5, 0.5}};
box->shape.shape = cpSpaceAddShape(space, cpPolyShapeNew(go->body, 4, verts, T, box->r));
init_phys2dshape(&box->shape, box->shape.go, box);
}
void phys2d_dbgdrawbox(struct phys2d_box *box) {
int n = cpPolyShapeGetCount(box->shape.shape);
HMM_Vec2 points[n+1];
struct gameobject *go = shape2go(box->shape.shape);
for (int i = 0; i < n; i++) {
HMM_Vec2 p;
p.cp = cpPolyShapeGetVert(box->shape.shape, i);
points[i] = go2world(go, p);
}
points[n] = points[0];
struct rgba c = shape_color(box->shape.shape);
struct rgba cl = c;
cl.a = col_alpha;
float seglen = cpShapeGetSensor(box->shape.shape) ? sensor_seg : 0;
draw_line(points, n, cl,seglen, 0);
draw_poly(points, n, c);
}
/************** POLYGON ************/
struct phys2d_poly *Make2DPoly(gameobject *go) {
@ -311,11 +259,18 @@ struct phys2d_poly *Make2DPoly(gameobject *go) {
new->shape.shape = cpSpaceAddShape(space, cpPolyShapeNewRaw(go->body, 0, (cpVect*)new->points, new->radius));
new->shape.debugdraw = phys2d_dbgdrawpoly;
new->shape.moi = phys2d_poly_moi;
new->shape.free = phys2d_poly_free;
new->shape.apply = phys2d_applypoly;
init_phys2dshape(&new->shape, go, new);
return new;
}
void phys2d_poly_free(struct phys2d_poly *poly)
{
arrfree(poly->points);
free(poly);
}
float phys2d_poly_moi(struct phys2d_poly *poly, float m) {
float moi = cpMomentForPoly(m, arrlen(poly->points), (cpVect*)poly->points, cpvzero, poly->radius);
if (isnan(moi)) {
@ -339,6 +294,7 @@ void phys2d_poly_setverts(struct phys2d_poly *poly, HMM_Vec2 *verts) {
if (!verts) return;
if (poly->points)
arrfree(poly->points);
arrsetlen(poly->points, arrlen(verts));
for (int i = 0; i < arrlen(verts); i++)
@ -390,12 +346,22 @@ struct phys2d_edge *Make2DEdge(gameobject *go) {
new->shape.moi = phys2d_edge_moi;
new->shape.shape = NULL;
new->shape.apply = NULL;
new->shape.free = phys2d_edge_free;
new->draws = 0;
phys2d_applyedge(new);
return new;
}
void phys2d_edge_free(struct phys2d_edge *edge)
{
for (int i = 0; i < arrlen(edge->shapes); i++)
cpShapeSetUserData(edge->shapes[i], NULL);
arrfree(edge->points);
arrfree(edge->shapes);
free(edge);
}
float phys2d_edge_moi(struct phys2d_edge *edge, float m) {
float moi = 0;
for (int i = 0; i < arrlen(edge->points) - 1; i++)

View file

@ -11,9 +11,6 @@ extern float phys2d_gravity;
extern int physOn;
extern cpSpace *space;
extern struct rgba color_white;
extern struct rgba color_black;
extern struct rgba disabled_color;
extern struct rgba dynamic_color;
extern struct rgba kinematic_color;
@ -28,6 +25,7 @@ struct phys2d_shape {
void (*debugdraw)(void *data);
float (*moi)(void *data, float mass);
void (*apply)(void *data);
void (*free)(void *data);
};
/* Circles are the fastest colldier type */
@ -37,14 +35,6 @@ struct phys2d_circle {
struct phys2d_shape shape;
};
/* A single segment */
struct phys2d_segment {
HMM_Vec2 a;
HMM_Vec2 b;
float thickness;
struct phys2d_shape shape;
};
/* A convex polygon; defined as the convex hull around the given set of points */
struct phys2d_poly {
HMM_Vec2 *points;
@ -53,13 +43,6 @@ struct phys2d_poly {
struct phys2d_shape shape;
};
/* A box shape; a type of a polygon collider */
struct phys2d_box {
transform2d t; /* Scale here is used as width/height */
float r; /* radius */
struct phys2d_shape shape;
};
/* An edge with no volume. Cannot collide with each other. Join to make levels. Static only. */
struct phys2d_edge {
HMM_Vec2 *points; /* Points defined relative to the gameobject */
@ -75,13 +58,8 @@ void phys2d_applycircle(struct phys2d_circle *circle);
void phys2d_dbgdrawcircle(struct phys2d_circle *circle);
float phys2d_circle_moi(struct phys2d_circle *c, float m);
struct phys2d_box *Make2DBox(gameobject *go);
void phys2d_boxdel(struct phys2d_box *box);
void phys2d_applybox(struct phys2d_box *box);
void phys2d_dbgdrawbox(struct phys2d_box *box);
float phys2d_box_moi(struct phys2d_box *box, float m);
struct phys2d_poly *Make2DPoly(gameobject *go);
void phys2d_poly_free(struct phys2d_poly *poly);
void phys2d_polydel(struct phys2d_poly *poly);
void phys2d_applypoly(struct phys2d_poly *poly);
void phys2d_dbgdrawpoly(struct phys2d_poly *poly);
@ -90,6 +68,7 @@ void phys2d_poly_setverts(struct phys2d_poly *poly, HMM_Vec2 *verts);
float phys2d_poly_moi(struct phys2d_poly *poly, float m);
struct phys2d_edge *Make2DEdge(gameobject *go);
void phys2d_edge_free(struct phys2d_edge *edge);
void phys2d_edgedel(struct phys2d_edge *edge);
void phys2d_applyedge(struct phys2d_edge *edge);
void phys2d_dbgdrawedge(struct phys2d_edge *edge);
@ -110,7 +89,6 @@ void phys2d_update(float deltaT);
cpShape *phys2d_query_pos(cpVect pos);
gameobject **phys2d_query_box(HMM_Vec2 pos, HMM_Vec2 wh);
struct shape_cb {
struct phys2d_shape *shape;
struct phys_cbs cbs;

View file

@ -4,7 +4,6 @@
#include "resources.h"
#include "stb_ds.h"
#include "font.h"
#include "window.h"
#include "gameobject.h"
//#include "diffuse.sglsl.h"

View file

@ -1,9 +1,7 @@
#ifndef CIRCBUF_H
#define CIRCBUF_H
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
static inline unsigned int powof2(unsigned int x)
{

View file

@ -1,7 +1,6 @@
#ifndef DEBUGDRAW_H
#define DEBUGDRAW_H
#include <chipmunk/chipmunk.h>
#include "HandmadeMath.h"
struct rgba;

View file

@ -1,7 +1,7 @@
#include "font.h"
#include "log.h"
#include "render.h"
#include <ctype.h>
#include "log.h"
#include <limits.h>
@ -9,11 +9,10 @@
#include <stdlib.h>
#include <string.h>
#include <window.h>
#include <chipmunk/chipmunk.h>
#include "2dphysics.h"
#include "resources.h"
#include "debugdraw.h"
#include "text.sglsl.h"
#include "render.h"
#include "stb_image_write.h"
#include "stb_rect_pack.h"

View file

@ -2,8 +2,7 @@
#define FONT_H
#include "sokol/sokol_gfx.h"
#include "texture.h"
#include "2dphysics.h"
#include "render.h"
#include "HandmadeMath.h"
struct shader;

View file

@ -1,7 +1,6 @@
#include "gameobject.h"
#include "2dphysics.h"
#include <chipmunk/chipmunk.h>
#include <string.h>
#include "debugdraw.h"
#include "log.h"
@ -177,6 +176,13 @@ gameobject *MakeGameobject() {
void rm_body_shapes(cpBody *body, cpShape *shape, void *data) {
struct phys2d_shape *s = cpShapeGetUserData(shape);
if (s) {
if (s->free)
s->free(s->data);
else
free(s->data);
}
cpSpaceRemoveShape(space, shape);
cpShapeFree(shape);
}

View file

@ -1,7 +1,6 @@
#ifndef GAMEOBJECT_H
#define GAMEOBJECT_H
#include <chipmunk/chipmunk.h>
#include "quickjs/quickjs.h"
#include "HandmadeMath.h"
#include "transform.h"

View file

@ -1,14 +1,12 @@
#include "input.h"
#include "jsffi.h"
#include "sokol/sokol_app.h"
#include "font.h"
#include "log.h"
#include "script.h"
#include "stb_ds.h"
#include "time.h"
#include <stdio.h>
#include <ctype.h>
#include <wchar.h>
#include "resources.h"
#include "jsffi.h"
@ -193,7 +191,8 @@ void input_dropped_files(int n)
argv[0] = jstr("emacs");
argv[1] = jstr("drop");
argv[2] = jstr("pressed");
argv[3] = str2js(sapp_get_dropped_file_path(0));
char *path = rebase_path(sapp_get_dropped_file_path(0));
argv[3] = str2js(path);
script_callee(pawn_callee, 4, argv);
JS_FreeValue(js,argv[3]);
}

View file

@ -1,12 +1,9 @@
#ifndef INPUT_H
#define INPUT_H
#include "sokol/sokol_app.h"
#include "script.h"
#include "window.h"
#include <chipmunk/chipmunk.h>
#include <stdint.h>
#include "HandmadeMath.h"
extern HMM_Vec2 mousewheel;
extern HMM_Vec2 mouse_pos;

View file

@ -3,6 +3,7 @@
#include "script.h"
#include "anim.h"
#include "timer.h"
#include "debug.h"
#include "debugdraw.h"
#include "font.h"
@ -1649,47 +1650,6 @@ JSValue duk_make_sprite(JSContext *js, JSValueConst this, int argc, JSValueConst
return sprite;
}
JSValue duk_make_box2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
gameobject *go = js2gameobject(argv[0]);
HMM_Vec2 size = js2vec2(argv[1]);
struct phys2d_box *box = Make2DBox(go);
box->t.scale = js2vec2(argv[1]);
box->t.pos = js2vec2(argv[2]);
phys2d_applybox(box);
JSValue boxval = JS_NewObject(js);
js_setprop_str(boxval, "id", ptr2js(box));
js_setprop_str(boxval, "shape", ptr2js(&box->shape));
return boxval;
}
JSValue duk_cmd_box2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
int cmd = js2int(argv[0]);
struct phys2d_box *box = js2ptr(argv[1]);
HMM_Vec2 arg;
if (!box) return JS_UNDEFINED;
switch (cmd) {
case 0:
box->t.scale = js2vec2(argv[2]);
break;
case 1:
box->t.pos = js2vec2(argv[2]);
break;
case 2:
box->t.angle = js2number(argv[2]);
break;
}
phys2d_applybox(box);
return JS_UNDEFINED;
}
JSValue duk_make_circle2d(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) {
gameobject *go = js2gameobject(argv[0]);
@ -1878,8 +1838,6 @@ void ffi_load() {
DUK_FUNC(make_sprite, 1)
DUK_FUNC(spline_cmd, 6)
DUK_FUNC(make_box2d, 3)
DUK_FUNC(cmd_box2d, 6)
DUK_FUNC(make_circle2d, 1)
DUK_FUNC(cmd_circle2d, 6)
DUK_FUNC(make_poly2d, 1)

View file

@ -2,8 +2,7 @@
#define FFI_H
#include "quickjs/quickjs.h"
#include <chipmunk/chipmunk.h>
#include "2dphysics.h"
#include "HandmadeMath.h"
void ffi_load();

View file

@ -596,3 +596,32 @@ sg_shader sg_compile_shader(const char *v, const char *f, sg_shader_desc *d)
free(fs);
return ret;
}
struct boundingbox cwh2bb(HMM_Vec2 c, HMM_Vec2 wh) {
struct boundingbox bb = {
.t = c.Y + wh.Y/2,
.b = c.Y - wh.Y/2,
.r = c.X + wh.X/2,
.l = c.X - wh.X/2
};
return bb;
}
float *rgba2floats(float *r, struct rgba c)
{
r[0] = (float)c.r / RGBA_MAX;
r[1] = (float)c.g / RGBA_MAX;
r[2] = (float)c.b / RGBA_MAX;
r[3] = (float)c.a / RGBA_MAX;
return r;
}
sg_blend_state blend_trans = {
.enabled = true,
.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA,
.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
.src_factor_alpha = SG_BLENDFACTOR_SRC_ALPHA,
.dst_factor_alpha = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA
};

View file

@ -17,15 +17,10 @@
#define RGBA_MAX 255
struct mCamera;
struct window;
#include "window.h"
extern struct shader *spriteShader;
extern struct shader *animSpriteShader;
extern sg_image ddimg;
extern struct sprite *tsprite;
extern struct rgba color_white;
extern struct rgba color_black;
extern int renderMode;
@ -34,26 +29,17 @@ extern HMM_Vec3 dirl_pos;
extern HMM_Mat4 projection;
extern HMM_Mat4 hudproj;
struct camera3d {
};
typedef struct camera3d camera3d;
struct draw_p {
float x;
float y;
};
extern float gridScale;
extern float smallGridUnit;
extern float bigGridUnit;
extern float gridSmallThickness;
extern float gridBigThickness;
extern struct rgba gridBigColor;
extern struct rgba gridSmallColor;
extern float gridOpacity;
extern float editorFOV;
extern float shadowLookahead;
extern char objectName[];
extern int debugColorPickBO;
extern struct gameobject *selectedobject;
#include <chipmunk/chipmunk.h>
enum RenderMode {
@ -69,7 +55,7 @@ void openglRender(struct window *window);
void opengl_rendermode(enum RenderMode r);
void openglInit3d(struct window *window);
void openglRender3d(struct window *window, struct mCamera *camera);
void openglRender3d(struct window *window, camera3d *camera);
void capture_screen(int x, int y, int w, int h, const char *path);
void render_winsize();
@ -116,32 +102,15 @@ struct rect {
float h, w, x, y;
};
static struct boundingbox cwh2bb(HMM_Vec2 c, HMM_Vec2 wh) {
struct boundingbox bb = {
.t = c.Y + wh.Y/2,
.b = c.Y - wh.Y/2,
.r = c.X + wh.X/2,
.l = c.X - wh.X/2
};
return bb;
}
static float *rgba2floats(float *r, struct rgba c)
{
r[0] = (float)c.r / RGBA_MAX;
r[1] = (float)c.g / RGBA_MAX;
r[2] = (float)c.b / RGBA_MAX;
r[3] = (float)c.a / RGBA_MAX;
return r;
}
static sg_blend_state blend_trans = {
.enabled = true,
.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA,
.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
.src_factor_alpha = SG_BLENDFACTOR_SRC_ALPHA,
.dst_factor_alpha = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA
/* Normalized S,T coordinates for rendering */
struct glrect {
float s0;
float s1;
float t0;
float t1;
};
struct boundingbox cwh2bb(HMM_Vec2 c, HMM_Vec2 wh);
float *rgba2floats(float *r, struct rgba c);
extern sg_blend_state blend_trans;
#endif

View file

@ -25,8 +25,8 @@
#include "core.cdb.h"
char *DATA_PATH = NULL;
char *PREF_PATH = NULL;
char *DATA_PATH = NULL; /* The top level asset path, where the executable resides */
char *PREF_PATH = NULL; /* Path to where the program can write data to, usually for save files etc. */
char **prefabs;
@ -51,6 +51,7 @@ void resources_init() {
int fd = open("test.cdb", O_RDONLY);
cdb_init(&game_cdb, fd);
cdb_initf(&corecdb, core_cdb, core_cdb_len);
printf("%s\n", DATA_PATH);
}
char *get_filename_from_path(char *path, int extension) {
@ -81,6 +82,16 @@ char *dirname(const char *path)
return dir;
}
char *rebase_path(const char *path)
{
int off = 0;
while (path[off] == DATA_PATH[off]) {
off++;
if (!path[off] || !DATA_PATH[off]) break;
}
return path+off;
}
FILE *res_open(char *path, const char *tag) {
strncpy(pathbuf, DATA_PATH, MAXPATH);
strncat(pathbuf, path, MAXPATH);

View file

@ -17,6 +17,7 @@ FILE *path_open(const char *tag, const char *fmt, ...);
char *make_path(const char *file);
char **ls(const char *path);
int cp(const char *p1, const char *p2);
char *rebase_path(const char *path); /* given a global path, rebase to the local structure */
int fexists(const char *path);
FILE *fopen_mkdir(const char *path, const char *mode);

View file

@ -71,7 +71,6 @@ void script_startup() {
void script_stop()
{
timers_free();
script_evalf("Event.notify('quit');");
send_signal("quit",0,NULL);

View file

@ -1,8 +1,6 @@
#ifndef SPRITE_H
#define SPRITE_H
#include <stdio.h>
#include "timer.h"
#include "texture.h"
#include "HandmadeMath.h"
#include "render.h"
@ -25,7 +23,6 @@ int make_sprite(gameobject *go);
struct sprite *id2sprite(int id);
void sprite_delete(int id);
void sprite_enabled(int id, int e);
void sprite_io(struct sprite *sprite, FILE *f, int read);
void sprite_loadtex(struct sprite *sprite, const char *path, struct glrect rect);
void sprite_settex(struct sprite *sprite, struct Texture *tex);
void sprite_setframe(struct sprite *sprite, struct glrect *frame);

View file

@ -1,38 +1,20 @@
#ifndef TEXTURE_H
#define TEXTURE_H
#include "timer.h"
#include <chipmunk/chipmunk.h>
#include "sokol/sokol_gfx.h"
#include "HandmadeMath.h"
#include "render.h"
#define TEX_SPEC 0
#define TEX_NORM 1
#define TEX_HEIGHT 2
#define TEX_DIFF 3
/* Normalized S,T coordinates for rendering */
struct glrect {
float s0;
float s1;
float t0;
float t1;
};
float st_s_w(struct glrect st);
float st_s_h(struct glrect st);
extern struct glrect ST_UNIT;
/* Pixel U,V coordiantes */
struct uvrect {
int u0;
int u1;
int v0;
int v1;
};
struct TextureOptions {
int sprite;
int mips;

View file

@ -1,11 +1,6 @@
#ifndef WINDOW_H
#define WINDOW_H
#include "render.h"
#include <stdbool.h>
#include <stdint.h>
struct window {
int id;
int width;
@ -13,18 +8,16 @@ struct window {
double dpi;
int rwidth;
int rheight;
bool render;
bool mouseFocus;
bool keyboardFocus;
bool fullscreen;
bool minimized;
bool iconified;
bool focus;
bool shown;
int render;
int mouseFocus;
int keyboardFocus;
int fullscreen;
int minimized;
int iconified;
int focus;
int shown;
};
struct Texture;
extern struct window mainwin;
void window_resize(int width, int height);