212 lines
5.8 KiB
C++
Executable file
212 lines
5.8 KiB
C++
Executable file
#include "../base.hpp"
|
|
#include "nes.cpp"
|
|
#include "snes.cpp"
|
|
#include "gameboy.cpp"
|
|
#include "user-interface.cpp"
|
|
InputManager *inputManager = 0;
|
|
|
|
void AbstractInput::attach(const string &primaryName, const string &secondaryName, const string &tertiaryName) {
|
|
string name = { primaryName, "::", secondaryName, "::", tertiaryName, "::", this->name };
|
|
name.replace(" ", "");
|
|
inputManager->config.attach(mapping, name);
|
|
}
|
|
|
|
void AbstractInput::bind() {
|
|
if(mapping == "") type = Type::Button, mapping = "None";
|
|
|
|
if(mapping.endswith(".Up")) type = Type::HatUp;
|
|
else if(mapping.endswith(".Down")) type = Type::HatDown;
|
|
else if(mapping.endswith(".Left")) type = Type::HatLeft;
|
|
else if(mapping.endswith(".Right")) type = Type::HatRight;
|
|
else if(mapping.endswith(".Lo")) type = Type::AxisLo;
|
|
else if(mapping.endswith(".Hi")) type = Type::AxisHi;
|
|
else if(mapping.beginswith("JP") && mapping.position("Axis")) type = Type::Axis;
|
|
else if(mapping.beginswith("MS") && mapping.endswith("axis")) type = Type::MouseAxis;
|
|
else if(mapping.beginswith("MS")) type = Type::MouseButton;
|
|
else type = Type::Button;
|
|
|
|
string decode = mapping;
|
|
if(auto position = decode.position(".")) decode[position()] = 0;
|
|
scancode = Scancode::decode(decode);
|
|
}
|
|
|
|
int16_t AbstractInput::poll() {
|
|
if(config->input.focusPolicy == 1 && mainWindow->focused() == false) return 0;
|
|
return inputManager->scancode[inputManager->activeScancode][scancode];
|
|
}
|
|
|
|
//
|
|
|
|
bool AnalogInput::bind(int16_t scancode, int16_t value) {
|
|
string encode = Scancode::encode(scancode);
|
|
Type type = Type::Button;
|
|
|
|
if(scancode == Scancode::None) goto bind;
|
|
if(Mouse::isAnyAxis(scancode)) { type = Type::MouseAxis; goto bind; }
|
|
if(Joypad::isAnyAxis(scancode)) { type = Type::Axis; goto bind; }
|
|
|
|
return false;
|
|
|
|
bind:
|
|
mapping = encode;
|
|
this->scancode = scancode;
|
|
this->type = Type::Axis;
|
|
return true;
|
|
}
|
|
|
|
int16_t AnalogInput::poll() {
|
|
int16_t value = AbstractInput::poll();
|
|
switch(type) {
|
|
case Type::MouseAxis: return input.acquired() ? value : 0;
|
|
case Type::Axis: return value;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
|
|
bool DigitalInput::bind(int16_t scancode, int16_t value) {
|
|
string encode = Scancode::encode(scancode);
|
|
Type type = Type::Button;
|
|
|
|
if(scancode == Scancode::None) goto bind;
|
|
|
|
if(Keyboard::isAnyKey(scancode) || Keyboard::isAnyModifier(scancode) || Joypad::isAnyButton(scancode)) {
|
|
if(value == 0) return false;
|
|
type = Type::Button;
|
|
goto bind;
|
|
}
|
|
|
|
if(Mouse::isAnyButton(scancode)) {
|
|
if(value == 0) return false;
|
|
type = Type::MouseButton;
|
|
goto bind;
|
|
}
|
|
|
|
if(Joypad::isAnyHat(scancode)) {
|
|
if(value & Joypad::HatUp ) { type = Type::HatUp; encode.append(".Up" ); goto bind; }
|
|
if(value & Joypad::HatDown ) { type = Type::HatDown; encode.append(".Down" ); goto bind; }
|
|
if(value & Joypad::HatLeft ) { type = Type::HatLeft; encode.append(".Left" ); goto bind; }
|
|
if(value & Joypad::HatRight) { type = Type::HatRight; encode.append(".Right"); goto bind; }
|
|
}
|
|
|
|
if(Joypad::isAnyAxis(scancode)) {
|
|
if(value < -12288) { type = Type::AxisLo; encode.append(".Lo"); goto bind; }
|
|
if(value > +24576) { type = Type::AxisHi; encode.append(".Hi"); goto bind; }
|
|
}
|
|
|
|
return false;
|
|
|
|
bind:
|
|
mapping = encode;
|
|
this->scancode = scancode;
|
|
this->type = type;
|
|
return true;
|
|
}
|
|
|
|
int16_t DigitalInput::poll() {
|
|
int16_t value = AbstractInput::poll();
|
|
switch(type) {
|
|
case Type::Button: return (bool)(value);
|
|
case Type::MouseButton: return (bool)(value & input.acquired());
|
|
case Type::HatUp: return (bool)(value & Joypad::HatUp);
|
|
case Type::HatDown: return (bool)(value & Joypad::HatDown);
|
|
case Type::HatLeft: return (bool)(value & Joypad::HatLeft);
|
|
case Type::HatRight: return (bool)(value & Joypad::HatRight);
|
|
case Type::AxisLo: return (bool)(value < -16384);
|
|
case Type::AxisHi: return (bool)(value > +16384);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
|
|
int16_t TurboInput::poll() {
|
|
int16_t result = DigitalInput::poll();
|
|
if(phase < 3) result = 0;
|
|
if(++phase >= 6) phase = 0;
|
|
return result;
|
|
}
|
|
|
|
TurboInput::TurboInput() : phase(0) {
|
|
}
|
|
|
|
//
|
|
|
|
void TertiaryInput::attach(const string &primaryName, const string &secondaryName) {
|
|
for(unsigned n = 0; n < size(); n++) {
|
|
operator[](n).attach(primaryName, secondaryName, name);
|
|
}
|
|
}
|
|
|
|
void TertiaryInput::bind() {
|
|
for(unsigned n = 0; n < size(); n++) {
|
|
operator[](n).bind();
|
|
}
|
|
}
|
|
|
|
int16_t TertiaryInput::poll(unsigned n) {
|
|
return operator[](n).poll();
|
|
}
|
|
|
|
//
|
|
|
|
void SecondaryInput::attach(const string &primaryName) {
|
|
for(unsigned n = 0; n < size(); n++) {
|
|
operator[](n).attach(primaryName, name);
|
|
}
|
|
}
|
|
|
|
void SecondaryInput::bind() {
|
|
for(unsigned n = 0; n < size(); n++) {
|
|
operator[](n).bind();
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
void PrimaryInput::attach() {
|
|
for(unsigned n = 0; n < size(); n++) {
|
|
operator[](n).attach(name);
|
|
}
|
|
}
|
|
|
|
void PrimaryInput::bind() {
|
|
for(unsigned n = 0; n < size(); n++) {
|
|
operator[](n).bind();
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
void InputManager::scan() {
|
|
activeScancode = !activeScancode;
|
|
input.poll(scancode[activeScancode]);
|
|
|
|
for(unsigned n = 0; n < Scancode::Limit; n++) {
|
|
if(scancode[!activeScancode][n] != scancode[activeScancode][n]) {
|
|
if(settingsWindow->focused()) inputSettings->inputEvent(n, scancode[activeScancode][n]);
|
|
if(mainWindow->focused()) userInterface.inputEvent(n, scancode[activeScancode][n]);
|
|
}
|
|
}
|
|
}
|
|
|
|
InputManager::InputManager() {
|
|
inputManager = this;
|
|
|
|
inputList.append(nes);
|
|
inputList.append(snes);
|
|
inputList.append(gameBoy);
|
|
inputList.append(userInterface);
|
|
|
|
for(unsigned n = 0; n < inputList.size(); n++) inputList[n].attach();
|
|
config.load(application->path("input.cfg"));
|
|
config.save(application->path("input.cfg"));
|
|
for(unsigned n = 0; n < inputList.size(); n++) inputList[n].bind();
|
|
|
|
activeScancode = 0;
|
|
}
|
|
|
|
InputManager::~InputManager() {
|
|
config.save(application->path("input.cfg"));
|
|
}
|