- committed input abstraction patch - as seen on list
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1305 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
456e205494
commit
44a2338368
@ -26,6 +26,7 @@ libstatic_ssg_a_CXXFLAGS = @NOREGMOVE@
|
||||
AM_CPPFLAGS=-DSUPERTUXKART_DATADIR="\"$(datadir)/games/@PACKAGE@/\""
|
||||
|
||||
supertuxkart_SOURCES = main.cpp \
|
||||
actionmap.cpp actionmap.hpp \
|
||||
material.cpp material.hpp \
|
||||
material_manager.cpp material_manager.hpp \
|
||||
attachment.cpp attachment.hpp \
|
||||
@ -38,7 +39,7 @@ supertuxkart_SOURCES = main.cpp \
|
||||
music_ogg.cpp music_ogg.hpp \
|
||||
sfx_openal.cpp sfx_openal.hpp \
|
||||
utils.cpp utils.hpp \
|
||||
inputmap.cpp inputmap.hpp \
|
||||
input.hpp \
|
||||
isect.cpp isect.hpp \
|
||||
track.cpp track.hpp \
|
||||
herring.cpp herring.hpp \
|
||||
|
@ -1,4 +1,4 @@
|
||||
// $Id: inputmap.cpp 1259 2007-09-24 12:28:19Z thebohemian $
|
||||
// $Id: actionmap.cpp 1259 2007-09-24 12:28:19Z thebohemian $
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2007 Robert Schuster
|
||||
@ -19,45 +19,43 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "player.hpp"
|
||||
#include "player_kart.hpp"
|
||||
#include "inputmap.hpp"
|
||||
#include "input.hpp"
|
||||
#include "actionmap.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void
|
||||
InputMap::putEntry(PlayerKart *kart, KartActions kc)
|
||||
ActionMap::putEntry(Input input, GameAction ga)
|
||||
{
|
||||
Player *p = kart->getPlayer();
|
||||
const Input *i = p->getInput(kc);
|
||||
|
||||
Entry *e = new Entry();
|
||||
e->kart = kart;
|
||||
e->action = kc;
|
||||
|
||||
inputMap[key(i->type, i->id0, i->id1, i->id2)] = e;
|
||||
inputMap[key(input)] = ga;
|
||||
}
|
||||
|
||||
InputMap::Entry *
|
||||
InputMap::getEntry(InputType it, int id0, int id1, int id2)
|
||||
GameAction
|
||||
ActionMap::getEntry(Input input)
|
||||
{
|
||||
return inputMap[key(it, id0, id1, id2)];
|
||||
return inputMap[key(input)];
|
||||
}
|
||||
|
||||
GameAction
|
||||
ActionMap::getEntry(InputType type, int id0, int id1, int id2)
|
||||
{
|
||||
return inputMap[key(type, id0, id1, id2)];
|
||||
}
|
||||
|
||||
void
|
||||
InputMap::clear()
|
||||
ActionMap::clear()
|
||||
{
|
||||
for (map<Key, Entry *>::iterator i = inputMap.begin();
|
||||
i != inputMap.end(); i++)
|
||||
{
|
||||
delete i->second;
|
||||
}
|
||||
|
||||
inputMap.clear();
|
||||
}
|
||||
|
||||
InputMap::Key
|
||||
InputMap::key(InputType it, int id0, int id1, int id2)
|
||||
ActionMap::Key
|
||||
ActionMap::key(Input input)
|
||||
{
|
||||
return key(input.type, input.id0, input.id1, input.id2);
|
||||
}
|
||||
|
||||
ActionMap::Key
|
||||
ActionMap::key(InputType it, int id0, int id1, int id2)
|
||||
{
|
||||
/*
|
||||
* A short reminder on the bit distribution and their usage:
|
@ -1,4 +1,4 @@
|
||||
// $Id: inputmap.hpp 1259 2007-09-24 12:28:19Z thebohemian $
|
||||
// $Id: actionmap.hpp 1259 2007-09-24 12:28:19Z thebohemian $
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2007 Robert Schuster
|
||||
@ -17,35 +17,33 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef HEADER_INPUTMAP_H
|
||||
#define HEADER_INPUTMAP_H
|
||||
#ifndef HEADER_ACTIONMAP_H
|
||||
#define HEADER_ACTIONMAP_H
|
||||
|
||||
#include <map>
|
||||
#include "player.hpp"
|
||||
#include "input.hpp"
|
||||
|
||||
class Playerkart;
|
||||
|
||||
class InputMap
|
||||
/**
|
||||
* This thing is named after what is put in as values.
|
||||
*/
|
||||
class ActionMap
|
||||
{
|
||||
typedef std::pair<int, int> Key;
|
||||
|
||||
public:
|
||||
typedef struct
|
||||
{
|
||||
PlayerKart *kart;
|
||||
KartActions action;
|
||||
} Entry;
|
||||
|
||||
void clear();
|
||||
|
||||
void putEntry(PlayerKart *, KartActions);
|
||||
void putEntry(Input, GameAction);
|
||||
|
||||
Entry *getEntry(InputType, int, int, int);
|
||||
GameAction getEntry(Input);
|
||||
GameAction getEntry(InputType, int, int, int);
|
||||
|
||||
private:
|
||||
inline Key key(Input);
|
||||
Key key(InputType, int, int, int);
|
||||
|
||||
std::map<Key, Entry *> inputMap;
|
||||
std::map<Key, GameAction> inputMap;
|
||||
|
||||
};
|
||||
|
@ -24,20 +24,9 @@
|
||||
#include "world.hpp"
|
||||
#include "menu_manager.hpp"
|
||||
|
||||
void BaseGUI::input(InputType type, int id0, int id1, int id2, int value)
|
||||
void
|
||||
BaseGUI::animateWidget(const int PREV_SELECTED_WGT, const int SELECTED_WGT)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case IT_KEYBOARD:
|
||||
inputKeyboard(id0, value);
|
||||
break;
|
||||
|
||||
case IT_MOUSEMOTION:
|
||||
{
|
||||
const int PREV_SELECTED_WGT = widget_manager->get_selected_wgt();
|
||||
const int SELECTED_WGT = widget_manager->handle_mouse( id0, id1 );
|
||||
|
||||
//FIXME: I should take WGT_NONE out of the class.
|
||||
if( SELECTED_WGT != WidgetManager::WGT_NONE )
|
||||
{
|
||||
if( PREV_SELECTED_WGT != WidgetManager::WGT_NONE )
|
||||
@ -48,121 +37,53 @@ void BaseGUI::input(InputType type, int id0, int id1, int id2, int value)
|
||||
widget_manager->lighten_wgt_color( SELECTED_WGT );
|
||||
widget_manager->pulse_wgt( SELECTED_WGT );
|
||||
}
|
||||
|
||||
#ifdef ALT_MOUSE_HANDLING
|
||||
if (id0 == 1 && value)
|
||||
if (id1 == AD_NEGATIVE)
|
||||
inputKeyboard(SDLK_UP, 1);
|
||||
else
|
||||
inputKeyboard(SDLK_DOWN, 1);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case IT_MOUSEBUTTON:
|
||||
if (!value) // Act on button release only.
|
||||
switch (id0)
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
select();
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
inputKeyboard(SDLK_ESCAPE, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case IT_STICKMOTION:
|
||||
if (id1 == 0)
|
||||
{
|
||||
// X-Axis
|
||||
inputKeyboard((id2 == AD_NEGATIVE) ? SDLK_LEFT : SDLK_RIGHT, !value);
|
||||
}
|
||||
else if (id1 == 1)
|
||||
{
|
||||
// Y-Axis
|
||||
inputKeyboard((id2 == AD_NEGATIVE) ? SDLK_UP : SDLK_DOWN, !value);
|
||||
}
|
||||
break;
|
||||
|
||||
case IT_STICKBUTTON:
|
||||
if( !value) // act on button release only
|
||||
switch (id1) // Button no
|
||||
{
|
||||
case 0:
|
||||
inputKeyboard(SDLK_RETURN, 0);
|
||||
break;
|
||||
case 1:
|
||||
inputKeyboard(SDLK_ESCAPE, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* Important note: One day the STK engine code will have no notion of SDL
|
||||
* key, button, axes and so on. It will only know actions like menu up, menu
|
||||
* down, enter menu, leave menu, ...
|
||||
*
|
||||
* However this requires some major reworking. Until this is done SDL's keys
|
||||
* take the role of the actions. That is why joystick axes & buttons and mouse
|
||||
* buttons are converted to key input (see BaseGUI::input).
|
||||
*
|
||||
* When the game actions are implemented not dealing with the input mechanisms
|
||||
* gives more flexibility:
|
||||
* - issue no game actions when input sensing is active
|
||||
* - what issues a certain game action can be conveniently selected
|
||||
* (at compile or runtime, depending on the need)
|
||||
*
|
||||
* Please keep this goal in mind when you work on the input stuff.
|
||||
*/
|
||||
void BaseGUI::inputKeyboard(int key, int pressed)
|
||||
void
|
||||
BaseGUI::handle(GameAction action, int value)
|
||||
{
|
||||
// Skip on keypress, act on keyrelease only.
|
||||
if (pressed)
|
||||
if (value)
|
||||
return;
|
||||
|
||||
switch ( key )
|
||||
{
|
||||
case SDLK_LEFT:
|
||||
case SDLK_RIGHT:
|
||||
case SDLK_UP:
|
||||
case SDLK_DOWN:
|
||||
{
|
||||
const int PREV_SELECTED_WGT = widget_manager->get_selected_wgt();
|
||||
const int SELECTED_WGT = widget_manager->handle_keyboard( key );
|
||||
int previous = widget_manager->get_selected_wgt();
|
||||
|
||||
if( SELECTED_WGT != WidgetManager::WGT_NONE )
|
||||
switch ( action )
|
||||
{
|
||||
if( PREV_SELECTED_WGT != WidgetManager::WGT_NONE )
|
||||
{
|
||||
widget_manager->darken_wgt_color( PREV_SELECTED_WGT );
|
||||
}
|
||||
case GA_CURSOR_LEFT:
|
||||
animateWidget(previous,
|
||||
widget_manager->handle_left());
|
||||
|
||||
widget_manager->lighten_wgt_color( SELECTED_WGT );
|
||||
widget_manager->pulse_wgt( SELECTED_WGT );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDLK_PLUS:
|
||||
case SDLK_MINUS:
|
||||
case SDLK_PAGEUP:
|
||||
case SDLK_PAGEDOWN:
|
||||
widget_manager->handle_keyboard( key );
|
||||
case GA_CURSOR_RIGHT:
|
||||
animateWidget(previous,
|
||||
widget_manager->handle_right());
|
||||
break;
|
||||
|
||||
case SDLK_SPACE:
|
||||
case SDLK_RETURN:
|
||||
case GA_CURSOR_UP:
|
||||
animateWidget(previous,
|
||||
widget_manager->handle_up());
|
||||
break;
|
||||
case GA_CURSOR_DOWN:
|
||||
animateWidget(previous,
|
||||
widget_manager->handle_down());
|
||||
break;
|
||||
case GA_INC_SCROLL_SPEED:
|
||||
widget_manager->increase_scroll_speed();
|
||||
break;
|
||||
case GA_INC_SCROLL_SPEED_FAST:
|
||||
widget_manager->increase_scroll_speed(true);
|
||||
break;
|
||||
case GA_DEC_SCROLL_SPEED:
|
||||
widget_manager->decrease_scroll_speed();
|
||||
break;
|
||||
case GA_DEC_SCROLL_SPEED_FAST:
|
||||
widget_manager->decrease_scroll_speed(true);
|
||||
break;
|
||||
case GA_ENTER:
|
||||
select();
|
||||
break;
|
||||
|
||||
case SDLK_ESCAPE:
|
||||
case GA_LEAVE:
|
||||
if (menu_manager->getMenuStackSize() > 1)
|
||||
{
|
||||
if(menu_manager->isCurrentMenu(MENUID_RACEMENU))
|
||||
@ -175,13 +96,13 @@ void BaseGUI::inputKeyboard(int key, int pressed)
|
||||
default:
|
||||
break;
|
||||
} // switch
|
||||
} // inputKeyboard
|
||||
} // handle
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
BaseGUI::inputPointer(int x, int y)
|
||||
{
|
||||
const int PREV_SELECTED_WGT = widget_manager->get_selected_wgt();
|
||||
const int SELECTED_WGT = widget_manager->handle_mouse( x, y );
|
||||
const int SELECTED_WGT = widget_manager->handle_pointer( x, y );
|
||||
|
||||
if( SELECTED_WGT != WidgetManager::WGT_NONE )
|
||||
{
|
||||
@ -196,7 +117,8 @@ BaseGUI::inputPointer(int x, int y)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void BaseGUI::update(float dt)
|
||||
void
|
||||
BaseGUI::update(float dt)
|
||||
{
|
||||
widget_manager->update(dt);
|
||||
#if 0
|
||||
@ -206,13 +128,22 @@ void BaseGUI::update(float dt)
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void BaseGUI::TimeToString(const float TIME, char *s)
|
||||
void
|
||||
BaseGUI::TimeToString(const float TIME, char *s)
|
||||
{
|
||||
int min = (int) floor ( TIME / 60.0 ) ;
|
||||
int sec = (int) floor ( TIME - (double) ( 60 * min ) ) ;
|
||||
int tenths = (int) floor ( 10.0f * (TIME - (double)(sec + 60* min)));
|
||||
sprintf ( s, "%d:%02d:%d", min, sec, tenths ) ;
|
||||
} // TimeToString
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
BaseGUI::inputKeyboard(SDLKey, int)
|
||||
{
|
||||
// This method is not supposed to be called since BaseGUI does not
|
||||
// handle low-level keyboard input.
|
||||
assert(false);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* EOF */
|
||||
|
@ -20,10 +20,14 @@
|
||||
#ifndef HEADER_BASEGUI_H
|
||||
#define HEADER_BASEGUI_H
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#include "player.hpp"
|
||||
|
||||
class BaseGUI
|
||||
{
|
||||
void animateWidget(const int, const int);
|
||||
|
||||
public:
|
||||
BaseGUI() {}
|
||||
virtual ~BaseGUI() {}
|
||||
@ -31,8 +35,9 @@ public:
|
||||
virtual void update(float dt);
|
||||
virtual void select() = 0;
|
||||
|
||||
virtual void input(InputType type, int id0, int id1, int id2, int value);
|
||||
virtual void inputKeyboard(int key, int pressed);
|
||||
virtual void handle(GameAction, int);
|
||||
|
||||
virtual void inputKeyboard(SDLKey, int);
|
||||
|
||||
void inputPointer(int x, int y);
|
||||
|
||||
|
@ -228,74 +228,74 @@ get stuck or fall too far, use the rescue button to get back on track."));
|
||||
|
||||
widget_manager->add_wgt(WTOK_LEFT, 20, 5);
|
||||
widget_manager->set_wgt_round_corners(WTOK_LEFT, WGT_AREA_LFT );
|
||||
widget_manager->set_wgt_text(WTOK_LEFT, sKartAction2String[KC_LEFT]);
|
||||
widget_manager->set_wgt_text(WTOK_LEFT, sKartAction2String[KA_LEFT]);
|
||||
widget_manager->add_wgt(WTOK_LEFTKEY, 20, 5);
|
||||
widget_manager->set_wgt_round_corners(WTOK_LEFTKEY, WGT_AREA_RGT );
|
||||
widget_manager->set_wgt_text(WTOK_LEFTKEY,
|
||||
user_config->getInputAsString(0, (KartActions)KC_LEFT).c_str());
|
||||
user_config->getMappingAsString(0, (KartAction)KA_LEFT).c_str());
|
||||
widget_manager->break_line();
|
||||
|
||||
widget_manager->add_wgt(WTOK_RIGHT, 20, 5);
|
||||
widget_manager->set_wgt_round_corners(WTOK_RIGHT, WGT_AREA_LFT );
|
||||
widget_manager->set_wgt_text(WTOK_RIGHT, sKartAction2String[KC_RIGHT]);
|
||||
widget_manager->set_wgt_text(WTOK_RIGHT, sKartAction2String[KA_RIGHT]);
|
||||
widget_manager->add_wgt(WTOK_RIGHTKEY, 20, 5);
|
||||
widget_manager->set_wgt_round_corners(WTOK_RIGHTKEY, WGT_AREA_RGT );
|
||||
widget_manager->set_wgt_text(WTOK_RIGHTKEY,
|
||||
user_config->getInputAsString(0, (KartActions)KC_RIGHT).c_str());
|
||||
user_config->getMappingAsString(0, (KartAction)KA_RIGHT).c_str());
|
||||
widget_manager->break_line();
|
||||
|
||||
widget_manager->add_wgt(WTOK_ACCEL, 20, 5);
|
||||
widget_manager->set_wgt_round_corners(WTOK_ACCEL, WGT_AREA_LFT );
|
||||
widget_manager->set_wgt_text(WTOK_ACCEL, sKartAction2String[KC_ACCEL]);
|
||||
widget_manager->set_wgt_text(WTOK_ACCEL, sKartAction2String[KA_ACCEL]);
|
||||
widget_manager->add_wgt(WTOK_ACCELKEY, 20, 5);
|
||||
widget_manager->set_wgt_round_corners(WTOK_ACCELKEY, WGT_AREA_RGT );
|
||||
widget_manager->set_wgt_text(WTOK_ACCELKEY,
|
||||
user_config->getInputAsString(0, (KartActions)KC_ACCEL).c_str());
|
||||
user_config->getMappingAsString(0, (KartAction)KA_ACCEL).c_str());
|
||||
widget_manager->break_line();
|
||||
|
||||
widget_manager->add_wgt(WTOK_BRAKE, 20, 5);
|
||||
widget_manager->set_wgt_round_corners(WTOK_BRAKE, WGT_AREA_LFT );
|
||||
widget_manager->set_wgt_text(WTOK_BRAKE, sKartAction2String[KC_BRAKE]);
|
||||
widget_manager->set_wgt_text(WTOK_BRAKE, sKartAction2String[KA_BRAKE]);
|
||||
widget_manager->add_wgt(WTOK_BRAKEKEY, 20, 5);
|
||||
widget_manager->set_wgt_round_corners(WTOK_BRAKEKEY, WGT_AREA_RGT );
|
||||
widget_manager->set_wgt_text(WTOK_BRAKEKEY,
|
||||
user_config->getInputAsString(0, (KartActions)KC_BRAKE).c_str());
|
||||
user_config->getMappingAsString(0, (KartAction)KA_BRAKE).c_str());
|
||||
widget_manager->break_line();
|
||||
|
||||
widget_manager->add_wgt(WTOK_WHEELIE, 20, 5);
|
||||
widget_manager->set_wgt_round_corners(WTOK_WHEELIE, WGT_AREA_LFT );
|
||||
widget_manager->set_wgt_text(WTOK_WHEELIE, sKartAction2String[KC_WHEELIE]);
|
||||
widget_manager->set_wgt_text(WTOK_WHEELIE, sKartAction2String[KA_WHEELIE]);
|
||||
widget_manager->add_wgt(WTOK_WHEELIEKEY, 20, 5);
|
||||
widget_manager->set_wgt_round_corners(WTOK_WHEELIEKEY, WGT_AREA_RGT );
|
||||
widget_manager->set_wgt_text(WTOK_WHEELIEKEY,
|
||||
user_config->getInputAsString(0, (KartActions)KC_WHEELIE).c_str());
|
||||
user_config->getMappingAsString(0, (KartAction)KA_WHEELIE).c_str());
|
||||
widget_manager->break_line();
|
||||
|
||||
widget_manager->add_wgt(WTOK_RESCUE, 20, 5);
|
||||
widget_manager->set_wgt_round_corners(WTOK_RESCUE, WGT_AREA_LFT );
|
||||
widget_manager->set_wgt_text(WTOK_RESCUE, sKartAction2String[KC_RESCUE]);
|
||||
widget_manager->set_wgt_text(WTOK_RESCUE, sKartAction2String[KA_RESCUE]);
|
||||
widget_manager->add_wgt(WTOK_RESCUEKEY, 20, 5);
|
||||
widget_manager->set_wgt_round_corners(WTOK_RESCUEKEY, WGT_AREA_RGT );
|
||||
widget_manager->set_wgt_text(WTOK_RESCUEKEY,
|
||||
user_config->getInputAsString(0, (KartActions)KC_RESCUE).c_str());
|
||||
user_config->getMappingAsString(0, (KartAction)KA_RESCUE).c_str());
|
||||
widget_manager->break_line();
|
||||
|
||||
widget_manager->add_wgt(WTOK_FIRE, 20, 5);
|
||||
widget_manager->set_wgt_round_corners(WTOK_FIRE, WGT_AREA_LFT );
|
||||
widget_manager->set_wgt_text(WTOK_FIRE, sKartAction2String[KC_FIRE]);
|
||||
widget_manager->set_wgt_text(WTOK_FIRE, sKartAction2String[KA_FIRE]);
|
||||
widget_manager->add_wgt(WTOK_FIREKEY, 20, 5);
|
||||
widget_manager->set_wgt_round_corners(WTOK_FIREKEY, WGT_AREA_RGT );
|
||||
widget_manager->set_wgt_text(WTOK_FIREKEY,
|
||||
user_config->getInputAsString(0, (KartActions)KC_FIRE).c_str());
|
||||
user_config->getMappingAsString(0, (KartAction)KA_FIRE).c_str());
|
||||
widget_manager->break_line();
|
||||
|
||||
widget_manager->add_wgt(WTOK_JUMP, 20, 5);
|
||||
widget_manager->set_wgt_round_corners(WTOK_JUMP, WGT_AREA_LFT );
|
||||
widget_manager->set_wgt_text(WTOK_JUMP, sKartAction2String[KC_JUMP]);
|
||||
widget_manager->set_wgt_text(WTOK_JUMP, sKartAction2String[KA_JUMP]);
|
||||
widget_manager->add_wgt(WTOK_JUMPKEY, 20, 5);
|
||||
widget_manager->set_wgt_round_corners(WTOK_JUMPKEY, WGT_AREA_RGT );
|
||||
widget_manager->set_wgt_text(WTOK_JUMPKEY,
|
||||
user_config->getInputAsString(0, (KartActions)KC_JUMP).c_str());
|
||||
user_config->getMappingAsString(0, (KartAction)KA_JUMP).c_str());
|
||||
widget_manager->break_line();
|
||||
|
||||
/*Buttons at the bottom*/
|
||||
|
@ -144,18 +144,19 @@ void MainMenu::select()
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void MainMenu::inputKeyboard(int key, int pressed)
|
||||
void MainMenu::handle(GameAction ga, int value)
|
||||
{
|
||||
switch ( key )
|
||||
switch ( ga )
|
||||
{
|
||||
case SDLK_ESCAPE: //ESC
|
||||
if(!pressed)
|
||||
case GA_LEAVE:
|
||||
if(!value)
|
||||
break;
|
||||
|
||||
menu_manager->pushMenu(MENUID_EXITGAME);
|
||||
break;
|
||||
|
||||
default:
|
||||
BaseGUI::inputKeyboard(key, pressed);
|
||||
BaseGUI::handle(ga, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,8 @@ public:
|
||||
~MainMenu();
|
||||
|
||||
void select();
|
||||
void inputKeyboard(int key, int pressed);
|
||||
void handle(GameAction, int);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "grand_prix_select.hpp"
|
||||
#include "sound_manager.hpp"
|
||||
#include "sdldrv.hpp"
|
||||
#include "user_config.hpp"
|
||||
#include "widget_manager.hpp"
|
||||
|
||||
MenuManager* menu_manager= new MenuManager();
|
||||
@ -95,10 +96,11 @@ void MenuManager::update()
|
||||
|
||||
if (m_handled_size != m_menu_stack.size())
|
||||
{
|
||||
if(m_current_menu==m_RaceGUI)
|
||||
if (m_RaceGUI
|
||||
&& m_current_menu == m_RaceGUI)
|
||||
{
|
||||
m_RaceGUI = 0;
|
||||
drv_showPointer();
|
||||
drv_setMode(MENU);
|
||||
}
|
||||
|
||||
delete m_current_menu;
|
||||
@ -138,7 +140,7 @@ void MenuManager::update()
|
||||
m_current_menu= new NumPlayers();
|
||||
break;
|
||||
case MENUID_RACE:
|
||||
drv_hidePointer();
|
||||
drv_setMode(INGAME);
|
||||
m_current_menu = new RaceGUI();
|
||||
m_RaceGUI = m_current_menu;
|
||||
break;
|
||||
|
@ -57,18 +57,18 @@ enum WidgetTokens
|
||||
WTOK_QUIT
|
||||
};
|
||||
|
||||
const char *sKartAction2String[KC_LAST+1] = {_("Left"), _("Right"), _("Accelerate"),
|
||||
/** Limits the maximum length of the player name. */
|
||||
const size_t PlayerControls::PLAYER_NAME_MAX = 10;
|
||||
|
||||
const char *sKartAction2String[KA_LAST+1] = {_("Left"), _("Right"), _("Accelerate"),
|
||||
_("Brake"), _("Wheelie"), _("Jump"),
|
||||
_("Rescue"), _("Fire"), _("Look back") };
|
||||
|
||||
|
||||
PlayerControls::PlayerControls(int whichPlayer):
|
||||
m_grab_id(WidgetManager::WGT_NONE), m_player_index(whichPlayer),
|
||||
m_player_index(whichPlayer),
|
||||
m_grab_input(false)
|
||||
{
|
||||
// We need the unicode character here, so enable the translation
|
||||
SDL_EnableUNICODE(1);
|
||||
|
||||
const bool SHOW_RECT = true;
|
||||
const bool SHOW_TEXT = true;
|
||||
widget_manager->set_initial_rect_state(SHOW_RECT, WGT_AREA_ALL, WGT_TRANS_BLACK);
|
||||
@ -89,14 +89,14 @@ PlayerControls::PlayerControls(int whichPlayer):
|
||||
widget_manager->activate_wgt( WTOK_PLYR_NAME1);
|
||||
widget_manager->break_line();
|
||||
|
||||
KartActions control;
|
||||
for(int i=0; i<=KC_LAST; i++)
|
||||
KartAction control;
|
||||
for(int i = KA_FIRST; i <= KA_LAST; i++)
|
||||
{
|
||||
widget_manager->add_wgt( WTOK_KEY0 + i, 30, 7);
|
||||
widget_manager->set_wgt_text( WTOK_KEY0 + i, sKartAction2String[i]);
|
||||
|
||||
control = (KartActions)i;
|
||||
m_key_names[control] = user_config->getInputAsString(m_player_index, control);
|
||||
control = (KartAction)i;
|
||||
m_key_names[control] = user_config->getMappingAsString(m_player_index, control);
|
||||
widget_manager->add_wgt( WTOK_LEFT + i, 30, 7);
|
||||
widget_manager->set_wgt_text( WTOK_LEFT + i, m_key_names[control].c_str());
|
||||
widget_manager->activate_wgt( WTOK_LEFT + i);
|
||||
@ -117,128 +117,169 @@ PlayerControls::~PlayerControls()
|
||||
{
|
||||
widget_manager->delete_wgts();
|
||||
// The unicode translation is not generally needed, so disable it again.
|
||||
SDL_EnableUNICODE(0);
|
||||
} // ~PlayerControls
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void PlayerControls::select()
|
||||
void
|
||||
PlayerControls::select()
|
||||
{
|
||||
if (m_grab_input) return;
|
||||
|
||||
m_grab_id = widget_manager->get_selected_wgt();
|
||||
if(m_grab_id == WTOK_PLYR_NAME1)
|
||||
const int selected = widget_manager->get_selected_wgt();
|
||||
switch (selected)
|
||||
{
|
||||
m_grab_input = true;
|
||||
return;
|
||||
}
|
||||
case WTOK_PLYR_NAME1:
|
||||
// Switch to typing in the player's name.
|
||||
widget_manager->set_wgt_text(WTOK_PLYR_NAME1, (m_name + "<").c_str());
|
||||
|
||||
const int MENU_CHOICE = widget_manager->get_selected_wgt() - WTOK_LEFT;
|
||||
drv_setMode(LOWLEVEL);
|
||||
|
||||
if(MENU_CHOICE == WTOK_QUIT)
|
||||
{
|
||||
break;
|
||||
case WTOK_QUIT:
|
||||
// Leave menu.
|
||||
menu_manager->popMenu();
|
||||
return;
|
||||
|
||||
break;
|
||||
default:
|
||||
// Switch to input sensing.
|
||||
|
||||
// If the only remaining and not yet handled widgets are the ones
|
||||
// that deal with the kart controls and the values are still in the
|
||||
// correct order the assertion should hold. If not did something
|
||||
// bad.
|
||||
assert (selected >= WTOK_LEFT
|
||||
&& selected <= WTOK_LOOK_BACK);
|
||||
|
||||
|
||||
m_edit_action = static_cast<KartAction>(selected - WTOK_LEFT);
|
||||
widget_manager->set_wgt_text(selected, _("Press key"));
|
||||
|
||||
drv_setMode(INPUT_SENSE);
|
||||
|
||||
break;
|
||||
}
|
||||
m_edit_action = static_cast<KartActions>(MENU_CHOICE);
|
||||
m_grab_input = true;
|
||||
drv_hidePointer();
|
||||
|
||||
widget_manager->set_wgt_text(m_grab_id, _("Press key"));
|
||||
} // select
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void PlayerControls::input(InputType type, int id0, int id1, int id2, int value)
|
||||
void
|
||||
PlayerControls::inputKeyboard(SDLKey key, int unicode)
|
||||
{
|
||||
if (m_grab_input && value)
|
||||
{
|
||||
// Handle input of user name
|
||||
// -------------------------
|
||||
if(m_grab_id == WTOK_PLYR_NAME1)
|
||||
{
|
||||
if(type==IT_KEYBOARD)
|
||||
switch (key)
|
||||
{
|
||||
case SDLK_RSHIFT:
|
||||
case SDLK_LSHIFT:
|
||||
// Ignore shift, otherwise shift will disable input
|
||||
// (making it impossible to enter upper case characters)
|
||||
if(id0==SDLK_RSHIFT || id0==SDLK_LSHIFT) return;
|
||||
// Handle backspace
|
||||
if(id0==SDLK_BACKSPACE)
|
||||
{
|
||||
if(m_name.size()>=1) m_name.erase(m_name.size()-1,1);
|
||||
}
|
||||
// All other control characters are ignored and will end
|
||||
// entering the name
|
||||
else if(id0<32 || id0>255)
|
||||
{
|
||||
m_grab_input = false;
|
||||
m_grab_id = WidgetManager::WGT_NONE;
|
||||
user_config->m_player[m_player_index].setName(m_name);
|
||||
// BaseGUI::input(type, id0, id1, id2, value);
|
||||
case SDLK_SPACE:
|
||||
// Ignore space to prevent invisible names.
|
||||
|
||||
// Note: This will never happen as long as SPACE has a mapping which
|
||||
// causes GA_ENTER and therefore finishes the typing. Please leave this
|
||||
// because I am not sure whether this is good behavior (that SPACE
|
||||
// cannot reach inputKeyboard()) and with some changes to the input
|
||||
// driver this code has suddenly a useful effect.
|
||||
case SDLK_KP_ENTER:
|
||||
case SDLK_RETURN:
|
||||
case SDLK_ESCAPE:
|
||||
// Ignore some control keys. What they could provide is implemented
|
||||
// in the handle() method.
|
||||
return;
|
||||
}
|
||||
else // Add the character to the name
|
||||
{
|
||||
case SDLK_BACKSPACE:
|
||||
// Handle backspace.
|
||||
if (m_name.size() >=1)
|
||||
m_name.erase(m_name.size()-1, 1);
|
||||
|
||||
widget_manager->set_wgt_text(WTOK_PLYR_NAME1, (m_name + "<").c_str());
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
// Adds the character to the name.
|
||||
// For this menu only unicode translation is enabled.
|
||||
// So we use the unicode character here, since this will
|
||||
// take care of upper/lower case etc.
|
||||
m_name = m_name + (char)id1;
|
||||
if (unicode && m_name.size() <= PLAYER_NAME_MAX)
|
||||
m_name += (char) unicode;
|
||||
widget_manager->set_wgt_text(WTOK_PLYR_NAME1, (m_name + "<").c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
PlayerControls::clearMapping()
|
||||
{
|
||||
const int selected = widget_manager->get_selected_wgt();
|
||||
if (selected >= WTOK_LEFT && selected <= WTOK_LOOK_BACK)
|
||||
{
|
||||
user_config->clearInput(m_player_index,
|
||||
(KartAction) (selected - WTOK_LEFT));
|
||||
updateAllKeyLabels();
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void PlayerControls::handle(GameAction ga, int value)
|
||||
{
|
||||
if (value)
|
||||
return;
|
||||
|
||||
switch (ga)
|
||||
{
|
||||
case GA_CLEAR_MAPPING:
|
||||
clearMapping();
|
||||
|
||||
break;
|
||||
case GA_SENSE_COMPLETE:
|
||||
// Updates the configuration with the newly sensed input.
|
||||
user_config->setInput(m_player_index,
|
||||
m_edit_action,
|
||||
drv_getSensedInput());
|
||||
// Fall through to recover the widget labels.
|
||||
case GA_SENSE_CANCEL:
|
||||
drv_setMode(MENU);
|
||||
|
||||
// Refresh all key labels since they mave changed because of
|
||||
// conflicting bindings.
|
||||
updateAllKeyLabels();
|
||||
break;
|
||||
case GA_ENTER:
|
||||
// If the user is typing her name this will be finished at this
|
||||
// point.
|
||||
if (drv_isInMode(LOWLEVEL))
|
||||
{
|
||||
// Prevents zero-length names.
|
||||
if (m_name.length() == 0)
|
||||
m_name = _("Player ") + m_player_index;
|
||||
user_config->m_player[m_player_index].setName(m_name);
|
||||
widget_manager->set_wgt_text(WTOK_PLYR_NAME1, m_name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ignore all other events, e.g. when pressing the mouse
|
||||
// button twice on the input field etc.
|
||||
}
|
||||
}
|
||||
// Handle the definition of a key
|
||||
// ------------------------------
|
||||
else
|
||||
{
|
||||
drv_showPointer();
|
||||
m_grab_input = false;
|
||||
|
||||
// Do not accept pressing ESC as input.
|
||||
if (type != IT_KEYBOARD || id0 != SDLK_ESCAPE)
|
||||
drv_setMode(MENU);
|
||||
}
|
||||
else
|
||||
select();
|
||||
break;
|
||||
case GA_LEAVE:
|
||||
// If the user is typing her name this will be cancelled at this
|
||||
// point.
|
||||
if (drv_isInMode(LOWLEVEL))
|
||||
{
|
||||
// Since unicode translation is enabled, the value of id1 will
|
||||
// be the unicode value. Since unicode is usually not enabled
|
||||
// in the race we have to set this value to zero (unicode
|
||||
// translation is only enabled here to help entering the name),
|
||||
// otherwise the keys will not be recognised in the race!!
|
||||
if(type==IT_KEYBOARD) id1=0;
|
||||
user_config->m_player[m_player_index].setInput(m_edit_action, type,
|
||||
id0, id1, id2);
|
||||
m_name = user_config->m_player[m_player_index].getName();
|
||||
widget_manager->set_wgt_text(WTOK_PLYR_NAME1, m_name.c_str());
|
||||
|
||||
drv_setMode(MENU);
|
||||
break;
|
||||
}
|
||||
// Fall through to reach the usual GA_LEAVE code (leave menu).
|
||||
default:
|
||||
BaseGUI::handle(ga, value);
|
||||
}
|
||||
|
||||
widget_manager->set_wgt_text(m_grab_id, m_key_names[m_edit_action].c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
BaseGUI::input(type, id0, id1, id2, value);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*void PlayerControls::addKeyLabel(int CHANGE_ID, KartActions control, bool start)
|
||||
void
|
||||
PlayerControls::updateAllKeyLabels()
|
||||
{
|
||||
|
||||
setKeyInfoString(control);
|
||||
|
||||
if (start)
|
||||
widgetSet -> start(CHANGE_ID, m_key_names[control].c_str(), GUI_MED, control);
|
||||
else
|
||||
widgetSet -> state(CHANGE_ID, m_key_names[control].c_str(), GUI_MED, control);
|
||||
} // addKeyLabel
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void PlayerControls::changeKeyLabel(int m_grab_id, KartActions control)
|
||||
{
|
||||
setKeyInfoString(control);
|
||||
widgetSet -> set_label(m_grab_id, m_key_names[control].c_str());
|
||||
// widgetSet -> layout(m_menu_id, 0, 0);
|
||||
} // changeKeyLabel
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void PlayerControls::setKeyInfoString(KartActions control)
|
||||
{
|
||||
} // setKeyInfoString
|
||||
*/
|
||||
for (int i = KA_FIRST; i <= KA_LAST; i++)
|
||||
{
|
||||
m_key_names[i] = user_config->getMappingAsString(m_player_index,
|
||||
(KartAction) i);
|
||||
widget_manager->set_wgt_text(WTOK_LEFT + i, m_key_names[i].c_str());
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "player.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
class PlayerControls: public BaseGUI
|
||||
{
|
||||
@ -32,18 +33,30 @@ public:
|
||||
~PlayerControls();
|
||||
|
||||
void select();
|
||||
void input(InputType type, int id0, int id1, int id2, int value);
|
||||
void clearMapping();
|
||||
|
||||
void handle(GameAction, int);
|
||||
void inputKeyboard(SDLKey, int);
|
||||
void addKeyLabel(int change_id, KartAction control, bool start);
|
||||
void setKeyInfoString(KartAction control);
|
||||
|
||||
private:
|
||||
int m_grab_id;
|
||||
void updateAllKeyLabels();
|
||||
|
||||
int m_player_index;
|
||||
bool m_grab_input;
|
||||
KartActions m_edit_action;
|
||||
|
||||
/** Stores the KartAction for which the input is being sensed. */
|
||||
KartAction m_edit_action;
|
||||
|
||||
// Stores the heading - making this an attribute here avoids
|
||||
// memory leaks or complicated memory management
|
||||
char m_heading[60];
|
||||
|
||||
std::string m_name;
|
||||
std::string m_key_names[KC_LAST+1];
|
||||
std::string m_key_names[KC_COUNT];
|
||||
|
||||
static const size_t PLAYER_NAME_MAX;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -18,30 +18,21 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
#include "user_config.hpp"
|
||||
#include "race_gui.hpp"
|
||||
|
||||
#include "input.hpp"
|
||||
#include "sdldrv.hpp"
|
||||
|
||||
#include "user_config.hpp"
|
||||
#include "history.hpp"
|
||||
#include "track.hpp"
|
||||
#include "material_manager.hpp"
|
||||
#include "menu_manager.hpp"
|
||||
#include "sdldrv.hpp"
|
||||
#include "translation.hpp"
|
||||
#include "font.hpp"
|
||||
#include "inputmap.hpp"
|
||||
|
||||
RaceGUI::RaceGUI(): m_input_map (new InputMap()), m_time_left(0.0)
|
||||
RaceGUI::RaceGUI(): m_time_left(0.0)
|
||||
{
|
||||
if(user_config->m_fullscreen)
|
||||
{
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
}
|
||||
|
||||
if(!user_config->m_profile)
|
||||
{
|
||||
updateInputMappings();
|
||||
} // if !user_config->m_profile
|
||||
|
||||
// FIXME: translation problem
|
||||
m_pos_string[0] = "?!?";
|
||||
m_pos_string[1] = "1st";
|
||||
@ -74,94 +65,49 @@ RaceGUI::RaceGUI(): m_input_map (new InputMap()), m_time_left(0.0)
|
||||
//-----------------------------------------------------------------------------
|
||||
RaceGUI::~RaceGUI()
|
||||
{
|
||||
delete m_input_map;
|
||||
|
||||
if(user_config->m_fullscreen)
|
||||
{
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
}
|
||||
//FIXME: does all that material stuff need freeing somehow?
|
||||
} // ~Racegui
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RaceGUI::updateInputMappings()
|
||||
void
|
||||
RaceGUI::handle(GameAction ga, int value)
|
||||
{
|
||||
m_input_map->clear();
|
||||
static int isWireframe = false;
|
||||
|
||||
// Defines the mappings for player keys to kart and action
|
||||
// To avoid looping over all players to find out what
|
||||
// player control key was pressed, a special data structure
|
||||
// is set up: keysToKart contains for each (player assigned)
|
||||
// key which kart it applies to (and therefore which player),
|
||||
// and typeForKey contains the assigned function of that key.
|
||||
const int NUM = world->m_race_setup.getNumPlayers();
|
||||
for(int i=0; i < NUM; i++)
|
||||
// The next lines find out the player and kartaction that belongs
|
||||
// to a certain gameaction value (GameAction -> Player number, Kartaction).
|
||||
// Since the numbers are fixed this can be done through computation
|
||||
// (instead of using e.g. a separate data structure).
|
||||
// Note that the kartaction enum value and their representatives in
|
||||
// gameaction enum have the same order (Otherwise the stuff below would
|
||||
// not work ...)!
|
||||
if (ga >= GA_FIRST_KARTACTION && ga <= GA_LAST_KARTACTION)
|
||||
{
|
||||
PlayerKart* kart = world->getPlayerKart(i);
|
||||
// 'Pulls down' the gameaction value to make them multiples of the
|
||||
// kartaction values.
|
||||
int ka = ga - GA_FIRST_KARTACTION;
|
||||
|
||||
for(int ka=(int)KC_FIRST; ka < (int)KC_LAST+1; ka++)
|
||||
m_input_map->putEntry(kart, (KartActions) ka);
|
||||
int playerNo = ka / KC_COUNT;
|
||||
ka = ka % KC_COUNT;
|
||||
|
||||
world->getPlayerKart(playerNo)->action((KartAction) ka, value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // UpdateKeyControl
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool RaceGUI::handleInput(InputType type, int id0, int id1, int id2, int value)
|
||||
{
|
||||
InputMap::Entry *e = m_input_map->getEntry(type, id0, id1, id2);
|
||||
|
||||
if (e)
|
||||
{
|
||||
e->kart->action(e->action, value);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RaceGUI::update(float dt)
|
||||
{
|
||||
assert(world != NULL);
|
||||
drawStatusText(world->m_race_setup, dt);
|
||||
cleanupMessages();
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RaceGUI::input(InputType type, int id0, int id1, int id2, int value)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case IT_KEYBOARD:
|
||||
// Stuff that handleInput() does not care about are
|
||||
// internal keyboard actions.
|
||||
if (!handleInput(type, id0, id1, id2, value))
|
||||
inputKeyboard(id0, value);
|
||||
break;
|
||||
default: // no keyboard event
|
||||
handleInput(type, id0, id1, id2, value);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RaceGUI::inputKeyboard(int key, int pressed)
|
||||
{
|
||||
if (!pressed)
|
||||
if (value)
|
||||
return;
|
||||
|
||||
static int isWireframe = false ;
|
||||
switch ( key )
|
||||
switch (ga)
|
||||
{
|
||||
case GA_DEBUG_ADD_MISSILE:
|
||||
if (world->m_race_setup.getNumPlayers() ==1 )
|
||||
{
|
||||
case SDLK_F7:
|
||||
if(world->m_race_setup.getNumPlayers()==1)
|
||||
{ // ctrl-r
|
||||
Kart* kart = world->getPlayerKart(0);
|
||||
kart->setCollectable((rand()%2)?COLLECT_MISSILE :COLLECT_HOMING_MISSILE, 10000);
|
||||
}
|
||||
break;
|
||||
case SDLK_F12:
|
||||
case GA_DEBUG_TOGGLE_FPS:
|
||||
user_config->m_display_fps = !user_config->m_display_fps;
|
||||
if(user_config->m_display_fps)
|
||||
{
|
||||
@ -171,11 +117,11 @@ void RaceGUI::inputKeyboard(int key, int pressed)
|
||||
}
|
||||
break;
|
||||
#ifdef BULLET
|
||||
case SDLK_F2:
|
||||
case GA_DEBUG_BULLET:
|
||||
user_config->m_bullet_debug = !user_config->m_bullet_debug;
|
||||
break;
|
||||
#endif
|
||||
case SDLK_F11:
|
||||
case GA_DEBUG_TOGGLE_WIREFRAME:
|
||||
glPolygonMode(GL_FRONT_AND_BACK, isWireframe ? GL_FILL : GL_LINE);
|
||||
isWireframe = ! isWireframe;
|
||||
break;
|
||||
@ -183,21 +129,30 @@ void RaceGUI::inputKeyboard(int key, int pressed)
|
||||
// For now disable F9 toggling fullscreen, since windows requires
|
||||
// to reload all textures, display lists etc. Fullscreen can
|
||||
// be toggled from the main menu (options->display).
|
||||
case SDLK_F9:
|
||||
case GA_TOGGLE_FULLSCREEN:
|
||||
drv_toggleFullscreen(0); // 0: do not reset textures
|
||||
// Fall through to put the game into pause mode.
|
||||
#endif
|
||||
case SDLK_ESCAPE: // ESC
|
||||
case GA_LEAVE_RACE:
|
||||
world->pause();
|
||||
menu_manager->pushMenu(MENUID_RACEMENU);
|
||||
break;
|
||||
case SDLK_F10:
|
||||
case GA_DEBUG_HISTORY:
|
||||
history->Save();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} // switch
|
||||
} // inputKeyboard
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RaceGUI::update(float dt)
|
||||
{
|
||||
assert(world != NULL);
|
||||
drawStatusText(world->m_race_setup, dt);
|
||||
cleanupMessages();
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RaceGUI::drawFPS ()
|
||||
|
@ -66,13 +66,12 @@ public:
|
||||
~RaceGUI();
|
||||
void update(float dt);
|
||||
void select() {}
|
||||
void input(InputType type, int id0, int id1, int id2, int value);
|
||||
void handleKartAction(KartActions ka, int value);
|
||||
void handle(GameAction, int);
|
||||
void handleKartAction(KartAction ka, int value);
|
||||
void addMessage(const char *message, Kart *kart, float time, int fonst_size,
|
||||
int red=255, int green=0, int blue=255);
|
||||
|
||||
private:
|
||||
InputMap *m_input_map;
|
||||
ulClock m_fps_timer;
|
||||
int m_fps_counter;
|
||||
char m_fps_string[10];
|
||||
@ -95,9 +94,6 @@ private:
|
||||
void drawAllMessages (Kart* player_kart,
|
||||
int offset_x, int offset_y,
|
||||
float ratio_x, float ratio_y );
|
||||
void updateInputMappings();
|
||||
bool handleInput(InputType type, int id0, int id1, int id2, int value);
|
||||
void inputKeyboard(int key, int pressed);
|
||||
void drawPlayerIcons ();
|
||||
void oldDrawPlayerIcons ();
|
||||
void drawGameOverText (const float dt);
|
||||
|
@ -134,19 +134,20 @@ void RaceMenu::select()
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RaceMenu::inputKeyboard(int key, int pressed)
|
||||
void RaceMenu::handle(GameAction ga, int value)
|
||||
{
|
||||
switch ( key )
|
||||
switch ( ga )
|
||||
{
|
||||
case SDLK_ESCAPE: //ESC
|
||||
if(!pressed)
|
||||
case GA_LEAVE:
|
||||
if (value)
|
||||
break;
|
||||
|
||||
world->unpause();
|
||||
menu_manager->popMenu();
|
||||
break;
|
||||
|
||||
default:
|
||||
BaseGUI::inputKeyboard(key, pressed);
|
||||
BaseGUI::handle(ga, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
~RaceMenu();
|
||||
|
||||
void select();
|
||||
void inputKeyboard(int key, int pressed);
|
||||
void handle(GameAction ga, int value);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -204,14 +204,14 @@ void RaceResultsGUI::select()
|
||||
} // select
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
RaceResultsGUI::inputKeyboard(int key, int pressed)
|
||||
RaceResultsGUI::handle(GameAction ga, int value)
|
||||
{
|
||||
// Attempts to close the menu are silently discarded
|
||||
// since they do not make sense at this point.
|
||||
if (key == SDLK_ESCAPE)
|
||||
if (ga == GA_LEAVE)
|
||||
return;
|
||||
else
|
||||
BaseGUI::inputKeyboard(key, pressed);
|
||||
BaseGUI::handle(ga, value);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
RaceResultsGUI();
|
||||
~RaceResultsGUI();
|
||||
|
||||
void inputKeyboard(int, int);
|
||||
void handle(GameAction, int);
|
||||
|
||||
void select();
|
||||
};
|
||||
|
200
src/input.hpp
Normal file
200
src/input.hpp
Normal file
@ -0,0 +1,200 @@
|
||||
#ifndef TUXKART_INPUT_H
|
||||
#define TUXKART_INPUT_H
|
||||
|
||||
#include <string>
|
||||
|
||||
enum AxisDirection {
|
||||
AD_NEGATIVE,
|
||||
AD_POSITIVE,
|
||||
AD_NEUTRAL
|
||||
};
|
||||
|
||||
enum InputType {
|
||||
IT_NONE = 0,
|
||||
IT_KEYBOARD,
|
||||
IT_STICKMOTION,
|
||||
IT_STICKBUTTON,
|
||||
IT_STICKHAT,
|
||||
IT_MOUSEMOTION,
|
||||
IT_MOUSEBUTTON
|
||||
};
|
||||
const int IT_LAST = IT_MOUSEBUTTON;
|
||||
|
||||
struct Input
|
||||
{
|
||||
InputType type;
|
||||
int id0;
|
||||
int id1;
|
||||
int id2;
|
||||
|
||||
// Esoteric C++ feature alarm: structs are classes where the fields and
|
||||
// methods are public by default. I just needed some convenient constructors
|
||||
// for this struct.
|
||||
Input()
|
||||
: type(IT_NONE), id0(0), id1(0), id2(0)
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/** Creates an Input instance which represents an arbitrary way of getting
|
||||
* game input using a type specifier and 3 integers.
|
||||
*
|
||||
* Meaning of the 3 integers for each InputType:
|
||||
* IT_NONE: This means nothing. In certain cases this is regarded as an
|
||||
* unset binding.
|
||||
* IT_KEYBOARD: id0 is an SDLKey value.
|
||||
* IT_STICKMOTION: id0 - stick index, id1 - axis index, id2 - axis direction
|
||||
* (negative, positive). You can assume that axis 0 is the X-Axis where the
|
||||
* negative direction is to the left and that axis 1 is the Y-Axis with the
|
||||
* negative direction being upwards.
|
||||
* IT_STICKBUTTON: id0 - stick index, id1 - button index. Button 0 and 1 are
|
||||
* usually reached most easily.
|
||||
* IT_STICKHAT: This is not yet implemented.
|
||||
* IT_MOUSEMOTION: id0 - axis index (0 -> X, 1 -> Y). Mouse wheel is
|
||||
* represented as buttons!
|
||||
* IT_MOUSEBUTTON: id0 - button number (1 -> left, 2 -> middle, 3 -> right,
|
||||
* ...)
|
||||
*
|
||||
* Note: For joystick bindings that are actice in the menu the joystick's
|
||||
* index should be zero. The binding will react to all joysticks connected
|
||||
* to the system.
|
||||
*/
|
||||
Input(InputType ntype, int nid0 , int nid1 = 0, int nid2= 0)
|
||||
: type(ntype), id0(nid0), id1(nid1), id2(nid2)
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
};
|
||||
|
||||
//When adding any action at the beginning or at the end, remember to update
|
||||
//the KA_FIRST and/or KA_LAST constants.
|
||||
enum KartAction {
|
||||
KA_LEFT,
|
||||
KA_RIGHT,
|
||||
KA_ACCEL,
|
||||
KA_BRAKE,
|
||||
KA_WHEELIE,
|
||||
KA_JUMP,
|
||||
KA_RESCUE,
|
||||
KA_FIRE,
|
||||
KA_LOOK_BACK
|
||||
};
|
||||
const int KA_FIRST = KA_LEFT;
|
||||
const int KA_LAST = KA_LOOK_BACK;
|
||||
const int KC_COUNT = (KA_LAST + 1);
|
||||
|
||||
enum GameAction
|
||||
{
|
||||
// Below this are synthetic game actions which are never triggered through
|
||||
// an input device.
|
||||
GA_NULL, // Nothing dummy entry.
|
||||
GA_SENSE_CANCEL, // Input sensing canceled.
|
||||
GA_SENSE_COMPLETE, // Input sensing successfully finished.
|
||||
|
||||
// Below this point are the game actions which can happen while in menu
|
||||
// mode.
|
||||
|
||||
GA_ENTER, // Enter menu, acknowledge, ...
|
||||
GA_LEAVE, // Leave a menu.
|
||||
|
||||
GA_CLEAR_MAPPING, // Clear an input mapping.
|
||||
|
||||
GA_INC_SCROLL_SPEED,
|
||||
GA_INC_SCROLL_SPEED_FAST,
|
||||
GA_DEC_SCROLL_SPEED,
|
||||
GA_DEC_SCROLL_SPEED_FAST,
|
||||
|
||||
GA_CURSOR_UP,
|
||||
GA_CURSOR_DOWN,
|
||||
GA_CURSOR_LEFT,
|
||||
GA_CURSOR_RIGHT,
|
||||
|
||||
// The following game actions occur when in ingame mode (= within a race).
|
||||
|
||||
GA_P1_LEFT,
|
||||
GA_P1_RIGHT,
|
||||
GA_P1_ACCEL,
|
||||
GA_P1_BRAKE,
|
||||
GA_P1_WHEELIE,
|
||||
GA_P1_JUMP,
|
||||
GA_P1_RESCUE,
|
||||
GA_P1_FIRE,
|
||||
GA_P1_LOOK_BACK,
|
||||
|
||||
GA_P2_LEFT,
|
||||
GA_P2_RIGHT,
|
||||
GA_P2_ACCEL,
|
||||
GA_P2_BRAKE,
|
||||
GA_P2_WHEELIE,
|
||||
GA_P2_JUMP,
|
||||
GA_P2_RESCUE,
|
||||
GA_P2_FIRE,
|
||||
GA_P2_LOOK_BACK,
|
||||
|
||||
GA_P3_LEFT,
|
||||
GA_P3_RIGHT,
|
||||
GA_P3_ACCEL,
|
||||
GA_P3_BRAKE,
|
||||
GA_P3_WHEELIE,
|
||||
GA_P3_JUMP,
|
||||
GA_P3_RESCUE,
|
||||
GA_P3_FIRE,
|
||||
GA_P3_LOOK_BACK,
|
||||
|
||||
GA_P4_LEFT,
|
||||
GA_P4_RIGHT,
|
||||
GA_P4_ACCEL,
|
||||
GA_P4_BRAKE,
|
||||
GA_P4_WHEELIE,
|
||||
GA_P4_JUMP,
|
||||
GA_P4_RESCUE,
|
||||
GA_P4_FIRE,
|
||||
GA_P4_LOOK_BACK,
|
||||
|
||||
GA_TOGGLE_FULLSCREEN, // Switch between windowed/fullscreen mode
|
||||
GA_LEAVE_RACE, // Switch from race to menu.
|
||||
|
||||
GA_DEBUG_ADD_MISSILE,
|
||||
GA_DEBUG_TOGGLE_FPS,
|
||||
GA_DEBUG_BULLET,
|
||||
GA_DEBUG_TOGGLE_WIREFRAME,
|
||||
GA_DEBUG_HISTORY
|
||||
|
||||
};
|
||||
/* Some constants to make future changes more easier to handle. If you use
|
||||
* any of the GameAction constants to mark the beginning or end of a range
|
||||
* or denote a count then something is wrong with your code. ;)
|
||||
*/
|
||||
|
||||
/** Generally the first GameAction constant. Unlikely to change. */
|
||||
const int GA_FIRST = GA_NULL;
|
||||
|
||||
/** A usefull value for array allocations. Should always be to the
|
||||
* last constant + 1.
|
||||
*/
|
||||
const int GA_COUNT = (GA_DEBUG_HISTORY + 1);
|
||||
|
||||
/* The range of GameAction constants that is used while in menu mode. */
|
||||
const int GA_FIRST_MENU = GA_ENTER;
|
||||
const int GA_LAST_MENU = GA_CURSOR_RIGHT;
|
||||
|
||||
/* The range of GameAction constants that is used while in ingame (race) mode. */
|
||||
const int GA_FIRST_INGAME = GA_P1_LEFT;
|
||||
const int GA_LAST_INGAME = GA_DEBUG_HISTORY;
|
||||
|
||||
/* The range of GameAction constants which are used ingame but are considered
|
||||
* fixed and their Inputs should not be used by the players.
|
||||
*/
|
||||
const int GA_FIRST_INGAME_FIXED = GA_TOGGLE_FULLSCREEN;
|
||||
const int GA_LAST_INGAME_FIXED = GA_DEBUG_HISTORY;
|
||||
|
||||
/** The range of GameAction constants that defines the mapping
|
||||
for the players kart actions. Besides that these are the actions
|
||||
whose mappings are changeable by the user (via menu & config file).
|
||||
When looking for conflicting mappings only the user changeable
|
||||
GameAction constants are regarded.
|
||||
*/
|
||||
const int GA_FIRST_KARTACTION = GA_P1_LEFT;
|
||||
const int GA_LAST_KARTACTION = GA_P4_LOOK_BACK;
|
||||
|
||||
#endif
|
@ -391,6 +391,7 @@ int main(int argc, char *argv[] )
|
||||
|
||||
//FIXME: this needs a better organization
|
||||
drv_init();
|
||||
|
||||
game_manager = new GameManager ();
|
||||
// loadMaterials needs ssgLoadTextures (internally), which can
|
||||
// only be called after ssgInit (since this adds the actual loader)
|
||||
|
@ -21,42 +21,16 @@
|
||||
#define TUXKART_PLAYER_H
|
||||
|
||||
#include <string>
|
||||
#include "input.hpp"
|
||||
|
||||
enum AxisDirection { AD_NEGATIVE, AD_POSITIVE };
|
||||
extern const char *sKartAction2String[KA_LAST+1];
|
||||
|
||||
enum InputType { IT_NONE, IT_KEYBOARD, IT_STICKMOTION, IT_STICKBUTTON, IT_STICKHAT, IT_MOUSEMOTION, IT_MOUSEBUTTON };
|
||||
#define IT_LAST (IT_MOUSEBUTTON)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
InputType type;
|
||||
int id0;
|
||||
int id1;
|
||||
int id2;
|
||||
}
|
||||
Input;
|
||||
|
||||
//When adding any action at the beginning or at the end, remember to update
|
||||
//the KC_FIRST and/or KC_LAST constants.
|
||||
enum KartActions { KC_LEFT,
|
||||
KC_RIGHT,
|
||||
KC_ACCEL,
|
||||
KC_BRAKE,
|
||||
KC_WHEELIE,
|
||||
KC_JUMP,
|
||||
KC_RESCUE,
|
||||
KC_FIRE,
|
||||
KC_LOOK_BACK };
|
||||
const int KC_FIRST = KC_LEFT;
|
||||
const int KC_LAST = KC_LOOK_BACK;
|
||||
|
||||
extern const char *sKartAction2String[KC_LAST+1];
|
||||
/*class for managing player name and control configuration*/
|
||||
class Player
|
||||
{
|
||||
private:
|
||||
std::string m_name;
|
||||
Input m_action_map[KC_LAST+1];
|
||||
Input m_action_map[KA_LAST+1];
|
||||
unsigned int m_last_kart_id;
|
||||
|
||||
public:
|
||||
@ -64,21 +38,8 @@ public:
|
||||
Player(const std::string &name_):m_name(name_){}
|
||||
void setName(const std::string &name_){m_name = name_;}
|
||||
|
||||
void setKey(KartActions action, int key) {}
|
||||
void setButton(KartActions action, int button){ }
|
||||
|
||||
std::string getName() {return m_name;}
|
||||
|
||||
Input *getInput(KartActions action) { return &m_action_map[action]; }
|
||||
void setInput(KartActions action, InputType type, int id0, int id1, int id2)
|
||||
{
|
||||
Input *i = &m_action_map[action];
|
||||
i->type = type;
|
||||
i->id0 = id0;
|
||||
i->id1 = id1;
|
||||
i->id2 = id2;
|
||||
}
|
||||
|
||||
unsigned int getLastKartId(){ return m_last_kart_id; }
|
||||
void setLastKartId(int newLastKartId){ m_last_kart_id = newLastKartId; }
|
||||
};
|
||||
|
@ -30,11 +30,11 @@
|
||||
#include "translation.hpp"
|
||||
#include "camera.hpp"
|
||||
|
||||
void PlayerKart::action(KartActions action, int value)
|
||||
void PlayerKart::action(KartAction action, int value)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case KC_LEFT:
|
||||
case KA_LEFT:
|
||||
m_steer_val_l = -value;
|
||||
if (value)
|
||||
m_steer_val = -value;
|
||||
@ -42,7 +42,7 @@ void PlayerKart::action(KartActions action, int value)
|
||||
m_steer_val = m_steer_val_r;
|
||||
|
||||
break;
|
||||
case KC_RIGHT:
|
||||
case KA_RIGHT:
|
||||
m_steer_val_r = value;
|
||||
if (value)
|
||||
m_steer_val = value;
|
||||
@ -50,27 +50,27 @@ void PlayerKart::action(KartActions action, int value)
|
||||
m_steer_val = m_steer_val_l;
|
||||
|
||||
break;
|
||||
case KC_ACCEL:
|
||||
case KA_ACCEL:
|
||||
m_accel_val = value;
|
||||
break;
|
||||
case KC_BRAKE:
|
||||
case KA_BRAKE:
|
||||
if (value)
|
||||
m_accel_val = 0;
|
||||
m_controls.brake = value;
|
||||
break;
|
||||
case KC_WHEELIE:
|
||||
case KA_WHEELIE:
|
||||
m_controls.wheelie = value;
|
||||
break;
|
||||
case KC_RESCUE:
|
||||
case KA_RESCUE:
|
||||
m_controls.rescue = value;
|
||||
break;
|
||||
case KC_FIRE:
|
||||
case KA_FIRE:
|
||||
m_controls.fire = value;
|
||||
break;
|
||||
case KC_LOOK_BACK:
|
||||
case KA_LOOK_BACK:
|
||||
m_camera->setReverseHeading(value);
|
||||
break;
|
||||
case KC_JUMP:
|
||||
case KA_JUMP:
|
||||
m_controls.jump = value;
|
||||
break;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
Player* getPlayer () {return m_player; }
|
||||
void update (float);
|
||||
void addMessages ();
|
||||
void action (KartActions action, int value);
|
||||
void action (KartAction action, int value);
|
||||
void forceCrash ();
|
||||
void handleZipper ();
|
||||
void collectedHerring (Herring* herring);
|
||||
|
410
src/sdldrv.cpp
410
src/sdldrv.cpp
@ -17,10 +17,14 @@
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#include <plib/ssg.h>
|
||||
|
||||
#include "input.hpp"
|
||||
#include "actionmap.hpp"
|
||||
#include "user_config.hpp"
|
||||
#include "sdldrv.hpp"
|
||||
#include "material_manager.hpp"
|
||||
@ -34,17 +38,27 @@
|
||||
#include "gui/menu_manager.hpp"
|
||||
#include "player.hpp"
|
||||
#include "gui/font.hpp"
|
||||
#include "user_config.hpp"
|
||||
|
||||
Input *sensedInput = 0;
|
||||
ActionMap *actionMap = 0;
|
||||
|
||||
SDL_Surface *mainSurface;
|
||||
long flags;
|
||||
SDL_Joystick **sticks;
|
||||
StickInfo **stickInfos = 0;
|
||||
|
||||
bool pointerVisible = true;
|
||||
InputDriverMode mode = BOOTSTRAP;
|
||||
|
||||
#define DEADZONE_MOUSE 1
|
||||
#define DEADZONE_MOUSE 150
|
||||
#define DEADZONE_MOUSE_SENSE 200
|
||||
#define DEADZONE_JOYSTICK 1000
|
||||
|
||||
#define MULTIPLIER_MOUSE 750
|
||||
|
||||
/** Helper values to store and track the relative mouse movements. If these
|
||||
* values exceed the deadzone value the input is reported to the game. This
|
||||
* Makes the mouse behave like an analog axis on a gamepad/joystick.
|
||||
*/
|
||||
int mouseValX = 0;
|
||||
int mouseValY = 0;
|
||||
|
||||
@ -63,28 +77,29 @@ void drv_init()
|
||||
|
||||
SDL_JoystickEventState(SDL_ENABLE);
|
||||
|
||||
const int NUM_STICKS = SDL_NumJoysticks();
|
||||
sticks = (SDL_Joystick **) malloc(sizeof(SDL_Joystick *) * NUM_STICKS);
|
||||
for (int i=0;i<NUM_STICKS;i++)
|
||||
sticks[i] = SDL_JoystickOpen(i);
|
||||
const int numSticks = SDL_NumJoysticks();
|
||||
stickInfos = new StickInfo *[numSticks];
|
||||
for (int i = 0; i < numSticks; i++)
|
||||
stickInfos[i] = new StickInfo(i);
|
||||
|
||||
SDL_WM_SetCaption("SuperTuxKart", NULL);
|
||||
|
||||
ssgInit () ;
|
||||
|
||||
// Get into menu mode initially.
|
||||
drv_setMode(MENU);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
drv_showPointer()
|
||||
showPointer()
|
||||
{
|
||||
pointerVisible = true;
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
drv_hidePointer()
|
||||
hidePointer()
|
||||
{
|
||||
pointerVisible = false;
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -99,10 +114,10 @@ void drv_toggleFullscreen(int resetTextures)
|
||||
flags |= SDL_FULLSCREEN;
|
||||
|
||||
if(menu_manager->isSomewhereOnStack(MENUID_RACE))
|
||||
drv_showPointer();
|
||||
showPointer();
|
||||
}
|
||||
else if(menu_manager->isSomewhereOnStack(MENUID_RACE))
|
||||
drv_hidePointer();
|
||||
hidePointer();
|
||||
|
||||
SDL_FreeSurface(mainSurface);
|
||||
mainSurface = SDL_SetVideoMode(user_config->m_width, user_config->m_height, 0, flags);
|
||||
@ -149,9 +164,9 @@ void drv_deinit()
|
||||
{
|
||||
const int NUM_STICKS = SDL_NumJoysticks();
|
||||
for (int i=0;i<NUM_STICKS;i++)
|
||||
SDL_JoystickClose(sticks[i]);
|
||||
delete stickInfos[i];
|
||||
|
||||
free(sticks);
|
||||
delete stickInfos;
|
||||
|
||||
SDL_FreeSurface(mainSurface);
|
||||
|
||||
@ -159,14 +174,73 @@ void drv_deinit()
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Handles the conversion from some input to a GameAction and its distribution
|
||||
* to the currently active menu.
|
||||
* It also handles whether the game is currently sensing input. It does so by
|
||||
* suppressing the distribution of the input as a GameAction. Instead the
|
||||
* input is stored in 'sensedInput' and GA_SENSE_COMPLETE is distributed. If
|
||||
* however the input in question has resolved to GA_LEAVE this is treated as
|
||||
* an attempt of the user to cancel the sensing. In that case GA_SENSE_CANCEL
|
||||
* is distributed.
|
||||
*
|
||||
* Note: It is the obligation of the called menu to switch of the sense mode.
|
||||
*
|
||||
*/
|
||||
void input(InputType type, int id0, int id1, int id2, int value)
|
||||
{
|
||||
BaseGUI* menu= menu_manager->getCurrentMenu();
|
||||
BaseGUI* menu = menu_manager->getCurrentMenu();
|
||||
|
||||
GameAction ga = actionMap->getEntry(type, id0, id1, id2);
|
||||
|
||||
if (menu != NULL)
|
||||
menu->input(type, id0, id1, id2, value);
|
||||
{
|
||||
// Act different in input sensing mode.
|
||||
if (mode == INPUT_SENSE)
|
||||
{
|
||||
// Input sensing should be canceled.
|
||||
if (ga == GA_LEAVE)
|
||||
{
|
||||
menu->handle(GA_SENSE_CANCEL, value);
|
||||
}
|
||||
// Stores the sensed input when the button/key/axes/<whatever> is
|
||||
// released only and is not used in a fixed mapping.
|
||||
else if (!(value || user_config->isFixedInput(type, id0, id1, id2)))
|
||||
{
|
||||
sensedInput->type = type;
|
||||
sensedInput->id0 = id0;
|
||||
sensedInput->id1 = id1;
|
||||
sensedInput->id2 = id2;
|
||||
|
||||
// Notify the completion of the input sensing.
|
||||
menu->handle(GA_SENSE_COMPLETE, 0);
|
||||
}
|
||||
}
|
||||
else if (ga != GA_NULL)
|
||||
{
|
||||
// Lets the currently active menu handle the GameAction.
|
||||
menu->handle(ga, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Reads the SDL event loop, does some tricks with certain values and calls
|
||||
* input() is appropriate.
|
||||
*
|
||||
* Digital inputs get the value of 32768 when pressed (key/button press,
|
||||
* digital axis) because this is what SDL provides. Relative mouse inputs
|
||||
* which do not fit into this scheme are converted to match. This is done to
|
||||
* relieve the KartAction implementor from the need to think about different
|
||||
* input devices and how SDL treats them. The same input gets the value of 0
|
||||
* when released.
|
||||
*
|
||||
* Analog axes can have any value from [0, 32768].
|
||||
*
|
||||
* There are no negative values. Instead this is reported as an axis with a
|
||||
* negative direction. This simplifies input configuration and allows greater
|
||||
* flexibility (= treat 4 directions as four buttons).
|
||||
*
|
||||
*/
|
||||
void drv_loop()
|
||||
{
|
||||
SDL_Event ev;
|
||||
@ -180,33 +254,58 @@ void drv_loop()
|
||||
break;
|
||||
|
||||
case SDL_KEYUP:
|
||||
input(IT_KEYBOARD, ev.key.keysym.sym, ev.key.keysym.unicode, 0, 0);
|
||||
input(IT_KEYBOARD, ev.key.keysym.sym, 0, 0, 0);
|
||||
break;
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
input(IT_KEYBOARD, ev.key.keysym.sym, ev.key.keysym.unicode, 0, 32768);
|
||||
if (mode == LOWLEVEL)
|
||||
{
|
||||
// Unicode translation in SDL is only done for keydown events.
|
||||
// Therefore for lowlevel keyboard handling we provide no notion
|
||||
// of whether a key was pressed or released.
|
||||
menu_manager->getCurrentMenu()
|
||||
->inputKeyboard(ev.key.keysym.sym,
|
||||
ev.key.keysym.unicode);
|
||||
}
|
||||
input(IT_KEYBOARD, ev.key.keysym.sym,
|
||||
ev.key.keysym.unicode, 0, 32768);
|
||||
|
||||
break;
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
if (pointerVisible)
|
||||
// Reports absolute pointer values on a separate path to the menu
|
||||
// system to avoid the trouble that arises because all other input
|
||||
// methods have only one value to inspect (pressed/release,
|
||||
// axis value) while the pointer has two.
|
||||
if (!mode)
|
||||
{
|
||||
BaseGUI* menu= menu_manager->getCurrentMenu();
|
||||
BaseGUI* menu = menu_manager->getCurrentMenu();
|
||||
if (menu != NULL)
|
||||
menu->inputPointer(ev.motion.x, mainSurface->h - ev.motion.y);
|
||||
}
|
||||
// If sensing input mouse movements are made less sensitive in order
|
||||
// to avoid it being detected unwantedly.
|
||||
else if (mode == INPUT_SENSE)
|
||||
{
|
||||
if (ev.motion.xrel <= -DEADZONE_MOUSE_SENSE)
|
||||
input(IT_MOUSEMOTION, 0, AD_NEGATIVE, 0, 0);
|
||||
else if (ev.motion.xrel >= DEADZONE_MOUSE_SENSE)
|
||||
input(IT_MOUSEMOTION, 0, AD_POSITIVE, 0, 0);
|
||||
|
||||
// Reset parameters for relative mouse handling to make sure we are
|
||||
// in a valid state when returning to relative mouse mode
|
||||
mouseValX = mouseValY = 0;
|
||||
if (ev.motion.yrel <= -DEADZONE_MOUSE_SENSE)
|
||||
input(IT_MOUSEMOTION, 1, AD_NEGATIVE, 0, 0);
|
||||
else if (ev.motion.yrel >= DEADZONE_MOUSE_SENSE)
|
||||
input(IT_MOUSEMOTION, 1, AD_POSITIVE, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
mouseValX = std::max(-32768,
|
||||
std::min(32768, mouseValX
|
||||
+ ev.motion.xrel
|
||||
// Calculates new values for the mouse helper variables. It
|
||||
// keeps them in the [-32768, 32768] range. The same values are
|
||||
// used by SDL for stick axes.
|
||||
mouseValX = std::max(-32768, std::min(32768,
|
||||
mouseValX + ev.motion.xrel
|
||||
* MULTIPLIER_MOUSE));
|
||||
mouseValY = std::max(-32768,
|
||||
std::min(32768, mouseValY
|
||||
+ ev.motion.yrel
|
||||
std::min(32768, mouseValY + ev.motion.yrel
|
||||
* MULTIPLIER_MOUSE));
|
||||
}
|
||||
break;
|
||||
@ -219,37 +318,266 @@ void drv_loop()
|
||||
break;
|
||||
|
||||
case SDL_JOYAXISMOTION:
|
||||
// If the joystick axis exceeds the deadzone report the input.
|
||||
// In menu mode (mode = MENU = 0) the joystick number is reported
|
||||
// to be zero in all cases. This has the neat effect that all
|
||||
// joysticks can be used to control the menu.
|
||||
if(ev.jaxis.value <= -DEADZONE_JOYSTICK)
|
||||
input(IT_STICKMOTION, ev.jaxis.which, ev.jaxis.axis, AD_NEGATIVE, -ev.jaxis.value);
|
||||
else if(ev.jaxis.value <= 0)
|
||||
input(IT_STICKMOTION, ev.jaxis.which, ev.jaxis.axis, AD_NEGATIVE, 0);
|
||||
{
|
||||
input(IT_STICKMOTION, !mode ? 0 : ev.jaxis.which,
|
||||
ev.jaxis.axis, AD_NEGATIVE, -ev.jaxis.value);
|
||||
stickInfos[ev.jaxis.which]->prevAxisDirections[ev.jaxis.axis]
|
||||
= AD_NEGATIVE;
|
||||
}
|
||||
else if(ev.jaxis.value >= DEADZONE_JOYSTICK)
|
||||
{
|
||||
input(IT_STICKMOTION, !mode ? 0 : ev.jaxis.which,
|
||||
ev.jaxis.axis, AD_POSITIVE, ev.jaxis.value);
|
||||
stickInfos[ev.jaxis.which]->prevAxisDirections[ev.jaxis.axis]
|
||||
= AD_POSITIVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Axis stands still: This is reported once for digital axes and
|
||||
// can be called multipled times for analog ones. Uses the
|
||||
// previous direction in which the axis was triggered to
|
||||
// determine which one has to be brought into the released
|
||||
// state. This allows us to regard two directions of an axis
|
||||
// as completely independent input variants (as if they where
|
||||
// two buttons).
|
||||
if (stickInfos[ev.jaxis.which]
|
||||
->prevAxisDirections[ev.jaxis.axis] == AD_NEGATIVE)
|
||||
input(IT_STICKMOTION, !mode ? 0 : ev.jaxis.which,
|
||||
ev.jaxis.axis, AD_NEGATIVE, 0);
|
||||
else if (stickInfos[ev.jaxis.which]
|
||||
->prevAxisDirections[ev.jaxis.axis] == AD_POSITIVE)
|
||||
input(IT_STICKMOTION, !mode ? 0 : ev.jaxis.which,
|
||||
ev.jaxis.axis, AD_POSITIVE, 0);
|
||||
|
||||
if(ev.jaxis.value >= DEADZONE_JOYSTICK)
|
||||
input(IT_STICKMOTION, ev.jaxis.which, ev.jaxis.axis, AD_POSITIVE, ev.jaxis.value);
|
||||
else if(ev.jaxis.value >= 0)
|
||||
input(IT_STICKMOTION, ev.jaxis.which, ev.jaxis.axis, AD_POSITIVE, 0);
|
||||
stickInfos[ev.jaxis.which]->prevAxisDirections[ev.jaxis.axis]
|
||||
= AD_NEUTRAL;
|
||||
}
|
||||
|
||||
break;
|
||||
case SDL_JOYBUTTONUP:
|
||||
input(IT_STICKBUTTON, ev.jbutton.which, ev.jbutton.button, 0,
|
||||
// See the SDL_JOYAXISMOTION case label because of !mode thingie.
|
||||
input(IT_STICKBUTTON, !mode ? 0 : ev.jbutton.which, ev.jbutton.button, 0,
|
||||
0);
|
||||
break;
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
input(IT_STICKBUTTON, ev.jbutton.which, ev.jbutton.button, 0,
|
||||
// See the SDL_JOYAXISMOTION case label because of !mode thingie.
|
||||
input(IT_STICKBUTTON, !mode ? 0 : ev.jbutton.which, ev.jbutton.button, 0,
|
||||
32768);
|
||||
break;
|
||||
} // switch
|
||||
} // while (SDL_PollEvent())
|
||||
|
||||
// Makes mouse behave like an analog axis.
|
||||
if (mouseValX <= DEADZONE_MOUSE)
|
||||
if (mouseValX <= -DEADZONE_MOUSE)
|
||||
input(IT_MOUSEMOTION, 0, AD_NEGATIVE, 0, -mouseValX);
|
||||
else if (mouseValX >= DEADZONE_MOUSE)
|
||||
input(IT_MOUSEMOTION, 0, AD_POSITIVE, 0, mouseValX);
|
||||
else
|
||||
mouseValX = 0;
|
||||
|
||||
if (mouseValY <= DEADZONE_MOUSE)
|
||||
if (mouseValY <= -DEADZONE_MOUSE)
|
||||
input(IT_MOUSEMOTION, 1, AD_NEGATIVE, 0, -mouseValY);
|
||||
else if (mouseValY >= DEADZONE_MOUSE)
|
||||
input(IT_MOUSEMOTION, 1, AD_POSITIVE, 0, mouseValY);
|
||||
else
|
||||
mouseValY = 0;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Retrieves the Input instance that has been prepared in the input sense
|
||||
* mode.
|
||||
*
|
||||
* The Instance has valid values of the last input sensing operation *only*
|
||||
* if called immediately after a BaseGUI::handle() implementation received
|
||||
* GA_SENSE_COMPLETE.
|
||||
*
|
||||
* It is wrong to call it when not in input sensing mode anymore.
|
||||
*/
|
||||
Input &
|
||||
drv_getSensedInput()
|
||||
{
|
||||
assert (mode == INPUT_SENSE);
|
||||
|
||||
// sensedInput should be available in input sense mode.
|
||||
assert (sensedInput);
|
||||
|
||||
return *sensedInput;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Queries the input driver whether it is in the given expected mode.
|
||||
*/
|
||||
bool
|
||||
drv_isInMode(InputDriverMode expMode)
|
||||
{
|
||||
return mode == expMode;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Sets the mode of the input driver.
|
||||
*
|
||||
* Switching of the input driver's modes is only needed for special menus
|
||||
* (those who need typing or input sensing) and the MenuManager (switch to
|
||||
* ingame/menu mode). Therefore there is a limited amount of legal combinations
|
||||
* of current and next input driver modes: From the menu mode you can switch
|
||||
* to any other mode and from any other mode only back to the menu mode.
|
||||
*
|
||||
* In menu mode the pointer is visible (and reports absolute values through
|
||||
* BaseGUI::inputKeyboard()) and the BaseGUI::handle() implementations can
|
||||
* receive GameAction values from GA_FIRST_MENU to GA_LAST_MENU.
|
||||
*
|
||||
* In ingame mode the pointer is invisible (and reports relative values)
|
||||
* and the BaseGUI::handle() implementations can receive GameAction values
|
||||
* from GA_FIRST_INGAME to GA_LAST_INGAME.
|
||||
*
|
||||
* In input sense mode the pointer is invisible (any movement reports are
|
||||
* suppressed). If an input happens it is stored internally and can be
|
||||
* retrieved through drv_getSensedInput() *after* GA_SENSE_COMPLETE has been
|
||||
* distributed to a menu (Normally the menu that received GA_SENSE_COMPLETE
|
||||
* will request the sensed input ...). If GA_SENSE_CANCEL is received instead
|
||||
* the user decided to cancel input sensing. No other game action values are
|
||||
* distributed in this mode.
|
||||
*
|
||||
* In lowlevel mode the pointer is invisible (and reports relative values -
|
||||
* this is just a side effect). BaseGUI::handle() can receive GameAction
|
||||
* values from GA_FIRST_MENU to GA_LAST_MENU. Additionally each key press is
|
||||
* distributed through BaseGUI::inputKeyboard(). This happens *before* the
|
||||
* same keypress is processed to be distributed as a GameAction. This was done
|
||||
* to make the effects of changing the input driver's mode from
|
||||
* BaseGUI::handle() implementations less strange. The way it is implemented
|
||||
* makes sure that such a change only affects the next keypress or keyrelease.
|
||||
* The same is not true for mode changes from within a BaseGUI::inputKeyboard()
|
||||
* implementation. It is therefore discouraged.
|
||||
*
|
||||
* And there is the bootstrap mode. You cannot switch to it and only leave it
|
||||
* once per application instance. It is the state the input driver is first.
|
||||
*
|
||||
*/
|
||||
void
|
||||
drv_setMode(InputDriverMode newMode)
|
||||
{
|
||||
switch (newMode)
|
||||
{
|
||||
case MENU:
|
||||
switch (mode)
|
||||
{
|
||||
case INGAME:
|
||||
// Leaving ingame mode.
|
||||
|
||||
if (actionMap)
|
||||
delete actionMap;
|
||||
|
||||
// Reset the helper values for the relative mouse movement
|
||||
// supresses to the notification of them as an input.
|
||||
mouseValX = mouseValY = 0;
|
||||
|
||||
showPointer();
|
||||
|
||||
// Fall through expected.
|
||||
case BOOTSTRAP:
|
||||
// Leaving boot strap mode.
|
||||
|
||||
// Installs the action map for the menu.
|
||||
actionMap = user_config->newMenuActionMap();
|
||||
|
||||
mode = MENU;
|
||||
|
||||
break;
|
||||
case INPUT_SENSE:
|
||||
// Leaving input sense mode.
|
||||
|
||||
showPointer();
|
||||
|
||||
// The order is deliberate just in case someone starts to make
|
||||
// STK multithreaded: sensedInput must not be 0 when
|
||||
// mode == INPUT_SENSE.
|
||||
mode = MENU;
|
||||
|
||||
delete sensedInput;
|
||||
sensedInput = 0;
|
||||
|
||||
break;
|
||||
case LOWLEVEL:
|
||||
// Leaving lowlevel mode.
|
||||
|
||||
SDL_EnableUNICODE(SDL_DISABLE);
|
||||
|
||||
showPointer();
|
||||
|
||||
mode = MENU;
|
||||
|
||||
break;
|
||||
default:
|
||||
// Something is broken.
|
||||
assert (false);
|
||||
}
|
||||
|
||||
break;
|
||||
case INGAME:
|
||||
// We must be in menu mode now in order to switch.
|
||||
assert (mode == MENU);
|
||||
|
||||
if (actionMap)
|
||||
delete actionMap;
|
||||
|
||||
// Installs the action map for the ingame mode.
|
||||
actionMap = user_config->newIngameActionMap();
|
||||
|
||||
hidePointer();
|
||||
|
||||
mode = INGAME;
|
||||
|
||||
break;
|
||||
case INPUT_SENSE:
|
||||
// We must be in menu mode now in order to switch.
|
||||
assert (mode == MENU);
|
||||
|
||||
// Reset the helper values for the relative mouse movement supresses to
|
||||
// the notification of them as an input.
|
||||
mouseValX = mouseValY = 0;
|
||||
|
||||
sensedInput = new Input();
|
||||
|
||||
hidePointer();
|
||||
|
||||
mode = INPUT_SENSE;
|
||||
|
||||
break;
|
||||
case LOWLEVEL:
|
||||
// We must be in menu mode now in order to switch.
|
||||
assert (mode == MENU);
|
||||
|
||||
SDL_EnableUNICODE(SDL_ENABLE);
|
||||
|
||||
hidePointer();
|
||||
|
||||
mode = LOWLEVEL;
|
||||
|
||||
break;
|
||||
default:
|
||||
// Invalid mode.
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
StickInfo::StickInfo(int index)
|
||||
{
|
||||
sdlJoystick = SDL_JoystickOpen(index);
|
||||
const int count = SDL_JoystickNumAxes(sdlJoystick);
|
||||
prevAxisDirections = new AxisDirection[count];
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
prevAxisDirections[i] = AD_NEUTRAL;
|
||||
}
|
||||
|
||||
StickInfo::~StickInfo()
|
||||
{
|
||||
delete prevAxisDirections;
|
||||
|
||||
SDL_JoystickClose(sdlJoystick);
|
||||
}
|
||||
|
@ -20,16 +20,41 @@
|
||||
#ifndef HEADER_SDLDRV_H
|
||||
#define HEADER_SDLDRV_H
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#include "input.hpp"
|
||||
|
||||
class ActionMap;
|
||||
|
||||
enum MouseState { INITIAL, MOVED, RESET_NEEDED };
|
||||
|
||||
enum InputDriverMode {
|
||||
MENU = 0,
|
||||
INGAME,
|
||||
INPUT_SENSE,
|
||||
LOWLEVEL,
|
||||
BOOTSTRAP
|
||||
};
|
||||
|
||||
struct StickInfo {
|
||||
SDL_Joystick *sdlJoystick;
|
||||
AxisDirection *prevAxisDirections;
|
||||
|
||||
StickInfo(int);
|
||||
~StickInfo();
|
||||
};
|
||||
|
||||
void drv_init();
|
||||
void drv_deinit();
|
||||
|
||||
void drv_showPointer();
|
||||
void drv_hidePointer();
|
||||
|
||||
void drv_toggleFullscreen(int resetTextures=1);
|
||||
|
||||
void drv_loop();
|
||||
|
||||
void drv_setMode(InputDriverMode);
|
||||
bool drv_isInMode(InputDriverMode);
|
||||
|
||||
Input &drv_getSensedInput();
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
// for mkdir:
|
||||
#if !defined(WIN32) || defined(__CYGWIN__)
|
||||
@ -33,6 +34,7 @@
|
||||
#include <SDL/SDL.h>
|
||||
#include <plib/ul.h>
|
||||
|
||||
#include "actionmap.hpp"
|
||||
#include "user_config.hpp"
|
||||
#include "lisp/lisp.hpp"
|
||||
#include "lisp/parser.hpp"
|
||||
@ -42,6 +44,9 @@
|
||||
# define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace lisp;
|
||||
|
||||
UserConfig *user_config;
|
||||
|
||||
UserConfig::UserConfig()
|
||||
@ -65,7 +70,7 @@ UserConfig::~UserConfig()
|
||||
// -----------------------------------------------------------------------------
|
||||
std::string UserConfig::getConfigDir()
|
||||
{
|
||||
std::string DIRNAME;
|
||||
string DIRNAME;
|
||||
#ifdef WIN32
|
||||
// For now the old windows config way is used: store a config file
|
||||
// in the current directory (in other OS a special subdirectory is created)
|
||||
@ -142,50 +147,151 @@ void UserConfig::setDefaults()
|
||||
m_player[i].setName(m_username);
|
||||
}
|
||||
|
||||
// Clear every entry.
|
||||
memset(inputMap, sizeof(inputMap), 0);
|
||||
|
||||
/*player 1 default keyboard settings*/
|
||||
m_player[0].setInput(KC_LEFT, IT_KEYBOARD, SDLK_LEFT, 0, 0);
|
||||
m_player[0].setInput(KC_RIGHT, IT_KEYBOARD, SDLK_RIGHT, 0, 0);
|
||||
m_player[0].setInput(KC_ACCEL, IT_KEYBOARD, SDLK_UP, 0, 0);
|
||||
m_player[0].setInput(KC_BRAKE, IT_KEYBOARD, SDLK_DOWN, 0, 0);
|
||||
m_player[0].setInput(KC_WHEELIE,IT_KEYBOARD, SDLK_RSHIFT, 0, 0);
|
||||
m_player[0].setInput(KC_JUMP, IT_KEYBOARD, SDLK_MINUS, 0, 0);
|
||||
m_player[0].setInput(KC_RESCUE, IT_KEYBOARD, SDLK_BACKSPACE, 0, 0);
|
||||
m_player[0].setInput(KC_FIRE, IT_KEYBOARD, SDLK_RCTRL, 0, 0);
|
||||
m_player[0].setInput(KC_LOOK_BACK, IT_KEYBOARD, SDLK_RALT, 0, 0);
|
||||
/* general game input settings */
|
||||
set(GA_ENTER,
|
||||
Input(IT_KEYBOARD, SDLK_RETURN),
|
||||
Input(IT_KEYBOARD, SDLK_SPACE),
|
||||
Input(IT_STICKBUTTON, 0, 0),
|
||||
Input(IT_MOUSEBUTTON, 1));
|
||||
set(GA_LEAVE,
|
||||
Input(IT_KEYBOARD, SDLK_ESCAPE),
|
||||
Input(IT_STICKBUTTON, 0, 1),
|
||||
Input(IT_MOUSEBUTTON, 2),
|
||||
Input(IT_MOUSEBUTTON, 3));
|
||||
set(GA_CURSOR_UP,
|
||||
Input(IT_KEYBOARD, SDLK_UP),
|
||||
Input(IT_STICKMOTION, 0, 1, AD_NEGATIVE));
|
||||
|
||||
/*player 2 default keyboard settings*/
|
||||
m_player[1].setInput(KC_LEFT, IT_KEYBOARD, SDLK_a, 0, 0);
|
||||
m_player[1].setInput(KC_RIGHT, IT_KEYBOARD, SDLK_d, 0, 0);
|
||||
m_player[1].setInput(KC_ACCEL, IT_KEYBOARD, SDLK_w, 0, 0);
|
||||
m_player[1].setInput(KC_BRAKE, IT_KEYBOARD, SDLK_s, 0, 0);
|
||||
m_player[1].setInput(KC_WHEELIE,IT_KEYBOARD, SDLK_LSHIFT, 0, 0);
|
||||
m_player[1].setInput(KC_JUMP, IT_KEYBOARD, SDLK_CAPSLOCK, 0, 0);
|
||||
m_player[1].setInput(KC_RESCUE, IT_KEYBOARD, SDLK_q, 0, 0);
|
||||
m_player[1].setInput(KC_FIRE, IT_KEYBOARD, SDLK_LCTRL, 0, 0);
|
||||
m_player[1].setInput(KC_LOOK_BACK, IT_KEYBOARD, SDLK_LALT, 0, 0);
|
||||
set(GA_CURSOR_DOWN,
|
||||
Input(IT_KEYBOARD, SDLK_DOWN),
|
||||
Input(IT_STICKMOTION, 0, 1, AD_POSITIVE));
|
||||
|
||||
/*player 3 default keyboard settings*/
|
||||
m_player[2].setInput(KC_LEFT, IT_KEYBOARD, SDLK_f, 0, 0);
|
||||
m_player[2].setInput(KC_RIGHT, IT_KEYBOARD, SDLK_h, 0, 0);
|
||||
m_player[2].setInput(KC_ACCEL, IT_KEYBOARD, SDLK_t, 0, 0);
|
||||
m_player[2].setInput(KC_BRAKE, IT_KEYBOARD, SDLK_g, 0, 0);
|
||||
m_player[2].setInput(KC_WHEELIE,IT_KEYBOARD, SDLK_c, 0, 0);
|
||||
m_player[2].setInput(KC_JUMP, IT_KEYBOARD, SDLK_v, 0, 0);
|
||||
m_player[2].setInput(KC_RESCUE, IT_KEYBOARD, SDLK_r, 0, 0);
|
||||
m_player[2].setInput(KC_FIRE, IT_KEYBOARD, SDLK_b, 0, 0);
|
||||
m_player[2].setInput(KC_LOOK_BACK, IT_KEYBOARD, SDLK_n, 0, 0);
|
||||
set(GA_CURSOR_LEFT,
|
||||
Input(IT_KEYBOARD, SDLK_LEFT),
|
||||
Input(IT_STICKMOTION, 0, 0, AD_NEGATIVE));
|
||||
|
||||
set(GA_CURSOR_RIGHT,
|
||||
Input(IT_KEYBOARD, SDLK_RIGHT),
|
||||
Input(IT_STICKMOTION, 0, 0, AD_POSITIVE));
|
||||
|
||||
set(GA_CLEAR_MAPPING,
|
||||
Input(IT_KEYBOARD, SDLK_BACKSPACE),
|
||||
Input(IT_STICKBUTTON, 0, 2));
|
||||
|
||||
set(GA_INC_SCROLL_SPEED,
|
||||
Input(IT_KEYBOARD, SDLK_PLUS));
|
||||
set(GA_INC_SCROLL_SPEED_FAST,
|
||||
Input(IT_KEYBOARD, SDLK_PAGEDOWN));
|
||||
|
||||
set(GA_DEC_SCROLL_SPEED,
|
||||
Input(IT_KEYBOARD, SDLK_MINUS));
|
||||
set(GA_DEC_SCROLL_SPEED_FAST,
|
||||
Input(IT_KEYBOARD, SDLK_PAGEUP));
|
||||
|
||||
set(GA_TOGGLE_FULLSCREEN,
|
||||
Input(IT_KEYBOARD, SDLK_F9));
|
||||
set(GA_LEAVE_RACE,
|
||||
Input(IT_KEYBOARD, SDLK_ESCAPE));
|
||||
|
||||
set(GA_DEBUG_ADD_MISSILE,
|
||||
Input(IT_KEYBOARD, SDLK_F7));
|
||||
set(GA_DEBUG_TOGGLE_FPS,
|
||||
Input(IT_KEYBOARD, SDLK_F12));
|
||||
set(GA_DEBUG_TOGGLE_WIREFRAME,
|
||||
Input(IT_KEYBOARD, SDLK_F11));
|
||||
set(GA_DEBUG_HISTORY,
|
||||
Input(IT_KEYBOARD, SDLK_F10));
|
||||
set(GA_DEBUG_BULLET,
|
||||
Input(IT_KEYBOARD, SDLK_F2));
|
||||
|
||||
// TODO: The following should become a static
|
||||
// array. This allows:
|
||||
// a) resetting to default values
|
||||
// b) prevent loading those defaults if config file contains any bindings
|
||||
|
||||
/* Player 1 default input settings */
|
||||
set(GA_P1_LEFT,
|
||||
Input(IT_KEYBOARD, SDLK_LEFT));
|
||||
set(GA_P1_RIGHT,
|
||||
Input(IT_KEYBOARD, SDLK_RIGHT));
|
||||
set(GA_P1_ACCEL,
|
||||
Input(IT_KEYBOARD, SDLK_UP));
|
||||
set(GA_P1_BRAKE,
|
||||
Input(IT_KEYBOARD, SDLK_DOWN));
|
||||
set(GA_P1_WHEELIE,
|
||||
Input(IT_KEYBOARD, SDLK_RSHIFT));
|
||||
set(GA_P1_JUMP,
|
||||
Input(IT_KEYBOARD, SDLK_MINUS));
|
||||
set(GA_P1_RESCUE,
|
||||
Input(IT_KEYBOARD, SDLK_BACKSPACE));
|
||||
set(GA_P1_FIRE,
|
||||
Input(IT_KEYBOARD, SDLK_RCTRL));
|
||||
set(GA_P1_LOOK_BACK,
|
||||
Input(IT_KEYBOARD, SDLK_RALT));
|
||||
|
||||
/* Player 2 default input settings */
|
||||
set(GA_P2_LEFT,
|
||||
Input(IT_KEYBOARD, SDLK_a));
|
||||
set(GA_P2_RIGHT,
|
||||
Input(IT_KEYBOARD, SDLK_d));
|
||||
set(GA_P2_ACCEL,
|
||||
Input(IT_KEYBOARD, SDLK_w));
|
||||
set(GA_P2_BRAKE,
|
||||
Input(IT_KEYBOARD, SDLK_s));
|
||||
set(GA_P2_WHEELIE,
|
||||
Input(IT_KEYBOARD, SDLK_LSHIFT));
|
||||
set(GA_P2_JUMP,
|
||||
Input(IT_KEYBOARD, SDLK_CAPSLOCK));
|
||||
set(GA_P2_RESCUE,
|
||||
Input(IT_KEYBOARD, SDLK_q));
|
||||
set(GA_P2_FIRE,
|
||||
Input(IT_KEYBOARD, SDLK_LCTRL));
|
||||
set(GA_P2_LOOK_BACK,
|
||||
Input(IT_KEYBOARD, SDLK_LALT));
|
||||
|
||||
/* Player 3 default input settings */
|
||||
set(GA_P3_LEFT,
|
||||
Input(IT_KEYBOARD, SDLK_f));
|
||||
set(GA_P3_RIGHT,
|
||||
Input(IT_KEYBOARD, SDLK_h));
|
||||
set(GA_P3_ACCEL,
|
||||
Input(IT_KEYBOARD, SDLK_t));
|
||||
set(GA_P3_BRAKE,
|
||||
Input(IT_KEYBOARD, SDLK_g));
|
||||
set(GA_P3_WHEELIE,
|
||||
Input(IT_KEYBOARD, SDLK_c));
|
||||
set(GA_P3_JUMP,
|
||||
Input(IT_KEYBOARD, SDLK_v));
|
||||
set(GA_P3_RESCUE,
|
||||
Input(IT_KEYBOARD, SDLK_r));
|
||||
set(GA_P3_FIRE,
|
||||
Input(IT_KEYBOARD, SDLK_b));
|
||||
set(GA_P3_LOOK_BACK,
|
||||
Input(IT_KEYBOARD, SDLK_n));
|
||||
|
||||
/* Player 4 default input settings */
|
||||
set(GA_P4_LEFT,
|
||||
Input(IT_KEYBOARD, SDLK_j));
|
||||
set(GA_P4_RIGHT,
|
||||
Input(IT_KEYBOARD, SDLK_l));
|
||||
set(GA_P4_ACCEL,
|
||||
Input(IT_KEYBOARD, SDLK_i));
|
||||
set(GA_P4_BRAKE,
|
||||
Input(IT_KEYBOARD, SDLK_k));
|
||||
set(GA_P4_WHEELIE,
|
||||
Input(IT_KEYBOARD, SDLK_m));
|
||||
set(GA_P4_JUMP,
|
||||
Input(IT_KEYBOARD, SDLK_COMMA));
|
||||
set(GA_P4_RESCUE,
|
||||
Input(IT_KEYBOARD, SDLK_u));
|
||||
set(GA_P4_FIRE,
|
||||
Input(IT_KEYBOARD, SDLK_PERIOD));
|
||||
set(GA_P4_LOOK_BACK,
|
||||
Input(IT_KEYBOARD, SDLK_SLASH));
|
||||
|
||||
/*player 4 default keyboard settings*/
|
||||
m_player[3].setInput(KC_LEFT, IT_KEYBOARD, SDLK_j, 0, 0);
|
||||
m_player[3].setInput(KC_RIGHT, IT_KEYBOARD, SDLK_l, 0, 0);
|
||||
m_player[3].setInput(KC_ACCEL, IT_KEYBOARD, SDLK_i, 0, 0);
|
||||
m_player[3].setInput(KC_BRAKE, IT_KEYBOARD, SDLK_k, 0, 0);
|
||||
m_player[3].setInput(KC_WHEELIE,IT_KEYBOARD, SDLK_m, 0, 0);
|
||||
m_player[3].setInput(KC_JUMP, IT_KEYBOARD, SDLK_COMMA, 0, 0);
|
||||
m_player[3].setInput(KC_RESCUE, IT_KEYBOARD, SDLK_u, 0, 0);
|
||||
m_player[3].setInput(KC_FIRE, IT_KEYBOARD, SDLK_PERIOD, 0, 0);
|
||||
m_player[3].setInput(KC_LOOK_BACK, IT_KEYBOARD, SDLK_SLASH, 0, 0);
|
||||
} // setDefaults
|
||||
|
||||
|
||||
@ -347,7 +453,7 @@ void UserConfig::loadConfig(const std::string& filename)
|
||||
}
|
||||
std::string name;
|
||||
reader->get("name", name);
|
||||
if(configFileVersion <=3)
|
||||
if (configFileVersion <= 3)
|
||||
{
|
||||
// For older config files, replace the default player
|
||||
// names "Player %d" with the user name
|
||||
@ -365,16 +471,16 @@ void UserConfig::loadConfig(const std::string& filename)
|
||||
m_player[i].setLastKartId(lastKartId);
|
||||
|
||||
// Retrieves a player's INPUT configuration
|
||||
readInput(reader, "left", KC_LEFT, m_player[i]);
|
||||
readInput(reader, "right", KC_RIGHT, m_player[i]);
|
||||
readInput(reader, "accel", KC_ACCEL, m_player[i]);
|
||||
readInput(reader, "brake", KC_BRAKE, m_player[i]);
|
||||
readPlayerInput(reader, "left", KA_LEFT, i);
|
||||
readPlayerInput(reader, "right", KA_RIGHT, i);
|
||||
readPlayerInput(reader, "accel", KA_ACCEL, i);
|
||||
readPlayerInput(reader, "brake", KA_BRAKE, i);
|
||||
|
||||
readInput(reader, "wheelie", KC_WHEELIE, m_player[i]);
|
||||
readInput(reader, "jump", KC_JUMP, m_player[i]);
|
||||
readInput(reader, "rescue", KC_RESCUE, m_player[i]);
|
||||
readInput(reader, "fire", KC_FIRE, m_player[i]);
|
||||
readInput(reader, "lookBack", KC_LOOK_BACK, m_player[i]);
|
||||
readPlayerInput(reader, "wheelie", KA_WHEELIE, i);
|
||||
readPlayerInput(reader, "jump", KA_JUMP, i);
|
||||
readPlayerInput(reader, "rescue", KA_RESCUE, i);
|
||||
readPlayerInput(reader, "fire", KA_FIRE, i);
|
||||
readPlayerInput(reader, "lookBack", KA_LOOK_BACK, i);
|
||||
}
|
||||
}
|
||||
catch(std::exception& e)
|
||||
@ -385,72 +491,75 @@ void UserConfig::loadConfig(const std::string& filename)
|
||||
}
|
||||
delete root;
|
||||
} // loadConfig
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void UserConfig::readInput(const lisp::Lisp* &r,
|
||||
const char *node,
|
||||
KartActions action,
|
||||
Player& player)
|
||||
void
|
||||
UserConfig::readPlayerInput(const lisp::Lisp *r, const char *node,
|
||||
KartAction ka, int playerIndex)
|
||||
{
|
||||
std::string inputTypeName;
|
||||
const lisp::Lisp* subReader = r->getLisp(node);
|
||||
InputType it=IT_KEYBOARD;
|
||||
readInput(r, node, (GameAction) (playerIndex * KC_COUNT + ka + GA_P1_LEFT));
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
void
|
||||
UserConfig::readInput(const lisp::Lisp* r,
|
||||
const char *node,
|
||||
GameAction action)
|
||||
{
|
||||
string inputTypeName;
|
||||
|
||||
const Lisp* nodeReader = r->getLisp(node);
|
||||
if (!nodeReader)
|
||||
return;
|
||||
|
||||
// Every unused id variable *must* be set to
|
||||
// something different than -1. Otherwise
|
||||
// the restored mapping will not be applied
|
||||
// to the player.
|
||||
int id0 = -1, id1 = -1, id2 = -1;
|
||||
// the restored mapping will not be applied.
|
||||
Input input = Input(IT_NONE, -1, -1, -1);
|
||||
|
||||
// If config file contains no such entry should
|
||||
// create an empty input mapping.
|
||||
if (!subReader)
|
||||
{
|
||||
player.setInput(action, IT_NONE, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
subReader->get("type", inputTypeName);
|
||||
nodeReader->get("type", inputTypeName);
|
||||
if (inputTypeName == "keyboard")
|
||||
{
|
||||
it = IT_KEYBOARD;
|
||||
subReader->get("key", id0);
|
||||
id1 = id2 = 0;
|
||||
input.type = IT_KEYBOARD;
|
||||
nodeReader->get("key", input.id0);
|
||||
input.id1 = input.id2 = 0;
|
||||
}
|
||||
else if (inputTypeName == "stickaxis")
|
||||
{
|
||||
it = IT_STICKMOTION;
|
||||
subReader->get("stick", id0);
|
||||
subReader->get("axis", id1);
|
||||
subReader->get("direction", id2);
|
||||
input.type = IT_STICKMOTION;
|
||||
nodeReader->get("stick", input.id0);
|
||||
nodeReader->get("axis", input.id1);
|
||||
nodeReader->get("direction", input.id2);
|
||||
}
|
||||
else if (inputTypeName == "stickbutton")
|
||||
{
|
||||
it = IT_STICKBUTTON;
|
||||
subReader->get("stick", id0);
|
||||
subReader->get("button", id1);
|
||||
id2 = 0;
|
||||
input.type = IT_STICKBUTTON;
|
||||
nodeReader->get("stick", input.id0);
|
||||
nodeReader->get("button", input.id1);
|
||||
input.id2 = 0;
|
||||
}
|
||||
else if (inputTypeName == "stickhat")
|
||||
{
|
||||
it = IT_STICKHAT;
|
||||
input.type = IT_STICKHAT;
|
||||
// TODO: Implement me
|
||||
}
|
||||
else if (inputTypeName == "mouseaxis")
|
||||
{
|
||||
it = IT_MOUSEMOTION;
|
||||
subReader->get("axis", id0);
|
||||
subReader->get("direction", id1);
|
||||
id2 = 0;
|
||||
input.type = IT_MOUSEMOTION;
|
||||
nodeReader->get("axis", input.id0);
|
||||
nodeReader->get("direction", input.id1);
|
||||
input.id2 = 0;
|
||||
}
|
||||
else if (inputTypeName == "mousebutton")
|
||||
{
|
||||
it = IT_MOUSEBUTTON;
|
||||
subReader->get("button", id0);
|
||||
id1 = id2 = 0;
|
||||
input.type = IT_MOUSEBUTTON;
|
||||
nodeReader->get("button", input.id0);
|
||||
input.id1 = input.id2 = 0;
|
||||
}
|
||||
|
||||
if (input.id0 != -1 && input.id1 != -1 && input.id2 != -1)
|
||||
{
|
||||
setInput(action, input);
|
||||
}
|
||||
|
||||
if (id0 != -1 && id1 != -1 && id2 != -1)
|
||||
player.setInput(action, it, id0, id1, id2);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -475,42 +584,44 @@ void UserConfig::saveConfig(const std::string& filename)
|
||||
// and we can exit here without any further messages.
|
||||
if (DIR_EXIST == 0) return;
|
||||
|
||||
Writer *writer = new Writer(filename);
|
||||
try
|
||||
{
|
||||
lisp::Writer writer(filename);
|
||||
writer->beginList("tuxkart-config");
|
||||
writer->writeComment("If the game's supported config file version is higher than this number the configuration is discarded.");
|
||||
writer->write("configFileVersion\t", CURRENT_CONFIG_VERSION);
|
||||
|
||||
writer.beginList("tuxkart-config");
|
||||
writer.writeComment("If the game's supported config file version is higher than this number the configuration is discarded.");
|
||||
writer.write("configFileVersion\t", CURRENT_CONFIG_VERSION);
|
||||
writer->writeComment("the following options can be set to #t or #f:");
|
||||
writer->write("sfx\t", !(m_sfx==UC_DISABLE));
|
||||
writer->write("music\t", !(m_music==UC_DISABLE));
|
||||
writer->write("smoke\t", m_smoke);
|
||||
writer->writeComment("Display frame per seconds");
|
||||
writer->write("displayFPS\t", m_display_fps);
|
||||
writer->writeComment("Name of the .herring file to use.");
|
||||
writer->write("herringStyle\t", m_herring_style);
|
||||
writer->writeComment("Background music file to use,");
|
||||
writer->write("background-music\t", m_background_music);
|
||||
writer->writeComment("Allow players to disable a magnet");
|
||||
writer->write("disableMagnet\t", m_disable_magnet);
|
||||
writer->writeComment("Use of kilometers per hours (km/h) instead of mph");
|
||||
writer->write("useKPH\t", m_use_kph);
|
||||
writer->writeComment("With improved physics the gravity on a non-horizontal");
|
||||
writer->writeComment("plane will add an accelerating force on the kart");
|
||||
writer->write("improvedPhysics\t", m_improved_physics);
|
||||
|
||||
writer.writeComment("the following options can be set to #t or #f:");
|
||||
writer.write("sfx\t", !(m_sfx==UC_DISABLE));
|
||||
writer.write("music\t", !(m_music==UC_DISABLE));
|
||||
writer.write("smoke\t", m_smoke);
|
||||
writer.writeComment("Display frame per seconds");
|
||||
writer.write("displayFPS\t", m_display_fps);
|
||||
writer.writeComment("Name of the .herring file to use.");
|
||||
writer.write("herringStyle\t", m_herring_style);
|
||||
writer.writeComment("Background music file to use,");
|
||||
writer.write("background-music\t", m_background_music);
|
||||
writer.writeComment("Allow players to disable a magnet");
|
||||
writer.write("disableMagnet\t", m_disable_magnet);
|
||||
writer.writeComment("Use of kilometers per hours (km/h) instead of mph");
|
||||
writer.write("useKPH\t", m_use_kph);
|
||||
writer.writeComment("With improved physics the gravity on a non-horizontal");
|
||||
writer.writeComment("plane will add an accelerating force on the kart");
|
||||
writer.write("improvedPhysics\t", m_improved_physics);
|
||||
writer->writeComment("screen resolution and windowing mode");
|
||||
writer->write("width\t", m_width);
|
||||
writer->write("height\t", m_height);
|
||||
writer->write("fullscreen\t", m_fullscreen);
|
||||
|
||||
writer.writeComment("screen resolution and windowing mode");
|
||||
writer.write("width\t", m_width);
|
||||
writer.write("height\t", m_height);
|
||||
writer.write("fullscreen\t", m_fullscreen);
|
||||
writer->writeComment("number of karts. -1 means use all");
|
||||
writer->write("karts\t", m_karts);
|
||||
|
||||
writer.writeComment("number of karts. -1 means use all");
|
||||
writer.write("karts\t", m_karts);
|
||||
writer->writeComment("number of karts. -1 means use all");
|
||||
writer->write("karts\t", m_karts);
|
||||
|
||||
writer.writeComment("error logging to log (true) or stderr (false)");
|
||||
writer.write("log-errors\t", m_log_errors);
|
||||
writer->writeComment("error logging to log (true) or stderr (false)");
|
||||
writer->write("log-errors\t", m_log_errors);
|
||||
|
||||
/* write player configurations */
|
||||
for(i=0; i<PLAYERS; ++i)
|
||||
@ -518,30 +629,30 @@ void UserConfig::saveConfig(const std::string& filename)
|
||||
temp = "player ";
|
||||
temp += i+'1';
|
||||
temp += " settings";
|
||||
writer.writeComment(temp);
|
||||
writer->writeComment(temp);
|
||||
temp = "player-";
|
||||
temp += i+'1';
|
||||
writer.beginList(temp);
|
||||
writer->beginList(temp);
|
||||
|
||||
writer.write("name\t", m_player[i].getName());
|
||||
writer->write("name\t", m_player[i].getName());
|
||||
|
||||
writer.writeComment("optional");
|
||||
writer.write("lastKartId", m_player[i].getLastKartId());
|
||||
writer->writeComment("optional");
|
||||
writer->write("lastKartId", m_player[i].getLastKartId());
|
||||
|
||||
writeInput(writer, "left\t", KC_LEFT, m_player[i]);
|
||||
writeInput(writer, "right\t", KC_RIGHT, m_player[i]);
|
||||
writeInput(writer, "accel\t", KC_ACCEL, m_player[i]);
|
||||
writeInput(writer, "brake\t", KC_BRAKE, m_player[i]);
|
||||
writeInput(writer, "wheelie\t", KC_WHEELIE, m_player[i]);
|
||||
writeInput(writer, "jump\t", KC_JUMP, m_player[i]);
|
||||
writeInput(writer, "rescue\t", KC_RESCUE, m_player[i]);
|
||||
writeInput(writer, "fire\t", KC_FIRE, m_player[i]);
|
||||
writeInput(writer, "lookBack\t", KC_LOOK_BACK, m_player[i]);
|
||||
writePlayerInput(writer, "left\t", KA_LEFT, i);
|
||||
writePlayerInput(writer, "right\t", KA_RIGHT, i);
|
||||
writePlayerInput(writer, "accel\t", KA_ACCEL, i);
|
||||
writePlayerInput(writer, "brake\t", KA_BRAKE, i);
|
||||
writePlayerInput(writer, "wheelie\t", KA_WHEELIE, i);
|
||||
writePlayerInput(writer, "jump\t", KA_JUMP, i);
|
||||
writePlayerInput(writer, "rescue\t", KA_RESCUE, i);
|
||||
writePlayerInput(writer, "fire\t", KA_FIRE, i);
|
||||
writePlayerInput(writer, "lookBack\t", KA_LOOK_BACK, i);
|
||||
|
||||
writer.endList(temp);
|
||||
writer->endList(temp);
|
||||
} // for i
|
||||
|
||||
writer.endList("tuxkart-config");
|
||||
writer->endList("tuxkart-config");
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
@ -549,88 +660,103 @@ void UserConfig::saveConfig(const std::string& filename)
|
||||
fprintf(stderr, e.what());
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
delete writer;
|
||||
} // saveConfig
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void UserConfig::writeInput(lisp::Writer &writer, const char *node, KartActions action, Player& player)
|
||||
void
|
||||
UserConfig::writePlayerInput(lisp::Writer *writer, const char *node,
|
||||
KartAction ka, int playerIndex)
|
||||
{
|
||||
const Input *INPUT = player.getInput(action);
|
||||
writeInput(writer, node, (GameAction) (playerIndex * KC_COUNT + ka + GA_P1_LEFT));
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
void
|
||||
UserConfig::writeInput(lisp::Writer *writer,
|
||||
const char *node,
|
||||
GameAction action)
|
||||
{
|
||||
writer->beginList(node);
|
||||
|
||||
// Write no entry if the input has no mapping.
|
||||
if (INPUT->type == IT_NONE)
|
||||
return;
|
||||
|
||||
writer.beginList(node);
|
||||
|
||||
switch (INPUT->type)
|
||||
if (inputMap[action].count)
|
||||
{
|
||||
|
||||
const Input input = inputMap[action].inputs[0];
|
||||
|
||||
if (input.type != IT_NONE)
|
||||
{
|
||||
switch (input.type)
|
||||
{
|
||||
case IT_NONE:
|
||||
break;
|
||||
case IT_KEYBOARD:
|
||||
writer.write("type", "keyboard");
|
||||
writer.write("key", INPUT->id0);
|
||||
writer->write("type", "keyboard");
|
||||
writer->write("key", input.id0);
|
||||
break;
|
||||
case IT_STICKMOTION:
|
||||
writer.write("type", "stickaxis");
|
||||
writer.write("stick", INPUT->id0);
|
||||
writer.write("axis", INPUT->id1);
|
||||
writer.writeComment("0 is negative/left/up, 1 is positive/right/down");
|
||||
writer.write("direction", INPUT->id2);
|
||||
writer->write("type", "stickaxis");
|
||||
writer->write("stick", input.id0);
|
||||
writer->write("axis", input.id1);
|
||||
writer->writeComment("0 is negative/left/up, 1 is positive/right/down");
|
||||
writer->write("direction", input.id2);
|
||||
break;
|
||||
case IT_STICKBUTTON:
|
||||
writer.write("type", "stickbutton");
|
||||
writer.write("stick", INPUT->id0);
|
||||
writer.write("button", INPUT->id1);
|
||||
writer->write("type", "stickbutton");
|
||||
writer->write("stick", input.id0);
|
||||
writer->write("button", input.id1);
|
||||
break;
|
||||
case IT_STICKHAT:
|
||||
// TODO: Implement me
|
||||
break;
|
||||
case IT_MOUSEMOTION:
|
||||
writer.write("type", "mouseaxis");
|
||||
writer.write("axis", INPUT->id0);
|
||||
writer.writeComment("0 is negative/left/up, 1 is positive/right/down");
|
||||
writer.write("direction", INPUT->id1);
|
||||
writer->write("type", "mouseaxis");
|
||||
writer->write("axis", input.id0);
|
||||
writer->writeComment("0 is negative/left/up, 1 is positive/right/down");
|
||||
writer->write("direction", input.id1);
|
||||
break;
|
||||
case IT_MOUSEBUTTON:
|
||||
writer.write("type", "mousebutton");
|
||||
writer.write("button", INPUT->id0);
|
||||
break;
|
||||
default:
|
||||
writer->write("type", "mousebutton");
|
||||
writer->writeComment("0 is left, 1 is middle, 2 is right, 3 is wheel up, 4 is wheel down");
|
||||
writer->writeComment("other values denote auxillary buttons");
|
||||
writer->write("button", input.id0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writer.endList(node);
|
||||
writer->endList(node);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
std::string UserConfig::getInputAsString(int player_index, KartActions control)
|
||||
std::string UserConfig::getInputAsString(Input &input)
|
||||
{
|
||||
const Input *INPUT = m_player[player_index].getInput(control);
|
||||
char msg[MAX_MESSAGE_LENGTH];
|
||||
std::ostringstream stm;
|
||||
|
||||
switch (INPUT->type)
|
||||
switch (input.type)
|
||||
{
|
||||
case IT_NONE:
|
||||
snprintf(msg, sizeof(msg), _("not set"));
|
||||
break;
|
||||
case IT_KEYBOARD:
|
||||
snprintf(msg, sizeof(msg), _("%s"), SDL_GetKeyName((SDLKey) INPUT->id0));
|
||||
snprintf(msg, sizeof(msg), _("%s"), SDL_GetKeyName((SDLKey) input.id0));
|
||||
break;
|
||||
case IT_STICKMOTION:
|
||||
snprintf(msg, sizeof(msg), _("joy %d axis %d %c"),
|
||||
INPUT->id0, INPUT->id1, (INPUT->id2 == AD_NEGATIVE) ? '-' : '+');
|
||||
input.id0, input.id1, (input.id2 == AD_NEGATIVE) ? '-' : '+');
|
||||
break;
|
||||
case IT_STICKBUTTON:
|
||||
snprintf(msg, sizeof(msg), _("joy %d btn %d"), INPUT->id0, INPUT->id1);
|
||||
snprintf(msg, sizeof(msg), _("joy %d btn %d"), input.id0, input.id1);
|
||||
break;
|
||||
case IT_STICKHAT:
|
||||
snprintf(msg, sizeof(msg), _("joy %d hat %d"), INPUT->id0, INPUT->id1);
|
||||
snprintf(msg, sizeof(msg), _("joy %d hat %d"), input.id0, input.id1);
|
||||
break;
|
||||
case IT_MOUSEBUTTON:
|
||||
snprintf(msg, sizeof(msg), _("mouse btn %d"), INPUT->id0);
|
||||
snprintf(msg, sizeof(msg), _("mouse btn %d"), input.id0);
|
||||
break;
|
||||
case IT_MOUSEMOTION:
|
||||
snprintf(msg, sizeof(msg), _("mouse axis %d %c"),
|
||||
INPUT->id0, ((INPUT->id1 == AD_NEGATIVE) ? '-' : '+'));
|
||||
input.id0, ((input.id1 == AD_NEGATIVE) ? '-' : '+'));
|
||||
break;
|
||||
default:
|
||||
snprintf(msg, sizeof(msg), _("Invalid"));
|
||||
@ -642,5 +768,165 @@ std::string UserConfig::getInputAsString(int player_index, KartActions control)
|
||||
} // GetKeyAsString
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
string
|
||||
UserConfig::getMappingAsString(GameAction ga)
|
||||
{
|
||||
if (inputMap[ga].count
|
||||
&& inputMap[ga].inputs[0].type)
|
||||
{
|
||||
stringstream s;
|
||||
s << getInputAsString(inputMap[ga].inputs[0]);
|
||||
|
||||
return s.str();
|
||||
}
|
||||
else
|
||||
{
|
||||
return string(_("not set"));
|
||||
}
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
string
|
||||
UserConfig::getMappingAsString(int playerIndex, KartAction ka)
|
||||
{
|
||||
return getMappingAsString((GameAction) (GA_FIRST_KARTACTION
|
||||
+ playerIndex * KC_COUNT + ka));
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
UserConfig::unsetDuplicates (GameAction ga, Input &i)
|
||||
{
|
||||
for (int cga = GA_FIRST_KARTACTION; cga <= GA_LAST_KARTACTION; cga++)
|
||||
{
|
||||
if (cga != ga)
|
||||
{
|
||||
// If the input occurs in any other mapping
|
||||
// delete it properly from there.
|
||||
|
||||
if (inputMap[cga].count
|
||||
&& inputMap[cga].inputs[0].type == i.type
|
||||
&& inputMap[cga].inputs[0].id0 == i.id0
|
||||
&& inputMap[cga].inputs[0].id1 == i.id1
|
||||
&& inputMap[cga].inputs[0].id2 == i.id2)
|
||||
{
|
||||
// Delete it.
|
||||
inputMap[cga].inputs[0].type = IT_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
void
|
||||
UserConfig::set(GameAction ga, Input i)
|
||||
{
|
||||
inputMap[ga].count = 1;
|
||||
inputMap[ga].inputs = new Input[1];
|
||||
inputMap[ga].inputs[0] = i;
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
void
|
||||
UserConfig::set(GameAction ga, Input i0, Input i1)
|
||||
{
|
||||
inputMap[ga].count = 2;
|
||||
inputMap[ga].inputs = new Input[2];
|
||||
inputMap[ga].inputs[0] = i0;
|
||||
inputMap[ga].inputs[1] = i1;
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
void
|
||||
UserConfig::set(GameAction ga, Input i0, Input i1, Input i2)
|
||||
{
|
||||
inputMap[ga].count = 3;
|
||||
inputMap[ga].inputs = new Input[3];
|
||||
inputMap[ga].inputs[0] = i0;
|
||||
inputMap[ga].inputs[1] = i1;
|
||||
inputMap[ga].inputs[2] = i2;
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
void
|
||||
UserConfig::set(GameAction ga, Input i0, Input i1, Input i2, Input i3)
|
||||
{
|
||||
inputMap[ga].count = 4;
|
||||
inputMap[ga].inputs = new Input[4];
|
||||
inputMap[ga].inputs[0] = i0;
|
||||
inputMap[ga].inputs[1] = i1;
|
||||
inputMap[ga].inputs[2] = i2;
|
||||
inputMap[ga].inputs[3] = i3;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void
|
||||
UserConfig::setInput(GameAction ga, Input &input)
|
||||
{
|
||||
// Removes the input from all mappings where it occurs.
|
||||
unsetDuplicates(ga, input);
|
||||
|
||||
set(ga, input);
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
void
|
||||
UserConfig::setInput(int playerIndex, KartAction ka, Input &input)
|
||||
{
|
||||
setInput((GameAction) (GA_FIRST_KARTACTION
|
||||
+ playerIndex * KC_COUNT + ka),
|
||||
input);
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
void
|
||||
UserConfig::clearInput(int playerIndex, KartAction ka)
|
||||
{
|
||||
inputMap[(GameAction) (GA_FIRST_KARTACTION + playerIndex * KC_COUNT + ka)]
|
||||
.count = 0;
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
ActionMap *
|
||||
UserConfig::newActionMap(const int from, const int to)
|
||||
{
|
||||
ActionMap *am = new ActionMap();
|
||||
|
||||
for (int i = from; i <= to; i++)
|
||||
{
|
||||
const int count = inputMap[i].count;
|
||||
for (int j = 0;j < count; j++)
|
||||
am->putEntry(inputMap[i].inputs[j], (GameAction) i);
|
||||
}
|
||||
|
||||
return am;
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
ActionMap *
|
||||
UserConfig::newMenuActionMap()
|
||||
{
|
||||
return newActionMap(GA_FIRST_MENU, GA_LAST_MENU);
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
ActionMap *
|
||||
UserConfig::newIngameActionMap()
|
||||
{
|
||||
ActionMap *am = newActionMap(GA_FIRST_INGAME, GA_LAST_INGAME);
|
||||
|
||||
return am;
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
/** Determines whether the given Input is used in a mapping where it is marked
|
||||
* as fixed. This allows the input driver to discard the mapping and not
|
||||
* allow the user to use it.
|
||||
*/
|
||||
bool
|
||||
UserConfig::isFixedInput(InputType type, int id0, int id1, int id2)
|
||||
{
|
||||
for (int i = GA_FIRST_INGAME_FIXED; i <= GA_LAST_INGAME_FIXED; i++)
|
||||
{
|
||||
const int count = inputMap[i].count;
|
||||
for (int j = 0;j < count; j++)
|
||||
if (inputMap[i].inputs[j].type == type
|
||||
&& inputMap[i].inputs[j].id0 == id0
|
||||
&& inputMap[i].inputs[j].id1 == id1
|
||||
&& inputMap[i].inputs[j].id2 == id2)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*EOF*/
|
||||
|
@ -37,6 +37,7 @@
|
||||
#define SUPPORTED_CONFIG_VERSION 3
|
||||
|
||||
#include <string>
|
||||
#include "input.hpp"
|
||||
#include "player.hpp"
|
||||
#include "lisp/lisp.hpp"
|
||||
#include "lisp/parser.hpp"
|
||||
@ -44,13 +45,29 @@
|
||||
|
||||
#define CONFIGDIR ".supertuxkart"
|
||||
|
||||
class ActionMap;
|
||||
|
||||
/*class for managing general tuxkart configuration data*/
|
||||
class UserConfig
|
||||
{
|
||||
private:
|
||||
typedef struct
|
||||
{
|
||||
int count;
|
||||
Input *inputs;
|
||||
} InputMapEntry;
|
||||
|
||||
std::string filename;
|
||||
|
||||
/** Stores the GameAction->Input mappings in a way that is suitable for
|
||||
* quick modification of the mappings. Internally this allows multiple
|
||||
* Input instances per GameAction but the public methods allow only one
|
||||
* mapping.
|
||||
*
|
||||
* It is named after what is put in as values.
|
||||
*/
|
||||
InputMapEntry inputMap[GA_COUNT];
|
||||
|
||||
void setFilename ();
|
||||
int CheckAndCreateDir();
|
||||
|
||||
@ -58,15 +75,57 @@ private:
|
||||
int m_sfx;
|
||||
int m_music;
|
||||
|
||||
void readInput(const lisp::Lisp* &r,
|
||||
const char *node,
|
||||
KartActions action,
|
||||
Player& player);
|
||||
void readPlayerInput(const lisp::Lisp *,
|
||||
const char *,
|
||||
KartAction ka,
|
||||
int);
|
||||
|
||||
void readInput(const lisp::Lisp *,
|
||||
const char *,
|
||||
GameAction);
|
||||
|
||||
void writeInput(lisp::Writer *,
|
||||
const char *,
|
||||
GameAction);
|
||||
|
||||
void writePlayerInput(lisp::Writer *,
|
||||
const char *,
|
||||
KartAction,
|
||||
int);
|
||||
|
||||
/** Iterates through the input mapping and unsets all
|
||||
* where the given input occurs.
|
||||
*
|
||||
* This makes sure an input is not bound multiple times.
|
||||
*/
|
||||
void unsetDuplicates(GameAction, Input &);
|
||||
|
||||
/** Creates an GameAction->Input mapping with one Input */
|
||||
void set(GameAction, Input);
|
||||
|
||||
/** Creates an GameAction->Input mapping with two Inputs */
|
||||
void set(GameAction, Input, Input);
|
||||
|
||||
/** Creates an GameAction->Input mapping with three Inputs */
|
||||
void set(GameAction, Input, Input, Input);
|
||||
|
||||
/** Creates an GameAction->Input mapping with four Inputs */
|
||||
void set(GameAction, Input, Input, Input, Input);
|
||||
|
||||
std::string getInputAsString(Input &);
|
||||
|
||||
/** Creates an ActionMap for the GameAction values of the specified
|
||||
* range.
|
||||
*/
|
||||
ActionMap *newActionMap(const int, const int);
|
||||
|
||||
/** Sets the Input for the given GameAction. Includes a check for
|
||||
* duplicates and automatic removing of the other candidate(s).
|
||||
*
|
||||
* For use when reading from file.
|
||||
*/
|
||||
void setInput(GameAction, Input &);
|
||||
|
||||
void writeInput(lisp::Writer &writer,
|
||||
const char *node,
|
||||
KartActions action,
|
||||
Player& player);
|
||||
public:
|
||||
enum UC_Mode {UC_ENABLE, UC_DISABLE, UC_TEMPORARY_DISABLE};
|
||||
|
||||
@ -106,7 +165,31 @@ public:
|
||||
void loadConfig(const std::string& filename);
|
||||
void saveConfig();
|
||||
void saveConfig(const std::string& filename);
|
||||
std::string getInputAsString(int player_index, KartActions control);
|
||||
|
||||
/** Retrieves a human readable string of the mapping for a GameAction */
|
||||
std::string getMappingAsString(GameAction);
|
||||
/** Retrieves a human readable string of the mapping for the given
|
||||
* player and KartAction.
|
||||
*/
|
||||
std::string getMappingAsString(int, KartAction);
|
||||
|
||||
/** Sets the Input for the given Player and KartAction. Includes a check
|
||||
* for duplicates and automatic removing of the other candidate(s).
|
||||
*
|
||||
* For use when sensing input.
|
||||
*/
|
||||
void setInput(int, KartAction, Input &);
|
||||
|
||||
/** Clears the mapping for a given Player and KartAction. */
|
||||
void clearInput(int, KartAction);
|
||||
|
||||
bool isFixedInput(InputType, int, int, int);
|
||||
|
||||
/** Creates ActionMap for use in menu mode. */
|
||||
ActionMap *newMenuActionMap();
|
||||
|
||||
/** Creates ActionMap for use in ingame mode. */
|
||||
ActionMap *newIngameActionMap();
|
||||
};
|
||||
|
||||
|
||||
|
@ -20,9 +20,6 @@
|
||||
|
||||
#include "user_config.hpp"
|
||||
|
||||
//TODO: this include should not be necesary?
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#include "gui/font.hpp"
|
||||
|
||||
//TEMP
|
||||
@ -887,11 +884,11 @@ void WidgetManager::darken_wgt_color(const int TOKEN)
|
||||
else std::cerr << "Tried to darken an unexistant widget with token " << TOKEN << '\n';
|
||||
}
|
||||
|
||||
/** The handle_mouse() function returns the current widget under the mouse
|
||||
/** The handle_pointer() function returns the current widget under the
|
||||
* pointer, if it's different from the selected widget. If the widget under
|
||||
* the mouse is the selected widget, it returns WGT_NONE.
|
||||
* the pointer is the selected widget, it returns WGT_NONE.
|
||||
*/
|
||||
int WidgetManager::handle_mouse(const int X, const int Y )
|
||||
int WidgetManager::handle_pointer(const int X, const int Y )
|
||||
{
|
||||
//Search if the given x and y positions are on top of any widget. Please
|
||||
//note that the bounding box for each widget is used instead of the
|
||||
@ -932,131 +929,74 @@ int WidgetManager::handle_mouse(const int X, const int Y )
|
||||
return WGT_NONE;
|
||||
}
|
||||
|
||||
/** The handle_keyboard() function stores the current widget under the cursor
|
||||
/** The handle_*() function stores the current widget under the cursor
|
||||
* after receiving input from a key.
|
||||
*/
|
||||
int WidgetManager::handle_keyboard(const int KEY)
|
||||
int
|
||||
WidgetManager::handle_left()
|
||||
{
|
||||
if( m_selected_wgt_token == WGT_NONE ) return WGT_NONE;
|
||||
|
||||
int next_wgt = find_id(m_selected_wgt_token);
|
||||
//FIXME: eventually, the keys should not be hard coded
|
||||
switch (KEY)
|
||||
{
|
||||
case SDLK_LEFT:
|
||||
next_wgt = find_left_widget(find_id(m_selected_wgt_token));
|
||||
break;
|
||||
return handle_finish(find_left_widget(find_id(m_selected_wgt_token)));
|
||||
}
|
||||
|
||||
case SDLK_RIGHT:
|
||||
next_wgt = find_right_widget(find_id(m_selected_wgt_token));
|
||||
break;
|
||||
int
|
||||
WidgetManager::handle_right()
|
||||
{
|
||||
if( m_selected_wgt_token == WGT_NONE ) return WGT_NONE;
|
||||
|
||||
case SDLK_UP:
|
||||
next_wgt = find_top_widget(find_id(m_selected_wgt_token));
|
||||
break;
|
||||
return handle_finish(find_right_widget(find_id(m_selected_wgt_token)));
|
||||
}
|
||||
|
||||
case SDLK_DOWN:
|
||||
next_wgt = find_bottom_widget(find_id(m_selected_wgt_token));
|
||||
break;
|
||||
int
|
||||
WidgetManager::handle_up()
|
||||
{
|
||||
if( m_selected_wgt_token == WGT_NONE ) return WGT_NONE;
|
||||
|
||||
//FIXME: apparently, there are different codes for the + and -
|
||||
//near the numlock.
|
||||
case SDLK_PLUS:
|
||||
{
|
||||
return handle_finish(find_top_widget(find_id(m_selected_wgt_token)));
|
||||
}
|
||||
|
||||
int
|
||||
WidgetManager::handle_down()
|
||||
{
|
||||
if( m_selected_wgt_token == WGT_NONE ) return WGT_NONE;
|
||||
|
||||
return handle_finish(find_bottom_widget(find_id(m_selected_wgt_token)));
|
||||
}
|
||||
|
||||
int
|
||||
WidgetManager::handle_finish(const int next_wgt)
|
||||
{
|
||||
if( next_wgt == WGT_NONE)
|
||||
return WGT_NONE;
|
||||
|
||||
m_selected_wgt_token = m_widgets[next_wgt].token;
|
||||
|
||||
return m_selected_wgt_token;
|
||||
}
|
||||
|
||||
void
|
||||
WidgetManager::increase_scroll_speed(const bool fast)
|
||||
{
|
||||
const int ID = find_id(m_selected_wgt_token);
|
||||
if( m_widgets[ID].widget->m_enable_scroll )
|
||||
{
|
||||
//FIXME: these increases shouldn't be in pixels, but in percentages.
|
||||
//This should increase it by 1%, and the page buttons by 5%.
|
||||
m_widgets[ID].widget->m_scroll_speed_y -= 1;
|
||||
m_widgets[ID].widget->m_scroll_speed_y -= (fast) ? 5 : 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDLK_MINUS:
|
||||
{
|
||||
const int ID = find_id(m_selected_wgt_token);
|
||||
if( m_widgets[ID].widget->m_enable_scroll )
|
||||
{
|
||||
m_widgets[ID].widget->m_scroll_speed_y += 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDLK_PAGEUP:
|
||||
{
|
||||
const int ID = find_id(m_selected_wgt_token);
|
||||
if( m_widgets[ID].widget->m_enable_scroll )
|
||||
{
|
||||
m_widgets[ID].widget->m_scroll_speed_y -= 5;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDLK_PAGEDOWN:
|
||||
{
|
||||
const int ID = find_id(m_selected_wgt_token);
|
||||
if( m_widgets[ID].widget->m_enable_scroll )
|
||||
{
|
||||
m_widgets[ID].widget->m_scroll_speed_y += 5;
|
||||
}
|
||||
return WGT_NONE;
|
||||
}
|
||||
|
||||
default: return WGT_NONE;
|
||||
}
|
||||
|
||||
if( next_wgt == WGT_NONE) return WGT_NONE;
|
||||
|
||||
m_selected_wgt_token = m_widgets[next_wgt].token;
|
||||
return m_selected_wgt_token;
|
||||
}
|
||||
|
||||
/** The handle_joystick() function stores the current widget under the cursor
|
||||
* after receiving input from the joystick.
|
||||
*/
|
||||
//FIXME: shouldn't direction and value be merged?
|
||||
int WidgetManager::handle_joystick
|
||||
(
|
||||
const int axis,
|
||||
const int direction,
|
||||
int value
|
||||
)
|
||||
void
|
||||
WidgetManager::decrease_scroll_speed(const bool fast)
|
||||
{
|
||||
if( m_selected_wgt_token == WGT_NONE ) return WGT_NONE;
|
||||
|
||||
int next_wgt = WGT_NONE; //This asignment is to prevent a compiler warning
|
||||
switch (axis)
|
||||
const int ID = find_id(m_selected_wgt_token);
|
||||
if( m_widgets[ID].widget->m_enable_scroll )
|
||||
{
|
||||
case 0:
|
||||
if( direction == 0 )
|
||||
{
|
||||
next_wgt = find_left_widget(find_id(m_selected_wgt_token));
|
||||
//FIXME: these increases shouldn't be in pixels, but in percentages.
|
||||
//This should increase it by 1%, and the page buttons by 5%.
|
||||
m_widgets[ID].widget->m_scroll_speed_y += (fast) ? 5 : 1;
|
||||
}
|
||||
else if( direction == 1 )
|
||||
{
|
||||
next_wgt = find_right_widget(find_id(m_selected_wgt_token));
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if( direction == 0 )
|
||||
{
|
||||
next_wgt = find_top_widget(find_id(m_selected_wgt_token));
|
||||
}
|
||||
else if( direction == 1 )
|
||||
{
|
||||
next_wgt = find_bottom_widget(find_id(m_selected_wgt_token));
|
||||
}
|
||||
break;
|
||||
|
||||
default: return WGT_NONE;
|
||||
}
|
||||
|
||||
if( next_wgt == find_id(m_selected_wgt_token) ) return WGT_NONE;
|
||||
|
||||
m_selected_wgt_token = m_widgets[next_wgt].token;
|
||||
return m_selected_wgt_token;
|
||||
}
|
||||
|
||||
//FIXME: find_left_widget() doesn't works properly yet
|
||||
|
@ -100,6 +100,8 @@ class WidgetManager
|
||||
int find_top_widget(const int START_WGT) const;
|
||||
int find_bottom_widget(const int START_WGT) const;
|
||||
|
||||
int handle_finish(const int);
|
||||
|
||||
public:
|
||||
//FIXME: maybe I should get this out of this class?
|
||||
static const int WGT_NONE;
|
||||
@ -190,9 +192,15 @@ public:
|
||||
void darken_wgt_color(const int TOKEN);
|
||||
|
||||
/* Input device handling. */
|
||||
int handle_mouse( const int X, const int Y );
|
||||
int handle_keyboard( const int KEY );
|
||||
int handle_joystick( int axis, int dir, int value );
|
||||
int handle_pointer( const int X, const int Y );
|
||||
int handle_left();
|
||||
int handle_right();
|
||||
int handle_up();
|
||||
int handle_down();
|
||||
|
||||
/* Scrolling modification. */
|
||||
void increase_scroll_speed(bool = false);
|
||||
void decrease_scroll_speed(bool = false);
|
||||
};
|
||||
|
||||
extern WidgetManager *widget_manager;
|
||||
|
Loading…
Reference in New Issue
Block a user