Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/include/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -1379,6 +1379,14 @@ struct amiberry_gui_theme
amiberry_gui_color foreground_color;
};

struct amiberry_shader_parameter
{
bool rtg = false;
std::string shader;
std::string name;
float value = 0.0f;
};

struct amiberry_options
{
bool quickstart_start = true;
Expand Down Expand Up @@ -1444,6 +1452,7 @@ struct amiberry_options
char gui_theme[128] = "Default.theme";
char shader[128] = "none";
char shader_rtg[128] = "none";
std::vector<amiberry_shader_parameter> shader_parameters;
bool use_bezel = false;
bool use_custom_bezel = false;
char custom_bezel[256] = "none";
Expand Down
60 changes: 60 additions & 0 deletions src/osdep/amiberry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <cstdint>
#endif
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cctype>
Expand Down Expand Up @@ -6413,6 +6414,13 @@ bool save_amiberry_settings_with_result()

// Shader to use for RTG modes (if any)
write_string_option("shader_rtg", amiberry_options.shader_rtg);
for (const auto& parameter : amiberry_options.shader_parameters)
{
_sntprintf(buffer, MAX_DPATH, "shader_parameter=%s|%s|%s|%.9g\n",
parameter.rtg ? "rtg" : "native", parameter.shader.c_str(),
parameter.name.c_str(), parameter.value);
fputs(buffer, f);
}

// Show CRT bezel frame overlay
write_bool_option("use_bezel", amiberry_options.use_bezel);
Expand Down Expand Up @@ -6513,6 +6521,56 @@ static void trim_wsa(char* s)
s[--len] = '\0';
}

static bool parse_shader_parameter_setting(const char* value)
{
const std::string serialized(value);
const auto target_end = serialized.find('|');
const auto shader_end = target_end == std::string::npos
? std::string::npos
: serialized.find('|', target_end + 1);
const auto name_end = shader_end == std::string::npos
? std::string::npos
: serialized.find('|', shader_end + 1);
if (target_end == std::string::npos || target_end == 0
|| shader_end == std::string::npos || shader_end == target_end + 1
|| name_end == std::string::npos || name_end == shader_end + 1
|| name_end + 1 >= serialized.size())
{
return false;
}

const auto target = serialized.substr(0, target_end);
if (target != "native" && target != "rtg")
return false;

const bool rtg = target == "rtg";
const auto shader = serialized.substr(target_end + 1, shader_end - target_end - 1);
const auto name = serialized.substr(shader_end + 1, name_end - shader_end - 1);
const auto value_string = serialized.substr(name_end + 1);
try
{
size_t consumed = 0;
const float parameter_value = std::stof(value_string, &consumed);
if (consumed != value_string.size() || !std::isfinite(parameter_value))
return false;

auto& parameters = amiberry_options.shader_parameters;
const auto existing = std::find_if(parameters.begin(), parameters.end(),
[&](const amiberry_shader_parameter& parameter) {
return parameter.rtg == rtg && parameter.shader == shader && parameter.name == name;
});
if (existing != parameters.end())
existing->value = parameter_value;
else
parameters.push_back({rtg, shader, name, parameter_value});
return true;
}
catch (const std::exception&)
{
return false;
}
}

static bool parse_base_content_path_line(const char* path, char* linea, std::string& value_out)
{
char line_copy[CONFIG_BLEN];
Expand Down Expand Up @@ -6743,6 +6801,8 @@ static int parse_amiberry_settings_line(const char *path, char *linea)
ret |= cfgfile_string(option, value, "gui_theme", amiberry_options.gui_theme, sizeof amiberry_options.gui_theme);
ret |= cfgfile_string(option, value, "shader", amiberry_options.shader, sizeof amiberry_options.shader);
ret |= cfgfile_string(option, value, "shader_rtg", amiberry_options.shader_rtg, sizeof amiberry_options.shader_rtg);
if (_tcscmp(option, _T("shader_parameter")) == 0)
ret |= parse_shader_parameter_setting(value) ? 1 : 0;
ret |= cfgfile_yesno(option, value, "use_bezel", &amiberry_options.use_bezel);
ret |= cfgfile_yesno(option, value, "use_custom_bezel", &amiberry_options.use_custom_bezel);
ret |= cfgfile_string(option, value, "custom_bezel", amiberry_options.custom_bezel, sizeof amiberry_options.custom_bezel);
Expand Down
89 changes: 66 additions & 23 deletions src/osdep/imgui/filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ static int find_shader_index(const char* shader_name)
}

static bool show_shader_params_popup = false;
#ifdef USE_OPENGL
static bool shader_params_popup_rtg = false;
static std::string shader_params_popup_name;
#endif

static void save_filter_defaults()
{
Expand All @@ -159,6 +163,15 @@ static void save_filter_defaults()
save_amiberry_settings();
}

#ifdef USE_OPENGL
static void open_shader_parameters_popup(const char* shader_name, const bool rtg)
{
shader_params_popup_name = shader_name ? shader_name : "none";
shader_params_popup_rtg = rtg;
show_shader_params_popup = true;
}
#endif

