Beispiel #1
0
static void shader_write_scale_dim(config_file_t *conf, const char *dim,
      enum gfx_scale_type type, float scale, unsigned abs, unsigned i)
{
   char key[64];
   print_buf(key, "scale_type_%s%u", dim, i);
   config_set_string(conf, key, scale_type_to_str(type));

   print_buf(key, "scale_%s%u", dim, i);
   if (type == RARCH_SCALE_ABSOLUTE)
      config_set_int(conf, key, abs);
   else
      config_set_float(conf, key, scale);
}
Beispiel #2
0
/**
 * Simple test cases classification
 */
int test_classify()
{
    int i, k, err = 0;
    fvec_t *f;

    test_printf("Classification using prototypes");

    /* Prepare training data */
    farray_t *fa1 = farray_create("train");
    for (i = 0; train_data[i].str; i++) {
        f = fvec_extract(train_data[i].str, strlen(train_data[i].str), NULL);
        farray_add(fa1, f, train_data[i].label);
    }

    /* Prepare testing data */
    farray_t *fa2 = farray_create("train");
    for (i = 0; test_data[i].str; i++) {
        f = fvec_extract(test_data[i].str, strlen(test_data[i].str), NULL);
        farray_add(fa2, f, test_data[i].label);
    }

    /* Classification of test data */
    config_set_float(&cfg, "classify.max_dist", 1.41);
    assign_t *a = class_assign(fa2, fa1);
    
    /* Check predicted labels */
    for (k = 0; test_data[k].str; k++) {
        char *l = farray_get_label(fa1, a->proto[k]);
        err += strcmp(l, test_data[k].label) != 0;
    }

    /* Clean up */
    assign_destroy(a);
    farray_destroy(fa1); 
    farray_destroy(fa2);

    test_return(err, i);
    return err;
}
Beispiel #3
0
/**
 * Test runs
 * @param error flag
 */
int test_compare()
{
    int i, err = FALSE;
    hstring_t x, y;

    printf("Testing subsequence kernel ");
    for (i = 0; tests[i].x && !err; i++) {
        config_set_float(&cfg, "measures.kern_subsequence.lambda",
                         tests[i].l);
        config_set_int(&cfg, "measures.kern_subsequence.length", tests[i].p);
        config_set_string(&cfg, "measures.kern_subsequence.norm", tests[i].n);
        measure_config("kern_subsequence");

        x = hstring_init(x, tests[i].x);
        y = hstring_init(y, tests[i].y);

        x = hstring_preproc(x);
        y = hstring_preproc(y);

        float d = measure_compare(x, y);
        double diff = fabs(tests[i].v - d);

        printf(".");
        if (diff > 1e-6) {
            printf("Error %f != %f\n", d, tests[i].v);
            hstring_print(x);
            hstring_print(y);
            err = TRUE;
        }

        hstring_destroy(&x);
        hstring_destroy(&y);
    }
    printf(" done.\n");

    return err;
}
Beispiel #4
0
/**
 * Parse command line options
 * @param argc Number of arguments
 * @param argv Argument values
 */
