Paintings ALMOST worked
This commit is contained in:
parent
29c5ece6da
commit
aa0c785a49
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,6 +5,7 @@ ignore/
|
|||||||
*.obj
|
*.obj
|
||||||
*.cam
|
*.cam
|
||||||
*.tar.gz
|
*.tar.gz
|
||||||
|
*.Identifier
|
||||||
callgrind.*
|
callgrind.*
|
||||||
|
|
||||||
# Images
|
# Images
|
||||||
|
53
ecs2.h
53
ecs2.h
@ -11,41 +11,64 @@
|
|||||||
#define ECS_MAXENTITIES 1024
|
#define ECS_MAXENTITIES 1024
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ECS_MAXCTYPES 63 // uint64 bits minus one
|
// We reserve one slot to automatically point back to the ecs system.
|
||||||
|
// This is the unusable 64th ID = 63 (your ids should start from 0)
|
||||||
|
#define ECS_MAXCTYPES 63
|
||||||
|
// The self flag is an ID that will get you back a component that is
|
||||||
|
// the ecs system itself. It is ALSO used to identify is an entity is
|
||||||
|
// valid, as ALL entities will implicitly have the ECS component
|
||||||
|
#define ECS_SELFFLAG (1ULL << ECS_MAXCTYPES)
|
||||||
|
|
||||||
typedef unsigned long long ecs_cid;
|
typedef unsigned long long ecs_cid;
|
||||||
typedef int ecs_eid;
|
typedef int ecs_eid;
|
||||||
|
|
||||||
#define ECS_START(name) \
|
#define ECS_START(name) \
|
||||||
typedef struct { \
|
typedef struct name name; \
|
||||||
|
struct name { \
|
||||||
ecs_cid entities[ECS_MAXENTITIES]; \
|
ecs_cid entities[ECS_MAXENTITIES]; \
|
||||||
ecs_eid entitytop;
|
ecs_eid entitytop; \
|
||||||
|
name *c_##name[ECS_MAXENTITIES];
|
||||||
|
|
||||||
#define ECS_END(name) \
|
#define ECS_END(name) \
|
||||||
} \
|
} \
|
||||||
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)); } \
|
||||||
|
/* Create an entity with the given base components (usually 0) */ \
|
||||||
static ecs_eid name##_newentity(name *_ecs, ecs_cid basecomponents) { \
|
static ecs_eid name##_newentity(name *_ecs, ecs_cid basecomponents) { \
|
||||||
for (int i = 0; i < ECS_MAXENTITIES; i++) { \
|
for (int i = 0; i < ECS_MAXENTITIES; i++) { \
|
||||||
ecs_eid id = _ecs->entitytop++; \
|
ecs_eid id = _ecs->entitytop; \
|
||||||
|
_ecs->entitytop = (_ecs->entitytop + 1) % ECS_MAXENTITIES; \
|
||||||
if (_ecs->entities[id] == 0) { \
|
if (_ecs->entities[id] == 0) { \
|
||||||
_ecs->entities[id] = (1ULL << ECS_MAXCTYPES) | basecomponents; \
|
_ecs->entities[id] = ECS_SELFFLAG | basecomponents; \
|
||||||
|
_ecs->c_##name[id] = _ecs; \
|
||||||
return id; \
|
return id; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
return -1; \
|
return -1; \
|
||||||
} \
|
} \
|
||||||
|
/* Delete an entity by eid from the given ecs sys */ \
|
||||||
static void name##_deleteentity(name *_ecs, ecs_eid eid) { \
|
static void name##_deleteentity(name *_ecs, ecs_eid eid) { \
|
||||||
if (eid >= 0 && eid < ECS_MAXENTITIES) \
|
if (eid >= 0 && eid < ECS_MAXENTITIES) \
|
||||||
_ecs->entities[eid] = 0; \
|
_ecs->entities[eid] = 0; \
|
||||||
} \
|
} \
|
||||||
|
/* Whether an entity matches a given list of components by flag */ \
|
||||||
static int name##_match(name *_ecs, ecs_eid _eid, ecs_cid _comps) { \
|
static int name##_match(name *_ecs, ecs_eid _eid, ecs_cid _comps) { \
|
||||||
ecs_cid _realcomps = (1ULL << ECS_MAXCTYPES) | _comps; \
|
ecs_cid _realcomps = ECS_SELFFLAG | _comps; \
|
||||||
return (_ecs->entities[_eid] & _realcomps) == _realcomps; \
|
return (_ecs->entities[_eid] & _realcomps) == _realcomps; \
|
||||||
}
|
} \
|
||||||
|
/* 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];
|
#define ECS_COMPONENT(type) type c_##type[ECS_MAXENTITIES];
|
||||||
|
|
||||||
|
// Define the CIDs necessary to access a component (each component MUST
|
||||||
|
// have a unique id and I can't do that inside a macro without requiring
|
||||||
|
// extensions)
|
||||||
#define ECS_CID(type, id) \
|
#define ECS_CID(type, id) \
|
||||||
const int type##_id = id; \
|
const int type##_id = id; \
|
||||||
const ecs_cid type##_fl = (1ULL << id);
|
const ecs_cid type##_fl = (1ULL << id);
|
||||||
@ -116,4 +139,18 @@ typedef int ecs_eid;
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add a system function which automatically calls your given function with
|
||||||
|
// pre-pulled items from the entity component arrays. The new function is
|
||||||
|
// named the same as the old one, just with _run appeneded
|
||||||
|
#define ECS_SYSTEM6(ecsname, fname, type1, type2, type3, type4, type5, type6) \
|
||||||
|
void fname##_run(ecsname *_ecs, ecs_eid eid) { \
|
||||||
|
ecs_cid _ecsflags = type1##_fl | type2##_fl | type3##_fl | type4##_fl | \
|
||||||
|
type5##_fl | type6##_fl; \
|
||||||
|
if (ecsname##_match(_ecs, eid, _ecsflags)) { \
|
||||||
|
fname(_ecs->c_##type1 + eid, _ecs->c_##type2 + eid, \
|
||||||
|
_ecs->c_##type3 + eid, _ecs->c_##type4 + eid, \
|
||||||
|
_ecs->c_##type5 + eid, _ecs->c_##type6 + eid); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
2
haloo3d
2
haloo3d
@ -1 +1 @@
|
|||||||
Subproject commit 8d814bd4abae2fb0113e5675f838ed2caa4e938f
|
Subproject commit 96dbee2942ae8b3d09302a24b075024c8134bb55
|
347
maze.c
347
maze.c
@ -9,8 +9,11 @@
|
|||||||
#include "unigi/unigi.headers/src/main.h"
|
#include "unigi/unigi.headers/src/main.h"
|
||||||
#include "unigi/unigi.platform.sdl1/src/main.c"
|
#include "unigi/unigi.platform.sdl1/src/main.c"
|
||||||
|
|
||||||
|
#define ECS_MAXENTITIES 100
|
||||||
|
|
||||||
#include "ecs2.h"
|
#include "ecs2.h"
|
||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
|
#include "maze_ecstypes.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@ -20,7 +23,7 @@
|
|||||||
#define WIDTH 320
|
#define WIDTH 320
|
||||||
#define HEIGHT 200
|
#define HEIGHT 200
|
||||||
#define ASPECT ((float)WIDTH / HEIGHT)
|
#define ASPECT ((float)WIDTH / HEIGHT)
|
||||||
#define SCREENSCALE 2
|
#define SCREENSCALE 1
|
||||||
#define SWIDTH (WIDTH * SCREENSCALE)
|
#define SWIDTH (WIDTH * SCREENSCALE)
|
||||||
#define SHEIGHT (HEIGHT * SCREENSCALE)
|
#define SHEIGHT (HEIGHT * SCREENSCALE)
|
||||||
#define NEARCLIP 0.01
|
#define NEARCLIP 0.01
|
||||||
@ -29,8 +32,9 @@
|
|||||||
#define AVGWEIGHT 0.85
|
#define AVGWEIGHT 0.85
|
||||||
|
|
||||||
// Game options
|
// Game options
|
||||||
#define MAZESIZE 15
|
#define MAZESIZE 5
|
||||||
#define HSCALE 1.5
|
#define HSCALE 1.5
|
||||||
|
#define PAINTINGODDS 2
|
||||||
|
|
||||||
// Maze grows in the positive direction
|
// Maze grows in the positive direction
|
||||||
#define MAZENORTH 1
|
#define MAZENORTH 1
|
||||||
@ -51,6 +55,8 @@
|
|||||||
#define STACKPUSH(s, t, v) s[t++] = v;
|
#define STACKPUSH(s, t, v) s[t++] = v;
|
||||||
|
|
||||||
#define ENDTEXTURE "resources/mazeend.ppm"
|
#define ENDTEXTURE "resources/mazeend.ppm"
|
||||||
|
#define PAINTINGTEXTURE "resources/specwall.ppm"
|
||||||
|
#define PAINTINGNAME "painting"
|
||||||
|
|
||||||
// Store all the values users can change at the beginning
|
// Store all the values users can change at the beginning
|
||||||
float ditherstart = -1;
|
float ditherstart = -1;
|
||||||
@ -229,18 +235,63 @@ void maze_generate(uint8_t *maze, int size, struct vec2i *start,
|
|||||||
free(mazestack);
|
free(mazestack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void maze_wall_generate(uint8_t *maze, int size, haloo3d_obj *obj) {
|
// int rand_painting(int size) {
|
||||||
|
// return (rand() % ()) == 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
void create_painting(struct vec2i mazepos, uint8_t dir,
|
||||||
|
haloo3d_easyinstancer *ins, mecs *ecs, ecs_world *world) {
|
||||||
|
// Create the painting render instance, set up the ecs instance, etc.
|
||||||
|
haloo3d_obj_instance *painting = haloo3d_easyinstantiate(ins, PAINTINGNAME);
|
||||||
|
ecs_eid id = mecs_newentity(ecs, 0);
|
||||||
|
ECS_SETCOMPONENT(ecs, id, ecs_syncgrow){.obj = painting,
|
||||||
|
.scale = &world->scaleto,
|
||||||
|
.basescale = 1,
|
||||||
|
.timer = &world->scaletimer};
|
||||||
|
ECS_SETCOMPONENT(ecs, id, ecs_dieoninit){
|
||||||
|
.obj = painting, .render = ins->render, .ws = world->state};
|
||||||
|
// Fix up some things based on dir.
|
||||||
|
switch (dir) {
|
||||||
|
case DIRNORTH:
|
||||||
|
mazepos.y++;
|
||||||
|
break;
|
||||||
|
case DIREAST: // East also needs the rotation from west
|
||||||
|
mazepos.x++;
|
||||||
|
// fall through
|
||||||
|
case DIRWEST:
|
||||||
|
vec3(painting->lookvec.v, 1, 0, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// OK now that it's setup, we need to put it in the right spot and scale it
|
||||||
|
vec3(painting->pos.v, mazepos.x * world->state->cellsize, 0,
|
||||||
|
mazepos.y * world->state->cellsize);
|
||||||
|
vec3(painting->scale.v, HSCALE, world->scaleto, HSCALE);
|
||||||
|
// rotation is around the left edge. That's both where we put it AND
|
||||||
|
// where the painting rotates around.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate walls AND create paintings. Kind of doing too much
|
||||||
|
void maze_wall_generate(uint8_t *maze, int size, haloo3d_obj *obj,
|
||||||
|
haloo3d_easyinstancer *ins, mecs *ecs,
|
||||||
|
ecs_world *world) {
|
||||||
// Reset ALL walls
|
// Reset ALL walls
|
||||||
obj->numfaces = 0;
|
obj->numfaces = 0;
|
||||||
// Simple: for each cell, we check if north or east is a wall. If so,
|
// Simple: for each cell, we check if north or east is a wall. If so,
|
||||||
// generate it. Also, generate walls for the south and west global wall
|
// generate it. Also, generate walls for the south and west global wall
|
||||||
for (int y = 0; y < size; y++) {
|
for (int y = 0; y < size; y++) {
|
||||||
for (int x = 0; x < size; x++) {
|
for (int x = 0; x < size; x++) {
|
||||||
|
struct vec2i mazepos = {.x = x, .y = y};
|
||||||
if (!maze_connected(maze, x, y, size, DIREAST)) {
|
if (!maze_connected(maze, x, y, size, DIREAST)) {
|
||||||
haloo3d_gen_grid_quad(obj, x, y, dirtovec(DIREAST));
|
haloo3d_gen_grid_quad(obj, x, y, dirtovec(DIREAST));
|
||||||
|
if ((rand() % PAINTINGODDS) == 0) {
|
||||||
|
create_painting(mazepos, DIREAST, ins, ecs, world);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!maze_connected(maze, x, y, size, DIRNORTH)) {
|
if (!maze_connected(maze, x, y, size, DIRNORTH)) {
|
||||||
haloo3d_gen_grid_quad(obj, x, y, dirtovec(DIRNORTH));
|
haloo3d_gen_grid_quad(obj, x, y, dirtovec(DIRNORTH));
|
||||||
|
if ((rand() % PAINTINGODDS) == 0) {
|
||||||
|
create_painting(mazepos, DIRNORTH, ins, ecs, world);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,21 +301,33 @@ void maze_wall_generate(uint8_t *maze, int size, haloo3d_obj *obj) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Turning into a blob? IDK. Maybe certain things should be
|
// // A simple linked list of objects
|
||||||
// global state, which is this.
|
// struct objlist {
|
||||||
typedef struct {
|
// haloo3d_obj_instance *obj;
|
||||||
// float timedelta;
|
// struct objlist *next;
|
||||||
int fps;
|
// };
|
||||||
uint8_t state;
|
//
|
||||||
uint8_t maze[MAZESIZE * MAZESIZE];
|
// // Add a new link at the given elem
|
||||||
// int size;
|
// struct objlist *objlist_add(struct objlist *elem, haloo3d_obj_instance *obj)
|
||||||
// A suggested start and end. The end is the actual
|
// {
|
||||||
// end, where we put the ending indicator
|
// mallocordie(elem->next, sizeof(struct objlist *));
|
||||||
struct vec2i start;
|
// elem->next->obj = obj;
|
||||||
struct vec2i end;
|
// elem->next->next = NULL;
|
||||||
// Some simple calcs for you to use
|
// return elem->next;
|
||||||
mfloat_t cellsize;
|
// }
|
||||||
} worldstate;
|
//
|
||||||
|
// // Free every single element starting at head
|
||||||
|
// void objlist_free(struct objlist *head, haloo3d_easyrender *r) {
|
||||||
|
// // void (*freefunc)(haloo3d_obj_instance *obj)) {
|
||||||
|
// if (head) {
|
||||||
|
// objlist_free(head->next, r);
|
||||||
|
// haloo3d_easyrender_deleteinstance(r, head->obj);
|
||||||
|
// // if (freefunc) {
|
||||||
|
// // freefunc(head->obj);
|
||||||
|
// //}
|
||||||
|
// free(head);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
WSTATE_INIT = 0,
|
WSTATE_INIT = 0,
|
||||||
@ -274,61 +337,6 @@ enum {
|
|||||||
WSTATE_SPINDOWN = 4
|
WSTATE_SPINDOWN = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
// A component that stores a position and a facing direction
|
|
||||||
// as an angle
|
|
||||||
typedef struct {
|
|
||||||
struct vec3 pos;
|
|
||||||
struct vec2 rot; // x is yaw, y is pitch
|
|
||||||
} ecs_placement;
|
|
||||||
|
|
||||||
// A component which links back to a camera
|
|
||||||
typedef struct {
|
|
||||||
haloo3d_camera *camera;
|
|
||||||
} ecs_camera;
|
|
||||||
|
|
||||||
// A component which allows automatic navigation
|
|
||||||
// of position through the use of timers.
|
|
||||||
typedef struct {
|
|
||||||
struct vec3 dest;
|
|
||||||
int timer;
|
|
||||||
} ecs_autonav;
|
|
||||||
|
|
||||||
// A component which allows automatic rotation
|
|
||||||
// through the use of timers.
|
|
||||||
typedef struct {
|
|
||||||
struct vec2 dest; // x is yaw, y is pitch
|
|
||||||
int timer;
|
|
||||||
} ecs_autorotate;
|
|
||||||
|
|
||||||
// Component which enables synchronized scale y from 0 to 1 or 1 to 0. It is
|
|
||||||
// expected that an external source is modifying the value
|
|
||||||
typedef struct {
|
|
||||||
haloo3d_obj_instance *obj;
|
|
||||||
mfloat_t *scale;
|
|
||||||
// When scales are set, they're multiplied by this
|
|
||||||
mfloat_t basescale;
|
|
||||||
int *timer;
|
|
||||||
} ecs_syncgrow;
|
|
||||||
|
|
||||||
// A billboard for OUR system, which does not look up or down at the target. As
|
|
||||||
// such, no matter what the lookat is set to, y is always going to be equal to
|
|
||||||
// the y of the instance, so it appears to be looking "straight"
|
|
||||||
typedef struct {
|
|
||||||
haloo3d_obj_instance *obj;
|
|
||||||
struct vec3 *lookat;
|
|
||||||
} ecs_billboard;
|
|
||||||
|
|
||||||
// A component which holds onto data specifically for world
|
|
||||||
// entities. You can think of it as private data so people
|
|
||||||
// can't poke at the worldstate data
|
|
||||||
typedef struct {
|
|
||||||
worldstate *state;
|
|
||||||
haloo3d_obj *wallmodel;
|
|
||||||
haloo3d_obj_instance *endobj;
|
|
||||||
int scaletimer;
|
|
||||||
mfloat_t scaleto;
|
|
||||||
} ecs_world;
|
|
||||||
|
|
||||||
void sys_billboard(ecs_billboard *bb) {
|
void sys_billboard(ecs_billboard *bb) {
|
||||||
// In our current system, the lookvec is the direction it wants to face, not a
|
// In our current system, the lookvec is the direction it wants to face, not a
|
||||||
// "lookat" point. To lookat something, you simply get the vector pointing
|
// "lookat" point. To lookat something, you simply get the vector pointing
|
||||||
@ -397,12 +405,27 @@ void sys_camera(ecs_camera *cam, ecs_placement *p) {
|
|||||||
cam->camera->pitch = p->rot.y;
|
cam->camera->pitch = p->rot.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sys_world(ecs_world *w) {
|
void sys_dieoninit(ecs_dieoninit *die, mecs **ecs) {
|
||||||
|
if (die->ws->state == WSTATE_INIT) {
|
||||||
|
ecs_eid id = mecs_eid(ecs);
|
||||||
|
eprintf("DELETING SELF: %d\n", id);
|
||||||
|
// Trivially delete the entity from the renderer
|
||||||
|
haloo3d_easyrender_deleteinstance(die->render, die->obj);
|
||||||
|
// Delete ourselves from existence
|
||||||
|
mecs_deleteentity(*ecs, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sys_world(ecs_world *w, mecs **ecs) {
|
||||||
const int spinspeed = w->state->fps * 4.0 / (5 * speed);
|
const int spinspeed = w->state->fps * 4.0 / (5 * speed);
|
||||||
switch (w->state->state) {
|
switch (w->state->state) {
|
||||||
case WSTATE_INIT:
|
case WSTATE_INIT:
|
||||||
maze_generate(w->state->maze, MAZESIZE, &w->state->start, &w->state->end);
|
// We don't need to free anything created from previous runs; they delete
|
||||||
maze_wall_generate(w->state->maze, MAZESIZE, w->wallmodel);
|
// themselves
|
||||||
|
maze_generate(w->state->maze, w->state->size, &w->state->start,
|
||||||
|
&w->state->end);
|
||||||
|
maze_wall_generate(w->state->maze, w->state->size, w->wallmodel,
|
||||||
|
w->instancer, *ecs, w);
|
||||||
eprintf("INIT MAZE COMPLETE, spinning up walls\n");
|
eprintf("INIT MAZE COMPLETE, spinning up walls\n");
|
||||||
maze_to_pos(&w->state->end, w->endobj->pos.v, w->state->cellsize);
|
maze_to_pos(&w->state->end, w->endobj->pos.v, w->state->cellsize);
|
||||||
w->state->state = WSTATE_SPINUP;
|
w->state->state = WSTATE_SPINUP;
|
||||||
@ -441,18 +464,6 @@ enum {
|
|||||||
SAI_GAMEPLAY,
|
SAI_GAMEPLAY,
|
||||||
};
|
};
|
||||||
|
|
||||||
// State for tracking a smart ai moving through the maze.
|
|
||||||
typedef struct {
|
|
||||||
uint8_t state;
|
|
||||||
// uint8_t rotstate;
|
|
||||||
uint8_t dir;
|
|
||||||
uint32_t timer;
|
|
||||||
mfloat_t rotchange;
|
|
||||||
struct vec2i mpos;
|
|
||||||
worldstate *ws;
|
|
||||||
haloo3d_obj_instance *startmarker;
|
|
||||||
} ecs_smartai;
|
|
||||||
|
|
||||||
int smartai_mazeend(ecs_smartai *smartai) {
|
int smartai_mazeend(ecs_smartai *smartai) {
|
||||||
if (smartai->mpos.x == smartai->ws->end.x &&
|
if (smartai->mpos.x == smartai->ws->end.x &&
|
||||||
smartai->mpos.y == smartai->ws->end.y) {
|
smartai->mpos.y == smartai->ws->end.y) {
|
||||||
@ -464,8 +475,8 @@ int smartai_mazeend(ecs_smartai *smartai) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sys_smartai(ecs_smartai *smartai, ecs_placement *p,
|
void sys_smartai(ecs_smartai *smartai, ecs_placement *p, ecs_autonav *anav,
|
||||||
ecs_autonav *anav, ecs_autorotate *arot) {
|
ecs_autorotate *arot) {
|
||||||
const int actiontime = smartai->ws->fps / (2 * speed);
|
const int actiontime = smartai->ws->fps / (2 * speed);
|
||||||
const int rotdelaytime = actiontime / 2; // 2 * actiontime / 5;
|
const int rotdelaytime = actiontime / 2; // 2 * actiontime / 5;
|
||||||
switch (smartai->state) {
|
switch (smartai->state) {
|
||||||
@ -475,8 +486,8 @@ static void sys_smartai(ecs_smartai *smartai, ecs_placement *p,
|
|||||||
if (smartai->ws->state == WSTATE_SPINUP) {
|
if (smartai->ws->state == WSTATE_SPINUP) {
|
||||||
smartai->mpos = smartai->ws->start;
|
smartai->mpos = smartai->ws->start;
|
||||||
smartai->dir =
|
smartai->dir =
|
||||||
maze_longesthallway(smartai->ws->maze, MAZESIZE, smartai->ws->start.x,
|
maze_longesthallway(smartai->ws->maze, smartai->ws->size,
|
||||||
smartai->ws->start.y);
|
smartai->ws->start.x, smartai->ws->start.y);
|
||||||
maze_to_pos(&smartai->ws->start, p->pos.v, smartai->ws->cellsize);
|
maze_to_pos(&smartai->ws->start, p->pos.v, smartai->ws->cellsize);
|
||||||
p->rot.x = dirtoyaw(smartai->dir);
|
p->rot.x = dirtoyaw(smartai->dir);
|
||||||
// Move startmarker to in front of player.
|
// Move startmarker to in front of player.
|
||||||
@ -527,7 +538,7 @@ static void sys_smartai(ecs_smartai *smartai, ecs_placement *p,
|
|||||||
}
|
}
|
||||||
// Player can only move forward if there's nothing in front of them
|
// Player can only move forward if there's nothing in front of them
|
||||||
if (maze_connected(smartai->ws->maze, smartai->mpos.x, smartai->mpos.y,
|
if (maze_connected(smartai->ws->maze, smartai->mpos.x, smartai->mpos.y,
|
||||||
MAZESIZE, smartai->dir)) {
|
smartai->ws->size, smartai->dir)) {
|
||||||
struct vec2i movement = dirtovec(smartai->dir);
|
struct vec2i movement = dirtovec(smartai->dir);
|
||||||
smartai->mpos.x += movement.x;
|
smartai->mpos.x += movement.x;
|
||||||
smartai->mpos.y += movement.y;
|
smartai->mpos.y += movement.y;
|
||||||
@ -538,12 +549,12 @@ static void sys_smartai(ecs_smartai *smartai, ecs_placement *p,
|
|||||||
// Figure out if a rotation should be scheduled
|
// Figure out if a rotation should be scheduled
|
||||||
if (!(smartai->mpos.x == smartai->ws->end.x &&
|
if (!(smartai->mpos.x == smartai->ws->end.x &&
|
||||||
smartai->mpos.y == smartai->ws->end.y)) {
|
smartai->mpos.y == smartai->ws->end.y)) {
|
||||||
// Ok we might be moving, we might not be. Let's go ahead and calculate
|
// Ok we might be moving, we might not be. Let's go ahead and
|
||||||
// rotation based on the FUTURE direction we want to turn.
|
// calculate rotation based on the FUTURE direction we want to turn.
|
||||||
uint8_t rightdir = TURNRIGHT(smartai->dir);
|
uint8_t rightdir = TURNRIGHT(smartai->dir);
|
||||||
uint8_t leftdir = TURNLEFT(smartai->dir);
|
uint8_t leftdir = TURNLEFT(smartai->dir);
|
||||||
if (maze_connected(smartai->ws->maze, smartai->mpos.x, smartai->mpos.y,
|
if (maze_connected(smartai->ws->maze, smartai->mpos.x, smartai->mpos.y,
|
||||||
MAZESIZE, rightdir)) {
|
smartai->ws->size, rightdir)) {
|
||||||
// Always choose right over left
|
// Always choose right over left
|
||||||
smartai->rotchange += MPI_2;
|
smartai->rotchange += MPI_2;
|
||||||
smartai->timer = rotdelaytime;
|
smartai->timer = rotdelaytime;
|
||||||
@ -553,7 +564,8 @@ static void sys_smartai(ecs_smartai *smartai, ecs_placement *p,
|
|||||||
// This while loop lets us turn around if necessary, so reaching a
|
// This while loop lets us turn around if necessary, so reaching a
|
||||||
// dead end isn't super painful waiting for two rotations
|
// dead end isn't super painful waiting for two rotations
|
||||||
while (!maze_connected(smartai->ws->maze, smartai->mpos.x,
|
while (!maze_connected(smartai->ws->maze, smartai->mpos.x,
|
||||||
smartai->mpos.y, MAZESIZE, smartai->dir)) {
|
smartai->mpos.y, smartai->ws->size,
|
||||||
|
smartai->dir)) {
|
||||||
// We seem to have reached a wall. Do we need to turn ALL the way
|
// We seem to have reached a wall. Do we need to turn ALL the way
|
||||||
// around? We only move left if the player can't move forward or
|
// around? We only move left if the player can't move forward or
|
||||||
// right
|
// right
|
||||||
@ -570,30 +582,8 @@ static void sys_smartai(ecs_smartai *smartai, ecs_placement *p,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup ECS system for our game
|
ECS_SYSTEM2(mecs, sys_world, ecs_world, mecs);
|
||||||
ECS_START(mecs)
|
ECS_SYSTEM2(mecs, sys_dieoninit, ecs_dieoninit, mecs);
|
||||||
ECS_COMPONENT(ecs_world);
|
|
||||||
ECS_COMPONENT(ecs_autonav);
|
|
||||||
ECS_COMPONENT(ecs_autorotate);
|
|
||||||
ECS_COMPONENT(ecs_placement);
|
|
||||||
ECS_COMPONENT(ecs_camera);
|
|
||||||
ECS_COMPONENT(ecs_smartai);
|
|
||||||
ECS_COMPONENT(ecs_syncgrow);
|
|
||||||
ECS_COMPONENT(ecs_billboard);
|
|
||||||
ECS_END(mecs)
|
|
||||||
|
|
||||||
// And then a copy of the components here... that sucksssss
|
|
||||||
ECS_CID(ecs_worldstate, 0);
|
|
||||||
ECS_CID(ecs_world, 1);
|
|
||||||
ECS_CID(ecs_autonav, 2);
|
|
||||||
ECS_CID(ecs_autorotate, 3);
|
|
||||||
ECS_CID(ecs_placement, 4);
|
|
||||||
ECS_CID(ecs_camera, 5);
|
|
||||||
ECS_CID(ecs_smartai, 6);
|
|
||||||
ECS_CID(ecs_syncgrow, 7);
|
|
||||||
ECS_CID(ecs_billboard, 8);
|
|
||||||
|
|
||||||
ECS_SYSTEM1(mecs, sys_world, ecs_world);
|
|
||||||
ECS_SYSTEM1(mecs, sys_syncgrow, ecs_syncgrow);
|
ECS_SYSTEM1(mecs, sys_syncgrow, ecs_syncgrow);
|
||||||
ECS_SYSTEM1(mecs, sys_billboard, ecs_billboard);
|
ECS_SYSTEM1(mecs, sys_billboard, ecs_billboard);
|
||||||
ECS_SYSTEM2(mecs, sys_autonav, ecs_autonav, ecs_placement);
|
ECS_SYSTEM2(mecs, sys_autonav, ecs_autonav, ecs_placement);
|
||||||
@ -602,6 +592,41 @@ ECS_SYSTEM2(mecs, sys_camera, ecs_camera, ecs_placement);
|
|||||||
ECS_SYSTEM4(mecs, sys_smartai, ecs_smartai, ecs_placement, ecs_autonav,
|
ECS_SYSTEM4(mecs, sys_smartai, ecs_smartai, ecs_placement, ecs_autonav,
|
||||||
ecs_autorotate);
|
ecs_autorotate);
|
||||||
|
|
||||||
|
// typedef struct {
|
||||||
|
// haloo3d_easyrender *render;
|
||||||
|
// haloo3d_obj_instance *paintings[MAXPAINTINGS];
|
||||||
|
// ecs_eid paintingecs[MAXPAINTINGS];
|
||||||
|
// haloo3d_fb *texture;
|
||||||
|
// haloo3d_obj *model;
|
||||||
|
// mecs *ecs;
|
||||||
|
// mfloat_t *scaleto;
|
||||||
|
// int *scaletimer;
|
||||||
|
// int numpaintings;
|
||||||
|
// } paintingmanager;
|
||||||
|
//
|
||||||
|
// void pm_add_painting(paintingmanager *pm) {
|
||||||
|
// if (pm->numpaintings < MAXPAINTINGS) {
|
||||||
|
// pm->paintings[pm->numpaintings] =
|
||||||
|
// haloo3d_easyrender_addinstance(pm->render, pm->model, pm->texture);
|
||||||
|
// ecs_eid id = mecs_newentity(pm->ecs, 0);
|
||||||
|
// ECS_SETCOMPONENT(pm->ecs, id,
|
||||||
|
// ecs_syncgrow){.obj = pm->paintings[pm->numpaintings],
|
||||||
|
// .scale = pm->scaleto,
|
||||||
|
// .basescale = 1,
|
||||||
|
// .timer = pm->scaletimer};
|
||||||
|
// pm->paintingecs[pm->numpaintings] = id;
|
||||||
|
// pm->numpaintings++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void pm_clear_all(paintingmanager * pm) {
|
||||||
|
// for(int i = 0; i < pm->numpaintings; i++) {
|
||||||
|
// mecs_deleteentity(pm->ecs, pm->paintingecs[i]);
|
||||||
|
// haloo3d_easyrender_deleteinstance(pm->render, pm->paintings[i]);
|
||||||
|
// }
|
||||||
|
// pm->numpaintings = 0;
|
||||||
|
// }
|
||||||
|
|
||||||
void init_floortexture(haloo3d_fb *floort) {
|
void init_floortexture(haloo3d_fb *floort) {
|
||||||
uint16_t cols[1] = {0xFD93};
|
uint16_t cols[1] = {0xFD93};
|
||||||
haloo3d_fb_init_tex(floort, 64, 64);
|
haloo3d_fb_init_tex(floort, 64, 64);
|
||||||
@ -679,6 +704,10 @@ void init_endtexture(haloo3d_fb *endt) {
|
|||||||
haloo3d_img_totransparent(endt, haloo3d_fb_get(endt, 0, 0));
|
haloo3d_img_totransparent(endt, haloo3d_fb_get(endt, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init_paintingtexture(haloo3d_fb *endt) {
|
||||||
|
haloo3d_img_loadppmfile(endt, PAINTINGTEXTURE);
|
||||||
|
}
|
||||||
|
|
||||||
void init_billboard(haloo3d_obj_instance *bb, mfloat_t scale) {
|
void init_billboard(haloo3d_obj_instance *bb, mfloat_t scale) {
|
||||||
// Haven't actually generated the object yet, oops. We don't let billboards
|
// Haven't actually generated the object yet, oops. We don't let billboards
|
||||||
// all share the same model, as they might require slightly different
|
// all share the same model, as they might require slightly different
|
||||||
@ -711,6 +740,56 @@ void init_mazeinstances(haloo3d_obj_instance *floori,
|
|||||||
ceili->pos.y = 1;
|
ceili->pos.y = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Given a pointer into an obj, fill it with everything required to make
|
||||||
|
// the painting that clips with the wall (it's a cube)
|
||||||
|
void create_paintingobj(haloo3d_obj *obj) {
|
||||||
|
// 2 for each face; we have 4 faces (top and bottom don't need anything)
|
||||||
|
haloo3d_gen_obj_prealloc(obj, 8, 8, 8);
|
||||||
|
// ppm is 128x128 but 1 pixel along the top is the wall side
|
||||||
|
const mfloat_t ptextop = 1.0 / 128.0;
|
||||||
|
const mfloat_t thickness = 1.0 / 64.0;
|
||||||
|
// box will be aligned along x/y axis, so it will be "facing" the negative z
|
||||||
|
// dir like most other models. Box is topleft, topright, bottomleft,
|
||||||
|
// bottomright, then same on other side. Box is not centered around 0,
|
||||||
|
// intstead it is the same as a wall where iti starts from y=0 and goes to
|
||||||
|
// y=1
|
||||||
|
vec4(obj->vertices[0].v, 0, 1, thickness, 1);
|
||||||
|
vec4(obj->vertices[1].v, 1, 1, thickness, 1);
|
||||||
|
vec4(obj->vertices[2].v, 0, 0, thickness, 1);
|
||||||
|
vec4(obj->vertices[3].v, 1, 0, thickness, 1);
|
||||||
|
vec4(obj->vertices[4].v, 0, 1, -thickness, 1);
|
||||||
|
vec4(obj->vertices[5].v, 1, 1, -thickness, 1);
|
||||||
|
vec4(obj->vertices[6].v, 0, 0, -thickness, 1);
|
||||||
|
vec4(obj->vertices[7].v, 1, 0, -thickness, 1);
|
||||||
|
// Now, the vtexture points. Some might be dupes, I don't care. First 4 are
|
||||||
|
// the painting texture, next 4 are the wall texture
|
||||||
|
vec3(obj->vtexture[0].v, 0.001, 0.999 - ptextop, 0);
|
||||||
|
vec3(obj->vtexture[1].v, 0.999, 0.999 - ptextop, 0);
|
||||||
|
vec3(obj->vtexture[2].v, 0.001, 0.001, 0);
|
||||||
|
vec3(obj->vtexture[3].v, 0.999, 0.001, 0);
|
||||||
|
vec3(obj->vtexture[4].v, 0.001, 0.999, 0);
|
||||||
|
vec3(obj->vtexture[5].v, 0.999, 0.999, 0);
|
||||||
|
vec3(obj->vtexture[6].v, 0.001, 1.0 - ptextop, 0);
|
||||||
|
vec3(obj->vtexture[7].v, 0.999, 1.0 - ptextop, 0);
|
||||||
|
// Preconstruct the simplified format of the face vertices and vtexture.
|
||||||
|
// First 3 are vertices, next are vtexture
|
||||||
|
// clang-format: off
|
||||||
|
const uint8_t f[8][6] = {
|
||||||
|
{0, 2, 3, 0, 2, 3}, // front face
|
||||||
|
{0, 3, 1, 0, 3, 1}, {5, 7, 6, 0, 2, 3}, // back face
|
||||||
|
{5, 6, 4, 0, 3, 1}, {1, 3, 7, 4, 6, 7}, // front side
|
||||||
|
{1, 7, 5, 4, 7, 5}, {4, 6, 2, 4, 6, 7}, // back side
|
||||||
|
{4, 2, 0, 4, 7, 5},
|
||||||
|
};
|
||||||
|
// clang-format: on
|
||||||
|
for (int fi = 0; fi < obj->numfaces; fi++) {
|
||||||
|
for (int v = 0; v < 3; v++) {
|
||||||
|
obj->faces[fi][v].posi = f[fi][v];
|
||||||
|
obj->faces[fi][v].texi = f[fi][v + 3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main() { // int argc, char **argv) {
|
int main() { // int argc, char **argv) {
|
||||||
|
|
||||||
haloo3d_easystore storage;
|
haloo3d_easystore storage;
|
||||||
@ -725,6 +804,8 @@ int main() { // int argc, char **argv) {
|
|||||||
render.tprint.fb = &screen;
|
render.tprint.fb = &screen;
|
||||||
eprintf("Initialized renderer\n");
|
eprintf("Initialized renderer\n");
|
||||||
|
|
||||||
|
haloo3d_easyinstancer instancer = {.storage = &storage, .render = &render};
|
||||||
|
|
||||||
haloo3d_easytimer frametimer, sdltimer, filltimer, logictimer;
|
haloo3d_easytimer frametimer, sdltimer, filltimer, logictimer;
|
||||||
haloo3d_easytimer_init(&frametimer, AVGWEIGHT);
|
haloo3d_easytimer_init(&frametimer, AVGWEIGHT);
|
||||||
haloo3d_easytimer_init(&sdltimer, AVGWEIGHT);
|
haloo3d_easytimer_init(&sdltimer, AVGWEIGHT);
|
||||||
@ -736,31 +817,40 @@ int main() { // int argc, char **argv) {
|
|||||||
haloo3d_obj *wallo = haloo3d_easystore_addobj(&storage, "walls");
|
haloo3d_obj *wallo = haloo3d_easystore_addobj(&storage, "walls");
|
||||||
haloo3d_obj *starto = haloo3d_easystore_addobj(&storage, "start");
|
haloo3d_obj *starto = haloo3d_easystore_addobj(&storage, "start");
|
||||||
haloo3d_obj *endo = haloo3d_easystore_addobj(&storage, "end");
|
haloo3d_obj *endo = haloo3d_easystore_addobj(&storage, "end");
|
||||||
|
haloo3d_obj *paintingo = haloo3d_easystore_addobj(&storage, PAINTINGNAME);
|
||||||
haloo3d_fb *floort = haloo3d_easystore_addtex(&storage, "floor");
|
haloo3d_fb *floort = haloo3d_easystore_addtex(&storage, "floor");
|
||||||
haloo3d_fb *ceilt = haloo3d_easystore_addtex(&storage, "ceiling");
|
haloo3d_fb *ceilt = haloo3d_easystore_addtex(&storage, "ceiling");
|
||||||
haloo3d_fb *wallt = haloo3d_easystore_addtex(&storage, "walls");
|
haloo3d_fb *wallt = haloo3d_easystore_addtex(&storage, "walls");
|
||||||
haloo3d_fb *startt = haloo3d_easystore_addtex(&storage, "start");
|
haloo3d_fb *startt = haloo3d_easystore_addtex(&storage, "start");
|
||||||
haloo3d_fb *endt = haloo3d_easystore_addtex(&storage, "end");
|
haloo3d_fb *endt = haloo3d_easystore_addtex(&storage, "end");
|
||||||
|
haloo3d_fb *paintingt = haloo3d_easystore_addtex(&storage, PAINTINGNAME);
|
||||||
|
|
||||||
haloo3d_gen_plane(planeo, MAZESIZE);
|
haloo3d_gen_plane(planeo, MAZESIZE);
|
||||||
haloo3d_gen_grid(wallo, MAZESIZE, 0);
|
haloo3d_gen_grid(wallo, MAZESIZE, 0);
|
||||||
|
create_paintingobj(paintingo);
|
||||||
init_floortexture(floort);
|
init_floortexture(floort);
|
||||||
init_ceilingtexture(ceilt);
|
init_ceilingtexture(ceilt);
|
||||||
init_walltexture(wallt);
|
init_walltexture(wallt);
|
||||||
init_starttexture(startt);
|
init_starttexture(startt);
|
||||||
init_endtexture(endt);
|
init_endtexture(endt);
|
||||||
|
init_paintingtexture(paintingt);
|
||||||
|
|
||||||
eprintf("Initialized models and textures\n");
|
eprintf("Initialized models and textures\n");
|
||||||
|
|
||||||
worldstate wstate;
|
worldstate wstate;
|
||||||
memset(&wstate, 0, sizeof(worldstate));
|
memset(&wstate, 0, sizeof(worldstate));
|
||||||
|
// The maze won't change size (for now), so we can set it here to some
|
||||||
|
// constant array
|
||||||
|
uint8_t maze[MAZESIZE * MAZESIZE];
|
||||||
|
wstate.size = MAZESIZE;
|
||||||
|
wstate.maze = maze;
|
||||||
wstate.fps = fps;
|
wstate.fps = fps;
|
||||||
wstate.state = WSTATE_INIT;
|
wstate.state = WSTATE_INIT;
|
||||||
wstate.cellsize = HSCALE;
|
wstate.cellsize = HSCALE;
|
||||||
|
|
||||||
// Lighting. Note that for performance, the lighting is always calculated
|
// Lighting. Note that for performance, the lighting is always calculated
|
||||||
// against the base model, and is thus not realistic if the object rotates in
|
// against the base model, and is thus not realistic if the object rotates
|
||||||
// the world. This can be fixed easily, since each object gets its own
|
// in the world. This can be fixed easily, since each object gets its own
|
||||||
// lighting vector, which can easily be rotated in the opposite direction of
|
// lighting vector, which can easily be rotated in the opposite direction of
|
||||||
// the model
|
// the model
|
||||||
struct vec3 light;
|
struct vec3 light;
|
||||||
@ -779,7 +869,7 @@ int main() { // int argc, char **argv) {
|
|||||||
init_mazeinstances(floori, ceili, walli);
|
init_mazeinstances(floori, ceili, walli);
|
||||||
init_billboard(starti, 1.0);
|
init_billboard(starti, 1.0);
|
||||||
init_billboard(endi, 0.25);
|
init_billboard(endi, 0.25);
|
||||||
eprintf("Setup all object instances\n");
|
eprintf("Setup all static object instances\n");
|
||||||
|
|
||||||
unigi_type_event event;
|
unigi_type_event event;
|
||||||
unigi_type_resolution res;
|
unigi_type_resolution res;
|
||||||
@ -817,11 +907,15 @@ int main() { // int argc, char **argv) {
|
|||||||
// Set up ECS entities. For this game, we mostly have global entities.
|
// Set up ECS entities. For this game, we mostly have global entities.
|
||||||
mecs ecs;
|
mecs ecs;
|
||||||
mecs_init(&ecs);
|
mecs_init(&ecs);
|
||||||
|
eprintf("ECS sys size: %zu\n", sizeof(mecs));
|
||||||
|
|
||||||
ecs_eid worldid = mecs_newentity(&ecs, 0);
|
ecs_eid worldid = mecs_newentity(&ecs, 0);
|
||||||
eprintf("World eid: %d\n", worldid);
|
eprintf("World eid: %d\n", worldid);
|
||||||
ECS_SETCOMPONENT(&ecs, worldid, ecs_world){
|
ECS_SETCOMPONENT(&ecs, worldid, ecs_world){.state = &wstate,
|
||||||
.state = &wstate, .wallmodel = wallo, .endobj = endi, .scaletimer = 0};
|
.wallmodel = wallo,
|
||||||
|
.endobj = endi,
|
||||||
|
.scaletimer = 0,
|
||||||
|
.instancer = &instancer};
|
||||||
ecs_world *eworld = ecs.c_ecs_world + worldid;
|
ecs_world *eworld = ecs.c_ecs_world + worldid;
|
||||||
|
|
||||||
// Setup some dynamic objects
|
// Setup some dynamic objects
|
||||||
@ -909,6 +1003,7 @@ int main() { // int argc, char **argv) {
|
|||||||
sys_autorotate_run(&ecs, i);
|
sys_autorotate_run(&ecs, i);
|
||||||
sys_camera_run(&ecs, i);
|
sys_camera_run(&ecs, i);
|
||||||
sys_billboard_run(&ecs, i);
|
sys_billboard_run(&ecs, i);
|
||||||
|
sys_dieoninit_run(&ecs, i);
|
||||||
}
|
}
|
||||||
haloo3d_easytimer_end(&logictimer);
|
haloo3d_easytimer_end(&logictimer);
|
||||||
|
|
||||||
|
125
maze_ecstypes.h
Normal file
125
maze_ecstypes.h
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#ifndef __MAZE_ECSTYPES
|
||||||
|
#define __MAZE_ECSTYPES
|
||||||
|
|
||||||
|
#include "ecs2.h"
|
||||||
|
#include "haloo3d/haloo3d.h"
|
||||||
|
#include "haloo3d/haloo3dex_easy.h"
|
||||||
|
|
||||||
|
// Turning into a blob? IDK. Maybe certain things should be
|
||||||
|
// global state, which is this.
|
||||||
|
typedef struct {
|
||||||
|
// float timedelta;
|
||||||
|
int fps;
|
||||||
|
uint8_t state;
|
||||||
|
uint8_t *maze; //[MAZESIZE * MAZESIZE];
|
||||||
|
int size; // The length of an edge, guaranteed to be a square
|
||||||
|
// A suggested start and end. The end is the actual
|
||||||
|
// end, where we put the ending indicator
|
||||||
|
struct vec2i start;
|
||||||
|
struct vec2i end;
|
||||||
|
// Some simple calcs for you to use
|
||||||
|
mfloat_t cellsize;
|
||||||
|
} worldstate;
|
||||||
|
|
||||||
|
// A component that stores a position and a facing direction
|
||||||
|
// as an angle
|
||||||
|
typedef struct {
|
||||||
|
struct vec3 pos;
|
||||||
|
struct vec2 rot; // x is yaw, y is pitch
|
||||||
|
} ecs_placement;
|
||||||
|
|
||||||
|
// A component which links back to a camera
|
||||||
|
typedef struct {
|
||||||
|
haloo3d_camera *camera;
|
||||||
|
} ecs_camera;
|
||||||
|
|
||||||
|
// A component which allows automatic navigation
|
||||||
|
// of position through the use of timers.
|
||||||
|
typedef struct {
|
||||||
|
struct vec3 dest;
|
||||||
|
int timer;
|
||||||
|
} ecs_autonav;
|
||||||
|
|
||||||
|
// A component which allows automatic rotation
|
||||||
|
// through the use of timers.
|
||||||
|
typedef struct {
|
||||||
|
struct vec2 dest; // x is yaw, y is pitch
|
||||||
|
int timer;
|
||||||
|
} ecs_autorotate;
|
||||||
|
|
||||||
|
// Component which enables synchronized scale y from 0 to 1 or 1 to 0. It is
|
||||||
|
// expected that an external source is modifying the value
|
||||||
|
typedef struct {
|
||||||
|
haloo3d_obj_instance *obj;
|
||||||
|
mfloat_t *scale;
|
||||||
|
// When scales are set, they're multiplied by this
|
||||||
|
mfloat_t basescale;
|
||||||
|
int *timer;
|
||||||
|
} ecs_syncgrow;
|
||||||
|
|
||||||
|
// A billboard for OUR system, which does not look up or down at the target. As
|
||||||
|
// such, no matter what the lookat is set to, y is always going to be equal to
|
||||||
|
// the y of the instance, so it appears to be looking "straight"
|
||||||
|
typedef struct {
|
||||||
|
haloo3d_obj_instance *obj;
|
||||||
|
struct vec3 *lookat;
|
||||||
|
} ecs_billboard;
|
||||||
|
|
||||||
|
// A component which holds onto data specifically for world
|
||||||
|
// entities. You can think of it as private data so people
|
||||||
|
// can't poke at the worldstate data
|
||||||
|
typedef struct {
|
||||||
|
worldstate *state;
|
||||||
|
haloo3d_obj *wallmodel;
|
||||||
|
haloo3d_obj_instance *endobj;
|
||||||
|
haloo3d_easyinstancer *instancer;
|
||||||
|
// paintingmanager * pm;
|
||||||
|
int scaletimer;
|
||||||
|
mfloat_t scaleto;
|
||||||
|
} ecs_world;
|
||||||
|
|
||||||
|
// State for tracking a smart ai moving through the maze.
|
||||||
|
typedef struct {
|
||||||
|
uint8_t state;
|
||||||
|
uint8_t dir;
|
||||||
|
uint32_t timer;
|
||||||
|
mfloat_t rotchange;
|
||||||
|
struct vec2i mpos;
|
||||||
|
worldstate *ws;
|
||||||
|
haloo3d_obj_instance *startmarker;
|
||||||
|
} ecs_smartai;
|
||||||
|
|
||||||
|
// A component which allows an object instance to die
|
||||||
|
// when the maze is initiailized.
|
||||||
|
typedef struct {
|
||||||
|
haloo3d_obj_instance *obj;
|
||||||
|
haloo3d_easyrender *render;
|
||||||
|
worldstate *ws;
|
||||||
|
} ecs_dieoninit;
|
||||||
|
|
||||||
|
// Setup ECS system for our game
|
||||||
|
ECS_START(mecs)
|
||||||
|
ECS_COMPONENT(ecs_world);
|
||||||
|
ECS_COMPONENT(ecs_autonav);
|
||||||
|
ECS_COMPONENT(ecs_autorotate);
|
||||||
|
ECS_COMPONENT(ecs_placement);
|
||||||
|
ECS_COMPONENT(ecs_camera);
|
||||||
|
ECS_COMPONENT(ecs_smartai);
|
||||||
|
ECS_COMPONENT(ecs_syncgrow);
|
||||||
|
ECS_COMPONENT(ecs_billboard);
|
||||||
|
ECS_COMPONENT(ecs_dieoninit);
|
||||||
|
ECS_END(mecs)
|
||||||
|
|
||||||
|
// And then a copy of the components here... that sucksssss
|
||||||
|
ECS_CID(ecs_worldstate, 0);
|
||||||
|
ECS_CID(ecs_world, 1);
|
||||||
|
ECS_CID(ecs_autonav, 2);
|
||||||
|
ECS_CID(ecs_autorotate, 3);
|
||||||
|
ECS_CID(ecs_placement, 4);
|
||||||
|
ECS_CID(ecs_camera, 5);
|
||||||
|
ECS_CID(ecs_smartai, 6);
|
||||||
|
ECS_CID(ecs_syncgrow, 7);
|
||||||
|
ECS_CID(ecs_billboard, 8);
|
||||||
|
ECS_CID(ecs_dieoninit, 9);
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user