static void render_shader_parameters_popup()
{
if (!show_shader_params_popup) return;
Expand All @@ -167,13 +180,39 @@ static void render_shader_parameters_popup()
ImGui::SetNextWindowSize(ImVec2(BUTTON_WIDTH * 5, BUTTON_HEIGHT * 10), ImGuiCond_FirstUseEver);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 2.0f);
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.6f, 0.6f, 0.6f, 1.0f));
if (ImGui::Begin("Shader Parameters", &show_shader_params_popup)) {
const char* popup_title = shader_params_popup_rtg ? "RTG Shader Parameters" : "Native Shader Parameters";
if (ImGui::Begin(popup_title, &show_shader_params_popup)) {
auto* gl_renderer = get_opengl_renderer();
auto* params = gl_renderer ? gl_renderer->shader_parameters() : nullptr;
auto* params = gl_renderer
? gl_renderer->shader_parameters(shader_params_popup_name.c_str(), shader_params_popup_rtg)
: nullptr;

if (params && !params->empty()) {
ImGui::Text("Adjust shader parameters:");
ImGui::Text("Shader: %s", shader_params_popup_name.c_str());
ImGui::Spacing();

if (AmigaButton(ICON_FA_ARROW_ROTATE_LEFT " Reset to Shader Defaults",
ImVec2(BUTTON_WIDTH * 2.25f, BUTTON_HEIGHT))) {
for (auto& param : *params) {
param.current_value = param.default_value;
gl_renderer->set_shader_parameter(shader_params_popup_name.c_str(),
shader_params_popup_rtg, param.name, param.default_value);
}
}
ShowHelpMarker("Restore the values declared by this shader.");
ImGui::SameLine();
if (AmigaButton(ICON_FA_FLOPPY_DISK " Save Parameters",
ImVec2(BUTTON_WIDTH * 1.75f, BUTTON_HEIGHT))) {
gl_renderer->save_shader_parameters(shader_params_popup_name.c_str(), shader_params_popup_rtg);
save_amiberry_settings();
}
ShowHelpMarker(shader_params_popup_rtg
? "Save these values as the defaults for the RTG shader."
: "Save these values as the defaults for the native shader.");

ImGui::Spacing();
ImGui::Separator();
ImGui::Text("Adjust shader parameters:");
ImGui::Spacing();

for (auto& param : *params) {
Expand All @@ -185,22 +224,17 @@ static void render_shader_parameters_popup()
ImGui::SetNextItemWidth(-1);
if (ImGui::SliderFloat("##val", &param.current_value,
param.min_value, param.max_value, "%.3f")) {
gl_renderer->set_shader_parameter(param.name, param.current_value);
gl_renderer->set_shader_parameter(shader_params_popup_name.c_str(),
shader_params_popup_rtg, param.name, param.current_value);
}
AmigaBevel(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), false);
ImGui::PopID();
}

ImGui::Spacing();
ImGui::Separator();
if (AmigaButton(ICON_FA_ARROW_ROTATE_LEFT " Reset to Defaults")) {
for (auto& param : *params) {
param.current_value = param.default_value;
gl_renderer->set_shader_parameter(param.name, param.default_value);
}
}
} else {
ImGui::Text("No adjustable parameters for the current shader.");
ImGui::Text("Shader: %s", shader_params_popup_name.c_str());
ImGui::Spacing();
ImGui::TextWrapped("No adjustable parameters are currently available for this %s shader.",
shader_params_popup_rtg ? "RTG" : "native");
}
}
ImGui::End();
Expand Down Expand Up @@ -305,6 +339,14 @@ void render_panel_filter()
ShowHelpMarker("CRT shader applied to native Amiga chipset display modes.");
ImGui::SameLine();
ImGui::Text("Shader for native Amiga modes");
ImGui::Spacing();
#ifdef USE_OPENGL
if (AmigaButton(ICON_FA_SLIDERS " Shader Parameters...##NativeShaderParameters",
ImVec2(BUTTON_WIDTH * 1.75f, BUTTON_HEIGHT))) {
open_shader_parameters_popup(changed_prefs.shader, false);
}
ShowHelpMarker("Edit parameters for the native display shader.");
#endif
}
EndGroupBox("Native Display Shader");

Expand Down Expand Up @@ -332,6 +374,14 @@ void render_panel_filter()
ShowHelpMarker("CRT shader applied to RTG/Picasso96 graphics card display modes.");
ImGui::SameLine();
ImGui::Text("Shader for RTG/Picasso modes");
ImGui::Spacing();
#ifdef USE_OPENGL
if (AmigaButton(ICON_FA_SLIDERS " Shader Parameters...##RTGShaderParameters",
ImVec2(BUTTON_WIDTH * 1.75f, BUTTON_HEIGHT))) {
open_shader_parameters_popup(changed_prefs.shader_rtg, true);
}
ShowHelpMarker("Edit parameters for the RTG display shader.");
#endif
}
EndGroupBox("RTG Display Shader");

Expand Down Expand Up @@ -400,18 +450,11 @@ void render_panel_filter()
}
ImGui::SameLine();

// Shader Parameters button (only shown when active shader has parameters)
if (g_renderer && g_renderer->has_shader_parameters()) {
if (AmigaButton(ICON_FA_SLIDERS " Shader Parameters...", ImVec2(BUTTON_WIDTH * 1.5f, BUTTON_HEIGHT))) {
show_shader_params_popup = true;
}
ImGui::SameLine();
}

// Save button
if (AmigaButton(ICON_FA_FLOPPY_DISK " Save Defaults", ImVec2(BUTTON_WIDTH * 1.5f, BUTTON_HEIGHT))) {
if (AmigaButton(ICON_FA_FLOPPY_DISK " Save Defaults", ImVec2(BUTTON_WIDTH * 1.75f, BUTTON_HEIGHT))) {
save_filter_defaults();
}
ShowHelpMarker("Save the shader selections and bezel settings as application defaults.");

// Render the shader parameters popup if open
render_shader_parameters_popup();
Expand Down
Loading
Loading