Input bindings rewrite

- moved input bindings to CRobotMain
- added virtual keymod and joystick button key presses
- fixed putenv error; other minor fixes
dev-ui
Piotr Dziwinski 2012-09-19 18:32:18 +02:00
parent 4a639cf543
commit 51884cef8e
15 changed files with 397 additions and 348 deletions

View File

@ -23,6 +23,7 @@
#include "common/logger.h" #include "common/logger.h"
#include "common/iman.h" #include "common/iman.h"
#include "common/image.h" #include "common/image.h"
#include "common/key.h"
#include "graphics/opengl/gldevice.h" #include "graphics/opengl/gldevice.h"
#include "object/robotmain.h" #include "object/robotmain.h"
@ -38,6 +39,9 @@
template<> CApplication* CSingleton<CApplication>::mInstance = nullptr; template<> CApplication* CSingleton<CApplication>::mInstance = nullptr;
//! Static buffer for putenv locale
static char S_LANGUAGE[50] = { 0 };
//! Interval of timer called to update joystick state //! Interval of timer called to update joystick state
const int JOYSTICK_TIMER_INTERVAL = 1000/30; const int JOYSTICK_TIMER_INTERVAL = 1000/30;
@ -114,9 +118,7 @@ CApplication::CApplication()
m_kmodState = 0; m_kmodState = 0;
m_mouseButtonsState = 0; m_mouseButtonsState = 0;
m_trackedKeys = 0;
for (int i = 0; i < TRKEY_MAX; ++i)
m_trackedKeysState[i] = false;
m_keyMotion = Math::Vector(0.0f, 0.0f, 0.0f); m_keyMotion = Math::Vector(0.0f, 0.0f, 0.0f);
m_joyMotion = Math::Vector(0.0f, 0.0f, 0.0f); m_joyMotion = Math::Vector(0.0f, 0.0f, 0.0f);
@ -124,8 +126,6 @@ CApplication::CApplication()
m_dataPath = "./data"; m_dataPath = "./data";
m_language = LANG_ENGLISH; m_language = LANG_ENGLISH;
SetDefaultInputBindings();
} }
CApplication::~CApplication() CApplication::~CApplication()
@ -261,7 +261,6 @@ bool CApplication::Create()
/* Gettext initialization */ /* Gettext initialization */
m_locale = "LANGUAGE=";
std::string locale = "C"; std::string locale = "C";
switch (m_language) switch (m_language)
{ {
@ -282,8 +281,10 @@ bool CApplication::Create()
break; break;
} }
m_locale += locale; std::string langStr = "LANGUAGE=";
putenv(m_locale.c_str()); langStr += locale;
strcpy(S_LANGUAGE, langStr.c_str());
putenv(S_LANGUAGE);
setlocale(LC_ALL, locale.c_str()); setlocale(LC_ALL, locale.c_str());
std::string trPath = m_dataPath + std::string("/i18n"); std::string trPath = m_dataPath + std::string("/i18n");
@ -704,6 +705,18 @@ int CApplication::Run()
if (passOn) if (passOn)
m_eventQueue->AddEvent(event); m_eventQueue->AddEvent(event);
} }
Event virtualEvent = CreateVirtualEvent(event);
if (virtualEvent.type != EVENT_NULL)
{
bool passOn = ProcessEvent(virtualEvent);
if (m_engine != nullptr && passOn)
passOn = m_engine->ProcessEvent(virtualEvent);
if (passOn)
m_eventQueue->AddEvent(virtualEvent);
}
} }
} }
@ -788,6 +801,7 @@ Event CApplication::ParseEvent()
else else
event.type = EVENT_KEY_UP; event.type = EVENT_KEY_UP;
event.key.virt = false;
event.key.key = m_private->currentEvent.key.keysym.sym; event.key.key = m_private->currentEvent.key.keysym.sym;
event.key.mod = m_private->currentEvent.key.keysym.mod; event.key.mod = m_private->currentEvent.key.keysym.mod;
event.key.state = TranslatePressState(m_private->currentEvent.key.state); event.key.state = TranslatePressState(m_private->currentEvent.key.state);
@ -849,13 +863,23 @@ Event CApplication::ParseEvent()
return event; return event;
} }
/** Processes incoming events. It is the first function called after an event is captures. /**
Function returns \c true if the event is to be passed on to other processing functions * Processes incoming events. It is the first function called after an event is captured.
or \c false if not. */ * Event is modified, updating its tracked keys state and mouse position to current values.
bool CApplication::ProcessEvent(const Event &event) * Function returns \c true if the event is to be passed on to other processing functions
* or \c false if not. */
bool CApplication::ProcessEvent(Event &event)
{ {
CLogger *l = GetLogger(); CLogger *l = GetLogger();
event.trackedKeys = m_trackedKeys;
if (GetSystemMouseVisibile())
event.mousePos = m_systemMousePos;
else
event.mousePos = m_engine->GetMousePos();
// TODO: mouse pos
if (event.type == EVENT_ACTIVE) if (event.type == EVENT_ACTIVE)
{ {
if (m_debugMode) if (m_debugMode)
@ -876,50 +900,50 @@ bool CApplication::ProcessEvent(const Event &event)
m_kmodState = event.key.mod; m_kmodState = event.key.mod;
if ((m_kmodState & KEY_MOD(SHIFT)) != 0) if ((m_kmodState & KEY_MOD(SHIFT)) != 0)
m_trackedKeysState[TRKEY_SHIFT] = true; m_trackedKeys |= TRKEY_SHIFT;
else if ((m_kmodState & KEY_MOD(CTRL)) != 0) else if ((m_kmodState & KEY_MOD(CTRL)) != 0)
m_trackedKeysState[TRKEY_CONTROL] = true; m_trackedKeys |= TRKEY_CONTROL;
else if (event.key.key == KEY(KP8)) else if (event.key.key == KEY(KP8))
m_trackedKeysState[TRKEY_NUM_UP] = true; m_trackedKeys |= TRKEY_NUM_UP;
else if (event.key.key == KEY(KP2)) else if (event.key.key == KEY(KP2))
m_trackedKeysState[TRKEY_NUM_DOWN] = true; m_trackedKeys |= TRKEY_NUM_DOWN;
else if (event.key.key == KEY(KP4)) else if (event.key.key == KEY(KP4))
m_trackedKeysState[TRKEY_NUM_LEFT] = true; m_trackedKeys |= TRKEY_NUM_LEFT;
else if (event.key.key == KEY(KP6)) else if (event.key.key == KEY(KP6))
m_trackedKeysState[TRKEY_NUM_RIGHT] = true; m_trackedKeys |= TRKEY_NUM_RIGHT;
else if (event.key.key == KEY(KP_PLUS)) else if (event.key.key == KEY(KP_PLUS))
m_trackedKeysState[TRKEY_NUM_PLUS] = true; m_trackedKeys |= TRKEY_NUM_PLUS;
else if (event.key.key == KEY(KP_MINUS)) else if (event.key.key == KEY(KP_MINUS))
m_trackedKeysState[TRKEY_NUM_MINUS] = true; m_trackedKeys |= TRKEY_NUM_MINUS;
else if (event.key.key == KEY(PAGEUP)) else if (event.key.key == KEY(PAGEUP))
m_trackedKeysState[TRKEY_PAGE_UP] = true; m_trackedKeys |= TRKEY_PAGE_UP;
else if (event.key.key == KEY(PAGEDOWN)) else if (event.key.key == KEY(PAGEDOWN))
m_trackedKeysState[TRKEY_PAGE_DOWN] = true; m_trackedKeys |= TRKEY_PAGE_DOWN;
} }
else if (event.type == EVENT_KEY_UP) else if (event.type == EVENT_KEY_UP)
{ {
m_kmodState = event.key.mod; m_kmodState = event.key.mod;
if ((m_kmodState & KEY_MOD(SHIFT)) != 0) if ((m_kmodState & KEY_MOD(SHIFT)) != 0)
m_trackedKeysState[TRKEY_SHIFT] = false; m_trackedKeys &= ~TRKEY_SHIFT;
else if ((m_kmodState & KEY_MOD(CTRL)) != 0) else if ((m_kmodState & KEY_MOD(CTRL)) != 0)
m_trackedKeysState[TRKEY_CONTROL] = false; m_trackedKeys &= ~TRKEY_CONTROL;
else if (event.key.key == KEY(KP8)) else if (event.key.key == KEY(KP8))
m_trackedKeysState[TRKEY_NUM_UP] = false; m_trackedKeys &= ~TRKEY_NUM_UP;
else if (event.key.key == KEY(KP2)) else if (event.key.key == KEY(KP2))
m_trackedKeysState[TRKEY_NUM_DOWN] = false; m_trackedKeys &= ~TRKEY_NUM_DOWN;
else if (event.key.key == KEY(KP4)) else if (event.key.key == KEY(KP4))
m_trackedKeysState[TRKEY_NUM_LEFT] = false; m_trackedKeys &= ~TRKEY_NUM_LEFT;
else if (event.key.key == KEY(KP6)) else if (event.key.key == KEY(KP6))
m_trackedKeysState[TRKEY_NUM_RIGHT] = false; m_trackedKeys &= ~TRKEY_NUM_RIGHT;
else if (event.key.key == KEY(KP_PLUS)) else if (event.key.key == KEY(KP_PLUS))
m_trackedKeysState[TRKEY_NUM_PLUS] = false; m_trackedKeys &= ~TRKEY_NUM_PLUS;
else if (event.key.key == KEY(KP_MINUS)) else if (event.key.key == KEY(KP_MINUS))
m_trackedKeysState[TRKEY_NUM_MINUS] = false; m_trackedKeys &= ~TRKEY_NUM_MINUS;
else if (event.key.key == KEY(PAGEUP)) else if (event.key.key == KEY(PAGEUP))
m_trackedKeysState[TRKEY_PAGE_UP] = false; m_trackedKeys &= ~TRKEY_PAGE_UP;
else if (event.key.key == KEY(PAGEDOWN)) else if (event.key.key == KEY(PAGEDOWN))
m_trackedKeysState[TRKEY_PAGE_DOWN] = false; m_trackedKeys &= ~TRKEY_PAGE_DOWN;
} }
else if (event.type == EVENT_MOUSE_BUTTON_DOWN) else if (event.type == EVENT_MOUSE_BUTTON_DOWN)
{ {
@ -938,6 +962,7 @@ bool CApplication::ProcessEvent(const Event &event)
case EVENT_KEY_DOWN: case EVENT_KEY_DOWN:
case EVENT_KEY_UP: case EVENT_KEY_UP:
l->Info("EVENT_KEY_%s:\n", (event.type == EVENT_KEY_DOWN) ? "DOWN" : "UP"); l->Info("EVENT_KEY_%s:\n", (event.type == EVENT_KEY_DOWN) ? "DOWN" : "UP");
l->Info(" virt = %s\n", (event.key.virt) ? "true" : "false");
l->Info(" key = %4x\n", event.key.key); l->Info(" key = %4x\n", event.key.key);
l->Info(" state = %s\n", (event.key.state == STATE_PRESSED) ? "STATE_PRESSED" : "STATE_RELEASED"); l->Info(" state = %s\n", (event.key.state == STATE_PRESSED) ? "STATE_PRESSED" : "STATE_RELEASED");
l->Info(" mod = %4x\n", event.key.mod); l->Info(" mod = %4x\n", event.key.mod);
@ -980,6 +1005,48 @@ bool CApplication::ProcessEvent(const Event &event)
return true; return true;
} }
Event CApplication::CreateVirtualEvent(const Event& sourceEvent)
{
Event virtualEvent;
virtualEvent.systemEvent = true;
if ((sourceEvent.type == EVENT_KEY_DOWN) || (sourceEvent.type == EVENT_KEY_UP))
{
virtualEvent.type = sourceEvent.type;
virtualEvent.key = sourceEvent.key;
virtualEvent.key.virt = true;
if (sourceEvent.key.key == KEY(LCTRL) || sourceEvent.key.key == KEY(RCTRL))
virtualEvent.key.key = VIRTUAL_KMOD(CTRL);
else if (sourceEvent.key.key == KEY(LSHIFT) || sourceEvent.key.key == KEY(RSHIFT))
virtualEvent.key.key = VIRTUAL_KMOD(SHIFT);
else if (sourceEvent.key.key == KEY(LALT) || sourceEvent.key.key == KEY(RALT))
virtualEvent.key.key = VIRTUAL_KMOD(ALT);
else if (sourceEvent.key.key == KEY(LMETA) || sourceEvent.key.key == KEY(RMETA))
virtualEvent.key.key = VIRTUAL_KMOD(META);
else
virtualEvent.type = EVENT_NULL;
}
else if ((sourceEvent.type == EVENT_JOY_BUTTON_DOWN) || (sourceEvent.type == EVENT_JOY_BUTTON_UP))
{
if (sourceEvent.type == EVENT_JOY_BUTTON_DOWN)
virtualEvent.type = EVENT_KEY_DOWN;
else
virtualEvent.type = EVENT_KEY_UP;
virtualEvent.key.virt = true;
virtualEvent.key.key = VIRTUAL_JOY(sourceEvent.joyButton.button);
virtualEvent.key.mod = 0;
virtualEvent.key.unicode = 0;
}
else
{
virtualEvent.type = EVENT_NULL;
}
return virtualEvent;
}
/** Renders the frame and swaps buffers as necessary */ /** Renders the frame and swaps buffers as necessary */
void CApplication::Render() void CApplication::Render()
{ {
@ -1144,41 +1211,6 @@ bool CApplication::GetDebugMode()
return m_debugMode; return m_debugMode;
} }
void CApplication::SetDefaultInputBindings()
{
for (int i = 0; i < KEYRANK_MAX; i++)
m_inputBindings[i].Reset();
m_inputBindings[KEYRANK_LEFT ].key = KEY(LEFT);
m_inputBindings[KEYRANK_RIGHT ].key = KEY(RIGHT);
m_inputBindings[KEYRANK_UP ].key = KEY(UP);
m_inputBindings[KEYRANK_DOWN ].key = KEY(DOWN);
m_inputBindings[KEYRANK_GUP ].kmod = KEY_MOD(SHIFT);
m_inputBindings[KEYRANK_GDOWN ].kmod = KEY_MOD(CTRL);
m_inputBindings[KEYRANK_CAMERA ].key = KEY(SPACE);
m_inputBindings[KEYRANK_CAMERA ].joy = 2;
m_inputBindings[KEYRANK_DESEL ].key = KEY(KP0);
m_inputBindings[KEYRANK_DESEL ].kmod = 6;
m_inputBindings[KEYRANK_ACTION ].key = KEY(RETURN);
m_inputBindings[KEYRANK_ACTION ].joy = 1;
m_inputBindings[KEYRANK_NEAR ].key = KEY(KP_PLUS);
m_inputBindings[KEYRANK_NEAR ].joy = 5;
m_inputBindings[KEYRANK_AWAY ].key = KEY(KP_MINUS);
m_inputBindings[KEYRANK_AWAY ].joy = 4;
m_inputBindings[KEYRANK_NEXT ].key = KEY(TAB);
m_inputBindings[KEYRANK_NEXT ].joy = 3;
m_inputBindings[KEYRANK_HUMAN ].key = KEY(HOME);
m_inputBindings[KEYRANK_HUMAN ].joy = 7;
m_inputBindings[KEYRANK_QUIT ].key = KEY(ESCAPE);
m_inputBindings[KEYRANK_HELP ].key = KEY(F1);
m_inputBindings[KEYRANK_PROG ].key = KEY(F2);
m_inputBindings[KEYRANK_CBOT ].key = KEY(F3);
m_inputBindings[KEYRANK_VISIT ].key = KEY(KP_PERIOD);
m_inputBindings[KEYRANK_SPEED10].key = KEY(F4);
m_inputBindings[KEYRANK_SPEED15].key = KEY(F5);
m_inputBindings[KEYRANK_SPEED20].key = KEY(F6);
}
int CApplication::GetKmods() int CApplication::GetKmods()
{ {
return m_kmodState; return m_kmodState;
@ -1191,7 +1223,7 @@ bool CApplication::GetKmodState(int kmod)
bool CApplication::GetTrackedKeyState(TrackedKey key) bool CApplication::GetTrackedKeyState(TrackedKey key)
{ {
return m_trackedKeysState[key]; return (m_trackedKeys & key) != 0;
} }
bool CApplication::GetMouseButtonState(int index) bool CApplication::GetMouseButtonState(int index)
@ -1201,24 +1233,12 @@ bool CApplication::GetMouseButtonState(int index)
void CApplication::ResetKeyStates() void CApplication::ResetKeyStates()
{ {
for (int i = 0; i < TRKEY_MAX; ++i) m_trackedKeys = 0;
m_trackedKeysState[i] = false;
m_kmodState = 0; m_kmodState = 0;
m_keyMotion = Math::Vector(0.0f, 0.0f, 0.0f); m_keyMotion = Math::Vector(0.0f, 0.0f, 0.0f);
m_joyMotion = Math::Vector(0.0f, 0.0f, 0.0f); m_joyMotion = Math::Vector(0.0f, 0.0f, 0.0f);
} }
void CApplication::SetInputBinding(InputSlot slot, const InputBinding& binding)
{
m_inputBindings[slot] = binding;
}
const InputBinding& CApplication::GetInputBinding(InputSlot slot)
{
return m_inputBindings[slot];
}
void CApplication::SetGrabInput(bool grab) void CApplication::SetGrabInput(bool grab)
{ {
SDL_WM_GrabInput(grab ? SDL_GRAB_ON : SDL_GRAB_OFF); SDL_WM_GrabInput(grab ? SDL_GRAB_ON : SDL_GRAB_OFF);

View File

@ -75,75 +75,16 @@ enum VideoQueryResult
*/ */
enum TrackedKey enum TrackedKey
{ {
TRKEY_SHIFT, TRKEY_SHIFT = (1<<0),
TRKEY_CONTROL, TRKEY_CONTROL = (1<<1),
TRKEY_NUM_UP, TRKEY_NUM_UP = (1<<2),
TRKEY_NUM_DOWN, TRKEY_NUM_DOWN = (1<<3),
TRKEY_NUM_LEFT, TRKEY_NUM_LEFT = (1<<4),
TRKEY_NUM_RIGHT, TRKEY_NUM_RIGHT = (1<<5),
TRKEY_NUM_PLUS, TRKEY_NUM_PLUS = (1<<6),
TRKEY_NUM_MINUS, TRKEY_NUM_MINUS = (1<<7),
TRKEY_PAGE_UP, TRKEY_PAGE_UP = (1<<8),
TRKEY_PAGE_DOWN, TRKEY_PAGE_DOWN = (1<<9)
TRKEY_MAX
};
/**
* \enum InputSlot
* \brief Available slots for input bindings
*/
enum InputSlot
{
INPUT_SLOT_LEFT = 0,
INPUT_SLOT_RIGHT = 1,
INPUT_SLOT_UP = 2,
INPUT_SLOT_DOWN = 3,
INPUT_SLOT_GUP = 4,
INPUT_SLOT_GDOWN = 5,
INPUT_SLOT_CAMERA = 6,
INPUT_SLOT_DESEL = 7,
INPUT_SLOT_ACTION = 8,
INPUT_SLOT_NEAR = 9,
INPUT_SLOT_AWAY = 10,
INPUT_SLOT_NEXT = 11,
INPUT_SLOT_HUMAN = 12,
INPUT_SLOT_QUIT = 13,
INPUT_SLOT_HELP = 14,
INPUT_SLOT_PROG = 15,
INPUT_SLOT_VISIT = 16,
INPUT_SLOT_SPEED10 = 17,
INPUT_SLOT_SPEED15 = 18,
INPUT_SLOT_SPEED20 = 19,
INPUT_SLOT_SPEED30 = 20,
INPUT_SLOT_AIMUP = 21,
INPUT_SLOT_AIMDOWN = 22,
INPUT_SLOT_CBOT = 23,
INPUT_SLOT_MAX
};
/**
* \struct InputBinding
* \brief Settable binding for user input
*/
struct InputBinding
{
//! Key
unsigned int key;
//! Key modifier (e.g. shift, control)
unsigned int kmod;
//! Joystick button
unsigned int joy;
inline InputBinding()
{
Reset();
}
inline void Reset()
{
key = kmod = joy = static_cast<unsigned int>(-1);
}
}; };
/** /**
@ -303,19 +244,6 @@ public:
//! Resets tracked key states, modifiers and motion vectors //! Resets tracked key states, modifiers and motion vectors
void ResetKeyStates(); void ResetKeyStates();
// TODO move input binding and motion vectors to CRobotMain
//! Sets the default input bindings
void SetDefaultInputBindings();
//! Management of input bindings
//@{
void SetInputBinding(InputSlot slot, const InputBinding& binding);
const InputBinding& GetInputBinding(InputSlot slot);
//@}
//! Management of the grab mode for input (keyboard & mouse) //! Management of the grab mode for input (keyboard & mouse)
//@{ //@{
void SetGrabInput(bool grab); void SetGrabInput(bool grab);
@ -355,8 +283,10 @@ protected:
//! Processes the captured SDL event to Event struct //! Processes the captured SDL event to Event struct
Event ParseEvent(); Event ParseEvent();
//! If applicable, creates a virtual event to match the changed state as of new event
Event CreateVirtualEvent(const Event& sourceEvent);
//! Handles some incoming events //! Handles some incoming events
bool ProcessEvent(const Event &event); bool ProcessEvent(Event &event);
//! Renders the image in window //! Renders the image in window
void Render(); void Render();
@ -423,13 +353,10 @@ protected:
//! Current state of key modifiers (mask of SDLMod) //! Current state of key modifiers (mask of SDLMod)
unsigned int m_kmodState; unsigned int m_kmodState;
//! Current state of some tracked keys (mask of TrackedKey) //! Current state of some tracked keys (mask of TrackedKey)
bool m_trackedKeysState[TRKEY_MAX]; unsigned int m_trackedKeys;
//! Current state of mouse buttons (mask of button indexes) //! Current state of mouse buttons (mask of button indexes)
unsigned int m_mouseButtonsState; unsigned int m_mouseButtonsState;
//! Bindings for user inputs
InputBinding m_inputBindings[INPUT_SLOT_MAX];
//! Motion vector set by keyboard //! Motion vector set by keyboard
Math::Vector m_keyMotion; Math::Vector m_keyMotion;
//! Motion vector set by joystick //! Motion vector set by joystick
@ -452,9 +379,5 @@ protected:
//! Application language //! Application language
Language m_language; Language m_language;
private:
//! Set locale, needed for putenv/setenv
std::string m_locale;
}; };

View File

@ -44,7 +44,9 @@ struct KeyEventData
{ {
//! STATE_PRESSED or STATE_RELEASED */ //! STATE_PRESSED or STATE_RELEASED */
PressState state; PressState state;
//! Key symbol: KEY(...) macro value (from common/key.h) //! If true, the key is a virtual code generated by key modifier press or joystick button press
bool virt;
//! Key symbol: KEY(...) macro value or virtual key VIRTUAL_... (from common/key.h)
unsigned int key; unsigned int key;
//! Keyboard modifiers: a bitmask made of KEY_MOD(...) macro values (from common/key.h) //! Keyboard modifiers: a bitmask made of KEY_MOD(...) macro values (from common/key.h)
unsigned int mod; unsigned int mod;
@ -52,7 +54,7 @@ struct KeyEventData
unsigned int unicode; unsigned int unicode;
KeyEventData() KeyEventData()
: state(STATE_PRESSED), key(0), mod(0), unicode(0) {} : state(STATE_PRESSED), virt(false), key(0), mod(0), unicode(0) {}
}; };
/** \struct MouseMotionEventData /** \struct MouseMotionEventData
@ -60,7 +62,7 @@ struct KeyEventData
struct MouseMoveEventData struct MouseMoveEventData
{ {
//! Current button state //! Current button state
unsigned char state; PressState state;
//! Position of mouse in normalized coordinates (0..1) //! Position of mouse in normalized coordinates (0..1)
Math::Point pos; Math::Point pos;
@ -171,17 +173,25 @@ struct Event
ActiveEventData active; ActiveEventData active;
}; };
//! State of tracked keys (mask of TrackedKey enum values)
unsigned int trackedKeys;
//! Mouse position is provided also for other types of events besides mouse events
Math::Point mousePos;
// TODO: remove and replace references with trackedKeys
short keyState;
// TODO: remove and replace references with mousePos
Math::Point pos;
// TODO: remove // TODO: remove
long param; // parameter long param; // parameter
// TODO: remove?
Math::Point pos; // mouse position (0 .. 1)
// TODO: ? // TODO: ?
float axeX; // control the X axis (-1 .. 1) float axeX; // control the X axis (-1 .. 1)
float axeY; // control of the Y axis (-1 .. 1) float axeY; // control of the Y axis (-1 .. 1)
float axeZ; // control the Z axis (-1 .. 1) float axeZ; // control the Z axis (-1 .. 1)
short keyState; // state of the keyboard (KS_ *)
// TODO: remove in longer term (use CApplication's new time functions instead) // TODO: remove in longer term (use CApplication's new time functions instead)
float rTime; // relative time float rTime; // relative time
@ -190,10 +200,10 @@ struct Event
{ {
type = aType; type = aType;
systemEvent = false; systemEvent = false;
trackedKeys = 0;
param = 0; param = 0;
axeX = axeY = axeZ = 0.0f; axeX = axeY = axeZ = 0.0f;
keyState = 0;
rTime = 0.0f; rTime = 0.0f;
} }
}; };

View File

@ -82,38 +82,37 @@ enum ResearchType
}; };
/** /**
* \enum KeyRank * \enum InputSlot
* \brief Slots for key assignment of user controls * \brief Available slots for input bindings
*/ */
// TODO: remove (use the new InputSlot enum from app/app.h) enum InputSlot
enum KeyRank
{ {
KEYRANK_LEFT = 0, INPUT_SLOT_LEFT = 0,
KEYRANK_RIGHT = 1, INPUT_SLOT_RIGHT = 1,
KEYRANK_UP = 2, INPUT_SLOT_UP = 2,
KEYRANK_DOWN = 3, INPUT_SLOT_DOWN = 3,
KEYRANK_GUP = 4, INPUT_SLOT_GUP = 4,
KEYRANK_GDOWN = 5, INPUT_SLOT_GDOWN = 5,
KEYRANK_CAMERA = 6, INPUT_SLOT_CAMERA = 6,
KEYRANK_DESEL = 7, INPUT_SLOT_DESEL = 7,
KEYRANK_ACTION = 8, INPUT_SLOT_ACTION = 8,
KEYRANK_NEAR = 9, INPUT_SLOT_NEAR = 9,
KEYRANK_AWAY = 10, INPUT_SLOT_AWAY = 10,
KEYRANK_NEXT = 11, INPUT_SLOT_NEXT = 11,
KEYRANK_HUMAN = 12, INPUT_SLOT_HUMAN = 12,
KEYRANK_QUIT = 13, INPUT_SLOT_QUIT = 13,
KEYRANK_HELP = 14, INPUT_SLOT_HELP = 14,
KEYRANK_PROG = 15, INPUT_SLOT_PROG = 15,
KEYRANK_VISIT = 16, INPUT_SLOT_VISIT = 16,
KEYRANK_SPEED10 = 17, INPUT_SLOT_SPEED10 = 17,
KEYRANK_SPEED15 = 18, INPUT_SLOT_SPEED15 = 18,
KEYRANK_SPEED20 = 19, INPUT_SLOT_SPEED20 = 19,
KEYRANK_SPEED30 = 20, INPUT_SLOT_SPEED30 = 20,
KEYRANK_AIMUP = 21, INPUT_SLOT_AIMUP = 21,
KEYRANK_AIMDOWN = 22, INPUT_SLOT_AIMDOWN = 22,
KEYRANK_CBOT = 23, INPUT_SLOT_CBOT = 23,
KEYRANK_MAX INPUT_SLOT_MAX
}; };
// TODO: move to CRobotMain // TODO: move to CRobotMain

View File

@ -33,3 +33,28 @@
// Key modifier defined as concatenation to KMOD_... // Key modifier defined as concatenation to KMOD_...
// If need arises, it can be changed to custom function or anything else // If need arises, it can be changed to custom function or anything else
#define KEY_MOD(x) KMOD_ ## x #define KEY_MOD(x) KMOD_ ## x
/**
* \enum VirtualKmod
* \brief Virtual key codes generated on kmod presses
*
* These are provided here because left and right pair of keys generate different codes.
*/
enum VirtualKmod
{
VIRTUAL_KMOD_CTRL = SDLK_LAST + 100, //! < control (left or right)
VIRTUAL_KMOD_SHIFT = SDLK_LAST + 101, //! < shift (left or right)
VIRTUAL_KMOD_ALT = SDLK_LAST + 102, //! < alt (left or right)
VIRTUAL_KMOD_META = SDLK_LAST + 103 //! < win key (left or right)
};
// Just syntax sugar
// So it is the same as other macros
#define VIRTUAL_KMOD(x) VIRTUAL_KMOD_ ## x
// Virtual key code generated on joystick button presses
// num is number of joystick button
#define VIRTUAL_JOY(num) (SDLK_LAST + 200 + num)
//! Special value for invalid key bindings
const unsigned int KEY_INVALID = SDLK_LAST + 1000;

View File

@ -21,6 +21,7 @@
#include "common/logger.h" #include "common/logger.h"
#include "CBot/resource.h" #include "CBot/resource.h"
#include "object/object.h" #include "object/object.h"
#include "object/robotmain.h"
#include <libintl.h> #include <libintl.h>
#include <SDL/SDL_keyboard.h> #include <SDL/SDL_keyboard.h>
@ -37,39 +38,38 @@ void SetGlobalGamerName(char *name)
struct KeyDesc struct KeyDesc
{ {
KeyRank key; InputSlot key;
char name[20]; char name[20];
}; };
static KeyDesc keyTable[22] = static KeyDesc keyTable[22] =
{ {
{ KEYRANK_LEFT, "left;" }, { INPUT_SLOT_LEFT, "left;" },
{ KEYRANK_RIGHT, "right;" }, { INPUT_SLOT_RIGHT, "right;" },
{ KEYRANK_UP, "up;" }, { INPUT_SLOT_UP, "up;" },
{ KEYRANK_DOWN, "down;" }, { INPUT_SLOT_DOWN, "down;" },
{ KEYRANK_GUP, "gup;" }, { INPUT_SLOT_GUP, "gup;" },
{ KEYRANK_GDOWN, "gdown;" }, { INPUT_SLOT_GDOWN, "gdown;" },
{ KEYRANK_CAMERA, "camera;" }, { INPUT_SLOT_CAMERA, "camera;" },
{ KEYRANK_DESEL, "desel;" }, { INPUT_SLOT_DESEL, "desel;" },
{ KEYRANK_ACTION, "action;" }, { INPUT_SLOT_ACTION, "action;" },
{ KEYRANK_NEAR, "near;" }, { INPUT_SLOT_NEAR, "near;" },
{ KEYRANK_AWAY, "away;" }, { INPUT_SLOT_AWAY, "away;" },
{ KEYRANK_NEXT, "next;" }, { INPUT_SLOT_NEXT, "next;" },
{ KEYRANK_HUMAN, "human;" }, { INPUT_SLOT_HUMAN, "human;" },
{ KEYRANK_QUIT, "quit;" }, { INPUT_SLOT_QUIT, "quit;" },
{ KEYRANK_HELP, "help;" }, { INPUT_SLOT_HELP, "help;" },
{ KEYRANK_PROG, "prog;" }, { INPUT_SLOT_PROG, "prog;" },
{ KEYRANK_CBOT, "cbot;" }, { INPUT_SLOT_CBOT, "cbot;" },
{ KEYRANK_VISIT, "visit;" }, { INPUT_SLOT_VISIT, "visit;" },
{ KEYRANK_SPEED10, "speed10;" }, { INPUT_SLOT_SPEED10, "speed10;" },
{ KEYRANK_SPEED15, "speed15;" }, { INPUT_SLOT_SPEED15, "speed15;" },
{ KEYRANK_SPEED20, "speed20;" }, { INPUT_SLOT_SPEED20, "speed20;" }
{ KEYRANK_SPEED30, "speed30;" },
}; };
// Seeks a key. // Seeks a key.
bool SearchKey(const char *cmd, KeyRank &key) bool SearchKey(const char *cmd, InputSlot &key)
{ {
int i; int i;
@ -88,9 +88,10 @@ bool SearchKey(const char *cmd, KeyRank &key)
static void PutKeyName(char* dst, const char* src) static void PutKeyName(char* dst, const char* src)
{ {
KeyRank key; InputSlot key;
char name[50]; char name[50];
int s, d, n, res; int s, d, n;
unsigned int res;
s = d = 0; s = d = 0;
while ( src[s] != 0 ) while ( src[s] != 0 )
@ -103,9 +104,8 @@ static void PutKeyName(char* dst, const char* src)
{ {
if ( SearchKey(src+s+5, key) ) if ( SearchKey(src+s+5, key) )
{ {
// FIXME: res = g_engine->RetKey(key, 0); res = CRobotMain::GetInstancePointer()->GetInputBinding(key).key;
res = 0; if (res != KEY_INVALID)
if ( res != 0 )
{ {
if ( GetResource(RES_KEY, res, name) ) if ( GetResource(RES_KEY, res, name) )
{ {
@ -144,7 +144,7 @@ static const char* GetResourceBase(ResType type, int num)
// assert(num < strings_event_len); // assert(num < strings_event_len);
if (num >= strings_event_len) if (num >= strings_event_len)
{ {
GetLogger()->Error("GetResource invalid event num: %d\n", num); GetLogger()->Warn("GetResource invalid event num: %d\n", num);
return ""; return "";
} }
str = strings_event[num]; str = strings_event[num];
@ -165,6 +165,7 @@ static const char* GetResourceBase(ResType type, int num)
break; break;
case RES_KEY: case RES_KEY:
assert(num < SDLK_LAST); assert(num < SDLK_LAST);
// TODO: virtual keys
str = SDL_GetKeyName(static_cast<SDLKey>(num)); str = SDL_GetKeyName(static_cast<SDLKey>(num));
break; break;
default: default:

View File

@ -43,7 +43,7 @@ enum ResType
// TODO: move to CRobotMain // TODO: move to CRobotMain
extern void SetGlobalGamerName(char *name); extern void SetGlobalGamerName(char *name);
extern bool SearchKey(const char *cmd, KeyRank &key); extern bool SearchKey(const char *cmd, InputSlot& slot);
extern bool GetResource(ResType type, int num, char* text); extern bool GetResource(ResType type, int num, char* text);
extern const char * const strings_text[]; extern const char * const strings_text[];

View File

@ -184,7 +184,6 @@ void Gfx::CGLDevice::BeginScene()
void Gfx::CGLDevice::EndScene() void Gfx::CGLDevice::EndScene()
{ {
glFlush();
} }
void Gfx::CGLDevice::Clear() void Gfx::CGLDevice::Clear()

View File

@ -202,12 +202,9 @@ bool CBrain::EventProcess(const Event &event)
action = EVENT_NULL; action = EVENT_NULL;
CApplication* app = CApplication::GetInstancePointer();
if ( event.type == EVENT_KEY_DOWN && if ( event.type == EVENT_KEY_DOWN &&
(event.key.key == app->GetInputBinding(INPUT_SLOT_ACTION).key (event.key.key == m_main->GetInputBinding(INPUT_SLOT_ACTION).key ||
/* TODO joystick input binding event.key.key == m_main->GetInputBinding(INPUT_SLOT_ACTION).joy ) &&
event.param == app->GetInputBinding(INPUT_SLOT_ACTION).joy*/ ) &&
!m_main->GetEditLock() ) !m_main->GetEditLock() )
{ {
pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0));

View File

@ -73,6 +73,8 @@
#include "ui/window.h" #include "ui/window.h"
template<> CRobotMain* CSingleton<CRobotMain>::mInstance = nullptr;
// TODO: remove once using std::string // TODO: remove once using std::string
const int MAX_FNAME = 255; const int MAX_FNAME = 255;
@ -811,6 +813,8 @@ CRobotMain::CRobotMain(CInstanceManager* iMan, CApplication* app)
InitClassFILE(); InitClassFILE();
CScript::InitFonctions(); CScript::InitFonctions();
SetDefaultInputBindings();
} }
//! Destructor of robot application //! Destructor of robot application
@ -858,6 +862,56 @@ void CRobotMain::CreateIni()
m_dialog->SetupMemorize();*/ m_dialog->SetupMemorize();*/
} }
void CRobotMain::SetDefaultInputBindings()
{
for (int i = 0; i < INPUT_SLOT_MAX; i++)
{
m_inputBindings[i].key = m_inputBindings[i].joy = KEY_INVALID;
}
m_inputBindings[INPUT_SLOT_LEFT ].key = KEY(LEFT);
m_inputBindings[INPUT_SLOT_RIGHT ].key = KEY(RIGHT);
m_inputBindings[INPUT_SLOT_UP ].key = KEY(UP);
m_inputBindings[INPUT_SLOT_DOWN ].key = KEY(DOWN);
m_inputBindings[INPUT_SLOT_GUP ].key = VIRTUAL_KMOD(SHIFT);
m_inputBindings[INPUT_SLOT_GDOWN ].key = VIRTUAL_KMOD(CTRL);
m_inputBindings[INPUT_SLOT_CAMERA ].key = KEY(SPACE);
m_inputBindings[INPUT_SLOT_CAMERA ].joy = VIRTUAL_JOY(2);
m_inputBindings[INPUT_SLOT_DESEL ].key = KEY(KP0);
m_inputBindings[INPUT_SLOT_DESEL ].joy = VIRTUAL_JOY(6);
m_inputBindings[INPUT_SLOT_ACTION ].key = KEY(RETURN);
m_inputBindings[INPUT_SLOT_ACTION ].joy = VIRTUAL_JOY(1);
m_inputBindings[INPUT_SLOT_NEAR ].key = KEY(KP_PLUS);
m_inputBindings[INPUT_SLOT_NEAR ].joy = VIRTUAL_JOY(5);
m_inputBindings[INPUT_SLOT_AWAY ].key = KEY(KP_MINUS);
m_inputBindings[INPUT_SLOT_AWAY ].joy = VIRTUAL_JOY(4);
m_inputBindings[INPUT_SLOT_NEXT ].key = KEY(TAB);
m_inputBindings[INPUT_SLOT_NEXT ].joy = VIRTUAL_JOY(3);
m_inputBindings[INPUT_SLOT_HUMAN ].key = KEY(HOME);
m_inputBindings[INPUT_SLOT_HUMAN ].joy = VIRTUAL_JOY(7);
m_inputBindings[INPUT_SLOT_QUIT ].key = KEY(ESCAPE);
m_inputBindings[INPUT_SLOT_HELP ].key = KEY(F1);
m_inputBindings[INPUT_SLOT_PROG ].key = KEY(F2);
m_inputBindings[INPUT_SLOT_CBOT ].key = KEY(F3);
m_inputBindings[INPUT_SLOT_VISIT ].key = KEY(KP_PERIOD);
m_inputBindings[INPUT_SLOT_SPEED10].key = KEY(F4);
m_inputBindings[INPUT_SLOT_SPEED15].key = KEY(F5);
m_inputBindings[INPUT_SLOT_SPEED20].key = KEY(F6);
}
void CRobotMain::SetInputBinding(InputSlot slot, InputBinding binding)
{
unsigned int index = static_cast<unsigned int>(slot);
assert(index >= 0 && index < INPUT_SLOT_MAX);
m_inputBindings[index] = binding;
}
const InputBinding& CRobotMain::GetInputBinding(InputSlot slot)
{
unsigned int index = static_cast<unsigned int>(slot);
assert(index >= 0 && index < INPUT_SLOT_MAX);
return m_inputBindings[index];
}
//! Changes phase //! Changes phase
void CRobotMain::ChangePhase(Phase phase) void CRobotMain::ChangePhase(Phase phase)
@ -1109,8 +1163,6 @@ void CRobotMain::ChangePhase(Phase phase)
//! Processes an event //! Processes an event
bool CRobotMain::EventProcess(const Event &event) bool CRobotMain::EventProcess(const Event &event)
{ {
// TODO: rewrite key handling to input bindings
if (event.type == EVENT_FRAME) if (event.type == EVENT_FRAME)
{ {
if (!m_movie->EventProcess(event)) // end of the movie? if (!m_movie->EventProcess(event)) // end of the movie?
@ -1197,10 +1249,10 @@ bool CRobotMain::EventProcess(const Event &event)
if (event.type == EVENT_KEY_DOWN) if (event.type == EVENT_KEY_DOWN)
{ {
if (event.key.key == m_app->GetInputBinding(INPUT_SLOT_HELP).key /* TODO: joystick if (event.key.key == GetInputBinding(INPUT_SLOT_HELP).key ||
|| event.key.key == m_app->GetInputBinding(INPUT_SLOT_HELP).joy */ || event.key.key == GetInputBinding(INPUT_SLOT_HELP).joy ||
event.key.key == m_app->GetInputBinding(INPUT_SLOT_PROG).key /* TODO: joystick event.key.key == GetInputBinding(INPUT_SLOT_PROG).key ||
|| event.key.key == m_app->GetInputBinding(INPUT_SLOT_PROG).joy */ || event.key.key == GetInputBinding(INPUT_SLOT_PROG).joy ||
event.key.key == KEY(ESCAPE)) event.key.key == KEY(ESCAPE))
{ {
StopDisplayInfo(); StopDisplayInfo();
@ -1235,14 +1287,14 @@ bool CRobotMain::EventProcess(const Event &event)
} }
if (m_editLock) // current edition? if (m_editLock) // current edition?
{ {
if (event.key.key == m_app->GetInputBinding(INPUT_SLOT_HELP).key /* TODO: joystick if (event.key.key == GetInputBinding(INPUT_SLOT_HELP).key ||
|| event.key.key == m_app->GetInputBinding(INPUT_SLOT_HELP).joy*/ ) event.key.key == GetInputBinding(INPUT_SLOT_HELP).joy)
{ {
StartDisplayInfo(SATCOM_HUSTON, false); StartDisplayInfo(SATCOM_HUSTON, false);
return false; return false;
} }
if (event.key.key == m_app->GetInputBinding(INPUT_SLOT_PROG).key /* TODO: joystick if (event.key.key == GetInputBinding(INPUT_SLOT_PROG).key ||
|| event.key.key == m_app->GetInputBinding(INPUT_SLOT_PROG).joy*/) event.key.key == GetInputBinding(INPUT_SLOT_PROG).joy)
{ {
StartDisplayInfo(SATCOM_PROG, false); StartDisplayInfo(SATCOM_PROG, false);
return false; return false;
@ -1251,8 +1303,8 @@ bool CRobotMain::EventProcess(const Event &event)
} }
if (m_movieLock) // current movie? if (m_movieLock) // current movie?
{ {
if (event.key.key == m_app->GetInputBinding(INPUT_SLOT_QUIT).key /* TODO: joystick if (event.key.key == GetInputBinding(INPUT_SLOT_QUIT).key ||
|| event.key.key == m_app->GetInputBinding(INPUT_SLOT_QUIT).joy */ || event.key.key == GetInputBinding(INPUT_SLOT_QUIT).joy ||
event.key.key == KEY(ESCAPE)) event.key.key == KEY(ESCAPE))
{ {
AbortMovie(); AbortMovie();
@ -1261,21 +1313,21 @@ bool CRobotMain::EventProcess(const Event &event)
} }
if (m_camera->GetType() == Gfx::CAM_TYPE_VISIT) if (m_camera->GetType() == Gfx::CAM_TYPE_VISIT)
{ {
if (event.key.key == m_app->GetInputBinding(INPUT_SLOT_VISIT).key /* TODO: joystick if (event.key.key == GetInputBinding(INPUT_SLOT_VISIT).key ||
|| event.key.key == m_app->GetInputBinding(INPUT_SLOT_VISIT).joy*/) event.key.key == GetInputBinding(INPUT_SLOT_VISIT).joy)
{ {
StartDisplayVisit(EVENT_NULL); StartDisplayVisit(EVENT_NULL);
} }
if (event.key.key == m_app->GetInputBinding(INPUT_SLOT_QUIT).key /* TODO: joystick if (event.key.key == GetInputBinding(INPUT_SLOT_QUIT).key ||
|| event.key.key == m_app->GetInputBinding(INPUT_SLOT_QUIT).joy */ || event.key.key == GetInputBinding(INPUT_SLOT_QUIT).joy ||
event.key.key == KEY(ESCAPE)) event.key.key == KEY(ESCAPE))
{ {
StopDisplayVisit(); StopDisplayVisit();
} }
return false; return false;
} }
if (event.key.key == m_app->GetInputBinding(INPUT_SLOT_QUIT).key /* TODO: joystick if (event.key.key == GetInputBinding(INPUT_SLOT_QUIT).key ||
|| event.key.key == m_app->GetInputBinding(INPUT_SLOT_QUIT).joy*/) event.key.key == GetInputBinding(INPUT_SLOT_QUIT).joy)
{ {
if (m_movie->IsExist()) if (m_movie->IsExist())
StartDisplayInfo(SATCOM_HUSTON, false); StartDisplayInfo(SATCOM_HUSTON, false);
@ -1295,55 +1347,55 @@ bool CRobotMain::EventProcess(const Event &event)
ChangePause(!m_engine->GetPause()); ChangePause(!m_engine->GetPause());
} }
} }
if (event.key.key == m_app->GetInputBinding(INPUT_SLOT_CAMERA).key /* TODO: joystick if (event.key.key == GetInputBinding(INPUT_SLOT_CAMERA).key ||
|| event.key.key == m_app->GetInputBinding(INPUT_SLOT_CAMERA).joy*/) event.key.key == GetInputBinding(INPUT_SLOT_CAMERA).joy)
{ {
ChangeCamera(); ChangeCamera();
} }
if (event.key.key == m_app->GetInputBinding(INPUT_SLOT_DESEL).key /* TODO: joystick if (event.key.key == GetInputBinding(INPUT_SLOT_DESEL).key ||
|| event.key.key == m_app->GetInputBinding(INPUT_SLOT_DESEL).joy*/) event.key.key == GetInputBinding(INPUT_SLOT_DESEL).joy)
{ {
if (m_shortCut) if (m_shortCut)
DeselectObject(); DeselectObject();
} }
if (event.key.key == m_app->GetInputBinding(INPUT_SLOT_HUMAN).key /* TODO: joystick if (event.key.key == GetInputBinding(INPUT_SLOT_HUMAN).key ||
|| event.key.key == m_app->GetInputBinding(INPUT_SLOT_HUMAN).joy*/) event.key.key == GetInputBinding(INPUT_SLOT_HUMAN).joy)
{ {
SelectHuman(); SelectHuman();
} }
if (event.key.key == m_app->GetInputBinding(INPUT_SLOT_NEXT).key /* TODO: joystick if (event.key.key == GetInputBinding(INPUT_SLOT_NEXT).key ||
|| event.key.key == m_app->GetInputBinding(INPUT_SLOT_NEXT).joy*/) event.key.key == GetInputBinding(INPUT_SLOT_NEXT).joy)
{ {
if (m_shortCut) if (m_shortCut)
m_short->SelectNext(); m_short->SelectNext();
} }
if (event.key.key == m_app->GetInputBinding(INPUT_SLOT_HELP).key /* TODO: joystick if (event.key.key == GetInputBinding(INPUT_SLOT_HELP).key ||
|| event.key.key == m_app->GetInputBinding(INPUT_SLOT_HELP).joy*/) event.key.key == GetInputBinding(INPUT_SLOT_HELP).joy)
{ {
StartDisplayInfo(SATCOM_HUSTON, true); StartDisplayInfo(SATCOM_HUSTON, true);
} }
if (event.key.key == m_app->GetInputBinding(INPUT_SLOT_PROG).key /* TODO: joystick if (event.key.key == GetInputBinding(INPUT_SLOT_PROG).key ||
|| event.key.key == m_app->GetInputBinding(INPUT_SLOT_PROG).joy*/) event.key.key == GetInputBinding(INPUT_SLOT_PROG).joy)
{ {
StartDisplayInfo(SATCOM_PROG, true); StartDisplayInfo(SATCOM_PROG, true);
} }
if (event.key.key == m_app->GetInputBinding(INPUT_SLOT_VISIT).key /* TODO: joystick if (event.key.key == GetInputBinding(INPUT_SLOT_VISIT).key ||
|| event.key.key == m_app->GetInputBinding(INPUT_SLOT_VISIT).joy*/) event.key.key == GetInputBinding(INPUT_SLOT_VISIT).joy)
{ {
StartDisplayVisit(EVENT_NULL); StartDisplayVisit(EVENT_NULL);
} }
if (event.key.key == m_app->GetInputBinding(INPUT_SLOT_SPEED10).key /* TODO: joystick if (event.key.key == GetInputBinding(INPUT_SLOT_SPEED10).key ||
|| event.key.key == m_app->GetInputBinding(INPUT_SLOT_SPEED10).joy*/) event.key.key == GetInputBinding(INPUT_SLOT_SPEED10).joy)
{ {
SetSpeed(1.0f); SetSpeed(1.0f);
} }
if (event.key.key == m_app->GetInputBinding(INPUT_SLOT_SPEED15).key /* TODO: joystick if (event.key.key == GetInputBinding(INPUT_SLOT_SPEED15).key ||
|| event.key.key == m_app->GetInputBinding(INPUT_SLOT_SPEED15).joy*/) event.key.key == GetInputBinding(INPUT_SLOT_SPEED15).joy)
{ {
SetSpeed(1.5f); SetSpeed(1.5f);
} }
if (event.key.key == m_app->GetInputBinding(INPUT_SLOT_SPEED20).key /* TODO: joystick if (event.key.key == GetInputBinding(INPUT_SLOT_SPEED20).key ||
|| event.key.key == m_app->GetInputBinding(INPUT_SLOT_SPEED20).joy*/) event.key.key == GetInputBinding(INPUT_SLOT_SPEED20).joy)
{ {
SetSpeed(2.0f); SetSpeed(2.0f);
} }
@ -2925,26 +2977,26 @@ void CRobotMain::KeyCamera(EventType type, unsigned int key)
if (type == EVENT_KEY_UP) if (type == EVENT_KEY_UP)
{ {
if (key == m_app->GetInputBinding(INPUT_SLOT_LEFT).key /* TODO: joystick if (key == GetInputBinding(INPUT_SLOT_LEFT).key ||
|| key == m_app->GetInputBinding(INPUT_SLOT_LEFT).joy*/) key == GetInputBinding(INPUT_SLOT_LEFT).joy)
{ {
m_cameraPan = 0.0f; m_cameraPan = 0.0f;
} }
if (key == m_app->GetInputBinding(INPUT_SLOT_RIGHT).key /* TODO: joystick if (key == GetInputBinding(INPUT_SLOT_RIGHT).key ||
|| key == m_app->GetInputBinding(INPUT_SLOT_RIGHT).joy*/) key == GetInputBinding(INPUT_SLOT_RIGHT).joy)
{ {
m_cameraPan = 0.0f; m_cameraPan = 0.0f;
} }
if (key == m_app->GetInputBinding(INPUT_SLOT_UP).key /* TODO: joystick if (key == GetInputBinding(INPUT_SLOT_UP).key ||
|| key == m_app->GetInputBinding(INPUT_SLOT_UP).joy*/ ) key == GetInputBinding(INPUT_SLOT_UP).joy)
{ {
m_cameraZoom = 0.0f; m_cameraZoom = 0.0f;
} }
if (key == m_app->GetInputBinding(INPUT_SLOT_DOWN).key /* TODO: joystick if (key == GetInputBinding(INPUT_SLOT_DOWN).key ||
|| key == m_app->GetInputBinding(INPUT_SLOT_DOWN).joy*/ ) key == GetInputBinding(INPUT_SLOT_DOWN).joy)
{ {
m_cameraZoom = 0.0f; m_cameraZoom = 0.0f;
} }
@ -2960,26 +3012,26 @@ void CRobotMain::KeyCamera(EventType type, unsigned int key)
if (type == EVENT_KEY_DOWN) if (type == EVENT_KEY_DOWN)
{ {
if (key == m_app->GetInputBinding(INPUT_SLOT_LEFT).key /* TODO: joystick if (key == GetInputBinding(INPUT_SLOT_LEFT).key ||
|| key == m_app->GetInputBinding(INPUT_SLOT_LEFT).joy*/) key == GetInputBinding(INPUT_SLOT_LEFT).joy)
{ {
m_cameraPan = -1.0f; m_cameraPan = -1.0f;
} }
if (key == m_app->GetInputBinding(INPUT_SLOT_RIGHT).key /* TODO: joystick if (key == GetInputBinding(INPUT_SLOT_RIGHT).key ||
|| key == m_app->GetInputBinding(INPUT_SLOT_RIGHT).joy*/) key == GetInputBinding(INPUT_SLOT_RIGHT).joy)
{ {
m_cameraPan = 1.0f; m_cameraPan = 1.0f;
} }
if (key == m_app->GetInputBinding(INPUT_SLOT_UP).key /* TODO: joystick if (key == GetInputBinding(INPUT_SLOT_UP).key ||
|| key == m_app->GetInputBinding(INPUT_SLOT_UP).joy*/) key == GetInputBinding(INPUT_SLOT_UP).joy)
{ {
m_cameraZoom = -1.0f; m_cameraZoom = -1.0f;
} }
if (key == m_app->GetInputBinding(INPUT_SLOT_DOWN).key /* TODO: joystick if (key == GetInputBinding(INPUT_SLOT_DOWN).key ||
|| key == m_app->GetInputBinding(INPUT_SLOT_DOWN).joy*/) key == GetInputBinding(INPUT_SLOT_DOWN).joy)
{ {
m_cameraZoom = 1.0f; m_cameraZoom = 1.0f;
} }

