Added "selection" parameter to chain input sampler

- if specified all textures (.png) within the same directoy of the given texture will be selectable via slider in the UI
- also added slider for "shadow mask tile mode" to HLSL chain
This commit is contained in:
ImJezze 2016-04-24 20:36:42 +02:00
parent 29f51e85db
commit 07d8b25571
26 changed files with 376 additions and 145 deletions

View File

@ -96,10 +96,11 @@
{ "type": "float", "name": "scanline_height", "text": "Individual Scanline Scale", "default": 1.00, "max": 4.00, "min": 0.0, "step": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "float", "name": "scanline_variation", "text": "Scanline Variation", "default": 1.00, "max": 4.00, "min": 0.0, "step": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "float", "name": "shadow_alpha", "text": "Shadow Mask Amount", "default": 0.20, "max": 1.00, "min": 0.00, "step": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "vec2", "name": "shadow_uv_count", "text": "Shadow Mask Pixel Count ", "default": [ 12, 12 ], "max": [ 128, 128 ], "min": [ 1, 1 ], "step": 1, "format": "%3f", "screen": "crt" },
{ "type": "vec2", "name": "shadow_uv_size", "text": "Shadow Mask UV Size ", "default": [ 0.500, 0.500 ], "max": [ 1.000, 1.000 ], "min": [ 0.000, 0.000 ], "step": 0.001, "format": "%1.3f", "screen": "crt" },
{ "type": "vec2", "name": "shadow_uv_offset", "text": "Shadow Mask UV Offset ", "default": [ 0.000, 0.000 ], "max": [ 1.000, 1.000 ], "min": [ 0.000, 0.000 ], "step": 0.001, "format": "%1.3f", "screen": "crt" },
{ "type": "intenum", "name": "shadow_tile_mode", "text": "Shadow Mask Tile Mode", "default": 0, "max": 1, "min": 0, "step": 1, "format": "%s", "screen": "any", "strings": [ "Screen", "Source" ] },
{ "type": "float", "name": "shadow_alpha", "text": "Shadow Mask Amount", "default": 0.20, "max": 1.00, "min": 0.00, "step": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "vec2", "name": "shadow_uv_count", "text": "Shadow Mask Pixel Count ", "default": [ 12, 12 ], "max": [ 128, 128 ], "min": [ 1, 1 ], "step": 1, "format": "%3f", "screen": "crt" },
{ "type": "vec2", "name": "shadow_uv_size", "text": "Shadow Mask UV Size ", "default": [ 0.500, 0.500 ], "max": [ 1.000, 1.000 ], "min": [ 0.000, 0.000 ], "step": 0.001, "format": "%1.3f", "screen": "crt" },
{ "type": "vec2", "name": "shadow_uv_offset", "text": "Shadow Mask UV Offset ", "default": [ 0.000, 0.000 ], "max": [ 1.000, 1.000 ], "min": [ 0.000, 0.000 ], "step": 0.001, "format": "%1.3f", "screen": "crt" },
{ "type": "float", "name": "humbar_alpha", "text": "Hum Bar Amount", "default": 0.05, "max": 1.00, "min": 0.00, "step": 0.01, "format": "%1.2f", "screen": "crt" },
{ "type": "float", "name": "humbar_hertz_rate", "text": "Hum Bar Frequency", "default": 0.001, "max": 1.000, "min": 0.000, "step": 0.00001, "format": "%1.5f", "screen": "crt" },
@ -280,6 +281,9 @@
// bilinear (optional, texture and target only): Whether to apply bilinear filtering to the sampler.
// values: true, false
// default: true
//
// selection (optional, option and texture only): Determines the name of the selection and alowes to select other textures in the same directory as the specified texture file.
// values: Any valid ASCII string.
{ "sampler": "s_tex", "texture": "screen" }
],
@ -451,6 +455,7 @@
{ "uniform": "u_scanline_bright_offset", "slider": "scanline_bright_offset" },
{ "uniform": "u_scanline_height", "slider": "scanline_height" },
{ "uniform": "u_scanline_variation", "slider": "scanline_variation" },
{ "uniform": "u_shadow_tile_mode", "slider": "shadow_tile_mode" },
{ "uniform": "u_shadow_alpha", "slider": "shadow_alpha" },
{ "uniform": "u_shadow_count", "slider": "shadow_uv_count" },
{ "uniform": "u_shadow_uv", "slider": "shadow_uv_size" },
@ -465,7 +470,7 @@
],
"input": [
{ "sampler": "s_tex", "target": "internal" },
{ "sampler": "s_shadow", "option": "bgfx_shadow_mask" }
{ "sampler": "s_shadow", "option": "bgfx_shadow_mask", "selection": "Shadow Mask" }
],
"output": "internal"
},

View File

