Update to v070r07 release.

byuu says:

- added menu options to select controller port devices, they do actually
  work too
- however, input mapping can't map analog axes yet, and the mouse can't
  be captured yet, so it's of little use
- added clear and clear all buttons to the input mapper window, mainly
  because there was no reason not to (escape clears active input too)
- going to be adding a "special" button in the future that lets you map
  mouse axes and buttons
- fixed phoenix/Qt port, both the video rendering and Window::focused()
  commands work now

The way I've implemented mouse mapping has always been screwy. So the
special button is going to pop open another window. For digital mapping,
it'll let you choose a mouse button, and for analog mapping, it'll let
you choose an axis. May add in some manual joypad assignment stuff in
there for analog joypad buttons, those things are impossible to
auto-detect.
This commit is contained in:
Tim Allen 2010-10-03 19:20:42 +11:00
parent 96e9333ec2
commit 440a59c879
25 changed files with 201 additions and 98 deletions

View File

@ -36,6 +36,7 @@ namespace nall {
public:
operator bool() const { return callback; }
R operator()(P... p) const { return (*callback)(std::forward<P>(p)...); }
void reset() { if(callback) { delete callback; callback = 0; } }
function& operator=(const function &source) {
if(this != &source) {

View File

@ -37,12 +37,30 @@ namespace phoenix {
#include "viewport.cpp"
#include "messagewindow.cpp"
OS &os = OS::handle();
Window Window::None;
OS& OS::handle() {
static OS os;
return os;
void OS::initialize() {
static bool initialized = false;
if(initialized == true) return;
initialized = true;
int argc = 1;
char *argv[2];
argv[0] = new char[8];
argv[1] = 0;
strcpy(argv[0], "phoenix");
char **argvp = argv;
gtk_init(&argc, &argvp);
gtk_rc_parse_string(
"style \"phoenix-gtk\"\n"
"{\n"
" GtkComboBox::appears-as-list = 1\n"
" GtkTreeView::vertical-separator = 0\n"
"}\n"
"class \"GtkComboBox\" style \"phoenix-gtk\"\n"
"class \"GtkTreeView\" style \"phoenix-gtk\"\n"
);
}
bool OS::pending() {
@ -167,25 +185,4 @@ string OS::fileSave(Window &parent, const char *filter, const char *path) {
return name;
}
OS::OS() {
os = new OS::Data;
int argc = 1;
char *argv[2];
argv[0] = new char[8];
argv[1] = 0;
strcpy(argv[0], "phoenix");
char **argvp = argv;
gtk_init(&argc, &argvp);
gtk_rc_parse_string(
"style \"phoenix-gtk\"\n"
"{\n"
" GtkComboBox::appears-as-list = 1\n"
" GtkTreeView::vertical-separator = 0\n"
"}\n"
"class \"GtkComboBox\" style \"phoenix-gtk\"\n"
"class \"GtkTreeView\" style \"phoenix-gtk\"\n"
);
}
}

View File

@ -87,7 +87,6 @@ struct Widget : Object {
};
struct Window : Widget {
static Window None;
nall::function<bool ()> onClose;
void create(unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
bool focused();
@ -104,6 +103,7 @@ struct Window : Widget {
//private:
struct Data;
Data *window;
static Window None;
};
struct Button : Widget {
@ -237,23 +237,17 @@ struct MessageWindow : Object {
};
struct OS : Object {
bool pending();
void run();
void main();
void quit();
unsigned desktopWidth();
unsigned desktopHeight();
nall::string folderSelect(Window &parent, const char *path = "");
nall::string fileOpen(Window &parent, const char *filter, const char *path = "");
nall::string fileSave(Window &parent, const char *filter, const char *path = "");
static bool pending();
static void run();
static void main();
static void quit();
static unsigned desktopWidth();
static unsigned desktopHeight();
static nall::string folderSelect(Window &parent, const char *path = "");
static nall::string fileOpen(Window &parent, const char *filter, const char *path = "");
static nall::string fileSave(Window &parent, const char *filter, const char *path = "");
//private:
static OS& handle();
struct Data;
Data *os;
private:
OS();
static void initialize();
};
extern OS &os;
}

View File

@ -46,13 +46,11 @@ struct ListBox::Data {
signed selection;
};
struct OS::Data {
};
void Object::unused() {
}
Object::Object() {
OS::initialize();
object = new Object::Data;
object->locked = false;
}

View File

@ -2,5 +2,6 @@ void Object::unused() {
}
Object::Object() {
OS::initialize();
object = new Object::Data(*this);
}

View File

@ -27,12 +27,22 @@ namespace phoenix {
#include "viewport.cpp"
#include "messagewindow.cpp"
OS &os = OS::handle();
OS::Data *OS::os = 0;
Window Window::None;
OS& OS::handle() {
static OS os;
return os;
void OS::initialize() {
static bool initialized = false;
if(initialized == true) return;
initialized = true;
os = new OS::Data;
static int argc = 1;
static char *argv[2];
argv[0] = new char[8];
argv[1] = 0;
strcpy(argv[0], "phoenix");
char **argvp = argv;
os->application = new QApplication(argc, argvp);
}
bool OS::pending() {
@ -110,15 +120,4 @@ string OS::fileSave(Window &parent, const char *filter, const char *path) {
return filename.toUtf8().constData();
}
OS::OS() {
os = new OS::Data(*this);
static int argc = 1;
static char *argv[2];
argv[0] = new char[8];
argv[1] = 0;
strcpy(argv[0], "phoenix");
char **argvp = argv;
os->application = new QApplication(argc, argvp);
}
}

View File

@ -112,8 +112,8 @@ struct Widget : Object {
void setVisible(bool visible = true);
bool enabled();
void setEnabled(bool enabled = true);
bool focused();
void setFocused();
virtual bool focused();
virtual void setFocused();
Widget();
//private:
struct Data;
@ -121,7 +121,6 @@ struct Widget : Object {
};
struct Window : Widget {
static Window None;
nall::function<bool ()> onClose;
void create(unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
void setGeometry(unsigned x, unsigned y, unsigned width, unsigned height);
@ -132,10 +131,12 @@ struct Window : Widget {
void setStatusText(const char *text);
void setMenuVisible(bool visible = true);
void setStatusVisible(bool visible = true);
bool focused();
Window();
//private:
struct Data;
Data *window;
static Window None;
};
struct Button : Widget {
@ -306,23 +307,19 @@ struct MessageWindow : Object {
};
struct OS : Object {
bool pending();
void run();
void main();
void quit();
unsigned desktopWidth();
unsigned desktopHeight();
nall::string folderSelect(Window &parent, const char *path = "");
nall::string fileOpen(Window &parent, const char *filter, const char *path = "");
nall::string fileSave(Window &parent, const char *filter, const char *path = "");
static bool pending();
static void run();
static void main();
static void quit();
static unsigned desktopWidth();
static unsigned desktopHeight();
static nall::string folderSelect(Window &parent, const char *path = "");
static nall::string fileOpen(Window &parent, const char *filter, const char *path = "");
static nall::string fileSave(Window &parent, const char *filter, const char *path = "");
//private:
static OS& handle();
struct Data;
Data *os;
private:
OS();
static Data *os;
static void initialize();
};
extern OS &os;
}

View File

@ -1,7 +1,7 @@
/****************************************************************************
** Meta object code from reading C++ file 'qt.moc.hpp'
**
** Created: Mon Sep 27 04:00:47 2010
** Created: Sat Oct 2 21:32:41 2010
** by: The Qt Meta Object Compiler version 62 (Qt 4.6.2)
**
** WARNING! All changes made in this file will be lost!

View File

@ -298,11 +298,7 @@ struct OS::Data : public QObject {
Q_OBJECT
public:
OS &self;
QApplication *application;
Data(OS &self) : self(self) {
}
public slots:
};

View File

@ -1,6 +1,8 @@
void Viewport::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height) {
viewport->setParent(parent.window->container);
viewport->setGeometry(x, y, width, height);
viewport->setAttribute(Qt::WA_PaintOnScreen, true);
viewport->setStyleSheet("background: #000000");
viewport->show();
}

View File

@ -62,6 +62,10 @@ void Window::setStatusVisible(bool visible) {
else window->statusBar->hide();
}
bool Window::focused() {
return window->isActiveWindow() && !window->isMinimized();
}
Window::Window() {
window = new Window::Data(*this);
window->defaultFont = 0;

View File

@ -92,7 +92,6 @@ struct Widget : Object {
};
struct Window : Widget {
static Window None;
nall::function<bool ()> onClose;
void create(unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
void setDefaultFont(Font &font);
@ -107,7 +106,7 @@ struct Window : Widget {
//private:
struct Data;
Data *window;
//private:
static Window None;
void resize(unsigned width, unsigned height);
};

View File

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

View File

@ -92,6 +92,9 @@ void System::init(Interface *interface_) {
video.init();
audio.init();
input.init();
input.port_set_device(0, config.controller_port1);
input.port_set_device(1, config.controller_port2);
}
void System::term() {
@ -173,8 +176,6 @@ void System::power() {
scheduler.init();
input.port_set_device(0, config.controller_port1);
input.port_set_device(1, config.controller_port2);
input.update();
//video.update();
}

View File

@ -6,7 +6,7 @@ ui_objects += $(if $(call streq,$(platform),win),resource)
ifeq ($(platform),x)
phoenix_compile = $(call compile,-DPHOENIX_GTK `pkg-config --cflags gtk+-2.0`)
link += `pkg-config --libs gtk+-2.0`
# flags += -DPHOENIX_QT `pkg-config --cflags QtCore QtGui`
# phoenix_compile = $(call compile,-DPHOENIX_QT `pkg-config --cflags QtCore QtGui`)
# link += `pkg-config --libs QtCore QtGui`
ruby := video.glx video.xv video.sdl

View File

@ -39,4 +39,7 @@ void Configuration::create() {
attach(settings.focusPolicy = 0, "settings.focusPolicy");
attach(settings.useNativeDialogs = false, "settings.useNativeDialogs");
attach(controller.port1 = 1, "controller.port1");
attach(controller.port2 = 1, "controller.port2");
}

View File

@ -41,6 +41,11 @@ struct Configuration : public configuration {
bool useNativeDialogs;
} settings;
struct Controller {
unsigned port1;
unsigned port2;
} controller;
void load();
void save();
void create();

View File

@ -91,7 +91,7 @@ void FileBrowser::setFolder(const char *pathname) {
}
void FileBrowser::folderBrowse() {
string pathname = os.folderSelect(*this, folder);
string pathname = OS::folderSelect(*this, folder);
if(pathname != "") setFolder(pathname);
}

View File

@ -20,9 +20,29 @@ void MainWindow::create() {
systemReset.create(system, "Reset");
systemSeparator2.create(system);
systemPort1.create(system, "Controller Port 1");
systemPort1.setEnabled(false);
systemPort1None.create(systemPort1, "None");
systemPort1Gamepad.create(systemPort1None, "Gamepad");
systemPort1Multitap.create(systemPort1None, "Multitap");
systemPort1Mouse.create(systemPort1None, "Mouse");
if(config.controller.port1 == 0) systemPort1None.setChecked();
if(config.controller.port1 == 1) systemPort1Gamepad.setChecked();
if(config.controller.port1 == 2) systemPort1Multitap.setChecked();
if(config.controller.port1 == 3) systemPort1Mouse.setChecked();
systemPort2.create(system, "Controller Port 2");
systemPort2.setEnabled(false);
systemPort2None.create(systemPort2, "None");
systemPort2Gamepad.create(systemPort2None, "Gamepad");
systemPort2Multitap.create(systemPort2None, "Multitap");
systemPort2Mouse.create(systemPort2None, "Mouse");
systemPort2SuperScope.create(systemPort2None, "Super Scope");
systemPort2Justifiers.create(systemPort2None, "Justifiers");
if(config.controller.port2 == 0) systemPort2None.setChecked();
if(config.controller.port2 == 1) systemPort2Gamepad.setChecked();
if(config.controller.port2 == 2) systemPort2Multitap.setChecked();
if(config.controller.port2 == 3) systemPort2Mouse.setChecked();
if(config.controller.port2 == 4) systemPort2SuperScope.setChecked();
if(config.controller.port2 == 5) systemPort2Justifiers.setChecked();
systemCaptureMouse.create(system, "Capture Mouse");
systemCaptureMouse.setEnabled(false);
settings.create(*this, "Settings");
settingsVideoMode.create(settings, "Video Mode");
@ -100,6 +120,18 @@ void MainWindow::create() {
utility.showMessage("System was reset");
};
systemPort1None.onTick = []() { config.controller.port1 = 0; utility.setControllers(); };
systemPort1Gamepad.onTick = []() { config.controller.port1 = 1; utility.setControllers(); };
systemPort1Multitap.onTick = []() { config.controller.port1 = 2; utility.setControllers(); };
systemPort1Mouse.onTick = []() { config.controller.port1 = 3; utility.setControllers(); };
systemPort2None.onTick = []() { config.controller.port2 = 0; utility.setControllers(); };
systemPort2Gamepad.onTick = []() { config.controller.port2 = 1; utility.setControllers(); };
systemPort2Multitap.onTick = []() { config.controller.port2 = 2; utility.setControllers(); };
systemPort2Mouse.onTick = []() { config.controller.port2 = 3; utility.setControllers(); };
systemPort2SuperScope.onTick = []() { config.controller.port2 = 4; utility.setControllers(); };
systemPort2Justifiers.onTick = []() { config.controller.port2 = 5; utility.setControllers(); };
settingsVideoMode1x.onTick = []() { utility.setScale(1); };
settingsVideoMode2x.onTick = []() { utility.setScale(2); };
settingsVideoMode3x.onTick = []() { utility.setScale(3); };

View File

@ -11,7 +11,18 @@ struct MainWindow : Window {
MenuItem systemReset;
MenuSeparator systemSeparator2;
Menu systemPort1;
MenuRadioItem systemPort1None;
MenuRadioItem systemPort1Gamepad;
MenuRadioItem systemPort1Multitap;
MenuRadioItem systemPort1Mouse;
Menu systemPort2;
MenuRadioItem systemPort2None;
MenuRadioItem systemPort2Gamepad;
MenuRadioItem systemPort2Multitap;
MenuRadioItem systemPort2Mouse;
MenuRadioItem systemPort2SuperScope;
MenuRadioItem systemPort2Justifiers;
MenuItem systemCaptureMouse;
Menu settings;
Menu settingsVideoMode;
MenuRadioItem settingsVideoMode1x;

View File

@ -52,7 +52,7 @@ void Application::main(int argc, char **argv) {
stateManager.create();
utility.setScale(config.video.scale);
mainWindow.setVisible();
os.run();
OS::run();
video.driver(config.video.driver);
video.set(Video::Handle, mainWindow.viewport.handle());
@ -63,7 +63,6 @@ void Application::main(int argc, char **argv) {
video.driver("None");
video.init();
}
utility.setShader();
audio.driver(config.audio.driver);
audio.set(Audio::Handle, mainWindow.viewport.handle());
@ -87,10 +86,13 @@ void Application::main(int argc, char **argv) {
input.init();
}
utility.setControllers();
utility.setShader();
if(argc == 2) cartridge.loadNormal(argv[1]);
while(quit == false) {
os.run();
OS::run();
inputMapper.poll();
utility.updateStatus();
@ -110,7 +112,7 @@ void Application::main(int argc, char **argv) {
cartridge.unload();
foreach(window, windows) window->setVisible(false);
os.run();
OS::run();
SNES::system.term();
config.save();

View File

@ -8,7 +8,7 @@ void InputSettings::create() {
setFont(application.proportionalFontBold);
setStatusVisible();
unsigned x = 5, y = 5;
unsigned x = 5, y = 5, height = Style::ButtonHeight;
portLabel.create(*this, x, y, 50, Style::ComboBoxHeight, "Port:");
portBox.create(*this, x + 50, y, 200, Style::ComboBoxHeight);
@ -21,12 +21,19 @@ void InputSettings::create() {
mappingList.setHeaderVisible();
mappingList.setFocused();
clearAllButton.create(*this, 515 - 85 - 85, y, 80, height, "Clear All");
clearButton.create(*this, 515 - 85, y, 80, height, "Clear");
y += height + 5;
setGeometry(160, 160, 515, y);
portChanged();
portBox.onChange = { &InputSettings::portChanged, this };
deviceBox.onChange = { &InputSettings::deviceChanged, this };
mappingList.onActivate = { &InputSettings::assignInput, this };
clearAllButton.onTick = { &InputSettings::clearAll, this };
clearButton.onTick = { &InputSettings::clearSelected, this };
}
void InputSettings::portChanged() {
@ -138,6 +145,36 @@ void InputSettings::calibrateJoypads() {
joypadsCalibrated = true;
}
void InputSettings::clearAll() {
if(MessageWindow::question(inputSettings, "Clear all input mappings?", MessageWindow::Buttons::YesNo) == MessageWindow::Response::Yes) {
InputMapper::ControllerPort &port = (
portBox.selection() == 0
? (InputMapper::ControllerPort&)inputMapper.port1
: (InputMapper::ControllerPort&)inputMapper.port2
);
InputMapper::Controller &controller = (InputMapper::Controller&)*port[deviceBox.selection()];
for(unsigned i = 0; i < controller.size(); i++) controller[i]->mapping = "";
inputMapper.bind();
deviceChanged();
}
}
void InputSettings::clearSelected() {
if(auto position = mappingList.selection()) {
InputMapper::ControllerPort &port = (
portBox.selection() == 0
? (InputMapper::ControllerPort&)inputMapper.port1
: (InputMapper::ControllerPort&)inputMapper.port2
);
InputMapper::Controller &controller = (InputMapper::Controller&)*port[deviceBox.selection()];
controller[position()]->mapping = "";
inputMapper.bind();
deviceChanged();
}
}
InputSettings::InputSettings() {
joypadsCalibrated = false;
joypadsCalibrating = false;

View File

@ -4,6 +4,8 @@ struct InputSettings : Window {
Label deviceLabel;
ComboBox deviceBox;
ListBox mappingList;
Button clearAllButton;
Button clearButton;
void inputEvent(uint16_t scancode, int16_t value);
void calibrateJoypads();
@ -19,6 +21,9 @@ private:
void deviceChanged();
void setMapping(const char *mapping);
void assignInput();
void clearAll();
void clearSelected();
};
extern InputSettings inputSettings;

View File

@ -34,6 +34,24 @@ void Utility::showMessage(const char *text) {
statusTime = time(0);
}
void Utility::setControllers() {
switch(config.controller.port1) {
case 0: SNES::input.port_set_device(0, SNES::Input::Device::None); break;
case 1: SNES::input.port_set_device(0, SNES::Input::Device::Joypad); break;
case 2: SNES::input.port_set_device(0, SNES::Input::Device::Multitap); break;
case 3: SNES::input.port_set_device(0, SNES::Input::Device::Mouse); break;
}
switch(config.controller.port2) {
case 0: SNES::input.port_set_device(1, SNES::Input::Device::None); break;
case 1: SNES::input.port_set_device(1, SNES::Input::Device::Joypad); break;
case 2: SNES::input.port_set_device(1, SNES::Input::Device::Multitap); break;
case 3: SNES::input.port_set_device(1, SNES::Input::Device::Mouse); break;
case 4: SNES::input.port_set_device(1, SNES::Input::Device::SuperScope); break;
case 5: SNES::input.port_set_device(1, SNES::Input::Device::Justifiers); break;
}
}
void Utility::setScale(unsigned scale) {
if(scale == 0) scale = config.video.scale;
config.video.scale = scale;
@ -79,7 +97,7 @@ void Utility::loadCartridgeNormal() {
cartridge.loadNormal(filename);
});
} else {
string filename = os.fileOpen(mainWindow, "SNES cartridges\t*.sfc\nAll files\t*", config.path.current);
string filename = OS::fileOpen(mainWindow, "SNES cartridges\t*.sfc\nAll files\t*", config.path.current);
if(filename != "") {
cartridge.loadNormal(filename);
SNES::system.power();

View File

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