static void sally_parse_options(int argc, char **argv)
{
    int ch, user_conf = FALSE;

    optind = 0;

    while ((ch = getopt_long(argc, argv, OPTSTRING, longopts, NULL)) != -1) {
        switch (ch) {
        case 'c':
            /* Skip. See sally_load_config(). */
            user_conf = TRUE;
            break;
        case 'i':
            config_set_string(&cfg, "input.input_format", optarg);
            break;
        case 1000:
            config_set_int(&cfg, "input.chunk_size", atoi(optarg));
            break;
        case 1001:
            config_set_string(&cfg, "input.fasta_regex", optarg);
            break;
        case 1002:
            config_set_string(&cfg, "input.lines_regex", optarg);
            break;
        case 1005:
            config_set_int(&cfg, "input.decode_str", atoi(optarg));
            break;
        case 1006:
            config_set_int(&cfg, "features.vect_sign", atoi(optarg));
            break;
        case 1007:
            config_set_int(&cfg, "input.reverse_str", atoi(optarg));
            break;
        case 1008:
            config_set_string(&cfg, "input.stopword_file", optarg);
            break;
        case 1009:
            config_set_float(&cfg, "features.thres_low", atof(optarg));
            break;
        case 1010:
            config_set_float(&cfg, "features.thres_high", atof(optarg));
            break;
        case 1011:
            config_set_string(&cfg, "features.hash_file", optarg);
            break;
        case 'n':
            config_set_int(&cfg, "features.ngram_len", atoi(optarg));
            break;
        case 'd':
            config_set_string(&cfg, "features.ngram_delim", optarg);
            break;
        case 'p':
            config_set_int(&cfg, "features.ngram_pos", atoi(optarg));
            break;
        case 's':
            config_set_int(&cfg, "features.ngram_sort", atoi(optarg));
            break;
        case 'E':
            config_set_string(&cfg, "features.vect_embed", optarg);
            break;
        case 'N':
            config_set_string(&cfg, "features.vect_norm", optarg);
            break;
        case 'b':
            config_set_int(&cfg, "features.hash_bits", atoi(optarg));
            break;
        case 1003:
            config_set_int(&cfg, "features.explicit_hash", atoi(optarg));
            break;
        case 1004:
            config_set_string(&cfg, "features.tfidf_file", optarg);
            break;
        case 'o':
            config_set_string(&cfg, "output.output_format", optarg);
            break;
        case 'q':
            verbose = 0;
            break;
        case 'v':
            verbose++;
            break;
        case 'D':
            print_config("Default configuration");
            exit(EXIT_SUCCESS);
            break;
        case 'C':
            print_conf = 1;
            break;
        case 'V':
            print_version();
            exit(EXIT_SUCCESS);
            break;
        case 'h':
        case '?':
            print_usage();
            exit(EXIT_SUCCESS);
            break;
        }
    }

#ifdef ENABLE_EVALTIME
    config_set_int(&cfg, "input.chunk_size", 1);
    verbose = 0;
#endif

    /* Check configuration */
    if(!config_check(&cfg)) {
        exit(EXIT_FAILURE);
    }

    /* We are through with parsing. Print the config if requested */
    if (print_conf) {
        print_config("Current configuration");
        exit(EXIT_SUCCESS);
    }

    argc -= optind;
    argv += optind;
    
    /* Check for input and output arguments */
    if (argc != 2) {
        print_usage();
        exit(EXIT_FAILURE);
    } else {
        input = argv[0];
        output = argv[1];
    }
    
    /* Last but not least. Warn about default config */
    if (!user_conf) {
        warning("No config file given. Using defaults (see -D)");
    }
}
Beispiel #5
0
/** 
 * video_shader_write_conf_cgp:
 * @conf              : Preset file to read from.
 * @shader            : Shader passes handle.
 *
 * Saves preset and all associated state (passes,
 * textures, imports, etc) to disk. 
 **/
void video_shader_write_conf_cgp(config_file_t *conf,
      struct video_shader *shader)
{
   unsigned i;

   config_set_int(conf, "shaders", shader->passes);
   if (shader->feedback_pass >= 0)
      config_set_int(conf, "feedback_pass", shader->feedback_pass);

   for (i = 0; i < shader->passes; i++)
   {
      char key[64] = {0};
      const struct video_shader_pass *pass = &shader->pass[i];

      snprintf(key, sizeof(key), "shader%u", i);
      config_set_string(conf, key, pass->source.path);

      if (pass->filter != RARCH_FILTER_UNSPEC)
      {
         snprintf(key, sizeof(key), "filter_linear%u", i);
         config_set_bool(conf, key, pass->filter == RARCH_FILTER_LINEAR);
      }

      snprintf(key, sizeof(key), "wrap_mode%u", i);
      config_set_string(conf, key, wrap_mode_to_str(pass->wrap));

      if (pass->frame_count_mod)
      {
         snprintf(key, sizeof(key), "frame_count_mod%u", i);
         config_set_int(conf, key, pass->frame_count_mod);
      }

      snprintf(key, sizeof(key), "mipmap_input%u", i);
      config_set_bool(conf, key, pass->mipmap);

      snprintf(key, sizeof(key), "alias%u", i);
      config_set_string(conf, key, pass->alias);

      shader_write_fbo(conf, &pass->fbo, i);
   }

