2010-04-05 23:38:59 +02:00
|
|
|
#include "ControllerBase.h"
|
|
|
|
|
|
|
|
#include "ModelBase.h"
|
|
|
|
#include "ViewBase.h"
|
|
|
|
#include "CommandsGlobal.h"
|
|
|
|
|
|
|
|
#include "keytable.h"
|
|
|
|
|
|
|
|
namespace Engine {
|
|
|
|
|
|
|
|
static ControllerBase *ControllerInstance = NULL;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Helper functions
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** \brief Converts the SDL_BUTTON_* to a value we know */
|
|
|
|
MouseButton convert_sdl_button (Uint8 button) {
|
|
|
|
MouseButton mouse_button;
|
|
|
|
switch (button) {
|
|
|
|
case SDL_BUTTON_LEFT:
|
|
|
|
mouse_button = MouseButtonLeft;
|
|
|
|
break;
|
|
|
|
case SDL_BUTTON_MIDDLE:
|
|
|
|
mouse_button = MouseButtonMiddle;
|
|
|
|
break;
|
|
|
|
case SDL_BUTTON_RIGHT:
|
|
|
|
mouse_button = MouseButtonRight;
|
|
|
|
break;
|
|
|
|
case SDL_BUTTON_WHEELUP:
|
|
|
|
mouse_button = MouseButtonWheelUp;
|
|
|
|
break;
|
|
|
|
case SDL_BUTTON_WHEELDOWN:
|
|
|
|
mouse_button = MouseButtonWheelDown;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
mouse_button = MouseButtonUnknown;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mouse_button;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Inherited Module functions
|
|
|
|
*/
|
|
|
|
int ControllerBase::OnInit (int argc, char* argv[]) {
|
|
|
|
LogDebug ("Controller Init");
|
|
|
|
|
2011-01-31 08:39:42 +01:00
|
|
|
// we want to use key repeat so that we can keep e.g. backspace pressed in a
|
|
|
|
// LineEdit
|
|
|
|
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
|
|
|
|
|
|
|
|
// we also enable unicode processing all the time as it is only little
|
|
|
|
// overhead and simplifies text input a lot
|
|
|
|
SDL_EnableUNICODE(1);
|
|
|
|
|
2010-04-05 23:38:59 +02:00
|
|
|
// clear all bindings
|
|
|
|
int i;
|
2010-08-29 23:59:24 +02:00
|
|
|
for (i = 0; i < BINDING_KEYS_LAST; i++) {
|
2010-04-05 23:38:59 +02:00
|
|
|
mBindings[i] = "";
|
2010-08-29 23:59:24 +02:00
|
|
|
mButtonStates.set(i, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
uistate.activeitem = 0;
|
|
|
|
uistate.hotitem = 0;
|
2010-04-05 23:38:59 +02:00
|
|
|
|
2010-09-11 02:28:50 +02:00
|
|
|
uistate.kbditem = 0;
|
|
|
|
uistate.last_keysym = SDLK_CLEAR;
|
|
|
|
uistate.last_unicode = 0;
|
2011-01-02 18:25:20 +01:00
|
|
|
uistate.last_key = SDLK_CLEAR;
|
2010-09-11 02:28:50 +02:00
|
|
|
|
|
|
|
uistate.lastwidget = 0;
|
|
|
|
|
2010-04-05 23:38:59 +02:00
|
|
|
ControllerInstance = this;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControllerBase::OnDestroy () {
|
|
|
|
ControllerInstance = NULL;
|
|
|
|
|
|
|
|
LogDebug ("Controller Destroy");
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Module specific functions
|
|
|
|
*/
|
|
|
|
bool ControllerBase::BindKey (int key, const char *command) {
|
|
|
|
if (key <= 0 || key >= BINDING_KEYS_LAST) {
|
|
|
|
LogError ("Could not bind to key with index '%d': invalid index!", key);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
mBindings[key] = command;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControllerBase::Process () {
|
|
|
|
ProcessEvents ();
|
|
|
|
|
|
|
|
mView->CalcWorldCoordinates (mMouseScreenPosition[0], mMouseScreenPosition[1],
|
|
|
|
0., mMouseWorldPosition);
|
|
|
|
|
|
|
|
/*
|
|
|
|
LogMessage ("Screenpos = %2d,%2d Worldpos = %f,%f,%f",
|
|
|
|
mMouseScreenPosition[0], mMouseScreenPosition[1],
|
|
|
|
mMouseWorldPosition[0], mMouseWorldPosition[1], mMouseWorldPosition[2]);
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControllerBase::ProcessEvents () {
|
|
|
|
SDL_Event event;
|
|
|
|
|
|
|
|
while (SDL_PollEvent(&event)) {
|
|
|
|
/* We are only worried about SDL_KEYDOWN and SDL_KEYUP events */
|
|
|
|
switch (event.type) {
|
|
|
|
case SDL_KEYDOWN:
|
|
|
|
OnKeyDown (event.key.keysym);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_KEYUP:
|
|
|
|
OnKeyUp (event.key.keysym);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_MOUSEMOTION:
|
|
|
|
OnMouseMotion(event.motion.x, event.motion.y);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
|
|
OnMouseButtonDown (event.button.button, event.button.x, event.button.y);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_MOUSEBUTTONUP:
|
|
|
|
OnMouseButtonUp (event.button.button, event.button.x, event.button.y);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_VIDEORESIZE:
|
|
|
|
OnVideoResize (event.resize.w, event.resize.h);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_QUIT:
|
|
|
|
EngineSetStatus (EngineStatusStopping);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-29 23:59:24 +02:00
|
|
|
void ControllerBase::IMGUIFinish () {
|
|
|
|
if (GetButtonState(MouseButtonLeft) == false) {
|
|
|
|
uistate.activeitem = 0;
|
|
|
|
} else {
|
|
|
|
if (uistate.activeitem == 0)
|
|
|
|
uistate.activeitem = -1;
|
|
|
|
}
|
2010-11-13 18:45:15 +01:00
|
|
|
|
|
|
|
// also reset the last keysym such that old values will not be reported
|
|
|
|
uistate.last_keysym = SDLK_FIRST;
|
2011-01-02 18:25:20 +01:00
|
|
|
uistate.last_key = SDLK_FIRST;
|
2011-01-30 21:43:04 +01:00
|
|
|
uistate.keypressed_set.clear();
|
2010-08-29 23:59:24 +02:00
|
|
|
}
|
|
|
|
|
2010-04-05 23:38:59 +02:00
|
|
|
/** \brief Keyboard processing */
|
|
|
|
bool ControllerBase::OnKeyDown (const SDL_keysym &keysym) {
|
2010-09-11 02:28:50 +02:00
|
|
|
uistate.last_keysym = keysym.sym;
|
2011-01-02 18:25:20 +01:00
|
|
|
uistate.last_key = keysym.sym;
|
2010-09-11 02:28:50 +02:00
|
|
|
|
|
|
|
// Only when Unicode processing is activated store the unicode value
|
|
|
|
if (SDL_EnableUNICODE(-1)) {
|
|
|
|
uistate.last_unicode = keysym.unicode;
|
2011-01-30 21:43:04 +01:00
|
|
|
// LogMessage ("Received key down of %s and unicode %d", convert_keycode(keysym.sym), keysym.unicode);
|
2010-09-11 02:28:50 +02:00
|
|
|
}
|
2010-08-29 23:59:24 +02:00
|
|
|
|
2011-01-31 08:39:42 +01:00
|
|
|
if (mBindings[keysym.sym].size () != 0
|
|
|
|
&& GetButtonState(keysym.sym) == false) {
|
2010-04-05 23:38:59 +02:00
|
|
|
QueueCommand (mBindings[keysym.sym]);
|
|
|
|
}
|
|
|
|
|
2011-01-31 08:39:42 +01:00
|
|
|
SetButtonState (keysym.sym, true);
|
|
|
|
|
2010-04-05 23:38:59 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \brief Keyboard processing */
|
|
|
|
bool ControllerBase::OnKeyUp (const SDL_keysym &keysym) {
|
2011-01-31 08:39:42 +01:00
|
|
|
SetButtonState (keysym.sym, false);
|
2011-02-12 15:43:06 +01:00
|
|
|
|
|
|
|
if (keysym.sym == SDLK_F12) {
|
|
|
|
if (mView->GetIsFullscreen())
|
|
|
|
mView->SetFullscreen(false);
|
|
|
|
else
|
|
|
|
mView->SetFullscreen(true);
|
|
|
|
}
|
2011-01-31 08:39:42 +01:00
|
|
|
|
2011-01-30 21:43:04 +01:00
|
|
|
uistate.keypressed_set.insert (keysym.sym);
|
2010-08-29 23:59:24 +02:00
|
|
|
|
2010-04-05 23:38:59 +02:00
|
|
|
if (mBindings[keysym.sym].size () != 0) {
|
|
|
|
if (mBindings[keysym.sym][0] == '+') {
|
|
|
|
std::string upcommand = mBindings[keysym.sym];
|
|
|
|
upcommand[0] = '-';
|
|
|
|
QueueCommand (upcommand);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \brief Mouse processing */
|
|
|
|
bool ControllerBase::OnMouseButtonDown (Uint8 button, Uint16 xpos, Uint16 ypos) {
|
|
|
|
MouseButton mouse_button = convert_sdl_button (button);
|
2010-08-29 23:59:24 +02:00
|
|
|
mButtonStates.set(mouse_button, true);
|
2011-01-02 18:25:20 +01:00
|
|
|
uistate.last_key = mouse_button;
|
2010-04-05 23:38:59 +02:00
|
|
|
|
2010-06-06 00:58:11 +02:00
|
|
|
if (mView->mOverlayManager.SendMouseButtonDown (button, xpos, ypos))
|
2010-04-05 23:38:59 +02:00
|
|
|
return true;
|
|
|
|
|
|
|
|
if (mBindings[mouse_button].size () != 0) {
|
|
|
|
QueueCommand (mBindings[mouse_button]);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \brief Mouse processing */
|
|
|
|
bool ControllerBase::OnMouseButtonUp (Uint8 button, Uint16 xpos, Uint16 ypos) {
|
|
|
|
MouseButton mouse_button = convert_sdl_button (button);
|
2010-08-29 23:59:24 +02:00
|
|
|
mButtonStates.set(mouse_button, false);
|
2011-01-30 21:43:04 +01:00
|
|
|
uistate.keypressed_set.insert (mouse_button);
|
2010-04-05 23:38:59 +02:00
|
|
|
|
2010-06-06 00:58:11 +02:00
|
|
|
if (mView->mOverlayManager.SendMouseButtonUp (button, xpos, ypos))
|
2010-04-05 23:38:59 +02:00
|
|
|
return true;
|
|
|
|
|
|
|
|
if (mBindings[mouse_button].size () != 0) {
|
|
|
|
if (mBindings[mouse_button][0] == '+') {
|
|
|
|
std::string upcommand = mBindings[mouse_button];
|
|
|
|
upcommand[0] = '-';
|
|
|
|
QueueCommand (upcommand);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \brief Mouse processing */
|
|
|
|
bool ControllerBase::OnMouseMotion (const int xnew, const int ynew) {
|
|
|
|
mMouseScreenPosition[0] = xnew;
|
|
|
|
mMouseScreenPosition[1] = ynew;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \brief Video */
|
|
|
|
bool ControllerBase::OnVideoResize (int width, int height) {
|
|
|
|
mView->Resize (width, height);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
int convert_keystring (const char *key_val) {
|
|
|
|
std::string keystr (key_val);
|
|
|
|
|
|
|
|
// convert the keystr to lowercase
|
|
|
|
for (std::string::iterator iter = keystr.begin(); iter != keystr.end(); iter++)
|
|
|
|
(*iter) = tolower(*iter);
|
|
|
|
|
|
|
|
// now we search through the table for he value we were given
|
|
|
|
int i = 0;
|
|
|
|
while (key_table[i].keynum != keytable_last) {
|
|
|
|
if (keystr.compare(key_table[i].keystr) == 0)
|
|
|
|
return key_table[i].keynum;
|
|
|
|
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-09-11 14:32:31 +02:00
|
|
|
const char* convert_keycode (const int &keycode) {
|
|
|
|
int i = 0;
|
|
|
|
while (key_table[i].keynum != keytable_last) {
|
|
|
|
if (key_table[i].keynum == keycode)
|
|
|
|
return key_table[i].keystr;
|
|
|
|
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-04-05 23:38:59 +02:00
|
|
|
/*
|
|
|
|
* Commands for the ControllerBase
|
|
|
|
*/
|
|
|
|
bool Cmd_Bind (const std::vector<std::string> args) {
|
|
|
|
if (ControllerInstance == NULL) {
|
|
|
|
CommandSetErrorString("Could not bind key: Controller not yet initialized!");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (args.size() != 2) {
|
|
|
|
CommandSetErrorString("usage: bind <key> <command>");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int key = convert_keystring (args[0].c_str());
|
|
|
|
|
|
|
|
if (key == 0) {
|
|
|
|
std::ostringstream error_msg;
|
|
|
|
error_msg << "bind failed: invalid key '" << args[0] << '"';
|
|
|
|
CommandSetErrorString(error_msg.str());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ControllerInstance->BindKey (key, args[1].c_str()))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControllerBase::OnRegisterCommands () {
|
|
|
|
AddCommand ("bind", Cmd_Bind);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|