The open source repository for the action RPG game in development by Sig Productions titled 'Adventures in Lestoria'!
https://forums.lestoria.net
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
546 lines
16 KiB
546 lines
16 KiB
#pragma region License
|
|
/*
|
|
License (OLC-3)
|
|
~~~~~~~~~~~~~~~
|
|
|
|
Copyright 2024 Joshua Sigona <sigonasr2@gmail.com>
|
|
|
|
Redistribution and use in source and binary forms, with or without modification,
|
|
are permitted provided that the following conditions are met:
|
|
|
|
1. Redistributions or derivations of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
2. Redistributions or derivative works in binary form must reproduce the above
|
|
copyright notice. This list of conditions and the following disclaimer must be
|
|
reproduced in the documentation and/or other materials provided with the distribution.
|
|
|
|
3. Neither the name of the copyright holder nor the names of its contributors may
|
|
be used to endorse or promote products derived from this software without specific
|
|
prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
|
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
SUCH DAMAGE.
|
|
|
|
Portions of this software are copyright © 2024 The FreeType
|
|
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
|
All rights reserved.
|
|
*/
|
|
#pragma endregion
|
|
#include "Key.h"
|
|
#include "DEFINES.h"
|
|
#include "AdventuresInLestoria.h"
|
|
#include "olcPGEX_Gamepad.h"
|
|
#include "Menu.h"
|
|
|
|
INCLUDE_game
|
|
INCLUDE_GFX
|
|
|
|
bool Input::usingGamepad;
|
|
safemap<std::string,InputGroup*>InputGroup::menuNamesToInputGroups;
|
|
|
|
Input::Input(InputType type,int key)
|
|
:type(type),key(key){}
|
|
|
|
bool Input::Pressed(){
|
|
if(!game->IsFocused())return false;
|
|
bool inputPressed=false;
|
|
switch(type){
|
|
case KEY:{
|
|
inputPressed=game->GetKey(Key(key)).bPressed;
|
|
}break;
|
|
case MOUSE:{
|
|
inputPressed=game->GetMouse(key).bPressed;
|
|
}break;
|
|
case CONTROLLER:{
|
|
for(GamePad*gamepad:GamePad::getGamepads()){
|
|
if(gamepad->stillConnected&&gamepad->getButton(static_cast<GPButtons>(key)).bPressed)inputPressed=true;
|
|
}
|
|
}break;
|
|
case ANALOG:{
|
|
//An analog input can never be "pressed". No-op.
|
|
}break;
|
|
default:{
|
|
ERR("Invalid Control Scheme detected! We shouldn't be here!! Type is "<<type);
|
|
}
|
|
}
|
|
if(inputPressed){
|
|
usingGamepad=type==CONTROLLER;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Input::Held(){
|
|
if(!game->IsFocused())return false;
|
|
bool inputHeld=false;
|
|
switch(type){
|
|
case KEY:{
|
|
inputHeld=game->GetKey(Key(key)).bHeld;
|
|
}break;
|
|
case MOUSE:{
|
|
inputHeld=game->GetMouse(key).bHeld;
|
|
}break;
|
|
case CONTROLLER:{
|
|
for(GamePad*gamepad:GamePad::getGamepads()){
|
|
if(gamepad->stillConnected&&gamepad->getButton(static_cast<GPButtons>(key)).bHeld)inputHeld=true;
|
|
}
|
|
}break;
|
|
case ANALOG:{
|
|
//An analog input can never be "held". No-op.
|
|
}break;
|
|
default:{
|
|
ERR("Invalid Control Scheme detected! We shouldn't be here!! Type is "<<type);
|
|
}
|
|
}
|
|
if(inputHeld){
|
|
usingGamepad=type==CONTROLLER;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Input::Released(){
|
|
if(!game->IsFocused())return false;
|
|
bool inputReleased=false;
|
|
switch(type){
|
|
case KEY:{
|
|
inputReleased=game->GetKey(Key(key)).bReleased;
|
|
}break;
|
|
case MOUSE:{
|
|
inputReleased=game->GetMouse(key).bReleased;
|
|
}break;
|
|
case CONTROLLER:{
|
|
for(GamePad*gamepad:GamePad::getGamepads()){
|
|
if(gamepad->stillConnected&&gamepad->getButton(static_cast<GPButtons>(key)).bReleased)inputReleased=true;
|
|
}
|
|
}break;
|
|
case ANALOG:{
|
|
//An analog input can never be "released". No-op.
|
|
}break;
|
|
default:{
|
|
ERR("Invalid Control Scheme detected! We shouldn't be here!! Type is "<<type);
|
|
}
|
|
}
|
|
if(inputReleased){
|
|
usingGamepad=type==CONTROLLER;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
float Input::Analog(){
|
|
if(!game->IsFocused())return false;
|
|
switch(type){
|
|
case ANALOG:{
|
|
for(GamePad*gamepad:GamePad::getGamepads()){
|
|
if(gamepad->stillConnected){
|
|
float axisVal=gamepad->getAxis(static_cast<GPAxes>(key));
|
|
if(axisVal!=0.f){
|
|
usingGamepad=true;
|
|
return axisVal;
|
|
}
|
|
}
|
|
}
|
|
}break;
|
|
case KEY:
|
|
case MOUSE:
|
|
case CONTROLLER:{
|
|
//Doesn't return analog inputs. No-op.
|
|
}break;
|
|
default:{
|
|
ERR("Invalid Control Scheme detected for analog controls! We shouldn't be here!! Type is "<<type);
|
|
}
|
|
}
|
|
return 0.f;
|
|
}
|
|
|
|
std::string Input::GetDisplayName()const{
|
|
return GenericKey::keyLiteral.at({type,key}).displayName;
|
|
}
|
|
|
|
const std::string Input::str()const{
|
|
std::string outputStr="";
|
|
switch(type){
|
|
case KEY:{
|
|
outputStr=std::format("[Type:KEY,Key:{}]",GetDisplayName());
|
|
}break;
|
|
case MOUSE:{
|
|
outputStr=std::format("[Type:MOUSE,Key:{}]",GetDisplayName());
|
|
}break;
|
|
case CONTROLLER:{
|
|
outputStr=std::format("[Type:CONTROLLER,Key:{}]",GetDisplayName());
|
|
}break;
|
|
case ANALOG:{
|
|
outputStr=std::format("[Type:ANALOG,Key:{}]",GetDisplayName());
|
|
}break;
|
|
default:{
|
|
ERR(std::format("WARNING! Unhandled input type: {}",int(type)))
|
|
}
|
|
}
|
|
return outputStr;
|
|
}
|
|
|
|
InputGroup::InputGroup(){}
|
|
|
|
void InputGroup::AddKeybind(Input bind){
|
|
keys.insert(bind);
|
|
keyOrder.push_back(bind);
|
|
}
|
|
|
|
void InputGroup::RemoveKeybind(Input bind){
|
|
size_t erased=keys.erase(bind);
|
|
erased+=std::erase(keyOrder,bind);
|
|
if(erased!=2)ERR(std::format("WARNING! Could not remove keybind {}",bind.str()));
|
|
}
|
|
|
|
const bool InputGroup::Pressed()const{
|
|
for(Input input:keys){
|
|
if(input.Pressed())return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
const bool InputGroup::Held()const{
|
|
for(Input input:keys){
|
|
if(input.Held())return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
const bool InputGroup::Released()const{
|
|
for(Input input:keys){
|
|
if(input.Released())return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
const float InputGroup::Analog()const{
|
|
for(Input input:keys){
|
|
float analogVal=input.Analog();
|
|
if(analogVal!=0.f)return analogVal;
|
|
}
|
|
return 0.f;
|
|
}
|
|
|
|
std::string InputGroup::GetDisplayName(){
|
|
std::string combinationDisplay="";
|
|
for(Input input:keys){
|
|
if(combinationDisplay.length()>0){
|
|
combinationDisplay+=",";
|
|
}
|
|
combinationDisplay+=input.GetDisplayName();
|
|
}
|
|
return combinationDisplay;
|
|
}
|
|
|
|
void InputGroup::DrawInput(const std::variant<AiL*const,TileTransformedView*const>renderer,const vf2d pos,const std::string_view displayText,const uint8_t alpha,InputType type)const{
|
|
std::optional<Input>primaryKey;
|
|
switch(type){
|
|
case CONTROLLER:primaryKey=GetPrimaryKey(CONTROLLER);break;
|
|
case MOUSE:primaryKey=GetPrimaryKey(MOUSE);break;
|
|
default:primaryKey=GetPrimaryKey(KEY);break;
|
|
}
|
|
|
|
vf2d buttonImgSize{};
|
|
std::vector<std::variant<Decal*,std::string>>buttonImgs;
|
|
if(primaryKey.has_value()){
|
|
if(primaryKey.value().HasIcon()){
|
|
buttonImgSize+=primaryKey.value().GetIcon().Sprite()->Size()+vf2d{"Interface.InputHelperSpacing"_F,"Interface.InputHelperSpacing"_F};
|
|
buttonImgs.push_back(primaryKey.value().GetIcon().Decal());
|
|
}else{
|
|
buttonImgSize+=game->GetTextSizeProp(primaryKey.value().GetDisplayName())+vf2d{"Interface.InputHelperSpacing"_F,"Interface.InputHelperSpacing"_F};
|
|
buttonImgs.push_back(primaryKey.value().GetDisplayName());
|
|
}
|
|
}
|
|
vf2d descriptionTextSize=game->GetTextSizeProp(displayText);
|
|
vf2d offset=-((buttonImgSize+descriptionTextSize)/2.f);
|
|
for(auto&button:buttonImgs){
|
|
if(std::holds_alternative<Decal*>(button)){
|
|
Decal*img=std::get<Decal*>(button);
|
|
game->view.DrawDecal(pos+offset,img,{1.f,1.f},{255,255,255,alpha});
|
|
offset.x+=img->sprite->width+"Interface.InputHelperSpacing"_I;
|
|
}else
|
|
if(std::holds_alternative<std::string>(button)){
|
|
std::string label=std::get<std::string>(button);
|
|
vf2d textSize=game->GetTextSizeProp(label);
|
|
Pixel buttonBackCol="Interface.InputButtonBackCol"_Pixel;
|
|
Pixel buttonTextCol="Interface.InputButtonTextCol"_Pixel;
|
|
buttonBackCol.a=alpha;
|
|
buttonTextCol.a=alpha;
|
|
|
|
#pragma region Render Macro
|
|
#define Render(rendererType) \
|
|
std::get<rendererType*const>(renderer)->FillRectDecal(pos+offset+vf2d{-2.f,0.f},vf2d{textSize.x+4,textSize.y},buttonBackCol); \
|
|
std::get<rendererType*const>(renderer)->FillRectDecal(pos+offset+vf2d{-1.f,-1.f},vf2d{textSize.x+2,textSize.y},buttonBackCol); \
|
|
std::get<rendererType*const>(renderer)->FillRectDecal(pos+offset+vf2d{-1.f,0.f},vf2d{textSize.x+2,textSize.y+1.f},buttonBackCol); \
|
|
std::get<rendererType*const>(renderer)->DrawStringPropDecal(pos+offset+vf2d{0.f,0.f},label,buttonTextCol);
|
|
#pragma endregion
|
|
|
|
if(std::holds_alternative<AiL*const>(renderer)){
|
|
Render(AiL);
|
|
}else
|
|
if(std::holds_alternative<TileTransformedView*const>(renderer)){
|
|
Render(TileTransformedView);
|
|
}
|
|
offset.x+=textSize.x+"Interface.InputHelperSpacing"_I;
|
|
}else [[unlikely]]ERR("WARNING! Hit a state where no data is inside of the button! THIS SHOULD NOT BE HAPPENING!");
|
|
|
|
game->view.DrawShadowStringPropDecal(pos+offset,displayText,{255,255,255,alpha},{0,0,0,alpha});
|
|
}
|
|
}
|
|
|
|
void InputGroup::DrawInput(const std::variant<AiL*const,TileTransformedView*const>renderer,const vf2d pos,const std::string_view displayText,const uint8_t alpha)const{
|
|
InputType primaryType;
|
|
if(Input::UsingGamepad())primaryType=CONTROLLER;
|
|
else if(Menu::UsingMouseNavigation())primaryType=MOUSE;
|
|
else primaryType=KEY;
|
|
DrawInput(renderer,pos,displayText,alpha,primaryType);
|
|
}
|
|
|
|
const bool Input::HasIcon()const{
|
|
return GenericKey::keyLiteral.at({type,key}).iconName.length()>0;
|
|
}
|
|
const Renderable&Input::GetIcon()const{
|
|
return GFX.at(GenericKey::keyLiteral.at({type,key}).iconName);
|
|
}
|
|
|
|
#undef END
|
|
|
|
std::map<std::pair<InputType,int>,GenericKey::KeyInfo> GenericKey::keyLiteral={
|
|
{{KEY, NONE},{""}},
|
|
{{KEY, A},{"A"}},
|
|
{{KEY, B},{"B"}},
|
|
{{KEY, C},{"C"}},
|
|
{{KEY, D},{"D"}},
|
|
{{KEY, E},{"E"}},
|
|
{{KEY, F},{"F"}},
|
|
{{KEY, G},{"G"}},
|
|
{{KEY, H},{"H"}},
|
|
{{KEY, I},{"I"}},
|
|
{{KEY, J},{"J"}},
|
|
{{KEY, K},{"L"}},
|
|
{{KEY, L},{"L"}},
|
|
{{KEY, M},{"M"}},
|
|
{{KEY, N},{"N"}},
|
|
{{KEY, O},{"O"}},
|
|
{{KEY, P},{"P"}},
|
|
{{KEY, Q},{"Q"}},
|
|
{{KEY, R},{"R"}},
|
|
{{KEY, S},{"S"}},
|
|
{{KEY, T},{"T"}},
|
|
{{KEY, U},{"U"}},
|
|
{{KEY, V},{"V"}},
|
|
{{KEY, W},{"W"}},
|
|
{{KEY, X},{"X"}},
|
|
{{KEY, Y},{"Y"}},
|
|
{{KEY, Z},{"Z"}},
|
|
{{KEY, K0},{"0"}},
|
|
{{KEY, K1},{"1"}},
|
|
{{KEY, K2},{"2"}},
|
|
{{KEY, K3},{"3"}},
|
|
{{KEY, K4},{"4"}},
|
|
{{KEY, K5},{"5"}},
|
|
{{KEY, K6},{"6"}},
|
|
{{KEY, K7},{"7"}},
|
|
{{KEY, K8},{"8"}},
|
|
{{KEY, K9},{"9"}},
|
|
{{KEY, F1},{"F1"}},
|
|
{{KEY, F2},{"F2"}},
|
|
{{KEY, F3},{"F3"}},
|
|
{{KEY, F4},{"F4"}},
|
|
{{KEY, F5},{"F5"}},
|
|
{{KEY, F6},{"F6"}},
|
|
{{KEY, F7},{"F7"}},
|
|
{{KEY, F8},{"F8"}},
|
|
{{KEY, F9},{"F9"}},
|
|
{{KEY, F10},{"F10"}},
|
|
{{KEY, F11},{"F11"}},
|
|
{{KEY, F12},{"F12"}},
|
|
{{KEY, UP},{"UP"}},
|
|
{{KEY, DOWN},{"DOWN"}},
|
|
{{KEY, LEFT},{"LEFT"}},
|
|
{{KEY, RIGHT},{"RIGHT"}},
|
|
{{KEY, SPACE},{"SPACE"}},
|
|
{{KEY, TAB},{"TAB"}},
|
|
{{KEY, SHIFT},{"SHIFT"}},
|
|
{{KEY, CTRL},{"CTRL"}},
|
|
{{KEY, INS},{"INS"}},
|
|
{{KEY, DEL},{"DEL"}},
|
|
{{KEY, HOME},{"HOME"}},
|
|
{{KEY, END},{"END"}},
|
|
{{KEY, PGUP},{"PGUP"}},
|
|
{{KEY, PGDN},{"PGDN"}},
|
|
{{KEY, BACK},{"BACK"}},
|
|
{{KEY, ESCAPE},{"ESC"}},
|
|
{{KEY, RETURN},{"ENTER"}},
|
|
{{KEY, ENTER},{"ENTER"}},
|
|
{{KEY, PAUSE},{"PAUSE"}},
|
|
{{KEY, SCROLL},{"SCR LK"}},
|
|
{{KEY, NP0},{"NP0"}},
|
|
{{KEY, NP1},{"NP1"}},
|
|
{{KEY, NP2},{"NP2"}},
|
|
{{KEY, NP3},{"NP3"}},
|
|
{{KEY, NP4},{"NP4"}},
|
|
{{KEY, NP5},{"NP5"}},
|
|
{{KEY, NP6},{"NP6"}},
|
|
{{KEY, NP7},{"NP7"}},
|
|
{{KEY, NP8},{"NP8"}},
|
|
{{KEY, NP9},{"NP9"}},
|
|
{{KEY, NP_MUL},{"NP*"}},
|
|
{{KEY, NP_DIV},{"NP/"}},
|
|
{{KEY, NP_ADD},{"NP+"}},
|
|
{{KEY, NP_SUB},{"NP-"}},
|
|
{{KEY, NP_DECIMAL},{"NP."}},
|
|
{{KEY, PERIOD},{"."}},
|
|
{{KEY, EQUALS},{"="}},
|
|
{{KEY, COMMA},{",{"}},
|
|
{{KEY, MINUS},{"-"}},
|
|
{{KEY, OEM_1},{";"}},
|
|
{{KEY, OEM_2},{"/"}},
|
|
{{KEY, OEM_3},{"~"}},
|
|
{{KEY, OEM_4},{"["}},
|
|
{{KEY, OEM_5},{"\\"}},
|
|
{{KEY, OEM_6},{"]"}},
|
|
{{KEY, OEM_7},{"\""}},
|
|
{{KEY, OEM_8},{"\\"}},
|
|
{{KEY, CAPS_LOCK},{"CAP LK"}},
|
|
{{KEY, olc::ENUM_END},{""}},
|
|
{{MOUSE, Mouse::LEFT},{"L.MOUSE"}},
|
|
{{MOUSE, Mouse::RIGHT},{"R.MOUSE"}},
|
|
{{MOUSE, Mouse::MIDDLE},{"M.MOUSE"}},
|
|
{{CONTROLLER, static_cast<int>(GPButtons::FACE_D)},{"A/X","themes/button_d.png"}},
|
|
{{CONTROLLER, static_cast<int>(GPButtons::FACE_L)},{"X/Square","themes/button_l.png"}},
|
|
{{CONTROLLER, static_cast<int>(GPButtons::FACE_R)},{"B/Circle","themes/button_r.png"}},
|
|
{{CONTROLLER, static_cast<int>(GPButtons::FACE_U)},{"Y/Triangle","themes/button_u.png"}},
|
|
{{CONTROLLER, static_cast<int>(GPButtons::L1)},{"L1","themes/button_l1.png"}},
|
|
{{CONTROLLER, static_cast<int>(GPButtons::L2)},{"L2","themes/button_l2.png"}},
|
|
{{CONTROLLER, static_cast<int>(GPButtons::L3)},{"L3"}},
|
|
{{CONTROLLER, static_cast<int>(GPButtons::R1)},{"R1","themes/button_r1.png"}},
|
|
{{CONTROLLER, static_cast<int>(GPButtons::R2)},{"R2","themes/button_r2.png"}},
|
|
{{CONTROLLER, static_cast<int>(GPButtons::R3)},{"R3"}},
|
|
{{CONTROLLER, static_cast<int>(GPButtons::SELECT)},{"SELECT"}},
|
|
{{CONTROLLER, static_cast<int>(GPButtons::START)},{"START"}},
|
|
{{CONTROLLER, static_cast<int>(GPButtons::DPAD_L)},{"LEFT"}},
|
|
{{CONTROLLER, static_cast<int>(GPButtons::DPAD_R)},{"RIGHT"}},
|
|
{{CONTROLLER, static_cast<int>(GPButtons::DPAD_U)},{"UP"}},
|
|
{{CONTROLLER, static_cast<int>(GPButtons::DPAD_D)},{"DOWN"}},
|
|
{{ANALOG, static_cast<int>(GPAxes::LY)},{"Up/Down","themes/button_analogstick_vert.png"}},
|
|
{{ANALOG, static_cast<int>(GPAxes::RY)},{"Up/Down","themes/button_analogstick_vert.png"}},
|
|
{{ANALOG, static_cast<int>(GPAxes::LX)},{"Right/Left","themes/button_analogstick_horz.png"}},
|
|
{{ANALOG, static_cast<int>(GPAxes::RX)},{"Right/Left","themes/button_analogstick_horz.png"}},
|
|
{{ANALOG, static_cast<int>(GPAxes::TL)},{"Left Trigger","themes/button_l2.png"}},
|
|
{{ANALOG, static_cast<int>(GPAxes::TR)},{"Right Trigger","themes/button_r2.png"}},
|
|
{{ANALOG, static_cast<int>(GPAxes::DX)},{"Right/Left","themes/button_analogstick_horz.png"}},
|
|
{{ANALOG, static_cast<int>(GPAxes::DY)},{"Up/Down","themes/button_analogstick_vert.png"}},
|
|
};
|
|
|
|
void Input::SetUsingGamepad(const bool usingGamepad){
|
|
Input::usingGamepad=usingGamepad;
|
|
}
|
|
|
|
const bool Input::UsingGamepad(){
|
|
return usingGamepad;
|
|
}
|
|
|
|
const bool Input::AxesActive(){
|
|
float xAxis=0.f,yAxis=0.f;
|
|
for(GamePad*gamepad:GamePad::getGamepads()){
|
|
if(gamepad->stillConnected){
|
|
if(fabs(gamepad->getAxis(GPAxes::RX))>0.f){
|
|
xAxis=gamepad->getAxis(GPAxes::RX);
|
|
}else
|
|
if(fabs(gamepad->getAxis(GPAxes::LX))>0.f){
|
|
xAxis=gamepad->getAxis(GPAxes::LX);
|
|
}
|
|
|
|
if(fabs(gamepad->getAxis(GPAxes::RY))>0.f){
|
|
yAxis=gamepad->getAxis(GPAxes::RY);
|
|
}else
|
|
if(fabs(gamepad->getAxis(GPAxes::LY))>0.f){
|
|
yAxis=gamepad->getAxis(GPAxes::LY);
|
|
}
|
|
|
|
if(xAxis!=0.f||yAxis!=0.f)break; //Found a controller, so we're good to break.
|
|
}
|
|
}
|
|
return xAxis!=0.f||yAxis!=0.f;
|
|
}
|
|
|
|
void Input::StartVibration(){
|
|
if(UsingGamepad()){
|
|
for(GamePad*gamepad:GamePad::getGamepads()){
|
|
if(gamepad->stillConnected){
|
|
gamepad->startVibration();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
void Input::StopVibration(){
|
|
for(GamePad*gamepad:GamePad::getGamepads()){
|
|
if(gamepad->stillConnected){
|
|
gamepad->stopVibration();
|
|
}
|
|
}
|
|
}
|
|
|
|
const bool operator<(const InputGroup&group1,const InputGroup&group2){
|
|
return &group1<&group2;
|
|
}
|
|
|
|
const bool operator<(const InputEngageGroup&group1,const InputEngageGroup&group2){
|
|
return &group1<&group2;
|
|
}
|
|
|
|
const InputType Input::GetType()const{
|
|
return type;
|
|
}
|
|
|
|
const std::optional<Input>InputGroup::GetPrimaryKey(InputType type)const{
|
|
if(type==ANALOG)ERR("WARNING! Type cannot be ANALOG! Not supported!");
|
|
std::optional<Input>result;
|
|
if(keyOrder.size()>0){
|
|
auto it=std::find_if(keyOrder.begin(),keyOrder.end(),[&](const Input&input){
|
|
return input.GetType()==type
|
|
||(type==CONTROLLER&&input.GetType()==ANALOG);
|
|
});
|
|
if(it!=keyOrder.end())return *it;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
const bool operator==(const Input&input1,const Input&input2){
|
|
return input1.type==input2.type&&input1.key==input2.key;
|
|
}
|
|
|
|
InputEngageGroup::InputEngageGroup(InputGroup&group,EngageType type)
|
|
:group(group),type(type){}
|
|
|
|
|
|
const InputEngageGroup::EngageType InputEngageGroup::GetEngageType()const{
|
|
return type;
|
|
}
|
|
|
|
InputGroup&InputEngageGroup::GetGroup()const{
|
|
return group;
|
|
}
|
|
|
|
const InputEngageGroup InputEngageGroup::operator=(const InputEngageGroup&rhs){
|
|
return InputEngageGroup{rhs.group,rhs.type};
|
|
}
|
|
|
|
|
|
void InputGroup::RemovePrimaryKeybind(InputType type){
|
|
std::erase(keyOrder.front());
|
|
}
|
|
void InputGroup::AddPrimaryKeybind(InputType type){
|
|
|
|
} |