- separate input map implementation
- make mouse axes work like analog axes - enable display menu for non-Win32 platforms git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1272 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
9ea37bf14f
commit
059d9037a7
@ -38,6 +38,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 \
|
||||
isect.cpp isect.hpp \
|
||||
track.cpp track.hpp \
|
||||
herring.cpp herring.hpp \
|
||||
|
@ -31,19 +31,6 @@ void BaseGUI::input(InputType type, int id0, int id1, int id2, int value)
|
||||
case IT_KEYBOARD:
|
||||
inputKeyboard(id0, value);
|
||||
break;
|
||||
|
||||
case IT_MOUSEMOTION:
|
||||
widgetSet->pulse(widgetSet->point(m_menu_id, id0, id1), 1.2f);
|
||||
|
||||
#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)
|
||||
@ -131,6 +118,12 @@ void BaseGUI::inputKeyboard(int key, int pressed)
|
||||
break;
|
||||
} // switch
|
||||
} // inputKeyboard
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
BaseGUI::inputPointer(int x, int y)
|
||||
{
|
||||
widgetSet->pulse(widgetSet->point(m_menu_id, x, y), 1.2f);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void BaseGUI::update(float dt)
|
||||
|
@ -33,6 +33,9 @@ public:
|
||||
|
||||
virtual void input(InputType type, int id0, int id1, int id2, int value);
|
||||
virtual void inputKeyboard(int key, int pressed);
|
||||
|
||||
void inputPointer(int x, int y);
|
||||
|
||||
void TimeToString(const float time, char *s);
|
||||
protected:
|
||||
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "credits_menu.hpp"
|
||||
#include "grand_prix_select.hpp"
|
||||
#include "sound_manager.hpp"
|
||||
#include "sdldrv.hpp"
|
||||
|
||||
MenuManager* menu_manager= new MenuManager();
|
||||
|
||||
@ -93,7 +94,11 @@ void MenuManager::update()
|
||||
|
||||
if (m_handled_size != m_menu_stack.size())
|
||||
{
|
||||
if(m_current_menu==m_RaceGUI) m_RaceGUI=0;
|
||||
if(m_current_menu==m_RaceGUI)
|
||||
{
|
||||
m_RaceGUI = 0;
|
||||
drv_showPointer();
|
||||
}
|
||||
|
||||
delete m_current_menu;
|
||||
m_current_menu= NULL;
|
||||
@ -132,6 +137,7 @@ void MenuManager::update()
|
||||
m_current_menu= new NumPlayers();
|
||||
break;
|
||||
case MENUID_RACE:
|
||||
drv_hidePointer();
|
||||
m_current_menu = new RaceGUI();
|
||||
m_RaceGUI = m_current_menu;
|
||||
break;
|
||||
|
@ -37,14 +37,16 @@ Options::Options()
|
||||
widgetSet -> space(m_menu_id);
|
||||
widgetSet -> label(m_menu_id, _("Options"), GUI_LRG, GUI_ALL, 0, 0);
|
||||
widgetSet -> start(m_menu_id, _("Player Config"), GUI_MED, WTOK_CONTROLS);
|
||||
|
||||
#ifndef WIN32
|
||||
// Don't display the fullscreen menu when called from within the race.
|
||||
// (Windows only)
|
||||
// The fullscreen mode will reload all textures, reload the models,
|
||||
// ... basically creating a big mess!! (and all of this only thanks
|
||||
// to windows, who discards all textures, ...)
|
||||
if(!menu_manager->isSomewhereOnStack(MENUID_RACE))
|
||||
{
|
||||
widgetSet -> state(m_menu_id, _("Display"), GUI_MED, WTOK_DISPLAY);
|
||||
}
|
||||
widgetSet -> state(m_menu_id, _("Display"), GUI_MED, WTOK_DISPLAY);
|
||||
#endif
|
||||
|
||||
widgetSet -> state(m_menu_id, _("Sound"), GUI_MED, WTOK_SOUND);
|
||||
widgetSet -> space(m_menu_id);
|
||||
widgetSet -> state(m_menu_id, _("Press <ESC> to go back"), GUI_SML, WTOK_BACK);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "user_config.hpp"
|
||||
#include "menu_manager.hpp"
|
||||
#include "translation.hpp"
|
||||
#include "sdldrv.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
@ -88,6 +89,8 @@ void PlayerControls::select()
|
||||
}
|
||||
m_edit_action = static_cast<KartActions>(MENU_CHOICE);
|
||||
m_grab_input = true;
|
||||
drv_hidePointer();
|
||||
|
||||
widgetSet->set_label(m_grab_id, _("Press key"));
|
||||
} // select
|
||||
|
||||
@ -138,6 +141,7 @@ void PlayerControls::input(InputType type, int id0, int id1, int id2, int value)
|
||||
// ------------------------------
|
||||
else
|
||||
{
|
||||
drv_showPointer();
|
||||
m_grab_input = false;
|
||||
|
||||
// Do not accept pressing ESC as input.
|
||||
|
@ -29,8 +29,9 @@
|
||||
#include "sdldrv.hpp"
|
||||
#include "translation.hpp"
|
||||
#include "font.hpp"
|
||||
#include "inputmap.hpp"
|
||||
|
||||
RaceGUI::RaceGUI(): m_time_left(0.0)
|
||||
RaceGUI::RaceGUI(): m_input_map (new InputMap()), m_time_left(0.0)
|
||||
{
|
||||
if(user_config->m_fullscreen)
|
||||
{
|
||||
@ -39,7 +40,7 @@ RaceGUI::RaceGUI(): m_time_left(0.0)
|
||||
|
||||
if(!user_config->m_profile)
|
||||
{
|
||||
UpdateKeyboardMappings();
|
||||
updateInputMappings();
|
||||
} // if !user_config->m_profile
|
||||
|
||||
// FIXME: translation problem
|
||||
@ -74,6 +75,8 @@ RaceGUI::RaceGUI(): m_time_left(0.0)
|
||||
//-----------------------------------------------------------------------------
|
||||
RaceGUI::~RaceGUI()
|
||||
{
|
||||
delete m_input_map;
|
||||
|
||||
if(user_config->m_fullscreen)
|
||||
{
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
@ -82,15 +85,9 @@ RaceGUI::~RaceGUI()
|
||||
} // ~Racegui
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RaceGUI::UpdateKeyboardMappings()
|
||||
void RaceGUI::updateInputMappings()
|
||||
{
|
||||
// Clear all entries.
|
||||
for(int type = 0;type< (int) IT_LAST+1;type++)
|
||||
for(int id0=0;id0<MAX_ID0;id0++)
|
||||
for(int id1=0;id1<MAX_ID1;id1++)
|
||||
for(int id2=0;id2<MAX_ID2;id2++)
|
||||
m_input_map[type][id0][id1][id2].kart = NULL;
|
||||
|
||||
m_input_map->clear();
|
||||
|
||||
// Defines the mappings for player keys to kart and action
|
||||
// To avoid looping over all players to find out what
|
||||
@ -104,29 +101,19 @@ void RaceGUI::UpdateKeyboardMappings()
|
||||
PlayerKart* kart = world->getPlayerKart(i);
|
||||
|
||||
for(int ka=(int)KC_FIRST; ka < (int)KC_LAST+1; ka++)
|
||||
putEntry(kart, (KartActions) ka);
|
||||
m_input_map->putEntry(kart, (KartActions) ka);
|
||||
}
|
||||
|
||||
} // UpdateKeyControl
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RaceGUI::putEntry(PlayerKart *kart, KartActions kc)
|
||||
{
|
||||
Player *p = kart->getPlayer();
|
||||
const Input *I = p->getInput(kc);
|
||||
|
||||
m_input_map[I->type][I->id0][I->id1][I->id2].kart = kart;
|
||||
m_input_map[I->type][I->id0][I->id1][I->id2].action = kc;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool RaceGUI::handleInput(InputType type, int id0, int id1, int id2, int value)
|
||||
{
|
||||
PlayerKart *k = m_input_map[type][id0][id1][id2].kart;
|
||||
InputMap::Entry *e = m_input_map->getEntry(type, id0, id1, id2);
|
||||
|
||||
if (k)
|
||||
if (e)
|
||||
{
|
||||
k->action(m_input_map[type][id0][id1][id2].action, value);
|
||||
e->kart->action(e->action, value);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -31,25 +31,11 @@
|
||||
#include "player.hpp"
|
||||
#include "world.hpp"
|
||||
|
||||
// TODO: Fix this.
|
||||
#define MAX_ID0 512
|
||||
#define MAX_ID1 16
|
||||
#define MAX_ID2 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PlayerKart *kart;
|
||||
KartActions action;
|
||||
}
|
||||
Entry;
|
||||
|
||||
class InputMap;
|
||||
class RaceSetup;
|
||||
|
||||
class RaceGUI: public BaseGUI
|
||||
{
|
||||
// A mapping for the assigned keys (like fire, ...) to
|
||||
// the kart which is using them
|
||||
Entry m_input_map[IT_LAST+1][MAX_ID0][MAX_ID1][MAX_ID2];
|
||||
|
||||
class TimedMessage
|
||||
{
|
||||
@ -86,6 +72,7 @@ public:
|
||||
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];
|
||||
@ -108,8 +95,7 @@ private:
|
||||
void drawAllMessages (Kart* player_kart,
|
||||
int offset_x, int offset_y,
|
||||
float ratio_x, float ratio_y );
|
||||
void UpdateKeyboardMappings();
|
||||
void putEntry(PlayerKart *kart, KartActions ka);
|
||||
void updateInputMappings();
|
||||
bool handleInput(InputType type, int id0, int id1, int id2, int value);
|
||||
void inputKeyboard(int key, int pressed);
|
||||
void drawPlayerIcons ();
|
||||
|
74
src/inputmap.cpp
Normal file
74
src/inputmap.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
// $Id: inputmap.cpp 1259 2007-09-24 12:28:19Z thebohemian $
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2007 Robert Schuster
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// 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 "player.hpp"
|
||||
#include "player_kart.hpp"
|
||||
#include "inputmap.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void
|
||||
InputMap::putEntry(PlayerKart *kart, KartActions kc)
|
||||
{
|
||||
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::Entry *
|
||||
InputMap::getEntry(InputType it, int id0, int id1, int id2)
|
||||
{
|
||||
return inputMap[key(it, id0, id1, id2)];
|
||||
}
|
||||
|
||||
void
|
||||
InputMap::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)
|
||||
{
|
||||
/*
|
||||
* A short reminder on the bit distribution and their usage:
|
||||
* it gets 8 bits (InputType)
|
||||
* id1 gets 16 bits (button, hat or axis number)
|
||||
* id2 gets 8 bits (direction bit)
|
||||
* id0 gets 32 bits (That is because id0 can be the keyboard key ids and
|
||||
* those are unicode and unicode 4.0 is 32 bit)
|
||||
*
|
||||
* Assumption: int is (at least) 32 bit
|
||||
*/
|
||||
return Key(it << 24 | id1 << 8 | id2, id0);
|
||||
}
|
||||
|
52
src/inputmap.hpp
Normal file
52
src/inputmap.hpp
Normal file
@ -0,0 +1,52 @@
|
||||
// $Id: inputmap.hpp 1259 2007-09-24 12:28:19Z thebohemian $
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2007 Robert Schuster
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// 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
|
||||
|
||||
#include <map>
|
||||
#include "player.hpp"
|
||||
|
||||
class Playerkart;
|
||||
|
||||
class InputMap
|
||||
{
|
||||
typedef std::pair<int, int> Key;
|
||||
|
||||
public:
|
||||
typedef struct
|
||||
{
|
||||
PlayerKart *kart;
|
||||
KartActions action;
|
||||
} Entry;
|
||||
|
||||
void clear();
|
||||
|
||||
void putEntry(PlayerKart *, KartActions);
|
||||
|
||||
Entry *getEntry(InputType, int, int, int);
|
||||
|
||||
private:
|
||||
Key key(InputType, int, int, int);
|
||||
|
||||
std::map<Key, Entry *> inputMap;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@ -39,9 +39,15 @@ SDL_Surface *mainSurface;
|
||||
long flags;
|
||||
SDL_Joystick **sticks;
|
||||
|
||||
bool pointerVisible = true;
|
||||
|
||||
#define DEADZONE_MOUSE 1
|
||||
#define DEADZONE_JOYSTICK 1000
|
||||
|
||||
#define MULTIPLIER_MOUSE 750
|
||||
int mouseValX = 0;
|
||||
int mouseValY = 0;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void drv_init()
|
||||
{
|
||||
@ -67,6 +73,20 @@ void drv_init()
|
||||
ssgInit () ;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
drv_showPointer()
|
||||
{
|
||||
pointerVisible = true;
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
drv_hidePointer()
|
||||
{
|
||||
pointerVisible = false;
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void drv_toggleFullscreen(int resetTextures)
|
||||
{
|
||||
@ -79,10 +99,10 @@ void drv_toggleFullscreen(int resetTextures)
|
||||
flags |= SDL_FULLSCREEN;
|
||||
|
||||
if(menu_manager->isSomewhereOnStack(MENUID_RACE))
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
drv_showPointer();
|
||||
}
|
||||
else if(menu_manager->isSomewhereOnStack(MENUID_RACE))
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
drv_hidePointer();
|
||||
|
||||
SDL_FreeSurface(mainSurface);
|
||||
mainSurface = SDL_SetVideoMode(user_config->m_width, user_config->m_height, 0, flags);
|
||||
@ -168,32 +188,28 @@ void drv_loop()
|
||||
break;
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
input(IT_MOUSEMOTION, ev.motion.x, mainSurface->h - ev.motion.y, 0, 0);
|
||||
|
||||
#ifdef ALT_MOUSE_HANDLING
|
||||
// This probably needs better handling
|
||||
if (ev.motion.xrel < -DEADZONE_MOUSE)
|
||||
input(IT_MOUSEMOTION, 0, AD_NEGATIVE, 0, 1);
|
||||
else if(ev.motion.xrel > DEADZONE_MOUSE)
|
||||
input(IT_MOUSEMOTION, 0, AD_POSITIVE, 0, 1);
|
||||
else
|
||||
{
|
||||
input(IT_MOUSEMOTION, 0, AD_NEGATIVE, 0, 0);
|
||||
input(IT_MOUSEMOTION, 0, AD_POSITIVE, 0, 0);
|
||||
}
|
||||
|
||||
if (ev.motion.yrel < -DEADZONE_MOUSE)
|
||||
input(IT_MOUSEMOTION, 1, AD_NEGATIVE, 0, 1);
|
||||
else if(ev.motion.yrel > DEADZONE_MOUSE)
|
||||
input(IT_MOUSEMOTION, 1, AD_POSITIVE, 0, 1);
|
||||
else
|
||||
{
|
||||
input(IT_MOUSEMOTION, 1, AD_NEGATIVE, 0, 0);
|
||||
input(IT_MOUSEMOTION, 1, AD_POSITIVE, 0, 0);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
if (pointerVisible)
|
||||
{
|
||||
BaseGUI* menu= menu_manager->getCurrentMenu();
|
||||
if (menu != NULL)
|
||||
menu->inputPointer(ev.motion.x, mainSurface->h - ev.motion.y);
|
||||
|
||||
// Reset parameters for relative mouse handling to make sure we are
|
||||
// in a valid state when returning to relative mouse mode
|
||||
mouseValX = mouseValY = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouseValX = std::max(-32768,
|
||||
std::min(32768, mouseValX
|
||||
+ ev.motion.xrel
|
||||
* MULTIPLIER_MOUSE));
|
||||
mouseValY = std::max(-32768,
|
||||
std::min(32768, mouseValY
|
||||
+ ev.motion.yrel
|
||||
* MULTIPLIER_MOUSE));
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
input(IT_MOUSEBUTTON, ev.button.button, 0, 0, 0);
|
||||
break;
|
||||
@ -224,4 +240,16 @@ void drv_loop()
|
||||
break;
|
||||
} // switch
|
||||
} // while (SDL_PollEvent())
|
||||
|
||||
// Makes mouse behave like an analog axis.
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
@ -20,9 +20,14 @@
|
||||
#ifndef HEADER_SDLDRV_H
|
||||
#define HEADER_SDLDRV_H
|
||||
|
||||
enum MouseState { INITIAL, MOVED, RESET_NEEDED };
|
||||
|
||||
void drv_init();
|
||||
void drv_deinit();
|
||||
|
||||
void drv_showPointer();
|
||||
void drv_hidePointer();
|
||||
|
||||
void drv_toggleFullscreen(int resetTextures=1);
|
||||
|
||||
void drv_loop();
|
||||
|
Loading…
Reference in New Issue
Block a user