Merge branch 'unstable'

This commit is contained in:
Jarcode
2018-02-07 20:06:09 -08:00
9 changed files with 201 additions and 87 deletions

15
glava.c
View File

@@ -18,7 +18,7 @@
#include "render.h"
#include "xwin.h"
#define GLAVA_VERSION "1.2"
#define GLAVA_VERSION "1.3"
#ifdef GLAD_DEBUG
#define GLAVA_RELEASE_TYPE_PREFIX "debug, "
#else
@@ -151,6 +151,8 @@ static void copy_cfg(const char* path, const char* dest, bool verbose) {
closedir(dir);
}
#define GLAVA_VERSION_STRING "GLava (glava) " GLAVA_VERSION " (" GLAVA_RELEASE_TYPE ")"
static const char* help_str =
"Usage: %s [OPTIONS]...\n"
"Opens a window with an OpenGL context to draw an audio visualizer.\n"
@@ -165,17 +167,19 @@ static const char* help_str =
"-C, --copy-config creates copies and symbolic links in the user configuration\n"
" directory for glava, copying any files in the root directory\n"
" of the installed shader directory, and linking any modules.\n"
"-V, --version print application version and exit\n"
"\n"
"GLava (glava) " GLAVA_VERSION " (" GLAVA_RELEASE_TYPE ")\n"
GLAVA_VERSION_STRING "\n"
" -- Copyright (C) 2017 Levi Webb\n";
static const char* opt_str = "hve:Cm:";
static const char* opt_str = "hvVe:Cm:";
static struct option p_opts[] = {
{"help", no_argument, 0, 'h'},
{"verbose", no_argument, 0, 'v'},
{"entry", required_argument, 0, 'e'},
{"force-mod", required_argument, 0, 'm'},
{"copy-config", no_argument, 0, 'C'},
{"version", no_argument, 0, 'V'},
{0, 0, 0, 0 }
};
@@ -198,10 +202,15 @@ int main(int argc, char** argv) {
case 'e': entry = optarg; break;
case 'm': force = optarg; break;
case '?': exit(EXIT_FAILURE); break;
case 'V':
puts(GLAVA_VERSION_STRING);
exit(EXIT_SUCCESS);
break;
default:
case 'h':
printf(help_str, argc > 0 ? argv[0] : "glava");
exit(EXIT_SUCCESS);
break;
}
}

View File

