Update to v070r03 release.

byuu says:

- fixed a bug in xml_element::parse() with <![CDATA[...]]> tags
- merged FragmentShader and and VertexShader into Shader, which is an
  XML file that contains all relevant data
- updated Qt port to reflect the above
- added support for pixel shaders to the phoenix port
- updated all pixel shaders to use the new format
- ruby won't crash if you give an HLSL driver a GLSL shader or vice
  versa, but it will still crash on bad programs
- phoenix::Viewport has its own window class, that paints a black brush
  background

[The XML shader] format is subject to change, more specifically I may
change the <source> tag from HLSL shaders.
In the long-long term, it'd be nice to extend the format to allow
multiple shaders to be chained together and to encode base64 texture
files.
But for now, this is good enough.
This commit is contained in:
Tim Allen 2010-09-29 10:05:36 +10:00
parent 73fdbf893f
commit f28d70f9e6
25 changed files with 200 additions and 156 deletions

View File

@ -17,31 +17,44 @@ namespace nall {
struct data_t { struct data_t {
R (*callback)(const data_t&, P...); R (*callback)(const data_t&, P...);
union {
R (*callback_global)(P...); R (*callback_global)(P...);
struct { struct {
R (derived::*callback_member)(P...); R (derived::*callback_member)(P...);
void *object; void *callback_object;
};
}; };
std::function<R (P...)> callback_lambda;
} data; } data;
static R callback_global(const data_t &data, P... p) { static R callback_global(const data_t &data, P... p) {
return data.callback_global(p...); return data.callback_global(std::forward<P>(p)...);
} }
template<typename C> template<typename C>
static R callback_member(const data_t &data, P... p) { static R callback_member(const data_t &data, P... p) {
return (((C*)data.object)->*((R (C::*&)(P...))data.callback_member))(p...); return (((C*)data.callback_object)->*((R (C::*&)(P...))data.callback_member))(std::forward<P>(p)...);
}
static R callback_lambda(const data_t &data, P... p) {
return data.callback_lambda(std::forward<P>(p)...);
} }
public: public:
R operator()(P... p) const { return data.callback(data, p...); } R operator()(P... p) const { return data.callback(data, std::forward<P>(p)...); }
operator bool() const { return data.callback; } operator bool() const { return data.callback; }
void reset() { data.callback = 0; } void reset() { data.callback = 0; }
function& operator=(const function &source) { memcpy(&data, &source.data, sizeof(data_t)); return *this; } function& operator=(const function &source) {
function(const function &source) { operator=(source); } data.callback = source.data.callback;
data.callback_global = source.data.callback_global;
data.callback_member = source.data.callback_member;
data.callback_object = source.data.callback_object;
data.callback_lambda = source.data.callback_lambda;
return *this;
}
function(const function &source) {
operator=(source);
}
//no pointer //no pointer
function() { function() {
@ -66,7 +79,7 @@ namespace nall {
static_assert(sizeof data.callback_member >= sizeof callback, "callback_member is too small"); static_assert(sizeof data.callback_member >= sizeof callback, "callback_member is too small");
data.callback = &callback_member<C>; data.callback = &callback_member<C>;
(R (C::*&)(P...))data.callback_member = callback; (R (C::*&)(P...))data.callback_member = callback;
data.object = object; data.callback_object = object;
} }
//const member function pointer //const member function pointer
@ -75,15 +88,15 @@ namespace nall {
static_assert(sizeof data.callback_member >= sizeof callback, "callback_member is too small"); static_assert(sizeof data.callback_member >= sizeof callback, "callback_member is too small");
data.callback = &callback_member<C>; data.callback = &callback_member<C>;
(R (C::*&)(P...))data.callback_member = (R (C::*&)(P...))callback; (R (C::*&)(P...))data.callback_member = (R (C::*&)(P...))callback;
data.object = object; data.callback_object = object;
} }
//lambda function pointer //lambda function pointer
template<typename T> template<typename T>
function(T callback) { function(const T &callback) {
static_assert(std::is_same<R, typename std::result_of<T(P...)>::type>::value, "lambda mismatch"); static_assert(std::is_same<R, typename std::result_of<T(P...)>::type>::value, "lambda mismatch");
data.callback = &callback_global; data.callback = &callback_lambda;
data.callback_global = (R (*)(P...))callback; data.callback_lambda = callback;
} }
}; };
} }

