/*

reinhard@finalmedia.de
Do 30. Jul 02:23:12 CEST 2026
Public Domain

fretina v0.27
Filesystem Retina Gaussian Splat RGBA Renderer
im djb codestil. Gibt rgba frames auf stdout aus
und liest Kamerabefehle auf stdin.

musl-gcc Q -O3 -march=x86-64 -static-pie -fPIE -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro -Wl,-z,now -o retina retina.c

*/

#include <unistd.h>
#include <stdint.h>
#include <fcntl.h>
#include <stdlib.h>

#define MAX_W 3840
#define MAX_H 2160
#define SEC_SZ 500
#define SPL_SZ 16
#define P_SZ 4194304
#define TOT_SPL (P_SZ / SPL_SZ)
#define M_SZ 262144
#define TPF 100
#define W_OFF 5000
#define IN_SZ 4096

static int32_t scr_w = 640;
static int32_t scr_h = 480;

static uint8_t ret_o[MAX_H * MAX_W];
static uint8_t ret_r[MAX_H * MAX_W];
static uint8_t ret_g[MAX_H * MAX_W];
static uint8_t ret_b[MAX_H * MAX_W];
static int16_t ret_z[MAX_H * MAX_W];
static uint8_t fb[MAX_H * MAX_W * 4];

struct __attribute__((packed)) Splat {
    int16_t x, y, z;
    uint16_t t0;
    uint8_t dt;
    uint8_t op;
    uint8_t r, g, b, pad;
};
static struct Splat p_pool[TOT_SPL];
static int8_t m_pool[TOT_SPL];

static const int16_t INT_SIN[64] = {
    0, 25, 49, 73, 96, 118, 139, 159, 177, 193, 208, 220, 231, 239, 245, 249,
    251, 249, 245, 239, 231, 220, 208, 193, 177, 159, 139, 118, 96, 73, 49, 25,
    0, -25, -49, -73, -96, -118, -139, -159, -177, -193, -208, -220, -231, -239, -245, -249,
    -251, -249, -245, -239, -231, -220, -208, -193, -177, -159, -139, -118, -96, -73, -49, -25
};

static int16_t get_sin(int32_t angle) {
    return INT_SIN[angle & 63];
}

static int16_t get_cos(int32_t angle) {
    return INT_SIN[(angle + 16) & 63];
}

static int32_t get_atan2(int32_t y, int32_t x) {
    if (x == 0 && y == 0) return 0;
    int32_t abs_x = (x < 0) ? -x : x;
    int32_t abs_y = (y < 0) ? -y : y;
    int32_t angle;
    if (abs_x >= abs_y) {
        angle = (abs_y * 8) / (abs_x + 1);
        if (x < 0) angle = 32 - angle;
    } else {
        angle = 16 - (abs_x * 8) / (abs_y + 1);
        if (x < 0) angle = 16 + angle;
    }
    if (y < 0) return 64 - angle;
    return angle;
}

static const char LUT[100][2] = {
    {'0','0'},{'0','1'},{'0','2'},{'0','3'},{'0','4'},{'0','5'},{'0','6'},{'0','7'},{'0','8'},{'0','9'},
    {'1','0'},{'1','1'},{'1','2'},{'1','3'},{'1','4'},{'1','5'},{'1','6'},{'1','7'},{'1','8'},{'1','9'},
    {'2','0'},{'2','1'},{'2','2'},{'2','3'},{'2','4'},{'2','5'},{'2','6'},{'2','7'},{'2','8'},{'2','9'},
    {'3','0'},{'3','1'},{'3','2'},{'3','3'},{'3','4'},{'3','5'},{'3','6'},{'3','7'},{'3','8'},{'3','9'},
    {'4','0'},{'4','1'},{'4','2'},{'4','3'},{'4','4'},{'4','5'},{'4','6'},{'4','7'},{'4','8'},{'4','9'},
    {'5','0'},{'5','1'},{'5','2'},{'5','3'},{'5','4'},{'5','5'},{'5','6'},{'5','7'},{'5','8'},{'5','9'},
    {'6','0'},{'6','1'},{'6','2'},{'6','3'},{'6','4'},{'6','5'},{'6','6'},{'6','7'},{'6','8'},{'6','9'},
    {'7','0'},{'7','1'},{'7','2'},{'7','3'},{'7','4'},{'7','5'},{'7','6'},{'7','7'},{'7','8'},{'7','9'},
    {'8','0'},{'8','1'},{'8','2'},{'8','3'},{'8','4'},{'8','5'},{'8','6'},{'8','7'},{'8','8'},{'8','9'},
    {'9','0'},{'9','1'},{'9','2'},{'9','3'},{'9','4'},{'9','5'},{'9','6'},{'9','7'},{'9','8'},{'9','9'}
};

