2009-05-25 09:01:26 +00:00
/*
* OpenClonk , http : //www.openclonk.org
*
2013-12-17 20:01:09 +00:00
* Copyright ( c ) 2005 - 2009 , RedWolf Design GmbH , http : //www.clonk.de/
* Copyright ( c ) 2009 - 2013 , The OpenClonk Team and contributors
2009-05-25 09:01:26 +00:00
*
2013-12-17 20:01:09 +00:00
* Distributed under the terms of the ISC license ; see accompanying file
* " COPYING " for details .
2009-05-25 09:01:26 +00:00
*
2013-12-17 20:01:09 +00:00
* " Clonk " is a registered trademark of Matthes Bender , used with permission .
* See accompanying file " TRADEMARK " for details .
2009-05-25 09:01:26 +00:00
*
2013-12-17 20:01:09 +00:00
* To redistribute this file separately , substitute the full license texts
* for the above references .
2009-05-25 09:01:26 +00:00
*/
// Input to player control mapping
# ifndef INC_C4PlayerControl
# define INC_C4PlayerControl
2009-12-17 13:06:24 +00:00
# include "C4KeyboardInput.h"
# include "C4LangStringTable.h"
# include "C4Id.h"
2013-12-04 12:35:07 +00:00
# include "C4TimeMilliseconds.h"
2009-12-17 13:06:24 +00:00
# include <list>
2009-05-25 09:01:26 +00:00
2010-09-29 01:44:05 +00:00
const float C4GFX_ZoomStep = 1.1040895f ;
2009-05-25 09:01:26 +00:00
// one control definition, e.g. "Left", "Throw", etc.
class C4PlayerControlDef
2010-03-28 17:58:21 +00:00
{
2011-11-20 20:49:38 +00:00
public :
enum CoordinateSpace // coordinate space for mouse position
{
COS_Game = 0 , // game (landscape) coordinates
COS_Viewport = 1 // viewport (GUI) coordinates
} ;
2015-02-04 18:26:45 +00:00
enum Actions //action to be performed when control is triggered
{
CDA_None = 0 , // do nothing
CDA_Script , // default: Script callback
CDA_Menu , // open player menu (async)
CDA_MenuOK , CDA_MenuCancel , CDA_MenuLeft , CDA_MenuUp , CDA_MenuRight , CDA_MenuDown , // player menu controls (async)
CDA_ObjectMenuTextComplete , // object menu fast-foward through text animation (async)
CDA_ObjectMenuOK , CDA_ObjectMenuOKAll , CDA_ObjectMenuSelect , CDA_ObjectMenuCancel , CDA_ObjectMenuLeft , CDA_ObjectMenuUp , CDA_ObjectMenuRight , CDA_ObjectMenuDown , // object menu controls (sync)
CDA_ZoomIn , CDA_ZoomOut // player viewport control (async)
} ;
2011-11-20 20:49:38 +00:00
2010-03-28 17:58:21 +00:00
private :
StdCopyStrBuf sIdentifier ; // name as seen in script and config
StdCopyStrBuf sGUIName ; // name as displayed to player
StdCopyStrBuf sGUIDesc ; // key description displayed to player in config dialog
bool fGlobal ; // if true, control can be bound to the global player only
bool fIsHoldKey ; // if true, the control can be in down and up state
2015-02-04 18:26:45 +00:00
bool fDefaultDisabled ; // if true, the control is disabled by default and needs to be enabled by script
bool fSendCursorPos ; // if true, x/y parameters will be set by current GUI mouse cursor pos (or GetCursor()-GUI coordinate pos for gamepad)
2010-03-28 17:58:21 +00:00
int32_t iRepeatDelay ; // if >0, the key will generate successive events when held down
int32_t iInitialRepeatDelay ; // delay after which KeyRepeat will be enabled
C4ID idControlExtraData ; // extra data to be passed to script function
2011-11-20 20:49:38 +00:00
CoordinateSpace eCoordSpace ; // coordinate space to be used for mouse coordinates when control is triggered by mouse
2010-03-28 17:58:21 +00:00
Actions eAction ;
public :
2015-02-04 18:26:45 +00:00
C4PlayerControlDef ( ) :
fGlobal ( false ) , fIsHoldKey ( false ) , fDefaultDisabled ( false ) , fSendCursorPos ( false ) ,
idControlExtraData ( C4ID : : None ) , eCoordSpace ( COS_Game ) , eAction ( CDA_Script )
{ }
2010-03-28 17:58:21 +00:00
~ C4PlayerControlDef ( ) { } ;
void CompileFunc ( StdCompiler * pComp ) ;
const char * GetIdentifier ( ) const { return sIdentifier . getData ( ) ; }
const char * GetGUIName ( ) const { return sGUIName . getData ( ) ; }
const char * GetGUIDesc ( ) const { return sGUIDesc . getData ( ) ; }
Actions GetAction ( ) const { return eAction ; }
bool IsHoldKey ( ) const { return fIsHoldKey ; }
C4ID GetExtraData ( ) const { return idControlExtraData ; }
bool IsGlobal ( ) const { return fGlobal ; }
int32_t GetRepeatDelay ( ) const { return iRepeatDelay ; }
int32_t GetInitialRepeatDelay ( ) const { return iInitialRepeatDelay ; }
bool IsDefaultDisabled ( ) const { return fDefaultDisabled ; }
2011-11-20 20:49:38 +00:00
CoordinateSpace GetCoordinateSpace ( ) const { return eCoordSpace ; }
2010-04-10 20:44:00 +00:00
bool IsSendCursorPos ( ) const { return fSendCursorPos ; }
2010-03-28 17:58:21 +00:00
bool operator = = ( const C4PlayerControlDef & cmp ) const ;
bool Execute ( bool fUp , const C4KeyEventData & rKeyExtraData ) ; // key was triggered - execute and return if handled
2014-08-10 18:58:26 +00:00
bool IsSyncObjectMenuControl ( ) const { return eAction > = CDA_ObjectMenuOK & & eAction < = CDA_ObjectMenuDown ; }
bool IsAsync ( ) const { return eAction ! = CDA_None & & eAction ! = CDA_Script & & ! IsSyncObjectMenuControl ( ) ; } // true if to be executed directly when triggered
bool IsSync ( ) const { return eAction = = CDA_Script | | IsSyncObjectMenuControl ( ) ; } // true if to be executed via control queue
2010-03-28 17:58:21 +00:00
bool IsValid ( ) const { return eAction ! = CDA_None ; }
} ;
2009-05-25 09:01:26 +00:00
// CON_* constants are indices into the C4PlayerControlDefs list
enum { CON_None = - 1 } ; // No/undefined control
// list of all known player control definitions
class C4PlayerControlDefs
2010-03-28 17:58:21 +00:00
{
private :
typedef std : : vector < C4PlayerControlDef > DefVecImpl ;
DefVecImpl Defs ;
2011-07-16 09:58:38 +00:00
bool clear_previous ; // if set is merged, all previous control defs are cleared - use
2010-03-28 17:58:21 +00:00
public :
struct CInternalCons
2009-05-25 09:01:26 +00:00
{
2010-05-07 13:57:56 +00:00
int32_t CON_ObjectMenuSelect , CON_ObjectMenuOKAll , CON_ObjectMenuOK , CON_ObjectMenuCancel , CON_CursorPos ;
CInternalCons ( ) : CON_ObjectMenuSelect ( CON_None ) , CON_ObjectMenuOKAll ( CON_None ) , CON_ObjectMenuOK ( CON_None ) , CON_ObjectMenuCancel ( CON_None ) , CON_CursorPos ( CON_None ) { }
2010-03-28 17:58:21 +00:00
} InternalCons ;
2009-05-26 06:10:38 +00:00
2010-03-28 17:58:21 +00:00
void UpdateInternalCons ( ) ;
2009-05-25 09:01:26 +00:00
2010-03-28 17:58:21 +00:00
public :
2011-07-16 09:58:38 +00:00
C4PlayerControlDefs ( ) : clear_previous ( false ) { }
2010-03-28 17:58:21 +00:00
~ C4PlayerControlDefs ( ) { }
void Clear ( ) ;
2009-06-09 23:29:16 +00:00
2010-03-28 17:58:21 +00:00
void CompileFunc ( StdCompiler * pComp ) ;
void MergeFrom ( const C4PlayerControlDefs & Src ) ; // copy all defs from source file; overwrite defs of same name if found
2009-05-26 06:10:38 +00:00
2010-03-28 17:58:21 +00:00
void FinalInit ( ) ; // after all defs have been loaded: register script constants
const C4PlayerControlDef * GetControlByIndex ( int32_t idx ) const ;
int32_t GetControlIndexByIdentifier ( const char * szIdentifier ) const ; // return CON_None for not found
2010-04-20 16:20:24 +00:00
size_t GetCount ( ) const { return Defs . size ( ) ; }
2010-03-28 17:58:21 +00:00
2011-07-16 09:58:38 +00:00
bool operator = = ( const C4PlayerControlDefs & cmp ) const { return Defs = = cmp . Defs & & clear_previous = = cmp . clear_previous ; }
2010-03-28 17:58:21 +00:00
} ;
2009-05-25 09:01:26 +00:00
2009-05-28 00:14:54 +00:00
struct C4PlayerControlRecentKey
2010-03-28 17:58:21 +00:00
{
2009-10-16 14:23:17 +00:00
C4KeyCodeEx pressed_key , matched_key ;
2013-12-04 12:35:07 +00:00
C4TimeMilliseconds tTime ;
C4PlayerControlRecentKey ( const C4KeyCodeEx & pressed_key , const C4KeyCodeEx & matched_key , C4TimeMilliseconds tTime ) : pressed_key ( pressed_key ) , matched_key ( matched_key ) , tTime ( tTime ) { }
2009-10-16 14:23:17 +00:00
bool operator = = ( const C4KeyCodeEx & cmp ) { return pressed_key = = cmp ; } // comparison op for finding items in lists: Search for the pressed key only
2010-03-28 17:58:21 +00:00
} ;
2009-05-28 00:14:54 +00:00
typedef std : : list < C4PlayerControlRecentKey > C4PlayerControlRecentKeyList ;
typedef std : : vector < C4KeyCodeEx > C4KeyCodeExVec ;
2009-05-25 09:01:26 +00:00
// a key/mouse/gamepad assignment to a PlayerControlDef
class C4PlayerControlAssignment
2010-03-28 17:58:21 +00:00
{
2015-02-04 18:26:45 +00:00
public :
// action to be performed on the control upon this key
enum TriggerModes
{
CTM_Default = 0 , // standard behaviour: The control will be triggered
CTM_Hold = 1 < < 0 , // the control will be put into "down"-mode
CTM_Release = 1 < < 1 , // the hold mode of the control will be released
CTM_AlwaysUnhandled = 1 < < 2 , // the key will not block handling of other keys even if it got handled
CTM_HandleDownStatesOnly = 1 < < 3 , // used when an already handled release key is processed to reset down states of overridden keys only
CTM_ClearRecentKeys = 1 < < 4 // if this assignment is triggered, RecentKeys are reset so no more combos can be generated
} ;
2010-03-28 17:58:21 +00:00
private :
// KeyCombo list:
// if size()>1, the control is triggered only if this combo is fulfilled
// used for simultanuous keypresses or sequences
struct KeyComboItem
2009-05-25 09:01:26 +00:00
{
2010-03-28 17:58:21 +00:00
C4KeyCodeEx Key ;
StdCopyStrBuf sKeyName ;
void CompileFunc ( StdCompiler * pComp ) ;
2011-03-30 20:11:47 +00:00
void UpdateKeyName ( ) ;
2013-02-09 00:03:06 +00:00
bool operator = = ( const KeyComboItem & cmp ) const { return Key = = cmp . Key ; }
2010-03-28 17:58:21 +00:00
} ;
typedef std : : vector < KeyComboItem > KeyComboVec ;
KeyComboVec KeyCombo ;
bool fComboIsSequence ; // if true, the keys must be pressed in sequence. Otherwise, they must be pressed simultanuously
2009-05-25 09:01:26 +00:00
2010-03-28 17:58:21 +00:00
// trigger key: key/mouse/gamepad event triggering this assignment. For combinations, the last key of the combo.
C4KeyCodeEx TriggerKey ;
2009-05-25 09:01:26 +00:00
2010-03-28 17:58:21 +00:00
StdCopyStrBuf sControlName ; // name of the control to be executed on this key
2012-10-08 20:29:15 +00:00
StdCopyStrBuf sGUIName ; // name as displayed to player. If empty, name stored in control def should be used.
StdCopyStrBuf sGUIDesc ; // key description displayed to player in config dialog. If empty, name stored in control def should be used.
2012-10-09 20:24:48 +00:00
bool fGUIDisabled ; // whether this key can't be reassigned through the GUI dialogue
2015-02-04 18:26:45 +00:00
bool fOverrideAssignments ; // override all other assignments to the same key?
bool is_inherited ; // set for assignments that were copied from a parent set without modification
bool fRefsResolved ; // set to true after sControlName and sKeyNames have been resolved to runtime values
2012-10-09 21:59:32 +00:00
int32_t iGUIGroup ; // in which this control is grouped in the gui
2010-03-28 17:58:21 +00:00
int32_t iControl ; // the control to be executed on this key, i.e. the resolved sControlName
int32_t iPriority ; // higher priority assignments get handled first
int32_t iTriggerMode ;
2009-05-26 06:10:38 +00:00
2015-02-04 18:26:45 +00:00
const C4PlayerControlAssignment * inherited_assignment ; // valid for assignments that were copied from a parent: source assignment
2009-05-25 09:01:26 +00:00
2010-03-28 17:58:21 +00:00
public :
2015-02-04 18:26:45 +00:00
C4PlayerControlAssignment ( ) :
TriggerKey ( ) , fOverrideAssignments ( false ) , is_inherited ( false ) , fRefsResolved ( false ) ,
iGUIGroup ( 0 ) , iControl ( CON_None ) , iPriority ( 0 ) , iTriggerMode ( CTM_Default ) ,
inherited_assignment ( NULL )
{ }
2010-03-28 17:58:21 +00:00
~ C4PlayerControlAssignment ( ) { }
2009-05-25 09:01:26 +00:00
2010-03-28 17:58:21 +00:00
void CompileFunc ( StdCompiler * pComp ) ;
2011-03-30 20:11:47 +00:00
void CopyKeyFrom ( const C4PlayerControlAssignment & src_assignment ) ;
2010-03-28 17:58:21 +00:00
bool ResolveRefs ( class C4PlayerControlAssignmentSet * pParentSet , C4PlayerControlDefs * pControlDefs ) ; // resolve references between assignments
bool IsComboMatched ( const C4PlayerControlRecentKeyList & DownKeys , const C4PlayerControlRecentKeyList & RecentKeys ) const ; // check if combo is currently fulfilled (assuming TriggerKey is already matched)
2011-03-30 20:11:47 +00:00
void SetInherited ( bool to_val ) { is_inherited = to_val ; }
void SetInheritedAssignment ( const C4PlayerControlAssignment * to_val ) { inherited_assignment = to_val ; }
void ResetKeyToInherited ( ) ;
2011-03-31 14:26:59 +00:00
bool IsKeyChanged ( ) const ;
2011-03-30 20:11:47 +00:00
void SetControlName ( const char * control_name ) { sControlName . Copy ( control_name ) ; }
void SetKey ( const C4KeyCodeEx & key ) ;
2010-03-28 17:58:21 +00:00
bool operator = = ( const C4PlayerControlAssignment & cmp ) const ; // doesn't compare resolved TriggerKey/iControl
bool operator < ( const C4PlayerControlAssignment & cmp ) const { return iPriority > cmp . iPriority ; } // assignments are processed in DESCENDING priority!
const char * GetControlName ( ) const { return sControlName . getData ( ) ; }
int32_t GetControl ( ) const { return iControl ; }
2012-10-08 20:29:15 +00:00
const char * GetGUIName ( const C4PlayerControlDefs & defs ) const ;
const char * GetGUIDesc ( const C4PlayerControlDefs & defs ) const ;
2012-10-09 20:24:48 +00:00
bool IsGUIDisabled ( ) const ;
2012-10-09 21:59:32 +00:00
int32_t GetGUIGroup ( ) const ;
2010-03-28 17:58:21 +00:00
bool IsRefsResolved ( ) const { return fRefsResolved ; }
2012-10-08 18:45:04 +00:00
void ResetRefsResolved ( ) { fRefsResolved = false ; } // Mark references to other assignments as not resolved
2010-03-28 17:58:21 +00:00
bool IsAlwaysUnhandled ( ) const { return ! ! ( iTriggerMode & CTM_AlwaysUnhandled ) ; }
int32_t GetTriggerMode ( ) const { return iTriggerMode ; }
const C4KeyCodeEx & GetTriggerKey ( ) const { return TriggerKey ; }
bool HasCombo ( ) const { return KeyCombo . size ( ) > 1 ; }
bool IsOverrideAssignments ( ) const { return fOverrideAssignments ; }
2011-03-30 20:11:47 +00:00
bool IsInherited ( ) const { return is_inherited ; }
const C4PlayerControlAssignment * GetInheritedAssignment ( ) const { return inherited_assignment ; }
2012-04-17 15:06:16 +00:00
StdStrBuf GetKeysAsString ( bool human_readable , bool short_name ) const ;
2010-03-28 17:58:21 +00:00
} ;
2009-05-26 06:10:38 +00:00
typedef std : : vector < C4PlayerControlAssignment > C4PlayerControlAssignmentVec ;
2009-05-28 00:14:54 +00:00
typedef std : : vector < const C4PlayerControlAssignment * > C4PlayerControlAssignmentPVec ;
2009-05-26 06:10:38 +00:00
2009-05-25 09:01:26 +00:00
// a set of key/mouse/gamepad assignments to all controls
class C4PlayerControlAssignmentSet
2010-03-28 17:58:21 +00:00
{
private :
2011-03-30 20:11:47 +00:00
StdCopyStrBuf sName , sGUIName , sParentSetName ;
const C4PlayerControlAssignmentSet * parent_set ;
2012-10-09 21:59:32 +00:00
C4PlayerControlAssignmentVec Assignments ; // ordered by priority
2011-03-30 20:11:47 +00:00
bool has_keyboard ;
2010-03-28 17:58:21 +00:00
bool has_mouse ;
bool has_gamepad ;
public :
2011-03-30 20:11:47 +00:00
C4PlayerControlAssignmentSet ( ) : parent_set ( NULL ) , has_keyboard ( true ) , has_mouse ( true ) , has_gamepad ( false ) { }
2010-03-28 17:58:21 +00:00
~ C4PlayerControlAssignmentSet ( ) { }
2011-03-30 20:11:47 +00:00
void InitEmptyFromTemplate ( const C4PlayerControlAssignmentSet & template_set ) ; // copy all fields except assignments
2010-03-28 17:58:21 +00:00
void CompileFunc ( StdCompiler * pComp ) ;
bool ResolveRefs ( C4PlayerControlDefs * pControlDefs ) ; // resolve references between assignments
2011-03-31 14:26:59 +00:00
void SortAssignments ( ) ;
2010-03-28 17:58:21 +00:00
2011-03-30 20:11:47 +00:00
enum MergeMode { MM_Normal , MM_LowPrio , MM_Inherit , MM_ConfigOverload } ;
void MergeFrom ( const C4PlayerControlAssignmentSet & Src , MergeMode merge_mode ) ; // take over all assignments defined in Src
C4PlayerControlAssignment * CreateAssignmentForControl ( const char * control_name ) ;
void RemoveAssignmentByControlName ( const char * control_name ) ;
2010-03-28 17:58:21 +00:00
const char * GetName ( ) const { return sName . getData ( ) ; }
2011-03-30 20:11:47 +00:00
const char * GetGUIName ( ) const { return sGUIName . getData ( ) ; }
2010-03-28 17:58:21 +00:00
bool IsWildcardName ( ) const { return IsWildcardString ( sName . getData ( ) ) ; }
2012-10-09 21:59:32 +00:00
C4PlayerControlAssignment * GetAssignmentByIndex ( int32_t index ) ; // assignments are ordered by priority
2010-03-28 17:58:21 +00:00
C4PlayerControlAssignment * GetAssignmentByControlName ( const char * szControlName ) ;
2011-03-30 20:11:47 +00:00
C4PlayerControlAssignment * GetAssignmentByControl ( int32_t control ) ;
2010-03-28 17:58:21 +00:00
void GetAssignmentsByKey ( const C4PlayerControlDefs & rDefs , const C4KeyCodeEx & key , bool fHoldKeysOnly , C4PlayerControlAssignmentPVec * pOutVec , const C4PlayerControlRecentKeyList & DownKeys , const C4PlayerControlRecentKeyList & RecentKeys ) const ; // match only by TriggerKey (last key of Combo) if fHoldKeysOnly
void GetTriggerKeys ( const C4PlayerControlDefs & rDefs , C4KeyCodeExVec * pRegularKeys , C4KeyCodeExVec * pHoldKeys ) const ; // put all trigger keys of keyset into output vectors
bool operator = = ( const C4PlayerControlAssignmentSet & cmp ) const ;
C4Facet GetPicture ( ) const ; // get image to be drawn to represent this control set
// todo
bool HasKeyboard ( ) const { return has_keyboard ; }
bool HasMouse ( ) const { return has_mouse ; }
bool HasGamepad ( ) const { return has_gamepad ; }
int32_t GetLayoutOrder ( ) const { return 0 ; } // returns position on keyboard (increasing from left to right) for viewport sorting
int32_t GetGamepadIndex ( ) const { return 0 ; }
bool IsMouseControlAssigned ( int32_t mouseevent ) const ;
} ;
2009-05-25 09:01:26 +00:00
// list of C4PlayerControlAssignmentSet
class C4PlayerControlAssignmentSets
2010-03-28 17:58:21 +00:00
{
private :
typedef std : : list < C4PlayerControlAssignmentSet > AssignmentSetList ;
AssignmentSetList Sets ;
2011-07-16 09:58:38 +00:00
bool clear_previous ;
2009-05-25 09:01:26 +00:00
2010-03-28 17:58:21 +00:00
public :
2011-07-16 09:58:38 +00:00
C4PlayerControlAssignmentSets ( ) : clear_previous ( false ) { }
2010-03-28 17:58:21 +00:00
~ C4PlayerControlAssignmentSets ( ) { }
void Clear ( ) ;
2009-05-25 09:01:26 +00:00
2010-03-28 17:58:21 +00:00
void CompileFunc ( StdCompiler * pComp ) ;
2011-03-30 20:11:47 +00:00
bool operator = = ( const C4PlayerControlAssignmentSets & cmp ) const ;
2010-03-28 17:58:21 +00:00
bool ResolveRefs ( C4PlayerControlDefs * pControlDefs ) ; // resolve references between assignments
2011-03-31 14:26:59 +00:00
void SortAssignments ( ) ;
2009-05-25 09:01:26 +00:00
2011-03-30 20:11:47 +00:00
void MergeFrom ( const C4PlayerControlAssignmentSets & Src , C4PlayerControlAssignmentSet : : MergeMode merge_mode ) ; // take over all assignments in known sets and new sets defined in Src
C4PlayerControlAssignmentSet * CreateEmptySetByTemplate ( const C4PlayerControlAssignmentSet & template_set ) ;
void RemoveSetByName ( const char * set_name ) ;
2009-05-26 06:10:38 +00:00
2010-03-28 17:58:21 +00:00
C4PlayerControlAssignmentSet * GetSetByName ( const char * szName ) ;
C4PlayerControlAssignmentSet * GetDefaultSet ( ) ;
int32_t GetSetIndex ( const C4PlayerControlAssignmentSet * set ) const ;
C4PlayerControlAssignmentSet * GetSetByIndex ( int32_t index ) ;
2010-04-20 16:20:24 +00:00
size_t GetSetCount ( ) const { return Sets . size ( ) ; }
2010-03-28 17:58:21 +00:00
} ;
2009-05-25 09:01:26 +00:00
// contents of one PlayerControls.txt file
class C4PlayerControlFile
2010-03-28 17:58:21 +00:00
{
private :
C4PlayerControlDefs ControlDefs ;
C4PlayerControlAssignmentSets AssignmentSets ;
public :
void Clear ( ) ;
void CompileFunc ( StdCompiler * pComp ) ;
bool Load ( C4Group & hGroup , const char * szFilename , C4LangStringTable * pLang ) ;
bool Save ( C4Group & hGroup , const char * szFilename ) ;
const C4PlayerControlDefs & GetControlDefs ( ) const { return ControlDefs ; }
const C4PlayerControlAssignmentSets & GetAssignmentSets ( ) const { return AssignmentSets ; }
} ;
2009-05-25 09:01:26 +00:00
// runtime information about a player's control
class C4PlayerControl
2010-03-28 17:58:21 +00:00
{
public :
enum { MaxRecentKeyLookback = 3000 , MaxSequenceKeyDelay = 800 } ; // milliseconds: Time to press key combos
2016-02-15 15:20:37 +00:00
enum ControlState {
CONS_Down = 0 ,
CONS_Up ,
CONS_Moved ,
} ;
2010-03-28 17:58:21 +00:00
private :
C4PlayerControlDefs & ControlDefs ; // shortcut
// owner
int32_t iPlr ;
// async values
C4PlayerControlAssignmentSet * pControlSet ; // the control set used by this player - may be NULL if the player cannot be controlled!
typedef std : : list < C4KeyBinding * > KeyBindingList ;
KeyBindingList KeyBindings ; // keys registered into Game.KeyboardInput
C4PlayerControlRecentKeyList RecentKeys ; // keys pressed recently; for combinations
C4PlayerControlRecentKeyList DownKeys ; // keys currently held down
2010-05-07 13:57:56 +00:00
bool IsCursorPosRequested ; // set to true when a SendCursorPos-control had been issued
2010-03-28 17:58:21 +00:00
public :
// sync values
struct CSync
2009-05-25 09:01:26 +00:00
{
2010-03-28 17:58:21 +00:00
struct ControlDownState
{
C4KeyEventData DownState ; // control is down if DownState.iStrength>0
int32_t iDownFrame ; // frame when control was pressed
bool fDownByUser ; // if true, the key is actually pressed. Otherwise, it's triggered as down by another key
ControlDownState ( const C4KeyEventData & rDownState , int32_t iDownFrame , bool fDownByUser )
2009-05-26 06:10:38 +00:00
: DownState ( rDownState ) , iDownFrame ( iDownFrame ) , fDownByUser ( fDownByUser ) { }
2010-03-28 17:58:21 +00:00
bool IsDown ( ) const { return DownState . iStrength > 0 ; }
ControlDownState ( ) : DownState ( ) , iDownFrame ( 0 ) , fDownByUser ( false ) { }
2009-05-25 09:01:26 +00:00
void CompileFunc ( StdCompiler * pComp ) ;
2010-03-28 17:58:21 +00:00
bool operator = = ( const ControlDownState & cmp ) const ;
} ;
typedef std : : vector < ControlDownState > DownStateVec ;
DownStateVec ControlDownStates ; // indexed by C4PlayerControlID: Down-state of a control. 0=up, 100=down; values inbetween e.g. for gamepad sticks
typedef std : : vector < int32_t > DisableStateVec ;
DisableStateVec ControlDisableStates ; // indexed by C4PlayerControlID: Disable-states of controls. >0 is disabled.
const ControlDownState * GetControlDownState ( int32_t iControl ) const ;
int32_t GetControlDisabled ( int32_t iControl ) const ;
bool IsControlDisabled ( int32_t iControl ) const { return GetControlDisabled ( iControl ) > 0 ; }
void SetControlDownState ( int32_t iControl , const C4KeyEventData & rDownState , int32_t iDownFrame , bool fDownByUser ) ;
2010-07-30 20:30:54 +00:00
void ResetControlDownState ( int32_t iControl ) ;
2010-03-28 17:58:21 +00:00
bool SetControlDisabled ( int32_t iControl , int32_t iVal ) ;
void InitDefaults ( const C4PlayerControlDefs & ControlDefs ) ;
2009-05-25 09:01:26 +00:00
void Clear ( ) ;
2010-03-28 17:58:21 +00:00
void CompileFunc ( StdCompiler * pComp ) ;
bool operator = = ( const CSync & cmp ) const ;
} ;
2009-05-25 09:01:26 +00:00
2010-03-28 17:58:21 +00:00
private :
CSync Sync ;
2010-03-26 13:48:28 +00:00
2010-03-28 17:58:21 +00:00
// callbacks from Game.KeyboardInput
2016-02-15 15:20:37 +00:00
bool ProcessKeyEvent ( const C4KeyCodeEx & pressed_key , const C4KeyCodeEx & matched_key , ControlState state , const C4KeyEventData & rKeyExtraData , bool reset_down_states_only = false , bool * clear_recent_keys = NULL ) ;
2010-03-28 17:58:21 +00:00
bool ProcessKeyDown ( const C4KeyCodeEx & pressed_key , const C4KeyCodeEx & matched_key ) ;
2011-11-20 20:49:38 +00:00
bool ProcessKeyUp ( const C4KeyCodeEx & pressed_key , const C4KeyCodeEx & matched_key ) ;
2016-02-15 15:20:37 +00:00
bool ProcessKeyMoved ( const C4KeyCodeEx & pressed_key , const C4KeyCodeEx & matched_key ) ;
2009-05-26 06:10:38 +00:00
2010-03-28 17:58:21 +00:00
// execute single control. return if handled.
2016-02-15 15:20:37 +00:00
bool ExecuteControl ( int32_t iControl , ControlState state , const C4KeyEventData & rKeyExtraData , int32_t iTriggerMode , bool fRepeated , bool fHandleDownStateOnly ) ;
bool ExecuteControlAction ( int32_t iControl , C4PlayerControlDef : : Actions eAction , C4ID idControlExtraData , ControlState state , const C4KeyEventData & rKeyExtraData , bool fRepeated ) ;
bool ExecuteControlScript ( int32_t iControl , C4ID idControlExtraData , ControlState state , const C4KeyEventData & rKeyExtraData , bool fRepeated ) ;
2009-05-26 06:10:38 +00:00
2010-03-28 17:58:21 +00:00
// init
void AddKeyBinding ( const C4KeyCodeEx & key , bool fHoldKey , int32_t idx ) ;
2009-05-26 06:10:38 +00:00
2010-04-10 20:44:00 +00:00
// helper function: get current cursor position of controlling player in GUI coordinates
// used e.g. to open menus at cursor pos
2011-11-20 20:49:38 +00:00
bool GetCurrentPlayerCursorPos ( int32_t * x_out , int32_t * y_out , int32_t * game_x_out , int32_t * game_y_out ) ;
2010-04-10 20:44:00 +00:00
2010-03-28 17:58:21 +00:00
public :
C4PlayerControl ( ) ;
~ C4PlayerControl ( ) { Clear ( ) ; }
void Clear ( ) ;
2009-05-28 00:14:54 +00:00
2010-03-28 17:58:21 +00:00
// first-time init call after player join
// not called again after control set change/savegame resume
// does DefaultDisabled controls
void Init ( ) ;
2009-10-17 15:53:26 +00:00
2010-03-28 17:58:21 +00:00
void CompileFunc ( StdCompiler * pComp ) ;
2009-12-27 18:11:14 +00:00
2010-03-28 17:58:21 +00:00
void RegisterKeyset ( int32_t iPlr , C4PlayerControlAssignmentSet * pKeyset ) ; // register all keys into Game.KeyboardInput creating KeyBindings
2009-12-27 18:11:14 +00:00
2010-03-28 17:58:21 +00:00
bool IsGlobal ( ) const { return iPlr = = - 1 ; }
const CSync : : ControlDownState * GetControlDownState ( int32_t iControl ) const
{ return Sync . GetControlDownState ( iControl ) ; }
2010-03-26 13:48:28 +00:00
2010-03-28 17:58:21 +00:00
// callback from control queue
void ExecuteControlPacket ( const class C4ControlPlayerControl * pCtrl ) ;
// sync execution: Do keyrepeat, etc.
void Execute ( ) ;
// mouse input
bool DoMouseInput ( uint8_t mouse_id , int32_t mouseevent , float game_x , float game_y , float gui_x , float gui_y , bool is_ctrl_down , bool is_shift_down , bool is_alt_down , int wheel_dir ) ;
// control enable/disable
bool SetControlDisabled ( int ctrl , bool is_disabled ) { return Sync . SetControlDisabled ( ctrl , is_disabled ) ; }
bool IsControlDisabled ( int ctrl ) const { return Sync . IsControlDisabled ( ctrl ) ; }
2010-05-07 13:57:56 +00:00
// callback from C4GameControl when the next control packet is finalized
void PrepareInput ( ) ;
2010-03-28 17:58:21 +00:00
} ;
2009-05-25 09:01:26 +00:00
2010-01-25 04:00:59 +00:00
# endif // INC_C4PlayerControl