diff --git a/Makefile.am b/Makefile.am index 7350cf1..19d97d3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = foreign subdir-objects -Wall bin_PROGRAMS = forge -forge_SOURCES = src/main.c src/args.c src/forge.c src/file.c src/window.c src/shaders.c src/timer.c src/string.c src/config_file.c src/rand.c src/video.c src/shared.c src/midi.c src/state.c $(top_srcdir)/include/glad/gl.h $(top_srcdir)/include/glad/egl.h $(top_srcdir)/hashmap.c/hashmap.c $(top_srcdir)/log.c/src/log.c +forge_SOURCES = src/main.c src/args.c src/forge.c src/file.c src/window.c src/shaders.c src/timer.c src/string.c src/config_file.c src/rand.c src/video.c src/shared.c src/midi.c src/state.c src/arr.c $(top_srcdir)/include/glad/gl.h $(top_srcdir)/include/glad/egl.h $(top_srcdir)/hashmap.c/hashmap.c $(top_srcdir)/log.c/src/log.c forge_CFLAGS = -Ofast -march=native -flto -funroll-loops -fprefetch-loop-arrays -fno-exceptions -fopenmp -I$(top_srcdir)/include -DGLFW_INCLUDE_NONE -DGLFW_EXPOSE_NATIVE_EGL -DGLFW_NATIVE_INCLUDE_NONE -DLOG_USE_COLOR forge_LDADD = -lm -lGL -lglfw -include_HEADERS = src/main.h src/args.h src/config.h src/types.h src/forge.h src/file.h src/constants.h src/window.h src/shaders.h src/timer.h src/string.h src/config_file.h src/rand.h src/video.h src/shared.h src/midi.h src/state.h $(top_srcdir)/include/glad/gl.h $(top_srcdir)/include/glad/egl.h $(top_srcdir)/include/linmath.h $(top_srcdir)/include/hashmap.h $(top_srcdir)/include/log.h \ No newline at end of file +include_HEADERS = src/main.h src/args.h src/config.h src/types.h src/forge.h src/file.h src/constants.h src/window.h src/shaders.h src/timer.h src/string.h src/config_file.h src/rand.h src/video.h src/shared.h src/midi.h src/state.h src/arr.h $(top_srcdir)/include/glad/gl.h $(top_srcdir)/include/glad/egl.h $(top_srcdir)/include/linmath.h $(top_srcdir)/include/hashmap.h $(top_srcdir)/include/log.h \ No newline at end of file diff --git a/src/arr.c b/src/arr.c new file mode 100644 index 0000000..2865b87 --- /dev/null +++ b/src/arr.c @@ -0,0 +1,13 @@ +#include "arr.h" + +unsigned int arr_uint_index_of(UintArray array, unsigned int value) { + unsigned int i; + + for (i = 0; i < array.length; i++) { + if (array.values[i] == value) { + return i; + } + } + + return ARRAY_NOT_FOUND; +} \ No newline at end of file diff --git a/src/arr.h b/src/arr.h new file mode 100644 index 0000000..f373844 --- /dev/null +++ b/src/arr.h @@ -0,0 +1,8 @@ +#include "types.h" + +#ifndef ARR_H +#define ARR_H + +unsigned int arr_uint_index_of(UintArray array, unsigned int value); + +#endif /* ARR_H */ \ No newline at end of file diff --git a/src/config.h b/src/config.h index b389d83..c5f1333 100644 --- a/src/config.h +++ b/src/config.h @@ -25,4 +25,8 @@ #define ARRAY_SIZE 1024 #endif +#ifndef ARRAY_NOT_FOUND +#define ARRAY_NOT_FOUND ARRAY_SIZE + 1 +#endif + #endif /* CONFIG_H */ \ No newline at end of file diff --git a/src/forge.c b/src/forge.c index da5a2df..ecae2b0 100644 --- a/src/forge.c +++ b/src/forge.c @@ -64,7 +64,7 @@ static void init_context(Parameters params, unsigned int in_count, memset(context->state, 0, sizeof(context->state)); if (params.demo) { - state_randomize(context, state_config, frag_count); + state_randomize(context, state_config); } memset(context->active, 0, sizeof(context->active)); @@ -200,7 +200,7 @@ static void key_callback(Window *window, int key, window_close(window); } else if (window_char_key(key, action, 82)) { // R: randomize - state_randomize(context, state_config, program.frag_count); + state_randomize(context, state_config); } else if (window_char_key(key, action, 68)) { // D: demo on/off context->demo = !context->demo; @@ -208,8 +208,7 @@ static void key_callback(Window *window, int key, } static void midi_callback(unsigned char code, float value) { - state_apply_event(context, state_config, program.frag_count, midi, code, - value); + state_apply_event(context, state_config, midi, code, value); } static void loop(bool hr) { @@ -288,10 +287,9 @@ void forge_run(Parameters params) { window_use(window_output, context); - program = shaders_init( - fragment_shaders, config, context, inputs, params.video_in_count, - state_config.select_page_count * state_config.select_item_count, - state_config.src_count, NULL); + program = shaders_init(fragment_shaders, config, context, inputs, + params.video_in_count, state_config.state_max, + state_config.src_count, NULL); } else { window_output = NULL; } @@ -303,10 +301,10 @@ void forge_run(Parameters params) { window_use(window_monitor, context); - program = shaders_init( - fragment_shaders, config, context, inputs, params.video_in_count, - state_config.select_page_count * state_config.select_item_count, - state_config.src_count, window_output != NULL ? &program : NULL); + program = shaders_init(fragment_shaders, config, context, inputs, + params.video_in_count, state_config.state_max, + state_config.src_count, + window_output != NULL ? &program : NULL); } else { window_monitor = NULL; } diff --git a/src/shaders.c b/src/shaders.c index 8c6289f..b279333 100644 --- a/src/shaders.c +++ b/src/shaders.c @@ -493,7 +493,7 @@ static void use_program(ShaderProgram program, int i, bool output, write_uniform_1i(program.ifps_locations[i], context->fps); write_uniform_1i(program.idemo_locations[i], context->demo ? 1 : 0); write_uniform_1i(program.ipage_locations[i], context->page); - write_uniform_1i(program.iselected_locations[i], context->page); + write_uniform_1i(program.iselected_locations[i], context->selected); write_uniform_2f(program.ires_locations[i], &resolution); write_uniform_2f(program.itexres_locations[i], &tex_resolution); diff --git a/src/state.c b/src/state.c index 9f835ee..33a9777 100644 --- a/src/state.c +++ b/src/state.c @@ -1,5 +1,6 @@ #include +#include "arr.h" #include "config.h" #include "config_file.h" #include "midi.h" @@ -12,32 +13,37 @@ StateConfig state_parse_config(ConfigFile config) { StateConfig state_config; char name[256]; - state_config.select_page_count = + state_config.select_page_codes.length = config_file_get_int(config, "SELECT_PAGE_COUNT", 0); - for (i = 0; i < state_config.select_page_count; i++) { + for (i = 0; i < state_config.select_page_codes.length; i++) { sprintf(name, "SELECT_PAGE_%d", i + 1); - state_config.select_page_codes[i] = + state_config.select_page_codes.values[i] = config_file_get_int(config, name, UNSET_MIDI_CODE); } - state_config.select_item_count = + state_config.select_item_codes.length = config_file_get_int(config, "SELECT_ITEM_COUNT", 0); - for (i = 0; i < state_config.select_item_count; i++) { + for (i = 0; i < state_config.select_item_codes.length; i++) { sprintf(name, "SELECT_ITEM_%d", i + 1); - state_config.select_item_codes[i] = + state_config.select_item_codes.values[i] = config_file_get_int(config, name, UNSET_MIDI_CODE); } - frag_count = config_file_get_int(config, "FRAG_COUNT", 1); + state_config.state_max = state_config.select_page_codes.length * + state_config.select_item_codes.length; - for (i = 0; i < frag_count; i++) { + state_config.select_frag_codes.length = + config_file_get_int(config, "FRAG_COUNT", 1); + + for (i = 0; i < state_config.select_frag_codes.length; i++) { sprintf(name, "SELECT_FRAG_%d", i + 1); - state_config.select_frag_codes[i] = + state_config.select_frag_codes.values[i] = config_file_get_int(config, name, UNSET_MIDI_CODE); } + // TODO uint arrays state_config.src_count = config_file_get_int(config, "SRC_COUNT", 0); total = 0; @@ -96,9 +102,44 @@ StateConfig state_parse_config(ConfigFile config) { } void state_apply_event(SharedContext *context, StateConfig state_config, - unsigned int state_count, MidiDevice midi, - unsigned char code, float value) { - log_debug("midi: %d %.2f", code, value); + MidiDevice midi, unsigned char code, float value) { + unsigned int index; + bool found; + + found = false; + + if (value > 0) { + index = + arr_uint_index_of(state_config.select_page_codes, (unsigned int)code); + + // PAGE CHANGE + if (index != ARRAY_NOT_FOUND) { + context->page = index; + found = true; + } + + index = arr_uint_index_of(state_config.select_frag_codes, code); + + // TARGET CHANGE + if (index != ARRAY_NOT_FOUND) { + context->selected = index + 1; + found = true; + } + + index = arr_uint_index_of(state_config.select_item_codes, code); + + // ITEM CHANGE + if (index != ARRAY_NOT_FOUND) { + context->state[context->selected - 1] = + context->page * state_config.select_item_codes.length + index; + found = true; + } + } + + if (!found) { + log_debug("unknown midi: %d %.2f", code, value); + } + midi_write(midi, code, value); // TODO } @@ -127,12 +168,10 @@ bool state_background_midi_write(SharedContext *context, return false; } -void state_randomize(SharedContext *context, StateConfig state_config, - unsigned int state_count) { +void state_randomize(SharedContext *context, StateConfig state_config) { unsigned int i; - for (i = 0; i < state_count; i++) { - context->state[i] = rand_uint(state_config.select_page_count * - state_config.select_item_count); + for (i = 0; i < state_config.select_frag_codes.length; i++) { + context->state[i] = rand_uint(state_config.state_max); } } \ No newline at end of file diff --git a/src/state.h b/src/state.h index 2c12452..4152876 100644 --- a/src/state.h +++ b/src/state.h @@ -6,13 +6,11 @@ StateConfig state_parse_config(ConfigFile config); void state_apply_event(SharedContext *context, StateConfig state_config, - unsigned int state_count, MidiDevice midi, - unsigned char code, float value); + MidiDevice midi, unsigned char code, float value); bool state_background_midi_write(SharedContext *context, StateConfig state_config, MidiDevice midi); -void state_randomize(SharedContext *context, StateConfig state_config, - unsigned int state_count); +void state_randomize(SharedContext *context, StateConfig state_config); #endif /* STATE_H */ \ No newline at end of file diff --git a/src/types.h b/src/types.h index 21cf85a..846278d 100644 --- a/src/types.h +++ b/src/types.h @@ -14,6 +14,11 @@ #ifndef TYPES_H #define TYPES_H +typedef struct UintArray { + unsigned int values[ARRAY_SIZE]; + unsigned int length; +} UintArray; + typedef struct Parameters { bool hot_reload; bool output; @@ -135,14 +140,14 @@ typedef struct SharedContext { } SharedContext; typedef struct StateConfig { - unsigned int select_page_count; - unsigned int select_page_codes[ARRAY_SIZE]; + unsigned int state_max; - unsigned int select_item_count; - unsigned int select_item_codes[ARRAY_SIZE]; + UintArray select_page_codes; + UintArray select_item_codes; - unsigned int select_frag_codes[ARRAY_SIZE]; + UintArray select_frag_codes; + // TODO Uint arrays unsigned int src_count; unsigned int src_active_counts[ARRAY_SIZE]; unsigned int src_active_offsets[ARRAY_SIZE];