From 1ac9f44aad35febf742835885d143f980babe487 Mon Sep 17 00:00:00 2001 From: WormHeamer Date: Fri, 7 Nov 2025 18:22:50 -0500 Subject: junk --- main.c | 312 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 270 insertions(+), 42 deletions(-) diff --git a/main.c b/main.c index ccc3cdc..b95e9cb 100644 --- a/main.c +++ b/main.c @@ -1,56 +1,284 @@ +#define _POSIX_C_SOURCE 202511L + +#include +#include +#include + +#include "wrmr.h" #include "vui.h" -int x = 0, y = 0; +/* input buffer */ -int main(void) { - vui_init(); +int inbuf[32] = { 0 }; +#define INBUF_MASK 0x1f +u32 inbuf_start = 0, inbuf_end = 0; + +int pop_input(void) { + /* + int k = inbuf[inbuf_start]; + inbuf[inbuf_start] = 0; + if (k) inbuf_start = (inbuf_start + 1) & INBUF_MASK; + return k; + */ + if (inbuf_start == inbuf_end) return 0; + int k = inbuf[inbuf_start++]; + inbuf_start &= INBUF_MASK; + return k; +} + +void push_input(int i) { + inbuf[inbuf_end++] = i; + inbuf_end &= INBUF_MASK; +} - int x = 0, y = 0; - int scroll_x = 0, scroll_y = 0; +u32 poll_input_iter = 0; +int poll_input(u32 ms) { + struct timespec start; + clock_gettime(CLOCK_MONOTONIC, &start); + u64 n = start.tv_nsec + (ms * 1000000); + struct timespec stop = { + .tv_sec = start.tv_sec + n / 1000000000, + .tv_nsec = n % 1000000000 + }; + poll_input_iter = 0; for (;;) { - static int last_left = 0; - int left = (COLS - (72 < COLS ? 72 : COLS - 2)) >> 1; - int right = COLS - left; - int top = 5; - int bottom = LINES - 5; - - //vui_fill(' ', FG_WHITE | BG_BLUE); - //vui_fill_rect(' ', FG_BLACK | BG_BLACK, left + 2, top + 1, right - left, bottom - top); - //vui_fill_rect(' ', FG_BLACK | BG_WHITE, left, top, right - left, bottom - top); - - if (y < top) { scroll_y = top - y; } - if (y > bottom) { scroll_y = bottom - y; } - - scroll_x += left - last_left; - last_left = left; - - int sdx = scroll_x > 0 ? 1 : (scroll_x < 0 ? -1 : 0); - sdx = scroll_x; - int sdy = scroll_y > 0 ? 1 : (scroll_y < 0 ? -1 : 0); - vui_scroll(sdx, sdy); - x += sdx; - y += sdy; - scroll_x -= sdx; - scroll_y -= sdy; + poll_input_iter++; + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + i64 ns_rem = (stop.tv_sec - now.tv_sec) * 1000000000 + (i64)stop.tv_nsec - (i64)now.tv_nsec; + i64 ms_rem = ns_rem / 1000000; + if (ns_rem < 1) break; + if (vui_wait_for_input(ms_rem)) push_input(vui_key()); + else break; + } + return 0; +} - vui_blit(); +/* program */ + +#define WIDTH 32 +#define HEIGHT 32 + +typedef enum { + TILE_FLOOR, + TILE_SNK_ODD, + TILE_SNK_EVEN, + TILE_APPLE, + TILE_MAX +} Tile; + +const VuiAttr tile_attr[TILE_MAX][2] = { + { FG_BLUE | BG_BLACK, FG_BLUE | BG_BLACK }, + { FG_YELLOW | BG_BLACK, FG_BYELLOW | BG_BLACK }, + { FG_GREEN | BG_BLACK, FG_BGREEN | BG_BLACK }, + { FG_BGREEN | BG_BLACK, FG_BRED | BG_BLACK }, +}; + +const VuiChar tile_chr[TILE_MAX][2] = { + { ' ', '.' }, + { '[', ']' }, + { '[', ']' }, + { '`', 'o' } +}; + +Tile board[HEIGHT][WIDTH]; + +typedef enum { + DIR_LEFT, + DIR_UP, + DIR_RIGHT, + DIR_DOWN +} Dir; + +#define DIR_IS_Y(d) ((d)&1) +#define DIR_IS_X(d) (~(d)&1) +#define DIR_SIGN(d) ((d)&2 ? 1 : -1) +#define DIR_FLIP(d) (((d) + 2) & 3) +#define DIR_DX(d) (DIR_IS_X(d) * DIR_SIGN(d)) +#define DIR_DY(d) (DIR_IS_Y(d) * DIR_SIGN(d)) - int animating = !!scroll_x || !!scroll_y; - if (animating && !vui_wait_for_input(50)) continue; - VuiKey c = vui_key(); - if (c == KEY_INVALID || c == KEY_ESC) goto done; - if (x >= right) { - x = left; +typedef struct { + i16 x, y; +} SnkSeg; + +#define SNK_SEG_MAX (WIDTH * HEIGHT) + +typedef struct { + Dir dir; + u32 len; + SnkSeg seg[SNK_SEG_MAX]; +} Snake; + +Snake snk = { 0 }; + +typedef struct { + i16 x, y; +} Apple; + +#define APPLE_MAX 32 +Apple apple[APPLE_MAX]; + +void replace_apple(u32 i) { + Apple *a = &apple[i]; + do { + a->x = rand() % WIDTH; + a->y = rand() % HEIGHT; + } while (board[a->y][a->x] != TILE_FLOOR); +} + +void place_apple(void) { + for (u32 i = 0; i < APPLE_MAX; i++) { + replace_apple(i); + } +} + +void brd_clear(void) { + for (u32 y = 0; y < HEIGHT; y++) { + for (u32 x = 0; x < WIDTH; x++) { + board[y][x] = TILE_FLOOR; + } + } +} + +void brd_draw(void) { + /* + u32 left = COLS / 2 - WIDTH; + u32 top = LINES / 2 - HEIGHT / 2; + */ + u32 left = COLS / 2 - snk.seg->x * 2; + u32 top = LINES / 2 - snk.seg->y; + + u32 right = left + WIDTH * 2; + u32 bottom = top + HEIGHT; + for (u32 y = 0; y < HEIGHT; y++) { + vui_chr(left - 1, top + y, u'❘'); + vui_chr(right + 1, top + y, u'❘'); + for (u32 x = 0; x < WIDTH; x++) { + Tile t = board[y][x]; + vui_chra(left + 2 * x, top + y, tile_chr[t][0], tile_attr[t][0]); + vui_chra(left + 2 * x + 1, top + y, tile_chr[t][1], tile_attr[t][1]); + vui_puts(left + 2 * x, top - 1, "──"); + vui_puts(left + 2 * x, bottom, "──"); + } + } + vui_chr(left - 1, top - 1, u'┌'); + vui_chr(right + 1, top - 1, u'┐'); + vui_chr(left - 1, bottom, u'└'); + vui_chr(right + 1, bottom, u'┘'); + /* + u32 x = 0; + u32 y = 1; + for (u32 i = 0; i < sizeof inbuf / sizeof *inbuf; i++) { + int within = (i >= inbuf_start && i < inbuf_end); + if (inbuf_end < inbuf_start) { + within = i >= inbuf_start || i < inbuf_end; + } + VuiAttr a = within ? FG_BCYAN : FG_BBLACK; + if (i == inbuf_start) vui_chra(x, bottom + y - 1, 'v', FG_BCYAN); + if (i == inbuf_end) vui_chra(x + 1, bottom + y - 1, 'v', FG_BMAGENTA); + x += vui_aprintf(x, bottom + y, a, "%6X ", inbuf[i]); + if (x >= COLS - 24) { + x = 0; y += 2; } - static unsigned i = 0; - i++; - int tx = x + vui_aprintf(x, y - 1, (i & 1 ? FG_WHITE : FG_CYAN) | BG_BLACK, "%02X", c); - vui_chra(x++, y, c < 0x20 || c > KEY_UTF8_MAX || c == 0x7f ? 0xfffd : c, FG_BYELLOW | BG_BLUE); - while (x < tx) vui_chra(x++, y, ' ', FG_BYELLOW | BG_BLUE); } -done: + */ +} + +void snk_draw(Snake *s) { + for (u32 i = 0; i < s->len; i++) { + board[s->seg[i].y][s->seg[i].x] = (i / 4) & 1 ? TILE_SNK_ODD : TILE_SNK_EVEN; + } +} + +void apple_draw(void) { + for (u32 i = 0; i < APPLE_MAX; i++) { + board[apple[i].y][apple[i].x] = TILE_APPLE; + } +} + +int alive, paused; + +void draw(void *ctx) { + (void)ctx; + vui_clear(); + + brd_clear(); + snk_draw(&snk); + apple_draw(); + brd_draw(); + + if (!alive) { + vui_puts(COLS/2 - 4, LINES/2, "YOU DIED!"); + } + vui_printf(0, 0, "input polling iterations: %u", poll_input_iter); +} + +void update(void) { + for (u32 i = 0; i < APPLE_MAX; i++) { + if (snk.seg[0].x == apple[i].x && snk.seg[0].y == apple[i].y) { + replace_apple(i); + snk.len++; + break; + } + } + memmove(snk.seg + 1, snk.seg, (SNK_SEG_MAX - 1) * sizeof(SnkSeg)); + + i16 x = snk.seg[0].x + DIR_DX(snk.dir); + i16 y = snk.seg[0].y + DIR_DY(snk.dir); + + if (x < 0 || y < 0 || x >= WIDTH || y >= HEIGHT) { + alive = 0; + return; + } + + for (u32 i = 1; i < snk.len; i++) { + if (snk.seg[i].x == x && snk.seg[i].y == y) { + alive = 0; + return; + } + } + + snk.seg[0].x = x; + snk.seg[0].y = y; + vui_scroll(-DIR_DX(snk.dir) * 2, -DIR_DY(snk.dir)); +} + +void snk_chg_dir(Snake *s, Dir d) { + if (s->len < 2 || d != DIR_FLIP(s->dir)) { + s->dir = d; + } +} + +int main(void) { + srand(time(NULL)); + vui_init(); + snk.dir = DIR_RIGHT; + snk.seg[snk.len++] = (SnkSeg) { 0, 0 }; + alive = 1; + paused = 0; + vui_redraw_fn(draw); + place_apple(); + while (alive) { + poll_input(30); + draw(NULL); + vui_blit(); + switch (pop_input()) { + case 0: break; + case KEY_ESC: goto done; + case KEY_LEFT : case 'j': snk_chg_dir(&snk, DIR_LEFT); break; + case KEY_UP : case 'i': snk_chg_dir(&snk, DIR_UP); break; + case KEY_RIGHT: case 'l': snk_chg_dir(&snk, DIR_RIGHT); break; + case KEY_DOWN : case 'k': snk_chg_dir(&snk, DIR_DOWN); break; + case ' ': paused = !paused; break; + } + if (!paused) update(); + } + draw(NULL); + vui_blit(); + (void)vui_key(); +done: vui_fini(); return 0; } -- cgit v1.2.3