diff --git a/.gitignore b/.gitignore index c88df49..bce9b94 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ /sprites.o /dod /boids +/boids_main +/libboids.so diff --git a/Makefile b/Makefile index 7429197..3dd12f7 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CFLAGS=-g -fsanitize=address -Wall -Wextra -pedantic -O0 +CFLAGS=-g -fsanitize=address -fno-omit-frame-pointer -Wall -Wextra -pedantic -O0 CC=gcc .PHONY: build clean run all @@ -14,8 +14,11 @@ sprites.o: sprites.c sprites.h lib.h dod: dod.c ./lib/libraylib.a $(CC) $(CFLAGS) -Iinclude/ -lm dod.c -o dod ./lib/libraylib.a -boids: boids.c lib.h ./lib/libraylib.a - $(CC) $(CFLAGS) -Iinclude/ -lm boids.c -o boids ./lib/libraylib.a +boids_main: boids_main.c lib.h ./lib/libraylib.a + $(CC) $(CFLAGS) -Iinclude/ -lm $< -o $@ ./lib/libraylib.a + +libboids.so: boids_game.c boids_game.h lib.h + $(CC) $(CFLAGS) -Iinclude/ -lm -c $< -o $@ run: all ./main diff --git a/boids.c b/boids.c deleted file mode 100644 index d672d7b..0000000 --- a/boids.c +++ /dev/null @@ -1,87 +0,0 @@ -#include "include/raylib.h" -#include "include/raymath.h" -#include -#include -#include "lib.h" - -#define SCREEN_WIDTH 1024 -#define SCREEN_HEIGHT 768 -#define TARGET_FPS 60 -#define NUM_BOIDS 16 - -const float max_speed = 5.0f; -const float max_force = 0.05; - -typedef struct Boid { - Point position; - Vector2 acceleration; - Vector2 velocity; -} Boid; - -int main(void) { - InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Boids"); - - SetTargetFPS(TARGET_FPS); - - Boid *boids = calloc(NUM_BOIDS, sizeof(Boid)); - for (int i = 0; i < NUM_BOIDS; i++) { - Boid *boid = &boids[i]; - int rand_x = GetRandomValue(0, SCREEN_WIDTH); - int rand_y = GetRandomValue(0, SCREEN_HEIGHT); - boid->position = (Vector2){rand_x, rand_y}; - int rand_vx = GetRandomValue(0, 100); - int rand_vy = GetRandomValue(0, 100); - boid->velocity = (Vector2){rand_vx * 0.01f - 0.5f, rand_vy * 0.01f - 0.5f}; - boid->velocity = Vector2Scale(boid->velocity, 10.0f); - // int rand_ax = GetRandomValue(0, 100); - // int rand_ay = GetRandomValue(0, 100); - // boid->velocity = (Vector2){rand_ax * 0.01f - 0.5f, rand_ay * 0.01f - 0.5f}; - } - - PointOption target_pos = {0}; - - while (!WindowShouldClose()) { - float dt = GetFrameTime(); - - // Update - if (IsMouseButtonPressed(0)) { - Vector2 mouse_pos = GetMousePosition(); - target_pos = (PointOption){.tag = SOME, .some.point = mouse_pos}; - } - - - for (int i = 0; i < NUM_BOIDS; i++) { - Boid *boid = &boids[i]; - if (target_pos.tag == SOME) { - Vector2 desired = Vector2Subtract(target_pos.some.point, boid->position); - desired = Vector2Normalize(desired); - desired = Vector2Scale(desired, max_speed); - Vector2 steer = Vector2Subtract(desired, boid->velocity); - steer = Vector2ClampValue(steer, 0.0f, max_force); - boid->acceleration = Vector2Add(boid->acceleration, steer); - } - boid->velocity = Vector2Add(boid->velocity, boid->acceleration); - boid->velocity = Vector2ClampValue(boid->velocity, 0.0f, max_speed); - boid->position = Vector2Add(boid->position, boid->velocity); - } - - - BeginDrawing(); - { - ClearBackground(RAYWHITE); - // You can draw a triangle but you'd need to rotate all 3 vectors, and I don't - // want to get distracted with that - // DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, GREEN); - // DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, GREEN); - for (int i = 0; i < NUM_BOIDS; i++) { - Boid *boid = &boids[i]; - DrawCircle(boid->position.x, boid->position.y, 27, BLACK); - DrawCircle(boid->position.x, boid->position.y, 20, GREEN); - } - } - EndDrawing(); - } - - free(boids); - CloseWindow(); -} diff --git a/boids_game.c b/boids_game.c new file mode 100644 index 0000000..30402c0 --- /dev/null +++ b/boids_game.c @@ -0,0 +1,102 @@ +#include +#include "include/raylib.h" +#include "include/raymath.h" +#include "boids_game.h" +#include "lib.h" + +#define SCREEN_WIDTH 1300 +#define SCREEN_HEIGHT 1080 +#define NUM_BOIDS 16 + +typedef struct Boid { + Point position; + Vector2 acceleration; + Vector2 velocity; +} Boid; + +typedef struct GameState { + Boid *boids; + PointOption target_pos; + int num_boids; + float max_speed; + float max_force; +} GameState; + +GameState *init() { + GameState *state = malloc(sizeof(struct GameApi)); + state->num_boids = 16; + state->max_speed = 5.0f; + state->max_force = 0.05; + Boid *boids = malloc(state->num_boids * sizeof(Boid)); + state->boids = boids; + for (int i = 0; i < state->num_boids; i++) { + Boid *boid = &boids[i]; + int rand_x = GetRandomValue(0, SCREEN_WIDTH); + int rand_y = GetRandomValue(0, SCREEN_HEIGHT); + boid->position = (Vector2){rand_x, rand_y}; + int rand_vx = GetRandomValue(0, 100); + int rand_vy = GetRandomValue(0, 100); + boid->velocity = (Vector2){rand_vx * 0.01f - 0.5f, rand_vy * 0.01f - 0.5f}; + // boid->velocity = Vector2Scale(boid->velocity, 10.0f); + // int rand_ax = GetRandomValue(0, 100); + // int rand_ay = GetRandomValue(0, 100); + // boid->velocity = (Vector2){rand_ax * 0.01f - 0.5f, rand_ay * 0.01f - 0.5f}; + boid->acceleration = (Vector2){0}; + } + + return state; +} + +void finalize(GameState *state) { + (void)state; +} + +void reload(GameState *state) { + (void)state; +} + +void unload(GameState *state) { + (void)state; +} + +void step(GameState *state) { + // Process Input + if (IsMouseButtonPressed(0)) { + Vector2 mouse_pos = GetMousePosition(); + state->target_pos = (PointOption){.tag = SOME, .some.point = mouse_pos}; + } + + + // Update + for (int i = 0; i < NUM_BOIDS; i++) { + Boid *boid = &state->boids[i]; + if (state->target_pos.tag == SOME) { + Vector2 desired = Vector2Subtract(state->target_pos.some.point, boid->position); + desired = Vector2Normalize(desired); + desired = Vector2Scale(desired, state->max_speed); + Vector2 steer = Vector2Subtract(desired, boid->velocity); + steer = Vector2ClampValue(steer, 0.0f, state->max_force); + boid->acceleration = Vector2Add(boid->acceleration, steer); + } + boid->velocity = Vector2Add(boid->velocity, boid->acceleration); + boid->velocity = Vector2ClampValue(boid->velocity, 0.0f, state->max_speed); + boid->position = Vector2Add(boid->position, boid->velocity); + } + + + // Update + BeginDrawing(); + { + ClearBackground(RAYWHITE); + // You can draw a triangle but you'd need to rotate all 3 vectors, and I don't + // want to get distracted with that + // DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, GREEN); + // DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, GREEN); + for (int i = 0; i < NUM_BOIDS; i++) { + Boid *boid = &state->boids[i]; + DrawCircle(boid->position.x, boid->position.y, 27, BLACK); + DrawCircle(boid->position.x, boid->position.y, 20, GREEN); + } + } + EndDrawing(); +} diff --git a/boids_game.h b/boids_game.h new file mode 100644 index 0000000..37ec1c6 --- /dev/null +++ b/boids_game.h @@ -0,0 +1,13 @@ +#pragma once + +struct GameState; + +typedef struct GameApi { + struct GameApi *(*init)(); + void (*finalize) (struct GameApi *state); + void (*reload) (struct GameApi *state); + void (*unload) (struct GameApi *state); + void (*step) (struct GameApi *state); +} GameApi; + +extern const struct GameApi GAME_API; diff --git a/boids_main.c b/boids_main.c new file mode 100644 index 0000000..796f649 --- /dev/null +++ b/boids_main.c @@ -0,0 +1,79 @@ +#define _DEFAULT_SOURCE // usleep() +#include +#include +#include +#include +#include +#include +// #include "inotify-syscalls.h" +#include "include/raylib.h" +#include "include/raymath.h" +#include "boids_game.h" + +#define SCREEN_WIDTH 1300 +#define SCREEN_HEIGHT 1080 +#define TARGET_FPS 60 + +const char *GAME_LIB = "./libboids.so"; +char epoll_buf[1024]; + +struct Game { + void *handle; + struct GameApi api; + struct GameState *state; +}; +#define MAX_EVENTS 1 + +int main(void) { + int fd = inotify_init(); + if (fd < 0) { + fprintf(stderr, "Error initializing inotify\n"); + } + int wd; + wd = inotify_add_watch(fd, GAME_LIB, IN_MODIFY); + + // create epoll instance + int epollfd = epoll_create1(0); + if (epollfd == -1) { + fprintf(stderr, "Error creating epoll instance\n"); + } + + struct epoll_event event; + event.events = EPOLLIN; + event.data.fd = fd; + + // register inotify fd with epoll + if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event) == -1) { + fprintf(stderr, "Error adding inotify descriptor to epoll\n"); + } + + InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Boids"); + + SetTargetFPS(TARGET_FPS); + + struct epoll_event events[MAX_EVENTS]; + + while (!WindowShouldClose()) { + int nfds = epoll_wait(epollfd, events, MAX_EVENTS, 0); + if (nfds == -1) { + fprintf(stderr, "epoll_wait failed\n"); + break; + } + + for (int n = 0; n < nfds; ++n) { + if (events[n].data.fd == fd) { + printf("SO has been updated!\n"); + read(fd, epoll_buf, sizeof(epoll_buf)); + } + } + + BeginDrawing(); + ClearBackground(BEIGE); + EndDrawing(); + } + + inotify_rm_watch(fd, wd); + close(fd); + close(epollfd); + CloseWindow(); +} diff --git a/hours.org b/hours.org index c5b5c12..4603ed2 100644 --- a/hours.org +++ b/hours.org @@ -1,12 +1,22 @@ * Bexorg Hours #+BEGIN: clocktable :scope subtree :maxlevel 2 -#+CAPTION: Clock summary at [2024-01-06 Sat 12:28] -| Headline | Time | -|------------+------| -| *Total time* | *0:00* | +#+CAPTION: Clock summary at [2024-01-09 Tue 20:31] +| Headline | Time | | +|----------------------+------+------| +| *Total time* | *3:41* | | +|----------------------+------+------| +| Bexorg Hours | 3:41 | | +| \_ <2024-01-06 Sat> | | 2:10 | +| \_ <2024-01-09 Tue> | | 1:31 | #+END: ** <2024-01-06 Sat> :LOGBOOK: CLOCK: [2024-01-06 Sat 11:00]--[2024-01-06 Sat 13:10] => 2:10 :END: +** <2024-01-09 Tue> +:LOGBOOK: +CLOCK: [2024-01-09 Tue 19:30]--[2024-01-09 Tue 20:31] => 1:01 +CLOCK: [2024-01-09 Tue 10:45]--[2024-01-09 Tue 11:15] => 0:30 +:END: + diff --git a/main.c b/main.c index 334363c..4de0fb6 100644 --- a/main.c +++ b/main.c @@ -6,7 +6,7 @@ #define TEXTURES_BUF_SIZE 16 #define TARGET_FPS 60 -#define MAX_KNIGHTS 512 +#define MAX_KNIGHTS 10000 #define SCREEN_WIDTH 1300 #define SCREEN_HEIGHT 1080 @@ -36,7 +36,7 @@ typedef enum Direction { // DIR_DOWN_RIGHT = 7, } Direction; -typedef struct { +typedef struct Knight { Point position; Point move_target_point; u8 look_dir; @@ -45,7 +45,7 @@ typedef struct { u8 ordered_to_move; } Knight; -typedef struct { +typedef struct GameState { int frame_count; Point camera_position; @@ -59,7 +59,7 @@ typedef struct { int entity_count; } GameState; -typedef struct { +typedef struct Assets { Texture2D *textures; } Assets;