diff --git a/README.md b/README.md
index 87dc7e0..6d7d432 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,5 @@
# pxl8
-### Requirements
-
-- **Clang 19+** (or GCC 15+) - Required for C23 `#embed` support
-- **SDL3** - System package or auto-vendored
-
### Quick Start
```bash
@@ -15,6 +10,11 @@
```
**Note** The demo has keys 1-8 bound for different examples.
+### Requirements
+
+- **Clang 19+** (or GCC 15+) - Required for C23 `#embed` support
+- **SDL3** - System package or auto-vendored
+
> [!WARNING]
> Heavy development. So... here be dragons :3
@@ -44,4 +44,4 @@ pxl8 is free and open source! All code in this repository is licensed under:
- Mozilla Public License, Version 2.0 ([LICENSE](LICENSE) or https://mozilla.org/MPL/2.0/)
-Third-party dependencies (Fennel, linenoise, log.c, LuaJIT, miniz, SDL3) retain their original licenses.
+Third-party dependencies (Fennel, linenoise, LuaJIT, miniz, SDL3) retain their original licenses.
diff --git a/pxl8.sh b/pxl8.sh
index f920079..11ac307 100755
--- a/pxl8.sh
+++ b/pxl8.sh
@@ -341,8 +341,10 @@ case "$COMMAND" in
src/pxl8_gfx.c
src/pxl8_gui.c
src/pxl8_io.c
+ src/pxl8_log.c
src/pxl8_math.c
src/pxl8_rec.c
+ src/pxl8_repl.c
src/pxl8_save.c
src/pxl8_script.c
src/pxl8_sdl3.c
diff --git a/src/pxl8.c b/src/pxl8.c
index e5eafc1..a7e0259 100644
--- a/src/pxl8.c
+++ b/src/pxl8.c
@@ -12,7 +12,8 @@
#include "pxl8_cart.h"
#include "pxl8_game.h"
#include "pxl8_hal.h"
-#include "pxl8_macros.h"
+#include "pxl8_log.h"
+#include "pxl8_repl.h"
#include "pxl8_script.h"
#include "pxl8_sys.h"
#include "pxl8_types.h"
@@ -20,19 +21,21 @@
struct pxl8 {
pxl8_cart* cart;
pxl8_game* game;
+ pxl8_repl* repl;
+ pxl8_log log;
const pxl8_hal* hal;
void* platform_data;
};
pxl8* pxl8_create(const pxl8_hal* hal) {
- if (!hal) {
- pxl8_error("HAL cannot be NULL");
- return NULL;
- }
-
pxl8* sys = (pxl8*)calloc(1, sizeof(pxl8));
- if (!sys) {
- pxl8_error("Failed to allocate pxl8 system");
+ if (!sys) return NULL;
+
+ pxl8_log_init(&sys->log);
+
+ if (!hal) {
+ pxl8_error("hal cannot be null");
+ free(sys);
return NULL;
}
@@ -40,7 +43,7 @@ pxl8* pxl8_create(const pxl8_hal* hal) {
sys->game = (pxl8_game*)calloc(1, sizeof(pxl8_game));
if (!sys->game) {
- pxl8_error("Failed to allocate game");
+ pxl8_error("failed to allocate game");
free(sys);
return NULL;
}
@@ -51,31 +54,19 @@ pxl8* pxl8_create(const pxl8_hal* hal) {
void pxl8_destroy(pxl8* sys) {
if (!sys) return;
- if (sys->game) {
- free(sys->game);
- }
-
- if (sys->cart) {
- pxl8_cart_destroy(sys->cart);
- }
-
- if (sys->hal && sys->platform_data) {
- sys->hal->destroy(sys->platform_data);
- }
+ if (sys->game) free(sys->game);
+ if (sys->cart) pxl8_cart_destroy(sys->cart);
+ if (sys->hal && sys->platform_data) sys->hal->destroy(sys->platform_data);
free(sys);
}
pxl8_result pxl8_init(pxl8* sys, i32 argc, char* argv[]) {
- if (!sys || !sys->game) {
- return PXL8_ERROR_INVALID_ARGUMENT;
- }
+ if (!sys || !sys->game) return PXL8_ERROR_INVALID_ARGUMENT;
pxl8_game* game = sys->game;
-
pxl8_pixel_mode pixel_mode = PXL8_PIXEL_INDEXED;
pxl8_resolution resolution = PXL8_RESOLUTION_640x360;
-
const char* script_arg = NULL;
bool bundle_mode = false;
bool pack_mode = false;
@@ -112,7 +103,7 @@ pxl8_result pxl8_init(pxl8* sys, i32 argc, char* argv[]) {
char exe_path[1024];
ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
if (len == -1) {
- pxl8_error("Failed to resolve executable path");
+ pxl8_error("failed to resolve executable path");
return PXL8_ERROR_SYSTEM_FAILURE;
}
exe_path[len] = '\0';
@@ -126,31 +117,31 @@ pxl8_result pxl8_init(pxl8* sys, i32 argc, char* argv[]) {
}
if (game->repl_mode) {
- fprintf(stderr, "\033[38;2;184;187;38m[pxl8]\033[0m Starting in REPL mode with script: %s\n", game->script_path);
+ pxl8_info("starting in REPL mode with script: %s", game->script_path);
}
- pxl8_info("Starting up");
+ pxl8_info("starting up");
sys->platform_data = sys->hal->create(pixel_mode, resolution, "pxl8", 1280, 720);
if (!sys->platform_data) {
- pxl8_error("Failed to create platform context");
+ pxl8_error("failed to create platform context");
return PXL8_ERROR_INITIALIZATION_FAILED;
}
game->gfx = pxl8_gfx_create(sys->hal, sys->platform_data, pixel_mode, resolution);
if (!game->gfx) {
- pxl8_error("Failed to create graphics context");
+ pxl8_error("failed to create graphics context");
return PXL8_ERROR_INITIALIZATION_FAILED;
}
if (pxl8_gfx_load_font_atlas(game->gfx) != PXL8_OK) {
- pxl8_error("Failed to load font atlas");
+ pxl8_error("failed to load font atlas");
return PXL8_ERROR_INITIALIZATION_FAILED;
}
game->script = pxl8_script_create(game->repl_mode);
if (!game->script) {
- pxl8_error("Failed to initialize scripting: %s", pxl8_script_get_last_error(game->script));
+ pxl8_error("failed to initialize scripting: %s", pxl8_script_get_last_error(game->script));
return PXL8_ERROR_INITIALIZATION_FAILED;
}
@@ -160,16 +151,16 @@ pxl8_result pxl8_init(pxl8* sys, i32 argc, char* argv[]) {
if (has_embedded && !script_arg) {
sys->cart = pxl8_cart_create();
if (!sys->cart) {
- pxl8_error("Failed to create cart");
+ pxl8_error("failed to create cart");
return PXL8_ERROR_INITIALIZATION_FAILED;
}
if (pxl8_cart_load_embedded(sys->cart, argv[0]) == PXL8_OK) {
pxl8_cart_mount(sys->cart);
strncpy(game->script_path, "main.fnl", sizeof(game->script_path) - 1);
game->script_path[sizeof(game->script_path) - 1] = '\0';
- pxl8_info("Running embedded cart");
+ pxl8_info("running embedded cart");
} else {
- pxl8_error("Failed to load embedded cart");
+ pxl8_error("failed to load embedded cart");
return PXL8_ERROR_INITIALIZATION_FAILED;
}
} else if (cart_path || !has_embedded) {
@@ -183,7 +174,7 @@ pxl8_result pxl8_init(pxl8* sys, i32 argc, char* argv[]) {
char* original_cwd = getcwd(NULL, 0);
sys->cart = pxl8_cart_create();
if (!sys->cart) {
- pxl8_error("Failed to create cart");
+ pxl8_error("failed to create cart");
return PXL8_ERROR_INITIALIZATION_FAILED;
}
if (pxl8_cart_load(sys->cart, cart_path) == PXL8_OK) {
@@ -192,7 +183,7 @@ pxl8_result pxl8_init(pxl8* sys, i32 argc, char* argv[]) {
strncpy(game->script_path, "main.fnl", sizeof(game->script_path) - 1);
game->script_path[sizeof(game->script_path) - 1] = '\0';
} else {
- pxl8_error("Failed to load cart: %s", cart_path);
+ pxl8_error("failed to load cart: %s", cart_path);
return PXL8_ERROR_INITIALIZATION_FAILED;
}
free(original_cwd);
@@ -227,19 +218,22 @@ pxl8_result pxl8_update(pxl8* sys) {
}
pxl8_game* game = sys->game;
-
u64 current_time = sys->hal->get_ticks();
f32 dt = (f32)(current_time - game->last_time) / 1000000000.0f;
game->last_time = current_time;
game->time += dt;
-
game->fps_accumulator += dt;
game->fps_frame_count++;
+
if (game->fps_accumulator >= 1.0f) {
game->fps = (f32)game->fps_frame_count / game->fps_accumulator;
if (!game->repl_mode) {
- pxl8_debug("FPS: %.1f (%.2fms)", game->fps, (game->fps_accumulator / game->fps_frame_count) * 1000.0f);
+ pxl8_debug(
+ "FPS: %.1f (%.2fms)",
+ game->fps,
+ (game->fps_accumulator / game->fps_frame_count) * 1000.0f
+ );
}
game->fps_accumulator = 0.0f;
game->fps_frame_count = 0;
@@ -252,37 +246,30 @@ pxl8_result pxl8_update(pxl8* sys) {
pxl8_script_call_function(game->script, "init");
}
- game->repl = pxl8_script_repl_create();
- if (game->repl) {
- fprintf(stderr, "\033[38;2;184;187;38m[pxl8 REPL]\033[0m Fennel %s - Tab for completions, Ctrl-D to exit\n", "1.5.1");
-
- if (pxl8_script_load_module(game->script, "pxl8") != PXL8_OK) {
- fprintf(stderr, "Warning: Failed to setup pxl8 global: %s\n", pxl8_script_get_last_error(game->script));
- }
-
- pxl8_script_repl_init(game->repl);
- game->repl_started = true;
+ if (pxl8_script_load_module(game->script, "pxl8") != PXL8_OK) {
+ const char* err_msg = pxl8_script_get_last_error(game->script);
+ pxl8_error("failed to setup pxl8 global: %s", err_msg);
}
+
+ sys->repl = pxl8_repl_create();
+ game->repl_started = true;
}
- if (game->repl_mode && game->repl) {
- if (pxl8_script_repl_should_quit(game->repl)) {
- game->running = false;
- }
+ if (game->repl_mode && sys->repl) {
+ if (pxl8_repl_should_quit(sys->repl)) game->running = false;
- pxl8_script_repl_command* cmd = pxl8_script_repl_pop_command(game->repl);
+ pxl8_repl_command* cmd = pxl8_repl_pop_command(sys->repl);
if (cmd) {
- pxl8_result result = pxl8_script_eval_repl(game->script, pxl8_script_repl_command_buffer(cmd));
+ pxl8_result result = pxl8_script_eval_repl(game->script, pxl8_repl_command_buffer(cmd));
if (result != PXL8_OK) {
if (pxl8_script_is_incomplete_input(game->script)) {
} else {
pxl8_error("%s", pxl8_script_get_last_error(game->script));
- pxl8_script_repl_clear_accumulator(game->repl);
+ pxl8_repl_clear_accumulator(sys->repl);
}
} else {
- pxl8_script_repl_clear_accumulator(game->repl);
+ pxl8_repl_clear_accumulator(sys->repl);
}
- pxl8_script_repl_eval_complete(game->repl);
}
}
@@ -296,9 +283,7 @@ pxl8_result pxl8_update(pxl8* sys) {
}
pxl8_result pxl8_frame(pxl8* sys) {
- if (!sys || !sys->game) {
- return PXL8_ERROR_INVALID_ARGUMENT;
- }
+ if (!sys || !sys->game) return PXL8_ERROR_INVALID_ARGUMENT;
pxl8_game* game = sys->game;
pxl8_bounds bounds = pxl8_gfx_get_bounds(game->gfx);
@@ -306,7 +291,7 @@ pxl8_result pxl8_frame(pxl8* sys) {
if (game->script_loaded) {
pxl8_result frame_result = pxl8_script_call_function(game->script, "frame");
if (frame_result == PXL8_ERROR_SCRIPT_ERROR) {
- pxl8_error("Error calling frame: %s", pxl8_script_get_last_error(game->script));
+ pxl8_error("error calling frame: %s", pxl8_script_get_last_error(game->script));
}
} else {
pxl8_clear(game->gfx, 32);
@@ -331,13 +316,13 @@ pxl8_result pxl8_frame(pxl8* sys) {
memset(game->input.keys_released, 0, sizeof(game->input.keys_released));
memset(game->input.mouse_buttons_pressed, 0, sizeof(game->input.mouse_buttons_pressed));
memset(game->input.mouse_buttons_released, 0, sizeof(game->input.mouse_buttons_released));
+
+ game->frame_count++;
game->input.mouse_dx = 0;
game->input.mouse_dy = 0;
game->input.mouse_wheel_x = 0;
game->input.mouse_wheel_y = 0;
- game->frame_count++;
-
return PXL8_OK;
}
@@ -346,14 +331,7 @@ void pxl8_quit(pxl8* sys) {
pxl8_game* game = sys->game;
- if (game->repl_mode && game->repl) {
- fprintf(stderr, "\r\033[K");
- fflush(stderr);
- pxl8_script_repl_shutdown(game->repl);
- pxl8_script_repl_destroy(game->repl);
- }
-
- pxl8_info("Shutting down");
+ pxl8_info("shutting down");
if (sys->cart) {
pxl8_cart_unmount(sys->cart);
@@ -361,6 +339,10 @@ void pxl8_quit(pxl8* sys) {
pxl8_gfx_destroy(game->gfx);
pxl8_script_destroy(game->script);
+
+ if (sys->repl) {
+ pxl8_repl_destroy(sys->repl);
+ }
}
bool pxl8_is_running(const pxl8* sys) {
diff --git a/src/pxl8_anim.c b/src/pxl8_anim.c
index e6d0468..740cbbf 100644
--- a/src/pxl8_anim.c
+++ b/src/pxl8_anim.c
@@ -5,7 +5,7 @@
#include "pxl8_ase.h"
#include "pxl8_atlas.h"
-#include "pxl8_macros.h"
+#include "pxl8_log.h"
#define PXL8_ANIM_MAX_STATES 32
diff --git a/src/pxl8_ase.c b/src/pxl8_ase.c
index cf277ec..9c3ed34 100644
--- a/src/pxl8_ase.c
+++ b/src/pxl8_ase.c
@@ -13,7 +13,7 @@
#include
#include "pxl8_io.h"
-#include "pxl8_macros.h"
+#include "pxl8_log.h"
static pxl8_result parse_ase_header(pxl8_stream* stream, pxl8_ase_header* header) {
header->file_size = pxl8_read_u32(stream);
diff --git a/src/pxl8_atlas.c b/src/pxl8_atlas.c
index 1da4c97..5653399 100644
--- a/src/pxl8_atlas.c
+++ b/src/pxl8_atlas.c
@@ -6,7 +6,7 @@
#include
#include "pxl8_color.h"
-#include "pxl8_macros.h"
+#include "pxl8_log.h"
typedef struct pxl8_skyline_fit {
bool found;
diff --git a/src/pxl8_bsp.c b/src/pxl8_bsp.c
index f335799..f7a3b37 100644
--- a/src/pxl8_bsp.c
+++ b/src/pxl8_bsp.c
@@ -6,7 +6,7 @@
#include "pxl8_gfx.h"
#include "pxl8_io.h"
-#include "pxl8_macros.h"
+#include "pxl8_log.h"
#define BSP_VERSION 29
diff --git a/src/pxl8_cart.c b/src/pxl8_cart.c
index 96acf39..c9620ff 100644
--- a/src/pxl8_cart.c
+++ b/src/pxl8_cart.c
@@ -7,7 +7,7 @@
#include
#include
-#include "pxl8_macros.h"
+#include "pxl8_log.h"
#define PXL8_CART_MAGIC 0x43585850
#define PXL8_CART_VERSION 1
@@ -329,7 +329,6 @@ void pxl8_cart_unmount(pxl8_cart* cart) {
if (pxl8_current_cart == cart) {
pxl8_current_cart = NULL;
}
- pxl8_info("Unmounted cart: %s", cart->name);
}
const char* pxl8_cart_get_base_path(const pxl8_cart* cart) {
diff --git a/src/pxl8_game.h b/src/pxl8_game.h
index 90bb8a5..ab7f3ee 100644
--- a/src/pxl8_game.h
+++ b/src/pxl8_game.h
@@ -17,7 +17,6 @@ typedef struct pxl8_game {
f32 fps;
pxl8_input_state input;
- pxl8_script_repl* repl;
bool repl_mode;
bool repl_started;
diff --git a/src/pxl8_gen.c b/src/pxl8_gen.c
index ec6f083..c03cc91 100644
--- a/src/pxl8_gen.c
+++ b/src/pxl8_gen.c
@@ -3,7 +3,7 @@
#include
#include
-#include "pxl8_macros.h"
+#include "pxl8_log.h"
typedef struct room_grid {
u8* cells;
diff --git a/src/pxl8_gfx.c b/src/pxl8_gfx.c
index 32c42fe..8511cfa 100644
--- a/src/pxl8_gfx.c
+++ b/src/pxl8_gfx.c
@@ -9,7 +9,7 @@
#include "pxl8_color.h"
#include "pxl8_font.h"
#include "pxl8_hal.h"
-#include "pxl8_macros.h"
+#include "pxl8_log.h"
#include "pxl8_math.h"
#include "pxl8_sys.h"
#include "pxl8_types.h"
diff --git a/src/pxl8_log.c b/src/pxl8_log.c
new file mode 100644
index 0000000..7611f4f
--- /dev/null
+++ b/src/pxl8_log.c
@@ -0,0 +1,103 @@
+#include "pxl8_log.h"
+#include "pxl8_repl.h"
+
+#include
+#include
+#include
+#include
+
+#define PXL8_LOG_COLOR_ERROR "\033[38;2;251;73;52m"
+#define PXL8_LOG_COLOR_WARN "\033[38;2;250;189;47m"
+#define PXL8_LOG_COLOR_INFO "\033[38;2;184;187;38m"
+#define PXL8_LOG_COLOR_DEBUG "\033[38;2;131;165;152m"
+#define PXL8_LOG_COLOR_TRACE "\033[38;2;211;134;155m"
+#define PXL8_LOG_COLOR_RESET "\033[0m"
+
+static pxl8_log* g_log = NULL;
+
+void pxl8_log_init(pxl8_log* log) {
+ g_log = log;
+ g_log->level = PXL8_LOG_LEVEL_DEBUG;
+}
+
+void pxl8_log_set_level(pxl8_log_level level) {
+ if (g_log) g_log->level = level;
+}
+
+static void log_timestamp(char* buffer, size_t size) {
+ time_t now = time(NULL);
+ struct tm* tm_info = localtime(&now);
+ strftime(buffer, size, "%H:%M:%S", tm_info);
+}
+
+static void log_output(const char* color, const char* level,
+ const char* file, int line, const char* fmt, va_list args) {
+ char buffer[4096];
+ char timestamp[16];
+ log_timestamp(timestamp, sizeof(timestamp));
+
+ int pos = 0;
+ if (file) {
+ pos = snprintf(buffer, sizeof(buffer), "%s[%s %s]" PXL8_LOG_COLOR_RESET " %s:%d: ",
+ color, timestamp, level, file, line);
+ } else {
+ pos = snprintf(buffer, sizeof(buffer), "%s[%s %s]" PXL8_LOG_COLOR_RESET " ",
+ color, timestamp, level);
+ }
+
+ if (pos > 0 && pos < (int)sizeof(buffer)) {
+ vsnprintf(buffer + pos, sizeof(buffer) - pos, fmt, args);
+ }
+
+ strncat(buffer, "\n", sizeof(buffer) - strlen(buffer) - 1);
+
+ if (!pxl8_repl_push_log(buffer)) {
+ printf("%s", buffer);
+ fflush(stdout);
+ }
+}
+
+void pxl8_log_write_trace(const char* file, int line, const char* fmt, ...) {
+ if (!g_log || g_log->level > PXL8_LOG_LEVEL_TRACE) return;
+
+ va_list args;
+ va_start(args, fmt);
+ log_output(PXL8_LOG_COLOR_TRACE, "TRACE", file, line, fmt, args);
+ va_end(args);
+}
+
+void pxl8_log_write_debug(const char* file, int line, const char* fmt, ...) {
+ if (!g_log || g_log->level > PXL8_LOG_LEVEL_DEBUG) return;
+
+ va_list args;
+ va_start(args, fmt);
+ log_output(PXL8_LOG_COLOR_DEBUG, "DEBUG", file, line, fmt, args);
+ va_end(args);
+}
+
+void pxl8_log_write_info(const char* fmt, ...) {
+ if (!g_log || g_log->level > PXL8_LOG_LEVEL_INFO) return;
+
+ va_list args;
+ va_start(args, fmt);
+ log_output(PXL8_LOG_COLOR_INFO, "INFO", NULL, 0, fmt, args);
+ va_end(args);
+}
+
+void pxl8_log_write_warn(const char* file, int line, const char* fmt, ...) {
+ if (!g_log || g_log->level > PXL8_LOG_LEVEL_WARN) return;
+
+ va_list args;
+ va_start(args, fmt);
+ log_output(PXL8_LOG_COLOR_WARN, "WARN", file, line, fmt, args);
+ va_end(args);
+}
+
+void pxl8_log_write_error(const char* file, int line, const char* fmt, ...) {
+ if (!g_log || g_log->level > PXL8_LOG_LEVEL_ERROR) return;
+
+ va_list args;
+ va_start(args, fmt);
+ log_output(PXL8_LOG_COLOR_ERROR, "ERROR", file, line, fmt, args);
+ va_end(args);
+}
diff --git a/src/pxl8_log.h b/src/pxl8_log.h
new file mode 100644
index 0000000..00dad40
--- /dev/null
+++ b/src/pxl8_log.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include
+
+typedef enum {
+ PXL8_LOG_LEVEL_TRACE = 0,
+ PXL8_LOG_LEVEL_DEBUG = 1,
+ PXL8_LOG_LEVEL_INFO = 2,
+ PXL8_LOG_LEVEL_WARN = 3,
+ PXL8_LOG_LEVEL_ERROR = 4,
+} pxl8_log_level;
+
+typedef struct pxl8_log {
+ pxl8_log_level level;
+} pxl8_log;
+
+void pxl8_log_init(pxl8_log* log);
+void pxl8_log_set_level(pxl8_log_level level);
+
+void pxl8_log_write_trace(const char* file, int line, const char* fmt, ...);
+void pxl8_log_write_debug(const char* file, int line, const char* fmt, ...);
+void pxl8_log_write_info(const char* fmt, ...);
+void pxl8_log_write_warn(const char* file, int line, const char* fmt, ...);
+void pxl8_log_write_error(const char* file, int line, const char* fmt, ...);
+
+#define pxl8_trace(...) pxl8_log_write_trace(__FILE__, __LINE__, __VA_ARGS__)
+#define pxl8_debug(...) pxl8_log_write_debug(__FILE__, __LINE__, __VA_ARGS__)
+#define pxl8_info(...) pxl8_log_write_info(__VA_ARGS__)
+#define pxl8_warn(...) pxl8_log_write_warn(__FILE__, __LINE__, __VA_ARGS__)
+#define pxl8_error(...) pxl8_log_write_error(__FILE__, __LINE__, __VA_ARGS__)
diff --git a/src/pxl8_macros.h b/src/pxl8_macros.h
index 809e370..5fb1532 100644
--- a/src/pxl8_macros.h
+++ b/src/pxl8_macros.h
@@ -1,98 +1,5 @@
#pragma once
-#include
-#include
-
-#define PXL8_LOG_ERROR "\033[38;2;251;73;52m"
-#define PXL8_LOG_SUCCESS "\033[38;2;254;128;25m"
-#define PXL8_LOG_WARN "\033[38;2;250;189;47m"
-#define PXL8_LOG_INFO "\033[38;2;184;187;38m"
-#define PXL8_LOG_DEBUG "\033[38;2;131;165;152m"
-#define PXL8_LOG_TRACE "\033[38;2;211;134;155m"
-#define PXL8_LOG_MUTED "\033[38;2;168;153;132m"
-#define PXL8_LOG_RESET "\033[0m"
-
-typedef enum {
- PXL8_LOG_LEVEL_TRACE = 0,
- PXL8_LOG_LEVEL_DEBUG = 1,
- PXL8_LOG_LEVEL_INFO = 2,
- PXL8_LOG_LEVEL_WARN = 3,
- PXL8_LOG_LEVEL_ERROR = 4,
-} pxl8_log_level;
-
-#ifndef PXL8_LOG_LEVEL
- // Temporary: Always use DEBUG level for benchmarking
- #define PXL8_LOG_LEVEL PXL8_LOG_LEVEL_DEBUG
-#endif
-
-static pxl8_log_level pxl8_current_log_level = PXL8_LOG_LEVEL;
-
-static inline void pxl8_log_timestamp(char* buffer, size_t size) {
- time_t now = time(NULL);
- struct tm* tm_info = localtime(&now);
- strftime(buffer, size, "%H:%M:%S", tm_info);
-}
-
-#define pxl8_trace(...) \
- do { \
- if (pxl8_current_log_level <= PXL8_LOG_LEVEL_TRACE) { \
- char timestamp[16]; \
- pxl8_log_timestamp(timestamp, sizeof(timestamp)); \
- fprintf(stderr, "\r\033[K" PXL8_LOG_TRACE "[%s TRACE]" PXL8_LOG_RESET \
- " %s:%d: ", timestamp, __FILE__, __LINE__); \
- fprintf(stderr, __VA_ARGS__); \
- fprintf(stderr, "\n"); \
- } \
- } while(0)
-
-#define pxl8_debug(...) \
- do { \
- if (pxl8_current_log_level <= PXL8_LOG_LEVEL_DEBUG) { \
- char timestamp[16]; \
- pxl8_log_timestamp(timestamp, sizeof(timestamp)); \
- fprintf(stderr, "\r\033[K" PXL8_LOG_DEBUG "[%s DEBUG]" PXL8_LOG_RESET \
- " %s:%d: ", timestamp, __FILE__, __LINE__); \
- fprintf(stderr, __VA_ARGS__); \
- fprintf(stderr, "\n"); \
- } \
- } while(0)
-
-#define pxl8_error(...) \
- do { \
- if (pxl8_current_log_level <= PXL8_LOG_LEVEL_ERROR) { \
- char timestamp[16]; \
- pxl8_log_timestamp(timestamp, sizeof(timestamp)); \
- fprintf(stderr, "\r\033[K" PXL8_LOG_ERROR "[%s ERROR]" PXL8_LOG_RESET \
- " %s:%d: ", timestamp, __FILE__, __LINE__); \
- fprintf(stderr, __VA_ARGS__); \
- fprintf(stderr, "\n"); \
- } \
- } while(0)
-
-#define pxl8_warn(...) \
- do { \
- if (pxl8_current_log_level <= PXL8_LOG_LEVEL_WARN) { \
- char timestamp[16]; \
- pxl8_log_timestamp(timestamp, sizeof(timestamp)); \
- fprintf(stderr, "\r\033[K" PXL8_LOG_WARN "[%s WARN]" PXL8_LOG_RESET \
- " %s:%d: ", timestamp, __FILE__, __LINE__); \
- fprintf(stderr, __VA_ARGS__); \
- fprintf(stderr, "\n"); \
- } \
- } while(0)
-
-#define pxl8_info(...) \
- do { \
- if (pxl8_current_log_level <= PXL8_LOG_LEVEL_INFO) { \
- char timestamp[16]; \
- pxl8_log_timestamp(timestamp, sizeof(timestamp)); \
- fprintf(stdout, "\r\033[K" PXL8_LOG_INFO "[%s INFO]" PXL8_LOG_RESET \
- " ", timestamp); \
- fprintf(stdout, __VA_ARGS__); \
- fprintf(stdout, "\n"); \
- } \
- } while(0)
-
#ifndef pxl8_min
#define pxl8_min(a, b) ((a) < (b) ? (a) : (b))
#endif
diff --git a/src/pxl8_rec.c b/src/pxl8_rec.c
index 3538640..9c750ec 100644
--- a/src/pxl8_rec.c
+++ b/src/pxl8_rec.c
@@ -1,6 +1,6 @@
#include "pxl8_rec.h"
-#include "pxl8_macros.h"
+#include "pxl8_log.h"
#include
#include
diff --git a/src/pxl8_repl.c b/src/pxl8_repl.c
new file mode 100644
index 0000000..75ace26
--- /dev/null
+++ b/src/pxl8_repl.c
@@ -0,0 +1,303 @@
+#include "pxl8_repl.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#define PXL8_MAX_REPL_COMMAND_SIZE 4096
+#define PXL8_REPL_QUEUE_SIZE 8
+
+struct pxl8_repl_command {
+ char buffer[PXL8_MAX_REPL_COMMAND_SIZE];
+};
+
+struct pxl8_repl {
+ char commands[PXL8_REPL_QUEUE_SIZE][PXL8_MAX_REPL_COMMAND_SIZE];
+ atomic_uint cmd_write_idx;
+ atomic_uint cmd_read_idx;
+
+ char logs[PXL8_REPL_QUEUE_SIZE][PXL8_MAX_REPL_COMMAND_SIZE];
+ atomic_uint log_write_idx;
+ atomic_uint log_read_idx;
+
+ atomic_bool should_quit;
+ pthread_t thread;
+ char accumulator[PXL8_MAX_REPL_COMMAND_SIZE];
+ pxl8_repl_command command;
+};
+
+static pxl8_repl* g_repl = NULL;
+
+static void pxl8_repl_completion(const char* buf, linenoiseCompletions* lc) {
+ const char* fennel_keywords[] = {
+ "fn", "let", "var", "set", "global", "local",
+ "if", "when", "do", "while", "for", "each",
+ "lambda", "λ", "partial", "macro", "macros",
+ "require", "include", "import-macros",
+ "values", "select", "table", "length",
+ ".", "..", ":", "->", "->>", "-?>", "-?>>",
+ "doto", "match", "case", "pick-values",
+ "collect", "icollect", "accumulate"
+ };
+
+ const char* pxl8_functions[] = {
+ "pxl8.clr", "pxl8.pixel", "pxl8.get_pixel",
+ "pxl8.line", "pxl8.rect", "pxl8.rect_fill",
+ "pxl8.circle", "pxl8.circle_fill", "pxl8.text",
+ "pxl8.get_screen", "pxl8.info", "pxl8.warn",
+ "pxl8.error", "pxl8.debug", "pxl8.trace"
+ };
+
+ size_t buf_len = strlen(buf);
+
+ for (size_t i = 0; i < sizeof(fennel_keywords) / sizeof(fennel_keywords[0]); i++) {
+ if (strncmp(buf, fennel_keywords[i], buf_len) == 0) {
+ linenoiseAddCompletion(lc, fennel_keywords[i]);
+ }
+ }
+
+ for (size_t i = 0; i < sizeof(pxl8_functions) / sizeof(pxl8_functions[0]); i++) {
+ if (strncmp(buf, pxl8_functions[i], buf_len) == 0) {
+ linenoiseAddCompletion(lc, pxl8_functions[i]);
+ }
+ }
+}
+
+static char* pxl8_repl_hints(const char* buf, int* color, int* bold) {
+ if (strncmp(buf, "pxl8.", 5) == 0 && strlen(buf) == 5) {
+ *color = 35;
+ *bold = 0;
+ return "clr|pixel|line|rect|circle|text|get_screen";
+ }
+
+ if (strcmp(buf, "(fn") == 0) {
+ *color = 36;
+ *bold = 0;
+ return " [args] body)";
+ }
+
+ if (strcmp(buf, "(let") == 0) {
+ *color = 36;
+ *bold = 0;
+ return " [bindings] body)";
+ }
+
+ return NULL;
+}
+
+static void pxl8_repl_flush_logs(pxl8_repl* repl) {
+ u32 log_read_idx = atomic_load(&repl->log_read_idx);
+ u32 log_write_idx = atomic_load(&repl->log_write_idx);
+ while (log_read_idx != log_write_idx) {
+ printf("%s", repl->logs[log_read_idx]);
+ atomic_store(&repl->log_read_idx, (log_read_idx + 1) % PXL8_REPL_QUEUE_SIZE);
+ log_read_idx = atomic_load(&repl->log_read_idx);
+ log_write_idx = atomic_load(&repl->log_write_idx);
+ }
+ fflush(stdout);
+}
+
+static void* pxl8_repl_thread(void* arg) {
+ pxl8_repl* repl = (pxl8_repl*)arg;
+
+ printf("[pxl8 REPL] Fennel 1.6.0 - Tab for completion, Ctrl-D to exit\n");
+ fflush(stdout);
+
+ struct linenoiseState ls;
+ char input_buf[PXL8_MAX_REPL_COMMAND_SIZE];
+ bool editing = false;
+ bool stopped_for_logs = false;
+
+ struct pollfd pfd = {
+ .fd = STDIN_FILENO,
+ .events = POLLIN
+ };
+
+ while (!atomic_load(&repl->should_quit)) {
+ u32 log_read_idx = atomic_load(&repl->log_read_idx);
+ u32 log_write_idx = atomic_load(&repl->log_write_idx);
+
+ if (log_read_idx != log_write_idx) {
+ if (editing) {
+ linenoiseEditStop(&ls);
+ editing = false;
+ stopped_for_logs = true;
+ }
+ while (log_read_idx != log_write_idx) {
+ printf("%s", repl->logs[log_read_idx]);
+ fflush(stdout);
+ atomic_store(&repl->log_read_idx, (log_read_idx + 1) % PXL8_REPL_QUEUE_SIZE);
+ log_read_idx = atomic_load(&repl->log_read_idx);
+ log_write_idx = atomic_load(&repl->log_write_idx);
+ }
+ continue;
+ }
+
+ if (!editing && !atomic_load(&repl->should_quit)) {
+ if (stopped_for_logs) {
+ struct timespec ts = {.tv_sec = 0, .tv_nsec = 5000000};
+ nanosleep(&ts, NULL);
+ stopped_for_logs = false;
+ continue;
+ }
+ const char* prompt = (repl->accumulator[0] != '\0') ? ".. " : ">> ";
+ if (linenoiseEditStart(&ls, STDIN_FILENO, STDOUT_FILENO, input_buf, sizeof(input_buf), prompt) == -1) {
+ atomic_store(&repl->should_quit, true);
+ break;
+ }
+ editing = true;
+ }
+
+ if (poll(&pfd, 1, 1) <= 0) continue;
+
+ char* line = linenoiseEditFeed(&ls);
+
+ if (line == NULL) {
+ atomic_store(&repl->should_quit, true);
+ break;
+ }
+
+ if (line == linenoiseEditMore) continue;
+
+ linenoiseEditStop(&ls);
+ editing = false;
+
+ bool in_multiline = (repl->accumulator[0] != '\0');
+
+ if (strlen(line) > 0 || in_multiline) {
+ if (!in_multiline) {
+ linenoiseHistoryAdd(line);
+ linenoiseHistorySave(".pxl8_history");
+ }
+
+ if (repl->accumulator[0] != '\0') {
+ strncat(repl->accumulator, "\n",
+ PXL8_MAX_REPL_COMMAND_SIZE - strlen(repl->accumulator) - 1);
+ }
+ strncat(repl->accumulator, line,
+ PXL8_MAX_REPL_COMMAND_SIZE - strlen(repl->accumulator) - 1);
+
+ u32 write_idx = atomic_load(&repl->cmd_write_idx);
+ u32 read_idx = atomic_load(&repl->cmd_read_idx);
+ u32 next_write = (write_idx + 1) % PXL8_REPL_QUEUE_SIZE;
+
+ if (next_write != read_idx) {
+ strncpy(repl->commands[write_idx], repl->accumulator, PXL8_MAX_REPL_COMMAND_SIZE - 1);
+ repl->commands[write_idx][PXL8_MAX_REPL_COMMAND_SIZE - 1] = '\0';
+ atomic_store(&repl->cmd_write_idx, next_write);
+ }
+ }
+
+ linenoiseFree(line);
+
+ while (atomic_load(&repl->cmd_write_idx) != atomic_load(&repl->cmd_read_idx)) {
+ struct timespec ts = {.tv_sec = 0, .tv_nsec = 1000000};
+ nanosleep(&ts, NULL);
+ }
+ }
+
+ if (editing) linenoiseEditStop(&ls);
+
+ pxl8_repl_flush_logs(repl);
+
+ return NULL;
+}
+
+pxl8_repl* pxl8_repl_create(void) {
+ pxl8_repl* repl = (pxl8_repl*)calloc(1, sizeof(pxl8_repl));
+ if (!repl) return NULL;
+
+ repl->accumulator[0] = '\0';
+ atomic_store(&repl->cmd_write_idx, 0);
+ atomic_store(&repl->cmd_read_idx, 0);
+ atomic_store(&repl->log_write_idx, 0);
+ atomic_store(&repl->log_read_idx, 0);
+ atomic_store(&repl->should_quit, false);
+
+ linenoiseHistorySetMaxLen(100);
+ linenoiseSetMultiLine(1);
+ linenoiseSetCompletionCallback(pxl8_repl_completion);
+ linenoiseSetHintsCallback(pxl8_repl_hints);
+ linenoiseHistoryLoad(".pxl8_history");
+
+ g_repl = repl;
+
+ if (pthread_create(&repl->thread, NULL, pxl8_repl_thread, repl) != 0) {
+ free(repl);
+ g_repl = NULL;
+ return NULL;
+ }
+
+ return repl;
+}
+
+void pxl8_repl_destroy(pxl8_repl* repl) {
+ if (!repl) return;
+
+ atomic_store(&repl->should_quit, true);
+
+ struct timespec ts = {.tv_sec = 0, .tv_nsec = 2000000};
+ nanosleep(&ts, NULL);
+
+ printf("\r\033[K");
+ fflush(stdout);
+
+ pthread_join(repl->thread, NULL);
+ pxl8_repl_flush_logs(repl);
+
+ g_repl = NULL;
+
+ system("stty sane 2>/dev/null");
+ free(repl);
+}
+
+pxl8_repl_command* pxl8_repl_pop_command(pxl8_repl* repl) {
+ if (!repl) return NULL;
+
+ u32 read_idx = atomic_load(&repl->cmd_read_idx);
+ u32 write_idx = atomic_load(&repl->cmd_write_idx);
+
+ if (read_idx == write_idx) return NULL;
+
+ strncpy(repl->command.buffer, repl->commands[read_idx], PXL8_MAX_REPL_COMMAND_SIZE - 1);
+ repl->command.buffer[PXL8_MAX_REPL_COMMAND_SIZE - 1] = '\0';
+
+ atomic_store(&repl->cmd_read_idx, (read_idx + 1) % PXL8_REPL_QUEUE_SIZE);
+
+ return &repl->command;
+}
+
+const char* pxl8_repl_command_buffer(pxl8_repl_command* cmd) {
+ return cmd ? cmd->buffer : NULL;
+}
+
+bool pxl8_repl_should_quit(pxl8_repl* repl) {
+ return repl ? atomic_load(&repl->should_quit) : false;
+}
+
+bool pxl8_repl_push_log(const char* message) {
+ if (!g_repl || !message) return false;
+
+ u32 write_idx = atomic_load(&g_repl->log_write_idx);
+ u32 read_idx = atomic_load(&g_repl->log_read_idx);
+ u32 next_write = (write_idx + 1) % PXL8_REPL_QUEUE_SIZE;
+
+ if (next_write != read_idx) {
+ strncpy(g_repl->logs[write_idx], message, PXL8_MAX_REPL_COMMAND_SIZE - 1);
+ g_repl->logs[write_idx][PXL8_MAX_REPL_COMMAND_SIZE - 1] = '\0';
+ atomic_store(&g_repl->log_write_idx, next_write);
+ }
+ return true;
+}
+
+void pxl8_repl_clear_accumulator(pxl8_repl* repl) {
+ if (!repl) return;
+ repl->accumulator[0] = '\0';
+}
diff --git a/src/pxl8_repl.h b/src/pxl8_repl.h
new file mode 100644
index 0000000..ee815e2
--- /dev/null
+++ b/src/pxl8_repl.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "pxl8_types.h"
+
+typedef struct pxl8_repl pxl8_repl;
+typedef struct pxl8_repl_command pxl8_repl_command;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+pxl8_repl* pxl8_repl_create(void);
+void pxl8_repl_destroy(pxl8_repl* repl);
+
+pxl8_repl_command* pxl8_repl_pop_command(pxl8_repl* repl);
+const char* pxl8_repl_command_buffer(pxl8_repl_command* cmd);
+bool pxl8_repl_push_log(const char* message);
+void pxl8_repl_clear_accumulator(pxl8_repl* repl);
+bool pxl8_repl_should_quit(pxl8_repl* repl);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/pxl8_save.c b/src/pxl8_save.c
index 936427b..2bec3fa 100644
--- a/src/pxl8_save.c
+++ b/src/pxl8_save.c
@@ -16,7 +16,7 @@
#define PATH_SEP '/'
#endif
-#include "pxl8_macros.h"
+#include "pxl8_log.h"
typedef struct {
u32 magic;
diff --git a/src/pxl8_script.c b/src/pxl8_script.c
index 410126d..94b2df1 100644
--- a/src/pxl8_script.c
+++ b/src/pxl8_script.c
@@ -14,7 +14,7 @@
#include "pxl8_cart.h"
#include "pxl8_embed.h"
-#include "pxl8_macros.h"
+#include "pxl8_log.h"
#include "pxl8_gui.h"
struct pxl8_script {
@@ -991,29 +991,6 @@ bool pxl8_script_check_reload(pxl8_script* script) {
return false;
}
-#include
-#include
-#include
-
-#define PXL8_REPL_RING_BUFFER_SIZE 64
-
-struct pxl8_script_repl_command {
- char buffer[PXL8_MAX_REPL_COMMAND_SIZE];
-};
-
-struct pxl8_script_repl {
- pthread_t thread;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- pxl8_script_repl_command ring_buffer[PXL8_REPL_RING_BUFFER_SIZE];
- u32 head;
- u32 tail;
- bool running;
- bool should_quit;
- bool waiting_for_eval;
- char accumulator[PXL8_MAX_REPL_COMMAND_SIZE];
-};
-
static bool pxl8_script_is_incomplete_error(const char* error) {
if (!error) return false;
return strstr(error, "expected closing delimiter") != NULL ||
@@ -1022,206 +999,6 @@ static bool pxl8_script_is_incomplete_error(const char* error) {
strstr(error, "unexpected end") != NULL;
}
-static void pxl8_script_repl_completion(const char* buf, linenoiseCompletions* lc) {
- const char* fennel_keywords[] = {
- "fn", "let", "var", "set", "global", "local",
- "if", "when", "do", "while", "for", "each",
- "lambda", "λ", "partial", "macro", "macros",
- "require", "include", "import-macros",
- "values", "select", "table", "length",
- ".", "..", ":", "->", "->>", "-?>", "-?>>",
- "doto", "match", "case", "pick-values",
- "collect", "icollect", "accumulate"
- };
-
- const char* pxl8_functions[] = {
- "pxl8.clr", "pxl8.pixel", "pxl8.get_pixel",
- "pxl8.line", "pxl8.rect", "pxl8.rect_fill",
- "pxl8.circle", "pxl8.circle_fill", "pxl8.text",
- "pxl8.get_screen", "pxl8.info", "pxl8.warn",
- "pxl8.error", "pxl8.debug", "pxl8.trace"
- };
-
- size_t buf_len = strlen(buf);
-
- for (size_t i = 0; i < sizeof(fennel_keywords) / sizeof(fennel_keywords[0]); i++) {
- if (strncmp(buf, fennel_keywords[i], buf_len) == 0) {
- linenoiseAddCompletion(lc, fennel_keywords[i]);
- }
- }
-
- for (size_t i = 0; i < sizeof(pxl8_functions) / sizeof(pxl8_functions[0]); i++) {
- if (strncmp(buf, pxl8_functions[i], buf_len) == 0) {
- linenoiseAddCompletion(lc, pxl8_functions[i]);
- }
- }
-}
-
-static char* pxl8_script_repl_hints(const char* buf, int* color, int* bold) {
- if (strncmp(buf, "pxl8.", 5) == 0 && strlen(buf) == 5) {
- *color = 35;
- *bold = 0;
- return "clr|pixel|line|rect|circle|text|get_screen";
- }
-
- if (strcmp(buf, "(fn") == 0) {
- *color = 36;
- *bold = 0;
- return " [args] body)";
- }
-
- if (strcmp(buf, "(let") == 0) {
- *color = 36;
- *bold = 0;
- return " [bindings] body)";
- }
-
- return NULL;
-}
-
-static void* pxl8_script_repl_stdin_thread(void* user_data) {
- pxl8_script_repl* repl = (pxl8_script_repl*)user_data;
- char* line;
- const char* history_file = ".pxl8_history";
-
- linenoiseHistorySetMaxLen(100);
- linenoiseSetMultiLine(1);
- linenoiseSetCompletionCallback(pxl8_script_repl_completion);
- linenoiseSetHintsCallback(pxl8_script_repl_hints);
- linenoiseHistoryLoad(history_file);
-
- while (repl->running) {
- pthread_mutex_lock(&repl->mutex);
- bool in_multiline = (repl->accumulator[0] != '\0');
- pthread_mutex_unlock(&repl->mutex);
-
- const char* prompt = in_multiline ? ".. " : ">> ";
- line = linenoise(prompt);
-
- if (!line) break;
-
- if (strlen(line) > 0 || in_multiline) {
- if (!in_multiline) {
- linenoiseHistoryAdd(line);
- linenoiseHistorySave(history_file);
- }
-
- pthread_mutex_lock(&repl->mutex);
-
- if (repl->accumulator[0] != '\0') {
- strncat(repl->accumulator, "\n", PXL8_MAX_REPL_COMMAND_SIZE - strlen(repl->accumulator) - 1);
- }
- strncat(repl->accumulator, line, PXL8_MAX_REPL_COMMAND_SIZE - strlen(repl->accumulator) - 1);
-
- u32 next_tail = (repl->tail + 1) % PXL8_REPL_RING_BUFFER_SIZE;
- if (next_tail != repl->head) {
- size_t len = strlen(repl->accumulator);
- size_t copy_len = len < PXL8_MAX_REPL_COMMAND_SIZE - 1 ? len : PXL8_MAX_REPL_COMMAND_SIZE - 1;
- memcpy(repl->ring_buffer[repl->tail].buffer, repl->accumulator, copy_len);
- repl->ring_buffer[repl->tail].buffer[copy_len] = '\0';
- repl->tail = next_tail;
- repl->waiting_for_eval = true;
-
- while (repl->waiting_for_eval && repl->running) {
- pthread_cond_wait(&repl->cond, &repl->mutex);
- }
- }
- pthread_mutex_unlock(&repl->mutex);
- }
- linenoiseFree(line);
- }
-
- pthread_mutex_lock(&repl->mutex);
- repl->should_quit = true;
- pthread_mutex_unlock(&repl->mutex);
-
- return NULL;
-}
-
-pxl8_script_repl* pxl8_script_repl_create(void) {
- pxl8_script_repl* repl = (pxl8_script_repl*)calloc(1, sizeof(pxl8_script_repl));
- return repl;
-}
-
-void pxl8_script_repl_destroy(pxl8_script_repl* repl) {
- if (!repl) return;
- free(repl);
-}
-
-void pxl8_script_repl_init(pxl8_script_repl* repl) {
- if (!repl) return;
-
- repl->head = 0;
- repl->tail = 0;
- repl->running = true;
- repl->waiting_for_eval = false;
- repl->accumulator[0] = '\0';
- pthread_mutex_init(&repl->mutex, NULL);
- pthread_cond_init(&repl->cond, NULL);
- pthread_create(&repl->thread, NULL, pxl8_script_repl_stdin_thread, repl);
-}
-
-void pxl8_script_repl_shutdown(pxl8_script_repl* repl) {
- if (!repl) return;
-
- pthread_mutex_lock(&repl->mutex);
- repl->running = false;
- pthread_cond_signal(&repl->cond);
- pthread_mutex_unlock(&repl->mutex);
-
- pthread_cancel(repl->thread);
- pthread_join(repl->thread, NULL);
-
- system("stty sane 2>/dev/null");
-
- pthread_cond_destroy(&repl->cond);
- pthread_mutex_destroy(&repl->mutex);
-}
-
-pxl8_script_repl_command* pxl8_script_repl_pop_command(pxl8_script_repl* repl) {
- if (!repl) return NULL;
-
- pthread_mutex_lock(&repl->mutex);
- pxl8_script_repl_command* cmd = NULL;
- if (repl->head != repl->tail) {
- cmd = &repl->ring_buffer[repl->head];
- repl->head = (repl->head + 1) % PXL8_REPL_RING_BUFFER_SIZE;
- }
- pthread_mutex_unlock(&repl->mutex);
- return cmd;
-}
-
-const char* pxl8_script_repl_command_buffer(pxl8_script_repl_command* cmd) {
- return cmd ? cmd->buffer : NULL;
-}
-
-bool pxl8_script_repl_should_quit(pxl8_script_repl* repl) {
- if (!repl) return false;
-
- pthread_mutex_lock(&repl->mutex);
- bool should_quit = repl->should_quit;
- pthread_mutex_unlock(&repl->mutex);
-
- return should_quit;
-}
-
-void pxl8_script_repl_eval_complete(pxl8_script_repl* repl) {
- if (!repl) return;
-
- pthread_mutex_lock(&repl->mutex);
- repl->waiting_for_eval = false;
- pthread_cond_signal(&repl->cond);
- pthread_mutex_unlock(&repl->mutex);
-}
-
-void pxl8_script_repl_clear_accumulator(pxl8_script_repl* repl) {
- if (!repl) return;
-
- pthread_mutex_lock(&repl->mutex);
- repl->accumulator[0] = '\0';
- pthread_mutex_unlock(&repl->mutex);
-}
-
bool pxl8_script_is_incomplete_input(pxl8_script* script) {
if (!script) return false;
return pxl8_script_is_incomplete_error(script->last_error);
diff --git a/src/pxl8_script.h b/src/pxl8_script.h
index e492618..d47a467 100644
--- a/src/pxl8_script.h
+++ b/src/pxl8_script.h
@@ -4,8 +4,6 @@
#include "pxl8_types.h"
typedef struct pxl8_script pxl8_script;
-typedef struct pxl8_script_repl pxl8_script_repl;
-typedef struct pxl8_script_repl_command pxl8_script_repl_command;
#ifdef __cplusplus
extern "C" {
@@ -32,17 +30,6 @@ pxl8_result pxl8_script_load_module(pxl8_script* script, const char* module_name
pxl8_result pxl8_script_run_fennel_file(pxl8_script* script, const char* filename);
pxl8_result pxl8_script_run_file(pxl8_script* script, const char* filename);
-pxl8_script_repl* pxl8_script_repl_create(void);
-void pxl8_script_repl_destroy(pxl8_script_repl* repl);
-
-void pxl8_script_repl_clear_accumulator(pxl8_script_repl* repl);
-const char* pxl8_script_repl_command_buffer(pxl8_script_repl_command* cmd);
-void pxl8_script_repl_eval_complete(pxl8_script_repl* repl);
-void pxl8_script_repl_init(pxl8_script_repl* repl);
-pxl8_script_repl_command* pxl8_script_repl_pop_command(pxl8_script_repl* repl);
-bool pxl8_script_repl_should_quit(pxl8_script_repl* repl);
-void pxl8_script_repl_shutdown(pxl8_script_repl* repl);
-
#ifdef __cplusplus
}
#endif
diff --git a/src/pxl8_sdl3.c b/src/pxl8_sdl3.c
index fff4e95..e009ea2 100644
--- a/src/pxl8_sdl3.c
+++ b/src/pxl8_sdl3.c
@@ -6,7 +6,7 @@
#include "pxl8_atlas.h"
#include "pxl8_color.h"
-#include "pxl8_macros.h"
+#include "pxl8_log.h"
#include "pxl8_rec.h"
#include "pxl8_sys.h"
diff --git a/src/pxl8_tilemap.c b/src/pxl8_tilemap.c
index de12d6e..ca129e9 100644
--- a/src/pxl8_tilemap.c
+++ b/src/pxl8_tilemap.c
@@ -4,6 +4,7 @@
#include
#include "pxl8_ase.h"
+#include "pxl8_log.h"
#include "pxl8_macros.h"
#include "pxl8_tilesheet.h"
diff --git a/src/pxl8_tilesheet.c b/src/pxl8_tilesheet.c
index 6b7225e..01fd5bb 100644
--- a/src/pxl8_tilesheet.c
+++ b/src/pxl8_tilesheet.c
@@ -5,7 +5,7 @@
#include "pxl8_ase.h"
#include "pxl8_color.h"
-#include "pxl8_macros.h"
+#include "pxl8_log.h"
#include "pxl8_tilemap.h"
struct pxl8_tilesheet {
diff --git a/src/pxl8_transition.c b/src/pxl8_transition.c
index cc056cd..e648617 100644
--- a/src/pxl8_transition.c
+++ b/src/pxl8_transition.c
@@ -3,7 +3,7 @@
#include
#include
-#include "pxl8_macros.h"
+#include "pxl8_log.h"
#include "pxl8_math.h"
pxl8_transition* pxl8_transition_create(pxl8_transition_type type, f32 duration) {
diff --git a/src/pxl8_world.c b/src/pxl8_world.c
index a56b0b7..36d3975 100644
--- a/src/pxl8_world.c
+++ b/src/pxl8_world.c
@@ -5,7 +5,7 @@
#include "pxl8_bsp.h"
#include "pxl8_gen.h"
-#include "pxl8_macros.h"
+#include "pxl8_log.h"
#include "pxl8_math.h"
struct pxl8_world {