View File

@ -19,8 +19,10 @@
#pragma once #pragma once
#include "common/global.h" #include "common/global.h"
#include "common/misc.h" #include "common/singleton.h"
#include "graphics/engine/particle.h" #include "graphics/engine/particle.h"
#include "object/object.h" #include "object/object.h"
#include "object/mainmovie.h" #include "object/mainmovie.h"
@ -140,8 +142,22 @@ const int SATCOM_SOLUCE = 5;
const int SATCOM_MAX = 6; const int SATCOM_MAX = 6;
/**
* \enum InputBinding
* \brief Binding for input slot
*/
struct InputBinding
{
//! Keyboard binding code (can be regular or virtual)
unsigned int key;
//! Joystick binding code (virtual)
unsigned int joy;
class CRobotMain InputBinding() : key(KEY_INVALID), joy(KEY_INVALID) {}
};
class CRobotMain : public CSingleton<CRobotMain>
{ {
public: public:
CRobotMain(CInstanceManager* iMan, CApplication* app); CRobotMain(CInstanceManager* iMan, CApplication* app);
@ -149,6 +165,15 @@ public:
void CreateIni(); void CreateIni();
//! Sets the default input bindings
void SetDefaultInputBindings();
//! Management of input bindings
//@{
void SetInputBinding(InputSlot slot, InputBinding binding);
const InputBinding& GetInputBinding(InputSlot slot);
//@}
void ChangePhase(Phase phase); void ChangePhase(Phase phase);
bool EventProcess(const Event &event); bool EventProcess(const Event &event);
@ -352,6 +377,9 @@ protected:
Ui::CDisplayInfo* m_displayInfo; Ui::CDisplayInfo* m_displayInfo;
CSoundInterface* m_sound; CSoundInterface* m_sound;
//! Bindings for user inputs
InputBinding m_inputBindings[INPUT_SLOT_MAX];
float m_time; float m_time;
float m_gameTime; float m_gameTime;
float m_checkEndTime; float m_checkEndTime;

View File

@ -82,7 +82,6 @@ CEdit::CEdit () : CControl ()
m_text = new char[m_maxChar+1]; m_text = new char[m_maxChar+1];
memset(m_text, 0, m_maxChar+1); memset(m_text, 0, m_maxChar+1);
m_len = 0; m_len = 0;
m_app = CApplication::GetInstancePointer();
memset(m_lineOffset, 0, sizeof(int) * EDITLINEMAX); memset(m_lineOffset, 0, sizeof(int) * EDITLINEMAX);
@ -1465,7 +1464,7 @@ bool CEdit::ReadText(const char *filename, int addSize)
char iName[50]; char iName[50];
char text[50]; char text[50];
float iWidth; float iWidth;
KeyRank key; InputSlot slot;
bool bInSoluce, bBOL; bool bInSoluce, bBOL;
if ( filename[0] == 0 ) return false; if ( filename[0] == 0 ) return false;
@ -1795,10 +1794,10 @@ bool CEdit::ReadText(const char *filename, int addSize)
{ {
if ( m_bSoluce || !bInSoluce ) if ( m_bSoluce || !bInSoluce )
{ {
if ( SearchKey(buffer+i+5, key) ) if ( SearchKey(buffer+i+5, slot) )
{ {
res = 0; CRobotMain* main = CRobotMain::GetInstancePointer();
//res = m_app->GetInputBinding(key).key; // TODO input bindings res = main->GetInputBinding(slot).key;
if ( res != 0 ) if ( res != 0 )
{ {
if ( GetResource(RES_KEY, res, iName) ) if ( GetResource(RES_KEY, res, iName) )
@ -1817,8 +1816,7 @@ bool CEdit::ReadText(const char *filename, int addSize)
m_format[j] = font; m_format[j] = font;
j ++; j ++;
// res = m_app->GetInputBinding(key).joy; // TODO input bindings res = main->GetInputBinding(slot).joy;
res = 0;
if ( res != 0 ) if ( res != 0 )
{ {
if ( GetResource(RES_KEY, res, iName) ) if ( GetResource(RES_KEY, res, iName) )

View File

@ -35,8 +35,6 @@
#include "common/iman.h" #include "common/iman.h"
#include "common/restext.h" #include "common/restext.h"
#include "app/app.h"
#include <vector> #include <vector>
@ -246,7 +244,6 @@ protected:
int m_len; // length used in m_text int m_len; // length used in m_text
int m_cursor1; // offset cursor int m_cursor1; // offset cursor
int m_cursor2; // offset cursor int m_cursor2; // offset cursor
CApplication *m_app;
bool m_bMulti; // true -> multi-line bool m_bMulti; // true -> multi-line
bool m_bEdit; // true -> editable bool m_bEdit; // true -> editable

View File

@ -5956,41 +5956,41 @@ void CMainDialog::ChangeSetupQuality(int quality)
static int key_table[KEY_TOTAL] = static int key_table[KEY_TOTAL] =
{ {
/* TODO: #if _SCHOOL & _TEEN /* TODO: #if _SCHOOL & _TEEN
KEYRANK_LEFT, INPUT_SLOT_LEFT,
KEYRANK_RIGHT, INPUT_SLOT_RIGHT,
KEYRANK_UP, INPUT_SLOT_UP,
KEYRANK_DOWN, INPUT_SLOT_DOWN,
KEYRANK_CAMERA, INPUT_SLOT_CAMERA,
KEYRANK_NEAR, INPUT_SLOT_NEAR,
KEYRANK_AWAY, INPUT_SLOT_AWAY,
KEYRANK_HELP, INPUT_SLOT_HELP,
KEYRANK_PROG, INPUT_SLOT_PROG,
KEYRANK_SPEED10, INPUT_SLOT_SPEED10,
KEYRANK_SPEED15, INPUT_SLOT_SPEED15,
KEYRANK_SPEED20, INPUT_SLOT_SPEED20,
KEYRANK_QUIT, INPUT_SLOT_QUIT,
#else */ #else */
KEYRANK_LEFT, INPUT_SLOT_LEFT,
KEYRANK_RIGHT, INPUT_SLOT_RIGHT,
KEYRANK_UP, INPUT_SLOT_UP,
KEYRANK_DOWN, INPUT_SLOT_DOWN,
KEYRANK_GUP, INPUT_SLOT_GUP,
KEYRANK_GDOWN, INPUT_SLOT_GDOWN,
KEYRANK_ACTION, INPUT_SLOT_ACTION,
KEYRANK_CAMERA, INPUT_SLOT_CAMERA,
KEYRANK_VISIT, INPUT_SLOT_VISIT,
KEYRANK_NEXT, INPUT_SLOT_NEXT,
KEYRANK_HUMAN, INPUT_SLOT_HUMAN,
KEYRANK_DESEL, INPUT_SLOT_DESEL,
KEYRANK_NEAR, INPUT_SLOT_NEAR,
KEYRANK_AWAY, INPUT_SLOT_AWAY,
KEYRANK_HELP, INPUT_SLOT_HELP,
KEYRANK_PROG, INPUT_SLOT_PROG,
KEYRANK_CBOT, INPUT_SLOT_CBOT,
KEYRANK_SPEED10, INPUT_SLOT_SPEED10,
KEYRANK_SPEED15, INPUT_SLOT_SPEED15,
KEYRANK_SPEED20, INPUT_SLOT_SPEED20,
KEYRANK_QUIT, INPUT_SLOT_QUIT,
// #endif // #endif
}; };

View File

@ -241,8 +241,8 @@ bool CStudio::EventProcess(const Event &event)
if ( event.type == EVENT_KEY_DOWN ) if ( event.type == EVENT_KEY_DOWN )
{ {
if ( event.key.key == m_app->GetInputBinding(INPUT_SLOT_CBOT).key // || if ( event.key.key == m_main->GetInputBinding(INPUT_SLOT_CBOT).key ||
/*TODO event.param == m_app->GetKey(KEYRANK_CBOT, 1)*/ ) event.param == m_main->GetInputBinding(INPUT_SLOT_CBOT).joy )
{ {
if ( m_helpFilename.length() > 0 ) if ( m_helpFilename.length() > 0 )
{ {