aboutsummaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorEmil Williams2026-02-05 09:29:51 +0000
committerEmil Williams2026-02-05 09:29:51 +0000
commit45570024a49b80359d848329f2c363d5bf9af44a (patch)
tree31243e117a965569ecbc745eba88b25536b7fc99 /source
parenta5209153cf8df1cd58c2f70f9eabb0bf5dd071f8 (diff)
downloadEUROPAXI-45570024a49b80359d848329f2c363d5bf9af44a.tar.xz
EUROPAXI-45570024a49b80359d848329f2c363d5bf9af44a.tar.zst
assets & core8e8m
Diffstat (limited to 'source')
-rw-r--r--source/all.h25
-rw-r--r--source/game.c125
-rw-r--r--source/main.c116
-rw-r--r--source/render.c6
-rw-r--r--source/time.c56
-rw-r--r--source/time.h14
6 files changed, 249 insertions, 93 deletions
diff --git a/source/all.h b/source/all.h
index 9d97653..df42641 100644
--- a/source/all.h
+++ b/source/all.h
@@ -9,32 +9,31 @@
#define TEXT_BUFFER_LIMIT (1<<12)
#define FRAME_LIMIT (1<<4)
-#define MIN(a,b) (a)<(b)?(a):(b)
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#define CLAMP(a,b,c) (a)<(b)?(b):(a)>(c)?(c):(a)
typedef struct {
Font font;
float frame_x[FRAME_LIMIT];
float frame_y[FRAME_LIMIT];
int horizontal, vertical;
+ float ups, fps;
} game_t;
/* render.c */
-/* Everything here assumes White On Black = OK. for now. */
-/* Things should be textured and have backgrounds which is a lot of extra params,
- which are not important right now. */
-
-/* I would prefer that things remain CENTERED as that makes preportional to WINDOW SIZE shit easier */
-/* The Window is resizable, by the way. */
-
-void draw_square_grid (game_t * game, size_t frame, int size, Texture * texture, int * array, size_t length);
-void draw_vertical_bargraph (game_t * game, size_t frame, int size, Color color, int * arr, size_t length);
-void draw_centered_text (game_t * game, size_t frame, int font_size, Color color, char * format, ...);
+void DrawSquareGrid (game_t * game, size_t frame, int size, Texture * texture, int * array, size_t length);
+void DrawVerticalBargraph (game_t * game, size_t frame, int size, Color color, int * arr, size_t length);
+void DrawCenteredText (game_t * game, size_t frame, int font_size, Color color, char * format, ...);
/* game.c */
-void game_frame(game_t * game, size_t frame, float x, float y);
-Vector2 game_frame_vector(game_t * game, size_t frame);
+void GameInitialize(game_t * game, char * window_name);
+void GameDeinitialize(game_t * game);
+void GameFrame(game_t * game, size_t frame, float x, float y);
+void GameFrameReset(game_t * game);
+Vector2 GameFrameVector(game_t * game, size_t frame);
/* ... */
diff --git a/source/game.c b/source/game.c
index 941b176..fa7633f 100644
--- a/source/game.c
+++ b/source/game.c
@@ -1,10 +1,131 @@
#include "all.h"
-void game_frame(game_t * game, size_t frame, float x, float y) {
+Font DefaultFont(char * choice) {
+ Font font = LoadFont(choice);
+ if (!IsFontValid(font)) { font = GetFontDefault(); }
+ return font;
+}
+
+void GameFrame(game_t * game, size_t frame, float x, float y) {
game->frame_x[frame] = x;
game->frame_y[frame] = y;
}
-Vector2 game_frame_vector(game_t * game, size_t frame) {
+void GameFrameReset(game_t * game) {
+ GameFrame(game, 0, game->horizontal/3, game->vertical - game->vertical/8);
+ /* GameFrame(game, 1, game->horizontal/12, game->vertical/12); */
+ /* GameFrame(game, 2, game->horizontal - game->horizontal/4, game->vertical/12); */
+}
+
+Vector2 GameFrameVector(game_t * game, size_t frame) {
return (Vector2) { game->frame_x[frame], game->frame_y[frame]};
}
+
+void GameInitialize(game_t * game, char * window_name) {
+ SetConfigFlags(FLAG_WINDOW_RESIZABLE);
+ /* tell raylib to shut up */
+ SetTraceLogLevel(LOG_NONE);
+ InitWindow(game->horizontal, game->vertical, window_name);
+ SetWindowState(FLAG_WINDOW_HIDDEN);
+ InitAudioDevice();
+ SetWindowPosition(0, 0);
+ /* :config */
+ game->horizontal = 1920;
+ game->vertical = 1080;
+ game->ups = 60;
+ game->fps = 30;
+ game->font = DefaultFont("fonts/Atkinson/mono/AtkinsonHyperlegibleMono-Bold.otf");
+ GameFrameReset(game);
+}
+
+void GameDeinitialize(game_t * game) {
+ SetWindowState(FLAG_WINDOW_HIDDEN);
+ UnloadFont(game->font);
+ CloseAudioDevice();
+ CloseWindow();
+}
+
+void GameLoop(game_t * game) {
+
+ extern int Update(game_t * game, struct timespec now);
+ extern void Frame(game_t * game, double interpolation);
+
+ #define StepStart(prefix) \
+ prefix##_delta = timespec_sub(now, prefix##_last); \
+ if (timespec_cmp(prefix##_delta, prefix##_interval) >= 0) { (void) 0
+
+ #define StepStop(prefix) \
+ prefix##s_per_second++; \
+ prefix##_total++; \
+ prefix##_last = timespec_add(prefix##_last, prefix##_interval); \
+ if (timespec_cmp(prefix##_last, now) < 0) { \
+ prefix##_last = now; \
+ } \
+ }
+
+ #define StepSimpleStart(prefix,linear) \
+ prefix##_delta = timespec_sub(now, prefix##_last); \
+ if (timespec_cmp(prefix##_delta, (struct timespec){1.,0.}) >= 0) { \
+ (void)0
+
+ #define StepSimpleStop(prefix) \
+ prefix##_last = now; \
+ }
+
+ struct timespec
+ now,
+ update_interval = {0, (double) TIMESPEC_HZ / game->ups},
+ frame_interval = {0, (double) TIMESPEC_HZ / game->fps},
+ update_last, frame_last, print_last,
+ update_delta, frame_delta, print_delta,
+ wait;
+
+ uint32_t
+ updates_per_second = 0, frames_per_second = 0,
+ frame_total = 0, update_total = 0;
+
+ double interpolation = 0.;
+
+ ClearWindowState(FLAG_WINDOW_HIDDEN);
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ update_last = frame_last = print_last = now;
+
+ while (1) {
+ StepStart(update);
+ if (Update(game, now)) { return; }
+ StepStop(update);
+
+ StepStart(frame);
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ interpolation =
+ CLAMP(
+ TIMESPEC_TO_DOUBLE(update_delta)
+ / TIMESPEC_TO_DOUBLE(update_interval),
+ 0.0, 1.0f);
+ Frame(game, interpolation);
+ StepStop(frame);
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
+
+ wait = timespec_sub(
+ timespec_min(
+ timespec_add(update_last, update_interval),
+ timespec_add(frame_last, frame_interval)),
+ now);
+
+ if (timespec_cmp(wait, zero_seconds) > 0) {
+ nanosleep(&wait, NULL);
+ }
+
+ StepSimpleStart(print, one_second);
+ printf("[FPS|UPS|Total] (%3.0f : %3.0f) | [%7u/%7u]\n",
+ round(frames_per_second / TIMESPEC_TO_DOUBLE(print_delta)),
+ round(updates_per_second / TIMESPEC_TO_DOUBLE(print_delta)),
+ frame_total, update_total);
+ frames_per_second = updates_per_second = 0;
+ StepSimpleStop(print);
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ }
+}
diff --git a/source/main.c b/source/main.c
index c775851..4bcaac8 100644
--- a/source/main.c
+++ b/source/main.c
@@ -1,89 +1,55 @@
#include <time.h>
+#include "time.h"
#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
#include <rlgl.h>
#include "all.h"
-/* I really like this in usage. */
+void Root(char * filename) {
+ char path[PATH_MAX], * terminator;
+ if (!realpath(filename, path)) { return; }
+ if ((terminator = strrchr(path, '/'))) {
+ *terminator = '\0';
+ if(chdir(path)) { abort(); }
+ }
+}
+
+int Update(game_t * game, struct timespec now) {
+ (void) now;
+ PollInputEvents();
+ if (IsWindowResized()) {
+ game->horizontal = GetScreenWidth(), game->vertical = GetScreenHeight();
+ GameFrameReset(game);
+ }
+ switch (GetKeyPressed()) {
+ case KEY_ESCAPE: return 1;
+ }
+ return 0;
+}
-static inline void frame_reset(game_t * game) {
- game_frame(game, 0, game->horizontal/12, game->vertical/12);
- game_frame(game, 1, game->horizontal/3, game->vertical - game->vertical/8);
- game_frame(game, 2, game->horizontal - game->horizontal/4, game->vertical/12);
+void Frame(game_t * game, double interpolation) {
+ (void)interpolation;
+ BeginDrawing();
+ ClearBackground(BLACK);
+ DrawCenteredText(game, 0, 20, WHITE, "Snails are now preparing! %d", rand());
+ rlDrawRenderBatchActive();
+ SwapScreenBuffer();
}
-int main (int count, char ** arguments)
+int Main(int count, char ** arguments)
{
(void)count;
game_t game[1] = {0};
- game->horizontal = 1920;
- game->vertical = 1080;
- /* :config */
- frame_reset(game);
- { /* this idented (DENTED) style is autistic and dumb but I like it visually */
- SetConfigFlags(FLAG_WINDOW_RESIZABLE);
- /* tell raylib to shut up */
- /* SetTraceLogLevel(LOG_NONE); */
- InitWindow(game->horizontal, game->vertical, arguments[0]);
- SetWindowState(FLAG_WINDOW_HIDDEN);
- InitAudioDevice();
- SetWindowPosition(0, 0);
- }
- game->font = LoadFont("fonts/Atkinson/mono/AtkinsonHyperlegibleMono-Bold.otf");
- if (!IsFontValid(game->font)) { game->font = GetFontDefault(); }
-
- /* :todo ping me I'll update this to a u/f seperated game loop */
- { /* loop to end all loops */
- uint64_t fc = 0;
- /* :config */
- float fps = 30;
- double wait = wait = 1.0 / fps, delta = wait;
- struct timespec start, end;
-
- clock_gettime(CLOCK_MONOTONIC, &start);
- ClearWindowState(FLAG_WINDOW_HIDDEN);
- int test[200*200] = {0};
- for (int i = 0; i < 200*200; i++) { test[i] = i;}
- while (1) {
- if (delta > wait) {
- clock_gettime(CLOCK_MONOTONIC, &start);
- { /* update */
- ++fc;
- PollInputEvents();
- if (IsWindowResized()) {
- game->horizontal = GetScreenWidth(), game->vertical = GetScreenHeight();
- frame_reset(game);
- }
- /* physical keys */
- switch (GetKeyPressed()) {
- /* case KEY_Q: goto stop; */
- case KEY_ESCAPE: goto stop;
- }
- /* routed keys */
- /* switch (GetCharPressed()) { case 'q': goto stop; } */
- }
- { /* draw */
- BeginDrawing();
- ClearBackground(BLACK);
- draw_square_grid(game, 0, MIN(game->vertical/20, game->horizontal/25), NULL, test, 200);
- draw_centered_text(game, 1, 20, WHITE, "Snails are now preparing!");
- draw_centered_text(game, 2, 20, WHITE, "Gambling here");
- rlDrawRenderBatchActive();
- SwapScreenBuffer();
- }
- }
- clock_gettime(CLOCK_MONOTONIC, &end);
- delta = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;
- if (delta < wait) {
- double should = -(delta - wait);
- if (should > 0) { usleep(1e6 * should); }
- }
- }
- }
-stop:
- SetWindowState(FLAG_WINDOW_HIDDEN);
- UnloadFont(game->font);
- CloseAudioDevice();
- CloseWindow();
+ char * program_name = arguments[0];
+ srand(time(NULL));
+ Root(program_name);
+ GameInitialize(game, program_name);
+ GameLoop(game);
+ GameDeinitialize(game);
return 0;
}
+
+int main (int count, char ** arguments) __attribute__((alias("Main")));
diff --git a/source/render.c b/source/render.c
index ef7280e..ef28cba 100644
--- a/source/render.c
+++ b/source/render.c
@@ -1,6 +1,6 @@
#include "all.h"
-void draw_square_grid(game_t * game, size_t frame, int size, Texture * texture, int * array, size_t length) {
+void DrawSquareGrid(game_t * game, size_t frame, int size, Texture * texture, int * array, size_t length) {
(void)texture;
float x = game->frame_x[frame], y = game->frame_y[frame];
float square_length = size;
@@ -15,10 +15,10 @@ void draw_square_grid(game_t * game, size_t frame, int size, Texture * texture,
}
}
-/* void draw_vertical_bargraph(game_t * game, size_t frame, int size, Color color, int * array, size_t length) { */
+/* void DrawVerticalBargraph(game_t * game, size_t frame, int size, Color color, int * array, size_t length) { */
/* } */
-void draw_centered_text(game_t * game, size_t frame, int font_size, Color color, char * format, ...) {
+void DrawCenteredText(game_t * game, size_t frame, int font_size, Color color, char * format, ...) {
char buffer[TEXT_BUFFER_LIMIT];
float x = game->frame_x[frame], y = game->frame_y[frame];
va_list ap;
diff --git a/source/time.c b/source/time.c
new file mode 100644
index 0000000..e2c47b0
--- /dev/null
+++ b/source/time.c
@@ -0,0 +1,56 @@
+#include "time.h"
+
+struct timespec timespec_add(struct timespec a, struct timespec b) {
+ a.tv_sec += b.tv_sec;
+ a.tv_nsec += b.tv_nsec;
+ if (a.tv_nsec >= 1000000000) {
+ a.tv_sec++;
+ a.tv_nsec -= 1000000000;
+ }
+ return a;
+}
+
+struct timespec timespec_sub(struct timespec a, struct timespec b) {
+ a.tv_sec -= b.tv_sec;
+ a.tv_nsec -= b.tv_nsec;
+ if (a.tv_nsec < 0) {
+ a.tv_sec--;
+ a.tv_nsec += 1000000000;
+ }
+ return a;
+}
+
+int timespec_cmp(struct timespec a, struct timespec b) {
+ return a.tv_sec > b.tv_sec ?
+ (1) :
+ a.tv_sec < b.tv_sec ?
+ (-1) :
+ (
+ a.tv_nsec > b.tv_nsec ?
+ (1) :
+ a.tv_nsec < b.tv_nsec ?
+ (-1) : 0
+ );
+}
+
+struct timespec timespec_max(struct timespec a, struct timespec b) {
+ return a.tv_sec > b.tv_sec ?
+ a :
+ a.tv_sec < b.tv_sec ?
+ b :
+ (
+ a.tv_nsec > b.tv_nsec ?
+ a : b
+ );
+}
+
+struct timespec timespec_min(struct timespec a, struct timespec b) {
+ return a.tv_sec < b.tv_sec ?
+ a :
+ a.tv_sec > b.tv_sec ?
+ b :
+ (
+ a.tv_nsec < b.tv_nsec ?
+ a : b
+ );
+}
diff --git a/source/time.h b/source/time.h
new file mode 100644
index 0000000..ca151f1
--- /dev/null
+++ b/source/time.h
@@ -0,0 +1,14 @@
+#ifndef TIME_H_
+#define TIME_H_
+#include <time.h>
+#define TIMESPEC_TO_DOUBLE(ts) ((double)(ts).tv_sec + ((double)(ts).tv_nsec / TIMESPEC_HZ))
+enum { TIMESPEC_HZ = 1000000000 };
+
+const struct timespec one_second = {1, 0}, zero_seconds = {0, 0};
+
+struct timespec timespec_add(struct timespec a, struct timespec b);
+struct timespec timespec_sub(struct timespec a, struct timespec b);
+int timespec_cmp(struct timespec a, struct timespec b);
+struct timespec timespec_min(struct timespec a, struct timespec b);
+struct timespec timespec_max(struct timespec a, struct timespec b);
+#endif /* TIME_H_ */