   if (shader->num_parameters)
   {
      char parameters[4096] = {0};

      strlcpy(parameters, shader->parameters[0].id, sizeof(parameters));

      for (i = 1; i < shader->num_parameters; i++)
      {
         /* O(n^2), but number of parameters is very limited. */
         strlcat(parameters, ";", sizeof(parameters));
         strlcat(parameters, shader->parameters[i].id, sizeof(parameters));
      }

      config_set_string(conf, "parameters", parameters);
      
      for (i = 0; i < shader->num_parameters; i++)
         config_set_float(conf, shader->parameters[i].id,
               shader->parameters[i].current);
   }

   if (shader->luts)
   {
      char textures[4096] = {0};

      strlcpy(textures, shader->lut[0].id, sizeof(textures));
      for (i = 1; i < shader->luts; i++)
      {
         /* O(n^2), but number of textures is very limited. */
         strlcat(textures, ";", sizeof(textures));
         strlcat(textures, shader->lut[i].id, sizeof(textures));
      }

      config_set_string(conf, "textures", textures);

      for (i = 0; i < shader->luts; i++)
      {
         char key[64] = {0};

         config_set_string(conf, shader->lut[i].id, shader->lut[i].path);

         if (shader->lut[i].filter != RARCH_FILTER_UNSPEC)
         {
            snprintf(key, sizeof(key), "%s_linear", shader->lut[i].id);
            config_set_bool(conf, key, 
                  shader->lut[i].filter == RARCH_FILTER_LINEAR);
         }

         snprintf(key, sizeof(key), "%s_wrap_mode", shader->lut[i].id);
         config_set_string(conf, key, wrap_mode_to_str(shader->lut[i].wrap));

         snprintf(key, sizeof(key), "%s_mipmap", shader->lut[i].id);
         config_set_bool(conf, key, shader->lut[i].mipmap);
      }
   }

   if (*shader->script_path)
      config_set_string(conf, "import_script", shader->script_path);
   if (*shader->script_class)
      config_set_string(conf, "import_script_class", shader->script_class);

