// Intro cracktro — 3D FX phases B/C/D (rotozoom, dot sphere, ray corridor).
// Faithful per-pixel ports of ui_freenove_allinone/src/ui/fx/fx_engine.cpp
// (renderMidRotoZoom, renderDotSphere3D, renderRayCorridor) rendered at
// 240x160 in a PSRAM buffer then pixel-doubled to the 480x320 LVGL canvas.
#pragma once

#include <stdbool.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

#define FX3D_W 240
#define FX3D_H 160

typedef enum {
    FX3D_ROTOZOOM   = 0,
    FX3D_DOTSPHERE  = 1,
    FX3D_CORRIDOR   = 2,
    FX3D_STARFIELD  = 3,   // renderStarfield3D — z-flight + rotation + trails
    FX3D_VOXEL      = 4,   // renderVoxelLandscape — raycast heightfield
    FX3D_WIRECUBE   = 5,   // v9 WireCubeFx — Bresenham wireframe cube
    FX3D_MODE_COUNT = 6,
} fx3d_mode_t;

// Allocate the low-res buffer + LUTs/textures (PSRAM). Idempotent.
bool fx3d_init(void);

// Render `mode` at time t_ms into dst (RGB565, dst_w x dst_h) with 2x pixel
// doubling. dst must be exactly FX3D_W*2 x FX3D_H*2; anything else is a no-op.
void fx3d_render(fx3d_mode_t mode, uint32_t t_ms, uint16_t *dst,
                 int dst_w, int dst_h);

#ifdef __cplusplus
}
#endif
