mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-10-04 07:01:32 +02:00
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.
61 lines
2.3 KiB
C++
Executable File
61 lines
2.3 KiB
C++
Executable File
#ifndef NALL_FUNCTION_HPP
|
|
#define NALL_FUNCTION_HPP
|
|
|
|
namespace nall {
|
|
template<typename T> class function;
|
|
|
|
template<typename R, typename... P> class function<R (P...)> {
|
|
struct container {
|
|
virtual R operator()(P... p) const = 0;
|
|
virtual container* copy() const = 0;
|
|
virtual ~container() {}
|
|
} *callback;
|
|
|
|
struct global : container {
|
|
R (*function)(P...);
|
|
R operator()(P... p) const { return function(std::forward<P>(p)...); }
|
|
container* copy() const { return new global(function); }
|
|
global(R (*function)(P...)) : function(function) {}
|
|
};
|
|
|
|
template<typename C> struct member : container {
|
|
R (C::*function)(P...);
|
|
C *object;
|
|
R operator()(P... p) const { return (object->*function)(std::forward<P>(p)...); }
|
|
container* copy() const { return new member(function, object); }
|
|
member(R (C::*function)(P...), C *object) : function(function), object(object) {}
|
|
};
|
|
|
|
template<typename L> struct lambda : container {
|
|
L object;
|
|
R operator()(P... p) const { return object(std::forward<P>(p)...); }
|
|
container* copy() const { return new lambda(object); }
|
|
lambda(const L& object) : object(object) {}
|
|
};
|
|
|
|
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) {
|
|
if(callback) { delete callback; callback = 0; }
|
|
if(source.callback) callback = source.callback->copy();
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
function(const function &source) { operator=(source); }
|
|
function() : callback(0) {}
|
|
function(void *function) : callback(0) { if(function) callback = new global((R (*)(P...))function); }
|
|
function(R (*function)(P...)) { callback = new global(function); }
|
|
template<typename C> function(R (C::*function)(P...), C *object) { callback = new member<C>(function, object); }
|
|
template<typename C> function(R (C::*function)(P...) const, C *object) { callback = new member<C>((R (C::*)(P...))function, object); }
|
|
template<typename L> function(const L& object) { callback = new lambda<L>(object); }
|
|
~function() { if(callback) delete callback; }
|
|
};
|
|
}
|
|
|
|
#endif
|