@ -35,6 +35,7 @@
{ "name": "u_time", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_screen_scale", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] },
{ "name": "u_screen_offset", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_shadow_tile_mode", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_alpha", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_scale", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_scanline_bright_scale", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },

View File

@ -158,7 +158,6 @@ float2 GetAdjustedCoords(float2 coord)
return coord;
}
// vector screen has the same quad texture coordinates for every screen orientation, raster screen differs
float2 GetShadowCoord(float2 QuadCoord, float2 SourceCoord)
{
float2 QuadTexel = 1.0f / QuadDims;

View File

@ -35,6 +35,7 @@ public:
// Getters
std::vector<bgfx_slider*>& sliders() { return m_sliders; }
std::vector<bgfx_chain_entry*>& entries() { return m_entries; }
uint32_t applicable_passes();
bool transform() { return m_transform; }

View File

@ -28,7 +28,7 @@
#include "render.h"
bgfx_chain_entry::bgfx_chain_entry(std::string name, bgfx_effect* effect, clear_state* clear, std::vector<bgfx_suppressor*> suppressors, std::vector<bgfx_input_pair> inputs, std::vector<bgfx_entry_uniform*> uniforms, target_manager& targets, std::string output)
bgfx_chain_entry::bgfx_chain_entry(std::string name, bgfx_effect* effect, clear_state* clear, std::vector<bgfx_suppressor*> suppressors, std::vector<bgfx_input_pair*> inputs, std::vector<bgfx_entry_uniform*> uniforms, target_manager& targets, std::string output)
: m_name(name)
, m_effect(effect)
, m_clear(clear)
@ -42,6 +42,11 @@ bgfx_chain_entry::bgfx_chain_entry(std::string name, bgfx_effect* effect, clear_
bgfx_chain_entry::~bgfx_chain_entry()
{
for (bgfx_input_pair* input : m_inputs)
{
delete input;
}
m_inputs.clear();
for (bgfx_entry_uniform* uniform : m_uniforms)
{
delete uniform;
@ -59,9 +64,9 @@ void bgfx_chain_entry::submit(int view, render_primitive* prim, texture_manager&
return;
}
for (bgfx_input_pair input : m_inputs)
for (bgfx_input_pair* input : m_inputs)
{
input.bind(m_effect, m_targets, textures, screen);
input->bind(m_effect, screen);
}
bgfx::TransientVertexBuffer buffer;
@ -92,7 +97,7 @@ void bgfx_chain_entry::setup_screensize_uniforms(texture_manager& textures, uint
float height = screen_height;
if (m_inputs.size() > 0)
{
std::string name = m_inputs[0].texture() + std::to_string(screen);
std::string name = m_inputs[0]->texture() + std::to_string(screen);
width = float(textures.provider(name)->width());
height = float(textures.provider(name)->height());
}
@ -181,7 +186,7 @@ void bgfx_chain_entry::setup_quaddims_uniform(render_primitive* prim) const
bgfx_uniform* quad_dims_uniform = m_effect->uniform("u_quad_dims");
if (quad_dims_uniform != nullptr)
{
float values[2] = { (prim->bounds.x1 - prim->bounds.x0) + 0.5f, (prim->bounds.y1 - prim->bounds.y0) + 0.5f};
float values[2] = { float(floor((prim->bounds.x1 - prim->bounds.x0) + 0.5f)), float(floor((prim->bounds.y1 - prim->bounds.y0) + 0.5f)) };
quad_dims_uniform->set(values, sizeof(float) * 2);
}
}

View File

@ -34,13 +34,14 @@ class target_manager;
class bgfx_chain_entry
{
public:
bgfx_chain_entry(std::string name, bgfx_effect* effect, clear_state* clear, std::vector<bgfx_suppressor*> suppressors, std::vector<bgfx_input_pair> inputs, std::vector<bgfx_entry_uniform*> uniforms, target_manager& targets, std::string output);
bgfx_chain_entry(std::string name, bgfx_effect* effect, clear_state* clear, std::vector<bgfx_suppressor*> suppressors, std::vector<bgfx_input_pair*> inputs, std::vector<bgfx_entry_uniform*> uniforms, target_manager& targets, std::string output);
~bgfx_chain_entry();
void submit(int view, render_primitive* prim, texture_manager& textures, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, uint64_t blend, int32_t screen);
// Getters
std::string name() const { return m_name; }
std::vector<bgfx_input_pair*>& inputs() { return m_inputs; }
bool skip();
private:
@ -62,7 +63,7 @@ private:
bgfx_effect* m_effect;
clear_state* m_clear;
std::vector<bgfx_suppressor*> m_suppressors;
std::vector<bgfx_input_pair> m_inputs;
std::vector<bgfx_input_pair*> m_inputs;
std::vector<bgfx_entry_uniform*> m_uniforms;
target_manager& m_targets;
std::string m_output;

View File

@ -20,6 +20,7 @@
#include "targetmanager.h"
#include "effectmanager.h"
#include "chainentry.h"
#include "chainmanager.h"
#include "slider.h"
#include "inputpair.h"
#include "entryuniform.h"
@ -29,7 +30,7 @@
#include "clear.h"
#include "clearreader.h"
bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::string prefix, osd_options& options, texture_manager& textures, target_manager& targets, effect_manager& effects, std::map<std::string, bgfx_slider*>& sliders, std::map<std::string, bgfx_parameter*>& params, uint32_t screen_index)
bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::string prefix, chain_manager& chains, std::map<std::string, bgfx_slider*>& sliders, std::map<std::string, bgfx_parameter*>& params, uint32_t screen_index)
{
if (!validate_parameters(value, prefix))
{
@ -37,7 +38,7 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::s
return nullptr;
}
bgfx_effect* effect = effects.effect(value["effect"].GetString());
bgfx_effect* effect = chains.effects().effect(value["effect"].GetString());
if (effect == nullptr)
{
return nullptr;
@ -45,7 +46,7 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::s
std::string name = value["name"].GetString();
std::vector<bgfx_input_pair> inputs;
std::vector<bgfx_input_pair*> inputs;
if (value.HasMember("input"))
{
const Value& input_array = value["input"];
@ -62,19 +63,105 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::s
if (!READER_CHECK(!has_target || input["target"].IsString(), (prefix + "input[" + std::to_string(i) + ": Value 'target' must be a string\n").c_str())) return nullptr;
if (!READER_CHECK(!has_option || input["option"].IsString(), (prefix + "input[" + std::to_string(i) + ": Value 'option' must be a string\n").c_str())) return nullptr;
if (!READER_CHECK(has_target || !input.HasMember("bilinear") || input["bilinear"].IsBool(), (prefix + "input[" + std::to_string(i) + ": Value 'bilinear' must be a boolean\n").c_str())) return nullptr;
if (!READER_CHECK(has_texture || has_option || !input.HasMember("selection") || input["selection"].IsString(), (prefix + "input[" + std::to_string(i) + ": Value 'selection' must be a string\n").c_str())) return nullptr;
bool bilinear = get_bool(input, "bilinear", true);
std::string selection = get_string(input, "selection", "");
std::vector<std::string> texture_names;
std::string texture_name = "";
if (has_texture)
if (has_texture || has_option)
{
texture_name = input["texture"].GetString();
if (texture_name != "screen")
if (has_texture)
{
bool bilinear = get_bool(input, "bilinear", true);
uint32_t flags = bilinear ? 0 : (BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT);
bgfx_texture* texture = textures.create_png_texture(options.art_path(), texture_name, texture_name, flags, screen_index);
if (texture == nullptr)
texture_name = input["texture"].GetString();
}
if (has_option)
{
std::string option = input["option"].GetString();
texture_name = chains.options().value(option.c_str());
}
if (texture_name != "" && texture_name != "screen")
{
if (selection == "")
{
return nullptr;
// create texture for specified file name
uint32_t flags = bilinear ? 0 : (BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT);
bgfx_texture* texture = chains.textures().create_png_texture(chains.options().art_path(), texture_name, texture_name, flags, screen_index);
if (texture == nullptr)
{
return nullptr;
}
}
else
{
// create texture for specified file name
uint32_t flags = bilinear ? 0 : (BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT);
bgfx_texture* texture = chains.textures().create_png_texture(chains.options().art_path(), texture_name, texture_name, flags, screen_index);
if (texture == nullptr)
{
return nullptr;
}
// get directory of file
std::string directory_path = std::string(chains.options().art_path());
std::string file_directory = "";
const size_t last_slash = texture_name.rfind('/');
if (last_slash != std::string::npos)
{
file_directory = texture_name.substr(0, last_slash);
directory_path += "/" + file_directory;
}
osd_directory *directory = osd_opendir(directory_path.c_str());
if (directory != nullptr)
{
for (const osd_directory_entry *entry = osd_readdir(directory); entry != nullptr; entry = osd_readdir(directory))
{
if (entry->type == ENTTYPE_FILE)
{
std::string file(entry->name);
std::string extension(".png");
// split into file name and extension
std::string file_name;
std::string file_extension;
const size_t last_dot = file.rfind('.');
if (last_dot != std::string::npos)
{
file_name = file.substr(0, last_dot);
file_extension = file.substr(last_dot, file.length() - last_dot);
}
std::string file_path;
if (file_directory == "")
{
file_path = file;
}
else
{
file_path = file_directory + "/" + file;
}
// check for .png extension
if (file_extension == extension)
{
// create textures for all files containd in the path of the specified file name
uint32_t flags = bilinear ? 0 : (BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT);
bgfx_texture* texture = chains.textures().create_png_texture(chains.options().art_path(), file_path, file_path, flags, screen_index);
if (texture == nullptr)
{
return nullptr;
}
texture_names.push_back(file_path);
}
}
}
osd_closedir(directory);
}
}
}
}
@ -82,24 +169,14 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::s
{
texture_name = input["target"].GetString();
}
else if (has_option)
{
bool bilinear = get_bool(input, "bilinear", true);
uint32_t flags = bilinear ? 0 : (BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT);
texture_name = input["option"].GetString();
bgfx_texture* texture = textures.create_png_texture(options.art_path(), options.value(texture_name.c_str()), texture_name, flags, screen_index);
if (texture == nullptr)
{
return nullptr;
}
}
else
{
return nullptr;
}
std::string sampler = input["sampler"].GetString();
inputs.push_back(bgfx_input_pair(i, sampler, texture_name));
bgfx_input_pair* input_pair = new bgfx_input_pair(i, sampler, texture_name, texture_names, selection, chains, screen_index);
inputs.push_back(input_pair);
}
}
@ -148,7 +225,7 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::s
}
std::string output = value["output"].GetString();
return new bgfx_chain_entry(name, effect, clear, suppressors, inputs, uniforms, targets, output);
return new bgfx_chain_entry(name, effect, clear, suppressors, inputs, uniforms, chains.targets(), output);
}
bool chain_entry_reader::validate_parameters(const Value& value, std::string prefix)

View File

@ -15,18 +15,15 @@
#include "statereader.h"
class osd_options;
class bgfx_chain_entry;
class texture_manager;
class target_manager;
class effect_manager;
class bgfx_slider;
class bgfx_parameter;
class chain_manager;
class chain_entry_reader : public state_reader
{
public:
static bgfx_chain_entry* read_from_value(const Value& value, std::string prefix, osd_options& options, texture_manager& textures, target_manager& targets, effect_manager& effects, std::map<std::string, bgfx_slider*>& sliders, std::map<std::string, bgfx_parameter*>& params, uint32_t screen_index);
static bgfx_chain_entry* read_from_value(const Value& value, std::string prefix, chain_manager& chains, std::map<std::string, bgfx_slider*>& sliders, std::map<std::string, bgfx_parameter*>& params, uint32_t screen_index);
private:
static bool validate_parameters(const Value& value, std::string prefix);

View File

@ -162,7 +162,7 @@ bgfx_chain* chain_manager::load_chain(std::string name, uint32_t screen_index)
return nullptr;
}
bgfx_chain* chain = chain_reader::read_from_value(document, name + ": ", m_options, m_machine, m_window_index, screen_index, m_textures, m_targets, m_effects);
bgfx_chain* chain = chain_reader::read_from_value(document, name + ": ", *this, screen_index);
if (chain == nullptr)
{
@ -472,6 +472,20 @@ std::vector<ui_menu_item> chain_manager::get_slider_list()
continue;
}
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();
for (bgfx_input_pair* input : entry_inputs)
{
std::vector<ui_menu_item> input_sliders = input->get_slider_list();
for (ui_menu_item slider : input_sliders)
{
sliders.push_back(slider);
}
}
}
std::vector<bgfx_slider*> chain_sliders = chain->sliders();
for (bgfx_slider* slider : chain_sliders)
{

View File

@ -25,6 +25,7 @@
class running_machine;
class osd_window;
class slider_dirty_notifier;
class render_primitive;
class bgfx_chain;
class bgfx_slider;
@ -39,6 +40,14 @@ public:
int32_t chain_changed(int32_t index, std::string *str, int32_t newval);
// Getters
running_machine& machine() { return m_machine; }
osd_options& options() { return m_options; }
texture_manager& textures() { return m_textures; }
target_manager& targets() { return m_targets; }
effect_manager& effects() { return m_effects; }
slider_dirty_notifier& slider_notifier() { return m_slider_notifier; }
uint32_t window_index() { return m_window_index; }
uint32_t screen_count() { return m_screen_count; }
bgfx_chain* screen_chain(uint32_t screen);
bgfx_chain* load_chain(std::string name, uint32_t screen_index);
bool has_applicable_chain(uint32_t screen);

View File

@ -14,8 +14,8 @@
#include <modules/lib/osdobj_common.h>
#include "chainreader.h"
#include "chain.h"
#include "chainmanager.h"
#include "sliderreader.h"
#include "paramreader.h"
#include "chainentryreader.h"
@ -24,7 +24,7 @@
#include "slider.h"
#include "parameter.h"
bgfx_chain* chain_reader::read_from_value(const Value& value, std::string prefix, osd_options& options, running_machine& machine, uint32_t window_index, uint32_t screen_index, texture_manager& textures, target_manager& targets, effect_manager& effects)
bgfx_chain* chain_reader::read_from_value(const Value& value, std::string prefix, chain_manager& chains, uint32_t screen_index)
{
if (!validate_parameters(value, prefix))
{
@ -41,7 +41,7 @@ bgfx_chain* chain_reader::read_from_value(const Value& value, std::string prefix
const Value& slider_array = value["sliders"];
for (UINT32 i = 0; i < slider_array.Size(); i++)
{
std::vector<bgfx_slider*> expanded_sliders = slider_reader::read_from_value(slider_array[i], prefix + "sliders[" + std::to_string(i) + "]: ", machine, window_index, screen_index);
std::vector<bgfx_slider*> expanded_sliders = slider_reader::read_from_value(slider_array[i], prefix + "sliders[" + std::to_string(i) + "]: ", chains, screen_index);
if (expanded_sliders.size() == 0)
{
return nullptr;
@ -74,7 +74,7 @@ bgfx_chain* chain_reader::read_from_value(const Value& value, std::string prefix
const Value& param_array = value["parameters"];
for (UINT32 i = 0; i < param_array.Size(); i++)
{
bgfx_parameter* parameter = parameter_reader::read_from_value(param_array[i], prefix + "parameters[" + std::to_string(i) + "]; ", window_index);
bgfx_parameter* parameter = parameter_reader::read_from_value(param_array[i], prefix + "parameters[" + std::to_string(i) + "]; ", chains);
if (parameter == nullptr)
{
return nullptr;
@ -98,7 +98,7 @@ bgfx_chain* chain_reader::read_from_value(const Value& value, std::string prefix
// TODO: Move into its own reader
for (UINT32 i = 0; i < target_array.Size(); i++)
{
bgfx_target* target = target_reader::read_from_value(target_array[i], prefix + "targets[" + std::to_string(i) + "]: ", targets, options, screen_index);
bgfx_target* target = target_reader::read_from_value(target_array[i], prefix + "targets[" + std::to_string(i) + "]: ", chains, screen_index);
if (target == nullptr)
{
return nullptr;
@ -114,7 +114,7 @@ bgfx_chain* chain_reader::read_from_value(const Value& value, std::string prefix
const Value& entry_array = value["passes"];
for (UINT32 i = 0; i < entry_array.Size(); i++)
{
bgfx_chain_entry* entry = chain_entry_reader::read_from_value(entry_array[i], prefix + "passes[" + std::to_string(i) + "]: ", options, textures, targets, effects, slider_map, param_map, screen_index);
bgfx_chain_entry* entry = chain_entry_reader::read_from_value(entry_array[i], prefix + "passes[" + std::to_string(i) + "]: ", chains, slider_map, param_map, screen_index);
if (entry == nullptr)
{
return nullptr;
@ -123,7 +123,7 @@ bgfx_chain* chain_reader::read_from_value(const Value& value, std::string prefix
}
}
return new bgfx_chain(name, author, transform, targets, sliders, parameters, entries, target_list, screen_index);
return new bgfx_chain(name, author, transform, chains.targets(), sliders, parameters, entries, target_list, screen_index);
}
bool chain_reader::validate_parameters(const Value& value, std::string prefix)

View File

@ -14,14 +14,12 @@
#include "statereader.h"
class bgfx_chain;
class texture_manager;
class target_manager;
class effect_manager;
class chain_manager;
class chain_reader : public state_reader
{
public:
static bgfx_chain* read_from_value(const Value& value, std::string prefix, osd_options& options, running_machine& machine, uint32_t window_index, uint32_t screen_index, texture_manager& textures, target_manager& targets, effect_manager& effects);
static bgfx_chain* read_from_value(const Value& value, std::string prefix, chain_manager& chains, uint32_t screen_index);
private:
static bool validate_parameters(const Value& value, std::string prefix);

View File

@ -9,29 +9,42 @@
//
//============================================================
#include "ui/uimain.h"
#include "emucore.h"
#include "inputpair.h"
#include "texture.h"
#include "target.h"
#include "effect.h"
#include "render.h"
#include "uniform.h"
#include "texturemanager.h"
#include "targetmanager.h"
#include "chainmanager.h"
#include "slider.h"
#include "sliderdirtynotifier.h"
bgfx_input_pair::bgfx_input_pair(int index, std::string sampler, std::string texture)
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)
, m_sampler(sampler)
, m_texture(texture)
, m_available_textures(available_textures)
, m_selection(selection)
, m_chains(chains)
{
if (m_available_textures.size() > 0)
{
m_current_texture = std::find(m_available_textures.begin(), m_available_textures.end(), m_texture) - m_available_textures.begin();
create_selection_slider(screen_index);
}
}
void bgfx_input_pair::bind(bgfx_effect *effect, target_manager& targets, texture_manager& textures, const int32_t screen) const
void bgfx_input_pair::bind(bgfx_effect *effect, const int32_t screen) const
{
assert(effect->uniform(m_sampler) != nullptr);
std::string name = m_texture + std::to_string(screen);
bgfx_texture_handle_provider* provider = textures.provider(name);
bgfx_texture_handle_provider* provider = chains().textures().provider(name);
bgfx_uniform *tex_size = effect->uniform("u_tex_size" + std::to_string(m_index));
if (tex_size != nullptr)
{
@ -39,5 +52,89 @@ void bgfx_input_pair::bind(bgfx_effect *effect, target_manager& targets, texture
tex_size->set(values, sizeof(float) * 2);
}
bgfx::setTexture(m_index, effect->uniform(m_sampler)->handle(), textures.handle(name));
bgfx::setTexture(m_index, effect->uniform(m_sampler)->handle(), chains().textures().handle(name));
}
static INT32 update_trampoline(running_machine &machine, void *arg, int id, std::string *str, INT32 newval)
{
if (arg != nullptr)
{
return reinterpret_cast<bgfx_input_pair*>(arg)->texture_changed(id, str, newval);
}
return 0;
}
int32_t bgfx_input_pair::texture_changed(int32_t id, std::string *str, int32_t newval)
{
if (newval != SLIDER_NOCHANGE)
{
m_current_texture = newval;
m_texture = m_available_textures[m_current_texture];
chains().slider_notifier().set_sliders_dirty();
}
if (str != nullptr)
{
std::string file = m_texture;
const size_t last_slash = m_texture.rfind('/');
if (last_slash != std::string::npos)
{
file = m_texture.substr(last_slash + 1, m_texture.length() - (last_slash + 1));
}
std::string file_name;
const size_t last_dot = file.rfind('.');
if (last_dot != std::string::npos)
{
file_name = file.substr(0, last_dot);
}
*str = string_format("%s", file_name.c_str());
}
return m_current_texture;
}
void bgfx_input_pair::create_selection_slider(uint32_t screen_index)
{
std::string description = "Window " + std::to_string(chains().window_index()) + ", Screen " + std::to_string(screen_index) + " " + m_selection + ":";
size_t size = sizeof(slider_state) + description.length();
slider_state *state = reinterpret_cast<slider_state *>(auto_alloc_array_clear(chains().machine(), UINT8, size));
state->minval = 0;
state->defval = m_current_texture;
state->maxval = m_available_textures.size() - 1;
state->incval = 1;
state->update = update_trampoline;
state->arg = this;
state->id = screen_index;
strcpy(state->description, description.c_str());
ui_menu_item item;
item.text = state->description;
item.subtext = "";
item.flags = 0;
item.ref = state;
item.type = ui_menu_item_type::SLIDER;
m_selection_slider = item;
}
bool bgfx_input_pair::needs_sliders()
{
return chains().screen_count() > 0 && m_available_textures.size() > 1;
}
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);
return sliders;
}

View File

@ -16,25 +16,37 @@
#include <string>
#include "ui/uimain.h"
class bgfx_effect;
class texture_manager;
class target_manager;
class chain_manager;
class bgfx_input_pair
{
public:
bgfx_input_pair(int index, std::string sampler, std::string texture);
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);
void bind(bgfx_effect *effect, target_manager& targets, texture_manager& textures, const int32_t screen) const;
void bind(bgfx_effect *effect, const int32_t screen) const;
int32_t texture_changed(int32_t index, std::string *str, int32_t newval);
// Getters
chain_manager& chains() const { return m_chains; }
std::string sampler() const { return m_sampler; }
std::string texture() const { return m_texture; }
std::vector<ui_menu_item> get_slider_list();
private:
int m_index;
std::string m_sampler;
std::string m_texture;
void create_selection_slider(uint32_t screen_index);
bool needs_sliders();
int m_index;
std::string m_sampler;
std::string m_texture;
std::vector<std::string> m_available_textures;
std::string m_selection;
chain_manager& m_chains;
int32_t m_current_texture;
ui_menu_item m_selection_slider;
};
#endif // __DRAWBGFX_INPUT_PAIR__

View File

@ -14,6 +14,7 @@
#include "frameparameter.h"
#include "windowparameter.h"
#include "timeparameter.h"
#include "chainmanager.h"
const parameter_reader::string_to_enum parameter_reader::TYPE_NAMES[parameter_reader::TYPE_COUNT] = {
{ "frame", bgfx_parameter::parameter_type::PARAM_FRAME },
@ -21,7 +22,7 @@ const parameter_reader::string_to_enum parameter_reader::TYPE_NAMES[parameter_re
{ "time", bgfx_parameter::parameter_type::PARAM_TIME }
};
bgfx_parameter* parameter_reader::read_from_value(const Value& value, std::string prefix, uint32_t window_index)
bgfx_parameter* parameter_reader::read_from_value(const Value& value, std::string prefix, chain_manager& chains)
{
if (!validate_parameters(value, prefix))
{
@ -38,7 +39,7 @@ bgfx_parameter* parameter_reader::read_from_value(const Value& value, std::strin
}
else if (type == bgfx_parameter::parameter_type::PARAM_WINDOW)
{
return new bgfx_window_parameter(name, type, window_index);
return new bgfx_window_parameter(name, type, chains.window_index());
}
else if (type == bgfx_parameter::parameter_type::PARAM_TIME)
{

View File

@ -14,11 +14,12 @@
#include "statereader.h"
class bgfx_parameter;
class chain_manager;
class parameter_reader : public state_reader
{
public:
static bgfx_parameter* read_from_value(const Value& value, std::string prefix, uint32_t window_index);
static bgfx_parameter* read_from_value(const Value& value, std::string prefix, chain_manager& chains);
private:
static bool validate_parameters(const Value& value, std::string prefix);

View File

@ -14,6 +14,7 @@ uniform vec4 u_source_dims; // size of the guest machine
uniform vec4 u_quad_dims;
uniform vec4 u_screen_scale;
uniform vec4 u_screen_offset;
// uniform vec4 u_back_color; // TODO
// User-supplied
uniform vec4 u_scanline_alpha;
@ -23,6 +24,7 @@ uniform vec4 u_scanline_bright_offset;
uniform vec4 u_scanline_jitter;
uniform vec4 u_scanline_height;
uniform vec4 u_scanline_variation;
uniform vec4 u_shadow_tile_mode;
uniform vec4 u_shadow_alpha;
uniform vec4 u_shadow_count;
uniform vec4 u_shadow_uv;
@ -61,32 +63,34 @@ vec2 GetAdjustedCoords(vec2 coord)
return coord;
}
// vector screen has the same quad texture coordinates for every screen orientation, raster screen differs
vec2 GetShadowCoord(vec2 QuadCoord, vec2 SourceCoord)
{
vec2 QuadTexel = vec2(1.0, 1.0) / (u_quad_dims.xy - 0.5f);
vec2 canvasCoord = QuadCoord + u_shadow_uv_offset.xy / u_quad_dims.xy;
vec2 canvasCoord = u_shadow_tile_mode.x == 0.0
? QuadCoord + u_shadow_uv_offset.xy / u_quad_dims.xy
: SourceCoord + u_shadow_uv_offset.xy / u_source_dims.xy;
vec2 canvasTexelDims = u_shadow_tile_mode.x == 0.0
? vec2(1.0, 1.0) / u_quad_dims.xy
: vec2(1.0, 1.0) / u_source_dims.xy;
vec2 shadowUV = u_shadow_uv.xy;
vec2 shadowCount = u_shadow_count.xy;
// swap x/y in screen mode (not source mode)
canvasCoord = u_swap_xy.x > 0.0
canvasCoord = u_shadow_tile_mode.x == 0.0 && u_swap_xy.x > 0.0
? canvasCoord.yx
: canvasCoord.xy;
// swap x/y in screen mode (not source mode)
shadowCount = u_swap_xy.x > 0.0
shadowCount = u_shadow_tile_mode.x == 0.0 && u_swap_xy.x > 0.0
? shadowCount.yx
: shadowCount.xy;
vec2 shadowTile = QuadTexel * shadowCount;
vec2 shadowTile = canvasTexelDims * shadowCount;
vec2 shadowFrac = fract(canvasCoord / shadowTile);
// swap x/y in screen mode (not source mode)
shadowFrac = u_swap_xy.x > 0.0
shadowFrac = u_shadow_tile_mode.x == 0.0 && u_swap_xy.x > 0.0
? shadowFrac.yx
: shadowFrac.xy;
@ -102,57 +106,66 @@ void main()
// Color
vec4 BaseColor = texture2D(s_tex, BaseCoord);
// Clamp
if (BaseCoord.x < 0.0 || BaseCoord.y < 0.0 || BaseCoord.x > 1.0 || BaseCoord.y > 1.0)
{
BaseColor.rgb = vec3(0.0, 0.0, 0.0);
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
}
// Mask Simulation
if (u_shadow_alpha.x > 0.0)
else
{
vec2 ShadowCoord = GetShadowCoord(v_texcoord0.xy, v_texcoord0.xy);
// Mask Simulation
if (u_shadow_alpha.x > 0.0)
{
vec2 ShadowCoord = GetShadowCoord(v_texcoord0.xy, BaseCoord.xy);
vec4 ShadowColor = texture2D(s_shadow, ShadowCoord);
vec3 ShadowMaskColor = mix(vec3(1.0, 1.0, 1.0), ShadowColor.rgb, u_shadow_alpha.xxx);
vec4 ShadowColor = texture2D(s_shadow, ShadowCoord);
vec3 ShadowMaskColor = mix(vec3(1.0, 1.0, 1.0), ShadowColor.rgb, u_shadow_alpha.xxx);
// apply shadow mask color
BaseColor.rgb *= ShadowMaskColor;
// apply shadow mask color
BaseColor.rgb *= ShadowMaskColor;
// // TODO
// vec3 ShadowMaskClear = (1.0f - ShadowColor.a) * u_shadow_alpha.xxx;
// // clear shadow mask by background color
// BaseColor.rgb = mix(BaseColor.rgb, u_back_color.rgb, ShadowMaskClear);
}
// Color Compression
// increasing the floor of the signal without affecting the ceiling
BaseColor.rgb = u_floor.rgb + (vec3(1.0, 1.0, 1.0) - u_floor.rgb) * BaseColor.rgb;
// Color Power
BaseColor.r = pow(BaseColor.r, u_power.r);
BaseColor.g = pow(BaseColor.g, u_power.g);
BaseColor.b = pow(BaseColor.b, u_power.b);
// Scanline Simulation
if (u_scanline_alpha.x > 0.0f)
{
float BrightnessOffset = (u_scanline_bright_offset.x * u_scanline_alpha.x);
float BrightnessScale = (u_scanline_bright_scale.x * u_scanline_alpha.x) + (1.0 - u_scanline_alpha.x);
float ColorBrightness = 0.299 * BaseColor.r + 0.587 * BaseColor.g + 0.114 * BaseColor.b;
float ScanCoord = BaseCoord.y * u_source_dims.y * u_scanline_scale.x * 3.1415927; // PI
float ScanCoordJitter = u_scanline_jitter.x * u_jitter_amount.x * 1.618034; // PHI
float ScanSine = sin(ScanCoord + ScanCoordJitter);
float ScanlineWide = u_scanline_height.x + u_scanline_variation.x * max(1.0, u_scanline_height.x) * (1.0 - ColorBrightness);
float ScanSineScaled = pow(ScanSine * ScanSine, ScanlineWide);
float ScanBrightness = ScanSineScaled * BrightnessScale + BrightnessOffset * BrightnessScale;
BaseColor.rgb *= mix(vec3(1.0, 1.0, 1.0), vec3(ScanBrightness, ScanBrightness, ScanBrightness), u_scanline_alpha.xxx);
}
// Hum Bar Simulation
if (u_humbar_alpha.x > 0.0f)
{
float HumTimeStep = fract(u_time.x * u_humbar_hertz_rate.x);
float HumBrightness = 1.0 - fract(BaseCoord.y + HumTimeStep) * u_humbar_alpha.x;
BaseColor.rgb *= HumBrightness;
}
gl_FragColor = vec4(BaseColor.rgb * v_color0.rgb, BaseColor.a);
}
// Color Compression
// increasing the floor of the signal without affecting the ceiling
BaseColor.rgb = u_floor.rgb + (vec3(1.0, 1.0, 1.0) - u_floor.rgb) * BaseColor.rgb;
// Color Power
BaseColor.r = pow(BaseColor.r, u_power.r);
BaseColor.g = pow(BaseColor.g, u_power.g);
BaseColor.b = pow(BaseColor.b, u_power.b);
// Scanline Simulation
if (u_scanline_alpha.x > 0.0f)
{
float BrightnessOffset = (u_scanline_bright_offset.x * u_scanline_alpha.x);
float BrightnessScale = (u_scanline_bright_scale.x * u_scanline_alpha.x) + (1.0 - u_scanline_alpha.x);
float ColorBrightness = 0.299 * BaseColor.r + 0.587 * BaseColor.g + 0.114 * BaseColor.b;
float ScanCoord = BaseCoord.y * u_source_dims.y * u_scanline_scale.x * 3.1415927; // PI
float ScanCoordJitter = u_scanline_jitter.x * u_jitter_amount.x * 1.618034; // PHI
float ScanSine = sin(ScanCoord + ScanCoordJitter);
float ScanlineWide = u_scanline_height.x + u_scanline_variation.x * max(1.0, u_scanline_height.x) * (1.0 - ColorBrightness);
float ScanSineScaled = pow(ScanSine * ScanSine, ScanlineWide);
float ScanBrightness = ScanSineScaled * BrightnessScale + BrightnessOffset * BrightnessScale;
BaseColor.rgb *= mix(vec3(1.0, 1.0, 1.0), vec3(ScanBrightness, ScanBrightness, ScanBrightness), u_scanline_alpha.xxx);
}
// Hum Bar Simulation
if (u_humbar_alpha.x > 0.0f)
{
float HumTimeStep = fract(u_time.x * u_humbar_hertz_rate.x);
float HumBrightness = 1.0 - fract(BaseCoord.y + HumTimeStep) * u_humbar_alpha.x;
BaseColor.rgb *= HumBrightness;
}
gl_FragColor = vec4(BaseColor.rgb * v_color0.rgb, BaseColor.a);
}

View File

@ -10,6 +10,7 @@
#include "emu.h"
#include "slider.h"
#include "chainmanager.h"
const slider_reader::string_to_enum slider_reader::TYPE_NAMES[slider_reader::TYPE_COUNT] = {
{ "intenum", uint64_t(bgfx_slider::slider_type::SLIDER_INT_ENUM) },
@ -33,7 +34,7 @@ const slider_reader::string_to_enum slider_reader::SCREEN_NAMES[slider_reader::S
{ "all", uint64_t(bgfx_slider::screen_type::SLIDER_SCREEN_TYPE_ANY) }
};
std::vector<bgfx_slider*> slider_reader::read_from_value(const Value& value, std::string prefix, running_machine& machine, uint32_t window_index, uint32_t screen_index)
std::vector<bgfx_slider*> slider_reader::read_from_value(const Value& value, std::string prefix, chain_manager& chains, uint32_t screen_index)
{
std::vector<bgfx_slider*> sliders;
@ -82,7 +83,7 @@ std::vector<bgfx_slider*> slider_reader::read_from_value(const Value& value, std
break;
}
std::string prefixed_desc = "Window " + std::to_string(window_index) + ", Screen " + std::to_string(screen_index) + ", " + description;
std::string prefixed_desc = "Window " + std::to_string(chains.window_index()) + ", Screen " + std::to_string(screen_index) + ", " + description;
if (slider_count > 1)
{
float min[3];
@ -113,7 +114,7 @@ std::vector<bgfx_slider*> slider_reader::read_from_value(const Value& value, std
desc = prefixed_desc + "Invalid";
break;
}
sliders.push_back(new bgfx_slider(machine, full_name, min[index], defaults[index], max[index], step, type, screen_type, format, desc, strings));
sliders.push_back(new bgfx_slider(chains.machine(), full_name, min[index], defaults[index], max[index], step, type, screen_type, format, desc, strings));
}
}
else
@ -121,7 +122,7 @@ std::vector<bgfx_slider*> slider_reader::read_from_value(const Value& value, std
float min = get_float(value, "min", 0.0f);
float def = get_float(value, "default", 0.0f);
float max = get_float(value, "max", 1.0f);
sliders.push_back(new bgfx_slider(machine, name + "0", min, def, max, step, type, screen_type, format, prefixed_desc, strings));
sliders.push_back(new bgfx_slider(chains.machine(), name + "0", min, def, max, step, type, screen_type, format, prefixed_desc, strings));
}
return sliders;
}
@ -132,7 +133,7 @@ bool slider_reader::get_values(const Value& value, std::string prefix, std::stri
const Value& value_array = value[name_str];
for (UINT32 i = 0; i < value_array.Size() && i < count; i++)
{
if (!READER_CHECK(value_array[i].IsNumber(), (prefix + "Entry " + std::to_string(i) + " must be a number point\n").c_str())) return false;
if (!READER_CHECK(value_array[i].IsNumber(), (prefix + "Entry " + std::to_string(i) + " must be a number\n").c_str())) return false;
values[i] = value_array[i].GetFloat();
}
return true;
@ -144,11 +145,11 @@ bool slider_reader::validate_parameters(const Value& value, std::string prefix)
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 point 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 point 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 point or array value 'max'\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 point value 'step'\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;

View File

@ -16,12 +16,12 @@
#include "statereader.h"
class bgfx_slider;
class running_machine;
class chain_manager;
class slider_reader : public state_reader
{
public:
static std::vector<bgfx_slider*> read_from_value(const Value& value, std::string prefix, running_machine& machine, uint32_t window_index, uint32_t screen_index);
static std::vector<bgfx_slider*> read_from_value(const Value& value, std::string prefix, chain_manager& chains, uint32_t screen_index);
private:
static bool get_values(const Value& value, std::string prefix, std::string name, float* values, const int count);

View File

@ -11,8 +11,8 @@
#include "emu.h"
#include <modules/lib/osdobj_common.h>
#include "chainmanager.h"
#include "targetreader.h"
#include "targetmanager.h"
#include "target.h"
const target_reader::string_to_enum target_reader::STYLE_NAMES[target_reader::STYLE_COUNT] = {
@ -21,7 +21,7 @@ const target_reader::string_to_enum target_reader::STYLE_NAMES[target_reader::ST
{ "custom", TARGET_STYLE_CUSTOM }
};
bgfx_target* target_reader::read_from_value(const Value& value, std::string prefix, target_manager& targets, osd_options& options, uint32_t screen_index)
bgfx_target* target_reader::read_from_value(const Value& value, std::string prefix, chain_manager& chains, uint32_t screen_index)
{
if (!validate_parameters(value, prefix))
{
@ -43,12 +43,12 @@ bgfx_target* target_reader::read_from_value(const Value& value, std::string pref
switch (mode)
{
case TARGET_STYLE_GUEST:
width = targets.width(TARGET_STYLE_GUEST, screen_index);
height = targets.height(TARGET_STYLE_GUEST, screen_index);
width = chains.targets().width(TARGET_STYLE_GUEST, screen_index);
height = chains.targets().height(TARGET_STYLE_GUEST, screen_index);
break;
case TARGET_STYLE_NATIVE:
width = targets.width(TARGET_STYLE_NATIVE, screen_index);
height = targets.height(TARGET_STYLE_NATIVE, screen_index);
width = chains.targets().width(TARGET_STYLE_NATIVE, screen_index);
height = chains.targets().height(TARGET_STYLE_NATIVE, screen_index);
break;
case TARGET_STYLE_CUSTOM:
if (!READER_CHECK(value.HasMember("width"), (prefix + "Target '" + target_name + "': Must have numeric value 'width'\n").c_str())) return nullptr;
@ -60,7 +60,7 @@ bgfx_target* target_reader::read_from_value(const Value& value, std::string pref
break;
}
return targets.create_target(target_name, bgfx::TextureFormat::RGBA8, width, height, mode, double_buffer, bilinear, scale, screen_index);
return chains.targets().create_target(target_name, bgfx::TextureFormat::RGBA8, width, height, mode, double_buffer, bilinear, scale, screen_index);
}
bool target_reader::validate_parameters(const Value& value, std::string prefix)

View File

@ -16,13 +16,12 @@
#include "statereader.h"
class bgfx_target;
class target_manager;
class osd_options;
class chain_manager;
class target_reader : public state_reader
{
public:
static bgfx_target* read_from_value(const Value& value, std::string prefix, target_manager& targets, osd_options& options, uint32_t screen_index);
static bgfx_target* read_from_value(const Value& value, std::string prefix, chain_manager& chains, uint32_t screen_index);
private:
static bool validate_parameters(const Value& value, std::string prefix);