summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2023-01-08 05:06:50 +1100
committer Vas Crabb <vas@vastheman.com>2023-01-08 05:06:50 +1100
commitc4f62ccb59574ed11024d10634c9e579374ba4d1 (patch)
treebeb97aec6000b60424ce9c03d5574066e45cc89f
parentbd87008722cc33b2adc83dc4611afc2e4eccb294 (diff)
bgfx: Save values of most sliders per-system.
-rw-r--r--src/emu/config.cpp7
-rw-r--r--src/osd/modules/render/bgfx/chain.h11
-rw-r--r--src/osd/modules/render/bgfx/chainmanager.cpp164
-rw-r--r--src/osd/modules/render/bgfx/chainmanager.h58
-rw-r--r--src/osd/modules/render/bgfx/inputpair.cpp25
-rw-r--r--src/osd/modules/render/bgfx/slider.h11
-rw-r--r--src/osd/modules/render/bgfx/sliderreader.cpp56
-rw-r--r--src/osd/modules/render/bgfx/statereader.cpp14
-rw-r--r--src/osd/modules/render/bgfx/statereader.h16
-rw-r--r--src/osd/modules/render/drawbgfx.cpp111
-rw-r--r--src/osd/modules/render/drawbgfx.h43
-rw-r--r--src/osd/windows/window.cpp3
12 files changed, 368 insertions, 151 deletions
diff --git a/src/emu/config.cpp b/src/emu/config.cpp
index a7d1218abe0..8e9423415ee 100644
--- a/src/emu/config.cpp
+++ b/src/emu/config.cpp
@@ -307,16 +307,21 @@ bool configuration_manager::save_xml(emu_file &file, config_type which_type)
systemnode->set_attribute("name", (which_type == config_type::DEFAULT) ? "default" : machine().system().name);
// loop over all registrants and call their save function
+ util::xml::data_node *curnode = nullptr;
for (auto const &type : m_typelist)
{
- util::xml::data_node *const curnode = systemnode->add_child(type.first.c_str(), nullptr);
+ if (!curnode || (type.first != curnode->get_name()))
+ curnode = systemnode->add_child(type.first.c_str(), nullptr);
if (!curnode)
return false;
type.second.save(which_type, curnode);
// if nothing was added, just nuke the node
if (!curnode->get_value() && !curnode->get_first_child() && !curnode->count_attributes())
+ {
curnode->delete_node();
+ curnode = nullptr;
+ }
}
// restore unhandled settings
diff --git a/src/osd/modules/render/bgfx/chain.h b/src/osd/modules/render/bgfx/chain.h
index 5080532210c..b8f5d2db21d 100644
--- a/src/osd/modules/render/bgfx/chain.h
+++ b/src/osd/modules/render/bgfx/chain.h
@@ -6,17 +6,17 @@
//
//============================================================
+#ifndef MAME_RENDER_BGFX_CHAIN_H
+#define MAME_RENDER_BGFX_CHAIN_H
+
#pragma once
-#ifndef __DRAWBGFX_CHAIN__
-#define __DRAWBGFX_CHAIN__
+#include "chainentry.h"
#include <string>
#include <vector>
#include <map>
-#include "chainentry.h"
-
class bgfx_slider;
class bgfx_parameter;
class texture_manager;
@@ -34,6 +34,7 @@ public:
void repopulate_targets();
// Getters
+ const std::string &name() const { return m_name; }
std::vector<bgfx_slider*>& sliders() { return m_sliders; }
std::vector<bgfx_chain_entry*>& entries() { return m_entries; }
uint32_t applicable_passes();
@@ -63,4 +64,4 @@ private:
bool m_has_adjuster;
};
-#endif // __DRAWBGFX_CHAIN__
+#endif // MAME_RENDER_BGFX_CHAIN_H
diff --git a/src/osd/modules/render/bgfx/chainmanager.cpp b/src/osd/modules/render/bgfx/chainmanager.cpp
index 3d5e3f6a482..891a12de62a 100644
--- a/src/osd/modules/render/bgfx/chainmanager.cpp
+++ b/src/osd/modules/render/bgfx/chainmanager.cpp
@@ -26,21 +26,24 @@
#include "bgfxutil.h"
-#include "chainreader.h"
#include "chain.h"
-
-#include "texture.h"
-#include "target.h"
+#include "chainreader.h"
#include "slider.h"
+#include "target.h"
+#include "texture.h"
#include "sliderdirtynotifier.h"
+#include "util/xmlfile.h"
+
#include "osdcore.h"
#include "osdfile.h"
+#include <algorithm>
+
+
using namespace rapidjson;
-const uint32_t chain_manager::CHAIN_NONE = 0;
chain_manager::screen_prim::screen_prim(render_primitive *prim)
{
@@ -420,20 +423,18 @@ int32_t chain_manager::slider_changed(int id, std::string *str, int32_t newval)
void chain_manager::create_selection_slider(uint32_t screen_index)
{
if (screen_index < m_selection_sliders.size())
- {
return;
- }
int32_t minval = 0;
int32_t defval = m_current_chain[screen_index];
int32_t maxval = m_available_chains.size() - 1;
int32_t incval = 1;
- std::string description = "Window " + std::to_string(m_window_index) + ", Screen " + std::to_string(screen_index) + " Effect:";
-
using namespace std::placeholders;
- auto state = std::make_unique<slider_state>(std::move(description), minval, defval, maxval, incval,
- std::bind(&chain_manager::slider_changed, this, screen_index, _1, _2));
+ auto state = std::make_unique<slider_state>(
+ util::string_format("Window %1$u, Screen %2$u Effect", m_window_index, screen_index),
+ minval, defval, maxval, incval,
+ std::bind(&chain_manager::slider_changed, this, screen_index, _1, _2));
ui::menu_item item(ui::menu_item_type::SLIDER, state.get());
item.set_text(state->description);
@@ -645,6 +646,141 @@ void chain_manager::restore_slider_settings(int32_t id, std::vector<std::vector<
}
}
+void chain_manager::load_config(util::xml::data_node const &windownode)
+{
+ bool const explicit_chains = OPTION_PRIORITY_NORMAL <= m_options.get_entry(OSDOPTION_BGFX_SCREEN_CHAINS)->priority();
+
+ // if chains weren't explicitly specified, restore the chains from the config file
+ if (!explicit_chains)
+ {
+ bool changed = false;
+ util::xml::data_node const *screennode = windownode.get_child("screen");
+ while (screennode)
+ {
+ auto const index = screennode->get_attribute_int("index", -1);
+ if ((0 <= index) && (m_screen_count > index))
+ {
+ char const *const chainname = screennode->get_attribute_string("chain", nullptr);
+ if (chainname)
+ {
+ auto const found = std::find_if(
+ m_available_chains.begin(),
+ m_available_chains.end(),
+ [&chainname] (auto const &avail) { return avail.m_name == chainname; });
+ if (m_available_chains.end() != found)
+ {
+ auto const chainnum = found - m_available_chains.begin();
+ if (chainnum != m_current_chain[index])
+ {
+ m_current_chain[index] = chainnum;
+ changed = true;
+ }
+ }
+ }
+ }
+
+ screennode = screennode->get_next_sibling("screen");
+ }
+
+ if (changed)
+ reload_chains();
+ }
+
+ // now apply slider settings for screens with chains matching config
+ util::xml::data_node const *screennode = windownode.get_child("screen");
+ while (screennode)
+ {
+ auto const index = screennode->get_attribute_int("index", -1);
+ if ((0 <= index) && (m_screen_count > index) && (m_screen_chains.size() > index))
+ {
+ bgfx_chain *const chain = m_screen_chains[index];
+ char const *const chainname = screennode->get_attribute_string("chain", nullptr);
+ if (chain && chainname && (m_available_chains[m_current_chain[index]].m_name == chainname))
+ {
+ auto const &sliders = chain->sliders();
+
+ util::xml::data_node const *slidernode = screennode->get_child("slider");
+ while (slidernode)
+ {
+ char const *const slidername = slidernode->get_attribute_string("name", nullptr);
+ if (slidername)
+ {
+ auto const found = std::find_if(
+ sliders.begin(),
+ sliders.end(),
+ [&slidername] (auto const &slider) { return slider->name() == slidername; });
+ if (sliders.end() != found)
+ {
+ bgfx_slider &slider = **found;
+ switch (slider.type())
+ {
+ case bgfx_slider::SLIDER_INT_ENUM:
+ case bgfx_slider::SLIDER_INT:
+ {
+ slider_state const &core = *slider.core_slider();
+ int32_t const val = slidernode->get_attribute_int("value", core.defval);
+ slider.update(nullptr, std::clamp(val, core.minval, core.maxval));
+ }
+ break;
+ default:
+ {
+ float const val = slidernode->get_attribute_float("value", slider.default_value());
+ slider.import(std::clamp(val, slider.min_value(), slider.max_value()));
+ }
+ }
+ }
+ }
+
+ slidernode = slidernode->get_next_sibling("slider");
+ }
+ }
+ }
+ screennode = screennode->get_next_sibling("screen");
+ }
+}
+
+void chain_manager::save_config(util::xml::data_node &parentnode)
+{
+ if (!needs_sliders())
+ return;
+
+ util::xml::data_node *const windownode = parentnode.add_child("window", nullptr);
+ windownode->set_attribute_int("index", m_window_index);
+
+ for (size_t index = 0; index < m_screen_chains.size() && index < m_screen_count; index++)
+ {
+ bgfx_chain *const chain = m_screen_chains[index];
+ if (!chain)
+ continue;
+
+ util::xml::data_node *const screennode = windownode->add_child("screen", nullptr);
+ screennode->set_attribute_int("index", index);
+ screennode->set_attribute("chain", m_available_chains[m_current_chain[index]].m_name.c_str());
+
+ for (bgfx_slider *slider : chain->sliders())
+ {
+ auto const val = slider->update(nullptr, SLIDER_NOCHANGE);
+ if (val == slider->core_slider()->defval)
+ continue;
+
+ util::xml::data_node *const slidernode = screennode->add_child("slider", nullptr);
+ slidernode->set_attribute("name", slider->name().c_str());
+ switch (slider->type())
+ {
+ case bgfx_slider::SLIDER_INT_ENUM:
+ case bgfx_slider::SLIDER_INT:
+ slidernode->set_attribute_int("value", val);
+ break;
+ default:
+ slidernode->set_attribute_float("value", slider->value());
+ }
+ }
+ }
+
+ if (!windownode->get_first_child())
+ windownode->delete_node();
+}
+
std::vector<std::vector<float>> chain_manager::slider_settings()
{
std::vector<std::vector<float>> curr;
@@ -679,13 +815,11 @@ std::vector<ui::menu_item> chain_manager::get_slider_list()
std::vector<ui::menu_item> sliders;
if (!needs_sliders())
- {
return sliders;
- }
for (size_t index = 0; index < m_screen_chains.size() && index < m_screen_count; index++)
{
- bgfx_chain* chain = m_screen_chains[index];
+ bgfx_chain *const chain = m_screen_chains[index];
sliders.push_back(m_selection_sliders[index]);
if (chain == nullptr)
@@ -693,7 +827,7 @@ std::vector<ui::menu_item> chain_manager::get_slider_list()
continue;
}
- std::vector<bgfx_chain_entry*> chain_entries = chain->entries();
+ std::vector<bgfx_chain_entry *> chain_entries = chain->entries();
for (bgfx_chain_entry* entry : chain_entries)
{
std::vector<bgfx_input_pair*> entry_inputs = entry->inputs();
diff --git a/src/osd/modules/render/bgfx/chainmanager.h b/src/osd/modules/render/bgfx/chainmanager.h
index 59a65dc59cf..01e567653b8 100644
--- a/src/osd/modules/render/bgfx/chainmanager.h
+++ b/src/osd/modules/render/bgfx/chainmanager.h
@@ -9,19 +9,22 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_CHAINMANAGER_H
+#define MAME_RENDER_BGFX_CHAINMANAGER_H
-#ifndef __DRAWBGFX_CHAIN_MANAGER__
-#define __DRAWBGFX_CHAIN_MANAGER__
+#pragma once
-#include "texturemanager.h"
-#include "targetmanager.h"
#include "effectmanager.h"
+#include "targetmanager.h"
+#include "texturemanager.h"
+
+#include "util/utilfwd.h"
#include <map>
#include <string>
#include <vector>
+
class running_machine;
class osd_window;
struct slider_state;
@@ -49,6 +52,24 @@ public:
class chain_manager
{
public:
+ class screen_prim
+ {
+ public:
+ screen_prim() = default;
+ screen_prim(render_primitive *prim);
+
+ render_primitive *m_prim = nullptr;
+ uint16_t m_screen_width = 0;
+ uint16_t m_screen_height = 0;
+ uint16_t m_quad_width = 0;
+ uint16_t m_quad_height = 0;
+ float m_tex_width = 0.0F;
+ float m_tex_height = 0.0F;
+ int m_rowpixels = 0;
+ uint32_t m_palette_length = 0;
+ uint32_t m_flags = 0;
+ };
+
chain_manager(running_machine& machine, osd_options& options, texture_manager& textures, target_manager& targets, effect_manager& effects, uint32_t window_index, slider_dirty_notifier& slider_notifier);
~chain_manager();
@@ -73,27 +94,8 @@ public:
// Setters
void restore_slider_settings(int32_t id, std::vector<std::vector<float>>& settings);
- class screen_prim
- {
- public:
- screen_prim() : m_prim(nullptr), m_screen_width(0), m_screen_height(0), m_quad_width(0), m_quad_height(0)
- , m_tex_width(0), m_tex_height(0), m_rowpixels(0), m_palette_length(0), m_flags(0)
- {
- }
-
- screen_prim(render_primitive *prim);
-
- render_primitive *m_prim;
- uint16_t m_screen_width;
- uint16_t m_screen_height;
- uint16_t m_quad_width;
- uint16_t m_quad_height;
- float m_tex_width;
- float m_tex_height;
- int m_rowpixels;
- uint32_t m_palette_length;
- uint32_t m_flags;
- };
+ void load_config(util::xml::data_node const &screennode);
+ void save_config(util::xml::data_node &parentnode);
private:
void load_chains();
@@ -138,7 +140,7 @@ private:
std::vector<screen_prim> m_screen_prims;
std::vector<uint8_t> m_palette_temp;
- static const uint32_t CHAIN_NONE;
+ static inline constexpr uint32_t CHAIN_NONE = 0;
};
-#endif // __DRAWBGFX_CHAIN_MANAGER__
+#endif // MAME_RENDER_BGFX_CHAINMANAGER_H
diff --git a/src/osd/modules/render/bgfx/inputpair.cpp b/src/osd/modules/render/bgfx/inputpair.cpp
index 5f1324c2581..db12144e952 100644
--- a/src/osd/modules/render/bgfx/inputpair.cpp
+++ b/src/osd/modules/render/bgfx/inputpair.cpp
@@ -11,15 +11,18 @@
#include "inputpair.h"
-#include "../frontend/mame/ui/slider.h"
-
-#include "texture.h"
-#include "target.h"
-#include "effect.h"
-#include "uniform.h"
#include "chainmanager.h"
+#include "effect.h"
#include "slider.h"
#include "sliderdirtynotifier.h"
+#include "target.h"
+#include "texture.h"
+#include "uniform.h"
+
+#include "../frontend/mame/ui/slider.h"
+
+#include "util/strformat.h"
+
bgfx_input_pair::bgfx_input_pair(int index, std::string sampler, std::string texture, std::vector<std::string> available_textures, std::string selection, chain_manager& chains, uint32_t screen_index)
: m_index(index)
@@ -109,11 +112,11 @@ void bgfx_input_pair::create_selection_slider(uint32_t screen_index)
int32_t maxval = m_available_textures.size() - 1;
int32_t incval = 1;
- std::string description = "Window " + std::to_string(chains().window_index()) + ", Screen " + std::to_string(screen_index) + " " + m_selection + ":";
-
using namespace std::placeholders;
- m_slider_state = std::make_unique<slider_state>(std::move(description), minval, defval, maxval, incval,
- std::bind(&bgfx_input_pair::texture_changed, this, screen_index, _1, _2));
+ m_slider_state = std::make_unique<slider_state>(
+ util::string_format("Window %1$u, Screen %1$u %3$s", chains().window_index(), screen_index, m_selection),
+ minval, defval, maxval, incval,
+ std::bind(&bgfx_input_pair::texture_changed, this, screen_index, _1, _2));
ui::menu_item item(ui::menu_item_type::SLIDER, m_slider_state.get());
item.set_text(m_slider_state->description);
@@ -130,9 +133,7 @@ std::vector<ui::menu_item> bgfx_input_pair::get_slider_list()
std::vector<ui::menu_item> sliders;
if (!needs_sliders())
- {
return sliders;
- }
sliders.push_back(m_selection_slider);
diff --git a/src/osd/modules/render/bgfx/slider.h b/src/osd/modules/render/bgfx/slider.h
index d7815765c34..26847d2d27e 100644
--- a/src/osd/modules/render/bgfx/slider.h
+++ b/src/osd/modules/render/bgfx/slider.h
@@ -6,10 +6,10 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_SLIDER_H
+#define MAME_RENDER_BGFX_SLIDER_H
-#ifndef __DRAWBGFX_SLIDER__
-#define __DRAWBGFX_SLIDER__
+#pragma once
#include <bgfx/bgfx.h>
@@ -56,6 +56,9 @@ public:
slider_type type() const { return m_type; }
float value() const { return m_value; }
float uniform_value() const { return float(m_value); }
+ float min_value() const { return m_min; }
+ float default_value() const { return m_default; }
+ float max_value() const { return m_max; }
slider_state *core_slider() const { return m_slider_state.get(); }
size_t size() const { return get_size_for_type(m_type); }
static size_t get_size_for_type(slider_type type);
@@ -82,4 +85,4 @@ protected:
running_machine&m_machine;
};
-#endif // __DRAWBGFX_SLIDER__
+#endif // MAME_RENDER_BGFX_SLIDER_H
diff --git a/src/osd/modules/render/bgfx/sliderreader.cpp b/src/osd/modules/render/bgfx/sliderreader.cpp
index 208bc241559..8d52069ad7a 100644
--- a/src/osd/modules/render/bgfx/sliderreader.cpp
+++ b/src/osd/modules/render/bgfx/sliderreader.cpp
@@ -82,18 +82,22 @@ std::vector<bgfx_slider*> slider_reader::read_from_value(const Value& value, std
break;
}
- std::string prefixed_desc = "Window " + std::to_string(chains.window_index()) + ", Screen " + std::to_string(screen_index) + ", " + description;
+ std::string prefixed_desc = util::string_format("Window %1$u, Screen %2$u, %3$s", chains.window_index(), screen_index, description);
if (slider_count > 1)
{
+ if (!READER_CHECK(value["min"].IsArray(), "%1$sSlider '%2$s': value 'min' must be an array", prefix, name))
+ return sliders;
+ if (!READER_CHECK(value["default"].IsArray(), "%1$sSlider '%2$s': value 'default' must be an array", prefix, name))
+ return sliders;
+ if (!READER_CHECK(value["max"].IsArray(), "%1$sSlider '%2$s': value 'max' must be an array", prefix, name))
+ return sliders;
+
float min[3];
float defaults[3];
float max[3];
- if (!READER_CHECK(value["min"].IsArray(), (prefix + "Slider '" + name + "': value 'min' must be an array\n").c_str())) return sliders;
- if (!READER_CHECK(value["default"].IsArray(), (prefix + "Slider '" + name + "': value 'default' must be an array\n").c_str())) return sliders;
- if (!READER_CHECK(value["max"].IsArray(), (prefix + "Slider '" + name + "': value 'max' must be an array\n").c_str())) return sliders;
- get_values(value, prefix + "Slider '" + name + "': 'min': ", "min", min, slider_count);
- get_values(value, prefix + "Slider '" + name + "': 'default': ", "default", defaults, slider_count);
- get_values(value, prefix + "Slider '" + name + "': 'max': ", "max", max, slider_count);
+ get_values(value, util::string_format("%1$sSlider '%2$s': 'min': ", prefix, name), "min", min, slider_count);
+ get_values(value, util::string_format("%1$sSlider '%2$s': 'default': ", prefix, name), "default", defaults, slider_count);
+ get_values(value, util::string_format("%1$sSlider '%2$s': 'max': ", prefix, name), "max", max, slider_count);
for (int index = 0; index < slider_count; index++)
{
std::string desc;
@@ -140,24 +144,24 @@ bool slider_reader::get_values(const Value& value, std::string prefix, std::stri
bool slider_reader::validate_parameters(const Value& value, std::string prefix)
{
- if (!READER_CHECK(value.HasMember("name"), (prefix + "Must have string value 'name'\n").c_str())) return false;
- if (!READER_CHECK(value["name"].IsString(), (prefix + "Value 'name' must be a string\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("min"), (prefix + "Must have a number or array value 'min'\n").c_str())) return false;
- if (!READER_CHECK(value["min"].IsNumber() || value["min"].IsArray(), (prefix + "Value 'min' must be a number or an array the size of the corresponding slider type\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("default"), (prefix + "Must have a number or array value 'default'\n").c_str())) return false;
- if (!READER_CHECK(value["default"].IsNumber() || value["default"].IsArray(), (prefix + "Value 'default' must be a number or an array the size of the corresponding slider type\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("max"), (prefix + "Must have a number or array value 'max'\n").c_str())) return false;
- if (!READER_CHECK(value["max"].IsNumber() || value["max"].IsArray(), (prefix + "Value 'max' must be a number or an array the size of the corresponding slider type\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("step"), (prefix + "Must have a number value 'step'\n").c_str())) return false;
- if (!READER_CHECK(value["step"].IsNumber(), (prefix + "Value 'step' must be a number (how much does this slider increment by internally?)\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("type"), (prefix + "Must have string value 'type'\n").c_str())) return false;
- if (!READER_CHECK(value["type"].IsString(), (prefix + "Value 'type' must be a string (what type of slider is this? [int_enum, int, float])\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("screen"), (prefix + "Must have string value 'screen'\n").c_str())) return false;
- if (!READER_CHECK(value["screen"].IsString(), (prefix + "Value 'screen' must be a string (what type of output device does this slider apply to? [none, raster, vector, crt, lcd, non_vector, any])\n").c_str())) return false;
- if (!READER_CHECK(value.HasMember("format"), (prefix + "Must have string value 'format'\n").c_str())) return false;
- if (!READER_CHECK(value["format"].IsString(), (prefix + "Value 'scale' must be a string (how would we display it in a printf?)").c_str())) return false;
- if (!READER_CHECK(value.HasMember("text"), (prefix + "Must have string value 'text'\n").c_str())) return false;
- if (!READER_CHECK(value["text"].IsString(), (prefix + "Value 'text' must be a string (how would you explain it?)").c_str())) return false;
- if (!READER_CHECK(!value.HasMember("strings") || value["strings"].IsArray(), (prefix + "Value 'strings' must be an array\n").c_str())) return false;
+ if (!READER_CHECK(value.HasMember("name"), "%1$sMust have string value 'name'", prefix)) return false;
+ if (!READER_CHECK(value["name"].IsString(), "%1$sValue 'name' must be a string", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("min"), "%1$sMust have a number or array value 'min'", prefix)) return false;
+ if (!READER_CHECK(value["min"].IsNumber() || value["min"].IsArray(), "%1$sValue 'min' must be a number or an array the size of the corresponding slider type", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("default"), "%1$sMust have a number or array value 'default'", prefix)) return false;
+ if (!READER_CHECK(value["default"].IsNumber() || value["default"].IsArray(), "%1$sValue 'default' must be a number or an array the size of the corresponding slider type", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("max"), "%1$sMust have a number or array value 'max'", prefix)) return false;
+ if (!READER_CHECK(value["max"].IsNumber() || value["max"].IsArray(), "%1$sValue 'max' must be a number or an array the size of the corresponding slider type", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("step"), "%1$sMust have a number value 'step'", prefix)) return false;
+ if (!READER_CHECK(value["step"].IsNumber(), "%1$sValue 'step' must be a number (how much does this slider increment by internally?)", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("type"), "%1$sMust have string value 'type'", prefix)) return false;
+ if (!READER_CHECK(value["type"].IsString(), "%1$sValue 'type' must be a string (what type of slider is this? [int_enum, int, float])", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("screen"), "%1$sMust have string value 'screen'", prefix)) return false;
+ if (!READER_CHECK(value["screen"].IsString(), "%1$sValue 'screen' must be a string (what type of output device does this slider apply to? [none, raster, vector, crt, lcd, non_vector, any])", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("format"), "%1$sMust have string value 'format'", prefix)) return false;
+ if (!READER_CHECK(value["format"].IsString(), "%1$sValue 'scale' must be a string (how would we display it in a printf?)", prefix)) return false;
+ if (!READER_CHECK(value.HasMember("text"), "%1$sMust have string value 'text'", prefix)) return false;
+ if (!READER_CHECK(value["text"].IsString(), "%1$sValue 'text' must be a string (how would you explain it?)", prefix)) return false;
+ if (!READER_CHECK(!value.HasMember("strings") || value["strings"].IsArray(), "%1$sValue 'strings' must be an array", prefix)) return false;
return true;
}
diff --git a/src/osd/modules/render/bgfx/statereader.cpp b/src/osd/modules/render/bgfx/statereader.cpp
index bd7923f1c5e..51b08fea864 100644
--- a/src/osd/modules/render/bgfx/statereader.cpp
+++ b/src/osd/modules/render/bgfx/statereader.cpp
@@ -11,20 +11,14 @@
#include "osdcore.h"
-#include <cstdarg>
#include <cmath>
-bool state_reader::READER_CHECK(bool condition, const char* format, ...)
+
+bool state_reader::V_READER_CHECK(bool condition, const util::format_argument_pack<std::ostream> &args)
{
if (!condition)
- {
- va_list ap;
- va_start(ap, format);
- char buf[2048];
- vsnprintf(buf, 2048, format, ap);
- osd_printf_error("Error: %s\n", buf);
- va_end(ap);
- }
+ osd_printf_error("Error: %s\n", util::string_format(args));
+
return condition;
}
diff --git a/src/osd/modules/render/bgfx/statereader.h b/src/osd/modules/render/bgfx/statereader.h
index 43596bf4e94..0c452aabee8 100644
--- a/src/osd/modules/render/bgfx/statereader.h
+++ b/src/osd/modules/render/bgfx/statereader.h
@@ -7,16 +7,19 @@
//
//================================================================
+#ifndef MAME_RENDER_BGFX_STATEREADER_H
+#define MAME_RENDER_BGFX_STATEREADER_H
+
#pragma once
-#ifndef DRAWBGFX_STATE_READER
-#define DRAWBGFX_STATE_READER
+#include "util/strformat.h"
#include <rapidjson/document.h>
#include <cstdint>
#include <string>
+
using namespace rapidjson;
class state_reader
@@ -44,10 +47,15 @@ protected:
static uint64_t get_param_from_string(std::string value, const string_to_enum* enums, const int count);
protected:
- static bool READER_CHECK(bool condition, const char* format, ...);
+ template <typename Format, typename... Params>
+ static bool READER_CHECK(bool condition, Format &&fmt, Params &&... args)
+ {
+ return V_READER_CHECK(condition, util::make_format_argument_pack(std::forward<Format>(fmt), std::forward<Params>(args)...));
+ }
private:
+ static bool V_READER_CHECK(bool condition, const util::format_argument_pack<std::ostream> &args);
static void get_vec_values(const Value& value_array, float* data, const unsigned int count);
};
-#endif // DRAWBGFX_STATE_READER
+#endif // MAME_RENDER_BGFX_STATEREADER_H
diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp
index fc9214fe446..11801fd800d 100644
--- a/src/osd/modules/render/drawbgfx.cpp
+++ b/src/osd/modules/render/drawbgfx.cpp
@@ -22,38 +22,46 @@ extern void *GetOSWindow(void *wincontroller);
#endif
#endif
-// MAMEOS headers
#include "emu.h"
-#include "window.h"
-#include "render.h"
-#include "rendutil.h"
-#include "aviwrite.h"
-
-#include <bgfx/bgfx.h>
-#include <bgfx/platform.h>
-#include <algorithm>
-
#include "drawbgfx.h"
-#include "bgfxutil.h"
-#include "bgfx/texturemanager.h"
-#include "bgfx/targetmanager.h"
-#include "bgfx/shadermanager.h"
-#include "bgfx/effectmanager.h"
-#include "bgfx/chainmanager.h"
+
+// render/bgfx
#include "bgfx/effect.h"
-#include "bgfx/texture.h"
-#include "bgfx/target.h"
-#include "bgfx/chain.h"
-#include "bgfx/vertex.h"
-#include "bgfx/uniform.h"
+#include "bgfx/effectmanager.h"
+#include "bgfx/shadermanager.h"
#include "bgfx/slider.h"
#include "bgfx/target.h"
+#include "bgfx/target.h"
+#include "bgfx/targetmanager.h"
+#include "bgfx/texture.h"
+#include "bgfx/texturemanager.h"
+#include "bgfx/uniform.h"
#include "bgfx/view.h"
+// render
+#include "aviwrite.h"
+#include "bgfxutil.h"
+
+// emu
+#include "config.h"
+#include "render.h"
+#include "rendutil.h"
+
+// util
+#include "util/xmlfile.h"
+
+// OSD
#include "modules/lib/osdobj_common.h"
+#include "window.h"
+
+#include <bgfx/bgfx.h>
+#include <bgfx/platform.h>
#include "imgui/imgui.h"
+#include <algorithm>
+
+
//============================================================
// DEBUGGING
//============================================================
@@ -294,9 +302,7 @@ int renderer_bgfx::create()
m_dimensions = wdim;
if (s_bgfx_library_initialized)
- {
exit();
- }
if (win->index() == 0)
{
@@ -340,9 +346,8 @@ int renderer_bgfx::create()
#endif
bgfx::touch(win->index());
- if (m_ortho_view) {
+ if (m_ortho_view)
m_ortho_view->set_backbuffer(m_framebuffer);
- }
}
m_chains = new chain_manager(win->machine(), m_options, *m_textures, *m_targets, *m_effects, win->index(), *this);
@@ -354,6 +359,12 @@ int renderer_bgfx::create()
memset(m_white, 0xff, sizeof(uint32_t) * 16 * 16);
m_texinfo.push_back(rectangle_packer::packable_rectangle(WHITE_HASH, PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32), 16, 16, 16, nullptr, m_white));
+ // Register configuration handlers
+ win->machine().configuration().config_register(
+ "bgfx",
+ configuration_manager::load_delegate(&renderer_bgfx::load_config, this),
+ configuration_manager::save_delegate(&renderer_bgfx::save_config, this));
+
return 0;
}
@@ -883,6 +894,19 @@ int renderer_bgfx::draw(int update)
if (num_screens)
{
+ // Restore config after counting screens the first time
+ // Doing this here is hacky - it means config is restored at the wrong
+ // time if the initial view has no screens and the user switches to a
+ // view with screens. The trouble is there's no real interface between
+ // the render targets and the renderer so we don't actually know when
+ // we're first called on to render a live view (as opposed to an info
+ // screen).
+ if (m_config)
+ {
+ m_chains->load_config(*m_config->get_first_child());
+ m_config.reset();
+ }
+
uint32_t chain_view_count = m_chains->process_screen_chains(s_current_view, *win.get());
s_current_view += chain_view_count;
}
@@ -1339,11 +1363,44 @@ void renderer_bgfx::set_sliders_dirty()
m_sliders_dirty = true;
}
-uint32_t renderer_bgfx::get_window_width(uint32_t index) const {
+uint32_t renderer_bgfx::get_window_width(uint32_t index) const
+{
return s_width[index];
}
-uint32_t renderer_bgfx::get_window_height(uint32_t index) const {
+uint32_t renderer_bgfx::get_window_height(uint32_t index) const
+{
return s_height[index];
}
+
+void renderer_bgfx::load_config(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
+{
+ if ((cfg_type == config_type::SYSTEM) && parentnode)
+ {
+ auto const win = try_getwindow();
+ if (win)
+ {
+ util::xml::data_node const *windownode = parentnode->get_child("window");
+ while (windownode)
+ {
+ if (windownode->get_attribute_int("index", -1) != win->index())
+ {
+ windownode = windownode->get_next_sibling("window");
+ continue;
+ }
+
+ m_config = util::xml::file::create();
+ windownode->copy_into(*m_config);
+ break;
+ }
+ }
+ }
+}
+
+
+void renderer_bgfx::save_config(config_type cfg_type, util::xml::data_node *parentnode)
+{
+ if (cfg_type == config_type::SYSTEM)
+ m_chains->save_config(*parentnode);
+}
diff --git a/src/osd/modules/render/drawbgfx.h b/src/osd/modules/render/drawbgfx.h
index fc728e41d67..bdc3e894ebd 100644
--- a/src/osd/modules/render/drawbgfx.h
+++ b/src/osd/modules/render/drawbgfx.h
@@ -1,30 +1,32 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
-#pragma once
+#ifndef MAME_RENDER_DRAWBGFX_H
+#define MAME_RENDER_DRAWBGFX_H
-#ifndef RENDER_BGFX
-#define RENDER_BGFX
+#pragma once
#include <bgfx/bgfx.h>
-#include <map>
-#include <vector>
-
#include "binpacker.h"
-#include "bgfx/vertex.h"
#include "bgfx/chain.h"
#include "bgfx/chainmanager.h"
+#include "bgfx/vertex.h"
#include "sliderdirtynotifier.h"
+#include "modules/osdwindow.h"
+
+#include <map>
+#include <memory>
+#include <vector>
+
+
class texture_manager;
class target_manager;
class shader_manager;
class effect_manager;
-class chain_manager;
class bgfx_texture;
class bgfx_effect;
class bgfx_target;
-class bgfx_chain;
class bgfx_view;
class osd_options;
class avi_write;
@@ -62,6 +64,15 @@ public:
static char const *const WINDOW_PREFIX;
private:
+ enum buffer_status
+ {
+ BUFFER_PRE_FLUSH,
+ BUFFER_FLUSH,
+ BUFFER_SCREEN,
+ BUFFER_EMPTY,
+ BUFFER_DONE
+ };
+
void init_bgfx_library();
void vertex(ScreenVertex* vertex, float x, float y, float z, uint32_t rgba, float u, float v);
@@ -73,14 +84,6 @@ private:
void setup_ortho_view();
void allocate_buffer(render_primitive *prim, uint32_t blend, bgfx::TransientVertexBuffer *buffer);
- enum buffer_status
- {
- BUFFER_PRE_FLUSH,
- BUFFER_FLUSH,
- BUFFER_SCREEN,
- BUFFER_EMPTY,
- BUFFER_DONE
- };
buffer_status buffer_primitives(bool atlas_valid, render_primitive** prim, bgfx::TransientVertexBuffer* buffer, int32_t screen);
void render_textured_quad(render_primitive* prim, bgfx::TransientVertexBuffer* buffer);
@@ -100,6 +103,9 @@ private:
void process_atlas_packs(std::vector<std::vector<rectangle_packer::packed_rectangle>>& packed);
uint32_t get_texture_hash(render_primitive *prim);
+ void load_config(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode);
+ void save_config(config_type cfg_type, util::xml::data_node *parentnode);
+
osd_options& m_options;
bgfx::PlatformData m_platform_data;
@@ -133,6 +139,7 @@ private:
bgfx::TextureHandle m_avi_texture;
bitmap_rgb32 m_avi_bitmap;
uint8_t *m_avi_data;
+ std::unique_ptr<util::xml::file> m_config;
static const uint16_t CACHE_SIZE;
static const uint32_t PACKABLE_SIZE;
@@ -144,4 +151,4 @@ private:
static uint32_t s_height[16];
};
-#endif // RENDER_BGFX
+#endif // MAME_RENDER_DRAWBGFX_H
diff --git a/src/osd/windows/window.cpp b/src/osd/windows/window.cpp
index 3cc991d7929..d206ea41273 100644
--- a/src/osd/windows/window.cpp
+++ b/src/osd/windows/window.cpp
@@ -1033,7 +1033,8 @@ int win_window_info::complete_create()
if (video_config.mode == VIDEO_MODE_NONE || attached_mode())
{
set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this()));
- renderer().create();
+ if (renderer().create())
+ return 1;
return 0;
}