View File

@ -79,7 +79,7 @@ inline string xml_element::parse() const {
data << cdata; data << cdata;
offset += strlen(cdata); offset += strlen(cdata);
source += offset + 3; source += 9 + offset + 3;
continue; continue;
} else { } else {
return ""; return "";

View File

@ -1,6 +1,6 @@
void Viewport::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height) { void Viewport::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height) {
widget->window = CreateWindow( widget->window = CreateWindow(
L"phoenix_window", L"", L"phoenix_viewport", L"",
WS_CHILD | WS_VISIBLE | WS_DISABLED, WS_CHILD | WS_VISIBLE | WS_DISABLED,
x, y, width, height, x, y, width, height,
parent.widget->window, (HMENU)object->id, GetModuleHandle(0), 0 parent.widget->window, (HMENU)object->id, GetModuleHandle(0), 0
@ -11,3 +11,7 @@ void Viewport::create(Window &parent, unsigned x, unsigned y, unsigned width, un
uintptr_t Viewport::handle() { uintptr_t Viewport::handle() {
return (uintptr_t)widget->window; return (uintptr_t)widget->window;
} }
static LRESULT CALLBACK Viewport_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
return DefWindowProc(hwnd, msg, wparam, lparam);
}

View File

@ -440,6 +440,18 @@ OS::OS() {
wc.lpszMenuName = 0; wc.lpszMenuName = 0;
wc.style = CS_HREDRAW | CS_VREDRAW; wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc); RegisterClass(&wc);
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hInstance = GetModuleHandle(0);
wc.lpfnWndProc = Viewport_windowProc;
wc.lpszClassName = L"phoenix_viewport";
wc.lpszMenuName = 0;
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc);
} }
} }

View File

@ -14,6 +14,7 @@ InputInterface input;
const char *Video::Handle = "Handle"; const char *Video::Handle = "Handle";
const char *Video::Synchronize = "Synchronize"; const char *Video::Synchronize = "Synchronize";
const char *Video::Filter = "Filter"; const char *Video::Filter = "Filter";
const char *Video::Shader = "Shader";
const char *Video::FragmentShader = "FragmentShader"; const char *Video::FragmentShader = "FragmentShader";
const char *Video::VertexShader = "VertexShader"; const char *Video::VertexShader = "VertexShader";

View File

@ -3,6 +3,7 @@ public:
static const char *Handle; static const char *Handle;
static const char *Synchronize; static const char *Synchronize;
static const char *Filter; static const char *Filter;
static const char *Shader;
static const char *FragmentShader; static const char *FragmentShader;
static const char *VertexShader; static const char *VertexShader;

View File

