Really messed up those directions...

This commit is contained in:
Carlos Sanchez 2024-08-18 01:26:07 -04:00
parent 9717b88e22
commit 754286cabe
2 changed files with 77 additions and 99 deletions

6
ecs.h
View File

@ -102,10 +102,10 @@ static int haloo_ecs_newcomponent(haloo_ecs *ecs, void *component) {
// components MUST be passed in the EXACT order the function expects them!
#define HECS_RUNSYS(ecs, eid, func, ...) \
{ \
hecs_cidt _hecstemp[] = {__VA_ARGS__}; \
const hecs_cidt _hecstemp[] = {__VA_ARGS__}; \
const int _hecsnumargs = sizeof(_hecstemp) / sizeof(hecs_cidt); \
hecs_cidt _hecsflags = 0; \
for (int _hecsi = 0; _hecsi < sizeof(_hecstemp) / sizeof(hecs_cidt); \
_hecsi++) { \
for (int _hecsi = 0; _hecsi < _hecsnumargs; _hecsi++) { \
_hecsflags |= _hecstemp[_hecsi]; \
} \
if (haloo_ecs_match(ecs, eid, _hecsflags)) { \

170
maze.c
View File

@ -18,10 +18,10 @@
// INteresting flags for performance comparisons
#define FASTFILL
#define WIDTH 640
#define HEIGHT 400
#define WIDTH 320
#define HEIGHT 200
#define ASPECT ((float)WIDTH / HEIGHT)
#define SCREENSCALE 1
#define SCREENSCALE 3
#define SWIDTH (WIDTH * SCREENSCALE)
#define SHEIGHT (HEIGHT * SCREENSCALE)
#define NEARCLIP 0.01
@ -30,78 +30,69 @@
#define AVGWEIGHT 0.85
// Game options
#define MAZESIZE 31
#define MAZESIZE 15
#define HSCALE 2.0
// Maze grows down and to the right.
#define MAZESOUTH 1
// Maze grows in the positive direction
#define MAZENORTH 1
#define MAZEEAST 2
#define MAZEVISIT 4
// When you rightshift these values, you "turn right"
#define DIRNORTH 8
#define DIREAST 4
#define DIRSOUTH 2
#define DIRWEST 1
#define STACKPUSH(s, t, v) s[t++] = v;
// everything in the maze is controlled by the CPU. As such, movement
// is as simple as "go here by this time". No need to complicate the
// components?
// Allows movement in 3 dimensions
// typedef struct {
// struct vec3 pos;
// struct vec3 vel;
// } ecs_movement;
// Allows rotational movement only with yaw and pitch (in that order)
// typedef struct {
// struct vec2 rot;
// struct vec2 rotvel;
// } ecs_rotmovement;
struct vec2i dirtovec(uint8_t dir) {
struct vec2i result;
switch (dir) {
case DIREAST:
vec2i(result.v, 1, 0);
break;
case DIRWEST:
vec2i(result.v, -1, 0);
break;
case DIRNORTH:
vec2i(result.v, 0, 1);
break;
case DIRSOUTH:
vec2i(result.v, 0, -1);
break;
default:
vec2i(result.v, 0, 0);
}
return result;
}
// A general position within the maze, and a pointer to the maze itself.
// Can be used to traverse the maze
typedef struct {
uint8_t *maze;
int size;
struct vec2i pos; // tile position within maze
struct vec2i dir; // facing dir
int size;
uint8_t dir; // facing dir (see DIREAST/DIRSOUTH/etc);
} ecs_maze;
// A component which can track progress towards some destination. Each
// frame it is expected that the timer will decrease, and that on 0,
// the destination should be reached
// typedef struct {
// int timer;
// struct vec3 dst;
// } ecs_destination;
// // A component that simply points back to an object instance. If combined
// // with movement, will pull pos from objin at start of frame, then write
// // pos back to obj at end of frame.
// typedef haloo3d_obj_instance *ecs_objin;
//
// // Like objin, this component simply points to a camera. It will set the
// // position AND rotation at the start of the frame, and pull the pos/
// // rotation back into the camera at the end.
// typedef haloo3d_camera *ecs_camera;
// typedef struct vec2i ecs_cpos;
// typedef struct vec2i ecs_npos;
// typedef struct vec2i ecs_cdir;
// typedef struct vec2i ecs_ndir;
// typedef haloo3d_obj_instance *ecs_objin;
// typedef haloo3d_camera *ecs_cam;
int maze_visited(uint8_t *maze, int x, int y, int size) {
return (maze[x + y * size] & MAZEVISIT) > 0;
}
int maze_connected(uint8_t *maze, int x, int y, int size, struct vec2i move) {
if (move.x == 1) {
int maze_connected(uint8_t *maze, int x, int y, int size, uint8_t move) {
if (move == DIREAST) {
return (maze[x + y * size] & MAZEEAST) == 0;
} else if (move.x == -1) {
} else if (move == DIRWEST) {
return (x > 0) && ((maze[x - 1 + y * size] & MAZEEAST) == 0);
} else if (move.y == 1) {
return (maze[x + y * size] & MAZESOUTH) == 0;
} else if (move.y == -1) {
return (y > 0) && ((maze[x + (y - 1) * size] & MAZESOUTH) == 0);
} else if (move == DIRNORTH) {
return (maze[x + y * size] & MAZENORTH) == 0;
} else if (move == DIRSOUTH) {
return (y > 0) && ((maze[x + (y - 1) * size] & MAZENORTH) == 0);
}
return 0;
}
@ -111,7 +102,7 @@ int maze_connected(uint8_t *maze, int x, int y, int size, struct vec2i move) {
void maze_generate(uint8_t *maze, int size) {
const int mazesquare = (size) * (size);
for (int i = 0; i < mazesquare; i++) {
maze[i] = MAZESOUTH | MAZEEAST;
maze[i] = MAZENORTH | MAZEEAST;
}
int *mazestack;
mallocordie(mazestack, sizeof(int) * mazesquare);
@ -124,7 +115,8 @@ void maze_generate(uint8_t *maze, int size) {
int mazetop = 0;
STACKPUSH(mazestack, mazetop, x + y * size);
maze[x + y * size] |= MAZEVISIT;
struct vec2i visitable[4];
// struct vec2i visitable[4];
uint8_t visitable[4];
int visittop = 0;
// Now let's make a maze!
@ -134,37 +126,34 @@ void maze_generate(uint8_t *maze, int size) {
x = mazestack[mazetop] % size;
y = mazestack[mazetop] / size;
if (x > 0 && !maze_visited(maze, x - 1, y, size)) {
visitable[visittop].x = -1;
visitable[visittop++].y = 0;
visitable[visittop++] = DIRWEST;
}
if (x < size - 1 && !maze_visited(maze, x + 1, y, size)) {
visitable[visittop].x = 1;
visitable[visittop++].y = 0;
visitable[visittop++] = DIREAST;
}
if (y > 0 && !maze_visited(maze, x, y - 1, size)) {
visitable[visittop].x = 0;
visitable[visittop++].y = -1;
visitable[visittop++] = DIRSOUTH;
}
if (y < size - 1 && !maze_visited(maze, x, y + 1, size)) {
visitable[visittop].x = 0;
visitable[visittop++].y = 1;
visitable[visittop++] = DIRNORTH;
}
// You can generate a random location!
if (visittop) {
// Readd ourselves, we're moving
STACKPUSH(mazestack, mazetop, x + y * size);
struct vec2i movedir = visitable[rand() % visittop];
uint8_t dir = visitable[rand() % visittop];
struct vec2i movedir = dirtovec(dir);
int nx = x + movedir.x;
int ny = y + movedir.y;
// Trust that the visitable array is always valid
if (movedir.x == 1) { // Tear down east wall
if (dir == DIREAST) { // Tear down east wall
maze[x + y * size] &= ~MAZEEAST;
} else if (movedir.x == -1) { // Move left and tear down east wall
} else if (dir == DIRWEST) { // Move left and tear down east wall
maze[(x - 1) + y * size] &= ~MAZEEAST;
} else if (movedir.y == 1) { // tear down south wall
maze[x + y * size] &= ~MAZESOUTH;
} else if (movedir.y == -1) { // move up and tear down south wall
maze[x + (y - 1) * size] &= ~MAZESOUTH;
} else if (dir == DIRNORTH) { // tear down north wall
maze[x + y * size] &= ~MAZENORTH;
} else if (dir == DIRSOUTH) { // move down and tear down north wall
maze[x + (y - 1) * size] &= ~MAZENORTH;
}
// Push onto stack and set visited
STACKPUSH(mazestack, mazetop, nx + ny * size);
@ -176,30 +165,21 @@ void maze_generate(uint8_t *maze, int size) {
}
void maze_wall_generate(uint8_t *maze, int size, haloo3d_obj *obj) {
// Simple: for each cell, we check if south 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 north and west global wall
struct vec2i dir;
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
dir.x = 1;
dir.y = 0;
if (!maze_connected(maze, x, y, size, dir)) {
haloo3d_gen_grid_quad(obj, x, y, dir);
if (!maze_connected(maze, x, y, size, DIREAST)) {
haloo3d_gen_grid_quad(obj, x, y, dirtovec(DIREAST));
}
dir.x = 0;
dir.y = 1;
if (!maze_connected(maze, x, y, size, dir)) {
haloo3d_gen_grid_quad(obj, x, y, dir);
if (!maze_connected(maze, x, y, size, DIRNORTH)) {
haloo3d_gen_grid_quad(obj, x, y, dirtovec(DIRNORTH));
}
}
}
for (int i = 0; i < size; i++) {
dir.x = -1;
dir.y = 0;
haloo3d_gen_grid_quad(obj, 0, i, dir);
dir.x = 0;
dir.y = -1;
haloo3d_gen_grid_quad(obj, i, 0, dir);
haloo3d_gen_grid_quad(obj, i, 0, dirtovec(DIRSOUTH));
haloo3d_gen_grid_quad(obj, 0, i, dirtovec(DIRWEST));
}
}
@ -318,9 +298,9 @@ int main() { // int argc, char **argv) {
unigi_graphics_init();
unigi_window_create(res, "maze.exe"); // render.printbuf);
// render.camera.pos.y = 5;
// render.camera.pitch = 2.2;
// ceili->pos.y = -10;
render.camera.pos.y = 5;
render.camera.pitch = 2.2;
ceili->pos.y = -10;
haloo3d_debugconsole_set(&dc, "obj/ceil/pos_y.f", &ceili->pos.y);
@ -329,19 +309,20 @@ int main() { // int argc, char **argv) {
haloo_ecs_init(&ecs);
HECS_ADDNEWCOMPONENT(ecs_moveto, &ecs);
HECS_ADDNEWCOMPONENT(ecs_rotateto, &ecs);
// HECS_ADDNEWCOMPONENT(ecs_rotateto, &ecs);
HECS_ADDNEWCOMPONENT(ecs_maze, &ecs);
HECS_ADDNEWCOMPONENT(ecs_objin, &ecs);
HECS_ADDNEWCOMPONENT(ecs_camera, &ecs);
hecs_eidt playerid = haloo_ecs_newentity(&ecs, 0);
// struct vec2i playerstart = {.x = 0, .y = 0};
// struct vec2i playerface = {.x = 0, .y = -1};
HECS_SETCOMPONENT(ecs_moveto, &ecs, playerid){
.pos = render.camera.pos, .dst = render.camera.pos, .timer = 0};
HECS_SETCOMPONENT(ecs_maze, &ecs, playerid){};
//.maze = maze, .pos = playerstart, .size = MAZESIZE, .dir = DIRSOUTH};
HECS_SETCOMPONENT(ecs_camera, &ecs, playerid) & render.camera;
// HECS_SETCOMPONENT(ecs_cpos, &ecs, playerid){.x = 1, .y = 1};
// ecs_ndir_f);
// -----------------------------------
// Actual rendering
@ -383,12 +364,6 @@ int main() { // int argc, char **argv) {
HECS_RUNSYS(&ecs, i, sys_ecs_objin_moveto, ecs_objin_f, ecs_moveto_f);
HECS_RUNSYS(&ecs, i, sys_ecs_moveto, ecs_moveto_f);
HECS_RUNSYS(&ecs, i, sys_ecs_moveto_objin, ecs_moveto_f, ecs_objin_f);
// if (haloo_ecs_match(&ecs, i, ecs_moveto_f | ecs_objin_f)) {
// sys_ecs_objin_moveto(&ecs, i, ecs_objin_f, ecs_moveto_f);
// }
// if (haloo_ecs_match(&ecs, i, ecs_moveto_f)) {
// sys_ecs_moveto(&ecs, i, ecs_moveto_f);
// }
}
totaldrawn = 0;
@ -440,6 +415,9 @@ int main() { // int argc, char **argv) {
}
}
// Just to get the compiler to STOP COMPLAINING about unused
haloo_ecs_removeentity(&ecs, playerid); //, int eid)
haloo3d_easystore_deleteallobj(&storage, haloo3d_obj_free);
haloo3d_easystore_deletealltex(&storage, haloo3d_fb_free);
}