feat(state): load state on start
This commit is contained in:
+1
-1
@@ -24,4 +24,4 @@ pkg
|
|||||||
forge-*
|
forge-*
|
||||||
confdeps.*
|
confdeps.*
|
||||||
conftest.*
|
conftest.*
|
||||||
state.txt
|
forge_saved_state.txt
|
||||||
@@ -54,7 +54,7 @@ make install
|
|||||||
## CLI arguments
|
## CLI arguments
|
||||||
|
|
||||||
```txt
|
```txt
|
||||||
usage: forge [-h] [-v] [-hr] [-s=SCREEN] [-m=SCREEN] [-mo] [-f=DIR_PATH] [-c=CFG_PATH] [-is=SIZE] [-v=FILE] [-vs=SIZE] [-t=TEMPO] [--demo] [-w]
|
usage: forge [-h] [-v] [-hr] [-s=SCREEN] [-m=SCREEN] [-mo] [-f=DIR_PATH] [-c=CFG_PATH] [-sf=STATE_PATH] [-ls / -nls] [-ss / -nss] [-is=SIZE] [-v=FILE] [-vs=SIZE] [-t=TEMPO] [--demo] [-w]
|
||||||
|
|
||||||
Fusion Of Real-time Generative Effects.
|
Fusion Of Real-time Generative Effects.
|
||||||
|
|
||||||
@@ -67,11 +67,16 @@ options:
|
|||||||
-mo, --monitor-only no output screen
|
-mo, --monitor-only no output screen
|
||||||
-f, --frag fragment shaders directory (default: /usr/share/forge/shaders)
|
-f, --frag fragment shaders directory (default: /usr/share/forge/shaders)
|
||||||
-c, --config fragment shaders config file (default: /usr/share/forge/default.cfg)
|
-c, --config fragment shaders config file (default: /usr/share/forge/default.cfg)
|
||||||
|
-sf, --state-file saved state file (default: forge_saved_state.txt)
|
||||||
|
-ls, --load-state load saved state (default)
|
||||||
|
-nls, --no-load-state do not load saved state
|
||||||
|
-ss, --save-state save state (default)
|
||||||
|
-nss, --no-save-state do not save state
|
||||||
-is, --internal-size internal texture height (default: 720)
|
-is, --internal-size internal texture height (default: 720)
|
||||||
-v, --video-in path to video capture device (multiple allowed)
|
-v, --video-in path to video capture device (multiple allowed)
|
||||||
-vs, --video-size video capture desired height (default: internal texture height)
|
-vs, --video-size video capture desired height (default: internal texture height)
|
||||||
-t, --tempo base tempo (default: 60)
|
-t, --tempo base tempo (default: 60)
|
||||||
--demo demonstration mode
|
--demo demonstration mode (assume --no-save-state and --no-load-state)
|
||||||
-w, --windowed not fullscreen
|
-w, --windowed not fullscreen
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -126,7 +131,7 @@ make -f Makefile.dev release-arch
|
|||||||
- [x] Write Midi events
|
- [x] Write Midi events
|
||||||
- [x] Send midi data to shaders
|
- [x] Send midi data to shaders
|
||||||
- [x] Save midi state
|
- [x] Save midi state
|
||||||
- [ ] Load midi state from last save
|
- [x] Load midi state from last save
|
||||||
- [x] State machine with A/B switch
|
- [x] State machine with A/B switch
|
||||||
- [x] Tap-tempo feature
|
- [x] Tap-tempo feature
|
||||||
- [ ] Clean code and fix things
|
- [ ] Clean code and fix things
|
||||||
|
|||||||
+23
-8
@@ -23,7 +23,8 @@ static void print_help(int status_code) {
|
|||||||
"[-f=DIR_PATH] "
|
"[-f=DIR_PATH] "
|
||||||
"[-c=CFG_PATH] "
|
"[-c=CFG_PATH] "
|
||||||
"[-sf=STATE_PATH] "
|
"[-sf=STATE_PATH] "
|
||||||
"[-es] "
|
"[-ls / -nls] "
|
||||||
|
"[-ss / -nss] "
|
||||||
"[-is=SIZE] "
|
"[-is=SIZE] "
|
||||||
"[-v=FILE] "
|
"[-v=FILE] "
|
||||||
"[-vs=SIZE] "
|
"[-vs=SIZE] "
|
||||||
@@ -41,17 +42,22 @@ static void print_help(int status_code) {
|
|||||||
" -mo, --monitor-only no output screen\n"
|
" -mo, --monitor-only no output screen\n"
|
||||||
" -f, --frag fragment shaders directory "
|
" -f, --frag fragment shaders directory "
|
||||||
"(default: " DATADIR "/shaders)\n"
|
"(default: " DATADIR "/shaders)\n"
|
||||||
" -sf, --state-file state save file (default: state.txt)\n"
|
|
||||||
" -es, --empty-state do not load state save file\n"
|
|
||||||
" -c, --config fragment shaders config file "
|
" -c, --config fragment shaders config file "
|
||||||
"(default: " DATADIR "/default.cfg)\n"
|
"(default: " DATADIR "/default.cfg)\n"
|
||||||
|
" -sf, --state-file saved state file (default: "
|
||||||
|
"forge_saved_state.txt)\n"
|
||||||
|
" -ls, --load-state load saved state (default)\n"
|
||||||
|
" -nls, --no-load-state do not load saved state\n"
|
||||||
|
" -ss, --save-state save state (default)\n"
|
||||||
|
" -nss, --no-save-state do not save state\n"
|
||||||
" -is, --internal-size internal texture height (default: 720)\n"
|
" -is, --internal-size internal texture height (default: 720)\n"
|
||||||
" -v, --video-in path to video capture device (multiple "
|
" -v, --video-in path to video capture device (multiple "
|
||||||
"allowed)\n"
|
"allowed)\n"
|
||||||
" -vs, --video-size video capture desired height (default: "
|
" -vs, --video-size video capture desired height (default: "
|
||||||
"internal texture height)\n"
|
"internal texture height)\n"
|
||||||
" -t, --tempo base tempo (default: 60)\n"
|
" -t, --tempo base tempo (default: 60)\n"
|
||||||
" --demo demonstration mode\n"
|
" --demo demonstration mode (assume --no-save-state "
|
||||||
|
"and --no-load-state)\n"
|
||||||
" -w, --windowed not fullscreen\n");
|
" -w, --windowed not fullscreen\n");
|
||||||
exit(status_code);
|
exit(status_code);
|
||||||
}
|
}
|
||||||
@@ -97,8 +103,9 @@ Parameters args_parse(int argc, char **argv) {
|
|||||||
params.monitor_screen = 0;
|
params.monitor_screen = 0;
|
||||||
params.frag_path = DATADIR "/shaders";
|
params.frag_path = DATADIR "/shaders";
|
||||||
params.config_path = DATADIR "/default.cfg";
|
params.config_path = DATADIR "/default.cfg";
|
||||||
params.state_file = "state.txt";
|
params.state_file = "forge_saved_state.txt";
|
||||||
params.empty_state = false;
|
params.load_state = true;
|
||||||
|
params.save_state = false;
|
||||||
params.internal_size = 720;
|
params.internal_size = 720;
|
||||||
params.video_size = 0;
|
params.video_size = 0;
|
||||||
params.base_tempo = 60.0f;
|
params.base_tempo = 60.0f;
|
||||||
@@ -124,8 +131,14 @@ Parameters args_parse(int argc, char **argv) {
|
|||||||
params.config_path = value;
|
params.config_path = value;
|
||||||
} else if (is_arg(arg, "-sf") || is_arg(arg, "--state-file")) {
|
} else if (is_arg(arg, "-sf") || is_arg(arg, "--state-file")) {
|
||||||
params.state_file = value;
|
params.state_file = value;
|
||||||
} else if (is_arg(arg, "-es") || is_arg(arg, "--empty-state")) {
|
} else if (is_arg(arg, "-ls") || is_arg(arg, "--load-state")) {
|
||||||
params.empty_state = true;
|
params.load_state = true;
|
||||||
|
} else if (is_arg(arg, "-nls") || is_arg(arg, "--no-load-state")) {
|
||||||
|
params.load_state = false;
|
||||||
|
} else if (is_arg(arg, "-ss") || is_arg(arg, "--save-state")) {
|
||||||
|
params.save_state = true;
|
||||||
|
} else if (is_arg(arg, "-nss") || is_arg(arg, "--no-save-state")) {
|
||||||
|
params.save_state = false;
|
||||||
} else if (is_arg(arg, "-is") || is_arg(arg, "--internal-size")) {
|
} else if (is_arg(arg, "-is") || is_arg(arg, "--internal-size")) {
|
||||||
params.internal_size = parse_uint(arg, value);
|
params.internal_size = parse_uint(arg, value);
|
||||||
if (params.internal_size == 0) {
|
if (params.internal_size == 0) {
|
||||||
@@ -153,6 +166,8 @@ Parameters args_parse(int argc, char **argv) {
|
|||||||
params.monitor = true;
|
params.monitor = true;
|
||||||
} else if (is_arg(arg, "--demo")) {
|
} else if (is_arg(arg, "--demo")) {
|
||||||
params.demo = true;
|
params.demo = true;
|
||||||
|
params.load_state = false;
|
||||||
|
params.save_state = false;
|
||||||
} else if (is_arg(arg, "-w") || is_arg(arg, "--windowed")) {
|
} else if (is_arg(arg, "-w") || is_arg(arg, "--windowed")) {
|
||||||
params.windowed = true;
|
params.windowed = true;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+1
-1
@@ -103,7 +103,7 @@ char *config_file_get_str(ConfigFile config, char *key, char *default_value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned int config_file_get_int(ConfigFile config, char *key,
|
unsigned int config_file_get_int(ConfigFile config, char *key,
|
||||||
int default_value) {
|
unsigned int default_value) {
|
||||||
ConfigFileItem c_key;
|
ConfigFileItem c_key;
|
||||||
ConfigFileItem *item;
|
ConfigFileItem *item;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ ConfigFile config_file_read(char *path, bool free_path);
|
|||||||
char *config_file_get_str(ConfigFile config, char *key, char *default_value);
|
char *config_file_get_str(ConfigFile config, char *key, char *default_value);
|
||||||
|
|
||||||
unsigned int config_file_get_int(ConfigFile config, char *key,
|
unsigned int config_file_get_int(ConfigFile config, char *key,
|
||||||
int default_value);
|
unsigned int default_value);
|
||||||
|
|
||||||
void config_file_free(ConfigFile config);
|
void config_file_free(ConfigFile config);
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -59,7 +59,7 @@ static void init_context(Parameters params, unsigned int in_count) {
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
state_init(context, state_config, params.demo, params.base_tempo,
|
state_init(context, state_config, params.demo, params.base_tempo,
|
||||||
params.state_file, params.empty_state);
|
params.state_file, params.load_state);
|
||||||
|
|
||||||
context->monitor = params.monitor;
|
context->monitor = params.monitor;
|
||||||
|
|
||||||
@@ -315,7 +315,9 @@ void forge_run(Parameters params) {
|
|||||||
|
|
||||||
context->stop = true;
|
context->stop = true;
|
||||||
|
|
||||||
state_save(context, state_config, params.state_file);
|
if (params.save_state) {
|
||||||
|
state_save(context, state_config, params.state_file);
|
||||||
|
}
|
||||||
|
|
||||||
shaders_free(program);
|
shaders_free(program);
|
||||||
|
|
||||||
|
|||||||
+34
-8
@@ -321,21 +321,47 @@ bool state_background_midi_write(SharedContext *context,
|
|||||||
|
|
||||||
void state_load(SharedContext *context, StateConfig state_config,
|
void state_load(SharedContext *context, StateConfig state_config,
|
||||||
char *state_file) {
|
char *state_file) {
|
||||||
File saved_state;
|
ConfigFile saved_state;
|
||||||
|
char key[100];
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
saved_state = file_read(state_file);
|
saved_state = config_file_read(state_file, false);
|
||||||
|
|
||||||
if (saved_state.error) {
|
tempo_set(&context->tempo,
|
||||||
return;
|
config_file_get_int(saved_state, "tempo", context->tempo.tempo));
|
||||||
|
context->page = config_file_get_int(saved_state, "page", 0);
|
||||||
|
context->selected = config_file_get_int(saved_state, "selected", 0);
|
||||||
|
|
||||||
|
for (i = 0; i < context->state.length; i++) {
|
||||||
|
sprintf(key, "seed_%d", i);
|
||||||
|
context->seeds[i] =
|
||||||
|
config_file_get_int(saved_state, key, context->seeds[i]);
|
||||||
|
sprintf(key, "state_%d", i);
|
||||||
|
context->state.values[i] = config_file_get_int(saved_state, key, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO load state
|
for (i = 0; i < state_config.midi_active_counts.length; i++) {
|
||||||
|
sprintf(key, "active_%d", i);
|
||||||
|
context->active[i] = config_file_get_int(saved_state, key, 0);
|
||||||
|
}
|
||||||
|
|
||||||
file_free(&saved_state, false);
|
for (i = 0; i < state_config.midi_codes.length; i++) {
|
||||||
|
sprintf(key, "value_%d_x", i);
|
||||||
|
context->values[i][0] =
|
||||||
|
(float)config_file_get_int(saved_state, key, 0) / MIDI_MAX;
|
||||||
|
sprintf(key, "value_%d_y", i);
|
||||||
|
context->values[i][1] =
|
||||||
|
(float)config_file_get_int(saved_state, key, 0) / MIDI_MAX;
|
||||||
|
sprintf(key, "value_%d_z", i);
|
||||||
|
context->values[i][2] =
|
||||||
|
(float)config_file_get_int(saved_state, key, 0) / MIDI_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
config_file_free(saved_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void state_init(SharedContext *context, StateConfig state_config, bool demo,
|
void state_init(SharedContext *context, StateConfig state_config, bool demo,
|
||||||
unsigned int base_tempo, char *state_file, bool empty_state) {
|
unsigned int base_tempo, char *state_file, bool load_state) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
context->tempo = tempo_init();
|
context->tempo = tempo_init();
|
||||||
@@ -361,7 +387,7 @@ void state_init(SharedContext *context, StateConfig state_config, bool demo,
|
|||||||
context->seeds[i] = rand_uint(1000);
|
context->seeds[i] = rand_uint(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty_state) {
|
if (load_state) {
|
||||||
state_load(context, state_config, state_file);
|
state_load(context, state_config, state_file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ bool state_background_midi_write(SharedContext *context,
|
|||||||
StateConfig state_config, MidiDevice midi);
|
StateConfig state_config, MidiDevice midi);
|
||||||
|
|
||||||
void state_init(SharedContext *context, StateConfig state_config, bool demo,
|
void state_init(SharedContext *context, StateConfig state_config, bool demo,
|
||||||
unsigned int base_tempo, char *state_file, bool empty_state);
|
unsigned int base_tempo, char *state_file, bool load_state);
|
||||||
|
|
||||||
void state_randomize(SharedContext *context, StateConfig state_config);
|
void state_randomize(SharedContext *context, StateConfig state_config);
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -39,7 +39,8 @@ typedef struct Parameters {
|
|||||||
char *frag_path;
|
char *frag_path;
|
||||||
char *config_path;
|
char *config_path;
|
||||||
char *state_file;
|
char *state_file;
|
||||||
bool empty_state;
|
bool load_state;
|
||||||
|
bool save_state;
|
||||||
unsigned int internal_size;
|
unsigned int internal_size;
|
||||||
unsigned int video_size;
|
unsigned int video_size;
|
||||||
float base_tempo;
|
float base_tempo;
|
||||||
|
|||||||
Reference in New Issue
Block a user