Android: Switch dpad default to use HAT X/Y +/- instead of "dpad", as documented.

Add a simple "autoconfigure" facility for input devices, that lets the user choose
if several are connected.

Can be expanded in the future to provide custom default mapppings for various devices as long as we manage to identify them.

Ideally, key mappings should be unique per device but they aren't yet.
This commit is contained in:
Henrik Rydgard 2014-05-19 23:29:35 +02:00
parent c4d8b31956
commit 3023f7d06b
7 changed files with 75 additions and 9 deletions

View File

@ -18,10 +18,12 @@
#if defined(_WIN32) && !defined(_XBOX)
#include <windows.h>
#endif
#include <set>
#include "base/logging.h"
#include "base/NativeApp.h"
#include "file/ini_file.h"
#include "input/input_state.h"
#include "base/NativeApp.h"
#include "KeyMap.h"
#include "../Core/HLE/sceUtility.h"
@ -40,6 +42,7 @@ struct DefMappingStruct {
};
KeyMapping g_controllerMap;
std::set<std::string> g_seenPads;
static const DefMappingStruct defaultQwertyKeyboardKeyMap[] = {
{CTRL_SQUARE, NKCODE_A},
@ -202,10 +205,11 @@ static const DefMappingStruct defaultPadMap[] = {
{CTRL_CIRCLE , NKCODE_BUTTON_B},
{CTRL_SQUARE , NKCODE_BUTTON_X},
{CTRL_TRIANGLE , NKCODE_BUTTON_Y},
{CTRL_UP , NKCODE_DPAD_UP},
{CTRL_RIGHT , NKCODE_DPAD_RIGHT},
{CTRL_DOWN , NKCODE_DPAD_DOWN},
{CTRL_LEFT , NKCODE_DPAD_LEFT},
// The hat for DPAD is standard for bluetooth pads, which is the most likely pads on Android I think.
{CTRL_LEFT , JOYSTICK_AXIS_HAT_X, -1},
{CTRL_RIGHT , JOYSTICK_AXIS_HAT_X, +1},
{CTRL_UP , JOYSTICK_AXIS_HAT_Y, -1},
{CTRL_DOWN , JOYSTICK_AXIS_HAT_Y, +1},
{CTRL_START , NKCODE_BUTTON_START},
{CTRL_SELECT , NKCODE_BUTTON_SELECT},
{CTRL_LTRIGGER , NKCODE_BUTTON_L1},
@ -894,4 +898,22 @@ bool HasBuiltinController(const std::string &name) {
return IsOuya(name) || IsXperiaPlay(name) || IsNvidiaShield(name) || IsBlackberryQWERTY(name);
}
void NotifyPadConnected(const std::string &name) {
g_seenPads.insert(name);
}
void AutoConfForPad(const std::string &name) {
ILOG("Autoconfiguring pad for %s", name.c_str());
if (name == "Xbox 360 Pad") {
SetDefaultKeyMap(DEFAULT_MAPPING_X360, true);
} else {
SetDefaultKeyMap(DEFAULT_MAPPING_PAD, true);
}
}
const std::set<std::string> &GetSeenPads() {
return g_seenPads;
}
} // KeyMap

View File

@ -20,6 +20,7 @@
#include <string>
#include <map>
#include <vector>
#include <set>
#include "input/keycodes.h" // keyboard keys
#include "../Core/HLE/sceCtrl.h" // psp keys
@ -156,9 +157,13 @@ namespace KeyMap {
void UpdateConfirmCancelKeys();
void NotifyPadConnected(const std::string &name);
bool IsNvidiaShield(const std::string &name);
bool IsBlackberryQWERTY(const std::string &name);
bool IsXperiaPlay(const std::string &name);
bool IsOuya(const std::string &name);
bool HasBuiltinController(const std::string &name);
const std::set<std::string> &GetSeenPads();
void AutoConfForPad(const std::string &name);
}

View File

@ -199,6 +199,9 @@ void ControlMappingScreen::CreateViews() {
LinearLayout *leftColumn = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(200, FILL_PARENT));
leftColumn->Add(new Choice(k->T("Clear All")))->OnClick.Handle(this, &ControlMappingScreen::OnClearMapping);
leftColumn->Add(new Choice(k->T("Default All")))->OnClick.Handle(this, &ControlMappingScreen::OnDefaultMapping);
if (KeyMap::GetSeenPads().size()) {
leftColumn->Add(new Choice(k->T("Autoconfigure")))->OnClick.Handle(this, &ControlMappingScreen::OnAutoConfigure);
}
leftColumn->Add(new Spacer(new LinearLayoutParams(1.0f)));
leftColumn->Add(new Choice(d->T("Back")))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
@ -238,6 +241,24 @@ UI::EventReturn ControlMappingScreen::OnDefaultMapping(UI::EventParams &params)
return UI::EVENT_DONE;
}
UI::EventReturn ControlMappingScreen::OnAutoConfigure(UI::EventParams &params) {
std::vector<std::string> items;
for (auto s : KeyMap::GetSeenPads()) {
items.push_back(s);
}
ListPopupScreen *autoConfList = new ListPopupScreen("Autoconfigure for device", items, -1);
screenManager()->push(autoConfList);
return UI::EVENT_DONE;
}
void ControlMappingScreen::dialogFinished(const Screen *dialog, DialogResult result) {
if (result == DR_OK && dialog->tag() == "listpopup") {
ListPopupScreen *popup = (ListPopupScreen *)dialog;
KeyMap::AutoConfForPad(popup->GetChoiceString());
RecreateViews();
}
}
void KeyMappingNewKeyDialog::CreatePopupContents(UI::ViewGroup *parent) {
using namespace UI;

View File

@ -33,6 +33,9 @@ protected:
private:
UI::EventReturn OnDefaultMapping(UI::EventParams &params);
UI::EventReturn OnClearMapping(UI::EventParams &params);
UI::EventReturn OnAutoConfigure(UI::EventParams &params);
virtual void dialogFinished(const Screen *dialog, DialogResult result) override;
};
class KeyMappingNewKeyDialog : public PopupScreen {

View File

@ -657,10 +657,17 @@ void NativeRender() {
}
}
void HandleGlobalMessage(const std::string &msg, const std::string &value) {
if (msg == "inputDeviceConnected") {
KeyMap::NotifyPadConnected(value);
}
}
void NativeUpdate(InputState &input) {
{
lock_guard lock(pendingMutex);
for (size_t i = 0; i < pendingMessages.size(); i++) {
HandleGlobalMessage(pendingMessages[i].msg, pendingMessages[i].value);
screenManager->sendMessage(pendingMessages[i].msg.c_str(), pendingMessages[i].value.c_str());
}
pendingMessages.clear();

View File

@ -2,6 +2,7 @@
#include "base/NativeApp.h"
#include "Core/Config.h"
#include "Common/KeyMap.h"
#include "input/input_state.h"
#include "input/keycodes.h"
#include "XinputDevice.h"
@ -116,14 +117,16 @@ int XinputDevice::UpdateState(InputState &input_state) {
if (!s_pXInputDLL)
return 0;
if (this->check_delay-- > 0) return -1;
if (this->check_delay-- > 0)
return -1;
XINPUT_STATE state;
ZeroMemory( &state, sizeof(XINPUT_STATE) );
DWORD dwResult;
if (this->gamepad_idx >= 0)
if (this->gamepad_idx >= 0) {
dwResult = PPSSPP_XInputGetState( this->gamepad_idx, &state );
else {
} else {
// use the first gamepad that responds
for (int i = 0; i < XUSER_MAX_COUNT; i++) {
dwResult = PPSSPP_XInputGetState( i, &state );
@ -135,6 +138,11 @@ int XinputDevice::UpdateState(InputState &input_state) {
}
if ( dwResult == ERROR_SUCCESS ) {
static bool notified = false;
if (!notified) {
notified = true;
KeyMap::NotifyPadConnected("Xbox 360 Pad");
}
ApplyButtons(state, input_state);
if (prevState.Gamepad.sThumbLX != state.Gamepad.sThumbLX || prevState.Gamepad.sThumbLY != state.Gamepad.sThumbLY) {

2
native

@ -1 +1 @@
Subproject commit edaea34df1b1b7b37eac23abf39a27e3f4b3b78e
Subproject commit e7001eb701a953c9508f5a85d40147e5f0a88f3a