From ce46a1d3d75b99e27c7957b8f07cf260d36f1011 Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Fri, 9 Feb 2024 22:48:49 -0600 Subject: [PATCH] Refactored analog control system to use digital DAS input system with directional input support. --- .../AdventuresInLestoria.cpp | 23 +++++++++++--- Adventures in Lestoria/AdventuresInLestoria.h | 8 +++-- .../InventoryConsumableWindow.cpp | 16 +--------- Adventures in Lestoria/Key.cpp | 29 ++++++++++++++++++ Adventures in Lestoria/Key.h | 1 + Adventures in Lestoria/LoadGameWindow.cpp | 15 +-------- Adventures in Lestoria/Menu.cpp | 10 +++--- .../OverworldMapLevelWindow.cpp | 4 +-- .../ScrollableWindowComponent.h | 10 ------ Adventures in Lestoria/State_MainMenu.cpp | 1 + Adventures in Lestoria/Version.h | 2 +- .../assets/themes/button_analogstick.png | Bin 0 -> 9418 bytes Adventures in Lestoria/olcPGEX_Gamepad.h | 1 + Adventures in Lestoria/olcPixelGameEngine.h | 24 +++++++++++++++ 14 files changed, 91 insertions(+), 53 deletions(-) create mode 100644 Adventures in Lestoria/assets/themes/button_analogstick.png diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp index fa9b3c98..8f3675c9 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.cpp +++ b/Adventures in Lestoria/AdventuresInLestoria.cpp @@ -108,13 +108,17 @@ InputGroup AiL::KEY_DOWN; InputGroup AiL::KEY_ATTACK; InputGroup AiL::KEY_CONFIRM; InputGroup AiL::KEY_MENU; -InputGroup AiL::KEY_SCROLLUP; -InputGroup AiL::KEY_SCROLLDOWN; InputGroup AiL::KEY_BACK; InputGroup AiL::KEY_START; InputGroup AiL::KEY_SELECT; InputGroup AiL::KEY_UNEQUIP; +InputGroup AiL::KEY_SCROLLDOWN; +InputGroup AiL::KEY_SCROLLUP; +InputGroup AiL::KEY_SCROLLLEFT; +InputGroup AiL::KEY_SCROLLRIGHT; +InputGroup AiL::KEY_SCROLLHORZ; +InputGroup AiL::KEY_SCROLLVERT; InputGroup AiL::KEY_SCROLL; InputGroup AiL::KEY_CHANGE_LOADOUT; @@ -2505,8 +2509,19 @@ void AiL::InitializeDefaultKeybinds(){ KEY_SELECT.AddKeybind({KEY,ESCAPE}); KEY_SELECT.AddKeybind({CONTROLLER,static_cast(GPButtons::SELECT)}); - KEY_SCROLL.AddKeybind({ANALOG,static_cast(GPAxes::LY)}); - KEY_SCROLL.AddKeybind({ANALOG,static_cast(GPAxes::RY)}); + KEY_SCROLLLEFT.AddKeybind({ANALOG,static_cast(GPAxes::LX)}); + KEY_SCROLLLEFT.AddKeybind({ANALOG,static_cast(GPAxes::RX)}); + KEY_SCROLLRIGHT.AddKeybind({ANALOG,static_cast(GPAxes::LX)}); + KEY_SCROLLRIGHT.AddKeybind({ANALOG,static_cast(GPAxes::RX)}); + KEY_SCROLLUP.AddKeybind({ANALOG,static_cast(GPAxes::LY)}); + KEY_SCROLLUP.AddKeybind({ANALOG,static_cast(GPAxes::RY)}); + KEY_SCROLLDOWN.AddKeybind({ANALOG,static_cast(GPAxes::LY)}); + KEY_SCROLLDOWN.AddKeybind({ANALOG,static_cast(GPAxes::RY)}); + KEY_SCROLLVERT.AddKeybind({ANALOG,static_cast(GPAxes::LY)}); + KEY_SCROLLVERT.AddKeybind({ANALOG,static_cast(GPAxes::RY)}); + KEY_SCROLLHORZ.AddKeybind({ANALOG,static_cast(GPAxes::LX)}); + KEY_SCROLLHORZ.AddKeybind({ANALOG,static_cast(GPAxes::RX)}); + KEY_SCROLL.AddKeybind({ANALOG,static_cast(GPAxes::ALL)}); KEY_UNEQUIP.AddKeybind({KEY,R}); KEY_UNEQUIP.AddKeybind({CONTROLLER,static_cast(GPButtons::FACE_U)}); diff --git a/Adventures in Lestoria/AdventuresInLestoria.h b/Adventures in Lestoria/AdventuresInLestoria.h index 3f1fd988..52482b79 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.h +++ b/Adventures in Lestoria/AdventuresInLestoria.h @@ -73,8 +73,6 @@ class AiL : public olc::PixelGameEngine SplashScreen splash; public: Pathfinding pathfinder; - static InputGroup KEY_SCROLLUP; - static InputGroup KEY_SCROLLDOWN; static InputGroup KEY_BACK; static InputGroup KEY_CONFIRM; static InputGroup KEY_ATTACK; @@ -88,6 +86,12 @@ public: static InputGroup KEY_START; static InputGroup KEY_SELECT; + static InputGroup KEY_SCROLLDOWN; + static InputGroup KEY_SCROLLUP; + static InputGroup KEY_SCROLLLEFT; + static InputGroup KEY_SCROLLRIGHT; + static InputGroup KEY_SCROLLHORZ; + static InputGroup KEY_SCROLLVERT; static InputGroup KEY_SCROLL; static InputGroup KEY_CHANGE_LOADOUT; diff --git a/Adventures in Lestoria/InventoryConsumableWindow.cpp b/Adventures in Lestoria/InventoryConsumableWindow.cpp index 462cda9e..00675c36 100644 --- a/Adventures in Lestoria/InventoryConsumableWindow.cpp +++ b/Adventures in Lestoria/InventoryConsumableWindow.cpp @@ -86,18 +86,6 @@ void Menu::InitializeConsumableInventoryWindow(){ auto okButton=inventoryWindow->ADD("OK Button",MenuComponent)(geom2d::rect{{windowSize.x/2-24,173.f},{48,12}},"Ok",[](MenuFuncData data){Menu::CloseMenu();return true;})END; - #pragma region ScrollWindow macro lambda - #define ScrollWindow(amount) \ - [](MenuType type){ \ - auto scrollWindow=Component(type,"inventory"); \ - scrollWindow->Scroll(amount); \ - int invWidth=int((scrollWindow->rect.size.x-12)/(float(scrollWindow->options.size.x)+scrollWindow->options.padding)); /*The inventory width determines how many items to skip at a time.*/ \ - scrollWindow->SetSelectionSkipIncrement(invWidth); \ - float scrollAmt=amount*game->GetElapsedTime()*"Interface.AnalogScrollSpeed"_F; \ - scrollWindow->IncreaseSelectionIndex(scrollAmt/24.f); \ - } - #pragma endregion - inventoryWindow->SetupKeyboardNavigation( [](MenuType type,Data&returnData){ //On Open //Try to find the component that matches the loadout item we have on us. @@ -123,9 +111,7 @@ void Menu::InitializeConsumableInventoryWindow(){ {game->KEY_BACK,{"Back",[](MenuType type){ Menu::CloseMenu(); }}}, - {{game->KEY_SCROLL,Analog},{"Scroll",ScrollWindow(game->KEY_SCROLL.Analog())}}, - {{game->KEY_SCROLLUP,Held},{"Scroll Up",ScrollWindow(-1.0f)}}, - {{game->KEY_SCROLLDOWN,Held},{"Scroll Down",ScrollWindow(1.0f)}}, + {{game->KEY_SCROLLVERT,Analog},{"Scroll",[](MenuType type){}}}, } ,{ //Button Navigation Rules {"OK Button",{ diff --git a/Adventures in Lestoria/Key.cpp b/Adventures in Lestoria/Key.cpp index 9c7718ef..11600ce8 100644 --- a/Adventures in Lestoria/Key.cpp +++ b/Adventures in Lestoria/Key.cpp @@ -260,6 +260,34 @@ const float InputGroup::Analog()const{ return 0.f; } +const float InputGroup::AnalogDAS(){ + for(Input input:keys){ + float analogVal=input.Analog(); + if(analogVal!=0.f&&initialHoldDownTime==0.f){ + initialHoldDownTime="Interface.InitialScrollDelay"_F; + return analogVal; + }else + if(analogVal!=0.f&&initialHoldDownTime>0.f){ + initialHoldDownTime-=game->GetElapsedTime(); + if(initialHoldDownTime<=0.f){ + holdDownTime="Interface.ScrollDelay"_F; + return analogVal; + } + return 0.f; + }else + if(analogVal!=0.f&&holdDownTime>0.f){ + holdDownTime-=game->GetElapsedTime(); + if(holdDownTime<=0.f){ + holdDownTime="Interface.ScrollDelay"_F; + return analogVal; + } + return 0.f; + } + } + initialHoldDownTime=holdDownTime=0.f; + return 0.f; +} + std::string InputGroup::GetDisplayName(){ std::string combinationDisplay=""; for(Input input:keys){ @@ -480,6 +508,7 @@ std::map,GenericKey::KeyInfo> GenericKey::keyLiteral={ {{ANALOG, static_cast(GPAxes::TR)},{"Right Trigger","themes/button_r2.png"}}, {{ANALOG, static_cast(GPAxes::DX)},{"Right/Left","themes/button_analogstick_horz.png"}}, {{ANALOG, static_cast(GPAxes::DY)},{"Up/Down","themes/button_analogstick_vert.png"}}, + {{ANALOG, static_cast(GPAxes::ALL)},{"Analog Stick","themes/button_analogstick.png"}}, }; void Input::SetUsingGamepad(const bool usingGamepad){ diff --git a/Adventures in Lestoria/Key.h b/Adventures in Lestoria/Key.h index 4202779e..09b88d95 100644 --- a/Adventures in Lestoria/Key.h +++ b/Adventures in Lestoria/Key.h @@ -111,6 +111,7 @@ public: const bool Held()const; const bool Released(); const float Analog()const; + const float AnalogDAS(); std::string GetDisplayName(); //Draws an input display with accompanying text centered at given position. void DrawInput(const std::variantrenderer,const vf2d pos,const std::string_view displayText,const uint8_t alpha)const; diff --git a/Adventures in Lestoria/LoadGameWindow.cpp b/Adventures in Lestoria/LoadGameWindow.cpp index 2e0b03f9..0e1ee4e6 100644 --- a/Adventures in Lestoria/LoadGameWindow.cpp +++ b/Adventures in Lestoria/LoadGameWindow.cpp @@ -81,17 +81,6 @@ void Menu::InitializeLoadGameWindow(){ onlineCharacterTab->SetSelectionType(HIGHLIGHT); #endif - #pragma region ScrollWindow macro lambda - #define ScrollWindow(amount) \ - [](MenuType type){ \ - auto scrollWindow=Component(type,"Game Files List"); \ - scrollWindow->Scroll(amount); \ - float scrollAmt=amount*game->GetElapsedTime()*"Interface.AnalogScrollSpeed"_F;\ - /*Height of these buttons is 48.*/ \ - scrollWindow->IncreaseSelectionIndex(scrollAmt/48.f); \ - } - #pragma endregion - #pragma region Keyboard Navigation Rules loadGameWindow->SetupKeyboardNavigation( [](MenuType type,Data&returnData){ //On Open @@ -109,9 +98,7 @@ void Menu::InitializeLoadGameWindow(){ {{game->KEY_BACK},{"Back to Title Screen",[](MenuType type){ Component(type,"Go Back Button")->Click(); }}}, - {{game->KEY_SCROLL,Analog},{"Scroll",ScrollWindow(game->KEY_SCROLL.Analog())}}, - {{game->KEY_SCROLLUP,Held},{"Scroll Up",ScrollWindow(-1.0f)}}, - {{game->KEY_SCROLLDOWN,Held},{"Scroll Down",ScrollWindow(1.0f)}}, + {{game->KEY_SCROLLVERT,Analog},{"Scroll",[](MenuType type){}}}, } ,{ //Button Navigation Rules {"Game Files List",{ diff --git a/Adventures in Lestoria/Menu.cpp b/Adventures in Lestoria/Menu.cpp index 681283e1..483addb1 100644 --- a/Adventures in Lestoria/Menu.cpp +++ b/Adventures in Lestoria/Menu.cpp @@ -342,7 +342,7 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){ if(navigationGroups.count(selectionButtonName)){ Navigation nav=navigationGroups[selectionButtonName]; - if(game->KEY_UP.PressedDAS()){ + if(game->KEY_UP.PressedDAS()||game->KEY_SCROLLUP.AnalogDAS()<-0.2f){ SetMouseNavigation(false); if(std::holds_alternative(nav.up)&&std::get(nav.up).length()>0)SetSelection(std::string_view(std::get(nav.up))); else @@ -352,7 +352,7 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){ SetSelection(returnData); } } - if(game->KEY_DOWN.PressedDAS()){ + if(game->KEY_DOWN.PressedDAS()||game->KEY_SCROLLDOWN.AnalogDAS()>0.2f){ SetMouseNavigation(false); if(std::holds_alternative(nav.down)&&std::get(nav.down).length()>0)SetSelection(std::string_view(std::get(nav.down))); else @@ -362,7 +362,7 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){ SetSelection(returnData); } } - if(game->KEY_LEFT.PressedDAS()){ + if(game->KEY_LEFT.PressedDAS()||game->KEY_SCROLLLEFT.AnalogDAS()<-0.2f){ SetMouseNavigation(false); if(std::holds_alternative(nav.left)&&std::get(nav.left).length()>0)SetSelection(std::string_view(std::get(nav.left))); else @@ -372,7 +372,7 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){ SetSelection(returnData); } } - if(game->KEY_RIGHT.PressedDAS()){ + if(game->KEY_RIGHT.PressedDAS()||game->KEY_SCROLLRIGHT.AnalogDAS()>0.2f){ SetMouseNavigation(false); if(std::holds_alternative(nav.right)&&std::get(nav.right).length()>0)SetSelection(std::string_view(std::get(nav.right))); else @@ -387,7 +387,7 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){ if(game->KEY_UP.Released()||game->KEY_RIGHT.Released()||game->KEY_LEFT.Released()||game->KEY_DOWN.Released()|| game->KEY_BACK.Released()||game->KEY_CONFIRM.Released()||game->KEY_START.Released()||game->KEY_SELECT.Released()|| - game->KEY_SCROLLDOWN.Released()||game->KEY_SCROLLUP.Released()||game->KEY_SCROLL.Analog()!=0.f){ + game->KEY_SCROLLDOWN.Released()||game->KEY_SCROLLUP.Released()||game->KEY_SCROLLVERT.Analog()!=0.f){ SetMouseNavigation(game->GetMouse(Mouse::LEFT).bReleased||game->GetMouse(Mouse::RIGHT).bReleased||game->GetMouse(Mouse::MIDDLE).bReleased); //If a click occurs we use mouse controls. buttonHoldTime=0; } diff --git a/Adventures in Lestoria/OverworldMapLevelWindow.cpp b/Adventures in Lestoria/OverworldMapLevelWindow.cpp index 40001f49..3c30e4a1 100644 --- a/Adventures in Lestoria/OverworldMapLevelWindow.cpp +++ b/Adventures in Lestoria/OverworldMapLevelWindow.cpp @@ -74,8 +74,8 @@ void Menu::InitializeOverworldMapLevelWindow(){ {{game->KEY_CHANGE_LOADOUT},{"Change Loadout",[](MenuType type){ Component(type,"Change Loadout Button")->Click(); }}}, - {{game->KEY_SCROLL,Analog},{"Scroll Encounters",[](MenuType type){ - Component(type,"Spawns List")->Scroll(game->KEY_SCROLL.Analog()); + {{game->KEY_SCROLLVERT,Analog},{"Scroll Encounters",[](MenuType type){ + Component(type,"Spawns List")->Scroll(game->KEY_SCROLLVERT.Analog()); }}}, {{game->KEY_SCROLLUP,Held},{"",[](MenuType type){ Component(type,"Spawns List")->Scroll(1.f); diff --git a/Adventures in Lestoria/ScrollableWindowComponent.h b/Adventures in Lestoria/ScrollableWindowComponent.h index d5a63b7c..90aad62e 100644 --- a/Adventures in Lestoria/ScrollableWindowComponent.h +++ b/Adventures in Lestoria/ScrollableWindowComponent.h @@ -105,16 +105,6 @@ public: return geom2d::overlaps(geom2d::rect{Menu::menus[parentMenu]->pos+rect.pos,rect.size},game->GetMousePos())&& //Make sure the mouse is inside the parent window component first.... geom2d::overlaps(geom2d::rect{Menu::menus[parentMenu]->pos+rect.pos+child->rect.pos,child->rect.size},game->GetMousePos()); } - - inline void SetSelectionSkipIncrement(const int selectionSkipIncrement){ - this->selectionSkipIncrement=selectionSkipIncrement; - } - - inline void IncreaseSelectionIndex(const float val){ - float prevIndex=selectionIndex/selectionSkipIncrement; - selectionIndex=std::clamp(selectionIndex+val,0.f,float(components.size()-1)); - if(size_t(prevIndex)!=size_t(selectionIndex/selectionSkipIncrement)){Menu::menus[parentMenu]->SetSelection(components[size_t(selectionIndex)],false);} - } protected: virtual inline vf2d GetScrollAmount()const{ return scrollOffset; diff --git a/Adventures in Lestoria/State_MainMenu.cpp b/Adventures in Lestoria/State_MainMenu.cpp index b6d2e7ee..f8a8bf8a 100644 --- a/Adventures in Lestoria/State_MainMenu.cpp +++ b/Adventures in Lestoria/State_MainMenu.cpp @@ -56,4 +56,5 @@ void State_MainMenu::OnUserUpdate(AiL*game){ }; void State_MainMenu::Draw(AiL*game){ TitleScreen::Draw(); + game->DrawOGStringDecal({0,0},"DOWN: "+std::to_string(game->KEY_SCROLLVERT.Analog())); }; \ No newline at end of file diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 07b2de9e..164fc87f 100644 --- a/Adventures in Lestoria/Version.h +++ b/Adventures in Lestoria/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 0 #define VERSION_MINOR 3 #define VERSION_PATCH 0 -#define VERSION_BUILD 6923 +#define VERSION_BUILD 6933 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/assets/themes/button_analogstick.png b/Adventures in Lestoria/assets/themes/button_analogstick.png new file mode 100644 index 0000000000000000000000000000000000000000..c157ac072f8e5b7dfc1a15a1632419c19065d933 GIT binary patch literal 9418 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::max(),const bool disableDynamicScaling=false); + void DrawOGStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }); void DrawStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }); void DrawStringPropDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }, const float width=std::numeric_limits::max(),const bool disableDynamicScaling=false); void DrawShadowStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits::max(),const float shadowSizeFactor=1,const bool disableDynamicScaling=false); @@ -3375,6 +3376,29 @@ namespace olc void PixelGameEngine::DrawPartialWarpedDecal(olc::Decal* decal, const olc::vf2d(&pos)[4], const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint) { DrawPartialWarpedDecal(decal, &pos[0], source_pos, source_size, tint); } + void PixelGameEngine::DrawOGStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col, const olc::vf2d& scale) + { + olc::vf2d spos = { 0.0f, 0.0f }; + for (auto c : sText) + { + if (c == '\n') + { + spos.x = 0; spos.y += 8.0f * scale.y; + } + else if (c == '\t') + { + spos.x += 8.0f * float(nTabSizeInSpaces) * scale.x; + } + else + { + int32_t ox = (c - 32) % 16; + int32_t oy = (c - 32) / 16; + DrawPartialDecal(pos + spos, fontRenderable.Decal(), {float(ox) * 8.0f, float(oy) * 8.0f}, {8.0f, 8.0f}, scale, col); + spos.x += 8.0f * scale.x; + } + } + } + void PixelGameEngine::DrawStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col, const olc::vf2d& scale,const float width,const bool disableDynamicScaling) { struct DecalData{