diff --git a/Makefile.dev b/Makefile.dev index f98987e..507e193 100644 --- a/Makefile.dev +++ b/Makefile.dev @@ -20,7 +20,7 @@ build: .PHONY: run run: build - ./build/$(TARGET) $(TEST_ARGS) --hot-reload + ./build/$(TARGET) $(TEST_ARGS) --monitor-only --hot-reload .PHONY: demo demo: build diff --git a/README.md b/README.md index 443903a..a0a77d7 100644 --- a/README.md +++ b/README.md @@ -131,9 +131,9 @@ make -f Makefile.dev release-arch - [ ] Fixed camera video - [ ] Video mapping config file - [ ] Clean code and fix things -- [ ] Monitor screen - - [ ] 2nd window +- [x] Monitor screen + - [x] 2nd window - [x] Use buffers as panels (INA A FXA / DEBUG A+B FXA+B / INB B FXB) - - [ ] Clean code and fix things + - [x] Clean code and fix things - [ ] Packaging & install - [ ] Clone "shaders" and config in system path at setup \ No newline at end of file diff --git a/src/args.c b/src/args.c index accfb1a..ed1ec86 100644 --- a/src/args.c +++ b/src/args.c @@ -19,6 +19,7 @@ static void print_help(int status_code) { "[-hr] " "[-s=SCREEN] " "[-m=SCREEN] " + "[-mo] " "[-f=DIR_PATH] " "[-fc=CFG_PATH] " "[-is=SIZE] " @@ -33,6 +34,7 @@ static void print_help(int status_code) { " -hr, --hot-reload hot reload of shaders scripts\n" " -s, --screen output screen number (default: primary)\n" " -m, --monitor monitor screen number (default: none)\n" + " -mo, --monitor-only no output screen\n" " -f, --frag fragment shaders directory (default: TODO)\n" " -fc, --frag-config fragment shaders config file (default: TODO)\n" " -is, --internal-size internal texture height (default: 720)\n" @@ -77,9 +79,10 @@ Parameters args_parse(int argc, char **argv) { char *value; params.hot_reload = false; - params.screen = 0; - params.monitor_screen = 0; + params.output = true; + params.output_screen = 0; params.monitor = false; + params.monitor_screen = 0; params.frag_path = 0; params.frag_config_path = 0; params.internal_size = 720; @@ -98,7 +101,7 @@ Parameters args_parse(int argc, char **argv) { } else if (is_arg(arg, "-hr") || is_arg(arg, "--hot-reload")) { params.hot_reload = true; } else if (is_arg(arg, "-s") || is_arg(arg, "--screen")) { - params.screen = parse_uint(arg, value); + params.output_screen = parse_uint(arg, value); } else if (is_arg(arg, "-f") || is_arg(arg, "--frag")) { params.frag_path = value; } else if (is_arg(arg, "-fc") || is_arg(arg, "--frag-config")) { @@ -110,6 +113,9 @@ Parameters args_parse(int argc, char **argv) { } else if (is_arg(arg, "-m") || is_arg(arg, "--monitor")) { params.monitor = true; params.monitor_screen = parse_uint(arg, value); + } else if (is_arg(arg, "-mo") || is_arg(arg, "--monitor-only")) { + params.output = false; + params.monitor = true; } else if (is_arg(arg, "--demo")) { params.demo = true; } else if (is_arg(arg, "-w") || is_arg(arg, "--windowed")) { @@ -124,8 +130,8 @@ Parameters args_parse(int argc, char **argv) { exit(EXIT_FAILURE); } - if (params.monitor && params.monitor_screen == params.screen && - !params.windowed) { + if (params.monitor && params.output && + params.monitor_screen == params.output_screen && !params.windowed) { log_error("monitor screen cannot be the same as output screen"); exit(EXIT_FAILURE); } diff --git a/src/forge.c b/src/forge.c index 83ca505..240a738 100644 --- a/src/forge.c +++ b/src/forge.c @@ -17,16 +17,20 @@ static Context context; static ShaderProgram program; static ShaderProgram program_monitor; +static Window *window_output; +static Window *window_monitor; -static unsigned int compute_fps(Window *window_out, Window *window_monitor, - Timer *timer) { +static unsigned int compute_fps(Timer *timer) { static double fps; char title[100]; if (timer_inc(timer)) { fps = timer_reset(timer); - sprintf(title, PACKAGE " " VERSION " - %.0ffps", fps); - window_update_title(window_out, title); + + if (window_output != NULL) { + sprintf(title, PACKAGE " " VERSION " - %.0ffps", fps); + window_update_title(window_output, title); + } if (window_monitor != NULL) { sprintf(title, PACKAGE " " VERSION " (monitor) - %.0ffps", fps); @@ -39,21 +43,31 @@ static unsigned int compute_fps(Window *window_out, Window *window_monitor, static void randomize_context_state() { unsigned int i; + unsigned int size; + unsigned int variants; - for (i = 0; i < program.frag_count * program.sub_type_count; i++) { - context.sub_state[i] = rand_uint(program.sub_variant_count); + size = window_output != NULL + ? program.frag_count * program.sub_type_count + : program_monitor.frag_count * program_monitor.sub_type_count; + + variants = window_output != NULL ? program.sub_variant_count + : program_monitor.sub_variant_count; + + for (i = 0; i < size; i++) { + context.sub_state[i] = rand_uint(variants); } } static void init_context(Parameters params) { - - int size; - int i; + unsigned int size; + unsigned int i; context.tempo = params.base_tempo; context.demo = params.demo; context.monitor = params.monitor; - size = program.frag_count * program.sub_type_count; + size = window_output != NULL + ? program.frag_count * program.sub_type_count + : program_monitor.frag_count * program_monitor.sub_type_count; context.sub_state = malloc(size * sizeof(unsigned int)); for (i = 0; i < size; i++) { @@ -64,8 +78,10 @@ static void init_context(Parameters params) { randomize_context_state(); } - context.seeds = malloc(program.frag_count * sizeof(unsigned int)); - for (i = 0; i < (int)program.frag_count; i++) { + size = + window_output != NULL ? program.frag_count : program_monitor.frag_count; + context.seeds = malloc(size * sizeof(unsigned int)); + for (i = 0; i < size; i++) { context.seeds[i] = rand_uint(1000); } } @@ -77,46 +93,56 @@ static void free_context() { static void hot_reload(File *common_shader_code, File *fragment_shaders) { unsigned int i; + unsigned int frag_count; bool force_update; force_update = false; + frag_count = + window_output != NULL ? program.frag_count : program_monitor.frag_count; + if (file_should_update(*common_shader_code)) { file_update(common_shader_code); force_update = true; } - for (i = 0; i < program.frag_count; i++) { + for (i = 0; i < frag_count; i++) { if (force_update || file_should_update(fragment_shaders[i])) { file_update(&fragment_shaders[i]); file_prepend(&fragment_shaders[i], *common_shader_code); - shaders_update(program, fragment_shaders, i); + + if (window_output != NULL) { + shaders_update(program, fragment_shaders, i); + } + + if (window_monitor != NULL) { + shaders_update(program_monitor, fragment_shaders, i); + } } } } -static void loop(Window *window_out, Window *window_monitor, bool hr, - File *common_shader_code, File *fragment_shaders, +static void loop(bool hr, File *common_shader_code, File *fragment_shaders, Timer *timer) { if (hr) { hot_reload(common_shader_code, fragment_shaders); } - context.fps = compute_fps(window_out, window_monitor, timer); + context.fps = compute_fps(timer); - window_get_context(window_out, &context, true); + context.time = window_get_time(); - window_use(window_out); + if (window_output != NULL) { + window_use(window_output, &context); - shaders_compute(program, context, false); + shaders_compute(program, context, false); - window_refresh(window_out); + window_refresh(window_output); + } if (window_monitor != NULL) { - window_get_context(window_monitor, &context, false); - - window_use(window_monitor); + window_use(window_monitor, &context); shaders_compute(program_monitor, context, true); @@ -192,8 +218,6 @@ void forge_run(Parameters params) { unsigned int frag_count; File *fragment_shaders; File common_shader_code; - Window *window_out; - Window *window_monitor; Timer timer; ConfigFile shader_config; @@ -208,21 +232,25 @@ void forge_run(Parameters params) { window_startup(error_callback); - window_out = window_init(PACKAGE " " VERSION, params.screen, params.windowed, - NULL, key_callback); - - window_get_context(window_out, &context, true); - context.internal_size = params.internal_size; - program = shaders_init(fragment_shaders, shader_config, context); + if (params.output) { + window_output = window_init(PACKAGE " " VERSION, params.output_screen, + params.windowed, NULL, key_callback); + + window_use(window_output, &context); + + program = shaders_init(fragment_shaders, shader_config, context); + } else { + window_output = NULL; + } if (params.monitor) { window_monitor = window_init(PACKAGE " " VERSION " (monitor)", params.monitor_screen, - params.windowed, window_out, key_callback); + params.windowed, window_output, key_callback); - window_get_context(window_monitor, &context, false); + window_use(window_monitor, &context); program_monitor = shaders_init(fragment_shaders, shader_config, context); } else { @@ -231,8 +259,11 @@ void forge_run(Parameters params) { init_context(params); - if (program.error) { - window_close(window_out, true); + if ((window_output != NULL && program.error) || + (window_monitor != NULL && program_monitor.error)) { + if (window_output != NULL) { + window_close(window_output, true); + } if (window_monitor != NULL) { window_close(window_monitor, true); } @@ -243,17 +274,18 @@ void forge_run(Parameters params) { log_success("Initialized"); - while (!window_should_close(window_out) && + while ((window_output == NULL || !window_should_close(window_output)) && (window_monitor == NULL || !window_should_close(window_monitor))) { - loop(window_out, window_monitor, params.hot_reload, &common_shader_code, - fragment_shaders, &timer); + loop(params.hot_reload, &common_shader_code, fragment_shaders, &timer); } free_files(&common_shader_code, fragment_shaders, frag_count); config_file_free(shader_config); - window_close(window_out, true); + if (window_output != NULL) { + window_close(window_output, true); + } if (window_monitor != NULL) { window_close(window_monitor, true); } diff --git a/src/types.h b/src/types.h index cc3271f..aec11cf 100644 --- a/src/types.h +++ b/src/types.h @@ -11,9 +11,10 @@ typedef struct Parameters { bool hot_reload; - unsigned char screen; - unsigned char monitor_screen; + bool output; + unsigned char output_screen; bool monitor; + unsigned char monitor_screen; char *frag_path; char *frag_config_path; unsigned int internal_size; diff --git a/src/window.c b/src/window.c index 615e811..1129ba8 100644 --- a/src/window.c +++ b/src/window.c @@ -116,11 +116,6 @@ void window_update_title(Window *window, char *title) { glfwSetWindowTitle(window, title); } -void window_use(Window *window) { - glfwMakeContextCurrent(window); - gladLoadGL(glfwGetProcAddress); -} - void window_refresh(Window *window) { // swap front and back buffers glfwSwapBuffers(window); @@ -128,12 +123,12 @@ void window_refresh(Window *window) { void window_events() { glfwPollEvents(); } -void window_get_context(Window *window, Context *context, bool with_time) { - glfwGetFramebufferSize(window, &context->width, &context->height); +double window_get_time() { return glfwGetTime(); } - if (with_time) { - context->time = glfwGetTime(); - } +void window_use(Window *window, Context *context) { + glfwMakeContextCurrent(window); + gladLoadGL(glfwGetProcAddress); + glfwGetFramebufferSize(window, &context->width, &context->height); } void window_close(Window *window, bool hard) { diff --git a/src/window.h b/src/window.h index 26351e4..349bca3 100644 --- a/src/window.h +++ b/src/window.h @@ -11,14 +11,14 @@ Window *window_init(char *title, unsigned char monitor_index, bool windowed, void window_update_title(Window *window, char *title); -void window_use(Window *window); +double window_get_time(); + +void window_use(Window *window, Context *context); void window_refresh(Window *window); void window_events(); -void window_get_context(Window *window, Context *context, bool with_time); - void window_close(Window *window, bool hard); bool window_should_close(Window *window);