static void gen_path(char *buf, int32_t cx, int32_t cy, int32_t cz, uint16_t gt, char sfx) {
    uint32_t tb = (gt / TPF) * TPF;
    int32_t ax = cx + W_OFF; if (ax < 0) ax = 0; else if (ax > 9999) ax = 9999;
    int32_t ay = cy + W_OFF; if (ay < 0) ay = 0; else if (ay > 9999) ay = 9999;
    int32_t az = cz + W_OFF; if (az < 0) az = 0; else if (az > 9999) az = 9999;

    uint32_t ux = (uint32_t)ax, uy = (uint32_t)ay, uz = (uint32_t)az;
    uint32_t hx = ux / 100, lx = ux - (hx * 100);
    buf[16] = LUT[hx][0]; buf[17] = LUT[hx][1]; buf[18] = LUT[lx][0]; buf[19] = LUT[lx][1];

    uint32_t hy = uy / 100, ly = uy - (hy * 100);
    buf[11] = LUT[hy][0]; buf[12] = LUT[hy][1]; buf[13] = LUT[ly][0]; buf[14] = LUT[ly][1];

    uint32_t hz = uz / 100, lz = uz - (hz * 100);
    buf[6] = LUT[hz][0]; buf[7] = LUT[hz][1]; buf[8] = LUT[lz][0]; buf[9] = LUT[lz][1];

    uint32_t ht = tb / 1000, rt = tb - (ht * 1000), mt = rt / 100, lt = rt - (mt * 100);
    buf[21] = LUT[ht][0]; buf[22] = LUT[ht][1]; buf[23] = '0' + mt; buf[24] = LUT[lt][0]; buf[25] = LUT[lt][1];
    buf[27] = sfx;
}

