#include "console.hpp"
#include "gameconfig.hpp"
+namespace{
+ const int SCAN_JOYSTICKS = Controller::CONTROLCOUNT + 1;
+}
+
class JoystickKeyboardController::JoystickMenu : public Menu
{
public:
void update_menu_item(Control id);
virtual void menu_action(MenuItem* item);
JoystickKeyboardController* controller;
+private:
+ void recreateMenu();
};
class JoystickKeyboardController::KeyboardMenu : public Menu
keymap[SDLK_CARET] = CONSOLE;
keymap[SDLK_DELETE] = PEEK_LEFT;
keymap[SDLK_END] = PEEK_RIGHT;
+ keymap[SDLK_PAGEUP] = PEEK_UP;
+ keymap[SDLK_PAGEDOWN] = PEEK_DOWN;
- int joystick_count = SDL_NumJoysticks();
- min_joybuttons = -1;
- max_joybuttons = -1;
- max_joyaxis = -1;
- max_joyhats = -1;
-
- for(int i = 0; i < joystick_count; ++i) {
- SDL_Joystick* joystick = SDL_JoystickOpen(i);
- bool good = true;
- if(SDL_JoystickNumButtons(joystick) < 2) {
- log_info << "Joystick " << i << " has less than 2 buttons" << std::endl;
- good = false;
- }
- if(SDL_JoystickNumAxes(joystick) < 2
- && SDL_JoystickNumHats(joystick) == 0) {
- log_info << "Joystick " << i << " has less than 2 axes and no hat" << std::endl;
- good = false;
- }
- if(!good) {
- SDL_JoystickClose(joystick);
- continue;
- }
-
- if(min_joybuttons < 0 || SDL_JoystickNumButtons(joystick) < min_joybuttons)
- min_joybuttons = SDL_JoystickNumButtons(joystick);
-
- if(SDL_JoystickNumButtons(joystick) > max_joybuttons)
- max_joybuttons = SDL_JoystickNumButtons(joystick);
-
- if(SDL_JoystickNumAxes(joystick) > max_joyaxis)
- max_joyaxis = SDL_JoystickNumAxes(joystick);
-
- if(SDL_JoystickNumHats(joystick) > max_joyhats)
- max_joyhats = SDL_JoystickNumHats(joystick);
+ jump_with_up_joy = false;
+ jump_with_up_kbd = false;
- joysticks.push_back(joystick);
- }
+ updateAvailableJoysticks();
dead_zone = 1000;
joy_axis_map[ 1] = RIGHT;
joy_axis_map[-2] = UP;
joy_axis_map[ 2] = DOWN;
-
- // some joysticks or SDL seem to produce some bogus events after being opened
- Uint32 ticks = SDL_GetTicks();
- while(SDL_GetTicks() - ticks < 200) {
- SDL_Event event;
- SDL_PollEvent(&event);
- }
}
JoystickKeyboardController::~JoystickKeyboardController()
}
void
+JoystickKeyboardController::updateAvailableJoysticks()
+{
+ for(std::vector<SDL_Joystick*>::iterator i = joysticks.begin();
+ i != joysticks.end(); ++i) {
+ if(*i != 0)
+ SDL_JoystickClose(*i);
+ }
+ joysticks.clear();
+
+ SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+ SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+
+ int joystick_count = SDL_NumJoysticks();
+ min_joybuttons = -1;
+ max_joybuttons = -1;
+ max_joyaxis = -1;
+ max_joyhats = -1;
+
+ if( joystick_count > 0 ){
+ for(int i = 0; i < joystick_count; ++i) {
+ SDL_Joystick* joystick = SDL_JoystickOpen(i);
+ bool good = true;
+ if(SDL_JoystickNumButtons(joystick) < 2) {
+ log_info << "Joystick " << i << ": " << SDL_JoystickName(i) << " has less than 2 buttons" << std::endl;
+ good = false;
+ }
+ if(SDL_JoystickNumAxes(joystick) < 2
+ && SDL_JoystickNumHats(joystick) == 0) {
+ log_info << "Joystick " << i << ": " << SDL_JoystickName(i) << " has less than 2 axes and no hat" << std::endl;
+ good = false;
+ }
+ if(!good) {
+ SDL_JoystickClose(joystick);
+ continue;
+ }
+
+ if(min_joybuttons < 0 || SDL_JoystickNumButtons(joystick) < min_joybuttons)
+ min_joybuttons = SDL_JoystickNumButtons(joystick);
+
+ if(SDL_JoystickNumButtons(joystick) > max_joybuttons)
+ max_joybuttons = SDL_JoystickNumButtons(joystick);
+
+ if(SDL_JoystickNumAxes(joystick) > max_joyaxis)
+ max_joyaxis = SDL_JoystickNumAxes(joystick);
+
+ if(SDL_JoystickNumHats(joystick) > max_joyhats)
+ max_joyhats = SDL_JoystickNumHats(joystick);
+
+ joysticks.push_back(joystick);
+ }
+ }
+
+ // some joysticks or SDL seem to produce some bogus events after being opened
+ Uint32 ticks = SDL_GetTicks();
+ while(SDL_GetTicks() - ticks < 200) {
+ SDL_Event event;
+ SDL_PollEvent(&event);
+ }
+}
+
+void
JoystickKeyboardController::read(const lisp::Lisp& lisp)
{
const lisp::Lisp* keymap_lisp = lisp.get_lisp("keymap");
if(keymap_lisp) {
keymap.clear();
+ keymap_lisp->get("jump-with-up", jump_with_up_kbd);
lisp::ListIterator iter(keymap_lisp);
while(iter.next()) {
if(iter.item() == "map") {
continue;
}
keymap[(SDLKey) key] = (Control)i;
- } else {
- log_info << "Invalid lisp element '" << iter.item() << "' in keymap" << std::endl;
}
}
}
const lisp::Lisp* joystick_lisp = lisp.get_lisp("joystick");
if(joystick_lisp) {
- joystick_lisp->get("dead_zone", dead_zone);
+ joystick_lisp->get("dead-zone", dead_zone);
+ joystick_lisp->get("jump-with-up", jump_with_up_joy);
lisp::ListIterator iter(joystick_lisp);
while(iter.next()) {
if(iter.item() == "map") {
JoystickKeyboardController::write(lisp::Writer& writer)
{
writer.start_list("keymap");
+ writer.write_bool("jump-with-up", jump_with_up_kbd);
for(KeyMap::iterator i = keymap.begin(); i != keymap.end(); ++i) {
writer.start_list("map");
writer.write_int("key", (int) i->first);
writer.end_list("keymap");
writer.start_list("joystick");
- writer.write_int("dead_zone", dead_zone);
+ writer.write_int("dead-zone", dead_zone);
+ writer.write_bool("jump-with-up", jump_with_up_joy);
for(ButtonMap::iterator i = joy_button_map.begin(); i != joy_button_map.end();
++i) {
}
void
+JoystickKeyboardController::set_joy_controls(Control id, bool value)
+{
+ if (jump_with_up_joy && id == Controller::UP)
+ controls[Controller::JUMP] = value;
+
+ controls[(Control)id] = value;
+}
+
+void
JoystickKeyboardController::process_event(const SDL_Event& event)
{
switch(event.type) {
if(i == joy_button_map.end()) {
log_debug << "Unmapped joybutton " << (int)jbutton.button << " pressed" << std::endl;
} else {
- controls[i->second] = (jbutton.state == SDL_PRESSED);
+ set_joy_controls(i->second, (jbutton.state == SDL_PRESSED));
}
}
}
std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
} else {
if (jaxis.value < -dead_zone)
- controls[left->second] = true;
+ set_joy_controls(left->second, true);
else if (jaxis.value > dead_zone)
- controls[left->second] = false;
+ set_joy_controls(left->second, false);
else
- controls[left->second] = false;
+ set_joy_controls(left->second, false);
}
if(right == joy_axis_map.end()) {
std::cout << "Unmapped joyaxis " << (int)jaxis.axis << " moved" << std::endl;
} else {
if (jaxis.value < -dead_zone)
- controls[right->second] = false;
+ set_joy_controls(right->second, false);
else if (jaxis.value > dead_zone)
- controls[right->second] = true;
+ set_joy_controls(right->second, true);
else
- controls[right->second] = false;
+ set_joy_controls(right->second, false);
}
}
}
{
HatMap::iterator it = joy_hat_map.find(SDL_HAT_UP);
if (it != joy_hat_map.end())
- controls[it->second] = jhat.value & SDL_HAT_UP;
+ set_joy_controls(it->second, jhat.value & SDL_HAT_UP);
}
if (changed & SDL_HAT_DOWN)
{
HatMap::iterator it = joy_hat_map.find(SDL_HAT_DOWN);
if (it != joy_hat_map.end())
- controls[it->second] = jhat.value & SDL_HAT_DOWN;
+ set_joy_controls(it->second, jhat.value & SDL_HAT_DOWN);
}
if (changed & SDL_HAT_LEFT)
{
HatMap::iterator it = joy_hat_map.find(SDL_HAT_LEFT);
if (it != joy_hat_map.end())
- controls[it->second] = jhat.value & SDL_HAT_LEFT;
+ set_joy_controls(it->second, jhat.value & SDL_HAT_LEFT);
}
if (changed & SDL_HAT_RIGHT)
{
HatMap::iterator it = joy_hat_map.find(SDL_HAT_RIGHT);
if (it != joy_hat_map.end())
- controls[it->second] = jhat.value & SDL_HAT_RIGHT;
+ set_joy_controls(it->second, jhat.value & SDL_HAT_RIGHT);
}
}
} else {
Control control = key_mapping->second;
controls[control] = (event.type == SDL_KEYDOWN);
+ if (jump_with_up_kbd && control == UP){
+ controls[JUMP] = (event.type == SDL_KEYDOWN);
+ }
}
}
}
add_controlfield(Controller::ACTION, _("Action"));
add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
+ add_controlfield(Controller::PEEK_UP, _("Peek Up"));
+ add_controlfield(Controller::PEEK_DOWN, _("Peek Down"));
if (config->console_enabled) {
add_controlfield(Controller::CONSOLE, _("Console"));
}
+ add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), controller->jump_with_up_kbd);
add_hl();
add_back(_("Back"));
update();
void
JoystickKeyboardController::KeyboardMenu::menu_action(MenuItem* item)
{
- assert(item->id >= 0 && item->id < Controller::CONTROLCOUNT);
- item->change_input(_("Press Key"));
- controller->wait_for_key = item->id;
+ if(item->id >= 0 && item->id < Controller::CONTROLCOUNT){
+ item->change_input(_("Press Key"));
+ controller->wait_for_key = item->id;
+ } else if( item->id == Controller::CONTROLCOUNT) {
+ controller->jump_with_up_kbd = item->toggled;
+ }
}
void
controller->reversemap_key(Controller::PEEK_LEFT)));
get_item_by_id((int) Controller::PEEK_RIGHT).change_input(get_key_name(
controller->reversemap_key(Controller::PEEK_RIGHT)));
+ get_item_by_id((int) Controller::PEEK_UP).change_input(get_key_name(
+ controller->reversemap_key(Controller::PEEK_UP)));
+ get_item_by_id((int) Controller::PEEK_DOWN).change_input(get_key_name(
+ controller->reversemap_key(Controller::PEEK_DOWN)));
if (config->console_enabled) {
get_item_by_id((int) Controller::CONSOLE).change_input(get_key_name(
controller->reversemap_key(Controller::CONSOLE)));
}
+ get_item_by_id(Controller::CONTROLCOUNT).toggled = controller->jump_with_up_kbd;
}
//---------------------------------------------------------------------------
JoystickKeyboardController* _controller)
: controller(_controller)
{
+ recreateMenu();
+}
+
+JoystickKeyboardController::JoystickMenu::~JoystickMenu()
+{}
+
+void
+JoystickKeyboardController::JoystickMenu::recreateMenu()
+{
+ clear();
add_label(_("Setup Joystick"));
add_hl();
if(controller->joysticks.size() > 0) {
add_controlfield(Controller::PAUSE_MENU, _("Pause/Menu"));
add_controlfield(Controller::PEEK_LEFT, _("Peek Left"));
add_controlfield(Controller::PEEK_RIGHT, _("Peek Right"));
+ add_controlfield(Controller::PEEK_UP, _("Peek Up"));
+ add_controlfield(Controller::PEEK_DOWN, _("Peek Down"));
+
+ add_toggle(Controller::CONTROLCOUNT, _("Jump with Up"), controller->jump_with_up_joy);
} else {
add_deactive(-1, _("No Joysticks found"));
}
+ add_deactive(-1,"");
+ add_entry(SCAN_JOYSTICKS, _("Scan for Joysticks"));
+
+ //Show Joysticks currently activated:
+ for(std::vector<SDL_Joystick*>::iterator i = controller->joysticks.begin();
+ i != controller->joysticks.end(); ++i) {
+ if(*i != 0)
+ add_deactive(-1, SDL_JoystickName(SDL_JoystickIndex(*i)) );
+ }
+
add_hl();
add_back(_("Back"));
update();
}
-JoystickKeyboardController::JoystickMenu::~JoystickMenu()
-{}
-
std::string
JoystickKeyboardController::JoystickMenu::get_button_name(int button)
{
void
JoystickKeyboardController::JoystickMenu::menu_action(MenuItem* item)
{
- assert(item->id >= 0 && item->id < Controller::CONTROLCOUNT);
- item->change_input(_("Press Button"));
- controller->wait_for_joystick = item->id;
+ if (item->id >= 0 && item->id < Controller::CONTROLCOUNT) {
+ item->change_input(_("Press Button"));
+ controller->wait_for_joystick = item->id;
+ } else if (item->id == Controller::CONTROLCOUNT) {
+ controller->jump_with_up_joy = item->toggled;
+ } else if( item->id == SCAN_JOYSTICKS) {
+ controller->updateAvailableJoysticks();
+ recreateMenu();
+ }
}
void
update_menu_item(Controller::PAUSE_MENU);
update_menu_item(Controller::PEEK_LEFT);
update_menu_item(Controller::PEEK_RIGHT);
+ update_menu_item(Controller::PEEK_UP);
+ update_menu_item(Controller::PEEK_DOWN);
+
+ get_item_by_id(Controller::CONTROLCOUNT).toggled = controller->jump_with_up_joy;
}