refactor(types): use array type when applicable

This commit is contained in:
2025-11-01 19:19:14 +01:00
parent aa0d03381b
commit 129ea6547f
6 changed files with 70 additions and 76 deletions
+3 -3
View File
@@ -98,7 +98,7 @@ Parameters args_parse(int argc, char **argv) {
params.base_tempo = 60.0f; params.base_tempo = 60.0f;
params.demo = false; params.demo = false;
params.windowed = false; params.windowed = false;
params.video_in_count = 0; params.video_in.length = 0;
for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {
arg = argv[i]; arg = argv[i];
@@ -122,12 +122,12 @@ Parameters args_parse(int argc, char **argv) {
invalid_value(arg, value); invalid_value(arg, value);
} }
} else if (is_arg(arg, "-v") || is_arg(arg, "--video-in")) { } else if (is_arg(arg, "-v") || is_arg(arg, "--video-in")) {
if (params.video_in_count == MAX_VIDEO) { if (params.video_in.length == MAX_VIDEO) {
log_error("maximum video input reached"); log_error("maximum video input reached");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
params.video_in[params.video_in_count++] = value; params.video_in.values[params.video_in.length++] = value;
} else if (is_arg(arg, "-vs") || is_arg(arg, "--video-size")) { } else if (is_arg(arg, "-vs") || is_arg(arg, "--video-size")) {
params.video_size = parse_uint(arg, value); params.video_size = parse_uint(arg, value);
if (params.video_size == 0) { if (params.video_size == 0) {
+16 -14
View File
@@ -65,7 +65,8 @@ static void init_context(Parameters params, unsigned int in_count,
context->demo = params.demo; context->demo = params.demo;
context->monitor = params.monitor; context->monitor = params.monitor;
memset(context->state, 0, sizeof(context->state)); context->state.length = frag_count;
memset(context->state.values, 0, sizeof(context->state.values));
if (params.demo) { if (params.demo) {
state_randomize(context, state_config); state_randomize(context, state_config);
@@ -83,15 +84,14 @@ static void init_context(Parameters params, unsigned int in_count,
context->seeds[i] = rand_uint(1000); context->seeds[i] = rand_uint(1000);
} }
memset(context->input_widths, 0, sizeof(context->input_widths)); memset(context->input_resolutions, 0, sizeof(context->input_resolutions));
memset(context->input_heights, 0, sizeof(context->input_heights));
memset(context->input_formats, 0, sizeof(context->input_formats)); memset(context->input_formats, 0, sizeof(context->input_formats));
memset(context->input_fps, 0, sizeof(context->input_fps)); memset(context->input_fps, 0, sizeof(context->input_fps));
for (i = 0; i < in_count; i++) { for (i = 0; i < in_count; i++) {
if (!inputs.values[i].error) { if (!inputs.values[i].error) {
context->input_widths[i] = inputs.values[i].width; context->input_resolutions[i][0] = inputs.values[i].width;
context->input_heights[i] = inputs.values[i].height; context->input_resolutions[i][1] = inputs.values[i].height;
context->input_formats[i] = inputs.values[i].pixelformat; context->input_formats[i] = inputs.values[i].pixelformat;
} }
} }
@@ -161,14 +161,13 @@ static void free_files(unsigned int frag_count) {
file_free(&common_shader_code, true); file_free(&common_shader_code, true);
} }
static void init_inputs(char *video_in[MAX_VIDEO], unsigned int input_count, static void init_inputs(StringArray video_in, unsigned int video_size) {
unsigned int video_size) {
unsigned int i; unsigned int i;
inputs.length = input_count; inputs.length = video_in.length;
for (i = 0; i < input_count; i++) { for (i = 0; i < video_in.length; i++) {
inputs.values[i] = video_init(video_in[i], video_size); inputs.values[i] = video_init(video_in.values[i], video_size);
} }
} }
@@ -207,12 +206,15 @@ static void key_callback(Window *window, int key,
__attribute__((unused)) int mods) { __attribute__((unused)) int mods) {
if (window_escape_key(key, action)) { if (window_escape_key(key, action)) {
// close window on escape key // close window on escape key
log_info("[ESC] Closing...");
window_close(window); window_close(window);
} else if (window_char_key(key, action, 82)) { } else if (window_char_key(key, action, 82)) {
// R: randomize // R: randomize
log_info("[R] Randomizing...");
state_randomize(context, state_config); state_randomize(context, state_config);
} else if (window_char_key(key, action, 68)) { } else if (window_char_key(key, action, 68)) {
// D: demo on/off // D: demo on/off
log_info((context->demo ? "[D] Demo OFF" : "[D] Demo ON"));
context->demo = !context->demo; context->demo = !context->demo;
} }
} }
@@ -265,11 +267,11 @@ void forge_run(Parameters params) {
init_files(params.frag_path, frag_count); init_files(params.frag_path, frag_count);
init_inputs(params.video_in, params.video_in_count, params.video_size); init_inputs(params.video_in, params.video_size);
init_context(params, in_count, frag_count); init_context(params, in_count, frag_count);
if (!start_video_captures(params.video_in_count)) { if (!start_video_captures(params.video_in.length)) {
return; return;
} }
@@ -289,7 +291,7 @@ void forge_run(Parameters params) {
window_startup(error_callback); window_startup(error_callback);
context->internal_height = params.internal_size; context->tex_resolution[1] = params.internal_size;
if (params.output) { if (params.output) {
window_output = window_init(PACKAGE " " VERSION, params.output_screen, window_output = window_init(PACKAGE " " VERSION, params.output_screen,
@@ -348,7 +350,7 @@ void forge_run(Parameters params) {
shaders_free_window(program, params.output); shaders_free_window(program, params.output);
} }
free_video_captures(params.video_in_count); free_video_captures(params.video_in.length);
free_context(); free_context();
+15 -26
View File
@@ -51,8 +51,8 @@ static void init_textures(ShaderProgram *program, SharedContext *context) {
glDisable(GL_BLEND); glDisable(GL_BLEND);
// define texture image as empty // define texture image as empty
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, context->internal_width, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, context->tex_resolution[0],
context->internal_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); context->tex_resolution[1], 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
// setup mipmap context // setup mipmap context
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -378,8 +378,8 @@ ShaderProgram shaders_init(FileArray fragment_shaders, ConfigFile config,
if (previous == NULL) { if (previous == NULL) {
program.error = false; program.error = false;
program.last_width = context->width; program.last_resolution[0] = context->resolution[0];
program.last_height = context->height; program.last_resolution[1] = context->resolution[1];
program.tex_count = config_file_get_int(config, "TEX_COUNT", 9); program.tex_count = config_file_get_int(config, "TEX_COUNT", 9);
program.frag_count = config_file_get_int(config, "FRAG_COUNT", 10); program.frag_count = config_file_get_int(config, "FRAG_COUNT", 10);
program.frag_output_index = program.frag_output_index =
@@ -446,13 +446,13 @@ static void update_viewport(ShaderProgram program, SharedContext *context) {
unsigned int i; unsigned int i;
// viewport changed // viewport changed
if (context->width != program.last_width || if (context->resolution[0] != program.last_resolution[0] ||
context->height != program.last_height) { context->resolution[1] != program.last_resolution[1]) {
// clean and resize all textures // clean and resize all textures
for (i = 0; i < program.tex_count; i++) { for (i = 0; i < program.tex_count; i++) {
glActiveTexture(GL_TEXTURE0 + i); glActiveTexture(GL_TEXTURE0 + i);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, context->internal_width, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, context->tex_resolution[0],
context->internal_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); context->tex_resolution[1], 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
} }
} }
} }
@@ -486,19 +486,11 @@ static void use_program(ShaderProgram program, int i, bool output,
SharedContext *context) { SharedContext *context) {
unsigned int j, k, offset; unsigned int j, k, offset;
GLuint subroutines[ARRAY_SIZE]; GLuint subroutines[ARRAY_SIZE];
// TODO direct vec2 in context
vec2 resolution, tex_resolution, in_resolution;
resolution[0] = (float)context->width;
resolution[1] = (float)context->height;
tex_resolution[0] = (float)context->internal_width;
tex_resolution[1] = (float)context->internal_height;
// use specific shader program // use specific shader program
glUseProgram(program.programs[i]); glUseProgram(program.programs[i]);
if (output) { if (output) {
glViewport(0, 0, context->width, context->height); glViewport(0, 0, context->resolution[0], context->resolution[1]);
// use default framebuffer (output) // use default framebuffer (output)
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -506,7 +498,7 @@ static void use_program(ShaderProgram program, int i, bool output,
// clear buffer // clear buffer
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
} else { } else {
glViewport(0, 0, context->internal_width, context->internal_height); glViewport(0, 0, context->tex_resolution[0], context->tex_resolution[1]);
// use memory framebuffer // use memory framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, program.frame_buffers[i]); glBindFramebuffer(GL_FRAMEBUFFER, program.frame_buffers[i]);
@@ -519,8 +511,8 @@ static void use_program(ShaderProgram program, int i, bool output,
write_uniform_1i(program.idemo_locations[i], context->demo ? 1 : 0); write_uniform_1i(program.idemo_locations[i], context->demo ? 1 : 0);
write_uniform_1i(program.ipage_locations[i], context->page); write_uniform_1i(program.ipage_locations[i], context->page);
write_uniform_1i(program.iselected_locations[i], context->selected + 1); write_uniform_1i(program.iselected_locations[i], context->selected + 1);
write_uniform_2f(program.ires_locations[i], &resolution); write_uniform_2f(program.ires_locations[i], &context->resolution);
write_uniform_2f(program.itexres_locations[i], &tex_resolution); write_uniform_2f(program.itexres_locations[i], &context->tex_resolution);
for (j = 0; j < program.active_count; j++) { for (j = 0; j < program.active_count; j++) {
write_uniform_1i(program.iactive_locations[i * program.active_count + j], write_uniform_1i(program.iactive_locations[i * program.active_count + j],
@@ -528,11 +520,8 @@ static void use_program(ShaderProgram program, int i, bool output,
} }
for (j = 0; j < program.in_count; j++) { for (j = 0; j < program.in_count; j++) {
in_resolution[0] = context->input_widths[j];
in_resolution[1] = context->input_heights[j];
write_uniform_2f(program.iinres_locations[i * program.in_count + j], write_uniform_2f(program.iinres_locations[i * program.in_count + j],
&in_resolution); &context->input_resolutions[j]);
write_uniform_1i(program.iinfmt_locations[i * program.in_count + j], write_uniform_1i(program.iinfmt_locations[i * program.in_count + j],
context->input_formats[j]); context->input_formats[j]);
write_uniform_1i(program.iinfps_locations[i * program.in_count + j], write_uniform_1i(program.iinfps_locations[i * program.in_count + j],
@@ -547,7 +536,7 @@ static void use_program(ShaderProgram program, int i, bool output,
for (j = 0; j < program.frag_count; j++) { for (j = 0; j < program.frag_count; j++) {
write_uniform_1i(program.istate_locations[i * program.frag_count + j], write_uniform_1i(program.istate_locations[i * program.frag_count + j],
context->state[j]); context->state.values[j]);
} }
offset = 0; offset = 0;
@@ -559,7 +548,7 @@ static void use_program(ShaderProgram program, int i, bool output,
} }
// set subroutines for fragment and update state uniforms // set subroutines for fragment and update state uniforms
k = context->state[i]; k = context->state.values[i];
for (j = 0; j < program.sub_type_count; j++) { for (j = 0; j < program.sub_type_count; j++) {
subroutines[j] = program.sub_locations[i * program.sub_type_count * subroutines[j] = program.sub_locations[i * program.sub_type_count *
program.sub_variant_count + program.sub_variant_count +
+16 -16
View File
@@ -10,8 +10,7 @@
#include "types.h" #include "types.h"
StateConfig state_parse_config(ConfigFile config) { StateConfig state_parse_config(ConfigFile config) {
unsigned int i, j, offset, total; unsigned int i, j, offset, count;
// TODO rename total var
StateConfig state_config; StateConfig state_config;
char name[256]; char name[256];
@@ -51,16 +50,16 @@ StateConfig state_parse_config(ConfigFile config) {
state_config.values_offsets.length = state_config.values_offsets.length =
config_file_get_int(config, "MIDI_COUNT", 0); config_file_get_int(config, "MIDI_COUNT", 0);
total = 0; count = 0;
for (i = 0; i < state_config.midi_active_counts.length; i++) { for (i = 0; i < state_config.midi_active_counts.length; i++) {
sprintf(name, "MIDI_%d_ACTIVE_COUNT", i + 1); sprintf(name, "MIDI_%d_ACTIVE_COUNT", i + 1);
state_config.midi_active_counts.values[i] = state_config.midi_active_counts.values[i] =
config_file_get_int(config, name, 1); config_file_get_int(config, name, 1);
state_config.midi_active_offsets.values[i] = total; state_config.midi_active_offsets.values[i] = count;
total += state_config.midi_active_counts.values[i]; count += state_config.midi_active_counts.values[i];
} }
state_config.midi_active_codes.length = total; state_config.midi_active_codes.length = count;
for (i = 0; i < state_config.midi_active_counts.length; i++) { for (i = 0; i < state_config.midi_active_counts.length; i++) {
for (j = 0; j < state_config.midi_active_counts.values[i]; j++) { for (j = 0; j < state_config.midi_active_counts.values[i]; j++) {
@@ -71,19 +70,19 @@ StateConfig state_parse_config(ConfigFile config) {
} }
} }
total = 0; count = 0;
offset = 0; offset = 0;
for (i = 0; i < state_config.midi_counts.length; i++) { for (i = 0; i < state_config.midi_counts.length; i++) {
sprintf(name, "MIDI_%d_COUNT", i + 1); sprintf(name, "MIDI_%d_COUNT", i + 1);
state_config.midi_counts.values[i] = config_file_get_int(config, name, 0); state_config.midi_counts.values[i] = config_file_get_int(config, name, 0);
state_config.midi_offsets.values[i] = total; state_config.midi_offsets.values[i] = count;
state_config.values_offsets.values[i] = offset; state_config.values_offsets.values[i] = offset;
offset += state_config.midi_counts.values[i] * offset += state_config.midi_counts.values[i] *
state_config.midi_active_counts.values[i]; state_config.midi_active_counts.values[i];
total += state_config.midi_counts.values[i]; count += state_config.midi_counts.values[i];
} }
state_config.midi_codes.length = total * 3; state_config.midi_codes.length = count * 3;
for (i = 0; i < state_config.midi_counts.length; i++) { for (i = 0; i < state_config.midi_counts.length; i++) {
offset = state_config.midi_offsets.values[i]; offset = state_config.midi_offsets.values[i];
@@ -137,11 +136,12 @@ static void update_page(SharedContext *context, StateConfig state_config,
page_item_min = state_config.select_item_codes.length * context->page; page_item_min = state_config.select_item_codes.length * context->page;
page_item_max = page_item_min + state_config.select_item_codes.length; page_item_max = page_item_min + state_config.select_item_codes.length;
if (context->state[context->selected] >= page_item_min && if (context->state.values[context->selected] >= page_item_min &&
context->state[context->selected] < page_item_max) { context->state.values[context->selected] < page_item_max) {
for (i = 0; i < state_config.select_item_codes.length; i++) { for (i = 0; i < state_config.select_item_codes.length; i++) {
safe_midi_write(midi, state_config.select_item_codes.values[i], safe_midi_write(midi, state_config.select_item_codes.values[i],
i == context->state[context->selected] - page_item_min i == context->state.values[context->selected] -
page_item_min
? MIDI_MAX ? MIDI_MAX
: 0); : 0);
} }
@@ -212,7 +212,7 @@ void state_apply_event(SharedContext *context, StateConfig state_config,
if (i != ARRAY_NOT_FOUND) { if (i != ARRAY_NOT_FOUND) {
found = true; found = true;
if (value > 0) { if (value > 0) {
context->state[context->selected] = context->state.values[context->selected] =
context->page * state_config.select_item_codes.length + i; context->page * state_config.select_item_codes.length + i;
update_page(context, state_config, midi); update_page(context, state_config, midi);
} }
@@ -320,7 +320,7 @@ bool state_background_midi_write(SharedContext *context,
void state_randomize(SharedContext *context, StateConfig state_config) { void state_randomize(SharedContext *context, StateConfig state_config) {
unsigned int i; unsigned int i;
for (i = 0; i < state_config.select_frag_codes.length; i++) { for (i = 0; i < context->state.length; i++) {
context->state[i] = rand_uint(state_config.state_max); context->state.values[i] = rand_uint(state_config.state_max);
} }
} }
+8 -14
View File
@@ -38,9 +38,7 @@ typedef struct Parameters {
float base_tempo; float base_tempo;
bool demo; bool demo;
bool windowed; bool windowed;
// TODO use array StringArray video_in;
char *video_in[MAX_VIDEO];
unsigned int video_in_count;
} Parameters; } Parameters;
typedef struct Vertex { typedef struct Vertex {
@@ -59,8 +57,7 @@ typedef ARRAY(FileArray, File);
typedef struct ShaderProgram { typedef struct ShaderProgram {
bool error; bool error;
int last_width; vec2 last_resolution;
int last_height;
GLuint vertex_shader; GLuint vertex_shader;
@@ -143,16 +140,14 @@ typedef struct Tempo {
typedef struct SharedContext { typedef struct SharedContext {
int fd; int fd;
// TODO use arrays vec2 resolution;
int width; vec2 tex_resolution;
int height; vec2 input_resolutions[MAX_VIDEO];
unsigned int internal_width;
unsigned int internal_height;
double time; double time;
unsigned int fps; unsigned int fps;
Tempo tempo; Tempo tempo;
// TODO use array UintArray state;
unsigned int state[MAX_FRAG];
unsigned int page; unsigned int page;
unsigned int selected; unsigned int selected;
unsigned int active[ARRAY_SIZE]; unsigned int active[ARRAY_SIZE];
@@ -160,8 +155,7 @@ typedef struct SharedContext {
bool demo; bool demo;
unsigned int seeds[MAX_FRAG]; unsigned int seeds[MAX_FRAG];
bool monitor; bool monitor;
unsigned int input_widths[MAX_VIDEO];
unsigned int input_heights[MAX_VIDEO];
unsigned int input_formats[MAX_VIDEO]; unsigned int input_formats[MAX_VIDEO];
unsigned int input_fps[MAX_VIDEO]; unsigned int input_fps[MAX_VIDEO];
bool stop; bool stop;
+12 -3
View File
@@ -120,10 +120,19 @@ void window_events() { glfwPollEvents(); }
double window_get_time() { return glfwGetTime(); } double window_get_time() { return glfwGetTime(); }
void window_use(Window *window, SharedContext *context) { void window_use(Window *window, SharedContext *context) {
int width, height;
glfwMakeContextCurrent(window); glfwMakeContextCurrent(window);
glfwGetFramebufferSize(window, &context->width, &context->height); glfwGetFramebufferSize(window, &width, &height);
context->internal_width = (int)(context->internal_height * context->resolution[0] = width;
(float)context->width / (context->height)); context->resolution[1] = height;
context->tex_resolution[0] =
(int)(context->tex_resolution[1] * context->resolution[0] /
context->resolution[1]);
log_debug("Resolution %f %f", context->resolution[0], context->resolution[1]);
log_debug("Tex resolution %f %f", context->tex_resolution[0],
context->tex_resolution[1]);
} }
void window_close(Window *window) { void window_close(Window *window) {