summaryrefslogtreecommitdiff
path: root/Peak/src/peak_header.h
diff options
context:
space:
mode:
authorVasco <[email protected]>2026-08-24 00:56:24 +0100
committerVasco <[email protected]>2026-08-24 00:56:24 +0100
commit5dc2716abd43166cd65133625f408ad36a6623b3 (patch)
tree19d89b838206b6bb11cc0b9f88311d855999d447 /Peak/src/peak_header.h
parentdc96fcd771bea09d726a760266739906e95c09a6 (diff)
Peak 0.4.0 and Draw
Diffstat (limited to 'Peak/src/peak_header.h')
-rw-r--r--Peak/src/peak_header.h164
1 files changed, 62 insertions, 102 deletions
diff --git a/Peak/src/peak_header.h b/Peak/src/peak_header.h
index 9521abb..b0a3023 100644
--- a/Peak/src/peak_header.h
+++ b/Peak/src/peak_header.h
@@ -17,12 +17,13 @@
* 0.0.0 - @vasco - prototyping
* 0.1.0 - @vasco - linux x11 that automagically loads X11 DLL
* 0.1.1 - @vasco - fixed event handling on linux
- *
- * TODO: demo that stress tests the whole API
+ * 0.1.2 - @vasco - better handling of windows, if multiple windows becomes necessary in the future
+ * 0.2.0 - @vasco - multiple windows, major-ish API changes.
+ * 0.3.0 - @vasco - web via emscripten
+ * 0.4.0 - @vasco - win32
*/
#include <assert.h>
-#include <stdarg.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
@@ -52,15 +53,13 @@
#else
#define PEAK_MACOS
#endif
-#elif defined(__linux__)
- #define PEAK_LINUX
-#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__)
- #define PEAK_BSD
#elif defined(__ANDROID__)
#define PEAK_ANDROID
#define PEAK_LINUX
#elif defined(__linux__)
#define PEAK_LINUX
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__)
+ #define PEAK_BSD
#endif
#if defined(PEAK_LINUX) || defined(PEAK_BSD) || defined(PEAK_APPLE)
@@ -77,7 +76,8 @@
#endif
typedef enum {
- PEAK_KEYMOD_ALT = 0,
+ PEAK_KEYMOD_NONE = 0,
+ PEAK_KEYMOD_ALT,
PEAK_KEYMOD_SHIFT,
PEAK_KEYMOD_CTRL,
PEAK_KEYMOD_CAPS,
@@ -102,7 +102,7 @@ typedef enum {
PEAK_EVENT_POINTER_CONNECTED,
PEAK_EVENT_POINTER_DISCONNECTED,
PEAK_EVENT_LAST
-} PeakEvenType;
+} PeakEventType;
typedef enum {
PEAK_POINTER_MOVED = 0,
@@ -118,7 +118,7 @@ typedef enum {
} PeakPointerType;
typedef struct {
- PeakEvenType type;
+ PeakEventType type;
union {
struct { PeakKeyCode key; PeakKeyMod mod; } key;
struct { uint32_t width, height; } resize;
@@ -126,106 +126,53 @@ typedef struct {
};
} PeakEvent;
+/* Implemented by the platform */
+typedef struct peak_window_internal_t PeakWindowInternal;
+typedef struct PeakWindow PeakWindow;
+
/* Public API */
-PEAK void peak_init(void); // open a window and initialize graphics. called automatically if using peak_setup().
-PEAK void peak_quit(void); // close the window and release resources. called automatically if using peak_setup().
-PEAK bool peak_poll_events(PeakEvent *ev); // Poll the next event from the window queue. Returns true if an event was retrieved.
-PEAK void peak_extensions(void); // retrieve gpu window surface extensions for native api access (e.g., vulkan/opengl).
-PEAK void peak_blit(int offset_x, int offset_y, const uint32_t *rgba, size_t width, size_t height); // blit rgba pixels to the screen.
-PEAK void peak_clip(int x, int y, size_t w, size_t h); // restrict all subsequent rendering operations to this bounding rectangle.
-PEAK void peak_clip_reset(void); // reset clipping plane to window size.
-PEAK void peak_draw_rectangle(int x, int y, size_t w, size_t h, uint32_t color); // draw a solid-color filled rectangle.
-PEAK void peak_draw_rectangle_gradient(int x, int y, size_t w, size_t h, uint32_t c0, uint32_t c1, uint32_t c2, uint32_t c3); // fill rectangle interpolating four corner colors in clock-wise order.
-PEAK void peak_draw_triangle(int x0, int y0, int x1, int y1, int x2, int y2, uint32_t color); // draw a solid-color filled triangle.
-PEAK void peak_draw_triangle_gradient(int x0, int y0, int x1, int y1, int x2, int y2, uint32_t c0, uint32_t c1, uint32_t c2); // fill triangle with color interpolation clock-wise across its three vertices.
-PEAK void peak_draw_line(int x0, int y0, int x1, int y1, size_t width, uint32_t color); // draw a line between two points.
-PEAK void peak_draw_line_gradient(int x0, int y0, int x1, int y1, size_t width, uint32_t c0, uint32_t c1); // draw a line with a color gradient.
+PEAK int peak_init(void); // Initialize platform context and load necessary DLLs.
+PEAK void peak_quit(void); // Close platform context.
+PEAK PeakWindow peak_window_open(const char *name, uint32_t width, uint32_t height, uint32_t flags); // Open a window.
+PEAK void peak_window_close(PeakWindow *window); // Close a window.
+PEAK void peak_window_run(PeakWindow *win, int (*peak_tick)(PeakWindow *win, void *userdata), void *userdata); // Hijacking the main loop makes life easier on platforms like web
+PEAK int peak_window_epoll(PeakWindow *win, PeakEvent *ev); // Poll a window for events.
+PEAK uint32_t* peak_window_backbuffer(PeakWindow *win, size_t *width, size_t *height); // Get the windows backbuffer.
+PEAK void peak_window_clear(PeakWindow *win, float r, float g, float b, float a);
+PEAK void peak_window_present(PeakWindow *win);
-/* Implemented by the platform */
-PEAK void peak_platform_window_open();
-PEAK void peak_platform_window_close();
-PEAK uint32_t *peak_platform_window_buffer(size_t *width, size_t *height);
-PEAK bool peak_platform_epoll(PeakEvent *ev);
+#endif // PEAK_H
-/*
- * He was wipping up amazing foods, like making happiness.
- * Actual happiness?
- * Actual happiness and joy.
- * Oh the smell, it was so divine.
- * He was making happiness!?
- * Happiness in the kettle!
- */
-#ifdef PEAK_REPLACE_MAIN
-enum PeakReturn { PEAK_CONTINUE = 0, PEAK_STOP = 1 };
-extern int peak__main(int argc, char**argv);
-extern void peak_events(PeakEvent ev);
-extern void peak_tick();
-static bool running = true;
-static inline void peak_stop() { running = false; }
-#ifndef PEAK_WEB
-#define main(...)\
-main(int argc, char **argv) {\
- assert(peak_events != 0 && "Declare peak_events() to handle window events.");\
- assert(peak_tick != 0 && "Declare peak_tick() to handle each frame ticks.");\
- peak_init();\
- int ret = peak__main(argc, argv);\
- if (ret != PEAK_CONTINUE) return ret;\
- PeakEvent ev;\
- while (running) {\
- while (running && peak_poll_events(&ev)) {\
- peak_events(ev);\
- }\
- peak_tick();\
- }\
- peak_quit();\
-}\
-int peak__main(__VA_ARGS__)
-#else
-#include <emscripten.h>
-/*
- * He was wipping up agony in the kettle.
- * Actual pain?
- * Boiling hatred in the kettle.
- * The smell, it's pain.
- * Boiling anger!?
- * Yes, boiling anger.
- */
+#ifdef PEAK_IMPLEMENTATION
+#undef PEAK_IMPLEMENTATION
+
+#if defined(PEAK_WIN32) || defined(PEAK_WEB)
+#define PEAK_Q 64
-static inline void
-peak__emscripten_loop_step(void *arg)
+typedef struct {
+ unsigned h, n;
+ PeakEvent e[PEAK_Q];
+} PeakQ;
+
+static void
+peak_q_push(PeakQ *q, PeakEvent ev)
{
- (void)arg;
- PeakEvent ev;
- while (peak_poll_events(&ev)) {
- peak_events(ev);
- }
-
- if (running) {
- peak_tick();
- } else {
- emscripten_cancel_main_loop();
- peak_quit();
- }
+ if (!q || q->n == PEAK_Q)
+ return;
+ q->e[(q->h + q->n++) % PEAK_Q] = ev;
}
-#define main(...)\
- main(int argc, char **argv) {\
- _Static_assert(peak_events != 0, "When using peak_setup, declare peak_events() to handle window events.");\
- _Static_assert(peak_tick != 0, "When using peak_setup, declare peak_tick() to handle frame ticks.");\
- peak_init();\
- int ret = peak__main(argc, argv);\
- if (ret != PEAK_CONTINUE) return ret;\
- emscripten_set_main_loop_arg(peak__emscripten_loop_step, NULL, 0, 1);\
- return 0;\
- }\
- int peak__main(__VA_ARGS__)
+static int
+peak_q_pop(PeakQ *q, PeakEvent *ev)
+{
+ if (!q || !q->n)
+ return 0;
+ *ev = q->e[q->h];
+ q->h = (q->h + 1) % PEAK_Q;
+ q->n--;
+ return 1;
+}
#endif
-#endif // PEAK_DONT_REPLACE_MAIN
-
-#endif // PEAK_H
-
-#ifdef PEAK_IMPLEMENTATION
-#undef PEAK_IMPLEMENTATION
#if defined(PEAK_WIN32)
#include "p_win32.c" // <REPLACE>
@@ -235,6 +182,19 @@ peak__emscripten_loop_step(void *arg)
#include "p_emscripten.c" // <REPLACE>
#endif
+/* We define PeakWindow only when we know the type of peak_window_internal_t */
+struct PeakWindow {
+ PeakWindowInternal internal;
+ int (*tick)(struct PeakWindow *win, void *userdata);
+ void *userdata;
+ uint32_t *buffer;
+ uint32_t width;
+ uint32_t height;
+ uint32_t bufsize;
+ int running;
+};
+
+
#include "peak.c" // <REPLACE>
#endif // PEAK_IMPLEMENTATION