@ -24,7 +24,7 @@ public:
LPDIRECT3DTEXTURE9 texture; LPDIRECT3DTEXTURE9 texture;
LPDIRECT3DSURFACE9 surface; LPDIRECT3DSURFACE9 surface;
LPD3DXEFFECT effect; LPD3DXEFFECT effect;
string shaderSource; string shader_source_xml;
bool lost; bool lost;
unsigned iwidth, iheight; unsigned iwidth, iheight;
@ -64,7 +64,7 @@ public:
if(name == Video::Handle) return true; if(name == Video::Handle) return true;
if(name == Video::Synchronize) return true; if(name == Video::Synchronize) return true;
if(name == Video::Filter) return true; if(name == Video::Filter) return true;
if(name == Video::FragmentShader) return true; if(name == Video::Shader) return true;
return false; return false;
} }
@ -92,8 +92,8 @@ public:
return true; return true;
} }
if(name == Video::FragmentShader) { if(name == Video::Shader) {
set_fragment_shader(any_cast<const char*>(value)); set_shader(any_cast<const char*>(value));
return true; return true;
} }
@ -268,7 +268,7 @@ public:
//failure to do so causes scaling issues on some video drivers. //failure to do so causes scaling issues on some video drivers.
if(state.width != rd.right || state.height != rd.bottom) { if(state.width != rd.right || state.height != rd.bottom) {
init(); init();
set_fragment_shader(shaderSource); set_shader(shader_source_xml);
return; return;
} }
@ -327,7 +327,7 @@ public:
if(device->Present(0, 0, 0, 0) == D3DERR_DEVICELOST) lost = true; if(device->Present(0, 0, 0, 0) == D3DERR_DEVICELOST) lost = true;
} }
void set_fragment_shader(const char *source) { void set_shader(const char *source) {
if(!caps.shader) return; if(!caps.shader) return;
if(effect) { if(effect) {
@ -336,11 +336,27 @@ public:
} }
if(!source || !*source) { if(!source || !*source) {
shaderSource = ""; shader_source_xml = "";
return; return;
} }
shader_source_xml = source;
shaderSource = source; bool is_hlsl = false;
string shader_source;
xml_element document = xml_parse(shader_source_xml);
foreach(head, document.element) {
if(head.name == "shader") {
foreach(attribute, head.attribute) {
if(attribute.name == "language" && attribute.content == "HLSL") is_hlsl = true;
}
foreach(element, head.element) {
if(element.name == "source") {
if(is_hlsl) shader_source = element.parse();
}
}
}
}
if(shader_source == "") return;
HMODULE d3dx; HMODULE d3dx;
for(unsigned i = 0; i < 256; i++) { for(unsigned i = 0; i < 256; i++) {
@ -356,7 +372,7 @@ public:
TextureProc textureProc = (TextureProc)GetProcAddress(d3dx, "D3DXCreateTextureFromFileA"); TextureProc textureProc = (TextureProc)GetProcAddress(d3dx, "D3DXCreateTextureFromFileA");
LPD3DXBUFFER pBufferErrors = NULL; LPD3DXBUFFER pBufferErrors = NULL;
effectProc(device, shaderSource, lstrlenA(source), NULL, NULL, 0, NULL, &effect, &pBufferErrors); effectProc(device, shader_source, lstrlenA(shader_source), NULL, NULL, 0, NULL, &effect, &pBufferErrors);
D3DXHANDLE hTech; D3DXHANDLE hTech;
effect->FindNextValidTechnique(NULL, &hTech); effect->FindNextValidTechnique(NULL, &hTech);

View File

@ -2,7 +2,7 @@
video.glx video.glx
author: byuu author: byuu
license: public domain license: public domain
last updated: 2010-01-05 last updated: 2010-09-28
Design notes: Design notes:
SGI's GLX is the X11/Xlib interface to OpenGL. SGI's GLX is the X11/Xlib interface to OpenGL.
@ -62,6 +62,7 @@ public:
if(name == Video::Handle) return true; if(name == Video::Handle) return true;
if(name == Video::Synchronize) return true; if(name == Video::Synchronize) return true;
if(name == Video::Filter) return true; if(name == Video::Filter) return true;
if(name == Video::Shader) return true;
if(name == Video::FragmentShader) return true; if(name == Video::FragmentShader) return true;
if(name == Video::VertexShader) return true; if(name == Video::VertexShader) return true;
return false; return false;
@ -93,6 +94,11 @@ public:
return true; return true;
} }
if(name == Video::Shader) {
OpenGL::set_shader(any_cast<const char*>(value));
return true;
}
if(name == Video::FragmentShader) { if(name == Video::FragmentShader) {
OpenGL::set_fragment_shader(any_cast<const char*>(value)); OpenGL::set_fragment_shader(any_cast<const char*>(value));
return true; return true;

View File

@ -122,7 +122,7 @@ public:
} }
} }
void set_fragment_shader(const char *source) { void set_shader(const char *source) {
if(!shader_support) return; if(!shader_support) return;
if(fragmentshader) { if(fragmentshader) {
@ -131,19 +131,6 @@ public:
fragmentshader = 0; fragmentshader = 0;
} }
if(source) {
fragmentshader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentshader, 1, &source, 0);
glCompileShader(fragmentshader);
glAttachShader(glprogram, fragmentshader);
}
glLinkProgram(glprogram);
}
void set_vertex_shader(const char *source) {
if(!shader_support) return;
if(vertexshader) { if(vertexshader) {
glDetachShader(glprogram, vertexshader); glDetachShader(glprogram, vertexshader);
glDeleteShader(vertexshader); glDeleteShader(vertexshader);
@ -151,15 +138,49 @@ public:
} }
if(source) { if(source) {
bool is_glsl = false;
string fragment_source;
string vertex_source;
xml_element document = xml_parse(source);
foreach(head, document.element) {
if(head.name == "shader") {
foreach(attribute, head.attribute) {
if(attribute.name == "language" && attribute.content == "GLSL") is_glsl = true;
}
foreach(element, head.element) {
if(element.name == "fragment") {
fragment_source = element.parse();
} else if(element.name == "vertex") {
vertex_source = element.parse();
}
}
}
}
if(is_glsl) {
if(fragment_source != "") set_fragment_shader(fragment_source);
if(vertex_source != "") set_vertex_shader(vertex_source);
}
}
glLinkProgram(glprogram);
}
void set_fragment_shader(const char *source) {
fragmentshader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentshader, 1, &source, 0);
glCompileShader(fragmentshader);
glAttachShader(glprogram, fragmentshader);
}
void set_vertex_shader(const char *source) {
vertexshader = glCreateShader(GL_VERTEX_SHADER); vertexshader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexshader, 1, &source, 0); glShaderSource(vertexshader, 1, &source, 0);
glCompileShader(vertexshader); glCompileShader(vertexshader);
glAttachShader(glprogram, vertexshader); glAttachShader(glprogram, vertexshader);
} }
glLinkProgram(glprogram);
}
void init() { void init() {
//disable unused features //disable unused features
glDisable(GL_ALPHA_TEST); glDisable(GL_ALPHA_TEST);

View File

@ -29,8 +29,7 @@ public:
if(name == Video::Handle) return true; if(name == Video::Handle) return true;
if(name == Video::Synchronize) return true; if(name == Video::Synchronize) return true;
if(name == Video::Filter) return true; if(name == Video::Filter) return true;
if(name == Video::FragmentShader) return true; if(name == Video::Shader) return true;
if(name == Video::VertexShader) return true;
return false; return false;
} }
@ -59,13 +58,8 @@ public:
return true; return true;
} }
if(name == Video::FragmentShader) { if(name == Video::Shader) {
OpenGL::set_fragment_shader(any_cast<const char*>(value)); OpenGL::set_shader(any_cast<const char*>(value));
return true;
}
if(name == Video::VertexShader) {
OpenGL::set_vertex_shader(any_cast<const char*>(value));
return true; return true;
} }

