Update to v080r06 release.

byuu says:

Ran out of time, so this is incomplete, but ...

Windows will disable the compositor in fullscreen mode, and enable it
when switching back to windowed mode. Should help with Vsync issues, but
of course only in fullscreen mode.

I've also merged the four settings windows back into a panel with a list
view (since I have no tab control widget.) The input settings window is
a bit incomplete, need to break assignment on window close, hide the
capture buttons on first showing, etc. Will probably try and finish that
up tonight.
This commit is contained in:
Tim Allen 2011-08-08 22:01:09 +10:00
parent 0c3f0834ab
commit 564e38ea9f
28 changed files with 653 additions and 184 deletions

View File

@ -137,6 +137,12 @@ namespace nall {
if(index >= buffersize) throw "array[] out of bounds";
return pool[index];
}
//iteration
T* begin() { return &pool[0]; }
T* end() { return &pool[buffersize]; }
const T* begin() const { return &pool[0]; }
const T* end() const { return &pool[buffersize]; }
};
template<typename T> struct has_size<array<T>> { enum { value = true }; };

View File

@ -12,7 +12,7 @@
#include <dlfcn.h>
#elif defined(PLATFORM_WIN)
#include <windows.h>
#include <nall/utf8.hpp>
#include <nall/windows/utf8.hpp>
#endif
namespace nall {

View File

@ -65,7 +65,7 @@ struct http {
inline bool send(const uint8_t *data, unsigned size) {
while(size) {
int length = ::send(serversocket, data, size, 0);
int length = ::send(serversocket, (const char*)data, size, 0);
if(length == -1) return false;
data += length;
size -= length;

View File

@ -35,8 +35,8 @@ struct png {
inline bool decode(const uint8_t *sourceData, unsigned sourceSize);
inline void transform();
inline void alphaTransform(uint32_t rgb = 0xffffff);
png();
~png();
inline png();
inline ~png();
protected:
enum class FourCC : unsigned {

View File

@ -94,14 +94,15 @@ namespace nall {
else resize(objectsize - count);
}
inline T& operator[](unsigned index) {
if(index >= objectsize) resize(index + 1);
return pool[index];
linear_vector() : pool(0), poolsize(0), objectsize(0) {
}
inline const T& operator[](unsigned index) const {
if(index >= objectsize) throw "vector[] out of bounds";
return pool[index];
linear_vector(std::initializer_list<T> list) : pool(0), poolsize(0), objectsize(0) {
for(const T *p = list.begin(); p != list.end(); ++p) append(*p);
}
~linear_vector() {
reset();
}
//copy
@ -132,17 +133,22 @@ namespace nall {
operator=(std::move(source));
}
//construction
linear_vector() : pool(0), poolsize(0), objectsize(0) {
//index
inline T& operator[](unsigned index) {
if(index >= objectsize) resize(index + 1);
return pool[index];
}
linear_vector(std::initializer_list<T> list) : pool(0), poolsize(0), objectsize(0) {
for(const T *p = list.begin(); p != list.end(); ++p) append(*p);
inline const T& operator[](unsigned index) const {
if(index >= objectsize) throw "vector[] out of bounds";
return pool[index];
}
~linear_vector() {
reset();
}
//iteration
T* begin() { return &pool[0]; }
T* end() { return &pool[objectsize]; }
const T* begin() const { return &pool[0]; }
const T* end() const { return &pool[objectsize]; }
};
//pointer_vector
@ -222,15 +228,15 @@ namespace nall {
else resize(objectsize - count);
}
inline T& operator[](unsigned index) {
if(index >= objectsize) resize(index + 1);
if(!pool[index]) pool[index] = new T;
return *pool[index];
pointer_vector() : pool(0), poolsize(0), objectsize(0) {
}
inline const T& operator[](unsigned index) const {
if(index >= objectsize || !pool[index]) throw "vector[] out of bounds";
return *pool[index];
pointer_vector(std::initializer_list<T> list) : pool(0), poolsize(0), objectsize(0) {
for(const T *p = list.begin(); p != list.end(); ++p) append(*p);
}
~pointer_vector() {
reset();
}
//copy
@ -261,17 +267,31 @@ namespace nall {
operator=(std::move(source));
}
//construction
pointer_vector() : pool(0), poolsize(0), objectsize(0) {
//index
inline T& operator[](unsigned index) {
if(index >= objectsize) resize(index + 1);
if(!pool[index]) pool[index] = new T;
return *pool[index];
}
pointer_vector(std::initializer_list<T> list) : pool(0), poolsize(0), objectsize(0) {
for(const T *p = list.begin(); p != list.end(); ++p) append(*p);
inline const T& operator[](unsigned index) const {
if(index >= objectsize || !pool[index]) throw "vector[] out of bounds";
return *pool[index];
}
~pointer_vector() {
reset();
}
//iteration
struct iterator {
bool operator!=(const iterator &source) const { return index != source.index; }
T& operator*() { return vector.operator[](index); }
iterator& operator++() { index++; return *this; }
iterator(pointer_vector &vector, unsigned index) : vector(vector), index(index) {}
private:
pointer_vector &vector;
unsigned index;
};
iterator begin() { return iterator(*this, 0); }
iterator end() { return iterator(*this, objectsize); }
};
template<typename T> struct has_size<linear_vector<T>> { enum { value = true }; };

View File

@ -0,0 +1,34 @@
#ifndef NALL_WINDOWS_COMPOSITOR_HPP
#define NALL_WINDOWS_COMPOSITOR_HPP
#ifdef _WIN32
namespace nall {
struct compositor {
static bool enable(bool status);
static void initialize();
private:
static HMODULE module;
static HRESULT (WINAPI *pDwmEnableComposition)(UINT);
};
HMODULE compositor::module = 0;
HRESULT (WINAPI *compositor::pDwmEnableComposition)(UINT) = 0;
bool compositor::enable(bool enable) {
initialize();
if(pDwmEnableComposition) return pDwmEnableComposition(enable) == S_OK;
return false;
}
void compositor::initialize() {
module = LoadLibraryA("dwmapi");
if(module) {
pDwmEnableComposition = (HRESULT (WINAPI*)(UINT))GetProcAddress(module, "DwmEnableComposition");
}
}
}
#endif
#endif

View File

@ -7,6 +7,28 @@ static gint Window_close(GtkWidget *widget, GdkEvent *event, Window *window) {
return true;
}
static gboolean Window_expose(GtkWidget *widget, GdkEvent *event, Window *window) {
cairo_t *context = gdk_cairo_create(widget->window);
Color color = window->backgroundColor();
double red = (double)color.red / 255.0;
double green = (double)color.green / 255.0;
double blue = (double)color.blue / 255.0;
double alpha = (double)color.alpha / 255.0;
if(gdk_screen_is_composited(gdk_screen_get_default())) {
cairo_set_source_rgba(context, red, green, blue, alpha);
} else {
cairo_set_source_rgb(context, red, green, blue);
}
cairo_set_operator(context, CAIRO_OPERATOR_SOURCE);
cairo_paint(context);
cairo_destroy(context);
return false;
}
static gboolean Window_configure(GtkWidget *widget, GdkEvent *event, Window *window) {
if(gtk_widget_get_realized(window->p.widget) == false) return false;
GdkWindow *gdkWindow = gtk_widget_get_window(widget);
@ -106,10 +128,10 @@ Geometry pWindow::geometry() {
void pWindow::setBackgroundColor(const Color &color) {
GdkColor gdkColor;
gdkColor.pixel = (color.red << 16) | (color.green << 8) | (color.blue << 0);
gdkColor.red = (color.red << 8) | (color.red << 0);
gdkColor.green = (color.green << 8) | (color.green << 0);
gdkColor.blue = (color.blue << 8) | (color.blue << 0);
gdkColor.pixel = (color.red << 16) | (color.green << 8) | (color.blue << 0);
gdkColor.red = (color.red << 8) | (color.red << 0);
gdkColor.green = (color.green << 8) | (color.green << 0);
gdkColor.blue = (color.blue << 8) | (color.blue << 0);
gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &gdkColor);
}
@ -190,6 +212,13 @@ void pWindow::setWidgetFont(Font &font) {
void pWindow::constructor() {
widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
if(gdk_screen_is_composited(gdk_screen_get_default())) {
gtk_widget_set_colormap(widget, gdk_screen_get_rgba_colormap(gdk_screen_get_default()));
} else {
gtk_widget_set_colormap(widget, gdk_screen_get_rgb_colormap(gdk_screen_get_default()));
}
gtk_window_set_resizable(GTK_WINDOW(widget), true);
gtk_widget_set_app_paintable(widget, true);
gtk_widget_add_events(widget, GDK_CONFIGURE);
@ -216,6 +245,7 @@ void pWindow::constructor() {
setGeometry(window.state.geometry);
g_signal_connect(G_OBJECT(widget), "delete-event", G_CALLBACK(Window_close), (gpointer)&window);
g_signal_connect(G_OBJECT(widget), "expose-event", G_CALLBACK(Window_expose), (gpointer)&window);
g_signal_connect(G_OBJECT(widget), "configure-event", G_CALLBACK(Window_configure), (gpointer)&window);
}

View File

@ -1,7 +1,7 @@
/****************************************************************************
** Meta object code from reading C++ file 'qt.moc.hpp'
**
** Created: Fri Aug 5 17:51:21 2011
** Created: Sat Aug 6 18:13:30 2011
** by: The Qt Meta Object Compiler version 62 (Qt 4.7.0)
**
** WARNING! All changes made in this file will be lost!

View File

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

View File

@ -40,6 +40,7 @@ struct Application {
Font proportionalFont;
Font proportionalFontBold;
Font monospaceFont;
Font titleFont;
bool pause;
bool quit;

View File

@ -152,17 +152,8 @@ void MainWindow::create() {
settings.append(settingsSeparator2);
settingsVideo.setText("Video Settings ...");
settings.append(settingsVideo);
settingsAudio.setText("Audio Settings ...");
settings.append(settingsAudio);
settingsInput.setText("Input Settings ...");
settings.append(settingsInput);
settingsAdvanced.setText("Advanced Settings ...");
settings.append(settingsAdvanced);
settingsConfiguration.setText("Configuration Settings ...");
settings.append(settingsConfiguration);
append(settings);
@ -337,10 +328,7 @@ void MainWindow::create() {
settingsMuteAudio.onTick = []() { config.audio.mute = mainWindow.settingsMuteAudio.checked(); };
settingsVideo.onTick = []() { videoSettings.setVisible(); };
settingsAudio.onTick = []() { audioSettings.setVisible(); };
settingsInput.onTick = []() { inputSettings.setVisible(); };
settingsAdvanced.onTick = []() { advancedSettings.setVisible(); };
settingsConfiguration.onTick = []() { settingsWindow.setVisible(); };
toolsStateSave1.onTick = []() { utility.saveState(1); };
toolsStateSave2.onTick = []() { utility.saveState(2); };

View File

@ -56,10 +56,7 @@ struct MainWindow : TopLevelWindow {
CheckItem settingsSynchronizeAudio;
CheckItem settingsMuteAudio;
Separator settingsSeparator2;
Item settingsVideo;
Item settingsAudio;
Item settingsInput;
Item settingsAdvanced;
Item settingsConfiguration;
Menu tools;
Menu toolsStateSave;

View File

@ -30,6 +30,10 @@ void Application::main(int argc, char **argv) {
monospaceFont.setFamily("Lucida Console");
monospaceFont.setSize(8);
titleFont.setFamily("Tahoma");
titleFont.setSize(14);
titleFont.setBold();
#else
proportionalFont.setFamily("Sans");
proportionalFont.setSize(8);
@ -40,6 +44,10 @@ void Application::main(int argc, char **argv) {
monospaceFont.setFamily("Liberation Mono");
monospaceFont.setSize(8);
titleFont.setFamily("Sans");
titleFont.setSize(14);
titleFont.setBold();
#endif
SNES::system.init(&interface);
@ -56,10 +64,7 @@ void Application::main(int argc, char **argv) {
doubleSlotLoader.create();
nssDipWindow.create();
aboutWindow.create();
videoSettings.create();
audioSettings.create();
inputSettings.create();
advancedSettings.create();
settingsWindow.create();
cheatEditor.create();
cheatDatabase.create();
stateManager.create();

230
bsnes/ui/settings-old/input.cpp Executable file
View File

@ -0,0 +1,230 @@
InputSettings inputSettings;
static InputMapper::AbstractInput *activeInput = 0;
void InputSettings::create() {
setTitle("Input Settings");
application.addWindow(this, "InputSettings", "160,160");
setStatusFont(application.proportionalFontBold);
setStatusVisible();
activeInput = 0;
activeMouse = 0;
portLabel.setText("Port:");
portBox.append(inputMapper.port1.name);
portBox.append(inputMapper.port2.name);
portBox.append(inputMapper.hotkeys.name);
deviceLabel.setText("Device:");
mappingList.setHeaderText("Name", "Mapping");
mappingList.setHeaderVisible(true);
clearButton.setText("Clear");
mouseXaxis.setText("Mouse X-axis");
mouseYaxis.setText("Mouse Y-axis");
mouseLeft.setText("Mouse Left");
mouseMiddle.setText("Mouse Middle");
mouseRight.setText("Mouse Right");
layout.setMargin(5);
selectionLayout.append(portLabel, 0, 0, 5);
selectionLayout.append(portBox, ~0, 0, 5);
selectionLayout.append(deviceLabel, 0, 0, 5);
selectionLayout.append(deviceBox, ~0, 0 );
layout.append(selectionLayout, 5);
layout.append(mappingList, ~0, ~0, 5);
mapLayout.append(spacer, ~0, 0 );
mapLayout.append(clearButton, 80, 0 );
layout.append(mapLayout);
axisLayout.setMargin(5);
axisLayout.append(axisSpacer, ~0, ~0 );
axisControlLayout.append(mouseXaxis, 100, 0, 5);
axisControlLayout.append(mouseYaxis, 100, 0, 5);
axisLayout.append(axisControlLayout);
buttonLayout.setMargin(5);
buttonLayout.append(buttonSpacer, ~0, ~0 );
buttonControlLayout.append(mouseLeft, 100, 0, 5);
buttonControlLayout.append(mouseMiddle, 100, 0, 5);
buttonControlLayout.append(mouseRight, 100, 0, 5);
buttonLayout.append(buttonControlLayout);
append(layout);
append(axisLayout);
append(buttonLayout);
setGeometry({ 0, 0, 480, layout.minimumGeometry().height + 250 });
axisLayout.setVisible(false);
buttonLayout.setVisible(false);
portChanged();
portBox.onChange = { &InputSettings::portChanged, this };
deviceBox.onChange = { &InputSettings::deviceChanged, this };
mappingList.onActivate = { &InputSettings::assignInput, this };
mouseXaxis.onTick = []() { inputSettings.setMapping(Scancode::encode(mouse(inputSettings.activeMouse)[Mouse::Xaxis])); };
mouseYaxis.onTick = []() { inputSettings.setMapping(Scancode::encode(mouse(inputSettings.activeMouse)[Mouse::Yaxis])); };
mouseLeft.onTick = []() { inputSettings.setMapping(Scancode::encode(mouse(inputSettings.activeMouse)[Mouse::Button0])); };
mouseMiddle.onTick = []() { inputSettings.setMapping(Scancode::encode(mouse(inputSettings.activeMouse)[Mouse::Button1])); };
mouseRight.onTick = []() { inputSettings.setMapping(Scancode::encode(mouse(inputSettings.activeMouse)[Mouse::Button2])); };
clearButton.onTick = { &InputSettings::clearInput, this };
onClose = []() { inputSettings.endAssignment(); };
}
void InputSettings::portChanged() {
deviceBox.reset();
InputMapper::ControllerPort &port = (
portBox.selection() == 0 ? (InputMapper::ControllerPort&)inputMapper.port1 :
portBox.selection() == 1 ? (InputMapper::ControllerPort&)inputMapper.port2 :
/*portBox.selection() == 2*/ (InputMapper::ControllerPort&)inputMapper.hotkeys
);
for(unsigned i = 0; i < port.size(); i++) deviceBox.append(port[i]->name);
deviceChanged();
}
void InputSettings::deviceChanged() {
mappingList.reset();
InputMapper::ControllerPort &port = (
portBox.selection() == 0 ? (InputMapper::ControllerPort&)inputMapper.port1 :
portBox.selection() == 1 ? (InputMapper::ControllerPort&)inputMapper.port2 :
/*portBox.selection() == 2*/ (InputMapper::ControllerPort&)inputMapper.hotkeys
);
InputMapper::Controller &controller = (InputMapper::Controller&)*port[deviceBox.selection()];
for(unsigned i = 0; i < controller.size(); i++) {
string mapping = controller[i]->mapping;
if(mapping == "") mapping = "None";
mappingList.append(controller[i]->name, mapping);
}
mappingList.autoSizeColumns();
}
void InputSettings::mappingChanged() {
InputMapper::ControllerPort &port = (
portBox.selection() == 0 ? (InputMapper::ControllerPort&)inputMapper.port1 :
portBox.selection() == 1 ? (InputMapper::ControllerPort&)inputMapper.port2 :
/*portBox.selection() == 2*/ (InputMapper::ControllerPort&)inputMapper.hotkeys
);
InputMapper::Controller &controller = (InputMapper::Controller&)*port[deviceBox.selection()];
for(unsigned i = 0; i < controller.size(); i++) {
string mapping = controller[i]->mapping;
if(mapping == "") mapping = "None";
mappingList.modify(i, controller[i]->name, mapping);
}
mappingList.autoSizeColumns();
}
void InputSettings::assignInput() {
if(mappingList.selected() == false) return;
InputMapper::ControllerPort &port = (
portBox.selection() == 0 ? (InputMapper::ControllerPort&)inputMapper.port1 :
portBox.selection() == 1 ? (InputMapper::ControllerPort&)inputMapper.port2 :
/*portBox.selection() == 2*/ (InputMapper::ControllerPort&)inputMapper.hotkeys
);
InputMapper::Controller &controller = (InputMapper::Controller&)*port[deviceBox.selection()];
portBox.setEnabled(false);
deviceBox.setEnabled(false);
mappingList.setEnabled(false);
inputMapper.poll(); //flush any pending keypresses
activeInput = controller[mappingList.selection()];
setStatusText({ "Set assignment for [", activeInput->name, "] ..." });
if(dynamic_cast<InputMapper::AnalogInput*>(activeInput)) {
axisLayout.setVisible(true);
buttonLayout.setVisible(false);
} else {
axisLayout.setVisible(false);
buttonLayout.setVisible(true);
}
}
void InputSettings::clearInput() {
if(mappingList.selected() == false) return;
InputMapper::ControllerPort &port = (
portBox.selection() == 0 ? (InputMapper::ControllerPort&)inputMapper.port1 :
portBox.selection() == 1 ? (InputMapper::ControllerPort&)inputMapper.port2 :
/*portBox.selection() == 2*/ (InputMapper::ControllerPort&)inputMapper.hotkeys
);
InputMapper::Controller &controller = (InputMapper::Controller&)*port[deviceBox.selection()];
controller[mappingList.selection()]->mapping = "";
inputMapper.bind();
endAssignment();
}
void InputSettings::setMapping(const string &mapping) {
activeInput->mapping = mapping;
inputMapper.bind();
endAssignment();
}
void InputSettings::endAssignment() {
activeInput = 0;
portBox.setEnabled(true);
deviceBox.setEnabled(true);
mappingList.setEnabled(true);
setStatusText("");
axisLayout.setVisible(false);
buttonLayout.setVisible(false);
mappingChanged();
mappingList.setFocused();
}
void InputSettings::inputEvent(uint16_t scancode, int16_t value) {
if(activeInput == 0) return; //not remapping any keys right now?
string mapping = Scancode::encode(scancode);
if(auto position = strpos(mapping, "::Escape")) return setMapping("");
if(dynamic_cast<InputMapper::AnalogInput*>(activeInput)) {
} else if(dynamic_cast<InputMapper::DigitalInput*>(activeInput)) {
if(Keyboard::isAnyKey(scancode) && value) {
setMapping(mapping);
} else if(Mouse::isAnyButton(scancode) && value) {
activeMouse = Mouse::numberDecode(scancode);
} else if(Joypad::isAnyHat(scancode) && value) {
if(value == Joypad::HatUp) setMapping({ mapping, ".Up" });
else if(value == Joypad::HatDown) setMapping({ mapping, ".Down" });
else if(value == Joypad::HatLeft) setMapping({ mapping, ".Left" });
else if(value == Joypad::HatRight) setMapping({ mapping, ".Right" });
} else if(Joypad::isAnyAxis(scancode)) {
if(joypadsCalibrated == false) return calibrateJoypads();
unsigned joypadNumber = Joypad::numberDecode(scancode);
unsigned axisNumber = Joypad::axisDecode(scancode);
int16_t calibration = joypadCalibration[joypadNumber][axisNumber];
if(calibration > -12288 && calibration < +12288 && value < -24576) setMapping({ mapping, ".Lo" });
else if(calibration > -12288 && calibration < +12288 && value > +24576) setMapping({ mapping, ".Hi" });
else if(calibration <= -12288 && value >= +12288) setMapping({ mapping, ".Hi" });
else if(calibration >= +12288 && value <= -12288) setMapping({ mapping, ".Lo" });
} else if(Joypad::isAnyButton(scancode) && value) {
setMapping(mapping);
}
}
}
void InputSettings::calibrateJoypads() {
if(joypadsCalibrating == true) return;
joypadsCalibrating = true;
MessageWindow::information(*this,
"Analog joypads must be calibrated prior to use.\n\n"
"Please move all analog axes, and press all analog buttons.\n"
"Please do this for every controller you wish to use.\n"
"Once finished, please let go of all axes and buttons, and press OK."
);
inputMapper.poll();
for(unsigned j = 0; j < Joypad::Count &&j<2; j++) {
for(unsigned a = 0; a < Joypad::Axes; a++) {
joypadCalibration[j][a] = inputMapper.value(joypad(j).axis(a));
}
}
joypadsCalibrating = false;
joypadsCalibrated = true;
}
InputSettings::InputSettings() {
joypadsCalibrated = false;
joypadsCalibrating = false;
}

46
bsnes/ui/settings-old/input.hpp Executable file
View File

@ -0,0 +1,46 @@
struct InputSettings : TopLevelWindow {
VerticalLayout layout;
HorizontalLayout selectionLayout;
Label portLabel;
ComboBox portBox;
Label deviceLabel;
ComboBox deviceBox;
ListView mappingList;
HorizontalLayout mapLayout;
Label spacer;
Button clearButton;
VerticalLayout axisLayout;
Widget axisSpacer;
HorizontalLayout axisControlLayout;
Button mouseXaxis;
Button mouseYaxis;
VerticalLayout buttonLayout;
Widget buttonSpacer;
HorizontalLayout buttonControlLayout;
Button mouseLeft;
Button mouseMiddle;
Button mouseRight;
void inputEvent(uint16_t scancode, int16_t value);
void calibrateJoypads();
void create();
InputSettings();
private:
bool joypadsCalibrated;
bool joypadsCalibrating;
int16_t joypadCalibration[Joypad::Count][Joypad::Axes];
unsigned activeMouse;
void portChanged();
void deviceChanged();
void mappingChanged();
void setMapping(const string &mapping);
void assignInput();
void clearInput();
void endAssignment();
};
extern InputSettings inputSettings;

View File

@ -0,0 +1 @@
#include "../base.hpp"

View File

View File

@ -1,25 +1,30 @@
AdvancedSettings advancedSettings;
void AdvancedSettings::create() {
setTitle("Advanced Settings");
application.addWindow(this, "AdvancedSettings", "160,160");
title.setText("Advanced Settings");
title.setFont(application.titleFont);
driverSelectionLabel.setText("Driver Selection :.");
driverSelectionLabel.setText("Driver Selection:");
driverSelectionLabel.setFont(application.proportionalFontBold);
videoDriverLabel.setText("Video:");
audioDriverLabel.setText("Audio:");
inputDriverLabel.setText("Input:");
focusPolicyLabel.setText("Focus Policy :.");
focusPolicyLabel.setText("Focus Policy:");
focusPolicyLabel.setFont(application.proportionalFontBold);
focusPolicyPause.setText("Pause emulator when inactive");
focusPolicyIgnore.setText("Ignore input when inactive");
focusPolicyAllow.setText("Always allow input");
focusPolicyPause.setText("Pause emulator");
focusPolicyIgnore.setText("Ignore input");
focusPolicyAllow.setText("Allow input");
RadioBox::group(focusPolicyPause, focusPolicyIgnore, focusPolicyAllow);
if(config.settings.focusPolicy == 0) focusPolicyPause.setChecked();
if(config.settings.focusPolicy == 1) focusPolicyIgnore.setChecked();
if(config.settings.focusPolicy == 2) focusPolicyAllow.setChecked();
layout.setMargin(5);
panelLayout.setMargin(5);
panelLayout.append(panel, SettingsWindow::PanelWidth, ~0, 5);
panelLayout.append(layout);
layout.append(title, ~0, 0, 5);
layout.append(driverSelectionLabel, ~0, 0 );
driverLayout.append(videoDriverLabel, 0, 0, 5);
driverLayout.append(videoDriverBox, ~0, 0, 5);
@ -33,8 +38,8 @@ void AdvancedSettings::create() {
focusPolicyLayout.append(focusPolicyIgnore, ~0, 0, 5);
focusPolicyLayout.append(focusPolicyAllow, ~0, 0);
layout.append(focusPolicyLayout);
append(layout);
setGeometry({ 0, 0, 640, layout.minimumGeometry().height });
layout.append(spacer, ~0, ~0);
lstring list;
@ -56,22 +61,22 @@ void AdvancedSettings::create() {
if(list[i] == config.input.driver) inputDriverBox.setSelection(i);
}
videoDriverBox.onChange = []() {
videoDriverBox.onChange = [this]() {
lstring list;
list.split(";", video.driver_list());
config.video.driver = list[advancedSettings.videoDriverBox.selection()];
config.video.driver = list[videoDriverBox.selection()];
};
audioDriverBox.onChange = []() {
audioDriverBox.onChange = [this]() {
lstring list;
list.split(";", audio.driver_list());
config.audio.driver = list[advancedSettings.audioDriverBox.selection()];
config.audio.driver = list[audioDriverBox.selection()];
};
inputDriverBox.onChange = []() {
inputDriverBox.onChange = [this]() {
lstring list;
list.split(";", input.driver_list());
config.input.driver = list[advancedSettings.inputDriverBox.selection()];
config.input.driver = list[inputDriverBox.selection()];
};
focusPolicyPause.onTick = []() { config.settings.focusPolicy = 0; };

View File

@ -1,19 +1,28 @@
struct AdvancedSettings : TopLevelWindow {
struct AdvancedSettings {
HorizontalLayout panelLayout;
Widget panel;
VerticalLayout layout;
Label title;
Label driverSelectionLabel;
HorizontalLayout driverLayout;
Label videoDriverLabel;
ComboBox videoDriverBox;
Label audioDriverLabel;
ComboBox audioDriverBox;
Label inputDriverLabel;
ComboBox inputDriverBox;
Label focusPolicyLabel;
HorizontalLayout focusPolicyLayout;
RadioBox focusPolicyPause;
RadioBox focusPolicyIgnore;
RadioBox focusPolicyAllow;
Widget spacer;
void create();
};

View File

@ -1,36 +1,42 @@
AudioSettings audioSettings;
void AudioSettings::create() {
setTitle("Audio Settings");
application.addWindow(this, "AudioSettings", "160,160");
title.setText("Audio Settings");
title.setFont(application.titleFont);
volumeLabel.setText("Volume:");
volumeSlider.setLength(201);
frequencyLabel.setText("Frequency:");
frequencySlider.setLength(2001);
layout.setMargin(5);
volumeLayout.append(volumeLabel, 70, 0);
volumeLayout.append(volumeValue, 60, 0);
volumeLayout.append(volumeSlider, ~0, 0);
layout.append(volumeLayout );
frequencyLayout.append(frequencyLabel, 70, 0);
frequencyLayout.append(frequencyValue, 60, 0);
panelLayout.setMargin(5);
panelLayout.append(panel, SettingsWindow::PanelWidth, ~0, 5);
panelLayout.append(layout);
layout.append(title, ~0, 0, 5);
volumeLayout.append(volumeLabel, 70, 0);
volumeLayout.append(volumeValue, 60, 0);
volumeLayout.append(volumeSlider, ~0, 0);
layout.append(volumeLayout);
frequencyLayout.append(frequencyLabel, 70, 0);
frequencyLayout.append(frequencyValue, 60, 0);
frequencyLayout.append(frequencySlider, ~0, 0);
layout.append(frequencyLayout);
append(layout);
setGeometry({ 0, 0, 480, layout.minimumGeometry().height });
volumeSlider.onChange = []() {
config.audio.volume = audioSettings.volumeSlider.position();
layout.append(spacer, ~0, ~0);
volumeSlider.onChange = [this]() {
config.audio.volume = volumeSlider.position();
audio.set(Audio::Volume, config.audio.volume);
audioSettings.volumeValue.setText({ config.audio.volume, "%" });
volumeValue.setText({ config.audio.volume, "%" });
};
frequencySlider.onChange = []() {
config.audio.inputFrequency = audioSettings.frequencySlider.position() + 31000;
frequencySlider.onChange = [this]() {
config.audio.inputFrequency = frequencySlider.position() + 31000;
audio.set(Audio::ResampleRatio, (double)config.audio.inputFrequency / (double)config.audio.outputFrequency);
audioSettings.frequencyValue.setText({ config.audio.inputFrequency, "hz" });
frequencyValue.setText({ config.audio.inputFrequency, "hz" });
};
volumeSlider.setPosition(config.audio.volume);

View File

@ -1,14 +1,21 @@
struct AudioSettings : TopLevelWindow {
struct AudioSettings {
HorizontalLayout panelLayout;
Widget panel;
VerticalLayout layout;
Label title;
HorizontalLayout volumeLayout;
Label volumeLabel;
Label volumeValue;
HorizontalSlider volumeSlider;
HorizontalLayout frequencyLayout;
Label frequencyLabel;
Label frequencyValue;
HorizontalSlider frequencySlider;
Widget spacer;
void create();
};

View File

@ -2,74 +2,56 @@ InputSettings inputSettings;
static InputMapper::AbstractInput *activeInput = 0;
void InputSettings::create() {
setTitle("Input Settings");
application.addWindow(this, "InputSettings", "160,160");
setStatusFont(application.proportionalFontBold);
setStatusVisible();
title.setText("Input Settings");
title.setFont(application.titleFont);
activeInput = 0;
activeMouse = 0;
joypadsCalibrated = false;
joypadsCalibrating = false;
portLabel.setText("Port:");
portBox.append(inputMapper.port1.name);
portBox.append(inputMapper.port2.name);
portBox.append(inputMapper.hotkeys.name);
deviceLabel.setText("Device:");
clearButton.setText("Clear");
mappingList.setHeaderText("Name", "Mapping");
mappingList.setHeaderVisible(true);
clearButton.setText("Clear");
mouseXaxis.setText("Mouse X-axis");
mouseYaxis.setText("Mouse Y-axis");
mouseLeft.setText("Mouse Left");
mouseMiddle.setText("Mouse Middle");
mouseRight.setText("Mouse Right");
layout.setMargin(5);
selectionLayout.append(portLabel, 0, 0, 5);
selectionLayout.append(portBox, ~0, 0, 5);
selectionLayout.append(deviceLabel, 0, 0, 5);
selectionLayout.append(deviceBox, ~0, 0 );
layout.append(selectionLayout, 5);
layout.append(mappingList, ~0, ~0, 5);
mapLayout.append(spacer, ~0, 0 );
mapLayout.append(clearButton, 80, 0 );
layout.append(mapLayout);
panelLayout.setMargin(5);
panelLayout.append(panel, SettingsWindow::PanelWidth, ~0, 5);
panelLayout.append(layout);
axisLayout.setMargin(5);
axisLayout.append(axisSpacer, ~0, ~0 );
axisControlLayout.append(mouseXaxis, 100, 0, 5);
axisControlLayout.append(mouseYaxis, 100, 0, 5);
axisLayout.append(axisControlLayout);
layout.append(title, ~0, 0, 5);
buttonLayout.setMargin(5);
buttonLayout.append(buttonSpacer, ~0, ~0 );
buttonControlLayout.append(mouseLeft, 100, 0, 5);
buttonControlLayout.append(mouseMiddle, 100, 0, 5);
buttonControlLayout.append(mouseRight, 100, 0, 5);
buttonLayout.append(buttonControlLayout);
selectionLayout.append(portLabel, 0, 0, 5);
selectionLayout.append(portBox, ~0, 0, 5);
selectionLayout.append(deviceLabel, 0, 0, 5);
selectionLayout.append(deviceBox, ~0, 0);
layout.append(selectionLayout, 5);
append(layout);
append(axisLayout);
append(buttonLayout);
setGeometry({ 0, 0, 480, layout.minimumGeometry().height + 250 });
layout.append(mappingList, ~0, ~0, 5);
axisLayout.setVisible(false);
buttonLayout.setVisible(false);
controlLayout.append(customButton1, 100, 0, 5);
controlLayout.append(customButton2, 100, 0, 5);
controlLayout.append(customButton3, 100, 0, 5);
controlLayout.append(spacer, ~0, 0);
controlLayout.append(clearButton, 100, 0);
layout.append(controlLayout);
portChanged();
portBox.onChange = { &InputSettings::portChanged, this };
deviceBox.onChange = { &InputSettings::deviceChanged, this };
mappingList.onActivate = { &InputSettings::assignInput, this };
mouseXaxis.onTick = []() { inputSettings.setMapping(Scancode::encode(mouse(inputSettings.activeMouse)[Mouse::Xaxis])); };
mouseYaxis.onTick = []() { inputSettings.setMapping(Scancode::encode(mouse(inputSettings.activeMouse)[Mouse::Yaxis])); };
mouseLeft.onTick = []() { inputSettings.setMapping(Scancode::encode(mouse(inputSettings.activeMouse)[Mouse::Button0])); };
mouseMiddle.onTick = []() { inputSettings.setMapping(Scancode::encode(mouse(inputSettings.activeMouse)[Mouse::Button1])); };
mouseRight.onTick = []() { inputSettings.setMapping(Scancode::encode(mouse(inputSettings.activeMouse)[Mouse::Button2])); };
customButton1.onTick = [this]() { manualInput(1); };
customButton2.onTick = [this]() { manualInput(2); };
customButton3.onTick = [this]() { manualInput(3); };
clearButton.onTick = [this]() { manualInput(0); };
clearButton.onTick = { &InputSettings::clearInput, this };
onClose = []() { inputSettings.endAssignment(); };
portChanged();
}
void InputSettings::portChanged() {
@ -126,18 +108,57 @@ void InputSettings::assignInput() {
);
InputMapper::Controller &controller = (InputMapper::Controller&)*port[deviceBox.selection()];
settingsWindow.panel.setEnabled(false);
portBox.setEnabled(false);
deviceBox.setEnabled(false);
mappingList.setEnabled(false);
inputMapper.poll(); //flush any pending keypresses
activeInput = controller[mappingList.selection()];
setStatusText({ "Set assignment for [", activeInput->name, "] ..." });
settingsWindow.setStatusText({ "Set assignment for [", activeInput->name, "] ..." });
if(dynamic_cast<InputMapper::AnalogInput*>(activeInput)) {
axisLayout.setVisible(true);
buttonLayout.setVisible(false);
customButton1.setText("Mouse X-axis");
customButton2.setText("Mouse Y-axis");
customButton3.setText("Mouse Z-axis");
} else {
axisLayout.setVisible(false);
buttonLayout.setVisible(true);
customButton1.setText("Mouse Left");
customButton2.setText("Mouse Middle");
customButton3.setText("Mouse Right");
}
customButton1.setVisible(true);
customButton2.setVisible(true);
customButton3.setVisible(true);
}
void InputSettings::manualInput(unsigned button) {
if(activeInput == 0 && button == 0) return clearInput();
if(activeInput == 0) return;
switch(button) {
case 0:
setMapping("");
break;
case 1:
if(dynamic_cast<InputMapper::AnalogInput*>(activeInput)) {
setMapping(Scancode::encode(mouse(inputSettings.activeMouse)[Mouse::Xaxis]));
} else {
setMapping(Scancode::encode(mouse(inputSettings.activeMouse)[Mouse::Button0]));
}
break;
case 2:
if(dynamic_cast<InputMapper::AnalogInput*>(activeInput)) {
setMapping(Scancode::encode(mouse(inputSettings.activeMouse)[Mouse::Yaxis]));
} else {
setMapping(Scancode::encode(mouse(inputSettings.activeMouse)[Mouse::Button1]));
}
break;
case 3:
if(dynamic_cast<InputMapper::AnalogInput*>(activeInput)) {
setMapping(Scancode::encode(mouse(inputSettings.activeMouse)[Mouse::Zaxis]));
} else {
setMapping(Scancode::encode(mouse(inputSettings.activeMouse)[Mouse::Button2]));
}
break;
}
}
@ -163,12 +184,14 @@ void InputSettings::setMapping(const string &mapping) {
void InputSettings::endAssignment() {
activeInput = 0;
settingsWindow.panel.setEnabled(true);
portBox.setEnabled(true);
deviceBox.setEnabled(true);
mappingList.setEnabled(true);
setStatusText("");
axisLayout.setVisible(false);
buttonLayout.setVisible(false);
settingsWindow.setStatusText("");
customButton1.setVisible(false);
customButton2.setVisible(false);
customButton3.setVisible(false);
mappingChanged();
mappingList.setFocused();
}
@ -208,7 +231,7 @@ void InputSettings::inputEvent(uint16_t scancode, int16_t value) {
void InputSettings::calibrateJoypads() {
if(joypadsCalibrating == true) return;
joypadsCalibrating = true;
MessageWindow::information(*this,
MessageWindow::information(settingsWindow,
"Analog joypads must be calibrated prior to use.\n\n"
"Please move all analog axes, and press all analog buttons.\n"
"Please do this for every controller you wish to use.\n"
@ -223,8 +246,3 @@ void InputSettings::calibrateJoypads() {
joypadsCalibrating = false;
joypadsCalibrated = true;
}
InputSettings::InputSettings() {
joypadsCalibrated = false;
joypadsCalibrating = false;
}

View File

@ -1,34 +1,28 @@
struct InputSettings : TopLevelWindow {
struct InputSettings {
HorizontalLayout panelLayout;
Widget panel;
VerticalLayout layout;
Label title;
HorizontalLayout selectionLayout;
Label portLabel;
ComboBox portBox;
Label deviceLabel;
ComboBox deviceBox;
ListView mappingList;
HorizontalLayout mapLayout;
Label spacer;
HorizontalLayout controlLayout;
Button customButton1;
Button customButton2;
Button customButton3;
Widget spacer;
Button clearButton;
VerticalLayout axisLayout;
Widget axisSpacer;
HorizontalLayout axisControlLayout;
Button mouseXaxis;
Button mouseYaxis;
VerticalLayout buttonLayout;
Widget buttonSpacer;
HorizontalLayout buttonControlLayout;
Button mouseLeft;
Button mouseMiddle;
Button mouseRight;
void inputEvent(uint16_t scancode, int16_t value);
void calibrateJoypads();
void create();
InputSettings();
private:
//
bool joypadsCalibrated;
bool joypadsCalibrating;
int16_t joypadCalibration[Joypad::Count][Joypad::Axes];
@ -37,10 +31,13 @@ private:
void portChanged();
void deviceChanged();
void mappingChanged();
void setMapping(const string &mapping);
void assignInput();
void manualInput(unsigned button);
void clearInput();
void setMapping(const string &mapping);
void endAssignment();
void inputEvent(uint16_t scancode, int16_t value);
void calibrateJoypads();
};
extern InputSettings inputSettings;

View File

@ -3,3 +3,43 @@
#include "audio.cpp"
#include "input.cpp"
#include "advanced.cpp"
SettingsWindow settingsWindow;
void SettingsWindow::create() {
setTitle("Configuration Settings");
application.addWindow(this, "SettingsWindow", "160,160");
setStatusFont(application.proportionalFontBold);
setStatusVisible();
panel.append("Video");
panel.append("Audio");
panel.append("Input");
panel.append("Advanced");
layout.setMargin(5);
layout.append(panel, PanelWidth, ~0, 5);
append(layout);
setGeometry({ 0, 0, 640, 360 });
videoSettings.create();
audioSettings.create();
inputSettings.create();
advancedSettings.create();
append(videoSettings.panelLayout);
append(audioSettings.panelLayout);
append(inputSettings.panelLayout);
append(advancedSettings.panelLayout);
panel.onChange = { &SettingsWindow::change, this };
panel.setSelection(0);
change();
}
void SettingsWindow::change() {
unsigned selection = panel.selection();
videoSettings.panelLayout.setVisible(selection == 0);
audioSettings.panelLayout.setVisible(selection == 1);
inputSettings.panelLayout.setVisible(selection == 2);
advancedSettings.panelLayout.setVisible(selection == 3);
}

View File

@ -1,3 +1,15 @@
struct SettingsWindow : TopLevelWindow {
enum : unsigned { PanelWidth = 120 };
HorizontalLayout layout;
ListView panel;
void create();
void change();
};
extern SettingsWindow settingsWindow;
#include "video.hpp"
#include "audio.hpp"
#include "input.hpp"

View File

@ -1,10 +1,10 @@
VideoSettings videoSettings;
void VideoSettings::create() {
setTitle("Video Settings");
application.addWindow(this, "VideoSettings", "160,160");
title.setText("Video Settings");
title.setFont(application.titleFont);
colorAdjustmentLabel.setText("Color Adjustment :.");
colorAdjustmentLabel.setText("Color Adjustment:");
colorAdjustmentLabel.setFont(application.proportionalFontBold);
brightnessLabel.setText("Brightness:");
brightnessSlider.setLength(201);
@ -13,14 +13,19 @@ void VideoSettings::create() {
gammaLabel.setText("Gamma:");
gammaSlider.setLength(201);
gammaRampCheck.setText("Enable NTSC gamma ramp simulation");
fullscreenLabel.setText("Fullscreen :.");
fullscreenLabel.setText("Fullscreen:");
fullscreenLabel.setFont(application.proportionalFontBold);
fullscreenCenter.setText("Center");
fullscreenScale.setText("Scale");
fullscreenStretch.setText("Stretch");
RadioBox::group(fullscreenCenter, fullscreenScale, fullscreenStretch);
layout.setMargin(5);
panelLayout.setMargin(5);
panelLayout.append(panel, SettingsWindow::PanelWidth, ~0, 5);
panelLayout.append(layout);
layout.append(title, ~0, 0, 5);
layout.append(colorAdjustmentLabel, ~0, 0 );
brightnessLayout.append(brightnessLabel, 80, 0 );
brightnessLayout.append(brightnessValue, 50, 0 );
@ -40,8 +45,8 @@ void VideoSettings::create() {
fullscreenLayout.append(fullscreenScale, ~0, 0, 5);
fullscreenLayout.append(fullscreenStretch, ~0, 0 );
layout.append(fullscreenLayout);
append(layout);
setGeometry({ 0, 0, 480, layout.minimumGeometry().height });
layout.append(spacer, ~0, ~0);
brightnessSlider.setPosition(config.video.brightness);
brightnessValue.setText({ config.video.brightness, "%" });
@ -66,6 +71,7 @@ void VideoSettings::create() {
fullscreenCenter.onTick = []() { config.video.fullscreenScale = 0; };
fullscreenScale.onTick = []() { config.video.fullscreenScale = 1; };
fullscreenStretch.onTick = []() { config.video.fullscreenScale = 2; };
}
void VideoSettings::adjust() {

View File

@ -1,5 +1,9 @@
struct VideoSettings : TopLevelWindow {
struct VideoSettings {
HorizontalLayout panelLayout;
Widget panel;
VerticalLayout layout;
Label title;
Label colorAdjustmentLabel;
Label brightnessLabel;
@ -25,6 +29,8 @@ struct VideoSettings : TopLevelWindow {
RadioBox fullscreenScale;
RadioBox fullscreenStretch;
Widget spacer;
void create();
void adjust();
};

View File

@ -131,6 +131,11 @@ void Utility::setFullScreen(bool fullScreen) {
mainWindow.viewport.setGeometry({ viewportX, viewportY, viewportWidth, viewportHeight });
}
#if defined(PLATFORM_WINDOWS)
//compositor interferes with Vsync; disable in fullscreen mode where it is not needed
compositor::enable(fullscreen == false);
#endif
}
void Utility::setFilter() {