From 944c4a5f39c9cdab63e9af4648dd5ec6c51bbc4f Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Wed, 11 Apr 2012 08:18:53 +0300 Subject: [PATCH 1/3] Wxwidgets: Fix key entry dialog key box sizing to behave --- src/platform/wxwidgets/settings.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/platform/wxwidgets/settings.cpp b/src/platform/wxwidgets/settings.cpp index 7a173075..e80aa104 100644 --- a/src/platform/wxwidgets/settings.cpp +++ b/src/platform/wxwidgets/settings.cpp @@ -74,6 +74,8 @@ namespace std::map modifiers; std::map> classes; std::string currentclass; + wxFlexGridSizer* top_s; + wxFlexGridSizer* t_s; wxComboBox* mainclass; wxComboBox* mainkey; wxButton* ok; @@ -105,15 +107,15 @@ namespace }); Centre(); - wxFlexGridSizer* top_s = new wxFlexGridSizer(2, 1, 0, 0); + top_s = new wxFlexGridSizer(2, 1, 0, 0); SetSizer(top_s); - wxFlexGridSizer* t_s = new wxFlexGridSizer(mods.size() + 1, 3, 0, 0); + t_s = new wxFlexGridSizer(mods.size() + 1, 3, 0, 0); for(auto i : mods) { t_s->Add(new wxStaticText(this, wxID_ANY, towxstring(i)), 0, wxGROW); keyentry_mod_data m; t_s->Add(m.pressed = new wxCheckBox(this, wxID_ANY, wxT("Pressed")), 0, wxGROW); - t_s->Add(m.unmasked = new wxCheckBox(this, wxID_ANY, wxT("Unmasked")), 0, wxGROW); + t_s->Add(m.unmasked = new wxCheckBox(this, wxID_ANY, wxT("Unmasked")), 1, wxGROW); m.pressed->Disable(); modifiers[i] = m; m.pressed->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, @@ -123,7 +125,7 @@ namespace } t_s->Add(new wxStaticText(this, wxID_ANY, wxT("Key")), 0, wxGROW); t_s->Add(mainclass = new wxComboBox(this, wxID_ANY, classeslist[0], wxDefaultPosition, wxDefaultSize, - classeslist.size(), &classeslist[0], wxCB_READONLY), 1, wxGROW); + classeslist.size(), &classeslist[0], wxCB_READONLY), 0, wxGROW); mainclass->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(wxdialog_keyentry::on_classchange), NULL, this); t_s->Add(mainkey = new wxComboBox(this, wxID_ANY, emptystring, wxDefaultPosition, wxDefaultSize, @@ -135,9 +137,9 @@ namespace wxBoxSizer* pbutton_s = new wxBoxSizer(wxHORIZONTAL); if(clearable) pbutton_s->Add(clear = new wxButton(this, wxID_OK, wxT("Clear")), 0, wxGROW); - pbutton_s->AddStretchSpacer(); pbutton_s->Add(ok = new wxButton(this, wxID_OK, wxT("OK")), 0, wxGROW); pbutton_s->Add(cancel = new wxButton(this, wxID_CANCEL, wxT("Cancel")), 0, wxGROW); + pbutton_s->AddStretchSpacer(); ok->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wxdialog_keyentry::on_ok), NULL, this); cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, @@ -223,7 +225,10 @@ namespace set_class(_class); mainclass->SetValue(towxstring(_class)); mainkey->SetValue(towxstring(key)); - } + t_s->Layout(); + top_s->Layout(); + Fit(); + } void wxdialog_keyentry::on_change_setting(wxCommandEvent& e) { @@ -303,6 +308,9 @@ namespace mainkey->Append(towxstring(i)); currentclass = _class; mainkey->SetSelection(0); + t_s->Layout(); + top_s->Layout(); + Fit(); } void wxdialog_keyentry::on_classchange(wxCommandEvent& e) From 6393e21c5dbf5baec8a44ab884870bc92748f8e1 Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Wed, 11 Apr 2012 16:46:10 +0300 Subject: [PATCH 2/3] Wxwidgets joystick support --- include/library/joyfun.hpp | 41 ++++++ manual.lyx | 4 + manual.txt | 3 + src/library/joyfun.cpp | 30 +++++ src/platform/evdev/joystick.cpp | 4 +- src/platform/win32mm/joystick.cpp | 50 ++------ src/platform/wxwidgets/Makefile | 7 ++ src/platform/wxwidgets/joystick.cpp | 189 ++++++++++++++++++++++++++++ 8 files changed, 287 insertions(+), 41 deletions(-) create mode 100644 include/library/joyfun.hpp create mode 100644 src/library/joyfun.cpp create mode 100644 src/platform/wxwidgets/joystick.cpp diff --git a/include/library/joyfun.hpp b/include/library/joyfun.hpp new file mode 100644 index 00000000..96cdcd0d --- /dev/null +++ b/include/library/joyfun.hpp @@ -0,0 +1,41 @@ +#ifndef _library__joyfun__hpp__included__ +#define _library__joyfun__hpp__included__ + +#include + +/** + * Perform axis calibration correction. + * + * Parameter v: The raw value read. + * Parameter low: The low limit. + * Parameter high: The high limit. + * Returns: The calibrated read value. + */ +short calibration_correction(int64_t v, int64_t low, int64_t high); + +/** + * Translate hundredths of degree position into hat bitmask. + * + * 0 is assumed to be up, and values are assumed to be clockwise. Negative values are centered. + * + * Parameter angle: The angle. + * Returns: The hat bitmask. + */ +short angle_to_bitmask(int angle); + +/** + * If a != b, a <- b and return true. Otherwise return false. + * + * Parameter a: The target. + * Parameter b: The source. + * Returns: a was not equal to b? + */ +template bool make_equal(T& a, const T& b) +{ + bool r = (a != b); + if(r) + a = b; + return r; +} + +#endif diff --git a/manual.lyx b/manual.lyx index 1dedc354..e7f3307d 100644 --- a/manual.lyx +++ b/manual.lyx @@ -387,6 +387,10 @@ EVDEV: Use EVDEV for joystick (Linux only). WIN32MM: Use Win32mm for joystick (Windows only). \end_layout +\begin_layout Itemize +WXWIDGETS: Use Wxwidgets for joystick (requires WXWIDGETS graphics) +\end_layout + \begin_layout Itemize DUMMY: Disable joystick support. \end_layout diff --git a/manual.txt b/manual.txt index e41edcaf..47ab8812 100644 --- a/manual.txt +++ b/manual.txt @@ -154,6 +154,9 @@ Building is via makefile, the following options are available: ∗ WIN32MM: Use Win32mm for joystick (Windows only). + ∗ WXWIDGETS: Use Wxwidgets for joystick (requires WXWIDGETS + graphics) + ∗ DUMMY: Disable joystick support. – Default is SDL. diff --git a/src/library/joyfun.cpp b/src/library/joyfun.cpp new file mode 100644 index 00000000..fa7b75a3 --- /dev/null +++ b/src/library/joyfun.cpp @@ -0,0 +1,30 @@ +#include "library/joyfun.hpp" + + +short calibration_correction(int64_t v, int64_t low, int64_t high) +{ + double _v = v; + double _low = low; + double _high = high; + double _pos = 65535 * (_v - _low) / (_high - _low) - 32768; + if(_pos < -32768) + return -32768; + else if(_pos > 32767) + return 32767; + else + return static_cast(_pos); +} + +short angle_to_bitmask(int pov) +{ + short m = 0; + if((pov >= 0 && pov <= 6000) || (pov >= 30000 && pov <= 36000)) + m |= 1; + if(pov >= 3000 && pov <= 15000) + m |= 2; + if(pov >= 12000 && pov <= 24000) + m |= 4; + if(pov >= 21000 && pov <= 33000) + m |= 8; + return m; +} diff --git a/src/platform/evdev/joystick.cpp b/src/platform/evdev/joystick.cpp index 83943484..c7a4a997 100644 --- a/src/platform/evdev/joystick.cpp +++ b/src/platform/evdev/joystick.cpp @@ -1,6 +1,7 @@ #include "core/command.hpp" #include "core/keymapper.hpp" #include "core/window.hpp" +#include "library/joyfun.hpp" #include #include @@ -202,8 +203,7 @@ namespace v = (e.current_status != 0); break; case ET_AXIS: - v = -32768 + 65535 * (static_cast(e.current_status) - e.axis_min) / - (static_cast(e.axis_max) - e.axis_min); + v = calibration_correction(e.current_status, e.axis_min, e.axis_max); break; case ET_HAT_X: case ET_HAT_Y: { diff --git a/src/platform/win32mm/joystick.cpp b/src/platform/win32mm/joystick.cpp index 92c069c8..f6e4da16 100644 --- a/src/platform/win32mm/joystick.cpp +++ b/src/platform/win32mm/joystick.cpp @@ -4,6 +4,7 @@ #include "core/window.hpp" #include "library/minmax.hpp" #include "library/string.hpp" +#include "library/joyfun.hpp" #include #include @@ -30,9 +31,9 @@ namespace volatile bool quit_signaled; volatile bool quit_ack; - void create_hat(unsigned i) + void create_hat(unsigned i, unsigned j = 0) { - std::string n = (stringfmt() << "joystick" << i << "hat").str(); + std::string n = (stringfmt() << "joystick" << i << "hat" << j).str(); keygroup* k = new keygroup(n, "joystick", keygroup::KT_HAT); hats[i] = k; } @@ -57,21 +58,8 @@ namespace auto key = std::make_pair(i, j); if(!axes.count(key)) return; - short cpos; - double _pos = pos; - double _pmin = pmin; - double _pmax = pmax; - _pos = 65535 * (_pos - _pmin) / (_pmax - _pmin) - 32768; - if(_pos < -32768) - cpos = -32768; - else if(_pos > 32767) - cpos = 32767; - else - cpos = _pos; - if(laxes[key] != cpos) { - platform::queue(keypress(modifier_set(), *axes[key], cpos)); - laxes[key] = cpos; - } + if(make_equal(laxes[key], calibration_correction(pos, pmin, pmax))) + platform::queue(keypress(modifier_set(), *axes[key], laxes[key])); } void init_joysticks() @@ -144,31 +132,15 @@ namespace info.dwFlags = JOY_RETURNALL; if(joyGetPosEx(jnum, &info) != JOYERR_NOERROR) continue; //Not usable. - if(caps.wCaps & JOYCAPS_HASPOV) { - //Read POV hat. - short m = 0; - int pov = info.dwPOV; - if((pov >= 0 && pov <= 6000) || (pov >= 30000 && pov <= 36000)) - m |= 1; - if(pov >= 3000 && pov <= 15000) - m |= 2; - if(pov >= 12000 && pov <= 24000) - m |= 4; - if(pov >= 21000 && pov <= 33000) - m |= 8; - if(lhats[jnum] != m) { - platform::queue(keypress(modifier_set(), *hats[jnum], m)); - lhats[jnum] = m; - } - } + if(caps.wCaps & JOYCAPS_HASPOV) + if(make_equal(lhats[jnum], angle_to_bitmask(info.dwPOV))) + platform::queue(keypress(modifier_set(), *hats[jnum], lhats[jnum])); for(unsigned j = 0; j < caps.wMaxButtons; j++) { //Read buttons auto key = std::make_pair(jnum, j); - short x = (info.dwButtons >> j) & 1; - if(buttons.count(key) && lbuttons[key] != x) { - platform::queue(keypress(modifier_set(), *buttons[key], x)); - lbuttons[key] = x; - } + if(buttons.count(key) && make_equal(lbuttons[key], + static_cast((info.dwButtons >> j) & 1))) + platform::queue(keypress(modifier_set(), *buttons[key], lbuttons[key])); } read_axis(jnum, 0, info.dwXpos, caps.wXmin, caps.wXmax); read_axis(jnum, 1, info.dwYpos, caps.wYmin, caps.wYmax); diff --git a/src/platform/wxwidgets/Makefile b/src/platform/wxwidgets/Makefile index 9a37cf73..02dd1afe 100644 --- a/src/platform/wxwidgets/Makefile +++ b/src/platform/wxwidgets/Makefile @@ -6,6 +6,13 @@ else OBJECTS = dummy.$(OBJECT_SUFFIX) endif +ifeq ($(JOYSTICK), WXWIDGETS) +ifneq ($(GRAPHICS), WXWIDGETS) +$(error "WXWIDGETS joystick requires WXWIDGETS graphics") +endif +WXW_CFLAGS += -DWXWIDGETS_JOYSTICK_SUPPORT +endif + .PRECIOUS: %.$(OBJECT_SUFFIX) diff --git a/src/platform/wxwidgets/joystick.cpp b/src/platform/wxwidgets/joystick.cpp new file mode 100644 index 00000000..69e40e58 --- /dev/null +++ b/src/platform/wxwidgets/joystick.cpp @@ -0,0 +1,189 @@ +#ifdef WXWIDGETS_JOYSTICK_SUPPORT +#include "core/command.hpp" +#include "core/framerate.hpp" +#include "core/keymapper.hpp" +#include "core/window.hpp" +#include "library/minmax.hpp" +#include "library/string.hpp" +#include "library/joyfun.hpp" +#include +#include + + +#define POLL_WAIT 20000 +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + std::set keygroups; + std::map, keygroup*> buttons; + std::map, keygroup*> axes; + std::map hats; + std::map, short> lbuttons; + std::map, short> laxes; + std::map lhats; + std::map joysticks; + volatile bool ready = false; + + void create_hat(unsigned i, unsigned j = 0) + { + std::string n = (stringfmt() << "joystick" << i << "hat" << j).str(); + keygroup* k = new keygroup(n, "joystick", keygroup::KT_HAT); + hats[i] = k; + } + + void create_button(unsigned i, unsigned j) + { + std::string n = (stringfmt() << "joystick" << i << "button" << j).str(); + keygroup* k = new keygroup(n, "joystick", keygroup::KT_KEY); + buttons[std::make_pair(i, j)] = k; + } + + void create_axis(unsigned i, unsigned j, int min, int max) + { + messages << "axis #" << j << ": " << min << " " << max << std::endl; + std::string n = (stringfmt() << "joystick" << i << "axis" << j).str(); + keygroup* k; + k = new keygroup(n, "joystick", keygroup::KT_AXIS_PAIR); + axes[std::make_pair(i, j)] = k; + } + + void read_axis(unsigned i, unsigned j, int pos, int pmin, int pmax) + { + auto key = std::make_pair(i, j); + if(!axes.count(key)) + return; + if(make_equal(laxes[key], calibration_correction(pos, pmin, pmax))) + platform::queue(keypress(modifier_set(), *axes[key], laxes[key])); + } + + void init_joysticks() + { + unsigned max_joysticks = wxJoystick::GetNumberJoysticks(); + if(!max_joysticks) + return; //No joystick support. + for(unsigned i = 0; i < max_joysticks; i++) { + wxJoystick* joy = new wxJoystick(i); + if(!joy->IsOk()) { + //Not usable. + delete joy; + continue; + } + joysticks[i] = joy; + messages << "Joystick #" << i << ": " << joy->GetProductName() << std::endl; + if(joy->HasPOV()) + create_hat(i); + for(unsigned j = 0; j < joy->GetNumberButtons() && j < 32; j++) + create_button(i, j); + unsigned axcount = 2; + create_axis(i, 0, joy->GetXMin(), joy->GetXMax()); + create_axis(i, 1, joy->GetYMin(), joy->GetYMax()); + if(joy->HasZ()) { + create_axis(i, 2, joy->GetZMin(), joy->GetZMax()); + axcount++; + } + if(joy->HasRudder()) { + create_axis(i, 3, joy->GetRudderMin(), joy->GetRudderMax()); + axcount++; + } + if(joy->HasU()) { + create_axis(i, 4, joy->GetUMin(), joy->GetUMax()); + axcount++; + } + if(joy->HasV()) { + create_axis(i, 5, joy->GetVMin(), joy->GetVMax()); + axcount++; + } + if(joy->HasPOV()) + messages << "1 hat, "; + messages << axcount << " axes, " << min((int)joy->GetNumberButtons(), 32) << " buttons" + << std::endl; + } + ready = true; + } + + void poll_joysticks() + { + if(!ready) + return; + modifier_set mod; + for(auto i : joysticks) { + unsigned jnum = i.first; + wxJoystick* joy = i.second; + if(joy->HasPOV()) + if(make_equal(lhats[jnum], angle_to_bitmask(joy->GetPOVCTSPosition()))) + platform::queue(keypress(modifier_set(), *hats[jnum], lhats[jnum])); + uint32_t bmask = joy->GetButtonState(); + for(unsigned j = 0; j < 32; j++) { + //Read buttons + auto key = std::make_pair(jnum, j); + if(buttons.count(key) && make_equal(lbuttons[key], static_cast((bmask >> j) & + 1))) + platform::queue(keypress(modifier_set(), *buttons[key], lbuttons[key])); + } + wxPoint xy = joy->GetPosition(); + read_axis(jnum, 0, xy.x, joy->GetXMin(), joy->GetXMax()); + read_axis(jnum, 1, xy.y, joy->GetYMin(), joy->GetYMax()); + if(joy->HasZ()) + read_axis(jnum, 2, joy->GetZPosition(), joy->GetZMin(), joy->GetZMax()); + if(joy->HasRudder()) + read_axis(jnum, 3, joy->GetRudderPosition(), joy->GetRudderMin(), joy->GetRudderMax()); + if(joy->HasU()) + read_axis(jnum, 4, joy->GetUPosition(), joy->GetUMin(), joy->GetUMax()); + if(joy->HasV()) + read_axis(jnum, 5, joy->GetVPosition(), joy->GetUMin(), joy->GetUMax()); + } + } + + struct joystick_timer : public wxTimer + { + joystick_timer() { start(); } + void start() { Start(POLL_WAIT / 1000); } + void stop() { Stop(); } + void Notify() { poll_joysticks(); } + }* jtimer; +} + +void joystick_plugin::init() throw() +{ + init_joysticks(); + jtimer = new joystick_timer(); +} + +void joystick_plugin::quit() throw() +{ + jtimer->stop(); + delete jtimer; + jtimer = NULL; + ready = false; + usleep(50000); + for(auto i : keygroups) + delete i; + for(auto i : joysticks) + delete i.second; + usleep(500000); + buttons.clear(); + axes.clear(); + hats.clear(); + keygroups.clear(); + joysticks.clear(); +} + +void joystick_plugin::thread_fn() throw() +{ + //We don't poll in this thread, so just quit instantly. +} + +void joystick_plugin::signal() throw() +{ + //We don't poll in dedicated thread, so nothing to do. +} + +const char* joystick_plugin::name = "Wxwidgets joystick plugin"; +#endif From 4838c2af9f1221976e23b7ef333dfa5670dfd387 Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Wed, 11 Apr 2012 22:45:06 +0300 Subject: [PATCH 3/3] =?UTF-8?q?lsnes=20rr1-=CE=946?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VERSION | 2 +- manual.lyx | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ manual.txt | 38 +++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 229f0ce0..3a17adcb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1-Δ5ε2 \ No newline at end of file +1-Δ6 \ No newline at end of file diff --git a/manual.lyx b/manual.lyx index e7f3307d..f22d7475 100644 --- a/manual.lyx +++ b/manual.lyx @@ -6040,5 +6040,81 @@ Fix writing port2 data to movie. Fix SRAM handling with Bsnes v087. \end_layout +\begin_layout Subsection +rr1-delta6 +\end_layout + +\begin_layout Itemize +Library loading support +\end_layout + +\begin_layout Itemize +Built-in TSCC encoder +\end_layout + +\begin_layout Itemize +Hi-color (256T colors) dumping. +\end_layout + +\begin_layout Itemize +Dump over TCP/IP(v6) +\end_layout + +\begin_layout Itemize +Hidable status panel +\end_layout + +\begin_layout Itemize +Turbo toggle/hold +\end_layout + +\begin_layout Itemize +Adjustable sound volume +\end_layout + +\begin_layout Itemize +Screen scaling +\end_layout + +\begin_layout Itemize +Allow DnD into filename boxes +\end_layout + +\begin_layout Itemize +Configurable paths +\end_layout + +\begin_layout Itemize +Portaudio: Fix speaker popping at start +\end_layout + +\begin_layout Itemize +Lots of UI changes +\end_layout + +\begin_layout Itemize +Speed adjustment menu +\end_layout + +\begin_layout Itemize +Win32 joystick support +\end_layout + +\begin_layout Itemize +Lua: gui.rainbow and gui.box +\end_layout + +\begin_layout Itemize +Split key lists into classes (the key list was large!) +\end_layout + +\begin_layout Itemize +More save slots support +\end_layout + +\begin_layout Itemize +Wxwidgets (wxJoystick) joystick support +\end_layout + \end_body \end_document diff --git a/manual.txt b/manual.txt index 47ab8812..21b14ed0 100644 --- a/manual.txt +++ b/manual.txt @@ -2979,3 +2979,41 @@ set-axis joystick0axis19 disabled • Fix SRAM handling with Bsnes v087. +15.56 rr1-delta6 + +• Library loading support + +• Built-in TSCC encoder + +• Hi-color (256T colors) dumping. + +• Dump over TCP/IP(v6) + +• Hidable status panel + +• Turbo toggle/hold + +• Adjustable sound volume + +• Screen scaling + +• Allow DnD into filename boxes + +• Configurable paths + +• Portaudio: Fix speaker popping at start + +• Lots of UI changes + +• Speed adjustment menu + +• Win32 joystick support + +• Lua: gui.rainbow and gui.box + +• Split key lists into classes (the key list was large!) + +• More save slots support + +• Wxwidgets (wxJoystick) joystick support +