Input Mapping suport for Gamepad Axis (multiply SourceCallback)

Apply the ControlValue as a multiplyer to the Callback. UI with indication bars for gamepad axis.
This commit is contained in:
Bruno Herbelin
2022-02-07 13:27:05 +01:00
parent 886305ec13
commit 6cf86d80e2
7 changed files with 157 additions and 6 deletions

View File

@@ -810,7 +810,8 @@ void Control::joystickCallback()
// wait for the joystick_end_ notification
std::mutex mtx;
std::unique_lock<std::mutex> lck(mtx);
while ( Control::joystick_end_.wait_for(lck,std::chrono::milliseconds(20) ) == std::cv_status::timeout ) {
// loop with a fixed refresh rate (~ 30 Hz)
while ( Control::joystick_end_.wait_for(lck,std::chrono::milliseconds(33) ) == std::cv_status::timeout ) {
// read joystick buttons
int num_buttons = 0;
@@ -825,7 +826,7 @@ void Control::joystickCallback()
int num_axis = 0;
const float *state_axis = glfwGetJoystickAxes(GLFW_JOYSTICK_1, &num_axis );
for (int a = 0; a < num_axis; ++a) {
Control::input_active[INPUT_JOYSTICK_FIRST_AXIS + a] = ABS(state_axis[a]) > 0.01 ? true : false;
Control::input_active[INPUT_JOYSTICK_FIRST_AXIS + a] = ABS(state_axis[a]) > 0.02 ? true : false;
Control::input_values[INPUT_JOYSTICK_FIRST_AXIS + a] = state_axis[a];
}
}

View File

@@ -1352,6 +1352,36 @@ void ImGuiToolkit::ShowPlotHistoLines (const char* label, float *histogram_array
}
void ImGuiToolkit::ValueBar(float fraction, const ImVec2& size_arg)
{
ImGuiWindow* window = ImGui::GetCurrentWindow();
if (window->SkipItems)
return;
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
ImVec2 pos = window->DC.CursorPos;
ImVec2 size = ImGui::CalcItemSize(size_arg, ImGui::CalcItemWidth(), g.FontSize + style.FramePadding.y*2.0f);
ImRect bb(pos, pos + size);
ImGui::ItemSize(size, style.FramePadding.y);
if (!ImGui::ItemAdd(bb, 0))
return;
// Render
ImGui::RenderFrame(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
bb.Expand(ImVec2(-style.FrameBorderSize, -style.FrameBorderSize));
fraction = CLAMP(fraction, -1.f, 1.f);
if (fraction>0.f) {
ImGui::RenderRectFilledRangeH(window->DrawList, bb, ImGui::GetColorU32(ImGuiCol_PlotHistogram), 0.5f, 0.5f+(fraction*0.5f), style.FrameRounding);
}
else {
ImGui::RenderRectFilledRangeH(window->DrawList, bb, ImGui::GetColorU32(ImGuiCol_PlotHistogram), 0.5f+(fraction*0.5f), 0.5f, style.FrameRounding);
}
}
void ImGuiToolkit::SetFont (ImGuiToolkit::font_style style, const std::string &ttf_font_name, int pointsize, int oversample)
{

View File

@@ -53,6 +53,8 @@ namespace ImGuiToolkit
bool EditPlotHistoLines(const char* label, float *histogram_array, float *lines_array, int values_count, float values_min, float values_max, guint64 begin, guint64 end, bool cut, bool *released, const ImVec2 size);
void ShowPlotHistoLines(const char* label, float *histogram_array, float *lines_array, int values_count, float values_min, float values_max, const ImVec2 size);
void ValueBar(float fraction, const ImVec2& size_arg);
// fonts from ressources 'fonts/'
typedef enum {
FONT_DEFAULT =0,

View File

@@ -746,6 +746,8 @@ void Source::updateCallbacks(float dt)
delete k->second.reverse_;
// generate a new callback from the model
SourceCallback *C = k->second.model_->clone();
// apply value multiplyer from input
C->multiply( Control::inputValue(k->first) );
// add callback to the source (force override)
call( C, true );
// get the reverse if the callback, and remember it (can be null)

View File

@@ -133,6 +133,11 @@ void SetAlpha::update(Source *s, float)
finished_ = true;
}
void SetAlpha::multiply (float factor)
{
alpha_ *= factor;
}
SourceCallback *SetAlpha::clone() const
{
return new SetAlpha(alpha_);
@@ -222,6 +227,11 @@ void Loom::update(Source *s, float dt)
finished_ = true;
}
void Loom::multiply (float factor)
{
speed_ *= factor;
}
SourceCallback *Loom::clone() const
{
return new Loom(speed_, duration_);
@@ -276,6 +286,11 @@ void SetDepth::update(Source *s, float dt)
finished_ = true;
}
void SetDepth::multiply (float factor)
{
target_ *= factor;
}
SourceCallback *SetDepth::clone() const
{
return new SetDepth(target_, duration_);
@@ -379,6 +394,11 @@ void Grab::update(Source *s, float dt)
finished_ = true;
}
void Grab::multiply (float factor)
{
speed_ *= factor;
}
SourceCallback *Grab::clone() const
{
return new Grab(speed_.x, speed_.y, duration_);
@@ -429,6 +449,11 @@ void Resize::update(Source *s, float dt)
finished_ = true;
}
void Resize::multiply (float factor)
{
speed_ *= factor;
}
SourceCallback *Resize::clone() const
{
return new Resize(speed_.x, speed_.y, duration_);
@@ -478,6 +503,11 @@ void Turn::update(Source *s, float dt)
finished_ = true;
}
void Turn::multiply (float factor)
{
speed_ *= factor;
}
SourceCallback *Turn::clone() const
{
return new Turn(speed_, duration_);

View File

@@ -30,6 +30,7 @@ public:
virtual ~SourceCallback() {}
virtual void update (Source *, float) = 0;
virtual void multiply (float) {};
virtual SourceCallback *clone () const = 0;
virtual SourceCallback *reverse (Source *) const { return nullptr; }
virtual CallbackType type () { return CALLBACK_GENERIC; }
@@ -68,6 +69,7 @@ public:
void setValue (float a) { alpha_ = a; }
void update (Source *s, float) override;
void multiply (float factor) override;
SourceCallback *clone () const override;
SourceCallback *reverse(Source *s) const override;
CallbackType type () override { return CALLBACK_ALPHA; }
@@ -92,6 +94,7 @@ public:
void setDuration (float d) { duration_ = d; }
void update (Source *s, float) override;
void multiply (float factor) override;
SourceCallback *clone() const override;
CallbackType type () override { return CALLBACK_LOOM; }
void accept (Visitor& v) override;
@@ -130,6 +133,7 @@ public:
void setDuration (float d) { duration_ = d; }
void update (Source *s, float dt) override;
void multiply (float factor) override;
SourceCallback *clone () const override;
SourceCallback *reverse(Source *s) const override;
CallbackType type () override { return CALLBACK_DEPTH; }
@@ -180,6 +184,7 @@ public:
void setDuration (float d) { duration_ = d; }
void update (Source *s, float) override;
void multiply (float factor) override;
SourceCallback *clone () const override;
CallbackType type () override { return CALLBACK_GRAB; }
void accept (Visitor& v) override;
@@ -202,6 +207,7 @@ public:
void setDuration (float d) { duration_ = d; }
void update (Source *s, float) override;
void multiply (float factor) override;
SourceCallback *clone () const override;
CallbackType type () override { return CALLBACK_RESIZE; }
void accept (Visitor& v) override;
@@ -224,6 +230,7 @@ public:
void setDuration (float d) { duration_ = d; }
void update (Source *s, float) override;
void multiply (float factor) override;
SourceCallback *clone () const override;
CallbackType type () override { return CALLBACK_TURN; }
void accept (Visitor& v) override;

View File

@@ -4664,9 +4664,8 @@ void InputMappingInterface::Render()
ICON_FA_CHEVRON_CIRCLE_RIGHT, "A", "B",
"L1", "LT", ICON_FA_DOT_CIRCLE, "RT", "R1" };
// Draw table of letter keys [A] to [Y]
// Draw table of Gamepad Buttons
ImGuiToolkit::PushFont(ImGuiToolkit::FONT_LARGE);
ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.5f, 0.50f));
ImVec4 color = ImGui::GetStyle().Colors[ImGuiCol_Header];
color.w /= Settings::application.mapping.disabled ? 2.f : 0.9f;
ImGui::PushStyleColor(ImGuiCol_Header, color);
@@ -4674,6 +4673,8 @@ void InputMappingInterface::Render()
color.w /= Settings::application.mapping.disabled ? 2.f : 1.0f;
ImGui::PushStyleColor(ImGuiCol_Text, color);
// CENTER text for button
ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.5f, 0.5f));
for (size_t b = 0; b < gamepad_inputs.size(); ++b ){
uint ig = gamepad_inputs[b];
// draw overlay on active keys
@@ -4692,14 +4693,92 @@ void InputMappingInterface::Render()
ImGui::PopID();
if ((b % 5) < 4) ImGui::SameLine();
// Draw frame around current keyboard letter
// Draw frame around current gamepad button
if (current_input_ == ig) {
ImVec2 pos = frame_top + keyLetterItemSize * ImVec2( b % 5, b / 5);
draw_list->AddRect(pos, pos + keyLetterIconSize, ImGui::GetColorU32(ImGuiCol_Text), 6.f, ImDrawCornerFlags_All, 3.f);
}
}
ImGui::PopStyleColor(2);
ImGui::PopStyleVar();
// Table of Gamepad Axis
const ImVec2 axis_top = frame_top + ImVec2(0.f, 3.f * keyLetterItemSize.y);
const ImVec2 axis_item_size(inputarea_width / 2.f, (2.f * keyLetterItemSize.y) / 3.f);
const ImVec2 axis_icon_size = axis_item_size - g.Style.ItemSpacing;
const ImVec2 axis_bar_size = axis_icon_size * ImVec2(0.4f, 0.4f);
ImVec2 axis_bar_pos(axis_icon_size.x * 0.5f, axis_icon_size.y *0.3f );
// LEFT align for 3 axis on the left
ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.09f, 0.5f));
// define top left screen cursor position
ImVec2 pos = axis_top;
// Draw a little bar showing activity on the gamepad axis
ImGui::SetCursorScreenPos( pos + axis_bar_pos);
ImGuiToolkit::ValueBar(Control::inputValue(INPUT_JOYSTICK_FIRST_AXIS), axis_bar_size);
// Draw button to assign the axis to an action
ImGui::SetCursorScreenPos( pos );
if (ImGui::Selectable("LX", input_assigned[INPUT_JOYSTICK_FIRST_AXIS], 0, axis_icon_size))
current_input_ = INPUT_JOYSTICK_FIRST_AXIS;
// Draw frame around current gamepad axis
if (current_input_ == INPUT_JOYSTICK_FIRST_AXIS)
draw_list->AddRect(pos, pos + axis_icon_size, ImGui::GetColorU32(ImGuiCol_Text), 6.f, ImDrawCornerFlags_All, 3.f);
pos = axis_top + ImVec2( 0, axis_item_size.y);
ImGui::SetCursorScreenPos( pos + axis_bar_pos);
ImGuiToolkit::ValueBar(Control::inputValue(INPUT_JOYSTICK_FIRST_AXIS+1), axis_bar_size);
ImGui::SetCursorScreenPos( pos );
if (ImGui::Selectable("LY", input_assigned[INPUT_JOYSTICK_FIRST_AXIS+1], 0, axis_icon_size))
current_input_ = INPUT_JOYSTICK_FIRST_AXIS+1;
if (current_input_ == INPUT_JOYSTICK_FIRST_AXIS+1)
draw_list->AddRect(pos, pos + axis_icon_size, ImGui::GetColorU32(ImGuiCol_Text), 6.f, ImDrawCornerFlags_All, 3.f);
pos = axis_top + ImVec2( 0, 2.f * axis_item_size.y);
ImGui::SetCursorScreenPos( pos + axis_bar_pos);
ImGuiToolkit::ValueBar(Control::inputValue(INPUT_JOYSTICK_FIRST_AXIS+2), axis_bar_size);
ImGui::SetCursorScreenPos( pos );
if (ImGui::Selectable("L2", input_assigned[INPUT_JOYSTICK_FIRST_AXIS+2], 0, axis_icon_size))
current_input_ = INPUT_JOYSTICK_FIRST_AXIS+2;
if (current_input_ == INPUT_JOYSTICK_FIRST_AXIS+2)
draw_list->AddRect(pos, pos + axis_icon_size, ImGui::GetColorU32(ImGuiCol_Text), 6.f, ImDrawCornerFlags_All, 3.f);
ImGui::PopStyleVar();
// RIGHT align for 3 axis on the right
ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.91f, 0.5f));
axis_bar_pos.x = g.Style.ItemSpacing.x;
pos = axis_top + ImVec2( axis_item_size.x, 0.f);
ImGui::SetCursorScreenPos( pos + axis_bar_pos);
ImGuiToolkit::ValueBar(Control::inputValue(INPUT_JOYSTICK_FIRST_AXIS+3), axis_bar_size);
ImGui::SetCursorScreenPos( pos );
if (ImGui::Selectable("RX", input_assigned[INPUT_JOYSTICK_FIRST_AXIS+3], 0, axis_icon_size))
current_input_ = INPUT_JOYSTICK_FIRST_AXIS+3;
if (current_input_ == INPUT_JOYSTICK_FIRST_AXIS+3)
draw_list->AddRect(pos, pos + axis_icon_size, ImGui::GetColorU32(ImGuiCol_Text), 6.f, ImDrawCornerFlags_All, 3.f);
pos = axis_top + ImVec2( axis_item_size.x, axis_item_size.y);
ImGui::SetCursorScreenPos( pos + axis_bar_pos);
ImGuiToolkit::ValueBar(Control::inputValue(INPUT_JOYSTICK_FIRST_AXIS+4), axis_bar_size);
ImGui::SetCursorScreenPos( pos );
if (ImGui::Selectable("RY", input_assigned[INPUT_JOYSTICK_FIRST_AXIS+4], 0, axis_icon_size))
current_input_ = INPUT_JOYSTICK_FIRST_AXIS+4;
if (current_input_ == INPUT_JOYSTICK_FIRST_AXIS+4)
draw_list->AddRect(pos, pos + axis_icon_size, ImGui::GetColorU32(ImGuiCol_Text), 6.f, ImDrawCornerFlags_All, 3.f);
pos = axis_top + ImVec2( axis_item_size.x, 2.f * axis_item_size.y);
ImGui::SetCursorScreenPos( pos + axis_bar_pos);
ImGuiToolkit::ValueBar(Control::inputValue(INPUT_JOYSTICK_FIRST_AXIS+5), axis_bar_size);
ImGui::SetCursorScreenPos( pos );
if (ImGui::Selectable("R2", input_assigned[INPUT_JOYSTICK_FIRST_AXIS+5], 0, axis_icon_size))
current_input_ = INPUT_JOYSTICK_FIRST_AXIS+5;
if (current_input_ == INPUT_JOYSTICK_FIRST_AXIS+5)
draw_list->AddRect(pos, pos + axis_icon_size, ImGui::GetColorU32(ImGuiCol_Text), 6.f, ImDrawCornerFlags_All, 3.f);
ImGui::PopStyleVar();
// Done with color and font change
ImGui::PopStyleColor(2);
ImGui::PopFont();
}