Customizable touch control (rebased with label)
@ -170,6 +170,10 @@ void Section::Set(const char* key, uint32_t newValue) {
|
||||
Set(key, StringFromFormat("0x%08x", newValue).c_str());
|
||||
}
|
||||
|
||||
void Section::Set(const char* key, uint64_t newValue) {
|
||||
Set(key, StringFromFormat("0x%016lx", newValue).c_str());
|
||||
}
|
||||
|
||||
void Section::Set(const char* key, float newValue) {
|
||||
Set(key, StringFromFormat("%f", newValue).c_str());
|
||||
}
|
||||
@ -311,6 +315,16 @@ bool Section::Get(const char* key, uint32_t* value, uint32_t defaultValue)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Section::Get(const char* key, uint64_t* value, uint64_t defaultValue)
|
||||
{
|
||||
std::string temp;
|
||||
bool retval = Get(key, &temp, 0);
|
||||
if (retval && TryParse(temp, value))
|
||||
return true;
|
||||
*value = defaultValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Section::Get(const char* key, bool* value, bool defaultValue)
|
||||
{
|
||||
std::string temp;
|
||||
@ -659,6 +673,17 @@ bool IniFile::Get(const char* sectionName, const char* key, uint32_t* value, uin
|
||||
}
|
||||
}
|
||||
|
||||
bool IniFile::Get(const char* sectionName, const char* key, uint64_t* value, uint64_t defaultValue)
|
||||
{
|
||||
Section *section = GetSection(sectionName);
|
||||
if (!section) {
|
||||
*value = defaultValue;
|
||||
return false;
|
||||
} else {
|
||||
return section->Get(key, value, defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
bool IniFile::Get(const char* sectionName, const char* key, bool* value, bool defaultValue)
|
||||
{
|
||||
Section *section = GetSection(sectionName);
|
||||
|
@ -35,6 +35,7 @@ public:
|
||||
bool Get(const char* key, std::string* value, const char* defaultValue);
|
||||
|
||||
void Set(const char* key, uint32_t newValue);
|
||||
void Set(const char* key, uint64_t newValue);
|
||||
void Set(const char* key, float newValue);
|
||||
void Set(const char* key, const float newValue, const float defaultValue);
|
||||
void Set(const char* key, double newValue);
|
||||
@ -58,6 +59,7 @@ public:
|
||||
|
||||
bool Get(const char* key, int* value, int defaultValue = 0);
|
||||
bool Get(const char* key, uint32_t* value, uint32_t defaultValue = 0);
|
||||
bool Get(const char* key, uint64_t* value, uint64_t defaultValue = 0);
|
||||
bool Get(const char* key, bool* value, bool defaultValue = false);
|
||||
bool Get(const char* key, float* value, float defaultValue = false);
|
||||
bool Get(const char* key, double* value, double defaultValue = false);
|
||||
@ -103,6 +105,9 @@ public:
|
||||
void Set(const char* sectionName, const char* key, uint32_t newValue) {
|
||||
GetOrCreateSection(sectionName)->Set(key, newValue);
|
||||
}
|
||||
void Set(const char* sectionName, const char* key, uint64_t newValue) {
|
||||
GetOrCreateSection(sectionName)->Set(key, newValue);
|
||||
}
|
||||
void Set(const char* sectionName, const char* key, bool newValue) {
|
||||
GetOrCreateSection(sectionName)->Set(key, newValue);
|
||||
}
|
||||
@ -114,6 +119,7 @@ public:
|
||||
bool Get(const char* sectionName, const char* key, std::string* value, const char* defaultValue = "");
|
||||
bool Get(const char* sectionName, const char* key, int* value, int defaultValue = 0);
|
||||
bool Get(const char* sectionName, const char* key, uint32_t* value, uint32_t defaultValue = 0);
|
||||
bool Get(const char* sectionName, const char* key, uint64_t* value, uint64_t defaultValue = 0);
|
||||
bool Get(const char* sectionName, const char* key, bool* value, bool defaultValue = false);
|
||||
bool Get(const char* sectionName, const char* key, std::vector<std::string>& values);
|
||||
|
||||
|
@ -71,6 +71,26 @@ bool TryParse(const std::string &str, uint32_t *const output) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryParse(const std::string &str, uint64_t *const output) {
|
||||
char *endptr = NULL;
|
||||
|
||||
// Holy crap this is ugly.
|
||||
|
||||
// Reset errno to a value other than ERANGE
|
||||
errno = 0;
|
||||
|
||||
uint64_t value = strtoul(str.c_str(), &endptr, 0);
|
||||
|
||||
if (!endptr || *endptr)
|
||||
return false;
|
||||
|
||||
if (errno == ERANGE)
|
||||
return false;
|
||||
|
||||
*output = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryParse(const std::string &str, bool *const output) {
|
||||
if ("1" == str || !strcasecmp("true", str.c_str()))
|
||||
*output = true;
|
||||
|
@ -57,6 +57,7 @@ bool ParseMacAddress(std::string str, uint8_t macAddr[6]);
|
||||
|
||||
bool TryParse(const std::string &str, bool *const output);
|
||||
bool TryParse(const std::string &str, uint32_t *const output);
|
||||
bool TryParse(const std::string &str, uint64_t *const output);
|
||||
|
||||
template <typename N>
|
||||
static bool TryParse(const std::string &str, N *const output) {
|
||||
|
@ -68,46 +68,56 @@ struct ConfigSetting {
|
||||
TYPE_BOOL,
|
||||
TYPE_INT,
|
||||
TYPE_UINT32,
|
||||
TYPE_UINT64,
|
||||
TYPE_FLOAT,
|
||||
TYPE_STRING,
|
||||
TYPE_TOUCH_POS,
|
||||
TYPE_PATH,
|
||||
TYPE_CUSTOM_BUTTON
|
||||
};
|
||||
union DefaultValue {
|
||||
bool b;
|
||||
int i;
|
||||
uint32_t u;
|
||||
uint64_t lu;
|
||||
float f;
|
||||
const char *s;
|
||||
const char *p; // not sure how much point..
|
||||
ConfigTouchPos touchPos;
|
||||
ConfigCustomButton customButton;
|
||||
};
|
||||
union SettingPtr {
|
||||
bool *b;
|
||||
int *i;
|
||||
uint32_t *u;
|
||||
uint64_t *lu;
|
||||
float *f;
|
||||
std::string *s;
|
||||
Path *p;
|
||||
ConfigTouchPos *touchPos;
|
||||
ConfigCustomButton *customButton;
|
||||
};
|
||||
|
||||
typedef bool (*BoolDefaultCallback)();
|
||||
typedef int (*IntDefaultCallback)();
|
||||
typedef uint32_t (*Uint32DefaultCallback)();
|
||||
typedef uint64_t (*Uint64DefaultCallback)();
|
||||
typedef float (*FloatDefaultCallback)();
|
||||
typedef const char *(*StringDefaultCallback)();
|
||||
typedef ConfigTouchPos(*TouchPosDefaultCallback)();
|
||||
typedef const char *(*PathDefaultCallback)();
|
||||
typedef ConfigCustomButton (*CustomButtonDefaultCallback)();
|
||||
|
||||
union Callback {
|
||||
BoolDefaultCallback b;
|
||||
IntDefaultCallback i;
|
||||
Uint32DefaultCallback u;
|
||||
Uint64DefaultCallback lu;
|
||||
FloatDefaultCallback f;
|
||||
StringDefaultCallback s;
|
||||
PathDefaultCallback p;
|
||||
TouchPosDefaultCallback touchPos;
|
||||
CustomButtonDefaultCallback customButton;
|
||||
};
|
||||
|
||||
ConfigSetting(bool v)
|
||||
@ -144,6 +154,13 @@ struct ConfigSetting {
|
||||
default_.u = def;
|
||||
}
|
||||
|
||||
ConfigSetting(const char *ini, uint64_t *v, uint64_t def, bool save = true, bool perGame = false)
|
||||
: iniKey_(ini), type_(TYPE_UINT64), report_(false), save_(save), perGame_(perGame) {
|
||||
ptr_.lu = v;
|
||||
cb_.lu = nullptr;
|
||||
default_.lu = def;
|
||||
}
|
||||
|
||||
ConfigSetting(const char *ini, float *v, float def, bool save = true, bool perGame = false)
|
||||
: iniKey_(ini), type_(TYPE_FLOAT), report_(false), save_(save), perGame_(perGame) {
|
||||
ptr_.f = v;
|
||||
@ -172,6 +189,13 @@ struct ConfigSetting {
|
||||
default_.touchPos = def;
|
||||
}
|
||||
|
||||
ConfigSetting(const char *iniKey, const char *iniImage, const char *iniShape, const char *iniToggle, ConfigCustomButton *v, ConfigCustomButton def, bool save = true, bool perGame = false)
|
||||
: iniKey_(iniKey), ini2_(iniImage), ini3_(iniShape), ini4_(iniToggle), type_(TYPE_CUSTOM_BUTTON), report_(false), save_(save), perGame_(perGame) {
|
||||
ptr_.customButton = v;
|
||||
cb_.customButton = nullptr;
|
||||
default_.customButton = def;
|
||||
}
|
||||
|
||||
ConfigSetting(const char *ini, bool *v, BoolDefaultCallback def, bool save = true, bool perGame = false)
|
||||
: iniKey_(ini), type_(TYPE_BOOL), report_(false), save_(save), perGame_(perGame) {
|
||||
ptr_.b = v;
|
||||
@ -242,6 +266,11 @@ struct ConfigSetting {
|
||||
default_.u = cb_.u();
|
||||
}
|
||||
return section->Get(iniKey_, ptr_.u, default_.u);
|
||||
case TYPE_UINT64:
|
||||
if (cb_.lu) {
|
||||
default_.lu = cb_.lu();
|
||||
}
|
||||
return section->Get(iniKey_, ptr_.lu, default_.lu);
|
||||
case TYPE_FLOAT:
|
||||
if (cb_.f) {
|
||||
default_.f = cb_.f();
|
||||
@ -277,6 +306,15 @@ struct ConfigSetting {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case TYPE_CUSTOM_BUTTON:
|
||||
if (cb_.customButton) {
|
||||
default_.customButton = cb_.customButton();
|
||||
}
|
||||
section->Get(iniKey_, &ptr_.customButton->key, default_.customButton.key);
|
||||
section->Get(ini2_, &ptr_.customButton->image, default_.customButton.image);
|
||||
section->Get(ini3_, &ptr_.customButton->shape, default_.customButton.shape);
|
||||
section->Get(ini4_, &ptr_.customButton->toggle, default_.customButton.toggle);
|
||||
return true;
|
||||
default:
|
||||
_dbg_assert_msg_(false, "Unexpected ini setting type");
|
||||
return false;
|
||||
@ -298,6 +336,8 @@ struct ConfigSetting {
|
||||
return section->Set(iniKey_, *ptr_.i);
|
||||
case TYPE_UINT32:
|
||||
return section->Set(iniKey_, *ptr_.u);
|
||||
case TYPE_UINT64:
|
||||
return section->Set(iniKey_, *ptr_.lu);
|
||||
case TYPE_FLOAT:
|
||||
return section->Set(iniKey_, *ptr_.f);
|
||||
case TYPE_STRING:
|
||||
@ -312,6 +352,12 @@ struct ConfigSetting {
|
||||
section->Set(ini4_, ptr_.touchPos->show);
|
||||
}
|
||||
return;
|
||||
case TYPE_CUSTOM_BUTTON:
|
||||
section->Set(iniKey_, ptr_.customButton->key);
|
||||
section->Set(ini2_, ptr_.customButton->image);
|
||||
section->Set(ini3_, ptr_.customButton->shape);
|
||||
section->Set(ini4_, ptr_.customButton->toggle);
|
||||
return;
|
||||
default:
|
||||
_dbg_assert_msg_(false, "Unexpected ini setting type");
|
||||
return;
|
||||
@ -329,6 +375,8 @@ struct ConfigSetting {
|
||||
return data.Add(prefix + iniKey_, *ptr_.i);
|
||||
case TYPE_UINT32:
|
||||
return data.Add(prefix + iniKey_, *ptr_.u);
|
||||
case TYPE_UINT64:
|
||||
return data.Add(prefix + iniKey_, *ptr_.lu);
|
||||
case TYPE_FLOAT:
|
||||
return data.Add(prefix + iniKey_, *ptr_.f);
|
||||
case TYPE_STRING:
|
||||
@ -338,6 +386,9 @@ struct ConfigSetting {
|
||||
case TYPE_TOUCH_POS:
|
||||
// Doesn't report.
|
||||
return;
|
||||
case TYPE_CUSTOM_BUTTON:
|
||||
// Doesn't report.
|
||||
return;
|
||||
default:
|
||||
_dbg_assert_msg_(false, "Unexpected ini setting type");
|
||||
return;
|
||||
@ -490,7 +541,6 @@ static ConfigSetting generalSettings[] = {
|
||||
ConfigSetting("GridView1", &g_Config.bGridView1, true),
|
||||
ConfigSetting("GridView2", &g_Config.bGridView2, true),
|
||||
ConfigSetting("GridView3", &g_Config.bGridView3, false),
|
||||
ConfigSetting("ComboMode", &g_Config.iComboMode, 0),
|
||||
ConfigSetting("RightAnalogUp", &g_Config.iRightAnalogUp, 0, true, true),
|
||||
ConfigSetting("RightAnalogDown", &g_Config.iRightAnalogDown, 0, true, true),
|
||||
ConfigSetting("RightAnalogLeft", &g_Config.iRightAnalogLeft, 0, true, true),
|
||||
@ -887,17 +937,16 @@ static ConfigSetting controlSettings[] = {
|
||||
ConfigSetting("ShowTouchSquare", &g_Config.bShowTouchSquare, true, true, true),
|
||||
ConfigSetting("ShowTouchTriangle", &g_Config.bShowTouchTriangle, true, true, true),
|
||||
|
||||
ConfigSetting("ComboKey0Mapping", &g_Config.iCombokey0, 0, true, true),
|
||||
ConfigSetting("ComboKey1Mapping", &g_Config.iCombokey1, 0, true, true),
|
||||
ConfigSetting("ComboKey2Mapping", &g_Config.iCombokey2, 0, true, true),
|
||||
ConfigSetting("ComboKey3Mapping", &g_Config.iCombokey3, 0, true, true),
|
||||
ConfigSetting("ComboKey4Mapping", &g_Config.iCombokey4, 0, true, true),
|
||||
|
||||
ConfigSetting("ComboKey0Toggle", &g_Config.bComboToggle0, false, true, true),
|
||||
ConfigSetting("ComboKey1Toggle", &g_Config.bComboToggle1, false, true, true),
|
||||
ConfigSetting("ComboKey2Toggle", &g_Config.bComboToggle2, false, true, true),
|
||||
ConfigSetting("ComboKey3Toggle", &g_Config.bComboToggle3, false, true, true),
|
||||
ConfigSetting("ComboKey4Toggle", &g_Config.bComboToggle4, false, true, true),
|
||||
ConfigSetting("Custom0Mapping", "Custom0Image", "Custom0Shape", "Custom0Toggle", &g_Config.CustomKey0, {0, 0, 0, false}, true, true),
|
||||
ConfigSetting("Custom1Mapping", "Custom1Image", "Custom1Shape", "Custom1Toggle", &g_Config.CustomKey1, {0, 1, 0, false}, true, true),
|
||||
ConfigSetting("Custom2Mapping", "Custom2Image", "Custom2Shape", "Custom2Toggle", &g_Config.CustomKey2, {0, 2, 0, false}, true, true),
|
||||
ConfigSetting("Custom3Mapping", "Custom3Image", "Custom3Shape", "Custom3Toggle", &g_Config.CustomKey3, {0, 3, 0, false}, true, true),
|
||||
ConfigSetting("Custom4Mapping", "Custom4Image", "Custom4Shape", "Custom4Toggle", &g_Config.CustomKey4, {0, 4, 0, false}, true, true),
|
||||
ConfigSetting("Custom5Mapping", "Custom5Image", "Custom5Shape", "Custom5Toggle", &g_Config.CustomKey5, {0, 0, 1, false}, true, true),
|
||||
ConfigSetting("Custom6Mapping", "Custom6Image", "Custom6Shape", "Custom6Toggle", &g_Config.CustomKey6, {0, 1, 1, false}, true, true),
|
||||
ConfigSetting("Custom7Mapping", "Custom7Image", "Custom7Shape", "Custom7Toggle", &g_Config.CustomKey7, {0, 2, 1, false}, true, true),
|
||||
ConfigSetting("Custom8Mapping", "Custom8Image", "Custom8Shape", "Custom8Toggle", &g_Config.CustomKey8, {0, 3, 1, false}, true, true),
|
||||
ConfigSetting("Custom9Mapping", "Custom9Image", "Custom9Shape", "Custom9Toggle", &g_Config.CustomKey9, {0, 4, 1, false}, true, true),
|
||||
|
||||
#if defined(_WIN32)
|
||||
// A win32 user seeing touch controls is likely using PPSSPP on a tablet. There it makes
|
||||
@ -956,11 +1005,11 @@ static ConfigSetting controlSettings[] = {
|
||||
ConfigSetting("fcombo2X", "fcombo2Y", "comboKeyScale2", "ShowComboKey2", &g_Config.touchCombo2, defaultTouchPosHide, true, true),
|
||||
ConfigSetting("fcombo3X", "fcombo3Y", "comboKeyScale3", "ShowComboKey3", &g_Config.touchCombo3, defaultTouchPosHide, true, true),
|
||||
ConfigSetting("fcombo4X", "fcombo4Y", "comboKeyScale4", "ShowComboKey4", &g_Config.touchCombo4, defaultTouchPosHide, true, true),
|
||||
ConfigSetting("Speed1KeyX", "Speed1KeyY", "Speed1KeyScale", "ShowSpeed1Key", &g_Config.touchSpeed1Key, defaultTouchPosHide, true, true),
|
||||
ConfigSetting("Speed2KeyX", "Speed2KeyY", "Speed2KeyScale", "ShowSpeed2Key", &g_Config.touchSpeed2Key, defaultTouchPosHide, true, true),
|
||||
ConfigSetting("RapidFireKeyX", "RapidFireKeyY", "RapidFireKeyScale", "ShowRapidFireKey", &g_Config.touchRapidFireKey, defaultTouchPosHide, true, true),
|
||||
ConfigSetting("AnalogRotationCWKeyX", "AnalogRotationKeyCWY", "AnalogRotationKeyCWScale", "ShowAnalogRotationCWKey", &g_Config.touchAnalogRotationCWKey, defaultTouchPosHide, true, true),
|
||||
ConfigSetting("AnalogRotationCCWKeyX", "AnalogRotationKeyCCWY", "AnalogRotationKeyCCWScale", "ShowAnalogRotationCCWKey", &g_Config.touchAnalogRotationCCWKey, defaultTouchPosHide, true, true),
|
||||
ConfigSetting("fcombo5X", "fcombo5Y", "comboKeyScale5", "ShowComboKey5", &g_Config.touchCombo5, defaultTouchPosHide, true, true),
|
||||
ConfigSetting("fcombo6X", "fcombo6Y", "comboKeyScale6", "ShowComboKey6", &g_Config.touchCombo6, defaultTouchPosHide, true, true),
|
||||
ConfigSetting("fcombo7X", "fcombo7Y", "comboKeyScale7", "ShowComboKey7", &g_Config.touchCombo7, defaultTouchPosHide, true, true),
|
||||
ConfigSetting("fcombo8X", "fcombo8Y", "comboKeyScale8", "ShowComboKey8", &g_Config.touchCombo8, defaultTouchPosHide, true, true),
|
||||
ConfigSetting("fcombo9X", "fcombo9Y", "comboKeyScale9", "ShowComboKey9", &g_Config.touchCombo9, defaultTouchPosHide, true, true),
|
||||
|
||||
ConfigSetting("AnalogDeadzone", &g_Config.fAnalogDeadzone, 0.15f, true, true),
|
||||
ConfigSetting("AnalogInverseDeadzone", &g_Config.fAnalogInverseDeadzone, 0.0f, true, true),
|
||||
@ -1788,11 +1837,11 @@ void Config::ResetControlLayout() {
|
||||
reset(g_Config.touchCombo2);
|
||||
reset(g_Config.touchCombo3);
|
||||
reset(g_Config.touchCombo4);
|
||||
reset(g_Config.touchSpeed1Key);
|
||||
reset(g_Config.touchSpeed2Key);
|
||||
reset(g_Config.touchRapidFireKey);
|
||||
reset(g_Config.touchAnalogRotationCWKey);
|
||||
reset(g_Config.touchAnalogRotationCCWKey);
|
||||
reset(g_Config.touchCombo5);
|
||||
reset(g_Config.touchCombo6);
|
||||
reset(g_Config.touchCombo7);
|
||||
reset(g_Config.touchCombo8);
|
||||
reset(g_Config.touchCombo9);
|
||||
}
|
||||
|
||||
void Config::GetReportingInfo(UrlEncoder &data) {
|
||||
|
@ -55,6 +55,13 @@ struct ConfigTouchPos {
|
||||
bool show;
|
||||
};
|
||||
|
||||
struct ConfigCustomButton {
|
||||
uint64_t key;
|
||||
int image;
|
||||
int shape;
|
||||
bool toggle;
|
||||
};
|
||||
|
||||
struct Config {
|
||||
public:
|
||||
Config();
|
||||
@ -299,8 +306,6 @@ public:
|
||||
bool bGridView1;
|
||||
bool bGridView2;
|
||||
bool bGridView3;
|
||||
//Combo key screen flag
|
||||
int iComboMode;
|
||||
|
||||
// Right analog binding
|
||||
int iRightAnalogUp;
|
||||
@ -349,11 +354,11 @@ public:
|
||||
ConfigTouchPos touchCombo2;
|
||||
ConfigTouchPos touchCombo3;
|
||||
ConfigTouchPos touchCombo4;
|
||||
ConfigTouchPos touchSpeed1Key;
|
||||
ConfigTouchPos touchSpeed2Key;
|
||||
ConfigTouchPos touchRapidFireKey;
|
||||
ConfigTouchPos touchAnalogRotationCWKey;
|
||||
ConfigTouchPos touchAnalogRotationCCWKey;
|
||||
ConfigTouchPos touchCombo5;
|
||||
ConfigTouchPos touchCombo6;
|
||||
ConfigTouchPos touchCombo7;
|
||||
ConfigTouchPos touchCombo8;
|
||||
ConfigTouchPos touchCombo9;
|
||||
|
||||
// Controls Visibility
|
||||
bool bShowTouchControls;
|
||||
@ -363,18 +368,16 @@ public:
|
||||
bool bShowTouchTriangle;
|
||||
bool bShowTouchSquare;
|
||||
|
||||
// Combo_key mapping. These are bitfields.
|
||||
int iCombokey0;
|
||||
int iCombokey1;
|
||||
int iCombokey2;
|
||||
int iCombokey3;
|
||||
int iCombokey4;
|
||||
|
||||
bool bComboToggle0;
|
||||
bool bComboToggle1;
|
||||
bool bComboToggle2;
|
||||
bool bComboToggle3;
|
||||
bool bComboToggle4;
|
||||
ConfigCustomButton CustomKey0;
|
||||
ConfigCustomButton CustomKey1;
|
||||
ConfigCustomButton CustomKey2;
|
||||
ConfigCustomButton CustomKey3;
|
||||
ConfigCustomButton CustomKey4;
|
||||
ConfigCustomButton CustomKey5;
|
||||
ConfigCustomButton CustomKey6;
|
||||
ConfigCustomButton CustomKey7;
|
||||
ConfigCustomButton CustomKey8;
|
||||
ConfigCustomButton CustomKey9;
|
||||
|
||||
// Ignored on iOS and other platforms that lack pause.
|
||||
bool bShowTouchPause;
|
||||
|
@ -16,6 +16,7 @@ public:
|
||||
void Update();
|
||||
|
||||
bool Key(const KeyInput &key, bool *pauseTrigger);
|
||||
void pspKey(int pspKeyCode, int flags);
|
||||
bool Axis(const AxisInput &axis);
|
||||
|
||||
// Required callbacks
|
||||
@ -29,7 +30,6 @@ public:
|
||||
|
||||
private:
|
||||
void processAxis(const AxisInput &axis, int direction);
|
||||
void pspKey(int pspKeyCode, int flags);
|
||||
void setVKeyAnalog(char axis, int stick, int virtualKeyMin, int virtualKeyMax, bool setZero = true);
|
||||
|
||||
void SetPSPAxis(char axis, float value, int stick);
|
||||
|
@ -30,117 +30,167 @@
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Core/Config.h"
|
||||
|
||||
#include "TouchControlVisibilityScreen.h"
|
||||
#include "UI/ComboKeyMappingScreen.h"
|
||||
|
||||
class ButtonPreview : public UI::View {
|
||||
public:
|
||||
ButtonPreview(ImageID bgImg, ImageID img, float rotationIcon, bool flipShape, float rotationShape, int x, int y)
|
||||
: View(new UI::AnchorLayoutParams(x, y, UI::NONE, UI::NONE, true)), bgImg_(bgImg), img_(img), rotI_(rotationIcon),
|
||||
flipS_(flipShape), rotS_(rotationShape), x_(x), y_(y) {}
|
||||
|
||||
void Draw(UIContext &dc) override {
|
||||
float opacity = g_Config.iTouchButtonOpacity / 100.0f;
|
||||
|
||||
uint32_t colorBg = colorAlpha(g_Config.iTouchButtonStyle != 0 ? 0xFFFFFF : 0xc0b080, opacity);
|
||||
uint32_t color = colorAlpha(0xFFFFFF, opacity);
|
||||
|
||||
dc.Draw()->DrawImageRotated(bgImg_, x_, y_, 1.0f, rotS_*PI/180, colorBg, flipS_);
|
||||
dc.Draw()->DrawImageRotated(img_, x_, y_, 1.0f, rotI_*PI/180, color, false);
|
||||
}
|
||||
private:
|
||||
int x_;
|
||||
int y_;
|
||||
float rotI_;
|
||||
float rotS_;
|
||||
bool flipS_;
|
||||
ImageID bgImg_;
|
||||
ImageID img_;
|
||||
};
|
||||
|
||||
void ComboKeyScreen::CreateViews() {
|
||||
using namespace UI;
|
||||
using namespace CustomKey;
|
||||
auto co = GetI18NCategory("Controls");
|
||||
auto mc = GetI18NCategory("MappableControls");
|
||||
root_ = new LinearLayout(ORIENT_VERTICAL);
|
||||
root_->Add(new ItemHeader(co->T("Combo Key Setting")));
|
||||
root_->Add(new ItemHeader(co->T("Custom Key Setting")));
|
||||
LinearLayout *root__ = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(1.0));
|
||||
root_->Add(root__);
|
||||
LinearLayout *leftColumn = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(120, FILL_PARENT));
|
||||
auto di = GetI18NCategory("Dialog");
|
||||
|
||||
static const ImageID comboKeyImages[5] = {
|
||||
ImageID("I_1"), ImageID("I_2"), ImageID("I_3"), ImageID("I_4"), ImageID("I_5"),
|
||||
};
|
||||
|
||||
comboselect = new ChoiceStrip(ORIENT_VERTICAL, new AnchorLayoutParams(10, 10, NONE, NONE));
|
||||
comboselect->SetSpacing(10);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
comboselect->AddChoice(comboKeyImages[i]);
|
||||
}
|
||||
comboselect->SetSelection(*mode, false);
|
||||
comboselect->OnChoice.Handle(this, &ComboKeyScreen::onCombo);
|
||||
leftColumn->Add(comboselect);
|
||||
root__->Add(leftColumn);
|
||||
rightScroll_ = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT, 1.0f));
|
||||
leftColumn->Add(new Spacer(new LinearLayoutParams(1.0f)));
|
||||
leftColumn->Add(new Choice(di->T("Back")))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
|
||||
root__->Add(rightScroll_);
|
||||
|
||||
const int cellSize = 400;
|
||||
|
||||
UI::GridLayoutSettings gridsettings(cellSize, 64, 5);
|
||||
gridsettings.fillCells = true;
|
||||
GridLayout *grid = rightScroll_->Add(new GridLayout(gridsettings, new LayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
|
||||
bool *toggle = nullptr;
|
||||
ConfigCustomButton* cfg = nullptr;
|
||||
bool* show = nullptr;
|
||||
memset(array, 0, sizeof(array));
|
||||
switch (*mode) {
|
||||
switch (id_) {
|
||||
case 0:
|
||||
toggle = &g_Config.bComboToggle0;
|
||||
for (int i = 0; i < 16; i++)
|
||||
array[i] = (0x01 == ((g_Config.iCombokey0 >> i) & 0x01));
|
||||
cfg = &g_Config.CustomKey0;
|
||||
show = &g_Config.touchCombo0.show;
|
||||
for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++)
|
||||
array[i] = (0x01 == ((g_Config.CustomKey0.key >> i) & 0x01));
|
||||
break;
|
||||
case 1:
|
||||
toggle = &g_Config.bComboToggle1;
|
||||
for (int i = 0; i < 16; i++)
|
||||
array[i] = (0x01 == ((g_Config.iCombokey1 >> i) & 0x01));
|
||||
cfg = &g_Config.CustomKey1;
|
||||
show = &g_Config.touchCombo1.show;
|
||||
for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++)
|
||||
array[i] = (0x01 == ((g_Config.CustomKey1.key >> i) & 0x01));
|
||||
break;
|
||||
case 2:
|
||||
toggle = &g_Config.bComboToggle2;
|
||||
for (int i = 0; i < 16; i++)
|
||||
array[i] = (0x01 == ((g_Config.iCombokey2 >> i) & 0x01));
|
||||
cfg = &g_Config.CustomKey2;
|
||||
show = &g_Config.touchCombo2.show;
|
||||
for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++)
|
||||
array[i] = (0x01 == ((g_Config.CustomKey2.key >> i) & 0x01));
|
||||
break;
|
||||
case 3:
|
||||
toggle = &g_Config.bComboToggle3;
|
||||
for (int i = 0; i < 16; i++)
|
||||
array[i] = (0x01 == ((g_Config.iCombokey3 >> i) & 0x01));
|
||||
cfg = &g_Config.CustomKey3;
|
||||
show = &g_Config.touchCombo3.show;
|
||||
for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++)
|
||||
array[i] = (0x01 == ((g_Config.CustomKey3.key >> i) & 0x01));
|
||||
break;
|
||||
case 4:
|
||||
toggle = &g_Config.bComboToggle4;
|
||||
for (int i = 0; i < 16; i++)
|
||||
array[i] = (0x01 == ((g_Config.iCombokey4 >> i) & 0x01));
|
||||
cfg = &g_Config.CustomKey4;
|
||||
show = &g_Config.touchCombo4.show;
|
||||
for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++)
|
||||
array[i] = (0x01 == ((g_Config.CustomKey4.key >> i) & 0x01));
|
||||
break;
|
||||
case 5:
|
||||
cfg = &g_Config.CustomKey5;
|
||||
show = &g_Config.touchCombo5.show;
|
||||
for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++)
|
||||
array[i] = (0x01 == ((g_Config.CustomKey5.key >> i) & 0x01));
|
||||
break;
|
||||
case 6:
|
||||
cfg = &g_Config.CustomKey6;
|
||||
show = &g_Config.touchCombo6.show;
|
||||
for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++)
|
||||
array[i] = (0x01 == ((g_Config.CustomKey6.key >> i) & 0x01));
|
||||
break;
|
||||
case 7:
|
||||
cfg = &g_Config.CustomKey7;
|
||||
show = &g_Config.touchCombo7.show;
|
||||
for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++)
|
||||
array[i] = (0x01 == ((g_Config.CustomKey7.key >> i) & 0x01));
|
||||
break;
|
||||
case 8:
|
||||
cfg = &g_Config.CustomKey8;
|
||||
show = &g_Config.touchCombo8.show;
|
||||
for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++)
|
||||
array[i] = (0x01 == ((g_Config.CustomKey8.key >> i) & 0x01));
|
||||
break;
|
||||
case 9:
|
||||
cfg = &g_Config.CustomKey9;
|
||||
show = &g_Config.touchCombo9.show;
|
||||
for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++)
|
||||
array[i] = (0x01 == ((g_Config.CustomKey9.key >> i) & 0x01));
|
||||
break;
|
||||
default:
|
||||
// This shouldn't happen, let's just not crash.
|
||||
toggle = &g_Config.bComboToggle0;
|
||||
cfg = &g_Config.CustomKey0;
|
||||
show = &g_Config.touchCombo0.show;
|
||||
break;
|
||||
}
|
||||
|
||||
std::map<std::string, ImageID> keyImages;
|
||||
keyImages["Circle"] = ImageID("I_CIRCLE");
|
||||
keyImages["Cross"] = ImageID("I_CROSS");
|
||||
keyImages["Square"] = ImageID("I_SQUARE");
|
||||
keyImages["Triangle"] = ImageID("I_TRIANGLE");
|
||||
keyImages["L"] = ImageID("I_L");
|
||||
keyImages["R"] = ImageID("I_R");
|
||||
keyImages["Start"] = ImageID("I_START");
|
||||
keyImages["Select"] = ImageID("I_SELECT");
|
||||
keyToggles["Circle"] = &array[13];
|
||||
keyToggles["Cross"] = &array[14];
|
||||
keyToggles["Square"] = &array[15];
|
||||
keyToggles["Triangle"] = &array[12];
|
||||
keyToggles["L"] = &array[8];
|
||||
keyToggles["R"] = &array[9];
|
||||
keyToggles["Left"] = &array[7];
|
||||
keyToggles["Up"] = &array[4];
|
||||
keyToggles["Right"] = &array[5];
|
||||
keyToggles["Down"] = &array[6];
|
||||
keyToggles["Start"] = &array[3];
|
||||
keyToggles["Select"] = &array[0];
|
||||
leftColumn->Add(new ButtonPreview(g_Config.iTouchButtonStyle == 0 ? comboKeyShapes[cfg->shape].i : comboKeyShapes[cfg->shape].l,
|
||||
comboKeyImages[cfg->image].i, comboKeyImages[cfg->image].r, comboKeyShapes[cfg->shape].f, comboKeyShapes[cfg->shape].r, 62, 82));
|
||||
|
||||
std::map<std::string, ImageID>::iterator imageFinder;
|
||||
root__->Add(leftColumn);
|
||||
rightScroll_ = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT, 1.0f));
|
||||
leftColumn->Add(new Spacer(new LinearLayoutParams(1.0f)));
|
||||
leftColumn->Add(new Choice(di->T("Back")))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
|
||||
root__->Add(rightScroll_);
|
||||
|
||||
auto mc = GetI18NCategory("MappableControls");
|
||||
LinearLayout *vertLayout = new LinearLayout(ORIENT_VERTICAL);
|
||||
rightScroll_->Add(vertLayout);
|
||||
|
||||
vertLayout->Add(new ItemHeader(co->T("Button Style")));
|
||||
vertLayout->Add(new CheckBox(show, co->T("Visible")));
|
||||
|
||||
for (auto i = keyToggles.begin(); i != keyToggles.end(); ++i) {
|
||||
// All icon and name are defined in GamepadEmu.h
|
||||
static const char *imageNames[ARRAY_SIZE(comboKeyImages)];
|
||||
for (int i = 0; i < ARRAY_SIZE(imageNames); ++i) {
|
||||
imageNames[i] = comboKeyImages[i].n;
|
||||
}
|
||||
PopupMultiChoice *icon = vertLayout->Add(new PopupMultiChoice(&(cfg->image), co->T("Icon"), imageNames, 0, ARRAY_SIZE(imageNames), mc->GetName(), screenManager()));
|
||||
icon->OnChoice.Handle(this, &ComboKeyScreen::onCombo);
|
||||
|
||||
// All shape and name are defined in GamepadEmu.h
|
||||
static const char *shapeNames[ARRAY_SIZE(comboKeyShapes)];
|
||||
for (int i = 0; i < ARRAY_SIZE(shapeNames); ++i) {
|
||||
shapeNames[i] = comboKeyShapes[i].n;
|
||||
}
|
||||
vertLayout->Add(new PopupMultiChoice(&(cfg->shape), co->T("Shape"), shapeNames, 0, ARRAY_SIZE(shapeNames), mc->GetName(), screenManager()))->OnChoice.Handle(this, &ComboKeyScreen::onCombo);
|
||||
|
||||
vertLayout->Add(new ItemHeader(co->T("Button Binding")));
|
||||
vertLayout->Add(new CheckBox(&(cfg->toggle), co->T("Toggle mode")));
|
||||
|
||||
const int cellSize = 400;
|
||||
UI::GridLayoutSettings gridsettings(cellSize, 64, 5);
|
||||
gridsettings.fillCells = true;
|
||||
GridLayout *grid = vertLayout->Add(new GridLayout(gridsettings, new LayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
|
||||
// Button name, image and action are defined in GamepadEmu.h
|
||||
for (int i = 0; i < ARRAY_SIZE(comboKeyList); ++i) {
|
||||
LinearLayout *row = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
|
||||
row->SetSpacing(0);
|
||||
|
||||
CheckBox *checkbox = new CheckBox(i->second, "", "", new LinearLayoutParams(50, WRAP_CONTENT));
|
||||
CheckBox *checkbox = new CheckBox(&array[i], "", "", new LinearLayoutParams(50, WRAP_CONTENT));
|
||||
row->Add(checkbox);
|
||||
|
||||
imageFinder = keyImages.find(i->first);
|
||||
Choice *choice;
|
||||
if (imageFinder != keyImages.end()) {
|
||||
choice = new Choice(keyImages[imageFinder->first], new LinearLayoutParams(1.0f));
|
||||
}
|
||||
else {
|
||||
choice = new Choice(mc->T(i->first.c_str()), new LinearLayoutParams(1.0f));
|
||||
if (comboKeyList[i].i.isValid()) {
|
||||
choice = new Choice(comboKeyList[i].i, new LinearLayoutParams(1.0f));
|
||||
} else {
|
||||
choice = new Choice(mc->T(comboKeyList[i].n), new LinearLayoutParams(1.0f));
|
||||
}
|
||||
|
||||
ChoiceEventHandler *choiceEventHandler = new ChoiceEventHandler(checkbox);
|
||||
@ -150,76 +200,67 @@ void ComboKeyScreen::CreateViews() {
|
||||
|
||||
row->Add(choice);
|
||||
grid->Add(row);
|
||||
|
||||
}
|
||||
|
||||
LinearLayout *row = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT));
|
||||
row->SetSpacing(0);
|
||||
|
||||
CheckBox *checkbox = new CheckBox(toggle, "", "", new LinearLayoutParams(50, WRAP_CONTENT));
|
||||
row->Add(checkbox);
|
||||
|
||||
Choice *choice = new Choice(mc->T("Toggle mode"), new LinearLayoutParams(1.0f));
|
||||
ChoiceEventHandler *choiceEventHandler = new ChoiceEventHandler(checkbox);
|
||||
choice->OnClick.Handle(choiceEventHandler, &ChoiceEventHandler::onChoiceClick);
|
||||
choice->SetCentered(true);
|
||||
|
||||
row->Add(choice);
|
||||
grid->Add(row);
|
||||
}
|
||||
|
||||
static int arrayToInt(bool ary[16]) {
|
||||
int value = 0;
|
||||
for (int i = 15; i >= 0; i--) {
|
||||
static uint64_t arrayToInt(bool ary[ARRAY_SIZE(CustomKey::comboKeyList)]) {
|
||||
uint64_t value = 0;
|
||||
for (int i = ARRAY_SIZE(CustomKey::comboKeyList)-1; i >= 0; i--) {
|
||||
value |= ary[i] ? 1 : 0;
|
||||
value = value << 1;
|
||||
if (i > 0) {
|
||||
value = value << 1;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void ComboKeyScreen::saveArray() {
|
||||
switch (id_) {
|
||||
case 0:
|
||||
g_Config.CustomKey0.key = arrayToInt(array);
|
||||
break;
|
||||
case 1:
|
||||
g_Config.CustomKey1.key = arrayToInt(array);
|
||||
break;
|
||||
case 2:
|
||||
g_Config.CustomKey2.key = arrayToInt(array);
|
||||
break;
|
||||
case 3:
|
||||
g_Config.CustomKey3.key = arrayToInt(array);
|
||||
break;
|
||||
case 4:
|
||||
g_Config.CustomKey4.key = arrayToInt(array);
|
||||
break;
|
||||
case 5:
|
||||
g_Config.CustomKey5.key = arrayToInt(array);
|
||||
break;
|
||||
case 6:
|
||||
g_Config.CustomKey6.key = arrayToInt(array);
|
||||
break;
|
||||
case 7:
|
||||
g_Config.CustomKey7.key = arrayToInt(array);
|
||||
break;
|
||||
case 8:
|
||||
g_Config.CustomKey8.key = arrayToInt(array);
|
||||
break;
|
||||
case 9:
|
||||
g_Config.CustomKey9.key = arrayToInt(array);
|
||||
break;
|
||||
}
|
||||
return value >> 1;
|
||||
}
|
||||
|
||||
void ComboKeyScreen::onFinish(DialogResult result) {
|
||||
switch (*mode) {
|
||||
case 0:
|
||||
g_Config.iCombokey0 = arrayToInt(array);
|
||||
break;
|
||||
case 1:
|
||||
g_Config.iCombokey1 = arrayToInt(array);
|
||||
break;
|
||||
case 2:
|
||||
g_Config.iCombokey2 = arrayToInt(array);
|
||||
break;
|
||||
case 3:
|
||||
g_Config.iCombokey3 = arrayToInt(array);
|
||||
break;
|
||||
case 4:
|
||||
g_Config.iCombokey4 = arrayToInt(array);
|
||||
break;
|
||||
}
|
||||
g_Config.Save("ComboKeyScreen::onFInish");
|
||||
saveArray();
|
||||
g_Config.Save("ComboKeyScreen::onFinish");
|
||||
}
|
||||
|
||||
UI::EventReturn ComboKeyScreen::ChoiceEventHandler::onChoiceClick(UI::EventParams &e){
|
||||
checkbox_->Toggle();
|
||||
|
||||
|
||||
return UI::EVENT_DONE;
|
||||
};
|
||||
|
||||
UI::EventReturn ComboKeyScreen::onCombo(UI::EventParams &e) {
|
||||
switch (*mode){
|
||||
case 0:g_Config.iCombokey0 = arrayToInt(array);
|
||||
break;
|
||||
case 1:g_Config.iCombokey1 = arrayToInt(array);
|
||||
break;
|
||||
case 2:g_Config.iCombokey2 = arrayToInt(array);
|
||||
break;
|
||||
case 3:g_Config.iCombokey3 = arrayToInt(array);
|
||||
break;
|
||||
case 4:g_Config.iCombokey4 = arrayToInt(array);
|
||||
}
|
||||
*mode = comboselect->GetSelection();
|
||||
saveArray();
|
||||
CreateViews();
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "MiscScreens.h"
|
||||
#include "UI/GamepadEmu.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
@ -27,15 +28,16 @@ namespace UI {
|
||||
|
||||
class ComboKeyScreen : public UIDialogScreenWithBackground {
|
||||
public:
|
||||
ComboKeyScreen(int *key): mode(key) {}
|
||||
ComboKeyScreen(int id): id_(id) {}
|
||||
|
||||
void CreateViews() override;
|
||||
void onFinish(DialogResult result) override;
|
||||
UI::EventReturn onCombo(UI::EventParams &e);
|
||||
private:
|
||||
std::map<std::string, bool*> keyToggles;
|
||||
bool array[16];
|
||||
int *mode;
|
||||
void saveArray();
|
||||
|
||||
bool array[ARRAY_SIZE(CustomKey::comboKeyList)];
|
||||
int id_;
|
||||
UI::ChoiceStrip *comboselect;
|
||||
UI::ScrollView *rightScroll_;
|
||||
class ChoiceEventHandler{
|
||||
|
@ -775,7 +775,7 @@ void EmuScreen::CreateViews() {
|
||||
|
||||
const Bounds &bounds = screenManager()->getUIContext()->GetLayoutBounds();
|
||||
InitPadLayout(bounds.w, bounds.h);
|
||||
root_ = CreatePadLayout(bounds.w, bounds.h, &pauseTrigger_);
|
||||
root_ = CreatePadLayout(bounds.w, bounds.h, &pauseTrigger_, &controlMapper_);
|
||||
if (g_Config.bShowDeveloperMenu) {
|
||||
root_->Add(new Button(dev->T("DevMenu")))->OnClick.Handle(this, &EmuScreen::OnDevTools);
|
||||
}
|
||||
|
@ -49,7 +49,6 @@
|
||||
#include "UI/TouchControlVisibilityScreen.h"
|
||||
#include "UI/TiltAnalogSettingsScreen.h"
|
||||
#include "UI/TiltEventProcessor.h"
|
||||
#include "UI/ComboKeyMappingScreen.h"
|
||||
#include "UI/GPUDriverTestScreen.h"
|
||||
#include "UI/MemStickScreen.h"
|
||||
|
||||
@ -688,7 +687,7 @@ void GameSettingsScreen::CreateViews() {
|
||||
if (System_GetPropertyInt(SYSPROP_DEVICE_TYPE) != DEVICE_TYPE_TV) {
|
||||
controlsSettings->Add(new ItemHeader(co->T("OnScreen", "On-Screen Touch Controls")));
|
||||
controlsSettings->Add(new CheckBox(&g_Config.bShowTouchControls, co->T("OnScreen", "On-Screen Touch Controls")));
|
||||
layoutEditorChoice_ = controlsSettings->Add(new Choice(co->T("Custom layout...")));
|
||||
layoutEditorChoice_ = controlsSettings->Add(new Choice(co->T("Customize Touch Controls")));
|
||||
layoutEditorChoice_->OnClick.Handle(this, &GameSettingsScreen::OnTouchControlLayout);
|
||||
layoutEditorChoice_->SetEnabledPtr(&g_Config.bShowTouchControls);
|
||||
|
||||
@ -696,11 +695,6 @@ void GameSettingsScreen::CreateViews() {
|
||||
CheckBox *floatingAnalog = controlsSettings->Add(new CheckBox(&g_Config.bAutoCenterTouchAnalog, co->T("Auto-centering analog stick")));
|
||||
floatingAnalog->SetEnabledPtr(&g_Config.bShowTouchControls);
|
||||
|
||||
// Combo key setup
|
||||
Choice *comboKey = controlsSettings->Add(new Choice(co->T("Combo Key Setup")));
|
||||
comboKey->OnClick.Handle(this, &GameSettingsScreen::OnComboKey);
|
||||
comboKey->SetEnabledPtr(&g_Config.bShowTouchControls);
|
||||
|
||||
// On non iOS systems, offer to let the user see this button.
|
||||
// Some Windows touch devices don't have a back button or other button to call up the menu.
|
||||
if (System_GetPropertyBool(SYSPROP_HAS_BACK_BUTTON)) {
|
||||
@ -1472,11 +1466,6 @@ UI::EventReturn GameSettingsScreen::OnChangeMacAddress(UI::EventParams &e) {
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn GameSettingsScreen::OnComboKey(UI::EventParams &e) {
|
||||
screenManager()->push(new ComboKeyScreen(&g_Config.iComboMode));
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn GameSettingsScreen::OnLanguage(UI::EventParams &e) {
|
||||
auto dev = GetI18NCategory("Developer");
|
||||
auto langScreen = new NewLanguageScreen(dev->T("Language"));
|
||||
|
@ -74,7 +74,6 @@ private:
|
||||
UI::EventReturn OnDumpNextFrameToLog(UI::EventParams &e);
|
||||
UI::EventReturn OnTiltTypeChange(UI::EventParams &e);
|
||||
UI::EventReturn OnTiltCustomize(UI::EventParams &e);
|
||||
UI::EventReturn OnComboKey(UI::EventParams &e);
|
||||
|
||||
// Global settings handlers
|
||||
UI::EventReturn OnLanguage(UI::EventParams &e);
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "Core/Core.h"
|
||||
#include "Core/System.h"
|
||||
#include "Core/HLE/sceCtrl.h"
|
||||
#include "Core/ControlMapper.h"
|
||||
#include "UI/GamepadEmu.h"
|
||||
|
||||
static u32 GetButtonColor() {
|
||||
@ -158,68 +159,6 @@ void BoolButton::Touch(const TouchInput &input) {
|
||||
}
|
||||
}
|
||||
|
||||
void FPSLimitButton::Touch(const TouchInput &input) {
|
||||
bool lastDown = pointerDownMask_ != 0;
|
||||
MultiTouchButton::Touch(input);
|
||||
bool down = pointerDownMask_ != 0;
|
||||
|
||||
if (!down && lastDown && IsDown()) {
|
||||
PSP_CoreParameter().fpsLimit = FPSLimit::NORMAL;
|
||||
} else if (down && !lastDown && PSP_CoreParameter().fpsLimit == FPSLimit::NORMAL) {
|
||||
int limit = limit_ == FPSLimit::CUSTOM1 ? g_Config.iFpsLimit1 : g_Config.iFpsLimit2;
|
||||
// Validate it actually has a setting (may this should override visible?)
|
||||
if (limit >= 0) {
|
||||
PSP_CoreParameter().fpsLimit = limit_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FPSLimitButton::IsDown() {
|
||||
return PSP_CoreParameter().fpsLimit == limit_;
|
||||
}
|
||||
|
||||
void RapidFireButton::Touch(const TouchInput &input) {
|
||||
bool lastDown = pointerDownMask_ != 0;
|
||||
MultiTouchButton::Touch(input);
|
||||
bool down = pointerDownMask_ != 0;
|
||||
if (down && !lastDown) {
|
||||
__CtrlSetRapidFire(!__CtrlGetRapidFire());
|
||||
}
|
||||
}
|
||||
|
||||
bool RapidFireButton::IsDown() {
|
||||
return __CtrlGetRapidFire();
|
||||
}
|
||||
|
||||
void AnalogRotationButton::Touch(const TouchInput &input) {
|
||||
bool lastDown = pointerDownMask_ != 0;
|
||||
MultiTouchButton::Touch(input);
|
||||
bool down = pointerDownMask_ != 0;
|
||||
if (down && !lastDown) {
|
||||
autoRotating_ = true;
|
||||
} else if (lastDown && !down) {
|
||||
autoRotating_ = false;
|
||||
__CtrlSetAnalogXY(0, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void AnalogRotationButton::Update() {
|
||||
const float now = time_now_d();
|
||||
float delta = now - lastFrameTime_;
|
||||
if (delta > 0) {
|
||||
secondsWithoutTouch_ += delta;
|
||||
}
|
||||
lastFrameTime_ = now;
|
||||
|
||||
if (autoRotating_) {
|
||||
float speed = clockWise_ ? -g_Config.fAnalogAutoRotSpeed : g_Config.fAnalogAutoRotSpeed;
|
||||
// Clamp to a square
|
||||
__CtrlSetAnalogXY(0,
|
||||
std::min(1.0f, std::max(-1.0f, 1.42f*cosf(now*speed))),
|
||||
std::min(1.0f, std::max(-1.0f, 1.42f*sinf(now*speed))));
|
||||
}
|
||||
}
|
||||
|
||||
void PSPButton::Touch(const TouchInput &input) {
|
||||
bool lastDown = pointerDownMask_ != 0;
|
||||
MultiTouchButton::Touch(input);
|
||||
@ -234,31 +173,30 @@ void PSPButton::Touch(const TouchInput &input) {
|
||||
}
|
||||
}
|
||||
|
||||
bool ComboKey::IsDown() {
|
||||
return (toggle_ && on_) || (!toggle_ && pointerDownMask_ != 0);
|
||||
}
|
||||
|
||||
void ComboKey::Touch(const TouchInput &input) {
|
||||
using namespace CustomKey;
|
||||
bool lastDown = pointerDownMask_ != 0;
|
||||
MultiTouchButton::Touch(input);
|
||||
bool down = pointerDownMask_ != 0;
|
||||
static const int combo[16] = {CTRL_SQUARE ,CTRL_TRIANGLE ,CTRL_CIRCLE ,CTRL_CROSS ,CTRL_UP ,CTRL_DOWN ,CTRL_LEFT ,CTRL_RIGHT ,CTRL_START ,CTRL_SELECT ,CTRL_LTRIGGER ,CTRL_RTRIGGER };
|
||||
if (down || lastDown) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (pspButtonBit_ & combo[i])
|
||||
{
|
||||
if (down && !lastDown) {
|
||||
if (g_Config.bHapticFeedback) {
|
||||
Vibrate(HAPTIC_VIRTUAL_KEY);
|
||||
}
|
||||
if (!toggle_) {
|
||||
__CtrlButtonDown(combo[i]);
|
||||
} else {
|
||||
if (__CtrlPeekButtons() & combo[i])
|
||||
__CtrlButtonUp(combo[i]);
|
||||
else
|
||||
__CtrlButtonDown(combo[i]);
|
||||
}
|
||||
}
|
||||
else if (lastDown && !down && !toggle_) {
|
||||
__CtrlButtonUp(combo[i]);
|
||||
}
|
||||
|
||||
if (down && !lastDown) {
|
||||
if (g_Config.bHapticFeedback)
|
||||
Vibrate(HAPTIC_VIRTUAL_KEY);
|
||||
for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++) {
|
||||
if (pspButtonBit_ & (1UL << i)) {
|
||||
controllMapper_->pspKey(comboKeyList[i].c, (on_ && toggle_) ? KEY_UP : KEY_DOWN);
|
||||
}
|
||||
}
|
||||
if (toggle_)
|
||||
on_ = !on_;
|
||||
} else if (!toggle_ && lastDown && !down) {
|
||||
for (int i = 0; i < ARRAY_SIZE(comboKeyList); i++) {
|
||||
if (pspButtonBit_ & (1UL << i)) {
|
||||
controllMapper_->pspKey(comboKeyList[i].c, KEY_UP);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -697,12 +635,6 @@ void InitPadLayout(float xres, float yres, float globalScale) {
|
||||
int unthrottle_key_Y = yres - 60 * scale;
|
||||
initTouchPos(g_Config.touchUnthrottleKey, unthrottle_key_X, unthrottle_key_Y);
|
||||
|
||||
initTouchPos(g_Config.touchSpeed1Key, unthrottle_key_X, unthrottle_key_Y - 60 * scale);
|
||||
initTouchPos(g_Config.touchSpeed2Key, unthrottle_key_X + bottom_key_spacing * scale, unthrottle_key_Y - 60 * scale);
|
||||
initTouchPos(g_Config.touchRapidFireKey, unthrottle_key_X + 2*bottom_key_spacing * scale, unthrottle_key_Y - 60 * scale);
|
||||
initTouchPos(g_Config.touchAnalogRotationCCWKey, unthrottle_key_X, unthrottle_key_Y - 120 * scale);
|
||||
initTouchPos(g_Config.touchAnalogRotationCWKey, unthrottle_key_X + bottom_key_spacing * scale, unthrottle_key_Y - 120 * scale);
|
||||
|
||||
// L and R------------------------------------------------------------
|
||||
// Put them above the analog stick / above the buttons to the right.
|
||||
// The corners were very hard to reach..
|
||||
@ -735,9 +667,29 @@ void InitPadLayout(float xres, float yres, float globalScale) {
|
||||
int combo4_key_X = halfW + bottom_key_spacing * scale * 2.2f;
|
||||
int combo4_key_Y = yres / 3;
|
||||
initTouchPos(g_Config.touchCombo4, combo4_key_X, combo4_key_Y);
|
||||
|
||||
int combo5_key_X = halfW - bottom_key_spacing * scale * 1.2f;
|
||||
int combo5_key_Y = yres / 2;
|
||||
initTouchPos(g_Config.touchCombo5, combo5_key_X, combo5_key_Y);
|
||||
|
||||
int combo6_key_X = halfW - bottom_key_spacing * scale * 2.2f;
|
||||
int combo6_key_Y = yres / 2;
|
||||
initTouchPos(g_Config.touchCombo6, combo6_key_X, combo6_key_Y);
|
||||
|
||||
int combo7_key_X = halfW - bottom_key_spacing * scale * 3.2f;
|
||||
int combo7_key_Y = yres / 2;
|
||||
initTouchPos(g_Config.touchCombo7, combo7_key_X, combo7_key_Y);
|
||||
|
||||
int combo8_key_X = halfW - bottom_key_spacing * scale * 1.2f;
|
||||
int combo8_key_Y = yres / 3;
|
||||
initTouchPos(g_Config.touchCombo8, combo8_key_X, combo8_key_Y);
|
||||
|
||||
int combo9_key_X = halfW - bottom_key_spacing * scale * 2.2f;
|
||||
int combo9_key_Y = yres / 3;
|
||||
initTouchPos(g_Config.touchCombo9, combo9_key_X, combo9_key_Y);
|
||||
}
|
||||
|
||||
UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause) {
|
||||
UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause, ControlMapper* controllMapper) {
|
||||
using namespace UI;
|
||||
|
||||
AnchorLayout *root = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT));
|
||||
@ -764,13 +716,11 @@ UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause) {
|
||||
const int halfW = xres / 2;
|
||||
|
||||
const ImageID roundImage = g_Config.iTouchButtonStyle ? ImageID("I_ROUND_LINE") : ImageID("I_ROUND");
|
||||
|
||||
const ImageID rectImage = g_Config.iTouchButtonStyle ? ImageID("I_RECT_LINE") : ImageID("I_RECT");
|
||||
const ImageID shoulderImage = g_Config.iTouchButtonStyle ? ImageID("I_SHOULDER_LINE") : ImageID("I_SHOULDER");
|
||||
const ImageID dirImage = g_Config.iTouchButtonStyle ? ImageID("I_DIR_LINE") : ImageID("I_DIR");
|
||||
const ImageID stickImage = g_Config.iTouchButtonStyle ? ImageID("I_STICK_LINE") : ImageID("I_STICK");
|
||||
const ImageID stickBg = g_Config.iTouchButtonStyle ? ImageID("I_STICK_BG_LINE") : ImageID("I_STICK_BG");
|
||||
static const ImageID comboKeyImages[5] = { ImageID("I_1"), ImageID("I_2"), ImageID("I_3"), ImageID("I_4"), ImageID("I_5") };
|
||||
|
||||
auto addPSPButton = [=](int buttonBit, const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, const ConfigTouchPos &touch, ButtonOffset off = { 0, 0 }) -> PSPButton * {
|
||||
if (touch.show) {
|
||||
@ -778,21 +728,21 @@ UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause) {
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
auto addComboKey = [=](int buttonBit, const char *key, bool toggle, ImageID bgImg, ImageID bgDownImg, ImageID img, const ConfigTouchPos &touch) -> ComboKey * {
|
||||
if (touch.show) {
|
||||
return root->Add(new ComboKey(buttonBit, key, toggle, bgImg, bgDownImg, img, touch.scale, buttonLayoutParams(touch)));
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
auto addBoolButton = [=](bool *value, const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, const ConfigTouchPos &touch) -> BoolButton * {
|
||||
if (touch.show) {
|
||||
return root->Add(new BoolButton(value, key, bgImg, bgDownImg, img, touch.scale, buttonLayoutParams(touch)));
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
auto addFPSLimitButton = [=](FPSLimit value, const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, const ConfigTouchPos &touch) -> FPSLimitButton * {
|
||||
auto addComboKey = [=](const ConfigCustomButton& cfg, const char *key, const ConfigTouchPos &touch) -> ComboKey * {
|
||||
using namespace CustomKey;
|
||||
if (touch.show) {
|
||||
return root->Add(new FPSLimitButton(value, key, bgImg, bgDownImg, img, touch.scale, buttonLayoutParams(touch)));
|
||||
auto aux = root->Add(new ComboKey(cfg.key, key, cfg.toggle, controllMapper,
|
||||
g_Config.iTouchButtonStyle == 0 ? comboKeyShapes[cfg.shape].i : comboKeyShapes[cfg.shape].l, comboKeyShapes[cfg.shape].i,
|
||||
comboKeyImages[cfg.image].i, touch.scale, buttonLayoutParams(touch)));
|
||||
aux->SetAngle(comboKeyImages[cfg.image].r, comboKeyShapes[cfg.shape].r);
|
||||
aux->FlipImageH(comboKeyShapes[cfg.shape].f);
|
||||
return aux;
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
@ -825,28 +775,6 @@ UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause) {
|
||||
});
|
||||
}
|
||||
|
||||
if (g_Config.touchRapidFireKey.show) {
|
||||
auto rapidFire = root->Add(new RapidFireButton("Rapid fire button", rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchRapidFireKey.scale, buttonLayoutParams(g_Config.touchRapidFireKey)));
|
||||
rapidFire->SetAngle(90.0f, 180.0f);
|
||||
}
|
||||
|
||||
if (g_Config.touchAnalogRotationCWKey.show) {
|
||||
auto analogRotationCC = root->Add(new AnalogRotationButton(true, "Analog clockwise rotation button", rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchAnalogRotationCWKey.scale, buttonLayoutParams(g_Config.touchAnalogRotationCWKey)));
|
||||
analogRotationCC->SetAngle(190.0f, 180.0f);
|
||||
}
|
||||
|
||||
if (g_Config.touchAnalogRotationCCWKey.show) {
|
||||
auto analogRotationCCW = root->Add(new AnalogRotationButton(false, "Analog counter clockwise rotation button", rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchAnalogRotationCCWKey.scale, buttonLayoutParams(g_Config.touchAnalogRotationCCWKey)));
|
||||
analogRotationCCW->SetAngle(350.0f, 180.0f);
|
||||
}
|
||||
|
||||
FPSLimitButton *speed1 = addFPSLimitButton(FPSLimit::CUSTOM1, "Alternate speed 1 button", rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchSpeed1Key);
|
||||
if (speed1)
|
||||
speed1->SetAngle(170.0f, 180.0f);
|
||||
FPSLimitButton *speed2 = addFPSLimitButton(FPSLimit::CUSTOM2, "Alternate speed 2 button", rectImage, ImageID("I_RECT"), ImageID("I_ARROW"), g_Config.touchSpeed2Key);
|
||||
if (speed2)
|
||||
speed2->SetAngle(190.0f, 180.0f);
|
||||
|
||||
addPSPButton(CTRL_LTRIGGER, "Left shoulder button", shoulderImage, ImageID("I_SHOULDER"), ImageID("I_L"), g_Config.touchLKey);
|
||||
PSPButton *rTrigger = addPSPButton(CTRL_RTRIGGER, "Right shoulder button", shoulderImage, ImageID("I_SHOULDER"), ImageID("I_R"), g_Config.touchRKey);
|
||||
if (rTrigger)
|
||||
@ -865,11 +793,16 @@ UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause) {
|
||||
root->Add(new PSPStick(stickBg, "Right analog stick", stickImage, ImageID("I_STICK"), 1, g_Config.touchRightAnalogStick.scale, buttonLayoutParams(g_Config.touchRightAnalogStick)));
|
||||
}
|
||||
|
||||
addComboKey(g_Config.iCombokey0, "Combo 1 button", g_Config.bComboToggle0, roundImage, ImageID("I_ROUND"), comboKeyImages[0], g_Config.touchCombo0);
|
||||
addComboKey(g_Config.iCombokey1, "Combo 2 button", g_Config.bComboToggle1, roundImage, ImageID("I_ROUND"), comboKeyImages[1], g_Config.touchCombo1);
|
||||
addComboKey(g_Config.iCombokey2, "Combo 3 button", g_Config.bComboToggle2, roundImage, ImageID("I_ROUND"), comboKeyImages[2], g_Config.touchCombo2);
|
||||
addComboKey(g_Config.iCombokey3, "Combo 4 button", g_Config.bComboToggle3, roundImage, ImageID("I_ROUND"), comboKeyImages[3], g_Config.touchCombo3);
|
||||
addComboKey(g_Config.iCombokey4, "Combo 5 button", g_Config.bComboToggle4, roundImage, ImageID("I_ROUND"), comboKeyImages[4], g_Config.touchCombo4);
|
||||
addComboKey(g_Config.CustomKey0, "Custom 1 button", g_Config.touchCombo0);
|
||||
addComboKey(g_Config.CustomKey1, "Custom 2 button", g_Config.touchCombo1);
|
||||
addComboKey(g_Config.CustomKey2, "Custom 3 button", g_Config.touchCombo2);
|
||||
addComboKey(g_Config.CustomKey3, "Custom 4 button", g_Config.touchCombo3);
|
||||
addComboKey(g_Config.CustomKey4, "Custom 5 button", g_Config.touchCombo4);
|
||||
addComboKey(g_Config.CustomKey5, "Custom 6 button", g_Config.touchCombo5);
|
||||
addComboKey(g_Config.CustomKey6, "Custom 7 button", g_Config.touchCombo6);
|
||||
addComboKey(g_Config.CustomKey7, "Custom 8 button", g_Config.touchCombo7);
|
||||
addComboKey(g_Config.CustomKey8, "Custom 9 button", g_Config.touchCombo8);
|
||||
addComboKey(g_Config.CustomKey9, "Custom 10 button", g_Config.touchCombo9);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
151
UI/GamepadEmu.h
@ -23,6 +23,7 @@
|
||||
#include "Common/UI/View.h"
|
||||
#include "Common/UI/ViewGroup.h"
|
||||
#include "Core/CoreParameter.h"
|
||||
#include "UI/EmuScreen.h"
|
||||
|
||||
class GamepadView : public UI::View {
|
||||
public:
|
||||
@ -86,41 +87,6 @@ private:
|
||||
bool *value_;
|
||||
};
|
||||
|
||||
class FPSLimitButton : public MultiTouchButton {
|
||||
public:
|
||||
FPSLimitButton(FPSLimit limit, const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams)
|
||||
: MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams), limit_(limit) {
|
||||
|
||||
}
|
||||
void Touch(const TouchInput &input) override;
|
||||
bool IsDown() override;
|
||||
|
||||
private:
|
||||
FPSLimit limit_;
|
||||
};
|
||||
|
||||
class RapidFireButton : public MultiTouchButton {
|
||||
public:
|
||||
RapidFireButton(const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams)
|
||||
: MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams) {
|
||||
}
|
||||
void Touch(const TouchInput &input) override;
|
||||
bool IsDown() override;
|
||||
};
|
||||
|
||||
class AnalogRotationButton : public MultiTouchButton {
|
||||
public:
|
||||
AnalogRotationButton(bool clockWise, const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams)
|
||||
: MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams), clockWise_(clockWise) {
|
||||
}
|
||||
void Touch(const TouchInput &input) override;
|
||||
void Update() override;
|
||||
|
||||
private:
|
||||
bool autoRotating_ = false;
|
||||
bool clockWise_;
|
||||
};
|
||||
|
||||
class PSPButton : public MultiTouchButton {
|
||||
public:
|
||||
PSPButton(int pspButtonBit, const char *key, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams)
|
||||
@ -196,18 +162,125 @@ private:
|
||||
//initializes the layout from Config. if a default layout does not exist,
|
||||
//it sets up default values
|
||||
void InitPadLayout(float xres, float yres, float globalScale = 1.15f);
|
||||
UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause);
|
||||
UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause, ControlMapper* controllMapper);
|
||||
|
||||
const int D_pad_Radius = 50;
|
||||
const int baseActionButtonSpacing = 60;
|
||||
|
||||
class ComboKey : public MultiTouchButton {
|
||||
public:
|
||||
ComboKey(int pspButtonBit, const char *key, bool toggle, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams)
|
||||
: MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams), pspButtonBit_(pspButtonBit), toggle_(toggle) {
|
||||
ComboKey(uint64_t pspButtonBit, const char *key, bool toggle, ControlMapper* controllMapper, ImageID bgImg, ImageID bgDownImg, ImageID img, float scale, UI::LayoutParams *layoutParams)
|
||||
: MultiTouchButton(key, bgImg, bgDownImg, img, scale, layoutParams), pspButtonBit_(pspButtonBit), toggle_(toggle), controllMapper_(controllMapper), on_(false) {
|
||||
}
|
||||
void Touch(const TouchInput &input) override;
|
||||
bool IsDown() override;
|
||||
private:
|
||||
int pspButtonBit_;
|
||||
uint64_t pspButtonBit_;
|
||||
bool toggle_;
|
||||
ControlMapper* controllMapper_;
|
||||
bool on_;
|
||||
};
|
||||
|
||||
// Just edit this to add new image, shape or button function
|
||||
namespace CustomKey {
|
||||
// Image list
|
||||
struct keyImage {
|
||||
const char* n; // UI name
|
||||
ImageID i; // ImageID
|
||||
float r; // Rotation angle in degree
|
||||
};
|
||||
static const keyImage comboKeyImages[] = {
|
||||
{ "1", ImageID("I_1"), 0.0f },
|
||||
{ "2", ImageID("I_2"), 0.0f },
|
||||
{ "3", ImageID("I_3"), 0.0f },
|
||||
{ "4", ImageID("I_4"), 0.0f },
|
||||
{ "5", ImageID("I_5"), 0.0f },
|
||||
{ "6", ImageID("I_6"), 0.0f },
|
||||
{ "A", ImageID("I_A"), 0.0f },
|
||||
{ "B", ImageID("I_B"), 0.0f },
|
||||
{ "C", ImageID("I_C"), 0.0f },
|
||||
{ "D", ImageID("I_D"), 0.0f },
|
||||
{ "E", ImageID("I_E"), 0.0f },
|
||||
{ "F", ImageID("I_F"), 0.0f },
|
||||
{ "Circle", ImageID("I_CIRCLE"), 0.0f },
|
||||
{ "Cross", ImageID("I_CROSS"), 0.0f },
|
||||
{ "Square", ImageID("I_SQUARE"), 0.0f },
|
||||
{ "Triangle", ImageID("I_TRIANGLE"), 0.0f },
|
||||
{ "L", ImageID("I_L"), 0.0f },
|
||||
{ "R", ImageID("I_R"), 0.0f },
|
||||
{ "Start", ImageID("I_START"), 0.0f },
|
||||
{ "Select", ImageID("I_SELECT"), 0.0f },
|
||||
{ "Plus", ImageID("I_CROSS"), 45.0f },
|
||||
{ "Rhombus", ImageID("I_SQUARE"), 45.0f },
|
||||
{ "Down Triangle", ImageID("I_TRIANGLE"), 180.0f },
|
||||
{ "Arrow up", ImageID("I_ARROW"), 90.0f},
|
||||
{ "Arrow down", ImageID("I_ARROW"), 270.0f},
|
||||
{ "Arrow left", ImageID("I_ARROW"), 0.0f},
|
||||
{ "Arrow right", ImageID("I_ARROW"), 180.0f},
|
||||
{ "Gear", ImageID("I_GEAR"), 0.0f},
|
||||
};
|
||||
|
||||
// Shape list
|
||||
struct keyShape {
|
||||
const char* n; // UI name
|
||||
ImageID i; // ImageID
|
||||
ImageID l; // ImageID line version
|
||||
float r; // Rotation angle in dregree
|
||||
bool f; // Flip Horizontally
|
||||
};
|
||||
static const keyShape comboKeyShapes[] = {
|
||||
{ "Circle", ImageID("I_ROUND"), ImageID("I_ROUND_LINE"), 0.0f, false },
|
||||
{ "Rectangle", ImageID("I_RECT"), ImageID("I_RECT_LINE"), 0.0f, false },
|
||||
{ "Vertical Rectangle", ImageID("I_RECT"), ImageID("I_RECT_LINE"), 90.0f, false },
|
||||
{ "L button", ImageID("I_SHOULDER"), ImageID("I_SHOULDER_LINE"), 0.0f, false },
|
||||
{ "R button", ImageID("I_SHOULDER"), ImageID("I_SHOULDER_LINE"), 0.0f, true },
|
||||
{ "Arrow up", ImageID("I_DIR"), ImageID("I_DIR_LINE"), 270.0f, false },
|
||||
{ "Arrow down", ImageID("I_DIR"), ImageID("I_DIR_LINE"), 90.0f, false },
|
||||
{ "Arrow left", ImageID("I_DIR"), ImageID("I_DIR_LINE"), 180.0f, false },
|
||||
{ "Arrow right", ImageID("I_DIR"), ImageID("I_DIR_LINE"), 0.0f, false },
|
||||
};
|
||||
|
||||
// Button list
|
||||
struct keyList {
|
||||
const char* n; // UI name
|
||||
ImageID i; // UI ImageID
|
||||
uint32_t c; // Key code
|
||||
};
|
||||
static const keyList comboKeyList[] = {
|
||||
{ "Square", ImageID("I_SQUARE"), CTRL_SQUARE },
|
||||
{ "Triangle", ImageID("I_TRIANGLE"), CTRL_TRIANGLE },
|
||||
{ "Circle", ImageID("I_CIRCLE"), CTRL_CIRCLE },
|
||||
{ "Cross", ImageID("I_CROSS"), CTRL_CROSS },
|
||||
{ "Up", ImageID::invalid(), CTRL_UP },
|
||||
{ "Down", ImageID::invalid(), CTRL_DOWN },
|
||||
{ "Left", ImageID::invalid(), CTRL_LEFT },
|
||||
{ "Right", ImageID::invalid(), CTRL_RIGHT },
|
||||
{ "Start", ImageID("I_START"), CTRL_START },
|
||||
{ "Select", ImageID("I_SELECT"), CTRL_SELECT },
|
||||
{ "L", ImageID("I_L"), CTRL_LTRIGGER },
|
||||
{ "R", ImageID("I_R"), CTRL_RTRIGGER },
|
||||
{ "RapidFire", ImageID::invalid(), VIRTKEY_RAPID_FIRE },
|
||||
{ "Unthrottle", ImageID::invalid(), VIRTKEY_UNTHROTTLE },
|
||||
{ "SpeedToggle", ImageID::invalid(), VIRTKEY_SPEED_TOGGLE },
|
||||
{ "Rewind", ImageID::invalid(), VIRTKEY_REWIND },
|
||||
{ "Save State", ImageID::invalid(), VIRTKEY_SAVE_STATE },
|
||||
{ "Load State", ImageID::invalid(), VIRTKEY_LOAD_STATE },
|
||||
{ "Next Slot", ImageID::invalid(), VIRTKEY_NEXT_SLOT },
|
||||
{ "Toggle Fullscreen", ImageID::invalid(), VIRTKEY_TOGGLE_FULLSCREEN },
|
||||
{ "Alt speed 1", ImageID::invalid(), VIRTKEY_SPEED_CUSTOM1 },
|
||||
{ "Alt speed 2", ImageID::invalid(), VIRTKEY_SPEED_CUSTOM2 },
|
||||
{ "Texture Dumping", ImageID::invalid(), VIRTKEY_TEXTURE_DUMP },
|
||||
{ "Texture Replacement", ImageID::invalid(), VIRTKEY_TEXTURE_REPLACE },
|
||||
{ "Screenshot", ImageID::invalid(), VIRTKEY_SCREENSHOT },
|
||||
{ "Mute toggle", ImageID::invalid(), VIRTKEY_MUTE_TOGGLE },
|
||||
{ "OpenChat", ImageID::invalid(), VIRTKEY_OPENCHAT },
|
||||
{ "Auto Analog Rotation (CW)", ImageID::invalid(), VIRTKEY_ANALOG_ROTATE_CW },
|
||||
{ "Auto Analog Rotation (CCW)", ImageID::invalid(), VIRTKEY_ANALOG_ROTATE_CCW },
|
||||
{ "Pause", ImageID::invalid(), VIRTKEY_PAUSE },
|
||||
{ "DevMenu", ImageID::invalid(), VIRTKEY_DEVMENU },
|
||||
#ifndef MOBILE_DEVICE
|
||||
{ "Record", ImageID::invalid(), VIRTKEY_RECORD },
|
||||
#endif
|
||||
};
|
||||
static_assert(ARRAY_SIZE(comboKeyList) <= 64, "Too many key for a uint64_t bit mask");
|
||||
};
|
||||
|
@ -333,6 +333,7 @@ void ControlLayoutView::Touch(const TouchInput &touch) {
|
||||
}
|
||||
|
||||
void ControlLayoutView::CreateViews() {
|
||||
using namespace CustomKey;
|
||||
const Bounds &bounds = GetBounds();
|
||||
if (bounds.w == 0.0f || bounds.h == 0.0f) {
|
||||
// Layout hasn't happened yet, return.
|
||||
@ -356,8 +357,6 @@ void ControlLayoutView::CreateViews() {
|
||||
ImageID stickBg = g_Config.iTouchButtonStyle ? ImageID("I_STICK_BG_LINE") : ImageID("I_STICK_BG");
|
||||
ImageID roundImage = g_Config.iTouchButtonStyle ? ImageID("I_ROUND_LINE") : ImageID("I_ROUND");
|
||||
|
||||
const ImageID comboKeyImages[5] = { ImageID("I_1"), ImageID("I_2"), ImageID("I_3"), ImageID("I_4"), ImageID("I_5") };
|
||||
|
||||
auto addDragDropButton = [&](ConfigTouchPos &pos, const char *key, ImageID bgImg, ImageID img) {
|
||||
DragDropButton *b = nullptr;
|
||||
if (pos.show) {
|
||||
@ -377,22 +376,6 @@ void ControlLayoutView::CreateViews() {
|
||||
if (auto *unthrottle = addDragDropButton(g_Config.touchUnthrottleKey, "Unthrottle button", rectImage, ImageID("I_ARROW"))) {
|
||||
unthrottle->SetAngle(180.0f);
|
||||
}
|
||||
if (auto *speed1 = addDragDropButton(g_Config.touchSpeed1Key, "Alternate speed 1 button", rectImage, ImageID("I_ARROW"))) {
|
||||
speed1->SetAngle(170.0f, 180.0f);
|
||||
}
|
||||
if (auto *speed2 = addDragDropButton(g_Config.touchSpeed2Key, "Alternate speed 2 button", rectImage, ImageID("I_ARROW"))) {
|
||||
speed2->SetAngle(190.0f, 180.0f);
|
||||
}
|
||||
if (auto *rapidFire = addDragDropButton(g_Config.touchRapidFireKey, "Rapid fire button", rectImage, ImageID("I_ARROW"))) {
|
||||
rapidFire->SetAngle(90.0f, 180.0f);
|
||||
}
|
||||
if (auto *analogRotationCW = addDragDropButton(g_Config.touchAnalogRotationCWKey, "Analog clockwise rotation button", rectImage, ImageID("I_ARROW"))) {
|
||||
analogRotationCW->SetAngle(190.0f, 180.0f);
|
||||
}
|
||||
if (auto *analogRotationCCW = addDragDropButton(g_Config.touchAnalogRotationCCWKey, "Analog counter clockwise rotation button", rectImage, ImageID("I_ARROW"))) {
|
||||
analogRotationCCW->SetAngle(350.0f, 180.0f);
|
||||
}
|
||||
|
||||
addDragDropButton(g_Config.touchLKey, "Left shoulder button", shoulderImage, ImageID("I_L"));
|
||||
if (auto *rbutton = addDragDropButton(g_Config.touchRKey, "Right shoulder button", shoulderImage, ImageID("I_R"))) {
|
||||
rbutton->FlipImageH(true);
|
||||
@ -400,11 +383,27 @@ void ControlLayoutView::CreateViews() {
|
||||
|
||||
addDragDropButton(g_Config.touchAnalogStick, "Left analog stick", stickBg, stickImage);
|
||||
addDragDropButton(g_Config.touchRightAnalogStick, "Right analog stick", stickBg, stickImage);
|
||||
addDragDropButton(g_Config.touchCombo0, "Combo 1 button", roundImage, comboKeyImages[0]);
|
||||
addDragDropButton(g_Config.touchCombo1, "Combo 2 button", roundImage, comboKeyImages[1]);
|
||||
addDragDropButton(g_Config.touchCombo2, "Combo 3 button", roundImage, comboKeyImages[2]);
|
||||
addDragDropButton(g_Config.touchCombo3, "Combo 4 button", roundImage, comboKeyImages[3]);
|
||||
addDragDropButton(g_Config.touchCombo4, "Combo 5 button", roundImage, comboKeyImages[4]);
|
||||
|
||||
auto addDragComboKey = [&](ConfigTouchPos &pos, const char *key, const ConfigCustomButton& cfg) {
|
||||
DragDropButton *b = nullptr;
|
||||
if (pos.show) {
|
||||
b = new DragDropButton(pos, key, g_Config.iTouchButtonStyle == 0 ? comboKeyShapes[cfg.shape].i : comboKeyShapes[cfg.shape].l, comboKeyImages[cfg.image].i, bounds);
|
||||
b->FlipImageH(comboKeyShapes[cfg.shape].f);
|
||||
b->SetAngle(comboKeyImages[cfg.image].r, comboKeyShapes[cfg.shape].r);
|
||||
controls_.push_back(b);
|
||||
}
|
||||
return b;
|
||||
};
|
||||
addDragComboKey(g_Config.touchCombo0, "Custom 1 button", g_Config.CustomKey0);
|
||||
addDragComboKey(g_Config.touchCombo1, "Custom 2 button", g_Config.CustomKey1);
|
||||
addDragComboKey(g_Config.touchCombo2, "Custom 3 button", g_Config.CustomKey2);
|
||||
addDragComboKey(g_Config.touchCombo3, "Custom 4 button", g_Config.CustomKey3);
|
||||
addDragComboKey(g_Config.touchCombo4, "Custom 5 button", g_Config.CustomKey4);
|
||||
addDragComboKey(g_Config.touchCombo5, "Custom 6 button", g_Config.CustomKey5);
|
||||
addDragComboKey(g_Config.touchCombo6, "Custom 7 button", g_Config.CustomKey6);
|
||||
addDragComboKey(g_Config.touchCombo7, "Custom 8 button", g_Config.CustomKey7);
|
||||
addDragComboKey(g_Config.touchCombo8, "Custom 9 button", g_Config.CustomKey8);
|
||||
addDragComboKey(g_Config.touchCombo9, "Custom 10 button", g_Config.CustomKey9);
|
||||
|
||||
for (size_t i = 0; i < controls_.size(); i++) {
|
||||
Add(controls_[i]);
|
||||
@ -500,7 +499,7 @@ void TouchControlLayoutScreen::CreateViews() {
|
||||
|
||||
Choice *reset = new Choice(di->T("Reset"), "", false, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 84));
|
||||
Choice *back = new Choice(di->T("Back"), "", false, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 10));
|
||||
Choice *visibility = new Choice(co->T("Visibility"), "", false, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 298));
|
||||
Choice *visibility = new Choice(co->T("Customize"), "", false, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 298));
|
||||
// controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fButtonScale, 0.80, 2.0, co->T("Button Scaling"), screenManager()))
|
||||
// ->OnChange.Handle(this, &GameSettingsScreen::OnChangeControlScaling);
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "TouchControlVisibilityScreen.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
#include "ComboKeyMappingScreen.h"
|
||||
|
||||
static const int leftColumnWidth = 140;
|
||||
|
||||
@ -42,6 +43,7 @@ private:
|
||||
|
||||
void TouchControlVisibilityScreen::CreateViews() {
|
||||
using namespace UI;
|
||||
using namespace CustomKey;
|
||||
|
||||
auto di = GetI18NCategory("Dialog");
|
||||
auto co = GetI18NCategory("Controls");
|
||||
@ -70,30 +72,62 @@ void TouchControlVisibilityScreen::CreateViews() {
|
||||
gridsettings.fillCells = true;
|
||||
GridLayout *grid = vert->Add(new GridLayoutList(gridsettings, new LayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
|
||||
static const char* rightAnalogKey = "Right Analog Stick (tap to customize)";
|
||||
toggles_.clear();
|
||||
toggles_.push_back({ "Circle", &g_Config.bShowTouchCircle, ImageID("I_CIRCLE") });
|
||||
toggles_.push_back({ "Cross", &g_Config.bShowTouchCross, ImageID("I_CROSS") });
|
||||
toggles_.push_back({ "Square", &g_Config.bShowTouchSquare, ImageID("I_SQUARE") });
|
||||
toggles_.push_back({ "Triangle", &g_Config.bShowTouchTriangle, ImageID("I_TRIANGLE") });
|
||||
toggles_.push_back({ "L", &g_Config.touchLKey.show, ImageID("I_L") });
|
||||
toggles_.push_back({ "R", &g_Config.touchRKey.show, ImageID("I_R") });
|
||||
toggles_.push_back({ "Start", &g_Config.touchStartKey.show, ImageID("I_START") });
|
||||
toggles_.push_back({ "Select", &g_Config.touchSelectKey.show, ImageID("I_SELECT") });
|
||||
toggles_.push_back({ "Dpad", &g_Config.touchDpad.show, ImageID::invalid() });
|
||||
toggles_.push_back({ "Analog Stick", &g_Config.touchAnalogStick.show, ImageID::invalid() });
|
||||
toggles_.push_back({ rightAnalogKey, &g_Config.touchRightAnalogStick.show, ImageID::invalid() });
|
||||
toggles_.push_back({ "Unthrottle", &g_Config.touchUnthrottleKey.show, ImageID::invalid() });
|
||||
toggles_.push_back({ "Combo0", &g_Config.touchCombo0.show, ImageID("I_1") });
|
||||
toggles_.push_back({ "Combo1", &g_Config.touchCombo1.show, ImageID("I_2") });
|
||||
toggles_.push_back({ "Combo2", &g_Config.touchCombo2.show, ImageID("I_3") });
|
||||
toggles_.push_back({ "Combo3", &g_Config.touchCombo3.show, ImageID("I_4") });
|
||||
toggles_.push_back({ "Combo4", &g_Config.touchCombo4.show, ImageID("I_5") });
|
||||
toggles_.push_back({ "Alt speed 1", &g_Config.touchSpeed1Key.show, ImageID::invalid() });
|
||||
toggles_.push_back({ "Alt speed 2", &g_Config.touchSpeed2Key.show, ImageID::invalid() });
|
||||
toggles_.push_back({ "RapidFire", &g_Config.touchRapidFireKey.show, ImageID::invalid() });
|
||||
toggles_.push_back({ "Auto Analog Rotation (CW)", &g_Config.touchAnalogRotationCWKey.show, ImageID::invalid() });
|
||||
toggles_.push_back({ "Auto Analog Rotation (CCW)", &g_Config.touchAnalogRotationCCWKey.show, ImageID::invalid() });
|
||||
toggles_.push_back({ "Circle", &g_Config.bShowTouchCircle, ImageID("I_CIRCLE"), nullptr });
|
||||
toggles_.push_back({ "Cross", &g_Config.bShowTouchCross, ImageID("I_CROSS"), nullptr });
|
||||
toggles_.push_back({ "Square", &g_Config.bShowTouchSquare, ImageID("I_SQUARE"), nullptr });
|
||||
toggles_.push_back({ "Triangle", &g_Config.bShowTouchTriangle, ImageID("I_TRIANGLE"), nullptr });
|
||||
toggles_.push_back({ "L", &g_Config.touchLKey.show, ImageID("I_L"), nullptr });
|
||||
toggles_.push_back({ "R", &g_Config.touchRKey.show, ImageID("I_R"), nullptr });
|
||||
toggles_.push_back({ "Start", &g_Config.touchStartKey.show, ImageID("I_START"), nullptr });
|
||||
toggles_.push_back({ "Select", &g_Config.touchSelectKey.show, ImageID("I_SELECT"), nullptr });
|
||||
toggles_.push_back({ "Dpad", &g_Config.touchDpad.show, ImageID::invalid(), nullptr });
|
||||
toggles_.push_back({ "Analog Stick", &g_Config.touchAnalogStick.show, ImageID::invalid(), nullptr });
|
||||
toggles_.push_back({ "Right Analog Stick", &g_Config.touchRightAnalogStick.show, ImageID::invalid(), [=](EventParams &e) {
|
||||
screenManager()->push(new RightAnalogMappingScreen());
|
||||
return UI::EVENT_DONE;
|
||||
}});
|
||||
toggles_.push_back({ "Unthrottle", &g_Config.touchUnthrottleKey.show, ImageID::invalid(), nullptr });
|
||||
toggles_.push_back({ "Custom 1", &g_Config.touchCombo0.show, ImageID::invalid(), [=](EventParams &e) {
|
||||
screenManager()->push(new ComboKeyScreen(0));
|
||||
return UI::EVENT_DONE;
|
||||
}});
|
||||
toggles_.push_back({ "Custom 2", &g_Config.touchCombo1.show, ImageID::invalid(), [=](EventParams &e) {
|
||||
screenManager()->push(new ComboKeyScreen(1));
|
||||
return UI::EVENT_DONE;
|
||||
}});
|
||||
toggles_.push_back({ "Custom 3", &g_Config.touchCombo2.show, ImageID::invalid(), [=](EventParams &e) {
|
||||
screenManager()->push(new ComboKeyScreen(2));
|
||||
return UI::EVENT_DONE;
|
||||
}});
|
||||
toggles_.push_back({ "Custom 4", &g_Config.touchCombo3.show, ImageID::invalid(), [=](EventParams &e) {
|
||||
screenManager()->push(new ComboKeyScreen(3));
|
||||
return UI::EVENT_DONE;
|
||||
}});
|
||||
toggles_.push_back({ "Custom 5", &g_Config.touchCombo4.show, ImageID::invalid(), [=](EventParams &e) {
|
||||
screenManager()->push(new ComboKeyScreen(4));
|
||||
return UI::EVENT_DONE;
|
||||
}});
|
||||
toggles_.push_back({ "Custom 6", &g_Config.touchCombo5.show, ImageID::invalid(), [=](EventParams &e) {
|
||||
screenManager()->push(new ComboKeyScreen(5));
|
||||
return UI::EVENT_DONE;
|
||||
}});
|
||||
toggles_.push_back({ "Custom 7", &g_Config.touchCombo6.show, ImageID::invalid(), [=](EventParams &e) {
|
||||
screenManager()->push(new ComboKeyScreen(6));
|
||||
return UI::EVENT_DONE;
|
||||
}});
|
||||
toggles_.push_back({ "Custom 8", &g_Config.touchCombo7.show, ImageID::invalid(), [=](EventParams &e) {
|
||||
screenManager()->push(new ComboKeyScreen(7));
|
||||
return UI::EVENT_DONE;
|
||||
}});
|
||||
toggles_.push_back({ "Custom 9", &g_Config.touchCombo8.show, ImageID::invalid(), [=](EventParams &e) {
|
||||
screenManager()->push(new ComboKeyScreen(8));
|
||||
return UI::EVENT_DONE;
|
||||
}});
|
||||
toggles_.push_back({ "Custom 10", &g_Config.touchCombo9.show, ImageID::invalid(), [=](EventParams &e) {
|
||||
screenManager()->push(new ComboKeyScreen(9));
|
||||
return UI::EVENT_DONE;
|
||||
}});
|
||||
|
||||
auto mc = GetI18NCategory("MappableControls");
|
||||
for (auto toggle : toggles_) {
|
||||
@ -102,21 +136,17 @@ void TouchControlVisibilityScreen::CreateViews() {
|
||||
|
||||
CheckBox *checkbox = new CheckBox(toggle.show, "", "", new LinearLayoutParams(50, WRAP_CONTENT));
|
||||
row->Add(checkbox);
|
||||
|
||||
if (toggle.key == rightAnalogKey) {
|
||||
Choice *rightAnalog = new Choice(mc->T(rightAnalogKey), "", false, new LinearLayoutParams(1.0f));
|
||||
rightAnalog->SetCentered(true);
|
||||
row->Add(rightAnalog)->OnClick.Handle(this, &TouchControlVisibilityScreen::RightAnalogBindScreen);
|
||||
Choice *choice;
|
||||
if (toggle.handle) {
|
||||
choice = new Choice(std::string(mc->T(toggle.key))+mc->T(" (tap to customize)"), "", false, new LinearLayoutParams(1.0f));
|
||||
choice->OnClick.Add(toggle.handle);
|
||||
} else if (toggle.img.isValid()) {
|
||||
choice = new CheckBoxChoice(toggle.img, checkbox, new LinearLayoutParams(1.0f));
|
||||
} else {
|
||||
Choice *choice;
|
||||
if (toggle.img.isValid()) {
|
||||
choice = new CheckBoxChoice(toggle.img, checkbox, new LinearLayoutParams(1.0f));
|
||||
} else {
|
||||
choice = new CheckBoxChoice(mc->T(toggle.key), checkbox, new LinearLayoutParams(1.0f));
|
||||
}
|
||||
choice->SetCentered(true);
|
||||
row->Add(choice);
|
||||
choice = new CheckBoxChoice(mc->T(toggle.key), checkbox, new LinearLayoutParams(1.0f));
|
||||
}
|
||||
choice->SetCentered(true);
|
||||
row->Add(choice);
|
||||
grid->Add(row);
|
||||
}
|
||||
}
|
||||
@ -143,14 +173,14 @@ void RightAnalogMappingScreen::CreateViews() {
|
||||
vert->SetSpacing(0);
|
||||
|
||||
static const char *rightAnalogButton[] = {"None", "L", "R", "Square", "Triangle", "Circle", "Cross", "D-pad up", "D-pad down", "D-pad left", "D-pad right", "Start", "Select"};
|
||||
|
||||
|
||||
vert->Add(new CheckBox(&g_Config.touchRightAnalogStick.show, co->T("Visible")));
|
||||
vert->Add(new CheckBox(&g_Config.bRightAnalogCustom, co->T("Use custom right analog")));
|
||||
PopupMultiChoice *rightAnalogUp = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogUp, mc->T("RightAn.Up"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), mc->GetName(), screenManager()));
|
||||
PopupMultiChoice *rightAnalogDown = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogDown, mc->T("RightAn.Down"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), mc->GetName(), screenManager()));
|
||||
PopupMultiChoice *rightAnalogLeft = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogLeft, mc->T("RightAn.Left"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), mc->GetName(), screenManager()));
|
||||
PopupMultiChoice *rightAnalogRight = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogRight, mc->T("RightAn.Right"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), mc->GetName(), screenManager()));
|
||||
PopupMultiChoice *rightAnalogPress = vert->Add(new PopupMultiChoice(&g_Config.iRightAnalogPress, co->T("Keep this button pressed when right analog is pressed"), rightAnalogButton, 0, ARRAY_SIZE(rightAnalogButton), mc->GetName(), screenManager()));
|
||||
vert->Add(new CheckBox(&g_Config.touchRightAnalogStick.show, co->T("Show right analog")));
|
||||
rightAnalogUp->SetEnabledPtr(&g_Config.bRightAnalogCustom);
|
||||
rightAnalogDown->SetEnabledPtr(&g_Config.bRightAnalogCustom);
|
||||
rightAnalogLeft->SetEnabledPtr(&g_Config.bRightAnalogCustom);
|
||||
|
@ -28,6 +28,7 @@ struct TouchButtonToggle {
|
||||
const char *key;
|
||||
bool *show;
|
||||
ImageID img;
|
||||
std::function<UI::EventReturn(UI::EventParams&)> handle;
|
||||
};
|
||||
|
||||
class TouchControlVisibilityScreen : public UIDialogScreenWithBackground {
|
||||
|
@ -51,4 +51,10 @@ image I_FLAG_KO source_assets/image/flag_ko.png copy
|
||||
image I_FULLSCREEN source_assets/image/fullscreen.png copy
|
||||
image I_RESTORE source_assets/image/restore.png copy
|
||||
image I_SDCARD source_assets/image/sdcard.png copy
|
||||
image I_HOME source_assets/image/home.png copy
|
||||
image I_HOME source_assets/image/home.png copy
|
||||
image I_A source_assets/image/a.png copy
|
||||
image I_B source_assets/image/b.png copy
|
||||
image I_C source_assets/image/c.png copy
|
||||
image I_D source_assets/image/d.png copy
|
||||
image I_E source_assets/image/e.png copy
|
||||
image I_F source_assets/image/f.png copy
|
||||
|
BIN
source_assets/image/a.png
Normal file
After Width: | Height: | Size: 941 B |
BIN
source_assets/image/b.png
Normal file
After Width: | Height: | Size: 815 B |
@ -12,7 +12,7 @@
|
||||
height="1052.3622047"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="1.0beta2 (5ba348d, 2020-03-28)"
|
||||
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
|
||||
sodipodi:docname="buttons.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
@ -1388,6 +1388,198 @@
|
||||
in2="offset"
|
||||
id="feComposite5130-3" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4775-3">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4777-6" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4779-7" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="1"
|
||||
result="blur"
|
||||
id="feGaussianBlur4781-5" />
|
||||
<feOffset
|
||||
dx="0"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4783-3" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4785-5" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4775-3-9">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4777-6-1" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4779-7-2" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="1"
|
||||
result="blur"
|
||||
id="feGaussianBlur4781-5-7" />
|
||||
<feOffset
|
||||
dx="0"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4783-3-0" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4785-5-9" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4775-3-0">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4777-6-6" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4779-7-26" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="1"
|
||||
result="blur"
|
||||
id="feGaussianBlur4781-5-1" />
|
||||
<feOffset
|
||||
dx="0"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4783-3-8" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4785-5-7" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4775-3-02">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4777-6-3" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4779-7-7" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="1"
|
||||
result="blur"
|
||||
id="feGaussianBlur4781-5-5" />
|
||||
<feOffset
|
||||
dx="0"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4783-3-9" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4785-5-2" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4775-3-97">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4777-6-36" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4779-7-1" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="1"
|
||||
result="blur"
|
||||
id="feGaussianBlur4781-5-2" />
|
||||
<feOffset
|
||||
dx="0"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4783-3-93" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4785-5-1" />
|
||||
</filter>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
inkscape:label="Drop Shadow"
|
||||
id="filter4775-3-8">
|
||||
<feFlood
|
||||
flood-opacity="0.498039"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
id="feFlood4777-6-4" />
|
||||
<feComposite
|
||||
in="flood"
|
||||
in2="SourceGraphic"
|
||||
operator="in"
|
||||
result="composite1"
|
||||
id="feComposite4779-7-5" />
|
||||
<feGaussianBlur
|
||||
in="composite1"
|
||||
stdDeviation="1"
|
||||
result="blur"
|
||||
id="feGaussianBlur4781-5-0" />
|
||||
<feOffset
|
||||
dx="0"
|
||||
dy="0"
|
||||
result="offset"
|
||||
id="feOffset4783-3-3" />
|
||||
<feComposite
|
||||
in="SourceGraphic"
|
||||
in2="offset"
|
||||
operator="over"
|
||||
result="composite2"
|
||||
id="feComposite4785-5-6" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
@ -1396,16 +1588,16 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="207.38755"
|
||||
inkscape:cy="188.37622"
|
||||
inkscape:zoom="3.959798"
|
||||
inkscape:cx="287.37168"
|
||||
inkscape:cy="17.065748"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1537"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1027"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:document-rotation="0">
|
||||
<inkscape:grid
|
||||
@ -2103,5 +2295,83 @@
|
||||
d="m 188.91385,48.29099 v 19.545807 h 19.28584 V 48.29099 Z m 2.49666,2.529991 h 14.295 v 14.485834 h -14.295 z"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter5216)" />
|
||||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4775-3)"
|
||||
x="287.70575"
|
||||
y="30.76185"
|
||||
id="text3635-6"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3637-2"
|
||||
x="287.70575"
|
||||
y="30.76185"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1">A</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4775-3-9)"
|
||||
x="309.8139"
|
||||
y="31.120909"
|
||||
id="text3635-6-3"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3637-2-6"
|
||||
x="309.8139"
|
||||
y="31.120909"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1">B</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4775-3-0)"
|
||||
x="331.02643"
|
||||
y="31.334555"
|
||||
id="text3635-6-9"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3637-2-2"
|
||||
x="331.02643"
|
||||
y="31.334555"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1">C</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4775-3-02)"
|
||||
x="351.77972"
|
||||
y="31.095232"
|
||||
id="text3635-6-2"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3637-2-8"
|
||||
x="351.77972"
|
||||
y="31.095232"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1">D</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4775-3-97)"
|
||||
x="350.99432"
|
||||
y="56.332092"
|
||||
id="text3635-6-94"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3637-2-7"
|
||||
x="350.99432"
|
||||
y="56.332092"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1">F</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4775-3-8)"
|
||||
x="373.82898"
|
||||
y="31.423817"
|
||||
id="text3635-6-1"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3637-2-0"
|
||||
x="373.82898"
|
||||
y="31.423817"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:27.5px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1">E</tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 89 KiB |
BIN
source_assets/image/c.png
Normal file
After Width: | Height: | Size: 749 B |
BIN
source_assets/image/d.png
Normal file
After Width: | Height: | Size: 809 B |
BIN
source_assets/image/e.png
Normal file
After Width: | Height: | Size: 512 B |
BIN
source_assets/image/f.png
Normal file
After Width: | Height: | Size: 468 B |