Joystick configuration, closes #499

Not yet tested as I don't have a joystick currently with me, but should work fine
dev-time-step
krzys-h 2016-01-24 17:36:25 +01:00
parent 40352be5cc
commit 7a521fbc90
9 changed files with 267 additions and 33 deletions

View File

@ -247,6 +247,13 @@ void InitializeEventTypeTexts()
EVENT_TYPE_TEXT[EVENT_INTERFACE_JOYSTICK]= "EVENT_INTERFACE_JOYSTICK";
EVENT_TYPE_TEXT[EVENT_INTERFACE_SOLUCE] = "EVENT_INTERFACE_SOLUCE";
EVENT_TYPE_TEXT[EVENT_INTERFACE_JOYSTICK_X]= "EVENT_INTERFACE_JOYSTICK_X";
EVENT_TYPE_TEXT[EVENT_INTERFACE_JOYSTICK_Y]= "EVENT_INTERFACE_JOYSTICK_Y";
EVENT_TYPE_TEXT[EVENT_INTERFACE_JOYSTICK_Z]= "EVENT_INTERFACE_JOYSTICK_Z";
EVENT_TYPE_TEXT[EVENT_INTERFACE_JOYSTICK_X_INVERT]= "EVENT_INTERFACE_JOYSTICK_X_INVERT";
EVENT_TYPE_TEXT[EVENT_INTERFACE_JOYSTICK_Y_INVERT]= "EVENT_INTERFACE_JOYSTICK_Y_INVERT";
EVENT_TYPE_TEXT[EVENT_INTERFACE_JOYSTICK_Z_INVERT]= "EVENT_INTERFACE_JOYSTICK_Z_INVERT";
EVENT_TYPE_TEXT[EVENT_INTERFACE_JOYSTICK_DEADZONE]= "EVENT_INTERFACE_JOYSTICK_DEADZONE";
EVENT_TYPE_TEXT[EVENT_INTERFACE_GLINTl] = "EVENT_INTERFACE_GLINTl";
EVENT_TYPE_TEXT[EVENT_INTERFACE_GLINTr] = "EVENT_INTERFACE_GLINTr";

View File

@ -278,6 +278,13 @@ enum EventType
EVENT_INTERFACE_JOYSTICK= 560,
EVENT_INTERFACE_SOLUCE = 561,
EVENT_INTERFACE_JOYSTICK_X = 562,
EVENT_INTERFACE_JOYSTICK_Y = 563,
EVENT_INTERFACE_JOYSTICK_Z = 564,
EVENT_INTERFACE_JOYSTICK_X_INVERT = 565,
EVENT_INTERFACE_JOYSTICK_Y_INVERT = 566,
EVENT_INTERFACE_JOYSTICK_Z_INVERT = 567,
EVENT_INTERFACE_JOYSTICK_DEADZONE = 568,
EVENT_INTERFACE_GLINTl = 570,
EVENT_INTERFACE_GLINTr = 571,

View File

@ -249,8 +249,10 @@ void InitializeRestext()
stringsEvent[EVENT_INTERFACE_SILENT] = TR("Mute\\No sound");
stringsEvent[EVENT_INTERFACE_NOISY] = TR("Normal\\Normal sound volume");
stringsEvent[EVENT_INTERFACE_JOYSTICK] = TR("Use a joystick\\Joystick or keyboard");
stringsEvent[EVENT_INTERFACE_SOLUCE] = TR("Access to solution\\Shows the solution (detailed instructions for missions)");
stringsEvent[EVENT_INTERFACE_JOYSTICK_X_INVERT] = TR("Invert\\Invert values on this axis");
stringsEvent[EVENT_INTERFACE_JOYSTICK_Y_INVERT] = TR("Invert\\Invert values on this axis");
stringsEvent[EVENT_INTERFACE_JOYSTICK_Z_INVERT] = TR("Invert\\Invert values on this axis");
stringsEvent[EVENT_INTERFACE_NEDIT] = TR("\\New player name");
stringsEvent[EVENT_INTERFACE_NOK] = TR("OK\\Choose the selected player");