   if (shader->variables)
   {
      char variables[4096] = {0};

      strlcpy(variables, shader->variable[0].id, sizeof(variables));

      for (i = 1; i < shader->variables; i++)
      {
         strlcat(variables, ";", sizeof(variables));
         strlcat(variables, shader->variable[i].id, sizeof(variables));
      }

      config_set_string(conf, "imports", variables);

      for (i = 0; i < shader->variables; i++)
         shader_write_variable(conf, &shader->variable[i]);
   }
}
void rarch_config_save(const char * conf_name)
{
   if(!path_file_exists(conf_name))
      rarch_config_create_default(conf_name);
   else
   {
      config_file_t * conf = config_file_new(conf_name);

      if(conf == NULL)
         conf = config_file_new(NULL);

      // g_settings
      config_set_string(conf, "libretro_path", g_settings.libretro);
#ifdef HAVE_XML
      config_set_string(conf, "cheat_database_path", g_settings.cheat_database);
#endif
      config_set_bool(conf, "rewind_enable", g_settings.rewind_enable);
      config_set_string(conf, "video_cg_shader", g_settings.video.cg_shader_path);
      config_set_float(conf, "video_aspect_ratio", g_settings.video.aspect_ratio);
#ifdef HAVE_FBO
      config_set_float(conf, "video_fbo_scale_x", g_settings.video.fbo_scale_x);
      config_set_float(conf, "video_fbo_scale_y", g_settings.video.fbo_scale_y);
      config_set_string(conf, "video_second_pass_shader", g_settings.video.second_pass_shader);
      config_set_bool(conf, "video_render_to_texture", g_settings.video.render_to_texture);
      config_set_bool(conf, "video_second_pass_smooth", g_settings.video.second_pass_smooth);
#endif
      config_set_bool(conf, "video_smooth", g_settings.video.smooth);
      config_set_bool(conf, "video_vsync", g_settings.video.vsync);
      config_set_string(conf, "audio_device", g_settings.audio.device);

      for (unsigned i = 0; i < 7; i++)
      {
         char cfg[64];
	 snprintf(cfg, sizeof(cfg), "input_dpad_emulation_p%u", i + 1);
	 config_set_int(conf, cfg, g_settings.input.dpad_emulation[i]);
      }

#ifdef RARCH_CONSOLE
      config_set_bool(conf, "fbo_enabled", g_console.fbo_enabled);
#ifdef __CELLOS_LV2__
      config_set_bool(conf, "custom_bgm_enable", g_console.custom_bgm_enable);
#endif
      config_set_bool(conf, "overscan_enable", g_console.overscan_enable);
      config_set_bool(conf, "screenshots_enable", g_console.screenshots_enable);
#ifdef _XBOX
      config_set_bool(conf, "gamma_correction_enable", g_console.gamma_correction_enable);
      config_set_int(conf, "color_format", g_console.color_format);
#endif
      config_set_bool(conf, "throttle_enable", g_console.throttle_enable);
      config_set_bool(conf, "triple_buffering_enable", g_console.triple_buffering_enable);
      config_set_bool(conf, "info_msg_enable", g_console.info_msg_enable);
      config_set_int(conf, "sound_mode", g_console.sound_mode);
      config_set_int(conf, "aspect_ratio_index", g_console.aspect_ratio_index);
      config_set_int(conf, "current_resolution_id", g_console.current_resolution_id);
      config_set_int(conf, "custom_viewport_width", g_console.viewports.custom_vp.width);
      config_set_int(conf, "custom_viewport_height", g_console.viewports.custom_vp.height);
      config_set_int(conf, "custom_viewport_x", g_console.viewports.custom_vp.x);
      config_set_int(conf, "custom_viewport_y", g_console.viewports.custom_vp.y);
      config_set_int(conf, "screen_orientation", g_console.screen_orientation);
      config_set_string(conf, "default_rom_startup_dir", g_console.default_rom_startup_dir);
      config_set_float(conf, "menu_font_size", g_console.menu_font_size);
      config_set_float(conf, "overscan_amount", g_console.overscan_amount);
#endif

      // g_extern
      config_set_int(conf, "state_slot", g_extern.state_slot);
      config_set_int(conf, "audio_mute", g_extern.audio_data.mute);

      if (!config_file_write(conf, conf_name))
         RARCH_ERR("Failed to write config file to \"%s\". Check permissions.\n", conf_name);

      free(conf);
   }
}
Beispiel #7
0
/**
 * Parse command line options
 * @param argc Number of arguments
 * @param argv Argument values
 */
