#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] = ""; 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 Keyboard processing */ bool ControllerBase::OnKeyDown (const SDL_keysym &keysym) { if (mView->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) { if (mView->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); if (mView->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); if (mView->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; } /* * Commands for the ControllerBase */ bool Cmd_Bind (const std::vector args) { if (ControllerInstance == NULL) { CommandSetErrorString("Could not bind key: Controller not yet initialized!"); return false; } if (args.size() != 2) { CommandSetErrorString("usage: bind "); 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); } }