View File

@ -89,7 +89,7 @@ void CSettings::SaveSettings()
GetConfigFile().SetBoolProperty("Setup", "ObjectDirty", engine->GetDirty());
GetConfigFile().SetBoolProperty("Setup", "FogMode", engine->GetFog());
GetConfigFile().SetBoolProperty("Setup", "LightMode", engine->GetLightMode());
GetConfigFile().SetIntProperty("Setup", "UseJoystick", app->GetJoystickEnabled() ? app->GetJoystick().index : -1);
GetConfigFile().SetIntProperty("Setup", "JoystickIndex", app->GetJoystickEnabled() ? app->GetJoystick().index : -1);
GetConfigFile().SetFloatProperty("Setup", "ParticleDensity", engine->GetParticleDensity());
GetConfigFile().SetFloatProperty("Setup", "ClippingDistance", engine->GetClippingDistance());
GetConfigFile().SetIntProperty("Setup", "AudioVolume", sound->GetAudioVolume());
@ -185,7 +185,7 @@ void CSettings::LoadSettings()
if (GetConfigFile().GetBoolProperty("Setup", "LightMode", bValue))
engine->SetLightMode(bValue);
if (GetConfigFile().GetIntProperty("Setup", "UseJoystick", iValue))
if (GetConfigFile().GetIntProperty("Setup", "JoystickIndex", iValue))
{
if (iValue >= 0)
{

View File

@ -896,6 +896,8 @@ void CEdit::Draw()
dim.y = m_dim.y;
DrawBack(pos, dim); // background
if ( (m_state & STATE_ENABLE) == 0 ) return;
// Displays all lines.
c1 = m_cursor1;
c2 = m_cursor2;

View File

@ -232,6 +232,7 @@ void CEditValue::Draw()
if (m_edit != nullptr)
{
m_edit->SetState(STATE_ENABLE, TestState(STATE_ENABLE));
m_edit->Draw();
}
if (m_buttonUp != nullptr)

View File

@ -129,7 +129,7 @@ void CKey::Draw()
return;
Math::Point iDim = m_dim;
m_dim.x = 200.0f/640.0f;
m_dim.x = 100.0f/640.0f;
if (m_state & STATE_SHADOW)
DrawShadow(m_pos, m_dim);
@ -192,7 +192,7 @@ void CKey::Draw()
return;
// Draws the name.
pos.x = m_pos.x + (214.0f / 640.0f);
pos.x = m_pos.x + (114.0f / 640.0f);
pos.y = m_pos.y + m_dim.y * 0.5f;
pos.y -= h;
m_engine->GetText()->DrawText(m_name, m_fontType, m_fontSize, pos, m_dim.x, Gfx::TEXT_ALIGN_LEFT, 0);

View File

@ -22,26 +22,26 @@
#include "app/app.h"
#include "common/settings.h"
#include "common/stringutils.h"
#include "graphics/engine/camera.h"
#include "ui/controls/button.h"
#include "ui/controls/check.h"
#include "ui/controls/editvalue.h"
#include "ui/controls/group.h"
#include "ui/controls/interface.h"
#include "ui/controls/key.h"
#include "ui/controls/label.h"
#include "ui/controls/list.h"
#include "ui/controls/scroll.h"
#include "ui/controls/window.h"
namespace Ui
{
const int KEY_VISIBLE = 6; // number of visible keys redefinable
const int KEY_VISIBLE = 8; // number of visible keys redefinable
CScreenSetupControls::CScreenSetupControls()
{
m_input = CInput::GetInstancePointer();
}
void CScreenSetupControls::SetActive()
@ -57,6 +57,8 @@ void CScreenSetupControls::CreateInterface()
CScroll* ps;
CButton* pb;
CGroup* pg;
CList* pli;
CEditValue* pev;
Math::Point pos, ddim;
std::string name;
@ -80,10 +82,10 @@ void CScreenSetupControls::CreateInterface()
pl = pw->CreateLabel(pos, ddim, 0, EVENT_INTERFACE_KINFO2, name);
pl->SetTextAlign(Gfx::TEXT_ALIGN_LEFT);
ddim.x = 428.0f/640.0f;
ddim.y = 128.0f/480.0f;
ddim.x = 273.0f/640.0f;
ddim.y = 168.0f/480.0f;
pos.x = 105.0f/640.0f;
pos.y = 164.0f/480.0f;
pos.y = 124.0f/480.0f;
pg = pw->CreateGroup(pos, ddim, 0, EVENT_INTERFACE_KGROUP);
pg->ClearState(STATE_ENABLE);
pg->SetState(STATE_DEAD);
@ -91,20 +93,88 @@ void CScreenSetupControls::CreateInterface()
ddim.x = 18.0f/640.0f;
ddim.y = (20.0f/480.0f)*KEY_VISIBLE;
pos.x = 510.0f/640.0f;
pos.y = 168.0f/480.0f;
pos.x = 355.0f/640.0f;
pos.y = 128.0f/480.0f;
ps = pw->CreateScroll(pos, ddim, -1, EVENT_INTERFACE_KSCROLL);
ps->SetVisibleRatio(static_cast<float>(KEY_VISIBLE/INPUT_SLOT_MAX));
ps->SetArrowStep(1.0f/(static_cast<float>(INPUT_SLOT_MAX-KEY_VISIBLE)));
UpdateKey();
ddim.x = dim.x*6;
ddim.y = dim.y*0.5f;
pos.x = ox+sx*3;
pos.y = 130.0f/480.0f;
pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_JOYSTICK);
ddim.x = 160.0f/640.0f;
ddim.y = 80.0f/480.0f;
pos.x = 400.0f/640.0f;
pos.y = 213.0f/480.0f;
pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_JOYSTICK);
pli->SetState(STATE_SHADOW);
ddim.x = dim.x*1.5f;
ddim.y = 18.0f/480.0f;
pos.y = 180.0f/480.0f;
pos.y -= 5.0f/480.0f;
pos.x = 390.0f/640.0f;
pw->CreateLabel(pos, ddim, 0, EVENT_LABEL0, "X:");
pos.y += 5.0f/480.0f;
pos.x = 422.0f/640.0f;
pev = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_JOYSTICK_X);
pev->SetState(STATE_SHADOW);
pev->SetType(EVT_INT);
pev->SetMinValue(0);
pev->SetMaxValue(2);
pev->SetStepValue(1);
pev->SetValue(0);
pos.x = 480.0f/640.0f;
pc = pw->CreateCheck(pos, ddim, 0, EVENT_INTERFACE_JOYSTICK_X_INVERT);
pc->SetState(STATE_SHADOW);
pos.y -= 20.0f/480.0f;
pos.x = 390.0f/640.0f;
pos.y -= 5.0f/480.0f;
pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, "Y:");
pos.y += 5.0f/480.0f;
pos.x = 422.0f/640.0f;
pev = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_JOYSTICK_Y);
pev->SetState(STATE_SHADOW);
pev->SetType(EVT_INT);
pev->SetMinValue(0);
pev->SetMaxValue(2);
pev->SetStepValue(1);
pev->SetValue(1);
pos.x = 480.0f/640.0f;
pc = pw->CreateCheck(pos, ddim, 0, EVENT_INTERFACE_JOYSTICK_Y_INVERT);
pc->SetState(STATE_SHADOW);
pos.y -= 20.0f/480.0f;
pos.x = 390.0f/640.0f;
pos.y -= 5.0f/480.0f;
pw->CreateLabel(pos, ddim, 0, EVENT_LABEL2, "Z:");
pos.y += 5.0f/480.0f;
pos.x = 422.0f/640.0f;
pev = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_JOYSTICK_Z);
pev->SetState(STATE_SHADOW);
pev->SetType(EVT_INT);
pev->SetMinValue(0);
pev->SetMaxValue(2);
pev->SetStepValue(1);
pev->SetValue(2);
pos.x = 480.0f/640.0f;
pc = pw->CreateCheck(pos, ddim, 0, EVENT_INTERFACE_JOYSTICK_Z_INVERT);
pc->SetState(STATE_SHADOW);
pos.y -= 25.0f/480.0f;
pos.x = 420.0f/640.0f;
pos.y -= 5.0f/480.0f;
pw->CreateLabel(pos, ddim, 0, EVENT_LABEL3, "Deadzone:");
pos.y += 5.0f/480.0f;
pos.x = 480.0f/640.0f;
ddim.x = dim.x*2.2f;
pev = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_JOYSTICK_DEADZONE);
pev->SetState(STATE_SHADOW);
pev->SetType(EVT_100);
pev->SetMinValue(0);
pev->SetMaxValue(1);
pev->SetStepValue(0.01);
ddim.x = dim.x*6;
ddim.y = dim.y*1;
pos.x = ox+sx*10;
@ -126,12 +196,24 @@ bool CScreenSetupControls::EventProcess(const Event &event)
break;
case EVENT_INTERFACE_KDEF:
CInput::GetInstancePointer()->SetDefaultInputBindings();
m_input->SetDefaultInputBindings();
UpdateKey();
break;
case EVENT_INTERFACE_JOYSTICK_X_INVERT:
case EVENT_INTERFACE_JOYSTICK_Y_INVERT:
case EVENT_INTERFACE_JOYSTICK_Z_INVERT:
ToggleJoystickInvert(event.type);
ChangeSetupButtons();
UpdateSetupButtons();
break;
case EVENT_INTERFACE_JOYSTICK:
m_app->SetJoystickEnabled(!m_app->GetJoystickEnabled());
case EVENT_INTERFACE_JOYSTICK_X:
case EVENT_INTERFACE_JOYSTICK_Y:
case EVENT_INTERFACE_JOYSTICK_Z:
case EVENT_INTERFACE_JOYSTICK_DEADZONE:
ChangeSetupButtons();
UpdateSetupButtons();
break;
@ -147,21 +229,145 @@ bool CScreenSetupControls::EventProcess(const Event &event)
return false;
}
// Updates the buttons during the setup phase.
void CScreenSetupControls::UpdateSetupButtons()
void CScreenSetupControls::ChangeSetupButtons()
{
CWindow* pw;
CList* pli;
CEditValue* pev;
CCheck* pc;
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
if ( pw == nullptr ) return;
pc = static_cast<CCheck*>(pw->SearchControl(EVENT_INTERFACE_JOYSTICK));
if ( pc != nullptr )
pli = static_cast<CList*>(pw->SearchControl(EVENT_INTERFACE_JOYSTICK));
if ( pli != nullptr )
{
if (pli->GetSelect() > 0)
{
m_app->ChangeJoystick(m_app->GetJoystickList()[pli->GetSelect()-1]);
m_app->SetJoystickEnabled(true);
}
else
{
m_app->SetJoystickEnabled(false);
}
}
if (nullptr != (pev = static_cast<CEditValue*>(pw->SearchControl(EVENT_INTERFACE_JOYSTICK_X))))
{
JoyAxisBinding binding = m_input->GetJoyAxisBinding(JOY_AXIS_SLOT_X);
binding.axis = static_cast<int>(round(pev->GetValue()));
m_input->SetJoyAxisBinding(JOY_AXIS_SLOT_X, binding);
}
if (nullptr != (pc = static_cast<CCheck*>(pw->SearchControl(EVENT_INTERFACE_JOYSTICK_X_INVERT))))
{
JoyAxisBinding binding = m_input->GetJoyAxisBinding(JOY_AXIS_SLOT_X);
binding.invert = pc->TestState(STATE_CHECK);
m_input->SetJoyAxisBinding(JOY_AXIS_SLOT_X, binding);
}
if (nullptr != (pev = static_cast<CEditValue*>(pw->SearchControl(EVENT_INTERFACE_JOYSTICK_Y))))
{
JoyAxisBinding binding = m_input->GetJoyAxisBinding(JOY_AXIS_SLOT_Y);
binding.axis = static_cast<int>(round(pev->GetValue()));
m_input->SetJoyAxisBinding(JOY_AXIS_SLOT_Y, binding);
}
if (nullptr != (pc = static_cast<CCheck*>(pw->SearchControl(EVENT_INTERFACE_JOYSTICK_Y_INVERT))))
{
JoyAxisBinding binding = m_input->GetJoyAxisBinding(JOY_AXIS_SLOT_Y);
binding.invert = pc->TestState(STATE_CHECK);
m_input->SetJoyAxisBinding(JOY_AXIS_SLOT_Y, binding);
}
if (nullptr != (pev = static_cast<CEditValue*>(pw->SearchControl(EVENT_INTERFACE_JOYSTICK_Z))))
{
JoyAxisBinding binding = m_input->GetJoyAxisBinding(JOY_AXIS_SLOT_Z);
binding.axis = static_cast<int>(round(pev->GetValue()));
m_input->SetJoyAxisBinding(JOY_AXIS_SLOT_Z, binding);
}
if (nullptr != (pc = static_cast<CCheck*>(pw->SearchControl(EVENT_INTERFACE_JOYSTICK_Z_INVERT))))
{
JoyAxisBinding binding = m_input->GetJoyAxisBinding(JOY_AXIS_SLOT_Z);
binding.invert = pc->TestState(STATE_CHECK);
m_input->SetJoyAxisBinding(JOY_AXIS_SLOT_Z, binding);
}
if (nullptr != (pev = static_cast<CEditValue*>(pw->SearchControl(EVENT_INTERFACE_JOYSTICK_DEADZONE))))
{
m_input->SetJoystickDeadzone(pev->GetValue());
}
}
void CScreenSetupControls::ToggleJoystickInvert(EventType type)
{
CWindow* pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
if (pw == nullptr) return;
CCheck* pc = static_cast<CCheck*>(pw->SearchControl(type));
if (pc == nullptr) return;
pc->SetState(STATE_CHECK, !pc->TestState(STATE_CHECK));
}
// Updates the buttons during the setup phase.
void CScreenSetupControls::UpdateSetupButtons()
{
CWindow* pw;
CList* pli;
CEditValue* pev;
CCheck* pc;
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
if (pw == nullptr) return;
pli = static_cast<CList*>(pw->SearchControl(EVENT_INTERFACE_JOYSTICK));
if (pli != nullptr)
{
pli->Flush();
pli->SetItemName(0, "[No joystick]");
auto joysticks = m_app->GetJoystickList();
for (unsigned int i = 0; i < joysticks.size(); i++)
{
pli->SetItemName(1 + i, joysticks[i].name.c_str());
}
pli->SetSelect(m_app->GetJoystick().index + 1);
}
if (nullptr != (pev = static_cast<CEditValue*>(pw->SearchControl(EVENT_INTERFACE_JOYSTICK_X))))
{
pev->SetState(STATE_ENABLE, m_app->GetJoystick().index >= 0);
pev->SetMaxValue(m_app->GetJoystick().axisCount-1);
pev->SetValue(m_input->GetJoyAxisBinding(JOY_AXIS_SLOT_X).axis);
}
if (nullptr != (pc = static_cast<CCheck*>(pw->SearchControl(EVENT_INTERFACE_JOYSTICK_X_INVERT))))
{
pc->SetState(STATE_ENABLE, m_app->GetJoystick().index >= 0);
pc->SetState(STATE_CHECK, m_app->GetJoystickEnabled());
pc->SetState(STATE_CHECK, m_input->GetJoyAxisBinding(JOY_AXIS_SLOT_X).invert);
}
if (nullptr != (pev = static_cast<CEditValue*>(pw->SearchControl(EVENT_INTERFACE_JOYSTICK_Y))))
{
pev->SetState(STATE_ENABLE, m_app->GetJoystick().index >= 0);
pev->SetMaxValue(m_app->GetJoystick().axisCount-1);
pev->SetValue(m_input->GetJoyAxisBinding(JOY_AXIS_SLOT_Y).axis);
}
if (nullptr != (pc = static_cast<CCheck*>(pw->SearchControl(EVENT_INTERFACE_JOYSTICK_Y_INVERT))))
{
pc->SetState(STATE_ENABLE, m_app->GetJoystick().index >= 0);
pc->SetState(STATE_CHECK, m_input->GetJoyAxisBinding(JOY_AXIS_SLOT_Y).invert);
}
if (nullptr != (pev = static_cast<CEditValue*>(pw->SearchControl(EVENT_INTERFACE_JOYSTICK_Z))))
{
pev->SetState(STATE_ENABLE, m_app->GetJoystick().index >= 0);
pev->SetMaxValue(m_app->GetJoystick().axisCount-1);
pev->SetValue(m_input->GetJoyAxisBinding(JOY_AXIS_SLOT_Z).axis);
}
if (nullptr != (pc = static_cast<CCheck*>(pw->SearchControl(EVENT_INTERFACE_JOYSTICK_Z_INVERT))))
{
pc->SetState(STATE_ENABLE, m_app->GetJoystick().index >= 0);
pc->SetState(STATE_CHECK, m_input->GetJoyAxisBinding(JOY_AXIS_SLOT_Z).invert);
}
if (nullptr != (pev = static_cast<CEditValue*>(pw->SearchControl(EVENT_INTERFACE_JOYSTICK_DEADZONE))))
{
pev->SetState(STATE_ENABLE, m_app->GetJoystick().index >= 0);
pev->SetValue(m_input->GetJoystickDeadzone());
}
}
@ -181,18 +387,18 @@ void CScreenSetupControls::UpdateKey()
pw->DeleteControl(static_cast<EventType>(EVENT_INTERFACE_KEY+i));
Math::Point dim;
dim.x = 400.0f/640.0f;
dim.x = 250.0f/640.0f;
dim.y = 20.0f/480.0f;
Math::Point pos;
pos.x = 110.0f/640.0f;
pos.y = 168.0f/480.0f + dim.y*(KEY_VISIBLE-1);
pos.y = 128.0f/480.0f + dim.y*(KEY_VISIBLE-1);
for (int i = 0; i < KEY_VISIBLE; i++)
{
pw->CreateKey(pos, dim, -1, static_cast<EventType>(EVENT_INTERFACE_KEY+first+i));
CKey* pk = static_cast<CKey*>(pw->SearchControl(static_cast<EventType>(EVENT_INTERFACE_KEY+first+i)));
if (pk == nullptr) break;
pk->SetBinding(CInput::GetInstancePointer()->GetInputBinding(static_cast<InputSlot>(first+i)));
pk->SetBinding(m_input->GetInputBinding(static_cast<InputSlot>(first+i)));
pos.y -= dim.y;
}
}
@ -214,7 +420,7 @@ void CScreenSetupControls::ChangeKey(EventType event)
CKey* pk = static_cast<CKey*>(pw->SearchControl(static_cast<EventType>(EVENT_INTERFACE_KEY+i)));
if (pk == nullptr) break;
CInput::GetInstancePointer()->SetInputBinding(static_cast<InputSlot>(i), pk->GetBinding());
m_input->SetInputBinding(static_cast<InputSlot>(i), pk->GetBinding());
}
}
}

View File

@ -21,6 +21,8 @@
#include "ui/screen/screen_setup.h"
class CInput;
namespace Ui
{
@ -34,9 +36,16 @@ public:
bool EventProcess(const Event &event) override;
protected:
void ChangeSetupButtons();
void UpdateSetupButtons();
void UpdateKey();
void ChangeKey(EventType event);
void UpdateKey();
void ToggleJoystickInvert(EventType type);
protected:
CInput* m_input;
};
} // namespace Ui