265 lines
5.5 KiB
C++
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);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|