8 Commits

Author SHA1 Message Date
Jarcode
6670c54827 Cleaned up and optimized 'graph' module and its settings, fixes #76 2018-10-29 20:16:40 -07:00
Jarcode
f4ad41df32 Added '@' include specifier, #define workaround, closes #74, closes #75 2018-10-26 21:40:31 -07:00
Jarcode
93df114308 update wording 2018-10-26 18:42:01 -07:00
Jarcode
d21edcfb29 update contribution guidelines 2018-10-26 18:41:00 -07:00
Jarcode
e0b4f7d6c7 Merge branch 'master' of https://github.com/wacossusca34/glava 2018-10-26 18:35:44 -07:00
Jarcode
386d32076c Style changes and contribution guidelines 2018-10-26 18:35:29 -07:00
Robin B
52af6ac173 radial: configurable offsets (#73)
* Add: Offset radial visualizer (config)

* Add: Offset radial visualizer
2018-10-25 18:56:59 +02:00
Jarcode
3da1fb34dd stopped using centered coords for radial module, see #69 2018-10-21 12:13:56 -07:00
20 changed files with 601 additions and 527 deletions

44
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,44 @@
## Code Style
GLava uses a bastardized version of the [linux kernel style](https://www.kernel.org/doc/html/v4.10/process/coding-style.html), with the following modifications:
* Opening braces are _always_ on the same line as the token it is associated with (`if`, `while`, labels, functions). The only time this is not honoured is when a set of braces has no associated token (ie. scope usage).
* Indentation is 4 spaces, and tabs are forbidden
* The content of a `switch` statement, including `case` labels, are indented.
* Preprocessor directives should inherit the same intentation level as the code it resides in.
* Align tokens in repetitious lines by padding spacing between tokens.
The following rules of the linux style are **ignored**:
* Function size and control flow recommendations
* Comment formatting rules
* Any other rules regarding preprocessor directives
Naming rules and the usage of `typedef` is strictly honoured from the Linux style. Anything not mentioned here is probably subjective and won't hurt your chances of getting a PR accepted.
If you use GNU Emacs, the above style can be configured via the following elisp:
```emacs
(setq-default c-basic-offset 4)
(setq c-default-style "linux")
(setq tab-stop-list (number-sequence 4 200 4))
(c-set-offset (quote cpp-macro) 0 nil)
(c-set-offset 'case-label '+)
```
## Shaders
If you author and maintain your own shader module for GLava, you are free to use your preferred code style. Otherwise, shaders follow the same style as GLava's C sources.
## Pull Requests
You are free to make pull requests for any change, even if you are not sure if the proposed changes are appropriate. @wacossusca34 and/or @coderobe will be able to suggest changes or commentary on the PR if there is a reason it is not acceptable.
## Conduct
Engagement in the issue tracker and pull requests simply requires participants remain rational and on-topic.

View File

@@ -4,7 +4,7 @@ obj = $(src:.c=.o)
# Build type parameter
ifeq ($(BUILD),debug)
CFLAGS_BUILD = -O0 -ggdb -Wall
CFLAGS_BUILD = -O0 -ggdb -Wall -DGLAVA_DEBUG
GLAD_GEN = c-debug
STRIP_CMD = $(info Skipping `strip` for debug builds)
else

58
fifo.c
View File

@@ -10,10 +10,8 @@
#include "fifo.h"
//input: FIFO
void* input_fifo(void* data)
{
struct audio_data *audio = (struct audio_data *)data;
void* input_fifo(void* data) {
struct audio_data* audio = (struct audio_data *) data;
int fd;
int n = 0;
signed char buf[1024];
@@ -28,12 +26,11 @@ void* input_fifo(void* data)
fd = open(audio->source, O_RDONLY);
flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
while (1) {
bytes = read(fd, buf, sizeof(buf));
if (bytes == -1) { //if no bytes read sleep 10ms and zero shared buffer
if (bytes == -1) { /* if no bytes read, sleep 10ms and zero shared buffer */
nanosleep (&req, NULL);
t++;
if (t > 10) {
@@ -41,46 +38,43 @@ void* input_fifo(void* data)
for (i = 0; i < 2048; i++)audio->audio_out_r[i] = 0;
t = 0;
}
} else { //if bytes read go ahead
} else { /* if bytes read, go ahead */
t = 0;
for (q = 0; q < (size / 4); q++) {
tempr = ( buf[ 4 * q + 3] << 2);
lo = ( buf[4 * q + 2] >> 6);
if (lo < 0)lo = abs(lo) + 1;
if (tempr >= 0)tempr = tempr + lo;
tempr = (buf[4 * q + 3] << 2);
lo = (buf[4 * q + 2] >> 6);
if (lo < 0) lo = abs(lo) + 1;
if (tempr >= 0) tempr = tempr + lo;
else tempr = tempr - lo;
templ = ( buf[ 4 * q + 1] << 2);
lo = ( buf[ 4 * q] >> 6);
if (lo < 0)lo = abs(lo) + 1;
if (templ >= 0)templ = templ + lo;
templ = (buf[4 * q + 1] << 2);
lo = (buf[4 * q] >> 6);
if (lo < 0) lo = abs(lo) + 1;
if (templ >= 0) templ = templ + lo;
else templ = templ - lo;
if (audio->channels == 1) audio->audio_out_l[n] = (tempr +
templ) /
2;
//stereo storing channels in buffer
if (audio->channels == 1) audio->audio_out_l[n] = (tempr + templ) / 2;
/* stereo storing channels in buffer */
if (audio->channels == 2) {
audio->audio_out_l[n] = templ;
audio->audio_out_r[n] = tempr;
}
n++;
if (n == 2048 - 1)n = 0;
}
}
if (audio->terminate == 1) {
close(fd);
break;
}
}
return 0;
}

47
glava.c
View File

@@ -113,8 +113,7 @@ static void copy_cfg(const char* path, const char* dest, bool verbose) {
}
switch (type) {
case 1:
{
case 1: {
int source = -1, dest = -1;
uint8_t buf[pgsz];
ssize_t r, t, w, a;
@@ -144,12 +143,12 @@ static void copy_cfg(const char* path, const char* dest, bool verbose) {
if (dest > 0) close(dest);
}
break;
case 2:
if (symlink(p, f) && errno != EEXIST)
fprintf(stderr, "failed to symlink '%s' -> '%s': %s\n", p, f, strerror(errno));
else if (verbose)
printf("symlink '%s' -> '%s'\n", p, f);
break;
case 2:
if (symlink(p, f) && errno != EEXIST)
fprintf(stderr, "failed to symlink '%s' -> '%s': %s\n", p, f, strerror(errno));
else if (verbose)
printf("symlink '%s' -> '%s'\n", p, f);
break;
}
}
closedir(dir);
@@ -218,22 +217,22 @@ int main(int argc, char** argv) {
int c, idx;
while ((c = getopt_long(argc, argv, opt_str, p_opts, &idx)) != -1) {
switch (c) {
case 'v': verbose = true; break;
case 'C': copy_mode = true; break;
case 'd': desktop = true; break;
case 'e': entry = optarg; break;
case 'm': force = optarg; break;
case 'b': backend = 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;
case 'v': verbose = true; break;
case 'C': copy_mode = true; break;
case 'd': desktop = true; break;
case 'e': entry = optarg; break;
case 'm': force = optarg; break;
case 'b': backend = 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

@@ -15,6 +15,14 @@
#include "glsl_ext.h"
#define LINE_START 0
#define GLSL 1
#define MACRO 2
#define REQUEST 3
#define INCLUDE 4
#define COLOR 5
#define DEFINE 6
struct sbuf {
char* buf;
size_t at; /* index of final null character */
@@ -56,12 +64,12 @@ static void se_append(struct sbuf* sbuf, size_t elen, const char* fmt, ...) {
va_end(args);
}
#define parse_error(line, f, fmt, ...) \
#define parse_error(line, f, fmt, ...) \
fprintf(stderr, "[%s:%d] " fmt "\n", f, (int) line, __VA_ARGS__); \
abort()
#define parse_error_s(line, f, s) \
fprintf(stderr, "[%s:%d] " s "\n", f, (int) line); \
#define parse_error_s(line, f, s) \
fprintf(stderr, "[%s:%d] " s "\n", f, (int) line); \
abort()
struct schar {
@@ -82,10 +90,10 @@ bool ext_parse_color(const char* str, size_t elem_sz, float** results) {
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;
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 */
@@ -121,145 +129,164 @@ static void inherit(struct glsl_ext* parent, struct glsl_ext* child) {
/* handle raw arguments for #include and #request directives */
static struct schar directive(struct glsl_ext* ext, char** args,
size_t args_sz, bool include,
size_t line, const char* f) {
if (include) {
if (args_sz == 0) {
parse_error_s(line, f, "No arguments provided to #include directive!");
size_t args_sz, int state,
size_t line, const char* f) {
switch (state) {
case DEFINE: {
/* Workaround for re-defining macros in GLSL. By default this is generally an error in most
compilers/drivers, but we would prefer to override (non-function) definitions instead.
Due to how this directive is parsed, the macro itself is still emitted afterwards. */
if (args_sz == 0) {
parse_error_s(line, f, "No arguments provided to #define directive!");
}
size_t bsz = (strlen(args[0]) * 3) + 64;
struct schar ret = { .buf = malloc(bsz) };
int r = snprintf(ret.buf, bsz, "#ifdef %1$s\n#undef %1$s\n#endif\n", args[0]);
if (r < 0) abort();
ret.sz = r;
free_after(ext, ret.buf);
return ret;
}
char* target = args[0];
case INCLUDE: {
if (args_sz == 0) {
parse_error_s(line, f, "No arguments provided to #include directive!");
}
char* target = args[0];
/* Handle `:` config specifier */
size_t tsz = strlen(target);
if (tsz && target[0] == ':' && ext->cfd) {
target = &target[1];
ext->cd = ext->cfd;
}
char path[strlen(ext->cd) + tsz + 2];
snprintf(path, sizeof(path) / sizeof(char), "%s/%s", ext->cd, target);
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",
path, strerror(errno));
}
struct stat st;
fstat(fd, &st);
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",
path, strerror(errno));
/* Handle `:` config specifier */
size_t tsz = strlen(target);
if (tsz && target[0] == ':' && ext->cfd) {
target = &target[1];
ext->cd = ext->cfd;
}
/* Handle `@` default specifier */
if (tsz && target[0] == '@') {
if (!ext->dd) {
parse_error_s(line, f, "encountered '@' path specifier while no default "
"directory is available in the current context");
}
target = &target[1];
ext->cd = ext->dd;
}
char path[strlen(ext->cd) + tsz + 2];
snprintf(path, sizeof(path) / sizeof(char), "%s/%s", ext->cd, target);
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",
path, strerror(errno));
}
struct stat st;
fstat(fd, &st);
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",
path, strerror(errno));
}
struct glsl_ext next = {
.source = map,
.source_len = st.st_size,
.cd = ext->cd,
.cfd = ext->cfd,
.dd = ext->dd,
.handlers = ext->handlers
};
/* recursively process */
ext_process(&next, target);
inherit(ext, &next);
munmap(map, st.st_size);
struct schar ret = {
.buf = next.processed,
.sz = next.p_len
};
return ret;
}
case REQUEST: {
if (args_sz > 0) {
char* request = args[0];
struct glsl_ext next = {
.source = map,
.source_len = st.st_size,
.cd = ext->cd,
.cfd = ext->cfd,
.handlers = ext->handlers
};
/* recursively process */
ext_process(&next, target);
inherit(ext, &next);
munmap(map, st.st_size);
struct schar ret = {
.buf = next.processed,
.sz = next.p_len
};
return ret;
} else {
if (args_sz > 0) {
char* request = args[0];
struct request_handler* handler;
bool found = false;
size_t t;
for (t = 0; (handler = &ext->handlers[t])->name != NULL; ++t) {
if(!strcmp(handler->name, request)) {
found = true;
void** processed_args = malloc(strlen(handler->fmt) * sizeof(void*));
struct request_handler* handler;
bool found = false;
size_t t;
for (t = 0; (handler = &ext->handlers[t])->name != NULL; ++t) {
if(!strcmp(handler->name, request)) {
found = true;
void** processed_args = malloc(strlen(handler->fmt) * sizeof(void*));
char c;
size_t i;
for (i = 0; (c = handler->fmt[i]) != '\0'; ++i) {
if (args_sz <= 1 + i) {
parse_error(line, f,
"failed to execute request '%s': expected format '%s'\n",
request, handler->fmt);
}
char* raw = args[1 + i];
switch (c) {
case 'i':
{
int v = (int) strtol(raw, NULL, 0);
processed_args[i] = malloc(sizeof(int));
*(int*) processed_args[i] = v;
break;
char c;
size_t i;
for (i = 0; (c = handler->fmt[i]) != '\0'; ++i) {
if (args_sz <= 1 + i) {
parse_error(line, f,
"failed to execute request '%s': expected format '%s'\n",
request, handler->fmt);
}
case 'f':
{
float f = strtof(raw, NULL);
processed_args[i] = malloc(sizeof(float));
*(float*) processed_args[i] = f;
break;
}
case 's': { *(char**) &processed_args[i] = raw; break; }
case 'b':
{
bool v;
if (!strcmp(raw, "true")) {
v = true;
} else if (!strcmp(raw, "false")) {
v = false;
} else if (strlen(raw) == 1) {
switch (raw[0]) {
case 't': { v = true; break; }
case 'f': { v = false; break; }
case '1': { v = true; break; }
case '0': { v = false; break; }
default:
char* raw = args[1 + i];
switch (c) {
case 'i': {
int v = (int) strtol(raw, NULL, 0);
processed_args[i] = malloc(sizeof(int));
*(int*) processed_args[i] = v;
break;
}
case 'f': {
float f = strtof(raw, NULL);
processed_args[i] = malloc(sizeof(float));
*(float*) processed_args[i] = f;
break;
}
case 's': { *(char**) &processed_args[i] = raw; break; }
case 'b': {
bool v;
if (!strcmp(raw, "true")) {
v = true;
} else if (!strcmp(raw, "false")) {
v = false;
} else if (strlen(raw) == 1) {
switch (raw[0]) {
case 't': { v = true; break; }
case 'f': { v = false; break; }
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");
}
} else {
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");
processed_args[i] = malloc(sizeof(bool));
*(bool*) processed_args[i] = v;
break;
}
processed_args[i] = malloc(sizeof(bool));
*(bool*) processed_args[i] = v;
break;
}
}
}
handler->handler(request, processed_args);
handler->handler(request, processed_args);
for (i = 0; (c = handler->fmt[i]) != '\0'; ++i)
if (c != 's')
free(processed_args[i]);
free(processed_args);
for (i = 0; (c = handler->fmt[i]) != '\0'; ++i)
if (c != 's')
free(processed_args[i]);
free(processed_args);
}
}
if (!found) {
parse_error(line, f, "unknown request type '%s'", request);
}
}
if (!found) {
parse_error(line, f, "unknown request type '%s'", request);
}
}
struct schar ret = {
.buf = NULL,
.sz = 0
};
return ret;
default: return (struct schar) { .buf = NULL, .sz = 0 };
}
}
@@ -269,13 +296,6 @@ void ext_process(struct glsl_ext* ext, const char* f) {
ext->destruct = malloc(1);
ext->destruct_sz = 0;
#define LINE_START 0
#define GLSL 1
#define MACRO 2
#define REQUEST 3
#define INCLUDE 4
#define COLOR 5
struct sbuf sbuf = {
.buf = malloc(256),
.at = 0,
@@ -301,137 +321,139 @@ void ext_process(struct glsl_ext* ext, const char* f) {
if (at == '\n')
++line;
switch (state) {
case LINE_START: /* processing start of line */
{
case LINE_START: { /* processing start of line */
switch (at) {
case '#': {
macro_start_idx = t;
state = MACRO;
continue; }
case '\n':
if (comment && comment_line) {
comment = false;
comment_line = false;
case '#': {
macro_start_idx = t;
state = MACRO;
continue;
}
case '\t':
case ' ':
goto copy;
default: state = GLSL;
/* let execution continue into next state */
case '\n':
if (comment && comment_line) {
comment = false;
comment_line = false;
}
case '\t':
case ' ':
goto copy;
default: state = GLSL;
/* let execution continue into next state */
}
}
case GLSL: /* copying GLSL source or unrelated preprocessor syntax */
{
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;
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;
} 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)) */
{
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);
case 'a' ... 'z':
case 'A' ... 'Z':
case '0' ... '9': {
cbuf[cbuf_idx] = at;
++cbuf_idx;
if (cbuf_idx >= 8)
goto emit_color;
else continue;
}
state = at == '\n' ? LINE_START : GLSL;
if (cbuf_idx >= 8)
continue;
else goto copy; /* copy character if it ended the sequence */
}
}
case MACRO: /* processing start of macro */
{
switch (at) {
case '\n':
case ' ':
case '\t':
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)) {
state = INCLUDE;
goto prepare_arg_parse;
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 {
n_append(&sbuf, t - macro_start_idx, &ext->source[macro_start_idx]);
state = at == '\n' ? LINE_START : GLSL;
goto copy;
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 */
}
}
/* emit contents from start of macro to current index and resume regular parsing*/
#define skip_macro() \
do { \
n_append(&sbuf, t - macro_start_idx, &ext->source[macro_start_idx]); \
state = at == '\n' ? LINE_START : GLSL; \
goto copy; \
} while (0)
case MACRO: { /* processing start of macro */
switch (at) {
case '\n':
case ' ':
case '\t':
case '\0': { /* end parsing directive */
#define DIRECTIVE_CMP(lower, upper) \
(!strncmp("#" lower, &ext->source[macro_start_idx], t - macro_start_idx) \
|| !strncmp("#" upper, &ext->source[macro_start_idx], t - macro_start_idx))
#define DIRECTIVE_CASE(lower, upper) \
do { if (state == MACRO && DIRECTIVE_CMP(#lower, #upper)) { state = upper; goto prepare_arg_parse; } } while (0)
DIRECTIVE_CASE(request, REQUEST);
DIRECTIVE_CASE(include, INCLUDE);
DIRECTIVE_CASE(define, DEFINE);
/* no match */
if (state == MACRO) skip_macro();
#undef DIRECTIVE_CMP
#undef DIRECTIVE_CASE
prepare_arg_parse:
{
arg_start_idx = t + 1;
@@ -440,72 +462,79 @@ void ext_process(struct glsl_ext* ext, const char* f) {
*args = NULL;
}
}
case 'a' ... 'z':
case 'A' ... 'Z':
continue;
default:
/* invalid char, malformed! */
parse_error(line, f, "Unexpected character '%c' while parsing GLSL directive", at);
case 'a' ... 'z':
case 'A' ... 'Z':
continue;
default:
/* invalid char, malformed! */
parse_error(line, f, "Unexpected character '%c' while parsing GLSL directive", at);
}
}
/* scope-violating macro to copy the result of the currently parsed argument */
#define copy_arg(end) \
do { if (end - arg_start_idx > 0) { \
++args_sz; \
args = realloc(args, sizeof(char*) * args_sz); \
args[args_sz - 1] = malloc((end - arg_start_idx) + 1); \
memcpy(args[args_sz - 1], &ext->source[arg_start_idx], end - arg_start_idx); \
args[args_sz - 1][end - arg_start_idx] = '\0'; \
} } while (0)
case REQUEST:
case INCLUDE:
{
/* scope-violating macro to copy the result of the currently parsed argument */
#define copy_arg(end) \
do { if (end - arg_start_idx > 0) { \
++args_sz; \
args = realloc(args, sizeof(char*) * args_sz); \
args[args_sz - 1] = malloc((end - arg_start_idx) + 1); \
memcpy(args[args_sz - 1], &ext->source[arg_start_idx], end - arg_start_idx); \
args[args_sz - 1][end - arg_start_idx] = '\0'; \
} } while (0)
case REQUEST:
case INCLUDE:
case DEFINE: {
switch (at) {
case ' ':
case '\t':
case '\n':
case '\0':
if (!quoted) {
/* end arg */
copy_arg(t);
arg_start = true;
arg_start_idx = t + 1;
} else arg_start = false;
if (at == '\n') {
/* end directive */
size_t a;
struct schar r = directive(ext, args, args_sz, state == INCLUDE, line, f);
for (a = 0; a < args_sz; ++a) {
free(args[a]);
case ' ':
case '\t':
case '\n':
case '\0':
if (!quoted) {
/* end arg */
copy_arg(t);
arg_start = true;
arg_start_idx = t + 1;
} else arg_start = false;
if (at == '\n' || state == DEFINE) {
/* end directive */
size_t a;
struct schar r = directive(ext, args, args_sz, state, line, f);
for (a = 0; a < args_sz; ++a) {
free(args[a]);
}
args_sz = 0;
/* if something was returned (ie. included file), paste the results */
if (r.buf) {
n_append(&sbuf, r.sz, r.buf);
append(&sbuf, "\n");
}
if (state == DEFINE) skip_macro();
else state = LINE_START;
}
args_sz = 0;
/* if something was returned (ie. included file), paste the results */
if (r.buf) {
n_append(&sbuf, r.sz, r.buf);
append(&sbuf, "\n");
}
state = LINE_START;
break;
case '(':
if (state != DEFINE || args_sz != 0) goto arg; /* only handle first arg of #define */
skip_macro(); /* ignore macro functions */
case '"':
if (state == DEFINE) goto arg; /* do not handle quoting for #define */
if (quoted) {
/* end arg */
copy_arg(t);
quoted = false;
arg_start = true;
arg_start_idx = t + 1;
} else if (arg_start) {
++arg_start_idx;
quoted = true;
} else arg_start = false;
break;
default: {
arg: arg_start = false;
}
break;
case '"':
if (quoted) {
/* end arg */
copy_arg(t);
quoted = false;
arg_start = true;
arg_start_idx = t + 1;
} else if (arg_start) {
++arg_start_idx;
quoted = true;
} else arg_start = false;
break;
default:
arg_start = false;
}
continue;
}
#undef copy_arg
}
copy:
if (at != '\0')

View File

@@ -27,6 +27,7 @@ struct glsl_ext {
size_t source_len; /* IN: raw source len */
const char* cd; /* IN: current directory */
const char* cfd; /* IN: config directory, if NULL it is assumed to cd */
const char* dd; /* IN: default directory */
void** destruct; /* internal */
size_t destruct_sz; /* internal */

View File

@@ -215,7 +215,7 @@ static void init(void) {
}
#define resolve(name) do { name = (typeof(name)) resolve_f(#name); } while (0)
#define intern(name, only_if_exists) \
#define intern(name, only_if_exists) \
do { ATOM_##name = XInternAtom(display, #name, only_if_exists); } while (0)
resolve(glXChooseFBConfig);
@@ -272,32 +272,32 @@ static void process_events(struct glxwin* w) {
XEvent ev;
XNextEvent(display, &ev);
switch (ev.type) {
case ClientMessage:
if (ev.xclient.message_type == ATOM_WM_PROTOCOLS
&& ev.xclient.data.l[0] == ATOM_WM_DELETE_WINDOW) {
w->should_close = true;
}
break;
case VisibilityNotify:
switch (ev.xvisibility.state) {
case VisibilityFullyObscured:
w->should_render = false;
case ClientMessage:
if (ev.xclient.message_type == ATOM_WM_PROTOCOLS
&& ev.xclient.data.l[0] == ATOM_WM_DELETE_WINDOW) {
w->should_close = true;
}
break;
case VisibilityUnobscured:
case VisibilityPartiallyObscured:
w->should_render = true;
case VisibilityNotify:
switch (ev.xvisibility.state) {
case VisibilityFullyObscured:
w->should_render = false;
break;
case VisibilityUnobscured:
case VisibilityPartiallyObscured:
w->should_render = true;
break;
default:
fprintf(stderr, "Invalid VisibilityNotify event state (%d)\n", ev.xvisibility.state);
break;
}
break;
default:
fprintf(stderr, "Invalid VisibilityNotify event state (%d)\n", ev.xvisibility.state);
case PropertyNotify:
if (ev.xproperty.atom == ATOM__XROOTPMAP_ID) {
w->bg_changed = true;
}
break;
}
break;
case PropertyNotify:
if (ev.xproperty.atom == ATOM__XROOTPMAP_ID) {
w->bg_changed = true;
}
break;
default: break;
default: break;
}
}
}
@@ -516,9 +516,9 @@ static void set_visible(struct glxwin* w, bool visible) {
XMapWindow(display, w->w);
apply_clickthrough(w);
switch (w->override_state) {
case '+': XRaiseWindow(display, w->w); break;
case '-': XLowerWindow(display, w->w); break;
default: break;
case '+': XRaiseWindow(display, w->w); break;
case '-': XLowerWindow(display, w->w); break;
default: break;
}
XFlush(display);
}

View File

@@ -35,16 +35,11 @@ static void cb(__attribute__((unused)) pa_context* pulseaudio_context,
static void pulseaudio_context_state_callback(pa_context* pulseaudio_context, void* userdata) {
/* Ensure loop is ready */
switch (pa_context_get_state(pulseaudio_context))
{
case PA_CONTEXT_UNCONNECTED:
break;
case PA_CONTEXT_CONNECTING:
break;
case PA_CONTEXT_AUTHORIZING:
break;
case PA_CONTEXT_SETTING_NAME:
break;
switch (pa_context_get_state(pulseaudio_context)) {
case PA_CONTEXT_UNCONNECTED: break;
case PA_CONTEXT_CONNECTING: break;
case PA_CONTEXT_AUTHORIZING: break;
case PA_CONTEXT_SETTING_NAME: break;
case PA_CONTEXT_READY: /* extract default sink name */
pa_operation_unref(pa_context_get_server_info(pulseaudio_context, cb, userdata));
break;
@@ -55,7 +50,7 @@ static void pulseaudio_context_state_callback(pa_context* pulseaudio_context, vo
case PA_CONTEXT_TERMINATED:
pa_mainloop_quit(m_pulseaudio_mainloop, 0);
break;
}
}
}

110
render.c
View File

@@ -32,7 +32,7 @@
/* Only a single vertex shader is needed for GLava, since all rendering is done in the fragment shader
over a fullscreen quad */
#define VERTEX_SHADER_SRC \
#define VERTEX_SHADER_SRC \
"layout(location = 0) in vec3 pos; void main() { gl_Position = vec4(pos.x, pos.y, 0.0F, 1.0F); }"
struct gl_wcb* wcbs[2] = {};
@@ -135,6 +135,7 @@ static GLuint shaderload(const char* rpath,
GLenum type,
const char* shader,
const char* config,
const char* defaults,
struct request_handler* handlers,
int shader_version,
bool raw,
@@ -181,6 +182,7 @@ static GLuint shaderload(const char* rpath,
.source_len = raw ? 0 : st.st_size,
.cd = shader,
.cfd = config,
.dd = defaults,
.handlers = handlers,
.processed = (char*) (raw ? shader : NULL),
.p_len = raw ? s_len : 0
@@ -205,10 +207,10 @@ static GLuint shaderload(const char* rpath,
GLint sl = (GLint) (ext.p_len + written);
glShaderSource(s, 1, (const GLchar* const*) &buf, &sl);
switch (glGetError()) {
case GL_INVALID_VALUE:
case GL_INVALID_OPERATION:
fprintf(stderr, "invalid operation while loading shader source\n");
return 0;
case GL_INVALID_VALUE:
case GL_INVALID_OPERATION:
fprintf(stderr, "invalid operation while loading shader source\n");
return 0;
}
glCompileShader(s);
GLint ret, ilen;
@@ -216,10 +218,14 @@ static GLuint shaderload(const char* rpath,
if (ret == GL_FALSE) {
glGetShaderiv(s, GL_INFO_LOG_LENGTH, &ilen);
if (ilen) {
GLchar buf[ilen];
glGetShaderInfoLog(s, ilen, NULL, buf);
GLchar ebuf[ilen];
glGetShaderInfoLog(s, ilen, NULL, ebuf);
fprintf(stderr, "Shader compilation failed for '%s':\n", path);
fwrite(buf, sizeof(GLchar), ilen - 1, stderr);
fwrite(ebuf, sizeof(GLchar), ilen - 1, stderr);
#ifdef GLAVA_DEBUG
fprintf(stderr, "Processed shader source for '%s':\n", path);
fwrite(buf, sizeof(GLchar), sl, stderr);
#endif
return 0;
} else {
fprintf(stderr, "Shader compilation failed for '%s', but no info was available\n", path);
@@ -247,13 +253,13 @@ static GLuint shaderlink_f(GLuint* arr) {
while ((f = arr[i++]) != 0) {
glAttachShader(p, f);
switch (glGetError()) {
case GL_INVALID_VALUE:
fprintf(stderr, "tried to pass invalid value to glAttachShader\n");
return 0;
case GL_INVALID_OPERATION:
fprintf(stderr, "shader is already attached, or argument types "
"were invalid when calling glAttachShader\n");
return 0;
case GL_INVALID_VALUE:
fprintf(stderr, "tried to pass invalid value to glAttachShader\n");
return 0;
case GL_INVALID_OPERATION:
fprintf(stderr, "shader is already attached, or argument types "
"were invalid when calling glAttachShader\n");
return 0;
}
}
glLinkProgram(p);
@@ -276,11 +282,11 @@ static GLuint shaderlink_f(GLuint* arr) {
}
/* load shaders */
#define shaderbuild(gl, shader_path, c, r, v, ...) \
shaderbuild_f(gl, shader_path, c, r, v, (const char*[]) {__VA_ARGS__, 0})
#define shaderbuild(gl, shader_path, c, d, r, v, ...) \
shaderbuild_f(gl, shader_path, c, d, r, v, (const char*[]) {__VA_ARGS__, 0})
static GLuint shaderbuild_f(struct gl_data* gl,
const char* shader_path,
const char* config,
const char* config, const char* defaults,
struct request_handler* handlers,
int shader_version,
const char** arr) {
@@ -296,15 +302,15 @@ static GLuint shaderbuild_f(struct gl_data* gl,
if (path[t] == '.') {
if (!strcmp(path + t + 1, "frag") || !strcmp(path + t + 1, "glsl")) {
if (!(shaders[i] = shaderload(path, GL_FRAGMENT_SHADER,
shader_path, config, handlers,
shader_path, config, defaults, handlers,
shader_version, false, gl))) {
return 0;
}
} else if (!strcmp(path + t + 1, "vert")) {
/*
if (!(shaders[i] = shaderload(path, GL_VERTEX_SHADER, shader_path))) {
return 0;
}
if (!(shaders[i] = shaderload(path, GL_VERTEX_SHADER, shader_path))) {
return 0;
}
*/
fprintf(stderr, "shaderbuild(): vertex shaders not allowed: %s\n", path);
abort();
@@ -317,7 +323,7 @@ static GLuint shaderbuild_f(struct gl_data* gl,
}
}
/* load builtin vertex shader */
shaders[sz] = shaderload(NULL, GL_VERTEX_SHADER, VERTEX_SHADER_SRC, NULL, handlers, shader_version, true, gl);
shaders[sz] = shaderload(NULL, GL_VERTEX_SHADER, VERTEX_SHADER_SRC, NULL, NULL, handlers, shader_version, true, gl);
fflush(stdout);
return shaderlink_f(shaders);
}
@@ -365,10 +371,10 @@ static void setup_sfbo(struct gl_sfbo* s, int w, int h) {
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
switch (glCheckFramebufferStatus(GL_FRAMEBUFFER)) {
case GL_FRAMEBUFFER_COMPLETE: break;
default:
fprintf(stderr, "error in frambuffer state\n");
abort();
case GL_FRAMEBUFFER_COMPLETE: break;
default:
fprintf(stderr, "error in frambuffer state\n");
abort();
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
@@ -568,7 +574,7 @@ void transform_average(struct gl_data* d, void** udata, void* data) {
for (t = 0; t < sz; ++t) { \
v = 0.0F; \
for (f = 0; f < d->avg_frames; ++f) { \
v += w * bufs[(f * sz) + t]; \
v += w * bufs[(f * sz) + t]; \
} \
b[t] = v / d->avg_frames; \
} \
@@ -1054,9 +1060,11 @@ struct renderer* rd_new(const char** paths, const char* entry,
directories will be populated with symlinks to the installed modules. */
const char* data;
const char* dd; /* defaults dir (system) */
const char* env = gl->wcb->get_environment();
size_t d_len, e_len;
for (const char** i = paths; (data = *i) != NULL; ++i) dd = data;
for (const char** i = paths; (data = *i) != NULL; ++i) {
d_len = strlen(data);
e_len = env ? strlen(env) : 0;
@@ -1237,7 +1245,7 @@ struct renderer* rd_new(const char** paths, const char* entry,
};
current = s;
GLuint id = shaderbuild(gl, shaders, data, handlers, shader_version, d->d_name);
GLuint id = shaderbuild(gl, shaders, data, dd, handlers, shader_version, d->d_name);
if (!id) {
abort();
}
@@ -1298,7 +1306,7 @@ struct renderer* rd_new(const char** paths, const char* entry,
char util[usz]; /* module pack path to use */
snprintf(util, usz, "%s/%s", data, util_folder);
loading_smooth_pass = true;
if (!(gl->sm_prog = shaderbuild(gl, util, data, handlers, shader_version, "smooth_pass.frag")))
if (!(gl->sm_prog = shaderbuild(gl, util, data, dd, handlers, shader_version, "smooth_pass.frag")))
abort();
loading_smooth_pass = false;
}
@@ -1475,9 +1483,9 @@ bool rd_update(struct renderer* r, float* lb, float* rb, size_t bsz, bool modifi
"}" "\n";
if (!setup) {
bg_prog = shaderlink(shaderload(NULL, GL_VERTEX_SHADER, VERTEX_SHADER_SRC,
NULL, NULL, 330, true, gl),
NULL, NULL, NULL, 330, true, gl),
shaderload(NULL, GL_FRAGMENT_SHADER, frag_shader,
NULL, NULL, 330, true, gl));
NULL, NULL, NULL, 330, true, gl));
bg_utex = glGetUniformLocation(bg_prog, "tex");
bg_screen = glGetUniformLocation(bg_prog, "screen");
glBindFragDataLocation(bg_prog, 1, "fragment");
@@ -1570,10 +1578,10 @@ bool rd_update(struct renderer* r, float* lb, float* rb, size_t bsz, bool modifi
GL_TEXTURE_1D, sm->tex, 0);
switch (glCheckFramebufferStatus(GL_FRAMEBUFFER)) {
case GL_FRAMEBUFFER_COMPLETE: break;
default:
fprintf(stderr, "error in frambuffer state\n");
abort();
case GL_FRAMEBUFFER_COMPLETE: break;
default:
fprintf(stderr, "error in frambuffer state\n");
abort();
}
} else {
/* Just bind our data if it was already allocated and setup */
@@ -1614,20 +1622,20 @@ bool rd_update(struct renderer* r, float* lb, float* rb, size_t bsz, bool modifi
(currently) exists. */
switch (bind->src_type) {
case SRC_PREV:
/* bind texture and pass it to the shader uniform if we need to pass
the sampler from the previous pass */
if (!prev_bound && prev != NULL) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, prev->tex);
prev_bound = true;
}
glUniform1i(bind->uniform, 0);
break;
case SRC_AUDIO_L: handle_1d_tex(gl->audio_tex_l, lb, ilb, bsz, 1, true); break;
case SRC_AUDIO_R: handle_1d_tex(gl->audio_tex_r, rb, irb, bsz, 2, true); break;
case SRC_AUDIO_SZ: glUniform1i(bind->uniform, bsz); break;
case SRC_SCREEN: glUniform2i(bind->uniform, (GLint) ww, (GLint) wh); break;
case SRC_PREV:
/* bind texture and pass it to the shader uniform if we need to pass
the sampler from the previous pass */
if (!prev_bound && prev != NULL) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, prev->tex);
prev_bound = true;
}
glUniform1i(bind->uniform, 0);
break;
case SRC_AUDIO_L: handle_1d_tex(gl->audio_tex_l, lb, ilb, bsz, 1, true); break;
case SRC_AUDIO_R: handle_1d_tex(gl->audio_tex_r, rb, irb, bsz, 2, true); break;
case SRC_AUDIO_SZ: glUniform1i(bind->uniform, bsz); break;
case SRC_SCREEN: glUniform2i(bind->uniform, (GLint) ww, (GLint) wh); break;
}
}

View File

@@ -6,6 +6,7 @@ uniform ivec2 screen;
#request uniform "audio_sz" audio_sz
uniform int audio_sz;
#include "@bars.glsl"
#include ":bars.glsl"
#request uniform "audio_l" audio_l

View File

@@ -7,6 +7,7 @@ uniform ivec2 screen;
uniform int audio_sz;
#include ":util/smooth.glsl"
#include "@circle.glsl"
#include ":circle.glsl"
#request uniform "audio_l" audio_l

View File

@@ -6,6 +6,7 @@ uniform sampler2D tex; /* screen texture */
out vec4 fragment; /* output */
#include "@circle.glsl"
#include ":circle.glsl"
void main() {

View File

@@ -4,24 +4,21 @@
/* Rendering direction, either -1 (outwards) or 1 (inwards). */
#define DIRECTION 1
/* The `RCOL_OFF`, `LCOL_OFF` AND `LSTEP` definitions are used to calculate
the `COLOR` macro definition for output. You can remove all these values
any simply define the `COLOR` macro yourself. */
/* right color offset */
#define RCOL_OFF (gl_FragCoord.x / 3000)
/* left color offset */
#define LCOL_OFF ((screen.x - gl_FragCoord.x) / 3000)
/* vertical color step */
#define LSTEP (pos / 170)
/* actual color definition */
#define COLOR vec4((0.3 + RCOL_OFF) + LSTEP, 0.6 - LSTEP, (0.3 + LCOL_OFF) + LSTEP, 1)
/* Color gradient scale, (optionally) used in `COLOR` macro */
#define GRADIENT_SCALE 75
/* Color definition. By default this is a gradient formed by mixing two colors.
`pos` represents the pixel position relative to the visualizer baseline. */
#define COLOR mix(#802A2A, #4F4F92, clamp(pos / GRADIENT_SCALE, 0, 1))
/* 1 to draw outline, 0 to disable */
#define DRAW_OUTLINE 0
/* 1 to draw edge highlight, 0 to disable */
#define DRAW_HIGHLIGHT 1
/* outline color */
#define OUTLINE #262626
/* 1 to invert (vertically), 0 otherwise */
#define INVERT 0
/* Gravity step, overrude frin `smooth_parameters.glsl` */
/* Gravity step, overrude from `smooth_parameters.glsl` */
#request setgravitystep 2.4
/* Smoothing factor, override from `smooth_parameters.glsl` */

View File

@@ -40,6 +40,7 @@ uniform int audio_sz;
*/
#include ":util/smooth.glsl"
#include "@graph.glsl"
#include ":graph.glsl"
#request uniform "audio_l" audio_l

View File

@@ -1,44 +1,40 @@
layout(pixel_center_integer) in vec4 gl_FragCoord;
in vec4 gl_FragCoord;
#request uniform "prev" tex
uniform sampler2D tex; /* screen texture */
#request uniform "screen" screen
uniform ivec2 screen; /* screen dimensions */
out vec4 fragment; /* output */
#include "@graph.glsl"
#include ":graph.glsl"
void main() {
fragment = texture(tex, vec2(gl_FragCoord.x / screen.x, gl_FragCoord.y / screen.y));
fragment = texelFetch(tex, ivec2(gl_FragCoord.x, gl_FragCoord.y), 0);
vec4
a0 = texture(tex, vec2((gl_FragCoord.x + 1) / screen.x, (gl_FragCoord.y + 0) / screen.y)),
a1 = texture(tex, vec2((gl_FragCoord.x + 1) / screen.x, (gl_FragCoord.y + 1) / screen.y)),
a2 = texture(tex, vec2((gl_FragCoord.x + 0) / screen.x, (gl_FragCoord.y + 1) / screen.y)),
a3 = texture(tex, vec2((gl_FragCoord.x + 1) / screen.x, (gl_FragCoord.y + 0) / screen.y)),
a0 = texelFetch(tex, ivec2((gl_FragCoord.x + 1), (gl_FragCoord.y + 0)), 0),
a1 = texelFetch(tex, ivec2((gl_FragCoord.x + 1), (gl_FragCoord.y + 1)), 0),
a2 = texelFetch(tex, ivec2((gl_FragCoord.x + 0), (gl_FragCoord.y + 1)), 0),
a3 = texelFetch(tex, ivec2((gl_FragCoord.x + 1), (gl_FragCoord.y + 0)), 0),
a4 = texture(tex, vec2((gl_FragCoord.x - 1) / screen.x, (gl_FragCoord.y - 0) / screen.y)),
a5 = texture(tex, vec2((gl_FragCoord.x - 1) / screen.x, (gl_FragCoord.y - 1) / screen.y)),
a6 = texture(tex, vec2((gl_FragCoord.x - 0) / screen.x, (gl_FragCoord.y - 1) / screen.y)),
a7 = texture(tex, vec2((gl_FragCoord.x - 1) / screen.x, (gl_FragCoord.y - 0) / screen.y));
a4 = texelFetch(tex, ivec2((gl_FragCoord.x - 1), (gl_FragCoord.y - 0)), 0),
a5 = texelFetch(tex, ivec2((gl_FragCoord.x - 1), (gl_FragCoord.y - 1)), 0),
a6 = texelFetch(tex, ivec2((gl_FragCoord.x - 0), (gl_FragCoord.y - 1)), 0),
a7 = texelFetch(tex, ivec2((gl_FragCoord.x - 1), (gl_FragCoord.y - 0)), 0);
vec4 avg = (a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7) / 8.0;
if (avg.a > 0){
#if INVERT > 0
#define EDGE_CHECK (gl_FragCoord.y != 0)
#define TEDGE_CHECK (gl_FragCoord.y != screen.y - 1)
#else
#define EDGE_CHECK (gl_FragCoord.y != screen.y - 1)
#define TEDGE_CHECK (gl_FragCoord.y != 0)
#endif
if (fragment.a <= 0 && EDGE_CHECK) {
if (fragment.a <= 0) {
/* outline */
#if DRAW_OUTLINE > 0
fragment = OUTLINE;
} else if (avg.a < 1 && TEDGE_CHECK) {
/* creates a nice 'glint' along the edge of the spectrum */
#endif
} else if (avg.a < 1) {
/* creates a highlight along the edge of the spectrum */
#if DRAW_HIGHLIGHT > 0
fragment.rgb *= avg.a * 2;
#endif
}
}
}

View File

@@ -27,6 +27,10 @@
the background. */
#define BAR_ALIAS_FACTOR 1.2
#define C_ALIAS_FACTOR 1.8
/* Offset (Y) of the visualization */
#define CENTER_OFFSET_Y 0
/* Offset (X) of the visualization */
#define CENTER_OFFSET_X 0
/* Gravity step, overrude frin `smooth_parameters.glsl` */
#request setgravitystep 5.0

View File

@@ -1,4 +1,4 @@
layout(pixel_center_integer) in vec4 gl_FragCoord;
in vec4 gl_FragCoord;
#request uniform "screen" screen
uniform ivec2 screen;
@@ -7,6 +7,7 @@ uniform ivec2 screen;
uniform int audio_sz;
#include ":util/smooth.glsl"
#include "@radial.glsl"
#include ":radial.glsl"
#request uniform "audio_l" audio_l
@@ -41,8 +42,8 @@ void main() {
Alpha layer blending is only applied when `xroot` transparency is enabled. */
float /* translate (x, y) to use (0, 0) as the center of the screen */
dx = gl_FragCoord.x - (screen.x / 2),
dy = gl_FragCoord.y - (screen.y / 2);
dx = gl_FragCoord.x - (screen.x / 2) + CENTER_OFFSET_X,
dy = gl_FragCoord.y - (screen.y / 2) + CENTER_OFFSET_Y;
float theta = atan(dy, dx); /* fragment angle with the center of the screen as the origin */
float d = sqrt((dx * dx) + (dy * dy)); /* distance */
if (d > C_RADIUS - (float(C_LINE) / 2.0F) && d < C_RADIUS + (float(C_LINE) / 2.0F)) {

View File

@@ -11,6 +11,7 @@ uniform sampler1D audio_l;
out vec4 fragment;
#include "@wave.glsl"
#include ":wave.glsl"
#define index(offset) ((texture(audio_l, (gl_FragCoord.x + offset) / screen.x).r - 0.5) * AMPLIFY) + 0.5F

View File

@@ -8,6 +8,7 @@ uniform ivec2 screen; /* screen dimensions */
out vec4 fragment; /* output */
#include "@wave.glsl"
#include ":wave.glsl"
void main() {

66
xwin.c
View File

@@ -82,7 +82,7 @@ void xwin_wait_for_wm(void) {
bool exists = false;
struct timespec tv = { .tv_sec = 0, .tv_nsec = 50 * 1000000 };
do {
do {
if (check == None) {
check = XInternAtom(d, "_NET_SUPPORTING_WM_CHECK", true);
}
@@ -161,7 +161,7 @@ bool xwin_should_render(struct gl_wcb* wcb, void* impl) {
XSetErrorHandler(handler); /* dummy error handler */
if (Success != XGetWindowProperty(d, DefaultRootWindow(d), prop, 0, 1, false, AnyPropertyType,
&actual_type, &actual_format, &nitems, &bytes_after, &data)) {
&actual_type, &actual_format, &nitems, &bytes_after, &data)) {
goto close; /* if an error occurs here, the WM probably isn't EWMH compliant */
}
@@ -186,7 +186,7 @@ bool xwin_should_render(struct gl_wcb* wcb, void* impl) {
ret = false;
}
}
close:
close:
if (data)
XFree(data);
if (should_close)
@@ -200,8 +200,8 @@ bool xwin_should_render(struct gl_wcb* wcb, void* impl) {
for (size_t t = 0; t < sizeof(out) / sizeof(char); ++t) { \
char c = in[t]; \
switch (c) { \
case 'a' ... 'z': c -= 'a' - 'A'; \
default: out[t] = c; \
case 'a' ... 'z': c -= 'a' - 'A'; \
default: out[t] = c; \
} \
} \
} while (0)
@@ -316,35 +316,35 @@ unsigned int xwin_copyglbg(struct renderer* rd, unsigned int tex) {
bool invalid = false, aligned = false;
GLenum type;
switch (image->bits_per_pixel) {
case 16:
switch (image->depth) {
case 12: type = GL_UNSIGNED_SHORT_4_4_4_4; break; /* 12-bit (rare) */
case 15: type = GL_UNSIGNED_SHORT_5_5_5_1; break; /* 15-bit, hi-color */
case 16: /* 16-bit, hi-color */
type = GL_UNSIGNED_SHORT_5_6_5;
aligned = true;
case 16:
switch (image->depth) {
case 12: type = GL_UNSIGNED_SHORT_4_4_4_4; break; /* 12-bit (rare) */
case 15: type = GL_UNSIGNED_SHORT_5_5_5_1; break; /* 15-bit, hi-color */
case 16: /* 16-bit, hi-color */
type = GL_UNSIGNED_SHORT_5_6_5;
aligned = true;
break;
}
break;
}
break;
case 32:
switch (image->depth) {
case 24: type = GL_UNSIGNED_BYTE; break; /* 24-bit, true color */
case 30: type = GL_UNSIGNED_INT_10_10_10_2; break; /* 30-bit, deep color */
}
break;
case 64:
if (image->depth == 48) /* 48-bit deep color */
type = GL_UNSIGNED_SHORT;
else goto invalid;
break;
/* >64-bit formats */
case 128:
if (image->depth == 96)
type = GL_UNSIGNED_INT;
else goto invalid;
break;
default:
invalid: invalid = true;
case 32:
switch (image->depth) {
case 24: type = GL_UNSIGNED_BYTE; break; /* 24-bit, true color */
case 30: type = GL_UNSIGNED_INT_10_10_10_2; break; /* 30-bit, deep color */
}
break;
case 64:
if (image->depth == 48) /* 48-bit deep color */
type = GL_UNSIGNED_SHORT;
else goto invalid;
break;
/* >64-bit formats */
case 128:
if (image->depth == 96)
type = GL_UNSIGNED_INT;
else goto invalid;
break;
default:
invalid: invalid = true;
}
uint8_t* buf;