@@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#include <errno.h>
@@ -51,7 +52,7 @@ static void se_append(struct sbuf* sbuf, size_t elen, const char* fmt, ...) {
int written;
if ((written = vsnprintf(sbuf->buf + sbuf->at, space, fmt, args)) < 0)
abort();
sbuf->at += space;
sbuf->at += written;
va_end(args);
}
@@ -68,6 +69,42 @@ struct schar {
size_t sz;
};
bool ext_parse_color(const char* str, size_t elem_sz, float** results) {
size_t t, len = strlen(str), i = 0, s = 0;
uint8_t elem_bytes[elem_sz];
/* Ignore '0x' prefix, if present */
if (len >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
len -= 2;
str += 2;
}
for (t = 0; t < len && t < 8; ++t) {
char c = str[t];
uint8_t b;
/* obtain value from character */
switch (c) {
case 'a' ... 'f': b = (c - 'a') + 10; break;
case 'A' ... 'F': b = (c - 'A') + 10; break;
case '0' ... '9': b = c - '0'; break;
default: return false;
}
elem_bytes[s] = b;
if (s >= elem_sz - 1) { /* advance to next element */
uint32_t e = 0; /* component storage */
/* mask storage with input data */
for (size_t v = 0; v < elem_sz; ++v) {
e |= (uint32_t) elem_bytes[v] << (((elem_sz - 1) - v) * 4);
}
/* convert to [0, 1] as floating point value */
*results[i] = (float) e / (float) ((1 << (elem_sz * 4)) - 1);
s = 0;
++i;
} else { /* advance character */
++s;
}
}
return true;
}
/* handle raw arguments for #include and #request directives */
/* NOTE: munmap needs to be called on the result */
static struct schar directive(struct glsl_ext* ext, char** args,
@@ -91,7 +128,8 @@ static struct schar directive(struct glsl_ext* ext, char** args,
int fd = open(path, O_RDONLY);
if (fd == -1) {
parse_error(line, f, "failed to load GLSL shader source specified by #include directive '%s': %s\n",
parse_error(line, f, "failed to load GLSL shader source "
"specified by #include directive '%s': %s\n",
path, strerror(errno));
}
@@ -100,7 +138,8 @@ static struct schar directive(struct glsl_ext* ext, char** args,
char* map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (!map) {
parse_error(line, f, "failed to map GLSL shader source specified by #include directive '%s': %s\n",
parse_error(line, f, "failed to map GLSL shader source "
"specified by #include directive '%s': %s\n",
path, strerror(errno));
}
@@ -128,7 +167,7 @@ static struct schar directive(struct glsl_ext* ext, char** args,
struct request_handler* handler;
bool found = false;
size_t t, i;
size_t t;
for (t = 0; (handler = &ext->handlers[t])->name != NULL; ++t) {
if(!strcmp(handler->name, request)) {
found = true;
@@ -173,10 +212,12 @@ static struct schar directive(struct glsl_ext* ext, char** args,
case '1': { v = true; break; }
case '0': { v = false; break; }
default:
parse_error_s(line, f, "tried to parse invalid raw string into a boolean");
parse_error_s(line, f,
"tried to parse invalid raw string into a boolean");
}
} else {
parse_error_s(line, f, "tried to parse invalid raw string into a boolean");
parse_error_s(line, f,
"tried to parse invalid raw string into a boolean");
}
processed_args[i] = malloc(sizeof(bool));
*(bool*) processed_args[i] = v;
@@ -211,10 +252,11 @@ static struct schar directive(struct glsl_ext* ext, char** args,
void ext_process(struct glsl_ext* ext, const char* f) {
#define LINE_START 0
#define IGNORING 1
#define GLSL 1
#define MACRO 2
#define REQUEST 3
#define INCLUDE 4
#define COLOR 5
struct sbuf sbuf = {
.buf = malloc(256),
@@ -226,12 +268,16 @@ void ext_process(struct glsl_ext* ext, const char* f) {
size_t t;
char at;
int state = LINE_START;
size_t macro_start_idx, arg_start_idx;
size_t macro_start_idx, arg_start_idx, cbuf_idx;
size_t line = 1;
bool quoted = false, arg_start;
char cbuf[9];
char** args = NULL;
size_t args_sz = 0;
bool prev_slash = false, comment = false, comment_line = false, prev_asterix = false,
prev_escape = false, string = false;
for (t = 0; t <= source_len; ++t) {
at = source_len == t ? '\0' : ext->source[t];
if (at == '\n')
@@ -244,40 +290,128 @@ void ext_process(struct glsl_ext* ext, const char* f) {
macro_start_idx = t;
state = MACRO;
continue; }
case ' ':
case '\t':
case '\n':
if (comment && comment_line) {
comment = false;
comment_line = false;
}
case '\t':
case ' ':
goto copy;
default: {
state = IGNORING;
goto copy; }
default: state = GLSL;
/* let execution continue into next state */
}
}
case IGNORING: /* copying GLSL source or unrelated preprocessor syntax */
if (at == '\n') {
state = LINE_START;
case GLSL: /* copying GLSL source or unrelated preprocessor syntax */
{
switch (at) {
case '"':
if (!comment && !prev_escape)
string = !string;
goto normal_char;
case '\\':
if (!comment) {
prev_escape = !prev_escape;
prev_asterix = false;
prev_slash = false;
goto copy;
} else goto normal_char;
case '/':
if (!comment) {
if (prev_slash) {
comment = true;
comment_line = true;
prev_slash = false;
} else prev_slash = true;
} else if (!comment_line) {
if (prev_asterix) {
comment = false;
prev_asterix = false;
}
}
prev_escape = false;
goto copy;
case '*':
if (!comment) {
if (prev_slash) {
comment = true;
prev_slash = false;
}
} else prev_asterix = true;
prev_escape = false;
goto copy;
case '#': {
/* handle hex color syntax */
if (!comment && !string) {
state = COLOR;
cbuf_idx = 0;
continue;
} else goto normal_char;
}
case '\n':
if (comment && comment_line) {
comment = false;
comment_line = false;
}
state = LINE_START;
normal_char:
default:
prev_asterix = false;
prev_slash = false;
prev_escape = false;
goto copy;
}
}
case COLOR: /* parse hex color syntax (#ffffffff -> vec4(1.0, 1.0, 1.0, 1.0)) */
{
switch (at) {
case 'a' ... 'z':
case 'A' ... 'Z':
case '0' ... '9': {
cbuf[cbuf_idx] = at;
++cbuf_idx;
if (cbuf_idx >= 8)
goto emit_color;
else continue;
}
emit_color:
default:
cbuf[cbuf_idx] = '\0'; /* null terminate */
float r = 0.0F, g = 0.0F, b = 0.0F, a = 1.0F;
if (ext_parse_color(cbuf, 2, (float*[]) { &r, &g, &b, &a })) {
se_append(&sbuf, 64, " vec4(%.6f, %.6f, %.6f, %.6f) ", r, g, b, a);
} else {
parse_error(line, f, "Invalid color format '#%s' while "
"parsing GLSL color syntax extension", cbuf);
}
state = at == '\n' ? LINE_START : GLSL;
if (cbuf_idx >= 8)
continue;
else goto copy; /* copy character if it ended the sequence */
}
}
goto copy;
case MACRO: /* processing start of macro */
{
switch (at) {
case '\n':
case ' ':
case '\t':
case '\0':
case '\0':
{
/* end parsing directive */
if (!strncmp("#request", &ext->source[macro_start_idx], t - macro_start_idx)
|| !strncmp("#REQUEST", &ext->source[macro_start_idx], t - macro_start_idx)) {
state = REQUEST;
goto prepare_arg_parse;
} else if (!strncmp("#include", &ext->source[macro_start_idx], t - macro_start_idx)
|| !strncmp("#INCLUDE", &ext->source[macro_start_idx], t - macro_start_idx)) {
} else if (!strncmp("#include", &ext->source[macro_start_idx],
t - macro_start_idx)
|| !strncmp("#INCLUDE", &ext->source[macro_start_idx],
t - macro_start_idx)) {
state = INCLUDE;
goto prepare_arg_parse;
} else {
n_append(&sbuf, t - macro_start_idx, &ext->source[macro_start_idx]);
state = IGNORING;
state = at == '\n' ? LINE_START : GLSL;
goto copy;
}
prepare_arg_parse:

View File

@@ -35,3 +35,4 @@ struct glsl_ext {
void ext_process(struct glsl_ext* ext, const char* f);
void ext_free (struct glsl_ext* ext);
bool ext_parse_color(const char* hex, size_t elem_sz, float** results);

View File

@@ -753,10 +753,10 @@ struct renderer* rd_new(const char** paths, const char* entry, const char* force
#ifdef GLFW_TRANSPARENT_FRAMEBUFFER
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, native_opacity ? GLFW_TRUE : GLFW_FALSE);
gl->use_alpha = false;
if (native_opacity) gl->use_alpha = false;
#elif GLFW_TRANSPARENT
glfwWindowHint(GLFW_TRANSPARENT, native_opacity ? GLFW_TRUE : GLFW_FALSE);
gl->use_alpha = false;
if (native_opacity) gl->use_alpha = false;
#else
if (native_opacity)
printf("WARNING: the linked version of GLFW3 does not have transparency support"
@@ -783,42 +783,9 @@ struct renderer* rd_new(const char** paths, const char* entry, const char* force
&gl->clear_color.b,
&gl->clear_color.a
};
const size_t elem_sz = 2;
char* str = (char*) args[0];
size_t t, len = strlen(str), i = 0, s = 0;
uint8_t elem_bytes[elem_sz];
/* Ignore '0x' prefix, if present */
if (len >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
len -= 2;
str += 2;
}
for (t = 0; t < len && t < 8; ++t) {
char c = str[t];
uint8_t b;
/* obtain value from character */
switch (c) {
case 'a' ... 'f': b = (c - 'a') + 10; break;
case 'A' ... 'F': b = (c - 'A') + 10; break;
case '0' ... '9': b = c - '0'; break;
default:
fprintf(stderr, "Invalid value for `setbg` request: '%s'\n", (char*) args[0]);
exit(EXIT_FAILURE);
}
elem_bytes[s] = b;
if (s >= elem_sz - 1) { /* advance to next element */
uint32_t e = 0; /* component storage */
/* mask storage with input data */
for (size_t v = 0; v < elem_sz; ++v) {
e |= (uint32_t) elem_bytes[v] << (((elem_sz - 1) - v) * 4);
}
/* convert to [0, 1] as floating point value */
*results[i] = (float) e / (float) ((1 << (elem_sz * 4)) - 1);
printf("[DEBUG] component %d value: %d (float: %f)\n", i, e, *results[i]);
s = 0;
++i;
} else { /* advance character */
++s;
}
if (!ext_parse_color((char*) args[0], 2, results)) {
fprintf(stderr, "Invalid value for `setbg` request: '%s'\n", (char*) args[0]);
exit(EXIT_FAILURE);
}
})
},
@@ -1055,6 +1022,16 @@ struct renderer* rd_new(const char** paths, const char* entry, const char* force
abort();
}
if (xwintype) {
xwin_settype(r, xwintype);
free(xwintype);
}
for (size_t t = 0; t < xwinstates_sz; ++t) {
xwin_addstate(r, xwinstates[t]);
}
free(xwinstates);
glfwSetWindowPos(gl->w, gl->geometry[0], gl->geometry[1]);
glfwSetWindowSize(gl->w, gl->geometry[2], gl->geometry[3]);
@@ -1086,7 +1063,7 @@ struct renderer* rd_new(const char** paths, const char* entry, const char* force
struct gl_sfbo* stages;
size_t count = 0;
{
char buf[32];
DIR* dir = opendir(shaders);
@@ -1219,20 +1196,10 @@ struct renderer* rd_new(const char** paths, const char* entry, const char* force
}
overlay(&gl->overlay);
glfwShowWindow(gl->w);
glClearColor(gl->clear_color.r, gl->clear_color.g, gl->clear_color.b, gl->clear_color.a);
if (xwintype) {
xwin_settype(r, xwintype);
free(xwintype);
}
for (size_t t = 0; t < xwinstates_sz; ++t) {
xwin_addstate(r, xwinstates[t]);
}
free(xwinstates);
glfwShowWindow(gl->w);
return r;
}

View File

@@ -7,13 +7,13 @@
/* width (in pixels) of each bar gap */
#define BAR_GAP 2
/* outline color */
#define BAR_OUTLINE vec4(0.15, 0.15, 0.15, 1)
#define BAR_OUTLINE #262626
/* outline width (in pixels, set to 0 to disable outline drawing) */
#define BAR_OUTLINE_WIDTH 0
/* Amplify magnitude of the results each bar displays */
#define AMPLIFY 300
/* Bar color */
#define COLOR (vec4(0.2, 0.4, 0.7, 1) * ((d / 60) + 1))
#define COLOR (#3366b2 * ((d / 60) + 1))
/* Direction that the bars are facing, 0 for inward, 1 for outward */
#define DIRECTION 0
/* Whether to switch left/right audio buffers */

View File

@@ -3,7 +3,7 @@
/* center line thickness (pixels) */
#define C_LINE 2
/* outline color */
#define OUTLINE vec4(0.20, 0.20, 0.20, 1)
#define OUTLINE #333333
/* Amplify magnitude of the results each bar displays */
#define AMPLIFY 150
/* Angle (in radians) for how much to rotate the visualizer */

View File

@@ -17,7 +17,7 @@
/* actual color definition */
#define COLOR vec4((0.3 + RCOL_OFF) + LSTEP, 0.6 - LSTEP, (0.3 + LCOL_OFF) + LSTEP, 1)
/* outline color */
#define OUTLINE vec4(0.15, 0.15, 0.15, 1)
#define OUTLINE #262626
/* 1 to invert (vertically), 0 otherwise */
#define INVERT 0

View File

@@ -4,7 +4,7 @@
/* center line thickness (pixels) */
#define C_LINE 2
/* outline color */
#define OUTLINE vec4(0.20, 0.20, 0.20, 1)
#define OUTLINE #333333
/* number of bars (use even values for best results) */
#define NBARS 180
/* width (in pixels) of each bar*/
@@ -15,8 +15,8 @@
#define BAR_OUTLINE_WIDTH 0
/* Amplify magnitude of the results each bar displays */
#define AMPLIFY 300
/* Bar color */
#define COLOR (vec4(0.8, 0.2, 0.2, 1) * ((d / 40) + 1))
/* Bar color */
#define COLOR (#cc3333 * ((d / 40) + 1))
/* Angle (in radians) for how much to rotate the visualizer */
#define ROTATE (PI / 2)
/* Whether to switch left/right audio buffers */

13
xwin.c
View File

@@ -16,13 +16,16 @@
#include <X11/extensions/XShm.h>
#define GLFW_EXPOSE_NATIVE_X11
/* Hack to make GLFW 3.1 headers work with GLava. We don't use the context APIs from GLFW, but
the old headers require one of them to be selected for exposure in glfw3native.h. */
#if (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR <= 1)
#define GLFW_EXPOSE_NATIVE_GLX
#endif
#include <glad/glad.h>
#include <GLFW/glfw3.h>
/* Hack to make GLFW 3.1 headers work with GLava. We don't use the context APIs from GLFW, but
the old headers require one of them to be selected for exposure in glfw3native.h. */
#if GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR <= 1
#define GLFW_EXPOSE_NATIVE_GLX
#error "GLX defined"
#endif
#include <GLFW/glfw3native.h>
#include "render.h"