diff --git a/firmware/src/app/ui.c b/firmware/src/app/ui.c index 5edca39..cfe6e19 100644 --- a/firmware/src/app/ui.c +++ b/firmware/src/app/ui.c @@ -41,22 +41,25 @@ static const char *const KNOB_LABEL[NVIEWS][4] = { /* the screen's colours: the cover of Ambient 1: Music for Airports (1978), as the web app and the site. * The map's paper, its ink; the land's greens for the pad (the chord) and the scale, its rivers for the * bells; the bass and the pulse in darker inks. Each layer has a pale tint for the shapes at rest. */ -#define K_BG RGB(246, 238, 181) -#define K_PANEL RGB(255, 251, 224) -#define K_LINE RGB(208, 214, 150) -#define K_DIM RGB(112, 106, 58) -#define K_TEXT RGB(29, 27, 2) -#define K_ACC RGB(64, 128, 124) /* the accent: the page, the knob being turned, a message's word */ -#define K_BELL RGB(84, 153, 149) -#define K_BELL_T RGB(176, 214, 206) -#define K_PAD RGB(112, 142, 62) -#define K_PAD_T RGB(208, 220, 146) -#define K_PULSE RGB(70, 66, 28) -#define K_PULSE_T RGB(214, 214, 160) -#define K_BASS RGB(138, 128, 52) -#define K_BASS_T RGB(222, 218, 160) -#define K_FROST RGB(60, 132, 160) -#define K_FROST_T RGB(170, 210, 216) +/* DoomBox crypt palette: near-black stone, blood red, bone text */ +#define K_BG RGB(12, 6, 8) +#define K_PANEL RGB(26, 10, 14) +#define K_LINE RGB(62, 22, 28) +#define K_DIM RGB(140, 96, 92) +#define K_TEXT RGB(232, 220, 206) +#define K_ACC RGB(220, 38, 38) /* the accent: the page, the knob being turned, a message's word */ +#define K_BELL RGB(239, 68, 68) +#define K_BELL_T RGB(96, 28, 34) +#define K_PAD RGB(168, 42, 56) +#define K_PAD_T RGB(70, 20, 30) +#define K_PULSE RGB(214, 190, 170) +#define K_PULSE_T RGB(60, 36, 36) +#define K_BASS RGB(190, 120, 40) +#define K_BASS_T RGB(70, 40, 20) +#define K_FROST RGB(80, 170, 190) +#define K_FROST_T RGB(24, 56, 66) +#define K_SIGIL RGB(40, 12, 16) +#define K_SIGIL_HI RGB(74, 16, 22) static struct { uint8_t view; @@ -664,10 +667,61 @@ static void polar(int32_t cx, int32_t cy, float r, int i, int n, int32_t *x, int *y = cy - (int32_t)(sy + (sy < 0.0f ? -0.5f : 0.5f)); } +/* DoomBox: a dim pentagram sigil behind the garden */ +static void cv_line_thick(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t r, uint16_t c) +{ + int32_t dx = (x1 > x0) ? (x1 - x0) : (x0 - x1); + int32_t dy = (y1 > y0) ? (y1 - y0) : (y0 - y1); + int32_t sx = (x0 < x1) ? 1 : -1; + int32_t sy = (y0 < y1) ? 1 : -1; + int32_t err = dx - dy; + + for (;;) { + cv_disc(x0, y0, r, c); + if (x0 == x1 && y0 == y1) + break; + { + int32_t e2 = err * 2; + if (e2 > -dy) { + err -= dy; + x0 += sx; + } + if (e2 < dx) { + err += dx; + y0 += sy; + } + } + } +} + +static void draw_sigil(void) +{ + int32_t i; + int32_t x, y; + + for (i = 0; i < 72; i++) { + polar(CX, CY, 72.0f, i, 72, &x, &y); + cv_disc(x, y, 1, K_SIGIL); + polar(CX, CY, 68.0f, i, 72, &x, &y); + cv_disc(x, y, 1, K_SIGIL); + } + + for (i = 0; i < 5; i++) { + int32_t i0 = (i * 2) % 5; + int32_t i1 = (i0 + 2) % 5; + int32_t x0, y0, x1, y1; + + polar(CX, CY, 66.0f, i0, 5, &x0, &y0); + polar(CX, CY, 66.0f, i1, 5, &x1, &y1); + cv_line_thick(x0, y0, x1, y1, 1, K_SIGIL_HI); + } +} + static void draw_ring(void) { uint32_t abs_pool = pool_abs(), chord = 0; int i, l; + draw_sigil(); for (i = 0; i < EN_NPAD; i++) chord |= 1u << (en_chord[i] % 12u); for (l = 0; l < EN_NLOOP; l++) { diff --git a/firmware/src/dsp/amb.c b/firmware/src/dsp/amb.c index 185b56e..4b468d5 100644 --- a/firmware/src/dsp/amb.c +++ b/firmware/src/dsp/amb.c @@ -2,6 +2,7 @@ /* The instrument (amb.h). One compilation unit, -O2. */ #include "amb.h" #include "fastmath.h" +#define DOOM_DRIVE 1.6f /* DoomBox saturation drive */ #ifdef EN_HOST #define EN_POOL @@ -1702,6 +1703,8 @@ static void render_chunk(int32_t *out, uint32_t n, float gain) reverb((rsend[j] * rg + (el + er + xl + xr) * 0.35f * rev_send) * 0.8f, &wl, &wr); l = (mixl[j] + 0.75f * el + 0.3f * xl + 1.3f * wl) * 0.36f * gain; r = (mixr[j] + 0.75f * er + 0.3f * xr + 1.3f * wr) * 0.36f * gain; + l = fm_tanhf(l * DOOM_DRIVE) * (1.0f / DOOM_DRIVE); /* DoomBox: tape-style saturation, unity at low level */ + r = fm_tanhf(r * DOOM_DRIVE) * (1.0f / DOOM_DRIVE); out[2 * j] = (int32_t)(fm_tanhf(l) * 8300000.0f); out[2 * j + 1] = (int32_t)(fm_tanhf(r) * 8300000.0f); }