fysxasteroids/engine/ControllerBase.cc

331 lines
7.2 KiB
C++

#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");
// clear all bindings
int i;
for (i = 0; i < BINDING_KEYS_LAST; i++) {
mBindings[i] = "";
mButtonStates.set(i, false);
}
uistate.activeitem = 0;
uistate.hotitem = 0;
uistate.kbditem = 0;
uistate.last_keysym = SDLK_CLEAR;
uistate.last_unicode = 0;
uistate.last_key = SDLK_CLEAR;
uistate.lastwidget = 0;
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;
}
}
}
/** \brief Activates or deactivates unicode processing and key delays of the keyboard inputs */
void ControllerBase::EnableTextinput (bool textinput_state) {
if (textinput_state) {
SDL_EnableUNICODE(1);
SDL_EnableKeyRepeat(500, 50);
} else {
SDL_EnableUNICODE(-1);
SDL_EnableKeyRepeat(0, 100);
}
}
void ControllerBase::IMGUIFinish () {
if (GetButtonState(MouseButtonLeft) == false) {
uistate.activeitem = 0;
} else {
if (uistate.activeitem == 0)
uistate.activeitem = -1;
}
// also reset the last keysym such that old values will not be reported
uistate.last_keysym = SDLK_FIRST;
uistate.last_key = SDLK_FIRST;
uistate.keypressed_set.clear();
}
/** \brief Keyboard processing */
bool ControllerBase::OnKeyDown (const SDL_keysym &keysym) {
mButtonStates.set(keysym.sym, true);
uistate.last_keysym = keysym.sym;
uistate.last_key = keysym.sym;
// Only when Unicode processing is activated store the unicode value
if (SDL_EnableUNICODE(-1)) {
uistate.last_unicode = keysym.unicode;
// LogMessage ("Received key down of %s and unicode %d", convert_keycode(keysym.sym), keysym.unicode);
}
if (mView->mOverlayManager.SendKeyDown (keysym))
return true;
if (mBindings[keysym.sym].size () != 0) {
QueueCommand (mBindings[keysym.sym]);
return true;
}
return false;
}
/** \brief Keyboard processing */
bool ControllerBase::OnKeyUp (const SDL_keysym &keysym) {
mButtonStates.set(keysym.sym, false);
uistate.keypressed_set.insert (keysym.sym);
if (mView->mOverlayManager.SendKeyUp (keysym))
return true;
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);
mButtonStates.set(mouse_button, true);
uistate.last_key = mouse_button;
if (mView->mOverlayManager.SendMouseButtonDown (button, xpos, ypos))
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);
mButtonStates.set(mouse_button, false);
uistate.keypressed_set.insert (mouse_button);
if (mView->mOverlayManager.SendMouseButtonUp (button, xpos, ypos))
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;
}
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;
}
/*
* 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);
}
}