presets en yaml
This commit is contained in:
@@ -22,6 +22,14 @@ namespace Options {
|
||||
Settings settings;
|
||||
std::vector<input_t> inputs;
|
||||
|
||||
std::vector<PostFXPreset> postfx_presets;
|
||||
std::string postfx_file_path;
|
||||
int current_postfx_preset = 0;
|
||||
|
||||
std::vector<CrtPiPreset> crtpi_presets;
|
||||
std::string crtpi_file_path;
|
||||
int current_crtpi_preset = 0;
|
||||
|
||||
// --- Helpers locals ---
|
||||
namespace {
|
||||
void parseBoolField(const fkyaml::node &node, const std::string &key, bool &target) {
|
||||
@@ -339,4 +347,212 @@ namespace Options {
|
||||
return true;
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// Presets de shaders (postfx.yaml / crtpi.yaml)
|
||||
//
|
||||
// Els defaults viuen en una única font (defaultPostFXPresets / defaultCrtPiPresets).
|
||||
// Generem el YAML a partir d'ells el primer cop i els usem també com a
|
||||
// fallback si el YAML és absent o corrupte. Si algú toca els valors, ho fa
|
||||
// en un sol lloc.
|
||||
// ========================================================================
|
||||
|
||||
namespace {
|
||||
void parseFloatField(const fkyaml::node &node, const std::string &key, float &target) {
|
||||
if (node.contains(key)) {
|
||||
try {
|
||||
target = node[key].get_value<float>();
|
||||
} catch (...) {}
|
||||
}
|
||||
}
|
||||
|
||||
auto defaultPostFXPresets() -> const std::vector<PostFXPreset> & {
|
||||
static const std::vector<PostFXPreset> DEFAULTS = {
|
||||
{"CRT", 0.6F, 0.7F, 0.15F, 0.6F, 0.8F},
|
||||
{"NTSC", 0.4F, 0.5F, 0.2F, 0.4F, 0.5F, 0.0F, 0.6F},
|
||||
{"CURVED", 0.5F, 0.6F, 0.1F, 0.5F, 0.7F, 0.8F},
|
||||
{"SCANLINES", 0.0F, 0.8F},
|
||||
{"SUBTLE", 0.3F, 0.4F, 0.05F, 0.0F, 0.3F},
|
||||
{"CRT LIVE", 0.5F, 0.6F, 0.3F, 0.3F, 0.4F, 0.3F, 0.4F, 0.8F},
|
||||
};
|
||||
return DEFAULTS;
|
||||
}
|
||||
|
||||
auto defaultCrtPiPresets() -> const std::vector<CrtPiPreset> & {
|
||||
static const std::vector<CrtPiPreset> DEFAULTS = {
|
||||
{"Default", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, true, true, false, false},
|
||||
{"Curved", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, true, true, true, false},
|
||||
{"Sharp", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, false, true, false, true},
|
||||
{"Minimal", 8.0F, 0.05F, 2.0F, 2.4F, 2.2F, 1.00F, 0.0F, 0.0F, 0, true, false, false, false, false},
|
||||
};
|
||||
return DEFAULTS;
|
||||
}
|
||||
|
||||
void writePostFXDefaults(std::ostream &out) {
|
||||
out << "# Coffee Crisis - PostFX Shader Presets\n\n";
|
||||
out << "presets:\n";
|
||||
for (const auto &p : defaultPostFXPresets()) {
|
||||
out << " - name: \"" << p.name << "\"\n";
|
||||
out << " vignette: " << p.vignette << "\n";
|
||||
out << " scanlines: " << p.scanlines << "\n";
|
||||
out << " chroma: " << p.chroma << "\n";
|
||||
out << " mask: " << p.mask << "\n";
|
||||
out << " gamma: " << p.gamma << "\n";
|
||||
out << " curvature: " << p.curvature << "\n";
|
||||
out << " bleeding: " << p.bleeding << "\n";
|
||||
out << " flicker: " << p.flicker << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void writeCrtPiDefaults(std::ostream &out) {
|
||||
out << "# Coffee Crisis - CrtPi Shader Presets\n\n";
|
||||
out << "presets:\n";
|
||||
for (const auto &p : defaultCrtPiPresets()) {
|
||||
out << " - name: \"" << p.name << "\"\n";
|
||||
out << " scanline_weight: " << p.scanline_weight << "\n";
|
||||
out << " scanline_gap_brightness: " << p.scanline_gap_brightness << "\n";
|
||||
out << " bloom_factor: " << p.bloom_factor << "\n";
|
||||
out << " input_gamma: " << p.input_gamma << "\n";
|
||||
out << " output_gamma: " << p.output_gamma << "\n";
|
||||
out << " mask_brightness: " << p.mask_brightness << "\n";
|
||||
out << " curvature_x: " << p.curvature_x << "\n";
|
||||
out << " curvature_y: " << p.curvature_y << "\n";
|
||||
out << " mask_type: " << p.mask_type << "\n";
|
||||
out << " enable_scanlines: " << boolToString(p.enable_scanlines) << "\n";
|
||||
out << " enable_multisample: " << boolToString(p.enable_multisample) << "\n";
|
||||
out << " enable_gamma: " << boolToString(p.enable_gamma) << "\n";
|
||||
out << " enable_curvature: " << boolToString(p.enable_curvature) << "\n";
|
||||
out << " enable_sharper: " << boolToString(p.enable_sharper) << "\n";
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void setPostFXFile(const std::string &path) {
|
||||
postfx_file_path = path;
|
||||
}
|
||||
|
||||
auto loadPostFXFromFile() -> bool {
|
||||
postfx_presets.clear();
|
||||
current_postfx_preset = 0;
|
||||
|
||||
std::ifstream file(postfx_file_path);
|
||||
if (!file.is_open()) {
|
||||
// No existeix: escriu el YAML a partir dels defaults i copia'ls a memòria.
|
||||
std::ofstream out(postfx_file_path);
|
||||
if (out.is_open()) {
|
||||
writePostFXDefaults(out);
|
||||
out.close();
|
||||
}
|
||||
postfx_presets = defaultPostFXPresets();
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string CONTENT((std::istreambuf_iterator<char>(file)),
|
||||
std::istreambuf_iterator<char>());
|
||||
file.close();
|
||||
|
||||
try {
|
||||
auto yaml = fkyaml::node::deserialize(CONTENT);
|
||||
if (yaml.contains("presets")) {
|
||||
for (const auto &p : yaml["presets"]) {
|
||||
PostFXPreset preset;
|
||||
if (p.contains("name")) {
|
||||
try { preset.name = p["name"].get_value<std::string>(); } catch (...) {}
|
||||
}
|
||||
parseFloatField(p, "vignette", preset.vignette);
|
||||
parseFloatField(p, "scanlines", preset.scanlines);
|
||||
parseFloatField(p, "chroma", preset.chroma);
|
||||
parseFloatField(p, "mask", preset.mask);
|
||||
parseFloatField(p, "gamma", preset.gamma);
|
||||
parseFloatField(p, "curvature", preset.curvature);
|
||||
parseFloatField(p, "bleeding", preset.bleeding);
|
||||
parseFloatField(p, "flicker", preset.flicker);
|
||||
postfx_presets.push_back(preset);
|
||||
}
|
||||
}
|
||||
std::cout << "PostFX loaded: " << postfx_presets.size() << " preset(s)\n";
|
||||
} catch (const fkyaml::exception &e) {
|
||||
std::cout << "Error parsing PostFX YAML: " << e.what() << ". Using defaults.\n";
|
||||
postfx_presets = defaultPostFXPresets();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (postfx_presets.empty()) {
|
||||
postfx_presets = defaultPostFXPresets();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void setCrtPiFile(const std::string &path) {
|
||||
crtpi_file_path = path;
|
||||
}
|
||||
|
||||
auto loadCrtPiFromFile() -> bool {
|
||||
crtpi_presets.clear();
|
||||
current_crtpi_preset = 0;
|
||||
|
||||
std::ifstream file(crtpi_file_path);
|
||||
if (!file.is_open()) {
|
||||
std::ofstream out(crtpi_file_path);
|
||||
if (out.is_open()) {
|
||||
writeCrtPiDefaults(out);
|
||||
out.close();
|
||||
}
|
||||
crtpi_presets = defaultCrtPiPresets();
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string CONTENT((std::istreambuf_iterator<char>(file)),
|
||||
std::istreambuf_iterator<char>());
|
||||
file.close();
|
||||
|
||||
try {
|
||||
auto yaml = fkyaml::node::deserialize(CONTENT);
|
||||
if (yaml.contains("presets")) {
|
||||
for (const auto &p : yaml["presets"]) {
|
||||
CrtPiPreset preset;
|
||||
if (p.contains("name")) {
|
||||
try { preset.name = p["name"].get_value<std::string>(); } catch (...) {}
|
||||
}
|
||||
parseFloatField(p, "scanline_weight", preset.scanline_weight);
|
||||
parseFloatField(p, "scanline_gap_brightness", preset.scanline_gap_brightness);
|
||||
parseFloatField(p, "bloom_factor", preset.bloom_factor);
|
||||
parseFloatField(p, "input_gamma", preset.input_gamma);
|
||||
parseFloatField(p, "output_gamma", preset.output_gamma);
|
||||
parseFloatField(p, "mask_brightness", preset.mask_brightness);
|
||||
parseFloatField(p, "curvature_x", preset.curvature_x);
|
||||
parseFloatField(p, "curvature_y", preset.curvature_y);
|
||||
if (p.contains("mask_type")) {
|
||||
try { preset.mask_type = p["mask_type"].get_value<int>(); } catch (...) {}
|
||||
}
|
||||
if (p.contains("enable_scanlines")) {
|
||||
try { preset.enable_scanlines = p["enable_scanlines"].get_value<bool>(); } catch (...) {}
|
||||
}
|
||||
if (p.contains("enable_multisample")) {
|
||||
try { preset.enable_multisample = p["enable_multisample"].get_value<bool>(); } catch (...) {}
|
||||
}
|
||||
if (p.contains("enable_gamma")) {
|
||||
try { preset.enable_gamma = p["enable_gamma"].get_value<bool>(); } catch (...) {}
|
||||
}
|
||||
if (p.contains("enable_curvature")) {
|
||||
try { preset.enable_curvature = p["enable_curvature"].get_value<bool>(); } catch (...) {}
|
||||
}
|
||||
if (p.contains("enable_sharper")) {
|
||||
try { preset.enable_sharper = p["enable_sharper"].get_value<bool>(); } catch (...) {}
|
||||
}
|
||||
crtpi_presets.push_back(preset);
|
||||
}
|
||||
}
|
||||
std::cout << "CrtPi loaded: " << crtpi_presets.size() << " preset(s)\n";
|
||||
} catch (const fkyaml::exception &e) {
|
||||
std::cout << "Error parsing CrtPi YAML: " << e.what() << ". Using defaults.\n";
|
||||
crtpi_presets = defaultCrtPiPresets();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (crtpi_presets.empty()) {
|
||||
crtpi_presets = defaultCrtPiPresets();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Options
|
||||
|
||||
Reference in New Issue
Block a user