static void parse_options(int argc, char **argv)
{
    int ch;
    
    /* reset getopt */
    optind = 0;
    
    while ((ch = getopt_long(argc, argv, OPTSTRING, longopts, NULL)) != -1) {
        switch (ch) {
        case 'n': 
            save = FALSE;
            break;
        case 'r':
            reset = TRUE;
            break;
        case 'v':
        case 'm':
            /* Empty. See load_config() */
            break;
        case 'o':
            output_file = optarg;
            break;
        case 'V':
            malheur_version(stdout);
            exit(EXIT_SUCCESS);
            break;
        case 'h':
        case '?':
            print_usage();
            exit(EXIT_SUCCESS);
            break;

        /* long options */
        case 1001:
            config_set_string(&cfg, "input.format", optarg);    
            break;
        case 1002:
            config_set_int(&cfg, "input.mist_level", atoi(optarg));    
            break;
        case 1003:
            config_set_int(&cfg, "input.mist_rlen", atoi(optarg));    
            break;
        case 1004:
            config_set_int(&cfg, "input.mist_tlen", atoi(optarg));    
            break;
        case 1005:
            config_set_string(&cfg, "features.ngram_delim", optarg);    
            break;
        case 1006:
            config_set_int(&cfg, "features.ngram_len", atoi(optarg));    
            break;
        case 1007:
            config_set_string(&cfg, "features.vect_embed", optarg);    
            break;
        case 1008:
            config_set_int(&cfg, "features.lookup_table", atoi(optarg));    
            break;
        case 1009:
            config_set_float(&cfg, "prototypes.max_dist", atof(optarg));    
            break;
        case 1010:
            config_set_int(&cfg, "prototypes.max_num", atoi(optarg));    
            break;
        case 1011:
            config_set_float(&cfg, "classify.max_dist", atof(optarg));    
            break;
        case 1012:
            config_set_string(&cfg, "cluster.link_mode", optarg);    
            break;
        case 1013:
            config_set_float(&cfg, "cluster.min_dist", atof(optarg));    
            break;
        case 1014:
            config_set_int(&cfg, "cluster.reject_num", atoi(optarg));    
            break;
        case 1015:
            config_set_int(&cfg, "cluster.shared_ngrams", atoi(optarg));    
            break;
        }
    }

    /* Check configuration */
    config_check(&cfg);

    argc -= optind;
    argv += optind;

    if (argc < 1)
        fatal("the <action> argument is required");

    /* Argument: action */
    if (!strcasecmp(argv[0], "prototype")) {
        action = PROTOTYPE;
    } else if (!strcasecmp(argv[0], "distance")) {
        action = DISTANCE;
    } else if (!strcasecmp(argv[0], "cluster")) {
        action = CLUSTER;
    } else if (!strcasecmp(argv[0], "classify")) {
        action = CLASSIFY;
    } else if (!strcasecmp(argv[0], "increment")) {
        action = INCREMENT;
    } else if (!strcasecmp(argv[0], "protodist")) {
        action = PROTODIST;
    } else if (!strcasecmp(argv[0], "info")) {
        action = INFO;
    } else {
        fatal("Unknown analysis action '%s'", argv[0]);
    }
    
    if (argc < 2 && action != PROTODIST && action != INFO) 
        fatal("the <dataset> argument is required");

    /* Assign input files */
    input_files = argv + 1;
    input_len = argc - 1;
}
void rarch_config_save(const char * conf_name)
{
      config_file_t * conf = config_file_new(conf_name);

      if(!conf)
      {
         RARCH_ERR("Failed to write config file to \"%s\". Check permissions.\n", conf_name);
         return;
      }

      // g_settings
      config_set_string(conf, "libretro_path", g_settings.libretro);
#ifdef HAVE_XML
      config_set_string(conf, "cheat_database_path", g_settings.cheat_database);
#endif
      config_set_bool(conf, "rewind_enable", g_settings.rewind_enable);
      config_set_string(conf, "video_cg_shader", g_settings.video.cg_shader_path);
      config_set_float(conf, "video_aspect_ratio", g_settings.video.aspect_ratio);
#ifdef HAVE_FBO
      config_set_float(conf, "video_fbo_scale_x", g_settings.video.fbo.scale_x);
      config_set_float(conf, "video_fbo_scale_y", g_settings.video.fbo.scale_y);
      config_set_string(conf, "video_second_pass_shader", g_settings.video.second_pass_shader);
      config_set_bool(conf, "video_render_to_texture", g_settings.video.render_to_texture);
      config_set_bool(conf, "video_second_pass_smooth", g_settings.video.second_pass_smooth);
      config_set_bool(conf, "fbo_enabled", g_settings.video.fbo.enable);
#endif
      config_set_bool(conf, "video_smooth", g_settings.video.smooth);
      config_set_bool(conf, "video_vsync", g_settings.video.vsync);
      config_set_int(conf, "aspect_ratio_index", g_settings.video.aspect_ratio_idx);
      config_set_int(conf, "color_format", g_settings.video.color_format);
      config_set_string(conf, "audio_device", g_settings.audio.device);
      config_set_bool(conf, "audio_rate_control", g_settings.audio.rate_control);
      config_set_float(conf, "audio_rate_control_delta", g_settings.audio.rate_control_delta);

      for (unsigned i = 0; i < 7; i++)
      {
         char cfg[64];
         snprintf(cfg, sizeof(cfg), "input_dpad_emulation_p%u", i + 1);
         config_set_int(conf, cfg, g_settings.input.dpad_emulation[i]);
         snprintf(cfg, sizeof(cfg), "input_device_p%u", i + 1);
         config_set_int(conf, cfg, g_settings.input.device[i]);
      }

      config_set_bool(conf, "overscan_enable", g_extern.console.screen.state.overscan.enable);
      config_set_bool(conf, "screenshots_enable", g_extern.console.screen.state.screenshots.enable);
      config_set_bool(conf, "gamma_correction", g_extern.console.screen.gamma_correction);
#ifdef _XBOX1
      config_set_int(conf, "flicker_filter", g_extern.console.screen.state.flicker_filter.value);
      config_set_int(conf, "sound_volume_level", g_extern.console.sound.volume_level);
#endif
      config_set_bool(conf, "throttle_enable", g_extern.console.screen.state.throttle.enable);
      config_set_bool(conf, "triple_buffering_enable", g_extern.console.screen.state.triple_buffering.enable);
      config_set_bool(conf, "info_msg_enable", g_extern.console.rmenu.state.msg_info.enable);
      config_set_int(conf, "current_resolution_id", g_extern.console.screen.resolutions.current.id);
      config_set_int(conf, "custom_viewport_width", g_extern.console.screen.viewports.custom_vp.width);
      config_set_int(conf, "custom_viewport_height", g_extern.console.screen.viewports.custom_vp.height);
      config_set_int(conf, "custom_viewport_x", g_extern.console.screen.viewports.custom_vp.x);
      config_set_int(conf, "custom_viewport_y", g_extern.console.screen.viewports.custom_vp.y);
      config_set_string(conf, "default_rom_startup_dir", g_extern.console.main_wrap.paths.default_rom_startup_dir);
      config_set_float(conf, "menu_font_size", g_extern.console.rmenu.font_size);
      config_set_float(conf, "overscan_amount", g_extern.console.screen.overscan_amount);
#ifdef HAVE_ZLIB
      config_set_int(conf, "zip_extract_mode", g_extern.file_state.zip_extract_mode);
#endif

      // g_extern
      config_set_int(conf, "sound_mode", g_extern.console.sound.mode);
      config_set_int(conf, "state_slot", g_extern.state_slot);
      config_set_int(conf, "audio_mute", g_extern.audio_data.mute);
      config_set_bool(conf, "soft_display_filter_enable", g_extern.console.screen.state.soft_filter.enable);
      config_set_int(conf, "screen_orientation", g_extern.console.screen.orientation);
      config_set_bool(conf, "custom_bgm_enable", g_extern.console.sound.custom_bgm.enable);

      if (!config_file_write(conf, conf_name))
         RARCH_ERR("Failed to write config file to \"%s\". Check permissions.\n", conf_name);

      free(conf);
}
/**
 * video_shader_write_conf_cgp:
 * @conf              : Preset file to read from.
 * @shader            : Shader passes handle.
 *
 * Saves preset and all associated state (passes,
 * textures, imports, etc) to disk.
 **/