View File

@ -1,7 +1,7 @@
namespace SNES { namespace SNES {
namespace Info { namespace Info {
static const char Name[] = "bsnes"; static const char Name[] = "bsnes";
static const char Version[] = "070.02"; static const char Version[] = "070.03";
static const unsigned SerializerVersion = 13; static const unsigned SerializerVersion = 13;
} }
} }

View File

@ -17,8 +17,9 @@ void Configuration::create() {
attach(video.driver = "", "video.driver"); attach(video.driver = "", "video.driver");
attach(video.synchronize = false, "video.synchronize"); attach(video.synchronize = false, "video.synchronize");
attach(video.region = 0, "video.region");
attach(video.smooth = true, "video.smooth"); attach(video.smooth = true, "video.smooth");
attach(video.shader = "", "video.shader");
attach(video.region = 0, "video.region");
attach(video.scale = 2, "video.scale"); attach(video.scale = 2, "video.scale");
attach(video.aspectRatioCorrection = true, "video.aspectRatioCorrection"); attach(video.aspectRatioCorrection = true, "video.aspectRatioCorrection");
attach(video.contrast = 100, "video.contrast"); attach(video.contrast = 100, "video.contrast");

View File

@ -11,8 +11,9 @@ struct Configuration : public configuration {
struct Video { struct Video {
string driver; string driver;
bool synchronize; bool synchronize;
bool region;
bool smooth; bool smooth;
string shader;
bool region;
unsigned scale; unsigned scale;
bool aspectRatioCorrection; bool aspectRatioCorrection;
unsigned contrast; unsigned contrast;

View File

@ -48,6 +48,9 @@ void FileBrowser::fileOpen(FileBrowser::Mode requestedMode, function<void (strin
filters.append(".gbc"); filters.append(".gbc");
filters.append(".sgb"); filters.append(".sgb");
} }
case Mode::Shader: {
filters.append(".shader");
}
} }
setVisible(false); setVisible(false);

View File

@ -4,7 +4,7 @@ struct FileBrowser : Window {
Button upButton; Button upButton;
ListBox contentsBox; ListBox contentsBox;
enum class Mode : unsigned { Cartridge, Satellaview, SufamiTurbo, GameBoy } mode; enum class Mode : unsigned { Cartridge, Satellaview, SufamiTurbo, GameBoy, Shader } mode;
void fileOpen(Mode mode, function<void (string)> callback); void fileOpen(Mode mode, function<void (string)> callback);
void create(); void create();

View File

@ -62,6 +62,7 @@ void Application::main(int argc, char **argv) {
video.driver("None"); video.driver("None");
video.init(); video.init();
} }
utility.setShader();
audio.driver(config.audio.driver); audio.driver(config.audio.driver);
audio.set(Audio::Handle, mainWindow.viewport.handle()); audio.set(Audio::Handle, mainWindow.viewport.handle());

View File

@ -5,7 +5,7 @@ void VideoSettings::create() {
Window::create(0, 0, 256, 256, "Video Settings"); Window::create(0, 0, 256, 256, "Video Settings");
setDefaultFont(application.proportionalFont); setDefaultFont(application.proportionalFont);
unsigned x = 5, y = 5; unsigned x = 5, y = 5, height = Style::TextBoxHeight;
colorAdjustmentLabel.create(*this, x, y, 430, Style::LabelHeight, "Color Adjustment :."); y += Style::LabelHeight + 5; colorAdjustmentLabel.create(*this, x, y, 430, Style::LabelHeight, "Color Adjustment :."); y += Style::LabelHeight + 5;
colorAdjustmentLabel.setFont(application.proportionalFontBold); colorAdjustmentLabel.setFont(application.proportionalFontBold);
@ -24,6 +24,15 @@ void VideoSettings::create() {
gammaRampCheck.create (*this, x, y, 430, Style::CheckBoxHeight, "Enable NTSC gamma ramp simulation"); y += Style::CheckBoxHeight + 5; gammaRampCheck.create (*this, x, y, 430, Style::CheckBoxHeight, "Enable NTSC gamma ramp simulation"); y += Style::CheckBoxHeight + 5;
shaderLabel.create(*this, x, y, 340, Style::LabelHeight, "Pixel Shader :."); y += Style::LabelHeight + 5;
shaderLabel.setFont(application.proportionalFontBold);
shaderPath.create(*this, x, y, 430 - height - height - 10, height);
shaderPath.setEditable(false);
shaderPath.setText(config.video.shader);
shaderClear.create(*this, x + 430 - height - height - 5, y, height, height, "");
shaderSelect.create(*this, x + 430 - height, y, height, height, "..."); y += height + 5;
setGeometry(160, 160, 440, y); setGeometry(160, 160, 440, y);
contrastSlider.setPosition(config.video.contrast); contrastSlider.setPosition(config.video.contrast);
@ -33,6 +42,20 @@ void VideoSettings::create() {
contrastSlider.onChange = brightnessSlider.onChange = gammaSlider.onChange = gammaRampCheck.onTick = contrastSlider.onChange = brightnessSlider.onChange = gammaSlider.onChange = gammaRampCheck.onTick =
{ &VideoSettings::adjust, this }; { &VideoSettings::adjust, this };
shaderClear.onTick = []() {
config.video.shader = "";
videoSettings.shaderPath.setText(config.video.shader);
utility.setShader();
};
shaderSelect.onTick = []() {
fileBrowser.fileOpen(FileBrowser::Mode::Shader, [](string filename) {
config.video.shader = filename;
videoSettings.shaderPath.setText(config.video.shader);
utility.setShader();
});
};
} }
void VideoSettings::adjust() { void VideoSettings::adjust() {

View File

@ -10,6 +10,10 @@ struct VideoSettings : Window {
Label gammaValue; Label gammaValue;
HorizontalSlider gammaSlider; HorizontalSlider gammaSlider;
CheckBox gammaRampCheck; CheckBox gammaRampCheck;
Label shaderLabel;
TextBox shaderPath;
Button shaderClear;
Button shaderSelect;
void create(); void create();
void adjust(); void adjust();

View File

@ -51,6 +51,12 @@ void Utility::setScale(unsigned scale) {
mainWindow.setGeometry(128, 128, width, height); mainWindow.setGeometry(128, 128, width, height);
} }
void Utility::setShader() {
string data;
data.readfile(config.video.shader);
video.set(Video::Shader, (const char*)data);
}
void Utility::cartridgeLoaded() { void Utility::cartridgeLoaded() {
SNES::system.power(); SNES::system.power();
cheatEditor.load(cartridge.baseName); cheatEditor.load(cartridge.baseName);

View File

@ -5,6 +5,7 @@ struct Utility : property<Utility> {
void showMessage(const char *text); void showMessage(const char *text);
void setScale(unsigned scale = 0); void setScale(unsigned scale = 0);
void setShader();
void cartridgeLoaded(); void cartridgeLoaded();
void cartridgeUnloaded(); void cartridgeUnloaded();

View File

@ -60,8 +60,7 @@ Configuration::Configuration() {
attach(path.bsx = "", "path.bsx"); attach(path.bsx = "", "path.bsx");
attach(path.st = "", "path.st"); attach(path.st = "", "path.st");
attach(path.sgb = "", "path.sgb"); attach(path.sgb = "", "path.sgb");
attach(path.fragmentShader = "", "path.fragmentShader"); attach(path.shader = "", "path.shader");
attach(path.vertexShader = "", "path.vertexShader");
attach(path.current.folder = "", "path.current.folder"); attach(path.current.folder = "", "path.current.folder");
attach(path.current.movie = "", "path.current.movie"); attach(path.current.movie = "", "path.current.movie");

View File

@ -30,7 +30,7 @@ public:
string startup; //startup path string startup; //startup path
string rom, save, state, patch, cheat, data; string rom, save, state, patch, cheat, data;
string bsx, st, sgb; string bsx, st, sgb;
string fragmentShader, vertexShader; string shader;
struct Current { struct Current {
string folder, movie, shader, cartridge; string folder, movie, shader, cartridge;

View File

@ -138,29 +138,14 @@ VideoSettingsWindow::VideoSettingsWindow() {
pixelShaderLayout = new QGridLayout; pixelShaderLayout = new QGridLayout;
layout->addLayout(pixelShaderLayout); layout->addLayout(pixelShaderLayout);
fragmentShaderLabel = new QLabel("Fragment:"); shaderValue = new QLineEdit;
pixelShaderLayout->addWidget(fragmentShaderLabel, 0, 0); pixelShaderLayout->addWidget(shaderValue, 0, 0);
fragmentShaderValue = new QLineEdit; shaderSelect = new QPushButton("Select ...");
pixelShaderLayout->addWidget(fragmentShaderValue, 0, 1); pixelShaderLayout->addWidget(shaderSelect, 0, 1);
fragmentShaderSelect = new QPushButton("Select ..."); shaderDefault = new QPushButton("Default");
pixelShaderLayout->addWidget(fragmentShaderSelect, 0, 2); pixelShaderLayout->addWidget(shaderDefault, 0, 2);
fragmentShaderDefault = new QPushButton("Default");
pixelShaderLayout->addWidget(fragmentShaderDefault, 0, 3);
vertexShaderLabel = new QLabel("Vertex:");
pixelShaderLayout->addWidget(vertexShaderLabel, 1, 0);
vertexShaderValue = new QLineEdit;
pixelShaderLayout->addWidget(vertexShaderValue, 1, 1);
vertexShaderSelect = new QPushButton("Select ...");
pixelShaderLayout->addWidget(vertexShaderSelect, 1, 2);
vertexShaderDefault = new QPushButton("Default");
pixelShaderLayout->addWidget(vertexShaderDefault, 1, 3);
connect(autoHideFullscreenMenu, SIGNAL(stateChanged(int)), this, SLOT(autoHideFullscreenMenuToggle())); connect(autoHideFullscreenMenu, SIGNAL(stateChanged(int)), this, SLOT(autoHideFullscreenMenuToggle()));
connect(contrastSlider, SIGNAL(valueChanged(int)), this, SLOT(contrastAdjust(int))); connect(contrastSlider, SIGNAL(valueChanged(int)), this, SLOT(contrastAdjust(int)));
@ -172,31 +157,18 @@ VideoSettingsWindow::VideoSettingsWindow() {
connect(cropTopSlider, SIGNAL(valueChanged(int)), this, SLOT(cropTopAdjust(int))); connect(cropTopSlider, SIGNAL(valueChanged(int)), this, SLOT(cropTopAdjust(int)));
connect(cropRightSlider, SIGNAL(valueChanged(int)), this, SLOT(cropRightAdjust(int))); connect(cropRightSlider, SIGNAL(valueChanged(int)), this, SLOT(cropRightAdjust(int)));
connect(cropBottomSlider, SIGNAL(valueChanged(int)), this, SLOT(cropBottomAdjust(int))); connect(cropBottomSlider, SIGNAL(valueChanged(int)), this, SLOT(cropBottomAdjust(int)));
connect(fragmentShaderSelect, SIGNAL(released()), this, SLOT(selectFragmentShader())); connect(shaderSelect, SIGNAL(released()), this, SLOT(selectShader()));
connect(fragmentShaderDefault, SIGNAL(released()), this, SLOT(defaultFragmentShader())); connect(shaderDefault, SIGNAL(released()), this, SLOT(defaultShader()));
connect(vertexShaderSelect, SIGNAL(released()), this, SLOT(selectVertexShader()));
connect(vertexShaderDefault, SIGNAL(released()), this, SLOT(defaultVertexShader()));
syncUi(); syncUi();
} }
void VideoSettingsWindow::synchronizePixelShaderSettings() { void VideoSettingsWindow::synchronizePixelShaderSettings() {
if(!video.cap(Video::FragmentShader) && !video.cap(Video::VertexShader)) { if(video.cap(Video::Shader) == false) {
pixelShaderLabel->hide(); pixelShaderLabel->hide();
} shaderValue->hide();
shaderSelect->hide();
if(!video.cap(Video::FragmentShader)) { shaderDefault->hide();
fragmentShaderLabel->hide();
fragmentShaderValue->hide();
fragmentShaderSelect->hide();
fragmentShaderDefault->hide();
}
if(!video.cap(Video::VertexShader)) {
vertexShaderLabel->hide();
vertexShaderValue->hide();
vertexShaderSelect->hide();
vertexShaderDefault->hide();
} }
} }
@ -239,8 +211,7 @@ void VideoSettingsWindow::syncUi() {
cropBottomValue->setText(string() << n << "%"); cropBottomValue->setText(string() << n << "%");
cropBottomSlider->setSliderPosition(n); cropBottomSlider->setSliderPosition(n);
fragmentShaderValue->setText(config().path.fragmentShader); shaderValue->setText(config().path.shader);
vertexShaderValue->setText(config().path.vertexShader);
} }
void VideoSettingsWindow::autoHideFullscreenMenuToggle() { void VideoSettingsWindow::autoHideFullscreenMenuToggle() {
@ -301,41 +272,21 @@ void VideoSettingsWindow::cropBottomAdjust(int state) {
syncUi(); syncUi();
} }
void VideoSettingsWindow::selectFragmentShader() { void VideoSettingsWindow::selectShader() {
fileBrowser->onChange.reset(); fileBrowser->onChange.reset();
fileBrowser->onActivate = { &VideoSettingsWindow::assignFragmentShader, this }; fileBrowser->onActivate = { &VideoSettingsWindow::assignShader, this };
fileBrowser->onAccept = { &VideoSettingsWindow::assignFragmentShader, this }; fileBrowser->onAccept = { &VideoSettingsWindow::assignShader, this };
fileBrowser->setWindowTitle("Select Fragment Shader"); fileBrowser->setWindowTitle("Select Pixel Shader");
fileBrowser->setPath(config().path.current.shader); fileBrowser->setPath(config().path.current.shader);
fileBrowser->setNameFilters("All files (*)"); fileBrowser->setNameFilters("Shader files (*.shader)");
fileBrowser->chooseFile(); fileBrowser->chooseFile();
} }
void VideoSettingsWindow::selectVertexShader() { void VideoSettingsWindow::defaultShader() { assignShader(""); }
fileBrowser->onChange.reset();
fileBrowser->onActivate = { &VideoSettingsWindow::assignVertexShader, this };
fileBrowser->onAccept = { &VideoSettingsWindow::assignVertexShader, this };
fileBrowser->setWindowTitle("Select Vertex Shader");
fileBrowser->setPath(config().path.current.shader);
fileBrowser->setNameFilters("All files (*)");
fileBrowser->chooseFile();
}
void VideoSettingsWindow::defaultFragmentShader() { assignFragmentShader(""); } void VideoSettingsWindow::assignShader(const string &filename) {
void VideoSettingsWindow::defaultVertexShader() { assignVertexShader(""); }
void VideoSettingsWindow::assignFragmentShader(const string &filename) {
if(filename == "" || QDir(filename).exists() == false) { if(filename == "" || QDir(filename).exists() == false) {
config().path.fragmentShader = filename; config().path.shader = filename;
if(filename != "") config().path.current.shader = dir(filename);
syncUi();
utility.updatePixelShader();
}
}
void VideoSettingsWindow::assignVertexShader(const string &filename) {
if(filename == "" || QDir(filename).exists() == false) {
config().path.vertexShader = filename;
if(filename != "") config().path.current.shader = dir(filename); if(filename != "") config().path.current.shader = dir(filename);
syncUi(); syncUi();
utility.updatePixelShader(); utility.updatePixelShader();

View File

@ -37,14 +37,9 @@ public:
QSlider *cropBottomSlider; QSlider *cropBottomSlider;
QLabel *pixelShaderLabel; QLabel *pixelShaderLabel;
QGridLayout *pixelShaderLayout; QGridLayout *pixelShaderLayout;
QLabel *fragmentShaderLabel; QLineEdit *shaderValue;
QLineEdit *fragmentShaderValue; QPushButton *shaderSelect;
QPushButton *fragmentShaderSelect; QPushButton *shaderDefault;
QPushButton *fragmentShaderDefault;
QLabel *vertexShaderLabel;
QLineEdit *vertexShaderValue;
QPushButton *vertexShaderSelect;
QPushButton *vertexShaderDefault;
void synchronizePixelShaderSettings(); void synchronizePixelShaderSettings();
void syncUi(); void syncUi();
@ -61,14 +56,11 @@ private slots:
void cropTopAdjust(int); void cropTopAdjust(int);
void cropRightAdjust(int); void cropRightAdjust(int);
void cropBottomAdjust(int); void cropBottomAdjust(int);
void selectFragmentShader(); void selectShader();
void selectVertexShader(); void defaultShader();
void defaultFragmentShader();
void defaultVertexShader();
private: private:
void assignFragmentShader(const string &filename); void assignShader(const string &filename);
void assignVertexShader(const string &filename);
}; };
extern VideoSettingsWindow *videoSettingsWindow; extern VideoSettingsWindow *videoSettingsWindow;

View File

@ -73,16 +73,10 @@ void Utility::updateColorFilter() {
void Utility::updatePixelShader() { void Utility::updatePixelShader() {
string filedata; string filedata;
if(filedata.readfile(config().path.fragmentShader)) { if(filedata.readfile(config().path.shader)) {
video.set(Video::FragmentShader, (const char*)filedata); video.set(Video::Shader, (const char*)filedata);
} else { } else {
video.set(Video::FragmentShader, (const char*)0); video.set(Video::Shader, (const char*)0);
}
if(filedata.readfile(config().path.vertexShader)) {
video.set(Video::VertexShader, (const char*)filedata);
} else {
video.set(Video::VertexShader, (const char*)0);
} }
} }