int main(void) {
    char path[] = "W0000/5000/5000/5000/00000.?";
    int32_t active_t = -1; uint16_t gt = 0;

    int32_t p[8]; int p_idx = 0, cur_v = 0, is_neg = 0, in_cmd = 0;

    static char in_buf[IN_SZ]; int in_bytes = 0, in_ptr = 0;
    char *w_env = getenv("SCREEN_WIDTH"), *h_env = getenv("SCREEN_HEIGHT");
    if (w_env) { int32_t v = atoi(w_env); if (v > 0 && v <= MAX_W) scr_w = v; }
    if (h_env) { int32_t v = atoi(h_env); if (v > 0 && v <= MAX_H) scr_h = v; }

    size_t tot_px = (size_t)(scr_w * scr_h), fb_sz = tot_px * 4;

    while (1) {
        if (in_ptr >= in_bytes) {
            in_bytes = read(0, in_buf, IN_SZ); if (in_bytes <= 0) break;
            in_ptr = 0;
        }
        char c = in_buf[in_ptr++];

        if (c == 'W') {
            in_cmd = 0;
            int valid = 1;
            char next_bytes[5];
            for (int i = 0; i < 5; i++) {
                if (in_ptr >= in_bytes) {
                    in_bytes = read(0, in_buf, IN_SZ);
                    if (in_bytes <= 0) { valid = 0; break; }
                    in_ptr = 0;
                }
                next_bytes[i] = in_buf[in_ptr++];
            }

            if (valid && next_bytes[0] == ' ' &&
                next_bytes[1] >= '0' && next_bytes[1] <= '9' &&
                next_bytes[2] >= '0' && next_bytes[2] <= '9' &&
                next_bytes[3] >= '0' && next_bytes[3] <= '9' &&
                next_bytes[4] >= '0' && next_bytes[4] <= '9') {

                path[1] = next_bytes[1];
                path[2] = next_bytes[2];
                path[3] = next_bytes[3];
                path[4] = next_bytes[4];
                active_t = -1;
            }
            continue;
        }

        if (c == 'P') { in_cmd = 1; p_idx = 0; cur_v = 0; is_neg = 0; continue; }

        if (in_cmd) {
            if (c == '-') { is_neg = 1; continue; }
            if (c >= '0' && c <= '9') { cur_v = (cur_v * 10) + (c - '0'); continue; }
            if (c == ' ' || c == '\n') {
                if (is_neg) cur_v = -cur_v;
                if (p_idx < 7) p[p_idx++] = cur_v;
                cur_v = 0; is_neg = 0;

                if (c == '\n' || p_idx == 7) {
                    in_cmd = 0; if (p_idx < 7) continue;

                    int32_t cam_x = p[0] + 250, cam_y = p[1] + 250, cam_z = p[2];
                    int32_t pan = p[3], tilt = p[4], zoom = p[5], b_shift = p[6];

                    gt++; int req_t = gt / TPF;
                    int32_t Sx = cam_x / SEC_SZ, Sy = cam_y / SEC_SZ, Sz = cam_z / SEC_SZ;
                    int32_t key = (Sx * 73856093) ^ (Sy * 19349663) ^ (Sz * 83492791) ^ req_t;

                    if (key != active_t) {
                        gen_path(path, Sx, Sy, Sz, gt, 'p');
                        int fd = open(path, O_RDONLY);
                        if (fd >= 0) {
                            posix_fadvise(fd, 0, P_SZ, POSIX_FADV_WILLNEED | POSIX_FADV_SEQUENTIAL);
                            size_t r = 0; while (r < P_SZ) { ssize_t n = read(fd, ((char*)p_pool) + r, P_SZ - r); if (n <= 0) break; r += n; }
                            posix_fadvise(fd, 0, P_SZ, POSIX_FADV_DONTNEED); close(fd);
                        }

                        path[27] = 'm';
                        fd = open(path, O_RDONLY);
                        if (fd >= 0) {
                            posix_fadvise(fd, 0, M_SZ, POSIX_FADV_WILLNEED | POSIX_FADV_SEQUENTIAL);
                            size_t r = 0; while (r < M_SZ) { ssize_t n = read(fd, ((char*)m_pool) + r, M_SZ - r); if (n <= 0) break; r += n; }
                            posix_fadvise(fd, 0, M_SZ, POSIX_FADV_DONTNEED); close(fd);
                        }
                        active_t = key;
                    }

                    for (size_t i = 0; i < tot_px; i++) { ret_o[i] = 0; ret_r[i] = 0; ret_g[i] = 0; ret_b[i] = 0; ret_z[i] = 32767; }

                    uint16_t relative_zeit = gt % TPF;
                    int32_t live_phase_int = gt / 2;

                    for (uint32_t i = 0; i < TOT_SPL; i++) {
                        if (p_pool[i].op == 0) continue;
                        if (p_pool[i].dt < 100 && (relative_zeit < p_pool[i].t0 || relative_zeit > (p_pool[i].t0 + p_pool[i].dt))) continue;

                        int32_t px = p_pool[i].x;
                        int32_t py = p_pool[i].y;
                        int32_t pz = p_pool[i].z;

                        if (p_pool[i].dt >= 100) {
                            int32_t dx = px - 250;
                            int32_t dy = py - 250;
                            int32_t dz = pz - 250;
                            int32_t angle_idx = get_atan2(dz, dx);
                            int32_t s_wave = get_sin(dy / 8 + live_phase_int);
                            int32_t c_wave = get_cos(angle_idx * 3);
                            int32_t wave_scale = 1024 + ((s_wave * c_wave) >> 10);
                            px = 250 + ((dx * wave_scale) >> 10);
                            pz = 250 + ((dz * wave_scale) >> 10);
                        }

                        int32_t rx = px - cam_x, ry = py - cam_y, rz = pz - cam_z;
                        if (rz <= 10) continue;

                        rx += (pan * rz) >> 9; ry += (tilt * rz) >> 9;
                        int32_t fl = 300 + zoom;
                        int32_t sx = (rx * fl) / rz + (scr_w / 2), sy = (ry * fl) / rz + (scr_h / 2);
                        sy = scr_h - sy;

                        int32_t fr = (fl * 4) / rz; if (fr < 1) fr = 1;
                        int32_t emaj = fr, emin = fr, sch = 0;
                        if (p_pool[i].dt >= 100) { emaj = (fr * ((px % 4) + 2)) >> 1; sch = (rx * fr) / 400; }

                        if (emaj > 24) emaj = 24; if (emin > 24) emin = 24;
                        int32_t max_r = (emaj > emin) ? emaj : emin;

                        int32_t x0 = sx - max_r; if (x0 < 0) x0 = 0; int32_t x1 = sx + max_r; if (x1 >= scr_w) x1 = scr_w - 1;
                        int32_t y0 = sy - max_r; if (y0 < 0) y0 = 0; int32_t y1 = sy + max_r; if (y1 >= scr_h) y1 = scr_h - 1;
                        if (x0 > x1 || y0 > y1) continue;

                        int32_t v_dz = (500 - rz) >> 2, sh = ((int32_t)m_pool[i] * v_dz) >> 6;
                        int32_t rf = p_pool[i].r + sh, gf = p_pool[i].g + sh, bf = p_pool[i].b + sh;
                        if (rf > 255) rf = 255; else if (rf < 0) rf = 0;
                        if (gf > 255) gf = 255; else if (gf < 0) gf = 0;
                        if (bf > 255) bf = 255; else if (bf < 0) bf = 0;

                        int32_t ia = (1048576 / (emin * emin + 1)), ic = (1048576 / (emaj * emaj + 1)), ib = (sch * 524288) / (max_r * max_r + 1);
                        int32_t dx0 = x0 - sx, step_x0 = (2 * dx0 + 1) * ia, step_xy0 = 2 * ib;

                        for (int32_t y = y0; y <= y1; y++) {
                            int32_t dy = y - sy, row = y * scr_w, dx = dx0;
                            int32_t ed = (dx * dx * ia) + (2 * dx * dy * ib) + (dy * dy * ic);
                            int32_t st_x = step_x0, st_xy = dy * step_xy0;

                            for (int32_t x = x0; x <= x1; x++) {
                                int32_t cur_d = ed >> 10; ed += st_x + st_xy; st_x += (2 * ia);
                                if (cur_d > 1024) continue;

                                int32_t idx = row + x; if (rz > ret_z[idx]) continue;
                                uint32_t ao = ret_o[idx]; if (ao >= 255) continue;

                                uint32_t bo = (p_pool[i].op * (1024 - cur_d)) >> 10; if (bo == 0) continue;
                                uint32_t ba = (bo * (255 - ao)) >> 8;

                                ret_r[idx] += (rf * ba) >> 8; ret_g[idx] += (gf * ba) >> 8; ret_b[idx] += (bf * ba) >> 8; ret_o[idx] += ba;
                                if (bo >= 230) ret_z[idx] = (int16_t)rz;
                            }
                        }
                    }

                    size_t f_idx = 0;
                    for (size_t i = 0; i < tot_px; i++) { fb[f_idx++] = ret_r[i]; fb[f_idx++] = ret_g[i]; fb[f_idx++] = ret_b[i]; fb[f_idx++] = ret_o[i]; }

                    size_t w_b = 0;
                    while (w_b < fb_sz) { ssize_t res = write(1, fb + w_b, fb_sz - w_b); if (res < 0) exit(1); w_b += res; }
                }
            }
        }
    }
    return 0;
}