void video_shader_write_conf_cgp(config_file_t *conf,
      struct video_shader *shader)
{
   unsigned i;

   config_set_int(conf, "shaders", shader->passes);
   if (shader->feedback_pass >= 0)
      config_set_int(conf, "feedback_pass", shader->feedback_pass);

   for (i = 0; i < shader->passes; i++)
   {
      char key[64];
      size_t tmp_size = PATH_MAX_LENGTH * sizeof(char);
      char *tmp       = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
      const struct video_shader_pass *pass = &shader->pass[i];

      key[0] = '\0';

      snprintf(key, sizeof(key), "shader%u", i);
      strlcpy(tmp, pass->source.path, tmp_size);

      if (!path_is_absolute(tmp))
         path_resolve_realpath(tmp, tmp_size);
      config_set_string(conf, key, tmp);

      free(tmp);

      if (pass->filter != RARCH_FILTER_UNSPEC)
      {
         snprintf(key, sizeof(key), "filter_linear%u", i);
         config_set_bool(conf, key, pass->filter == RARCH_FILTER_LINEAR);
      }

      snprintf(key, sizeof(key), "wrap_mode%u", i);
      config_set_string(conf, key, wrap_mode_to_str(pass->wrap));

      if (pass->frame_count_mod)
      {
         snprintf(key, sizeof(key), "frame_count_mod%u", i);
         config_set_int(conf, key, pass->frame_count_mod);
      }

      snprintf(key, sizeof(key), "mipmap_input%u", i);
      config_set_bool(conf, key, pass->mipmap);

      snprintf(key, sizeof(key), "alias%u", i);
      config_set_string(conf, key, pass->alias);

      shader_write_fbo(conf, &pass->fbo, i);
   }

