diff --git a/ecs2.h b/ecs2.h index e16e1ce..4376efb 100644 --- a/ecs2.h +++ b/ecs2.h @@ -34,8 +34,14 @@ typedef int ecs_eid; #define ECS_END(name) \ } \ ; \ + const ecs_cid name##_fl = ECS_SELFFLAG; + +// NOTE: these generate functions individually because some systems might +// not allow unused functions and you may not need them all +#define ECS_FN_INIT(name) \ /* Always initialize the ecs system when you create a new one! */ \ - static void name##_init(name *_ecs) { memset(_ecs, 0, sizeof(name)); } \ + static void name##_init(name *_ecs) { memset(_ecs, 0, sizeof(name)); } +#define ECS_FN_NEWENTITY(name) \ /* Create an entity with the given base components (usually 0) */ \ static ecs_eid name##_newentity(name *_ecs, ecs_cid basecomponents) { \ for (int i = 0; i < ECS_MAXENTITIES; i++) { \ @@ -48,12 +54,14 @@ typedef int ecs_eid; } \ } \ return -1; \ - } \ + } +#define ECS_FN_DELETEENTITY(name) \ /* Delete an entity by eid from the given ecs sys */ \ static void name##_deleteentity(name *_ecs, ecs_eid eid) { \ if (eid >= 0 && eid < ECS_MAXENTITIES) \ _ecs->entities[eid] = 0; \ - } \ + } +#define ECS_FN_QUERY(name) \ /* Whether an entity matches a given list of components by flag */ \ static int name##_match(name *_ecs, ecs_eid _eid, ecs_cid _comps) { \ ecs_cid _realcomps = ECS_SELFFLAG | _comps; \ @@ -68,12 +76,12 @@ typedef int ecs_eid; } \ } \ return count; \ - } \ + } +#define ECS_FN_EID(name) \ /* Calculate the eid from a double ecs pointer. Useful to get eid in sys */ \ static ecs_eid name##_eid(name **_ecs) { \ return (ecs_eid)(_ecs - (*_ecs)->c_##name); \ - } \ - const ecs_cid name##_fl = ECS_SELFFLAG; + } // Create an ECS component within an ECS struct #define ECS_COMPONENT(type) type c_##type[ECS_MAXENTITIES]; diff --git a/maze_ecstypes.h b/maze_ecstypes.h index cf6eab0..27df303 100644 --- a/maze_ecstypes.h +++ b/maze_ecstypes.h @@ -126,6 +126,12 @@ ECS_COMPONENT(ecs_object); ECS_COMPONENT(ecs_mazeentity); ECS_END(mecs) +ECS_FN_INIT(mecs) +ECS_FN_NEWENTITY(mecs) +ECS_FN_DELETEENTITY(mecs) +ECS_FN_EID(mecs) +ECS_FN_QUERY(mecs) + // And then a copy of the components here... that sucksssss ECS_CID(ecs_worldstate, 0); ECS_CID(ecs_world, 1); diff --git a/terrain.c b/terrain.c index 44e8b8d..e5249ac 100644 --- a/terrain.c +++ b/terrain.c @@ -3,6 +3,7 @@ #include "haloo3d/haloo3dex_gen.h" #include "haloo3d/haloo3dex_obj.h" +#include "haloo3d/haloo3dex_print.h" #include "haloo3d/lib/mathc.h" #include "unigi/unigi.headers/src/main.h" #include "unigi/unigi.platform.sdl1/src/main.c" @@ -12,6 +13,7 @@ #include "terrain_ecstypes.h" #include +#include #define WIDTH 480 #define HEIGHT 300 @@ -24,44 +26,66 @@ #define CAM_INITPITCH MPI_2 #define INIT_NEARCLIP 0.01 #define INIT_FARCLIP 100.0 +#define INIT_FOV 90.0 #define INIT_DITHERSTART 10000 #define INIT_DITHEREND 10000 -// Some globals you can mess around with potentially -int fps = 30; +#define INIT_PLAYERSPEED \ + { .x = 0, .y = 0, .z = -0.5 } +// Some globals you can mess around with potentially +int fps = 60; + +// --------------------------------------------------- // The terrain ecs systems +// --------------------------------------------------- // All initialization for a specific render context void sys_rendercontext(ecs_rendercontext *erc, ecs_placement *p) { render_context *rc = *erc; - rc->precalc_halfwidth = rc->window.width * H3DVF(0.5); - rc->precalc_halfheight = rc->window.height * H3DVF(0.5); - haloo3d_perspective(rc->precalc_perspective, rc->fov, - (mfloat_t)rc->window.width / rc->window.height, - rc->nearclip, rc->farclip); + struct vec3 lookat; + mfloat_t cammatrix[MAT4_SIZE]; + mfloat_t perspective[MAT4_SIZE]; + // Some initial clearing haloo3d_fb_cleardepth(&rc->window); if (rc->windowclear & 0xF000) { haloo3d_fb_clear(&rc->window, rc->windowclear); } + // Precalc stuff for later object rendering + rc->precalc_halfwidth = rc->window.width * H3DVF(0.5); + rc->precalc_halfheight = rc->window.height * H3DVF(0.5); + haloo3d_perspective(perspective, rc->fov, + (mfloat_t)rc->window.width / rc->window.height, + rc->nearclip, rc->farclip); + vec3_add(lookat.v, p->pos.v, p->lookvec.v); + haloo3d_my_lookat(cammatrix, p->pos.v, lookat.v, p->up.v); + mat4_inverse(cammatrix, cammatrix); + mat4_multiply(rc->precalc_screen, perspective, cammatrix); } -// Apply rotation to lookvec of placement +// Apply rotation to lookvec of placement, overrides lookvec void sys_rotation(ecs_placement *p, ecs_rotation *r) { YAWP2VEC(r->yaw, r->pitch, p->lookvec.v); } -void sys_movement(ecs_placement *p, ecs_movement *m) { - vec3_add(p->lookvec.v, p->lookvec.v, m->lookvec.v); - vec3_add(p->up.v, p->up.v, m->up.v); - vec3_add(p->pos.v, p->pos.v, m->pos.v); +void sys_movement(ecs_placement *p, ecs_movement *m, tecs **ecs) { + mfloat_t temp[VEC3_SIZE]; + vec3_multiply_f(temp, m->lookvec.v, (*ecs)->delta_s); + vec3_add(p->lookvec.v, p->lookvec.v, temp); + vec3_multiply_f(temp, m->up.v, (*ecs)->delta_s); + vec3_add(p->up.v, p->up.v, temp); + vec3_multiply_f(temp, m->pos.v, (*ecs)->delta_s); + vec3_add(p->pos.v, p->pos.v, temp); } // Perform the entire rendering of an object void sys_renderobject(ecs_placement *p, ecs_object *o) { struct vec3 lighting; struct vec4 precalc_verts[H3D_OBJ_MAXVERTICES]; - // First, precalc all the vertices in the object + // The compiler is complaining about lighting beined used unitialized, even + // though it's not. Just shut it up First, precalc all the vertices in the + vec3(lighting.v, 0, 0, 0); + // object // ------------------------------------------------------------------ mfloat_t tmp[VEC4_SIZE]; mfloat_t modelm[MAT4_SIZE]; @@ -166,10 +190,12 @@ int main() { // int argc, char **argv) { eprintf("Initialized storage and default textures/etc\n"); - haloo3d_fb screen3d; - haloo3d_fb_init(&screen3d, WIDTH, HEIGHT); haloo3d_fb screen; haloo3d_fb_init(&screen, SWIDTH, SHEIGHT); + haloo3d_print_tracker pt; + char printbuf[8192]; + haloo3d_print_initdefault(&pt, printbuf, sizeof(printbuf)); + pt.fb = &screen; haloo3d_easytimer frametimer, drawtimer, sdltimer, filltimer, logictimer; haloo3d_easytimer_init(&frametimer, AVGWEIGHT); @@ -178,14 +204,40 @@ int main() { // int argc, char **argv) { haloo3d_easytimer_init(&filltimer, AVGWEIGHT); haloo3d_easytimer_init(&logictimer, AVGWEIGHT); - eprintf("Initialized screen buffers and timers\n"); + render_context context; + context.windowclear = 0xF000; + context.nearclip = INIT_NEARCLIP; + context.farclip = INIT_FARCLIP; + context.fov = INIT_FOV; + haloo3d_fb_init(&context.window, WIDTH, HEIGHT); + + eprintf("Initialized screen buffers, context, and timers\n"); tecs ecs; + ecs.delta_s = 0; tecs_init(&ecs); + int tecs_size = sizeof(tecs); + + struct vec3 defup; + vec3(defup.v, 0, 1, 0); + + ecs_eid playerid = tecs_newentity(&ecs, 0); + ECS_SETCOMPONENT(&ecs, playerid, ecs_placement){ + .pos = {.x = 0, .y = 10, .z = 0}, .up = defup}; + ECS_SETCOMPONENT(&ecs, playerid, ecs_movement){.pos = INIT_PLAYERSPEED}; + ECS_SETCOMPONENT(&ecs, playerid, ecs_rotation){.yaw = 0, + .pitch = CAM_INITPITCH}; + ECS_SETCOMPONENT(&ecs, playerid, ecs_rendercontext) & context; + ecs_placement *playerpos = &ECS_GETCOMPONENT(&ecs, playerid, ecs_placement); + + eprintf("Setup ECS system (%d bytes)\n", tecs_size); + + // clock_t previous_clock = 0, this_clock; // MAIN LOOP while (1) { haloo3d_easytimer_start(&frametimer); + haloo3d_print_refresh(&pt); do { unigi_event_get(&event); @@ -204,29 +256,35 @@ int main() { // int argc, char **argv) { } } while (event.type != unigi_enum_event_none); + // this_clock = clock(); + // ECS logic (which includes rendering) - ECS_RUNSYSTEM2(&ecs, sys_rotation, ecs_placement, ecs_rotation); - ECS_RUNSYSTEM2(&ecs, sys_movement, ecs_placement, ecs_movement); - ECS_RUNSYSTEM2(&ecs, sys_rendercontext, ecs_rendercontext, ecs_placement); - ECS_RUNSYSTEM2(&ecs, sys_renderobject, ecs_placement, ecs_object); + if (ecs.delta_s) { + // ecs.delta_s = (mfloat_t)(this_clock - previous_clock) / CLOCKS_PER_SEC; + ECS_RUNSYSTEM2(&ecs, sys_rotation, ecs_placement, ecs_rotation); + ECS_RUNSYSTEM3(&ecs, sys_movement, ecs_placement, ecs_movement, tecs); + ECS_RUNSYSTEM2(&ecs, sys_rendercontext, ecs_rendercontext, ecs_placement); + ECS_RUNSYSTEM2(&ecs, sys_renderobject, ecs_placement, ecs_object); + } + + // previous_clock = this_clock; // Scale 3D into final buffer haloo3d_easytimer_start(&filltimer); - haloo3d_fb_fill(&screen, &screen3d); + haloo3d_fb_fill(&screen, &context.window); haloo3d_easytimer_end(&filltimer); - /* - haloo3d_print(&render.tprint, - "Pframe: %05.2f (%05.2f)\nPSDLFl: %05.2f " - "(%05.2f)\nFill: %05.2f " - "(%05.2f)\nLogic: %05.2f (%05.2f)\nTris: %d / %d\nVerts: " - "%d\nWState: %d", - frametimer.last * 1000, frametimer.sum * 1000, + // clang-format off + haloo3d_print(&pt, + "Pframe: %05.2f (%05.2f) DT: %0.3f\n" + "PSDLFl: %05.2f (%05.2f)\n" + "Fill: %05.2f (%05.2f)\n" + "PlPos: %05.2f (%05.2f)\n", + frametimer.last * 1000, frametimer.sum * 1000, ecs.delta_s, sdltimer.last * 1000, sdltimer.sum * 1000, filltimer.last * 1000, filltimer.sum * 1000, - logictimer.last * 1000, logictimer.sum * 1000, totaldrawn, - render.totalfaces, render.totalverts, wstate.state); - */ + playerpos->pos.x, playerpos->pos.z); + // clang-format on // Finally, actually put buffer onto screen haloo3d_easytimer_start(&sdltimer); @@ -242,10 +300,11 @@ int main() { // int argc, char **argv) { if (waittime > 0) { unigi_time_sleep(waittime * unigi_time_clocks_per_s); } + ecs.delta_s = frametimer.last + waittime; } haloo3d_fb_free(&screen); - haloo3d_fb_free(&screen3d); + haloo3d_fb_free(&context.window); haloo3d_easystore_deleteallobj(&storage, haloo3d_obj_free); haloo3d_easystore_deletealltex(&storage, haloo3d_fb_free); } diff --git a/terrain_ecstypes.h b/terrain_ecstypes.h index 6ed270b..d79c515 100644 --- a/terrain_ecstypes.h +++ b/terrain_ecstypes.h @@ -12,7 +12,7 @@ typedef struct { // struct vec4 precalcs[H3D_OBJ_MAXVERTICES]; // haloo3d_facef outfaces[H3D_FACEF_MAXCLIP]; // haloo3d_perspective(render.perspective, fov, ASPECT, NEARCLIP, FARCLIP); - mfloat_t precalc_perspective[MAT4_SIZE]; + // mfloat_t precalc_perspective[MAT4_SIZE]; mfloat_t precalc_screen[MAT4_SIZE]; mfloat_t precalc_halfwidth; // Optimization for reducing calcs per tri mfloat_t precalc_halfheight; // Optimization for reducing calcs per tri @@ -100,6 +100,7 @@ typedef struct { // Setup ECS system for our game ECS_START(tecs) +float delta_s; // Store delta time in ecs ECS_COMPONENT(ecs_rendercontext); ECS_COMPONENT(ecs_object); ECS_COMPONENT(ecs_placement); @@ -107,6 +108,9 @@ ECS_COMPONENT(ecs_rotation); ECS_COMPONENT(ecs_movement); ECS_END(tecs) +ECS_FN_INIT(tecs) +ECS_FN_NEWENTITY(tecs) + // And then a copy of the components here... that sucksssss ECS_CID(ecs_rendercontext, 0); ECS_CID(ecs_object, 1);