Initial incarnation of the new input configuration menu. More to come
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5349 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
68bc6a7e65
commit
1b3ea64041
Binary file not shown.
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 8.8 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 4.9 KiB |
@ -16,97 +16,21 @@
|
||||
|
||||
<box proportion="1" width="100%" layout="vertical-row">
|
||||
|
||||
<scrollable_ribbon id="devices" proportion="3" label_location="each" width="100%"
|
||||
square_items="false" align="center" child_width="256" child_height="128" />
|
||||
<spacer width="5" height="5"/>
|
||||
|
||||
<label width="100%"
|
||||
I18N="In key bindings configuration menu"
|
||||
text="Press enter or double-click on a device to configure it"
|
||||
text_align="center" />
|
||||
|
||||
<div width="85%" proportion="1" layout="horizontal-row" align="center">
|
||||
<label proportion="2" height="100%" I18N="Key binding" text="Accelerate" text_align="right"/>
|
||||
<spacer proportion="1" height="100%" />
|
||||
<button id="binding_up" proportion="3" height="100%"
|
||||
I18N="Unbound key binding" text="[none]"/>
|
||||
<spacer proportion="1" height="100%" />
|
||||
</div>
|
||||
<spacer height="5" width="10"/>
|
||||
<spacer width="5" height="20"/>
|
||||
<list id="devices" proportion="5" width="75%" align="center"/>
|
||||
<spacer width="50" height="25" />
|
||||
|
||||
|
||||
<div width="85%" proportion="1" layout="horizontal-row" align="center">
|
||||
<label proportion="2" height="100%" I18N="Key binding" text="Brake" text_align="right"/>
|
||||
<spacer proportion="1" height="100%" />
|
||||
<button id="binding_down" proportion="3" height="100%"
|
||||
I18N="Unbound key binding" text="[none]"/>
|
||||
<spacer proportion="1" height="100%" />
|
||||
</div>
|
||||
<spacer height="5" width="10"/>
|
||||
|
||||
<div width="85%" proportion="1" layout="horizontal-row" align="center">
|
||||
<label proportion="2" height="100%" I18N="Key binding" text="Left" text_align="right"/>
|
||||
<spacer proportion="1" height="100%" />
|
||||
<button id="binding_left" proportion="3" height="100%"
|
||||
I18N="Unbound key binding" text="[none]"/>
|
||||
<spacer proportion="1" height="100%" />
|
||||
</div>
|
||||
<spacer height="5" width="10"/>
|
||||
|
||||
<div width="85%" proportion="1" layout="horizontal-row" align="center">
|
||||
<label proportion="2" height="100%" I18N="Key binding" text="Right" text_align="right"/>
|
||||
<spacer proportion="1" height="100%" />
|
||||
<button id="binding_right" proportion="3" height="100%"
|
||||
I18N="Unbound key binding" text="[none]"/>
|
||||
<spacer proportion="1" height="100%" />
|
||||
</div>
|
||||
<spacer height="5" width="10"/>
|
||||
|
||||
<div width="85%" proportion="1" layout="horizontal-row" align="center">
|
||||
<label proportion="2" height="100%" I18N="Key binding" text="Fire" text_align="right"/>
|
||||
<spacer proportion="1" height="100%" />
|
||||
<button id="binding_fire" proportion="3" height="100%"
|
||||
I18N="Unbound key binding" text="[none]"/>
|
||||
<spacer proportion="1" height="100%" />
|
||||
</div>
|
||||
<spacer height="5" width="10"/>
|
||||
|
||||
<div width="85%" proportion="1" layout="horizontal-row" align="center" >
|
||||
<label proportion="2" height="100%" I18N="Key binding" text="Nitro" text_align="right"/>
|
||||
<spacer proportion="1" height="100%" />
|
||||
<button id="binding_nitro" proportion="3" height="100%"
|
||||
I18N="Unbound key binding" text="[none]"/>
|
||||
<spacer proportion="1" height="100%" />
|
||||
</div>
|
||||
<spacer height="5" width="10"/>
|
||||
|
||||
<div width="85%" proportion="1" layout="horizontal-row" align="center">
|
||||
<label proportion="2" height="100%" I18N="Key binding" text="Sharp Turn" text_align="right"/>
|
||||
<spacer proportion="1" height="100%" />
|
||||
<button id="binding_drift" proportion="3" height="100%"
|
||||
I18N="Unbound key binding" text="[none]"/>
|
||||
<spacer proportion="1" height="100%" />
|
||||
</div>
|
||||
<spacer height="5" width="10"/>
|
||||
|
||||
<div width="85%" proportion="1" layout="horizontal-row" align="center">
|
||||
<label proportion="2" height="100%" I18N="Key binding" text="Rescue" text_align="right"/>
|
||||
<spacer proportion="1" height="100%" />
|
||||
<button id="binding_rescue" proportion="3" height="100%"
|
||||
I18N="Unbound key binding" text="[none]"/>
|
||||
<spacer proportion="1" height="100%" />
|
||||
</div>
|
||||
<spacer height="5" width="10"/>
|
||||
|
||||
<div width="85%" proportion="1" layout="horizontal-row" align="center">
|
||||
<label proportion="2" height="100%" I18N="Key binding" text="Look Back" text_align="right"/>
|
||||
<spacer proportion="1" height="100%" />
|
||||
<button id="binding_look_back" proportion="3" height="100%"
|
||||
I18N="Unbound key binding" text="[none]"/>
|
||||
<spacer proportion="1" height="100%" />
|
||||
</div>
|
||||
|
||||
<spacer width="50" height="10" />
|
||||
|
||||
<button id="add_device" proportion="1" I18N="In the input configuration screen" text="Add a device"/>
|
||||
<button id="add_device" I18N="In the input configuration screen" text="Add a device"/>
|
||||
|
||||
<label text="* Which config to use will be inferred from which 'fire' key is pressed to join the game."
|
||||
proportion="3" word_wrap="true"/>
|
||||
proportion="2" word_wrap="true"/>
|
||||
</box>
|
||||
|
||||
<spacer width="50" height="40" />
|
||||
|
@ -296,6 +296,8 @@ supertuxkart_SOURCES = \
|
||||
states_screens/options_screen_av.hpp \
|
||||
states_screens/options_screen_input.cpp \
|
||||
states_screens/options_screen_input.hpp \
|
||||
states_screens/options_screen_input2.cpp \
|
||||
states_screens/options_screen_input2.hpp \
|
||||
states_screens/options_screen_players.cpp \
|
||||
states_screens/options_screen_players.hpp \
|
||||
states_screens/race_gui.cpp \
|
||||
|
@ -199,10 +199,10 @@ void KeyboardConfig::setDefaultBinds()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
KeyboardConfig::KeyboardConfig()
|
||||
KeyboardConfig::KeyboardConfig() : DeviceConfig(DEVICE_CONFIG_TYPE_KEYBOARD)
|
||||
{
|
||||
m_name = "Keyboard";
|
||||
setInUse(true);
|
||||
setPlugged(true);
|
||||
setDefaultBinds();
|
||||
}
|
||||
|
||||
@ -234,18 +234,18 @@ void GamepadConfig::setDefaultBinds ()
|
||||
|
||||
GamepadConfig::GamepadConfig ( const std::string name,
|
||||
const int axis_count,
|
||||
const int btnCount )
|
||||
const int btnCount ) : DeviceConfig( DEVICE_CONFIG_TYPE_GAMEPAD )
|
||||
{
|
||||
m_name = name;
|
||||
m_axis_count = axis_count;
|
||||
m_button_count = btnCount;
|
||||
setInUse(false);
|
||||
setPlugged(false);
|
||||
setDefaultBinds();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
GamepadConfig::GamepadConfig(irr::io::IrrXMLReader* xml)
|
||||
GamepadConfig::GamepadConfig(irr::io::IrrXMLReader* xml) : DeviceConfig( DEVICE_CONFIG_TYPE_GAMEPAD )
|
||||
{
|
||||
const char* name_string = xml->getAttributeValue("name");
|
||||
if(name_string == NULL)
|
||||
@ -256,7 +256,7 @@ GamepadConfig::GamepadConfig(irr::io::IrrXMLReader* xml)
|
||||
{
|
||||
m_name = name_string;
|
||||
}
|
||||
setInUse(false);
|
||||
setPlugged(false);
|
||||
setDefaultBinds();
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,12 @@ struct KeyBinding
|
||||
|
||||
};
|
||||
|
||||
enum DeviceConfigType
|
||||
{
|
||||
DEVICE_CONFIG_TYPE_GAMEPAD,
|
||||
DEVICE_CONFIG_TYPE_KEYBOARD
|
||||
};
|
||||
|
||||
|
||||
//==== D E V I C E C O N F I G =================================================
|
||||
|
||||
@ -32,17 +38,25 @@ class DeviceConfig
|
||||
private:
|
||||
|
||||
KeyBinding m_bindings[PA_COUNT];
|
||||
bool m_inuse; //!< Is there a device connected to the system which uses this config?
|
||||
bool m_plugged; //!< Is there a device connected to the system which uses this config?
|
||||
|
||||
protected:
|
||||
|
||||
std::string m_name;
|
||||
|
||||
DeviceConfigType m_type;
|
||||
|
||||
DeviceConfig(DeviceConfigType type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
std::string getName() const { return m_name; };
|
||||
irr::core::stringw getBindingAsString (const PlayerAction action) const;
|
||||
std::string getName () const { return m_name; };
|
||||
irr::core::stringw toString ();
|
||||
DeviceConfigType getType () const { return m_type; }
|
||||
irr::core::stringw getBindingAsString(const PlayerAction action) const;
|
||||
|
||||
void serialize (std::ofstream& stream);
|
||||
bool deserializeAction (irr::io::IrrXMLReader* xml);
|
||||
@ -52,8 +66,8 @@ public:
|
||||
const int id,
|
||||
Input::AxisDirection direction = Input::AD_NEUTRAL);
|
||||
|
||||
void setInUse (bool inuse) {m_inuse = inuse;}
|
||||
bool isInUse () {return m_inuse;}
|
||||
void setPlugged (bool plugged) {m_plugged = plugged;}
|
||||
bool isPlugged () {return m_plugged;}
|
||||
|
||||
/**
|
||||
* Don't call this directly unless you are KeyboardDevice or GamepadDevice
|
||||
|
@ -43,7 +43,7 @@ namespace GUIEngine
|
||||
|
||||
/** When inferring widget size from its label length, this method will be called to
|
||||
* if/how much space must be added to the raw label's size for the widget to be large enough */
|
||||
virtual int getHeightNeededAroundLabel() const { return 16; }
|
||||
virtual int getHeightNeededAroundLabel() const { return 8; }
|
||||
|
||||
public:
|
||||
ButtonWidget();
|
||||
|
@ -62,6 +62,8 @@ namespace GUIEngine
|
||||
* A dynamic ribbon builds upon RibbonWidget, adding dynamic contents creation and sizing,
|
||||
* scrolling, multiple-row layouts.
|
||||
* \ingroup widgets
|
||||
* \note items you add to a list are kept after the the ribbon was in is removed
|
||||
* (i.e. you don't need to add items everytime the screen is shown, only upon loading)
|
||||
*/
|
||||
class DynamicRibbonWidget : public Widget, public RibbonWidget::IRibbonListener
|
||||
{
|
||||
|
@ -31,7 +31,40 @@ using namespace irr::gui;
|
||||
|
||||
ListWidget::ListWidget() : Widget(WTYPE_LIST)
|
||||
{
|
||||
m_use_icons = false; //TODO: make configurable if needed
|
||||
m_use_icons = false;
|
||||
m_icons = NULL;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ListWidget::setIcons(STKModifiedSpriteBank* icons)
|
||||
{
|
||||
m_use_icons = (icons != NULL);
|
||||
m_icons = icons;
|
||||
|
||||
if (m_use_icons)
|
||||
{
|
||||
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
|
||||
assert(list != NULL);
|
||||
|
||||
list->setSpriteBank(m_icons);
|
||||
|
||||
// determine needed height
|
||||
int item_height = 0;
|
||||
const core::array< core::rect<s32> >& rects = m_icons->getPositions();
|
||||
const int count = rects.size();
|
||||
for (int n=0; n<count; n++)
|
||||
{
|
||||
const int h = rects[n].getHeight();
|
||||
if (h > item_height) item_height = h;
|
||||
}
|
||||
|
||||
if (item_height > 0)
|
||||
{
|
||||
list->setItemHeight( item_height );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -43,19 +76,6 @@ void ListWidget::add()
|
||||
IGUIListBox* list = GUIEngine::getGUIEnv()->addListBox (widget_size, m_parent, getNewID());
|
||||
list->setAutoScrollEnabled(false);
|
||||
|
||||
if (m_use_icons)
|
||||
{
|
||||
//TODO: allow choosing which icons to use
|
||||
video::ITexture* icon = irr_driver->getTexture( file_manager->getGUIDir() + "/difficulty_medium.png" );
|
||||
|
||||
// TODO: delete the bank when done using, it currently leaks
|
||||
STKModifiedSpriteBank* bank = new STKModifiedSpriteBank( GUIEngine::getGUIEnv() );
|
||||
bank->setScale(0.5f);
|
||||
bank->addTextureAsSprite(icon);
|
||||
list->setSpriteBank(bank);
|
||||
list->setItemHeight( icon->getSize().Height*0.5f );
|
||||
}
|
||||
|
||||
m_element = list;
|
||||
}
|
||||
|
||||
@ -67,35 +87,52 @@ void ListWidget::clear()
|
||||
assert(list != NULL);
|
||||
|
||||
list->clear();
|
||||
m_internal_names.clear();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ListWidget::addItem(const char* item)
|
||||
void ListWidget::addItem(const stringw item, const int icon)
|
||||
{
|
||||
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
|
||||
assert(list != NULL);
|
||||
|
||||
if (m_use_icons)
|
||||
if (m_use_icons && icon != -1)
|
||||
{
|
||||
//TODO: allow choosing which icon to use
|
||||
u32 newItem = list->addItem( stringw(item).c_str(), 0 /* icon */ );
|
||||
u32 newItem = list->addItem( item.c_str(), icon );
|
||||
list->setItemOverrideColor( newItem, gui::EGUI_LBC_ICON, video::SColor(255,255,255,255) );
|
||||
list->setItemOverrideColor( newItem, gui::EGUI_LBC_ICON_HIGHLIGHT, video::SColor(255,255,255,255) );
|
||||
}
|
||||
else
|
||||
{
|
||||
list->addItem( stringw(item).c_str() );
|
||||
list->addItem( item.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
std::string ListWidget::getSelectionName() const
|
||||
void ListWidget::addItem(const std::string internalName, const irr::core::stringw item, const int icon)
|
||||
{
|
||||
m_internal_names[item] = internalName;
|
||||
addItem(item, icon);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
std::string ListWidget::getSelectionInternalName()
|
||||
{
|
||||
const IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
|
||||
assert(list != NULL);
|
||||
return stringc( list->getListItem( list->getSelected() ) ).c_str();
|
||||
return m_internal_names[ list->getListItem( list->getSelected() ) ];
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
irr::core::stringw ListWidget::getSelectionLabel() const
|
||||
{
|
||||
const IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
|
||||
assert(list != NULL);
|
||||
return list->getListItem( list->getSelected() );
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -25,15 +25,25 @@
|
||||
#include "guiengine/widget.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
|
||||
namespace irr { namespace gui { class STKModifiedSpriteBank; } }
|
||||
|
||||
namespace GUIEngine
|
||||
{
|
||||
/** \brief A vertical list widget with text entries
|
||||
* \ingroup widgets
|
||||
* \note items you add to a list are not kept after the the list is in was removed
|
||||
* (i.e. you need to add items everytime the screen is shown)
|
||||
*/
|
||||
class ListWidget : public Widget
|
||||
{
|
||||
/** \brief whether this list has icons */
|
||||
bool m_use_icons;
|
||||
|
||||
/** \brief if m_use_icons is true, this will contain the icon bank */
|
||||
irr::gui::STKModifiedSpriteBank* m_icons;
|
||||
|
||||
std::map< irr::core::stringw /*label*/, std::string /* internal name */> m_internal_names;
|
||||
|
||||
public:
|
||||
ListWidget();
|
||||
|
||||
@ -45,26 +55,63 @@ namespace GUIEngine
|
||||
/** \brief implement callback from base class GUIEngine::Widget */
|
||||
virtual void unfocused(const int playerID);
|
||||
|
||||
/** \brief set the icon bank to use for list entries.
|
||||
* The height of list entries will be ajusted to the size of the highest icon.
|
||||
* Icons must therefore be at least as high as text.
|
||||
* \note the list widget does NOT take ownership of the bank, dso you must delete it when
|
||||
* you're done with it (but do not delete it when the list widget is still active)
|
||||
* \precondition may only be called after the widget has been added to the screen with add()
|
||||
*/
|
||||
void setIcons(irr::gui::STKModifiedSpriteBank* icons);
|
||||
|
||||
// ---- contents management
|
||||
|
||||
/** \brief add an item to the list */
|
||||
void addItem(const char* item);
|
||||
/**
|
||||
* \brief add an item to the list
|
||||
* \param item name of the item
|
||||
* \param icon ID of the icon within the icon bank. Only used if an icon bank was passed.
|
||||
* \precondition may only be called after the widget has been added to the screen with add()
|
||||
*/
|
||||
void addItem(const irr::core::stringw item, const int icon=-1);
|
||||
|
||||
/** \brief erases all items in the list */
|
||||
/**
|
||||
* \brief add an item to the list
|
||||
* \param item name of the item
|
||||
* \param icon ID of the icon within the icon bank. Only used if an icon bank was passed.
|
||||
* \precondition may only be called after the widget has been added to the screen with add()
|
||||
*/
|
||||
void addItem(const std::string internalName, const irr::core::stringw item, const int icon=-1);
|
||||
|
||||
/**
|
||||
* \brief erases all items in the list
|
||||
* \precondition may only be called after the widget has been added to the screen with add()
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/** \return the number of items in the list */
|
||||
/**
|
||||
* \return the number of items in the list
|
||||
* \precondition may only be called after the widget has been added to the screen with add()
|
||||
*/
|
||||
int getItemCount() const;
|
||||
|
||||
/** \return the index of the selected element within the list, or -1 if none */
|
||||
/**
|
||||
* \return the index of the selected element within the list, or -1 if none
|
||||
* \precondition may only be called after the widget has been added to the screen with add()
|
||||
*/
|
||||
int getSelectionID() const;
|
||||
|
||||
/** \return the text of the selected item */
|
||||
std::string getSelectionName() const;
|
||||
/**
|
||||
* \return the text of the selected item
|
||||
* \precondition may only be called after the widget has been added to the screen with add()
|
||||
*/
|
||||
std::string getSelectionInternalName();
|
||||
|
||||
irr::core::stringw getSelectionLabel() const;
|
||||
|
||||
/**
|
||||
* \brief change the selected item
|
||||
* \param index the index of the element to select within the list, or -1 to select nothing
|
||||
* \precondition may only be called after the widget has been added to the screen with add()
|
||||
*/
|
||||
void setSelectionID(const int index);
|
||||
};
|
||||
|
@ -39,6 +39,8 @@ namespace GUIEngine
|
||||
/** \brief A static text/icons/tabs bar widget.
|
||||
* The contents of this ribbon are static.
|
||||
* \ingroup widgets
|
||||
* \note items you add to a list are kept after the the ribbon was in is removed
|
||||
* (i.e. you don't need to add items everytime the screen is shown, only upon loading)
|
||||
*/
|
||||
class RibbonWidget : public Widget
|
||||
{
|
||||
|
@ -12,6 +12,7 @@
|
||||
9507E9D20FC1CDCE00BD2B92 /* OpenAL.framework in Copy frameworks */ = {isa = PBXBuildFile; fileRef = 9551C7FA0FC1B63C00DB481B /* OpenAL.framework */; };
|
||||
9507E9DB0FC1CDD500BD2B92 /* Vorbis.framework in Copy frameworks */ = {isa = PBXBuildFile; fileRef = 9551C7FB0FC1B63C00DB481B /* Vorbis.framework */; };
|
||||
950D448C118DEE3C006CFC41 /* CGUISpriteBank.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 950D448A118DEE3C006CFC41 /* CGUISpriteBank.cpp */; };
|
||||
950D45D1118E040E006CFC41 /* options_screen_input2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 950D45CF118E040E006CFC41 /* options_screen_input2.cpp */; };
|
||||
951B7D19108E52C900BC03AE /* challenges.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 951B7D18108E52C900BC03AE /* challenges.cpp */; };
|
||||
951BC65E0FFAF290006B5FF1 /* ipo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 951BC65C0FFAF290006B5FF1 /* ipo.cpp */; };
|
||||
9522F125107948AD0067ECF5 /* main_menu_screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9522F124107948AD0067ECF5 /* main_menu_screen.cpp */; };
|
||||
@ -309,6 +310,8 @@
|
||||
9507E9B60FC1CCE900BD2B92 /* stk.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = stk.icns; sourceTree = SOURCE_ROOT; };
|
||||
950D448A118DEE3C006CFC41 /* CGUISpriteBank.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGUISpriteBank.cpp; path = ../../guiengine/CGUISpriteBank.cpp; sourceTree = SOURCE_ROOT; };
|
||||
950D448B118DEE3C006CFC41 /* CGUISpriteBank.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CGUISpriteBank.h; path = ../../guiengine/CGUISpriteBank.h; sourceTree = SOURCE_ROOT; };
|
||||
950D45CF118E040E006CFC41 /* options_screen_input2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = options_screen_input2.cpp; path = ../../states_screens/options_screen_input2.cpp; sourceTree = SOURCE_ROOT; };
|
||||
950D45D0118E040E006CFC41 /* options_screen_input2.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = options_screen_input2.hpp; path = ../../states_screens/options_screen_input2.hpp; sourceTree = SOURCE_ROOT; };
|
||||
951B7D17108E52C900BC03AE /* challenges.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = challenges.hpp; path = ../../states_screens/challenges.hpp; sourceTree = SOURCE_ROOT; };
|
||||
951B7D18108E52C900BC03AE /* challenges.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = challenges.cpp; path = ../../states_screens/challenges.cpp; sourceTree = SOURCE_ROOT; };
|
||||
951BC65C0FFAF290006B5FF1 /* ipo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ipo.cpp; path = ../../animations/ipo.cpp; sourceTree = SOURCE_ROOT; };
|
||||
@ -1275,6 +1278,8 @@
|
||||
9522F1EA107961560067ECF5 /* options_screen_av.hpp */,
|
||||
9522F1EB107961560067ECF5 /* options_screen_input.cpp */,
|
||||
9522F1EE107961560067ECF5 /* options_screen_input.hpp */,
|
||||
950D45CF118E040E006CFC41 /* options_screen_input2.cpp */,
|
||||
950D45D0118E040E006CFC41 /* options_screen_input2.hpp */,
|
||||
9522F1ED107961560067ECF5 /* options_screen_players.cpp */,
|
||||
9522F1EC107961560067ECF5 /* options_screen_players.hpp */,
|
||||
958330C810122B4A00C5137E /* race_gui.cpp */,
|
||||
@ -2537,6 +2542,7 @@
|
||||
958BD770117F6AE90095B483 /* music_manager.cpp in Sources */,
|
||||
95453ACA11808B8700A155B9 /* emergency_animation.cpp in Sources */,
|
||||
950D448C118DEE3C006CFC41 /* CGUISpriteBank.cpp in Sources */,
|
||||
950D45D1118E040E006CFC41 /* options_screen_input2.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -88,7 +88,7 @@ bool DeviceManager::initialize()
|
||||
printf("using existing configuration.\n");
|
||||
}
|
||||
|
||||
gamepadConfig->setInUse(true);
|
||||
gamepadConfig->setPlugged(true);
|
||||
gamepadDevice = new GamePadDevice( id,
|
||||
m_irrlicht_gamepads[id].Name.c_str(),
|
||||
m_irrlicht_gamepads[id].Axes,
|
||||
|
@ -43,7 +43,7 @@
|
||||
#include "race/history.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
#include "states_screens/kart_selection.hpp"
|
||||
#include "states_screens/options_screen_input.hpp"
|
||||
#include "states_screens/options_screen_input2.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
InputManager *input_manager;
|
||||
@ -214,7 +214,7 @@ void InputManager::inputSensing(Input::InputType type, int deviceID, int btnID,
|
||||
|
||||
if (type == Input::IT_KEYBOARD)
|
||||
{
|
||||
OptionsScreenInput::getInstance()->gotSensedInput(m_sensed_input);
|
||||
OptionsScreenInput2::getInstance()->gotSensedInput(m_sensed_input);
|
||||
return;
|
||||
}
|
||||
else if (type == Input::IT_STICKMOTION)
|
||||
@ -230,7 +230,7 @@ void InputManager::inputSensing(Input::InputType type, int deviceID, int btnID,
|
||||
|
||||
if (abs(value) > Input::MAX_VALUE/2.0f)
|
||||
{
|
||||
OptionsScreenInput::getInstance()->gotSensedInput(m_sensed_input);
|
||||
OptionsScreenInput2::getInstance()->gotSensedInput(m_sensed_input);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -249,12 +249,12 @@ void InputManager::inputSensing(Input::InputType type, int deviceID, int btnID,
|
||||
}
|
||||
else if ( abs(value) < Input::MAX_VALUE/8.0f && id_has_high_value )
|
||||
{
|
||||
OptionsScreenInput::getInstance()->gotSensedInput(m_sensed_input);
|
||||
OptionsScreenInput2::getInstance()->gotSensedInput(m_sensed_input);
|
||||
}
|
||||
else if ( abs(value) < Input::MAX_VALUE/8.0f && inverse_id_has_high_value )
|
||||
{
|
||||
m_sensed_input->axisDirection = (axisDirection?0:-1);
|
||||
OptionsScreenInput::getInstance()->gotSensedInput(m_sensed_input);
|
||||
OptionsScreenInput2::getInstance()->gotSensedInput(m_sensed_input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,19 +16,21 @@
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "states_screens/options_screen_input.hpp"
|
||||
#include "states_screens/options_screen_input2.hpp"
|
||||
#include "states_screens/options_screen_av.hpp"
|
||||
#include "states_screens/options_screen_players.hpp"
|
||||
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "guiengine/CGUISpriteBank.h"
|
||||
#include "guiengine/screen.hpp"
|
||||
#include "guiengine/widget.hpp"
|
||||
#include "guiengine/widgets/button_widget.hpp"
|
||||
#include "guiengine/widgets/dynamic_ribbon_widget.hpp"
|
||||
#include "guiengine/widgets/list_widget.hpp"
|
||||
#include "guiengine/widgets/ribbon_widget.hpp"
|
||||
#include "input/input_manager.hpp"
|
||||
#include "input/device_manager.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "states_screens/dialogs/add_device_dialog.hpp"
|
||||
#include "states_screens/dialogs/press_a_key_dialog.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
@ -45,198 +47,35 @@ DEFINE_SCREEN_SINGLETON( OptionsScreenInput );
|
||||
|
||||
OptionsScreenInput::OptionsScreenInput() : Screen("options_input.stkgui")
|
||||
{
|
||||
m_inited = false;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput::loadedFromFile()
|
||||
{
|
||||
m_inited = false;
|
||||
}
|
||||
video::ITexture* icon1 = irr_driver->getTexture( file_manager->getGUIDir() + "/keyboard.png" );
|
||||
video::ITexture* icon2 = irr_driver->getTexture( file_manager->getGUIDir() + "/gamepad.png" );
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput::updateInputButtons(DeviceConfig* config)
|
||||
{
|
||||
|
||||
// Should never happen
|
||||
if (config == NULL)
|
||||
{
|
||||
printf("ERROR: No configuration associated with device?\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
// to detect duplicate entries
|
||||
std::set<core::stringw> existing_bindings;
|
||||
|
||||
{
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_up");
|
||||
core::stringw binding_name = config->getBindingAsString(PA_ACCEL);
|
||||
btn->setLabel( binding_name );
|
||||
|
||||
// check if another binding already uses this key
|
||||
if (existing_bindings.find(binding_name) != existing_bindings.end())
|
||||
{
|
||||
btn->setBadge(BAD_BADGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_bindings.insert(binding_name);
|
||||
btn->resetAllBadges();
|
||||
}
|
||||
}
|
||||
{
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_down");
|
||||
core::stringw binding_name = config->getBindingAsString(PA_BRAKE);
|
||||
btn->setLabel( binding_name );
|
||||
|
||||
// check if another binding already uses this key
|
||||
if (existing_bindings.find(binding_name) != existing_bindings.end())
|
||||
{
|
||||
btn->setBadge(BAD_BADGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_bindings.insert(binding_name);
|
||||
btn->resetAllBadges();
|
||||
}
|
||||
}
|
||||
{
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_left");
|
||||
core::stringw binding_name = config->getBindingAsString(PA_LEFT);
|
||||
btn->setLabel( binding_name );
|
||||
|
||||
// check if another binding already uses this key
|
||||
if (existing_bindings.find(binding_name) != existing_bindings.end())
|
||||
{
|
||||
btn->setBadge(BAD_BADGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_bindings.insert(binding_name);
|
||||
btn->resetAllBadges();
|
||||
}
|
||||
}
|
||||
{
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_right");
|
||||
core::stringw binding_name = config->getBindingAsString(PA_RIGHT);
|
||||
btn->setLabel( binding_name );
|
||||
|
||||
// check if another binding already uses this key
|
||||
if (existing_bindings.find(binding_name) != existing_bindings.end())
|
||||
{
|
||||
btn->setBadge(BAD_BADGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_bindings.insert(binding_name);
|
||||
btn->resetAllBadges();
|
||||
}
|
||||
}
|
||||
|
||||
std::set<core::stringw>::iterator it;
|
||||
|
||||
/*
|
||||
std::cout << "existing_bindings contains:";
|
||||
for ( it=existing_bindings.begin() ; it != existing_bindings.end(); it++ )
|
||||
{
|
||||
std::wcout << (*it).c_str() << ", ";
|
||||
}
|
||||
std::cout << "\n";
|
||||
*/
|
||||
|
||||
{
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_fire");
|
||||
core::stringw binding_name = config->getBindingAsString(PA_FIRE);
|
||||
btn->setLabel( binding_name );
|
||||
|
||||
// check if another binding already uses this key
|
||||
if (existing_bindings.find(binding_name) != existing_bindings.end())
|
||||
{
|
||||
btn->setBadge(BAD_BADGE);
|
||||
//std::cout << "Setting bad badge!!!!\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_bindings.insert(binding_name);
|
||||
btn->resetAllBadges();
|
||||
}
|
||||
}
|
||||
{
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_nitro");
|
||||
core::stringw binding_name = config->getBindingAsString(PA_NITRO);
|
||||
btn->setLabel( binding_name );
|
||||
|
||||
// check if another binding already uses this key
|
||||
if (existing_bindings.find(binding_name) != existing_bindings.end())
|
||||
{
|
||||
btn->setBadge(BAD_BADGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_bindings.insert(binding_name);
|
||||
btn->resetAllBadges();
|
||||
}
|
||||
}
|
||||
{
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_drift");
|
||||
core::stringw binding_name = config->getBindingAsString(PA_DRIFT);
|
||||
btn->setLabel( binding_name );
|
||||
|
||||
// check if another binding already uses this key
|
||||
if (existing_bindings.find(binding_name) != existing_bindings.end())
|
||||
{
|
||||
btn->setBadge(BAD_BADGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_bindings.insert(binding_name);
|
||||
btn->resetAllBadges();
|
||||
}
|
||||
}
|
||||
{
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_rescue");
|
||||
core::stringw binding_name = config->getBindingAsString(PA_RESCUE);
|
||||
btn->setLabel( binding_name );
|
||||
|
||||
// check if another binding already uses this key
|
||||
if (existing_bindings.find(binding_name) != existing_bindings.end())
|
||||
{
|
||||
btn->setBadge(BAD_BADGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_bindings.insert(binding_name);
|
||||
btn->resetAllBadges();
|
||||
}
|
||||
}
|
||||
{
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_look_back");
|
||||
core::stringw binding_name = config->getBindingAsString(PA_LOOK_BACK);
|
||||
btn->setLabel( binding_name );
|
||||
|
||||
// check if another binding already uses this key
|
||||
if (existing_bindings.find(binding_name) != existing_bindings.end())
|
||||
{
|
||||
btn->setBadge(BAD_BADGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_bindings.insert(binding_name);
|
||||
btn->resetAllBadges();
|
||||
}
|
||||
}
|
||||
m_icon_bank = new irr::gui::STKModifiedSpriteBank( GUIEngine::getGUIEnv() );
|
||||
m_icon_bank->addTextureAsSprite(icon1);
|
||||
m_icon_bank->addTextureAsSprite(icon2);
|
||||
|
||||
// scale icons depending on screen resolution. the numbers below are a bit arbitrary
|
||||
const int screen_width = irr_driver->getFrameSize().Width;
|
||||
const float scale = 0.3f + 0.2f*std::max(0, screen_width - 640)/564.0f;
|
||||
m_icon_bank->setScale(scale);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput::buildDeviceList()
|
||||
{
|
||||
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
|
||||
GUIEngine::ListWidget* devices = this->getWidget<GUIEngine::ListWidget>("devices");
|
||||
assert( devices != NULL );
|
||||
|
||||
assert( m_icon_bank != NULL );
|
||||
devices->setIcons(m_icon_bank);
|
||||
|
||||
const int keyboard_config_count = input_manager->getDeviceList()->getKeyboardConfigAmount();
|
||||
|
||||
for (int i=0; i<keyboard_config_count; i++)
|
||||
@ -247,8 +86,9 @@ void OptionsScreenInput::buildDeviceList()
|
||||
kbname << "keyboard" << i;
|
||||
const std::string internal_name = kbname.str();
|
||||
|
||||
|
||||
devices->addItem(StringUtils::insertValues(_("Keyboard %i"), i), internal_name, "/gui/keyboard.png");
|
||||
//FIXME: I18N: since irrLicht's list widget has the nasty tendency to put the
|
||||
// icons very close to the text, I'm adding spaces to compensate...
|
||||
devices->addItem(internal_name, StringUtils::insertValues(_(" Keyboard %i"), i), 0 /* icon */);
|
||||
}
|
||||
|
||||
const int gpad_config_count = input_manager->getDeviceList()->getGamePadConfigAmount();
|
||||
@ -256,16 +96,19 @@ void OptionsScreenInput::buildDeviceList()
|
||||
for (int i = 0; i < gpad_config_count; i++)
|
||||
{
|
||||
GamepadConfig *config = input_manager->getDeviceList()->getGamepadConfig(i);
|
||||
|
||||
// Don't display the configuration if a matching device is not available
|
||||
if (config->isInUse())
|
||||
if (config->isPlugged())
|
||||
{
|
||||
const irr::core::stringw name = config->getName().c_str();
|
||||
//FIXME: since irrLicht's list widget has the nasty tendency to put the
|
||||
// icons very close to the text, I'm adding spaces to compensate...
|
||||
const irr::core::stringw name = irr::core::stringw(" ") + config->getName().c_str();
|
||||
|
||||
std::ostringstream gpname;
|
||||
gpname << "gamepad" << i;
|
||||
const std::string internal_name = gpname.str();
|
||||
|
||||
devices->addItem(name, internal_name, "/gui/gamepad.png");
|
||||
devices->addItem(internal_name, name, 1 /* icon */);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -276,124 +119,44 @@ void OptionsScreenInput::init()
|
||||
RibbonWidget* tabBar = this->getWidget<RibbonWidget>("options_choice");
|
||||
if (tabBar != NULL) tabBar->select( "tab_controls", PLAYER_ID_GAME_MASTER );
|
||||
|
||||
|
||||
/*
|
||||
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
|
||||
assert( devices != NULL );
|
||||
*/
|
||||
|
||||
|
||||
if (!m_inited)
|
||||
{
|
||||
buildDeviceList();
|
||||
m_inited = true;
|
||||
}
|
||||
devices->updateItemDisplay();
|
||||
|
||||
//devices->updateItemDisplay();
|
||||
|
||||
/*
|
||||
// trigger displaying bindings for default selected device
|
||||
const std::string name2("devices");
|
||||
eventCallback(devices, name2, PLAYER_ID_GAME_MASTER);
|
||||
*/
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput::rebuildDeviceList()
|
||||
{
|
||||
/*
|
||||
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
|
||||
assert( devices != NULL );
|
||||
|
||||
devices->clearItems();
|
||||
buildDeviceList();
|
||||
devices->updateItemDisplay();
|
||||
}
|
||||
*/
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static PlayerAction binding_to_set;
|
||||
static std::string binding_to_set_button;
|
||||
|
||||
void OptionsScreenInput::gotSensedInput(Input* sensedInput)
|
||||
{
|
||||
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
|
||||
ListWidget* devices = this->getWidget<ListWidget>("devices");
|
||||
assert( devices != NULL );
|
||||
|
||||
std::string deviceID = devices->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
const bool keyboard = sensedInput->type == Input::IT_KEYBOARD && deviceID.find("keyboard") != std::string::npos;
|
||||
const bool gamepad = (sensedInput->type == Input::IT_STICKMOTION ||
|
||||
sensedInput->type == Input::IT_STICKBUTTON) &&
|
||||
deviceID.find("gamepad") != std::string::npos;
|
||||
|
||||
if (!keyboard && !gamepad) return;
|
||||
if (gamepad)
|
||||
{
|
||||
if (sensedInput->type != Input::IT_STICKMOTION &&
|
||||
sensedInput->type != Input::IT_STICKBUTTON)
|
||||
{
|
||||
return; // that kind of input does not interest us
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (keyboard)
|
||||
{
|
||||
if(UserConfigParams::m_verbosity>=5)
|
||||
std::cout << "% Binding " << KartActionStrings[binding_to_set]
|
||||
<< " : setting to keyboard key " << sensedInput->btnID << " \n\n";
|
||||
|
||||
// extract keyboard ID from name
|
||||
int configID = -1;
|
||||
sscanf( devices->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str(), "keyboard%i", &configID );
|
||||
|
||||
KeyboardConfig* keyboard = input_manager->getDeviceList()->getKeyboardConfig(configID);
|
||||
keyboard->setBinding(binding_to_set, Input::IT_KEYBOARD, sensedInput->btnID, Input::AD_NEUTRAL);
|
||||
|
||||
// refresh display
|
||||
init();
|
||||
}
|
||||
else if (gamepad)
|
||||
{
|
||||
if(UserConfigParams::m_verbosity>=5)
|
||||
std::cout << "% Binding " << KartActionStrings[binding_to_set]
|
||||
<< " : setting to gamepad #" << sensedInput->deviceID << " : ";
|
||||
if (sensedInput->type == Input::IT_STICKMOTION)
|
||||
{
|
||||
std::cout << "axis " << sensedInput->btnID << " direction " <<
|
||||
(sensedInput->axisDirection == Input::AD_NEGATIVE ? "-" : "+") << "\n\n";
|
||||
}
|
||||
else if (sensedInput->type == Input::IT_STICKBUTTON)
|
||||
{
|
||||
std::cout << "button " << sensedInput->btnID << "\n\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Sensed unknown gamepad event type??\n";
|
||||
}
|
||||
|
||||
// extract gamepad ID from name
|
||||
int configID = -1;
|
||||
sscanf( devices->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str(), "gamepad%i", &configID );
|
||||
|
||||
GamepadConfig* config = input_manager->getDeviceList()->getGamepadConfig(configID);
|
||||
config->setBinding(binding_to_set, sensedInput->type, sensedInput->btnID,
|
||||
(Input::AxisDirection)sensedInput->axisDirection);
|
||||
|
||||
// refresh display
|
||||
init();
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ModalDialog::dismiss();
|
||||
input_manager->setMode(InputManager::MENU);
|
||||
|
||||
// re-select the previous button
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>(binding_to_set_button.c_str());
|
||||
if(btn != NULL) btn->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
// save new binding to file
|
||||
input_manager->getDeviceList()->serialize();
|
||||
devices->clear();
|
||||
buildDeviceList();
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput::tearDown()
|
||||
@ -424,17 +187,19 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name,
|
||||
}
|
||||
else if (name == "devices")
|
||||
{
|
||||
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
|
||||
ListWidget* devices = this->getWidget<ListWidget>("devices");
|
||||
assert(devices != NULL);
|
||||
|
||||
const std::string& selection = devices->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
const std::string& selection = devices->getSelectionInternalName();
|
||||
if (selection.find("gamepad") != std::string::npos)
|
||||
{
|
||||
int i = -1, read = 0;
|
||||
read = sscanf( selection.c_str(), "gamepad%i", &i );
|
||||
if (read == 1 && i != -1)
|
||||
{
|
||||
updateInputButtons( input_manager->getDeviceList()->getGamepadConfig(i) );
|
||||
OptionsScreenInput2::getInstance()->setDevice( input_manager->getDeviceList()->getGamepadConfig(i) );
|
||||
StateManager::get()->replaceTopMostScreen(OptionsScreenInput2::getInstance());
|
||||
//updateInputButtons( input_manager->getDeviceList()->getGamepadConfig(i) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -447,7 +212,9 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name,
|
||||
read = sscanf( selection.c_str(), "keyboard%i", &i );
|
||||
if (read == 1 && i != -1)
|
||||
{
|
||||
updateInputButtons( input_manager->getDeviceList()->getKeyboardConfig(i) );
|
||||
// updateInputButtons( input_manager->getDeviceList()->getKeyboardConfig(i) );
|
||||
OptionsScreenInput2::getInstance()->setDevice( input_manager->getDeviceList()->getKeyboardConfig(i) );
|
||||
StateManager::get()->replaceTopMostScreen(OptionsScreenInput2::getInstance());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -459,76 +226,6 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name,
|
||||
std::cerr << "Cannot read internal input device ID : " << selection.c_str() << std::endl;
|
||||
}
|
||||
}
|
||||
else if(name.find("binding_") != std::string::npos)
|
||||
{
|
||||
binding_to_set_button = name;
|
||||
|
||||
if(name == "binding_up")
|
||||
{
|
||||
binding_to_set = PA_ACCEL;
|
||||
}
|
||||
else if(name == "binding_down")
|
||||
{
|
||||
binding_to_set = PA_BRAKE;
|
||||
}
|
||||
else if(name == "binding_left")
|
||||
{
|
||||
binding_to_set = PA_LEFT;
|
||||
}
|
||||
else if(name == "binding_right")
|
||||
{
|
||||
binding_to_set = PA_RIGHT;
|
||||
}
|
||||
else if(name == "binding_fire")
|
||||
{
|
||||
binding_to_set = PA_FIRE;
|
||||
}
|
||||
else if(name == "binding_nitro")
|
||||
{
|
||||
binding_to_set = PA_NITRO;
|
||||
}
|
||||
else if(name == "binding_drift")
|
||||
{
|
||||
binding_to_set = PA_DRIFT;
|
||||
}
|
||||
else if(name == "binding_rescue")
|
||||
{
|
||||
binding_to_set = PA_RESCUE;
|
||||
}
|
||||
else if(name == "binding_look_back")
|
||||
{
|
||||
binding_to_set = PA_LOOK_BACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Unknown binding name : " << name.c_str() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
DynamicRibbonWidget* devices = this->getWidget<DynamicRibbonWidget>("devices");
|
||||
assert( devices != NULL );
|
||||
if(UserConfigParams::m_verbosity>=5)
|
||||
std::cout << "\n% Entering sensing mode for "
|
||||
<< devices->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str()
|
||||
<< std::endl;
|
||||
|
||||
new PressAKeyDialog(0.4f, 0.4f);
|
||||
|
||||
std::string selection = devices->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
if (selection.find("keyboard") != std::string::npos)
|
||||
{
|
||||
input_manager->setMode(InputManager::INPUT_SENSE_KEYBOARD);
|
||||
}
|
||||
else if (selection.find("gamepad") != std::string::npos)
|
||||
{
|
||||
input_manager->setMode(InputManager::INPUT_SENSE_GAMEPAD);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "unknown selection device in options : " << selection.c_str() << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -536,6 +233,7 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name,
|
||||
|
||||
void OptionsScreenInput::unloaded()
|
||||
{
|
||||
m_inited = false;
|
||||
delete m_icon_bank;
|
||||
m_icon_bank = NULL;
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,8 @@
|
||||
|
||||
namespace GUIEngine { class Widget; }
|
||||
class DeviceConfig;
|
||||
namespace irr { namespace gui { class STKModifiedSpriteBank; } }
|
||||
|
||||
|
||||
struct Input;
|
||||
|
||||
@ -37,11 +39,11 @@ class OptionsScreenInput : public GUIEngine::Screen, public GUIEngine::ScreenSin
|
||||
{
|
||||
OptionsScreenInput();
|
||||
|
||||
bool m_inited;
|
||||
|
||||
void updateInputButtons(DeviceConfig* config);
|
||||
void buildDeviceList();
|
||||
|
||||
irr::gui::STKModifiedSpriteBank* m_icon_bank;
|
||||
|
||||
public:
|
||||
friend class GUIEngine::ScreenSingleton<OptionsScreenInput>;
|
||||
|
||||
@ -66,11 +68,6 @@ public:
|
||||
*/
|
||||
void rebuildDeviceList();
|
||||
|
||||
/**
|
||||
* \brief invoke in "input sensing" mode, when input was sensed.
|
||||
* Updates the input bindings accordingly with the sensed input.
|
||||
*/
|
||||
void gotSensedInput(Input* sensedInput);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
420
src/states_screens/options_screen_input2.cpp
Normal file
420
src/states_screens/options_screen_input2.cpp
Normal file
@ -0,0 +1,420 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2009 Marianne Gagnon
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "states_screens/options_screen_input.hpp"
|
||||
#include "states_screens/options_screen_input2.hpp"
|
||||
#include "states_screens/options_screen_av.hpp"
|
||||
#include "states_screens/options_screen_players.hpp"
|
||||
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "guiengine/CGUISpriteBank.h"
|
||||
#include "guiengine/screen.hpp"
|
||||
#include "guiengine/widget.hpp"
|
||||
#include "guiengine/widgets/button_widget.hpp"
|
||||
#include "guiengine/widgets/label_widget.hpp"
|
||||
#include "guiengine/widgets/list_widget.hpp"
|
||||
#include "guiengine/widgets/ribbon_widget.hpp"
|
||||
#include "input/input_manager.hpp"
|
||||
#include "input/device_manager.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "states_screens/dialogs/press_a_key_dialog.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <set>
|
||||
|
||||
using namespace GUIEngine;
|
||||
|
||||
DEFINE_SCREEN_SINGLETON( OptionsScreenInput2 );
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
OptionsScreenInput2::OptionsScreenInput2() : Screen("options_device.stkgui")
|
||||
{
|
||||
m_config = NULL;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput2::loadedFromFile()
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput2::updateInputButtons()
|
||||
{
|
||||
assert(m_config != NULL);
|
||||
|
||||
// to detect duplicate entries
|
||||
std::set<core::stringw> existing_bindings;
|
||||
|
||||
{
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_up");
|
||||
core::stringw binding_name = m_config->getBindingAsString(PA_ACCEL);
|
||||
btn->setLabel( binding_name );
|
||||
|
||||
// check if another binding already uses this key
|
||||
if (existing_bindings.find(binding_name) != existing_bindings.end())
|
||||
{
|
||||
btn->setBadge(BAD_BADGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_bindings.insert(binding_name);
|
||||
btn->resetAllBadges();
|
||||
}
|
||||
}
|
||||
{
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_down");
|
||||
core::stringw binding_name = m_config->getBindingAsString(PA_BRAKE);
|
||||
btn->setLabel( binding_name );
|
||||
|
||||
// check if another binding already uses this key
|
||||
if (existing_bindings.find(binding_name) != existing_bindings.end())
|
||||
{
|
||||
btn->setBadge(BAD_BADGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_bindings.insert(binding_name);
|
||||
btn->resetAllBadges();
|
||||
}
|
||||
}
|
||||
{
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_left");
|
||||
core::stringw binding_name = m_config->getBindingAsString(PA_LEFT);
|
||||
btn->setLabel( binding_name );
|
||||
|
||||
// check if another binding already uses this key
|
||||
if (existing_bindings.find(binding_name) != existing_bindings.end())
|
||||
{
|
||||
btn->setBadge(BAD_BADGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_bindings.insert(binding_name);
|
||||
btn->resetAllBadges();
|
||||
}
|
||||
}
|
||||
{
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_right");
|
||||
core::stringw binding_name = m_config->getBindingAsString(PA_RIGHT);
|
||||
btn->setLabel( binding_name );
|
||||
|
||||
// check if another binding already uses this key
|
||||
if (existing_bindings.find(binding_name) != existing_bindings.end())
|
||||
{
|
||||
btn->setBadge(BAD_BADGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_bindings.insert(binding_name);
|
||||
btn->resetAllBadges();
|
||||
}
|
||||
}
|
||||
|
||||
std::set<core::stringw>::iterator it;
|
||||
|
||||
|
||||
{
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_fire");
|
||||
core::stringw binding_name = m_config->getBindingAsString(PA_FIRE);
|
||||
btn->setLabel( binding_name );
|
||||
|
||||
// check if another binding already uses this key
|
||||
if (existing_bindings.find(binding_name) != existing_bindings.end())
|
||||
{
|
||||
btn->setBadge(BAD_BADGE);
|
||||
//std::cout << "Setting bad badge!!!!\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_bindings.insert(binding_name);
|
||||
btn->resetAllBadges();
|
||||
}
|
||||
}
|
||||
{
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_nitro");
|
||||
core::stringw binding_name = m_config->getBindingAsString(PA_NITRO);
|
||||
btn->setLabel( binding_name );
|
||||
|
||||
// check if another binding already uses this key
|
||||
if (existing_bindings.find(binding_name) != existing_bindings.end())
|
||||
{
|
||||
btn->setBadge(BAD_BADGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_bindings.insert(binding_name);
|
||||
btn->resetAllBadges();
|
||||
}
|
||||
}
|
||||
{
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_drift");
|
||||
core::stringw binding_name = m_config->getBindingAsString(PA_DRIFT);
|
||||
btn->setLabel( binding_name );
|
||||
|
||||
// check if another binding already uses this key
|
||||
if (existing_bindings.find(binding_name) != existing_bindings.end())
|
||||
{
|
||||
btn->setBadge(BAD_BADGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_bindings.insert(binding_name);
|
||||
btn->resetAllBadges();
|
||||
}
|
||||
}
|
||||
{
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_rescue");
|
||||
core::stringw binding_name = m_config->getBindingAsString(PA_RESCUE);
|
||||
btn->setLabel( binding_name );
|
||||
|
||||
// check if another binding already uses this key
|
||||
if (existing_bindings.find(binding_name) != existing_bindings.end())
|
||||
{
|
||||
btn->setBadge(BAD_BADGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_bindings.insert(binding_name);
|
||||
btn->resetAllBadges();
|
||||
}
|
||||
}
|
||||
{
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>("binding_look_back");
|
||||
core::stringw binding_name = m_config->getBindingAsString(PA_LOOK_BACK);
|
||||
btn->setLabel( binding_name );
|
||||
|
||||
// check if another binding already uses this key
|
||||
if (existing_bindings.find(binding_name) != existing_bindings.end())
|
||||
{
|
||||
btn->setBadge(BAD_BADGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_bindings.insert(binding_name);
|
||||
btn->resetAllBadges();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput2::init()
|
||||
{
|
||||
RibbonWidget* tabBar = this->getWidget<RibbonWidget>("options_choice");
|
||||
if (tabBar != NULL) tabBar->select( "tab_controls", PLAYER_ID_GAME_MASTER );
|
||||
|
||||
updateInputButtons();
|
||||
|
||||
LabelWidget* label = this->getWidget<LabelWidget>("title");
|
||||
label->setText( m_config->getName().c_str() );
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static PlayerAction binding_to_set;
|
||||
static std::string binding_to_set_button;
|
||||
|
||||
void OptionsScreenInput2::gotSensedInput(Input* sensedInput)
|
||||
{
|
||||
const bool keyboard = (m_config->getType() == DEVICE_CONFIG_TYPE_KEYBOARD &&
|
||||
sensedInput->type == Input::IT_KEYBOARD);
|
||||
const bool gamepad = (sensedInput->type == Input::IT_STICKMOTION ||
|
||||
sensedInput->type == Input::IT_STICKBUTTON) &&
|
||||
m_config->getType() == DEVICE_CONFIG_TYPE_GAMEPAD;
|
||||
|
||||
if (keyboard)
|
||||
{
|
||||
if (UserConfigParams::m_verbosity>=5)
|
||||
{
|
||||
std::cout << "% Binding " << KartActionStrings[binding_to_set]
|
||||
<< " : setting to keyboard key " << sensedInput->btnID << " \n\n";
|
||||
}
|
||||
|
||||
KeyboardConfig* keyboard = (KeyboardConfig*)m_config;
|
||||
keyboard->setBinding(binding_to_set, Input::IT_KEYBOARD, sensedInput->btnID, Input::AD_NEUTRAL);
|
||||
|
||||
// refresh display
|
||||
init();
|
||||
}
|
||||
else if (gamepad)
|
||||
{
|
||||
if (UserConfigParams::m_verbosity>=5)
|
||||
{
|
||||
std::cout << "% Binding " << KartActionStrings[binding_to_set]
|
||||
<< " : setting to gamepad #" << sensedInput->deviceID << " : ";
|
||||
|
||||
if (sensedInput->type == Input::IT_STICKMOTION)
|
||||
{
|
||||
std::cout << "axis " << sensedInput->btnID << " direction "
|
||||
<< (sensedInput->axisDirection == Input::AD_NEGATIVE ? "-" : "+") << "\n\n";
|
||||
}
|
||||
else if (sensedInput->type == Input::IT_STICKBUTTON)
|
||||
{
|
||||
std::cout << "button " << sensedInput->btnID << "\n\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Sensed unknown gamepad event type??\n";
|
||||
}
|
||||
}
|
||||
|
||||
// extract gamepad ID from name
|
||||
GamepadConfig* config = (GamepadConfig*)m_config;
|
||||
config->setBinding(binding_to_set, sensedInput->type, sensedInput->btnID,
|
||||
(Input::AxisDirection)sensedInput->axisDirection);
|
||||
|
||||
// refresh display
|
||||
init();
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ModalDialog::dismiss();
|
||||
input_manager->setMode(InputManager::MENU);
|
||||
|
||||
// re-select the previous button
|
||||
ButtonWidget* btn = this->getWidget<ButtonWidget>(binding_to_set_button.c_str());
|
||||
if(btn != NULL) btn->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
// save new binding to file
|
||||
input_manager->getDeviceList()->serialize();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput2::tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput2::eventCallback(Widget* widget, const std::string& name, const int playerID)
|
||||
{
|
||||
//const std::string& screen_name = this->getName();
|
||||
|
||||
if (name == "options_choice")
|
||||
{
|
||||
std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str();
|
||||
|
||||
if (selection == "tab_audio_video")
|
||||
{
|
||||
StateManager::get()->replaceTopMostScreen(OptionsScreenAV::getInstance());
|
||||
}
|
||||
else if (selection == "tab_players")
|
||||
{
|
||||
StateManager::get()->replaceTopMostScreen(OptionsScreenPlayers::getInstance());
|
||||
}
|
||||
else if (selection == "tab_controls")
|
||||
{
|
||||
}
|
||||
}
|
||||
else if (name == "back_to_device_list")
|
||||
{
|
||||
StateManager::get()->replaceTopMostScreen(OptionsScreenInput::getInstance());
|
||||
}
|
||||
else if (name == "back")
|
||||
{
|
||||
StateManager::get()->escapePressed();
|
||||
}
|
||||
else if(name.find("binding_") != std::string::npos)
|
||||
{
|
||||
binding_to_set_button = name;
|
||||
|
||||
if(name == "binding_up")
|
||||
{
|
||||
binding_to_set = PA_ACCEL;
|
||||
}
|
||||
else if(name == "binding_down")
|
||||
{
|
||||
binding_to_set = PA_BRAKE;
|
||||
}
|
||||
else if(name == "binding_left")
|
||||
{
|
||||
binding_to_set = PA_LEFT;
|
||||
}
|
||||
else if(name == "binding_right")
|
||||
{
|
||||
binding_to_set = PA_RIGHT;
|
||||
}
|
||||
else if(name == "binding_fire")
|
||||
{
|
||||
binding_to_set = PA_FIRE;
|
||||
}
|
||||
else if(name == "binding_nitro")
|
||||
{
|
||||
binding_to_set = PA_NITRO;
|
||||
}
|
||||
else if(name == "binding_drift")
|
||||
{
|
||||
binding_to_set = PA_DRIFT;
|
||||
}
|
||||
else if(name == "binding_rescue")
|
||||
{
|
||||
binding_to_set = PA_RESCUE;
|
||||
}
|
||||
else if(name == "binding_look_back")
|
||||
{
|
||||
binding_to_set = PA_LOOK_BACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Unknown binding name : " << name.c_str() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (UserConfigParams::m_verbosity>=5)
|
||||
{
|
||||
std::cout << "\n% Entering sensing mode for "
|
||||
<< m_config->getName().c_str()
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
new PressAKeyDialog(0.4f, 0.4f);
|
||||
|
||||
if (m_config->getType() == DEVICE_CONFIG_TYPE_KEYBOARD)
|
||||
{
|
||||
input_manager->setMode(InputManager::INPUT_SENSE_KEYBOARD);
|
||||
}
|
||||
else if (m_config->getType() == DEVICE_CONFIG_TYPE_GAMEPAD)
|
||||
{
|
||||
input_manager->setMode(InputManager::INPUT_SENSE_GAMEPAD);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "unknown selection device in options : " << m_config->getName().c_str() << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void OptionsScreenInput2::unloaded()
|
||||
{
|
||||
}
|
||||
|
73
src/states_screens/options_screen_input2.hpp
Normal file
73
src/states_screens/options_screen_input2.hpp
Normal file
@ -0,0 +1,73 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2009 Marianne Gagnon
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
#ifndef __HEADER_OPTIONS_SCREEN_INPUT2_HPP__
|
||||
#define __HEADER_OPTIONS_SCREEN_INPUT2_HPP__
|
||||
|
||||
#include <string>
|
||||
#include "irrlicht.h"
|
||||
|
||||
#include "guiengine/screen.hpp"
|
||||
|
||||
namespace GUIEngine { class Widget; }
|
||||
class DeviceConfig;
|
||||
namespace irr { namespace gui { class STKModifiedSpriteBank; } }
|
||||
|
||||
|
||||
struct Input;
|
||||
|
||||
/**
|
||||
* \brief Input options screen
|
||||
* \ingroup states_screens
|
||||
*/
|
||||
class OptionsScreenInput2 : public GUIEngine::Screen, public GUIEngine::ScreenSingleton<OptionsScreenInput2>
|
||||
{
|
||||
OptionsScreenInput2();
|
||||
|
||||
void updateInputButtons();
|
||||
|
||||
DeviceConfig* m_config;
|
||||
|
||||
public:
|
||||
friend class GUIEngine::ScreenSingleton<OptionsScreenInput2>;
|
||||
|
||||
void setDevice(DeviceConfig* config) { m_config = config; }
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void loadedFromFile();
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name, const int playerID);
|
||||
|
||||
/** \brief implement optional callback from parent class GUIEngine::Screen */
|
||||
virtual void unloaded();
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void init();
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void tearDown();
|
||||
|
||||
/**
|
||||
* \brief invoke in "input sensing" mode, when input was sensed.
|
||||
* Updates the input bindings accordingly with the sensed input.
|
||||
*/
|
||||
void gotSensedInput(Input* sensedInput);
|
||||
};
|
||||
|
||||
#endif
|
@ -161,7 +161,7 @@ void OptionsScreenPlayers::eventCallback(Widget* widget, const std::string& name
|
||||
ListWidget* players = this->getWidget<ListWidget>("players");
|
||||
assert(players != NULL);
|
||||
|
||||
std::string selectedPlayer = players->getSelectionName();
|
||||
std::string selectedPlayer = stringc( players->getSelectionLabel().c_str() ).c_str();
|
||||
const int playerAmount = UserConfigParams::m_all_players.size();
|
||||
for (int n=0; n<playerAmount; n++)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user