   if (shader->num_parameters)
   {
      size_t param_size = 4096 * sizeof(char);
      char *parameters  = (char*)malloc(4096 * sizeof(char));

      parameters[0] = '\0';

      strlcpy(parameters, shader->parameters[0].id, param_size);

      for (i = 1; i < shader->num_parameters; i++)
      {
         /* O(n^2), but number of parameters is very limited. */
         strlcat(parameters, ";", param_size);
         strlcat(parameters, shader->parameters[i].id, param_size);
      }

      config_set_string(conf, "parameters", parameters);

      for (i = 0; i < shader->num_parameters; i++)
         config_set_float(conf, shader->parameters[i].id,
               shader->parameters[i].current);
      free(parameters);
   }

   if (shader->luts)
   {
      size_t tex_size = 4096 * sizeof(char);
      char *textures  = (char*)malloc(4096 * sizeof(char));

      textures[0] = '\0';

      strlcpy(textures, shader->lut[0].id, tex_size);
      for (i = 1; i < shader->luts; i++)
      {
         /* O(n^2), but number of textures is very limited. */
         strlcat(textures, ";", tex_size);
         strlcat(textures, shader->lut[i].id, tex_size);
      }

      config_set_string(conf, "textures", textures);

      free(textures);

      for (i = 0; i < shader->luts; i++)
      {
         char key[64];

         key[0] = '\0';

         config_set_string(conf, shader->lut[i].id, shader->lut[i].path);

         if (shader->lut[i].filter != RARCH_FILTER_UNSPEC)
         {
            snprintf(key, sizeof(key), "%s_linear", shader->lut[i].id);
            config_set_bool(conf, key,
                  shader->lut[i].filter == RARCH_FILTER_LINEAR);
         }

         snprintf(key, sizeof(key),
               "%s_wrap_mode", shader->lut[i].id);
         config_set_string(conf, key,
               wrap_mode_to_str(shader->lut[i].wrap));

         snprintf(key, sizeof(key),
               "%s_mipmap", shader->lut[i].id);
         config_set_bool(conf, key,
               shader->lut[i].mipmap);
      }
   }

   if (*shader->script_path)
      config_set_string(conf, "import_script", shader->script_path);
   if (*shader->script_class)
      config_set_string(conf, "import_script_class", shader->script_class);

   if (shader->variables)
   {
      size_t var_tmp  = 4096 * sizeof(char);
      char *variables = (char*)malloc(4096 * sizeof(char));

      variables[0] = '\0';

      strlcpy(variables, shader->variable[0].id, var_tmp);

      for (i = 1; i < shader->variables; i++)
      {
         strlcat(variables, ";", var_tmp);
         strlcat(variables, shader->variable[i].id, var_tmp);
      }

      config_set_string(conf, "imports", variables);

      for (i = 0; i < shader->variables; i++)
         shader_write_variable(conf, &shader->variable[i]);
      free(variables);
   }
}