diff --git a/ControlManager.cpp b/ControlManager.cpp index 0a16bc4..03231bc 100644 --- a/ControlManager.cpp +++ b/ControlManager.cpp @@ -810,7 +810,8 @@ void Control::joystickCallback() // wait for the joystick_end_ notification std::mutex mtx; std::unique_lock 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]; } } diff --git a/ImGuiToolkit.cpp b/ImGuiToolkit.cpp index 0eac6cd..b45c01d 100644 --- a/ImGuiToolkit.cpp +++ b/ImGuiToolkit.cpp @@ -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) { diff --git a/ImGuiToolkit.h b/ImGuiToolkit.h index 857c338..4bc9907 100644 --- a/ImGuiToolkit.h +++ b/ImGuiToolkit.h @@ -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, diff --git a/Source.cpp b/Source.cpp index cf64df2..1c21846 100644 --- a/Source.cpp +++ b/Source.cpp @@ -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) diff --git a/SourceCallback.cpp b/SourceCallback.cpp index f078283..05315fc 100644 --- a/SourceCallback.cpp +++ b/SourceCallback.cpp @@ -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_); diff --git a/SourceCallback.h b/SourceCallback.h index 30d6029..0fd621d 100644 --- a/SourceCallback.h +++ b/SourceCallback.h @@ -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; diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 2d92358..c2f9c70 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -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(); }