fysxasteroids/engine/ControllerBase.cc

265 lines
5.5 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] = "";
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<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);
}
}