Mouse implemented!

This commit is contained in:
Carlos Sanchez 2024-08-22 15:30:42 -04:00
parent 2a68ada51e
commit 2da6fca442
3 changed files with 121 additions and 16 deletions

116
maze.c
View File

@ -18,10 +18,10 @@
// INteresting flags for performance comparisons
#define FASTFILL
#define WIDTH 320
#define HEIGHT 200
#define WIDTH 640
#define HEIGHT 400
#define ASPECT ((float)WIDTH / HEIGHT)
#define SCREENSCALE 3
#define SCREENSCALE 2
#define SWIDTH (WIDTH * SCREENSCALE)
#define SHEIGHT (HEIGHT * SCREENSCALE)
#define NEARCLIP 0.01
@ -33,6 +33,8 @@
#define MAZESIZE 15
#define MAZEENDGAP (MAZESIZE / 5)
#define HSCALE 1.5
#define MOUSESCALE 0.25
#define MOUSESPEED 0.45 // Player speed is 0.5. Lower is faster
#define PAINTINGODDS 20
// Some arbitrarily large number, up to you
#define MAZEHRAND 100
@ -62,6 +64,7 @@
#define ENDTEXTURE "resources/mazeend.ppm"
#define PAINTINGTEXTURE "resources/specwall.ppm"
#define MOUSETEXTURE "resources/mouse.ppm"
#define PAINTINGNAME "painting"
// Store all the values users can change at the beginning
@ -379,11 +382,14 @@ void sys_autorotate(ecs_autorotate *arot, ecs_placement *p) {
// update camera with placement value on entity
void sys_camera(ecs_camera *cam, ecs_placement *p) {
cam->camera->pos = p->pos;
cam->camera->yaw = p->rot.x;
cam->camera->pitch = p->rot.y;
(*cam)->pos = p->pos;
(*cam)->yaw = p->rot.x;
(*cam)->pitch = p->rot.y;
}
// do we do anything with the lookvec? idk...
void sys_object(ecs_object *obj, ecs_placement *p) { (*obj)->pos = p->pos; }
void sys_dieoninit(ecs_dieoninit *die, mecs **ecs) {
if (die->ws->state == WSTATE_INIT) {
ecs_eid id = mecs_eid(ecs);
@ -467,7 +473,7 @@ void sys_smartai(ecs_smartai *smartai, ecs_placement *p, ecs_autonav *anav,
smartai->dir =
maze_longesthallway(smartai->ws->maze, smartai->ws->size,
smartai->ws->start.x, smartai->ws->start.y);
maze_to_pos(&smartai->ws->start, p->pos.v, smartai->ws->cellsize);
maze_to_pos(&smartai->mpos, p->pos.v, smartai->ws->cellsize);
p->rot.x = dirtoyaw(smartai->dir);
// Move startmarker to in front of player.
struct vec2i lookdir = dirtovec(smartai->dir);
@ -561,6 +567,62 @@ void sys_smartai(ecs_smartai *smartai, ecs_placement *p, ecs_autonav *anav,
}
}
void sys_mouseai(ecs_mouseai *mouseai, ecs_placement *p, ecs_autonav *anav) {
const int actiontime = fps * MOUSESPEED / speed;
switch (mouseai->state) {
case SAI_INIT: // Just reuse smartai state
// Here, we wait until the world state is spinup, in which
// case we can spawn and face
if (mouseai->ws->state == WSTATE_SPINUP) {
mouseai->mpos = (struct vec2i){.x = rand() % mouseai->ws->size,
.y = rand() % mouseai->ws->size};
mouseai->dir = 1;
maze_to_pos(&mouseai->mpos, p->pos.v, mouseai->ws->cellsize);
// Reset autonav + autorotate
anav->dest = p->pos;
anav->timer = 0;
mouseai->state = SAI_READY;
eprintf("MOUSE READY: %f %f, waiting for spinup\n", anav->dest.x,
anav->dest.z);
}
break;
case SAI_READY:
if (mouseai->ws->state == WSTATE_GAMEPLAY) {
mouseai->state = SAI_GAMEPLAY;
eprintf("MOUSE STARTING GAMEPLAY\n");
}
break;
case SAI_GAMEPLAY:
// Normal gameplay: move through the maze, etc.
if (mouseai->ws->state != WSTATE_GAMEPLAY) {
eprintf("GAMEPLAY OVER, MOUSE RESETTING\n");
mouseai->state = SAI_INIT;
anav->timer = 0; // Stop moving
return;
}
// Only decide to do things if you're not moving anymore. Movement is the
// most important thing
if (anav->timer == 0) {
eprintf("MOUSEAI DIR: %d POS: (%f, %f)\n", mouseai->dir, p->pos.x,
p->pos.z);
// Player can only move forward if there's nothing in front of them
if (maze_connected(mouseai->ws->maze, mouseai->mpos.x, mouseai->mpos.y,
mouseai->ws->size, mouseai->dir)) {
struct vec2i movement = dirtovec(mouseai->dir);
mouseai->mpos.x += movement.x;
mouseai->mpos.y += movement.y;
anav->timer = actiontime;
anav->dest.x = p->pos.x + mouseai->ws->cellsize * movement.x;
anav->dest.z = p->pos.z + mouseai->ws->cellsize * movement.y;
} else {
// Mouse only picks new direction if it can't move forward anymore
mouseai->dir = (1 << (rand() % 4));
}
}
break;
}
}
ECS_SYSTEM2(mecs, sys_world, ecs_world, mecs);
ECS_SYSTEM2(mecs, sys_dieoninit, ecs_dieoninit, mecs);
ECS_SYSTEM1(mecs, sys_syncgrow, ecs_syncgrow);
@ -568,8 +630,10 @@ ECS_SYSTEM1(mecs, sys_billboard, ecs_billboard);
ECS_SYSTEM2(mecs, sys_autonav, ecs_autonav, ecs_placement);
ECS_SYSTEM2(mecs, sys_autorotate, ecs_autorotate, ecs_placement);
ECS_SYSTEM2(mecs, sys_camera, ecs_camera, ecs_placement);
ECS_SYSTEM2(mecs, sys_object, ecs_object, ecs_placement);
ECS_SYSTEM4(mecs, sys_smartai, ecs_smartai, ecs_placement, ecs_autonav,
ecs_autorotate);
ECS_SYSTEM3(mecs, sys_mouseai, ecs_mouseai, ecs_placement, ecs_autonav);
void init_floortexture(haloo3d_fb *floort) {
uint16_t cols[1] = {0xFD93};
@ -652,6 +716,12 @@ void init_paintingtexture(haloo3d_fb *endt) {
haloo3d_img_loadppmfile(endt, PAINTINGTEXTURE);
}
void init_mousetexture(haloo3d_fb *mouset) {
haloo3d_img_loadppmfile(mouset, MOUSETEXTURE);
// Assume the corner of the image is the "transparent" color
haloo3d_img_totransparent(mouset, haloo3d_fb_get(mouset, 0, 0));
}
void init_billboard(haloo3d_obj_instance *bb, mfloat_t scale) {
// Haven't actually generated the object yet, oops. We don't let billboards
// all share the same model, as they might require slightly different
@ -761,12 +831,14 @@ int main() { // int argc, char **argv) {
haloo3d_obj *wallo = haloo3d_easystore_addobj(&storage, "walls");
haloo3d_obj *starto = haloo3d_easystore_addobj(&storage, "start");
haloo3d_obj *endo = haloo3d_easystore_addobj(&storage, "end");
haloo3d_obj *mouseo = haloo3d_easystore_addobj(&storage, "mouse");
haloo3d_obj *paintingo = haloo3d_easystore_addobj(&storage, PAINTINGNAME);
haloo3d_fb *floort = haloo3d_easystore_addtex(&storage, "floor");
haloo3d_fb *ceilt = haloo3d_easystore_addtex(&storage, "ceiling");
haloo3d_fb *wallt = haloo3d_easystore_addtex(&storage, "walls");
haloo3d_fb *startt = haloo3d_easystore_addtex(&storage, "start");
haloo3d_fb *endt = haloo3d_easystore_addtex(&storage, "end");
haloo3d_fb *mouset = haloo3d_easystore_addtex(&storage, "mouse");
haloo3d_fb *paintingt = haloo3d_easystore_addtex(&storage, PAINTINGNAME);
haloo3d_gen_plane(planeo, MAZESIZE);
@ -777,6 +849,7 @@ int main() { // int argc, char **argv) {
init_walltexture(wallt);
init_starttexture(startt);
init_endtexture(endt);
init_mousetexture(mouset);
init_paintingtexture(paintingt);
eprintf("Initialized models and textures\n");
@ -809,9 +882,14 @@ int main() { // int argc, char **argv) {
haloo3d_easyrender_addinstance(&render, starto, startt);
haloo3d_obj_instance *endi =
haloo3d_easyrender_addinstance(&render, endo, endt);
haloo3d_obj_instance *mousei =
haloo3d_easyrender_addinstance(&render, mouseo, mouset);
init_mazeinstances(floori, ceili, walli);
init_billboard(starti, 1.0);
init_billboard(endi, 0.25);
init_billboard(mousei, MOUSESCALE);
// Mouse should be near the floor
mousei->pos.y = MOUSESCALE;
eprintf("Setup all static object instances\n");
unigi_type_event event;
@ -863,9 +941,10 @@ int main() { // int argc, char **argv) {
// Setup some dynamic objects
ecs_eid wallid = mecs_newentity(&ecs, 0);
ECS_SETCOMPONENT(&ecs, wallid, ecs_syncgrow){.obj = walli,
ECS_SETCOMPONENT(&ecs, wallid, ecs_syncgrow){
.obj = walli,
.scale = &eworld->scaleto,
.basescale = 1,
.basescale = 1, // can't set to scale because hscale
.timer = &eworld->scaletimer};
ecs_eid startid = mecs_newentity(&ecs, 0);
ECS_SETCOMPONENT(&ecs, startid, ecs_syncgrow){.obj = starti,
@ -888,7 +967,7 @@ int main() { // int argc, char **argv) {
ECS_SETCOMPONENT(&ecs, playerid, ecs_placement){
.pos = render.camera.pos,
.rot = {.x = render.camera.yaw, .y = render.camera.pitch}};
ECS_SETCOMPONENT(&ecs, playerid, ecs_camera){.camera = &render.camera};
ECS_SETCOMPONENT(&ecs, playerid, ecs_camera) & render.camera;
ECS_SETCOMPONENT(&ecs, playerid, ecs_autonav){.timer = 0};
ECS_SETCOMPONENT(&ecs, playerid, ecs_autorotate){.timer = 0};
ECS_SETCOMPONENT(&ecs, playerid, ecs_smartai){.state = SAI_INIT,
@ -897,6 +976,21 @@ int main() { // int argc, char **argv) {
.timer = 0,
.startmarker = starti};
ecs_eid mouseid = mecs_newentity(&ecs, 0);
eprintf("Mouse eid: %d\n", mouseid);
ECS_SETCOMPONENT(&ecs, mouseid,
ecs_placement){.pos = mousei->pos}; // we don't use rot
ECS_SETCOMPONENT(&ecs, mouseid, ecs_autonav){.timer = 0};
ECS_SETCOMPONENT(&ecs, mouseid, ecs_object) mousei;
ECS_SETCOMPONENT(&ecs, mouseid, ecs_mouseai){.state = SAI_INIT,
.ws = &wstate};
ECS_SETCOMPONENT(&ecs, mouseid, ecs_billboard){.obj = mousei,
.lookat = &render.camera.pos};
ECS_SETCOMPONENT(&ecs, mouseid, ecs_syncgrow){.obj = mousei,
.scale = &eworld->scaleto,
.basescale = mousei->scale.x,
.timer = &eworld->scaletimer};
// -----------------------------------
// Actual rendering
// -----------------------------------
@ -941,10 +1035,12 @@ int main() { // int argc, char **argv) {
for (int i = 0; i < ECS_MAXENTITIES; i++) {
sys_world_run(&ecs, i);
sys_smartai_run(&ecs, i);
sys_mouseai_run(&ecs, i);
sys_syncgrow_run(&ecs, i);
sys_autonav_run(&ecs, i);
sys_autorotate_run(&ecs, i);
sys_camera_run(&ecs, i);
sys_object_run(&ecs, i);
sys_billboard_run(&ecs, i);
sys_dieoninit_run(&ecs, i);
}

View File

@ -26,10 +26,8 @@ typedef struct {
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;
typedef haloo3d_camera *ecs_camera;
typedef haloo3d_obj_instance *ecs_object;
// A component which allows automatic navigation
// of position through the use of timers.
@ -87,6 +85,13 @@ typedef struct {
haloo3d_obj_instance *startmarker;
} ecs_smartai;
typedef struct {
uint8_t state;
uint8_t dir;
struct vec2i mpos;
worldstate *ws;
} ecs_mouseai;
// A component which allows an object instance to die
// when the maze is initiailized.
typedef struct {
@ -106,6 +111,8 @@ ECS_COMPONENT(ecs_smartai);
ECS_COMPONENT(ecs_syncgrow);
ECS_COMPONENT(ecs_billboard);
ECS_COMPONENT(ecs_dieoninit);
ECS_COMPONENT(ecs_mouseai);
ECS_COMPONENT(ecs_object);
ECS_END(mecs)
// And then a copy of the components here... that sucksssss
@ -119,5 +126,7 @@ ECS_CID(ecs_smartai, 6);
ECS_CID(ecs_syncgrow, 7);
ECS_CID(ecs_billboard, 8);
ECS_CID(ecs_dieoninit, 9);
ECS_CID(ecs_mouseai, 10);
ECS_CID(ecs_object, 11);
#endif

BIN
resources/mouse.ppm Normal file

Binary file not shown.