From 2abeb7fed074e80ebdd71759aa0c03c4bc77da63 Mon Sep 17 00:00:00 2001 From: thebohemian Date: Wed, 19 Sep 2007 10:54:27 +0000 Subject: [PATCH] - adds behind view feature and the neccessary settings additions git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1245 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/camera.cpp | 34 +++++++++++++++++++++++++++------- src/camera.hpp | 6 ++++++ src/gui/help_menu.cpp | 2 +- src/gui/player_controls.cpp | 6 +++--- src/gui/player_controls.hpp | 2 +- src/gui/race_gui.cpp | 4 ++-- src/player.hpp | 12 +++++++----- src/player_kart.cpp | 5 +++++ src/player_kart.hpp | 6 ++++-- src/race_manager.cpp | 3 --- src/scene.cpp | 11 ++++++++--- src/scene.hpp | 4 ++-- src/user_config.cpp | 33 ++++++++++++++++++++++++++++----- src/world.cpp | 9 +++++++-- 14 files changed, 101 insertions(+), 36 deletions(-) diff --git a/src/camera.cpp b/src/camera.cpp index 6f0a2f7a6..16ce6b634 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -67,6 +67,7 @@ Camera::setScreenPosition ( int numPlayers, int pos ) //----------------------------------------------------------------------------- Camera::Camera ( int numPlayers, int which_ ) + : m_reverse(false) { m_which_kart = which_ ; // Just for now m_mode = CM_NORMAL; @@ -90,6 +91,13 @@ Camera::setMode(Mode mode_) m_mode = mode_; } +//----------------------------------------------------------------------------- +void +Camera::setReverseHeading(bool b) +{ + m_reverse = b; +} + //----------------------------------------------------------------------------- void Camera::update (float dt) { @@ -132,7 +140,17 @@ void Camera::update (float dt) else sgMakeTransMat4(cam_pos, 0.f, -3.5f, 1.5f); - if (m_mode == CM_NO_FAKE_DRIFT) + if (m_reverse) + { + // If player is looking back all other camera options are ignored. + sgMat4 cam_lb; + sgMakeTransMat4(cam_pos, 0.f, -2.5f, 0.75f); + + // Applies 'look back' rotation. + sgMakeRotMat4(cam_lb, 180, 0, 0); + sgMultMat4(relative, cam_pos, cam_lb); + } + else if (m_mode == CM_NO_FAKE_DRIFT) { const float STEER_OFFSET = world->getPlayerKart(m_which_kart)->getSteerAngle()*-10.0f; @@ -145,12 +163,14 @@ void Camera::update (float dt) } else { - sgMat4 cam_rot; - if (m_mode == CM_CLOSEUP) - sgMakeRotMat4(cam_rot, 0, -15, 0); - else - sgMakeRotMat4(cam_rot, 0, -5, 0); - sgMultMat4(relative, cam_pos, cam_rot); + sgMat4 cam_rot; + + if (m_mode == CM_CLOSEUP) + sgMakeRotMat4(cam_rot, 0, -15, 0); + else + sgMakeRotMat4(cam_rot, 0, -5, 0); + + sgMultMat4(relative, cam_pos, cam_rot); } sgMat4 result; diff --git a/src/camera.hpp b/src/camera.hpp index e2f6bf9cb..dd81b346f 100644 --- a/src/camera.hpp +++ b/src/camera.hpp @@ -42,16 +42,22 @@ protected: float m_x, m_y, m_w, m_h ; float m_LastPitch; + bool m_reverse; + public: Camera ( int numPlayers, int id ) ; /** Set the camera to the given mode */ void setMode(Mode mode_); + void setReverseHeading(bool); + void setScreenPosition ( int numPlayers, int pos ) ; void update (float dt) ; void apply () ; + + int getKartId() const { return m_which_kart; } } ; #endif diff --git a/src/gui/help_menu.cpp b/src/gui/help_menu.cpp index 01adcb06e..6ae6d3f6b 100644 --- a/src/gui/help_menu.cpp +++ b/src/gui/help_menu.cpp @@ -190,7 +190,7 @@ get stuck or fall too far, use the rescue button to get back on track."), const int LABEL_ID = widgetSet->varray(HS3); widgetSet -> filler(HS3); - for(int i = KC_LEFT; i <= KC_FIRE; i++) + for(int i = KC_LEFT; i <= KC_LAST; i++) { //FIXME: this is temporal, just while the jumping is disabled. if(i == KC_JUMP) continue; diff --git a/src/gui/player_controls.cpp b/src/gui/player_controls.cpp index 570261b6b..96cb7c94b 100644 --- a/src/gui/player_controls.cpp +++ b/src/gui/player_controls.cpp @@ -27,9 +27,9 @@ #include -char *sKartAction2String[KC_FIRE+1] = {_("Left"), _("Right"), _("Accelerate"), +char *sKartAction2String[KC_LAST+1] = {_("Left"), _("Right"), _("Accelerate"), _("Brake"), _("Wheelie"), _("Jump"), - _("Rescue"), _("Fire") }; + _("Rescue"), _("Fire"), _("Look back") }; PlayerControls::PlayerControls(int whichPlayer): m_player_index(whichPlayer), @@ -50,7 +50,7 @@ PlayerControls::PlayerControls(int whichPlayer): m_player_index(whichPlayer), widgetSet->label(LABEL_ID, _("Player name")); m_name = user_config->m_player[m_player_index].getName(); m_name_id = widgetSet->state(CHANGE_ID, m_name.c_str(), GUI_MED, -2); - for(int i=KC_LEFT; i<=KC_FIRE; i++) + for(int i=0; i<=KC_LAST; i++) { //FIXME: this is temporal, just while the jumping is disabled. if(i==KC_JUMP) continue; diff --git a/src/gui/player_controls.hpp b/src/gui/player_controls.hpp index d0f93d64e..501c5b76e 100644 --- a/src/gui/player_controls.hpp +++ b/src/gui/player_controls.hpp @@ -47,7 +47,7 @@ private: // memory leaks or complicated memory management char m_heading[60]; std::string m_name; - std::string m_key_names[KC_FIRE+1]; + std::string m_key_names[KC_LAST+1]; }; #endif diff --git a/src/gui/race_gui.cpp b/src/gui/race_gui.cpp index 4dab8043c..bb3b543c1 100644 --- a/src/gui/race_gui.cpp +++ b/src/gui/race_gui.cpp @@ -95,7 +95,7 @@ void RaceGUI::UpdateKeyboardMappings() // 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) + // 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(); @@ -103,7 +103,7 @@ void RaceGUI::UpdateKeyboardMappings() { PlayerKart* kart = world->getPlayerKart(i); - for(int ka=(int) KC_LEFT;ka< (int) KC_FIRE+1;ka++) + for(int ka=(int) KC_LEFT;ka< (int) KC_LAST+1;ka++) putEntry(kart, (KartActions) ka); } diff --git a/src/player.hpp b/src/player.hpp index ad2d09d5e..ebe3248b7 100644 --- a/src/player.hpp +++ b/src/player.hpp @@ -24,8 +24,8 @@ enum AxisDirection { AD_NEGATIVE, AD_POSITIVE }; -enum InputType { IT_KEYBOARD, IT_STICKMOTION, IT_STICKBUTTON, IT_STICKHAT, IT_MOUSEMOTION, IT_MOUSEBUTTON }; -#define IT_LAST IT_MOUSEBUTTON +enum InputType { IT_NONE, IT_KEYBOARD, IT_STICKMOTION, IT_STICKBUTTON, IT_STICKHAT, IT_MOUSEMOTION, IT_MOUSEBUTTON }; +#define IT_LAST (IT_MOUSEBUTTON) typedef struct { @@ -46,15 +46,17 @@ enum KartActions { KC_LEFT, KC_WHEELIE, KC_JUMP, KC_RESCUE, - KC_FIRE }; + KC_FIRE, + KC_LOOK_BACK }; +#define KC_LAST (KC_LOOK_BACK) -extern char *sKartAction2String[KC_FIRE+1]; +extern 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_FIRE+1]; + Input m_action_map[KC_LAST+1]; unsigned int m_last_kart_id; public: diff --git a/src/player_kart.cpp b/src/player_kart.cpp index 6a0d726cd..44b728220 100644 --- a/src/player_kart.cpp +++ b/src/player_kart.cpp @@ -28,6 +28,7 @@ #include "gui/menu_manager.hpp" #include "gui/race_gui.hpp" #include "translation.hpp" +#include "camera.hpp" void PlayerKart::action(KartActions action, int value) { @@ -66,6 +67,9 @@ void PlayerKart::action(KartActions action, int value) case KC_FIRE: m_controls.fire = value; break; + case KC_LOOK_BACK: + m_camera->setReverseHeading(value); + break; case KC_JUMP: #ifdef ENABLE_JUMPING m_controls.jump = value; @@ -189,6 +193,7 @@ void PlayerKart::reset() m_controls.wheelie = false; m_controls.jump = false; m_penalty_time = 0; + m_camera->setReverseHeading(false); Kart::reset(); } //----------------------------------------------------------------------------- diff --git a/src/player_kart.hpp b/src/player_kart.hpp index 9253d4104..dc66a4575 100644 --- a/src/player_kart.hpp +++ b/src/player_kart.hpp @@ -26,6 +26,7 @@ #include "player.hpp" class Player; +class Camera; /** PlayerKart manages control events from the player and moves them to the Kart */ @@ -36,14 +37,15 @@ private: Player *m_player; float m_penalty_time; + Camera *m_camera; void steer(float, int); public: PlayerKart(const KartProperties *kart_properties, int position, Player *_player, - sgCoord init_pos) : + sgCoord init_pos, Camera *cam) : Kart(kart_properties, position, init_pos), m_player(_player), - m_penalty_time(0.0) {reset(); } + m_penalty_time(0.0), m_camera(cam) {reset(); } int earlyStartPenalty () {return m_penalty_time>0; } Player* getPlayer () {return m_player; } diff --git a/src/race_manager.cpp b/src/race_manager.cpp index 082ab886b..ee9aeb4f0 100644 --- a/src/race_manager.cpp +++ b/src/race_manager.cpp @@ -118,7 +118,6 @@ GrandPrixMode::start_race(int n) // handling of objects which get created in the constructor // and need world to be defined. new World(raceSetup); - scene->set_race_cameras(raceSetup.getNumPlayers()); } //----------------------------------------------------------------------------- @@ -198,7 +197,6 @@ QuickRaceMode::start() // handling of objects which get created in the constructor // and need world to be defined. new World(raceSetup); - scene->set_race_cameras(raceSetup.getNumPlayers()); } //============================================================================= @@ -226,7 +224,6 @@ TimeTrialMode::start() // handling of objects which get created in the constructor // and need world to be defined. new World(raceSetup); - scene->set_race_cameras(raceSetup.getNumPlayers()); } //============================================================================= diff --git a/src/scene.cpp b/src/scene.cpp index b09fe39a7..ca7d2297f 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -64,10 +64,15 @@ void Scene::clear () } //----------------------------------------------------------------------------- -void Scene::set_race_cameras(int num_players) + +Camera * +Scene::createCamera(int numPlayers, int playerId) { - for(int i = 0; i < num_players; ++i) - m_cameras.push_back(new Camera(num_players, i)); + Camera *cam = new Camera(numPlayers, playerId); + + m_cameras.push_back(cam); + + return cam; } //----------------------------------------------------------------------------- diff --git a/src/scene.hpp b/src/scene.hpp index 957badf49..acde38512 100644 --- a/src/scene.hpp +++ b/src/scene.hpp @@ -42,9 +42,9 @@ public: void add(ssgEntity *kid); void remove(ssgEntity *kid); void draw(float dt); - void set_race_cameras(int num_players); - //TODO: add camera + Camera *createCamera(int numPlayers, int playerId); + }; extern Scene *scene; diff --git a/src/user_config.cpp b/src/user_config.cpp index 9bed0a5b1..ee45372f1 100644 --- a/src/user_config.cpp +++ b/src/user_config.cpp @@ -151,6 +151,7 @@ void UserConfig::setDefaults() 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); /*player 2 default keyboard settings*/ m_player[1].setInput(KC_LEFT, IT_KEYBOARD, SDLK_a, 0, 0); @@ -159,8 +160,9 @@ void UserConfig::setDefaults() 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_LALT, 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); /*player 3 default keyboard settings*/ m_player[2].setInput(KC_LEFT, IT_KEYBOARD, SDLK_f, 0, 0); @@ -169,8 +171,9 @@ void UserConfig::setDefaults() 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_b, 0, 0); - m_player[2].setInput(KC_FIRE, IT_KEYBOARD, SDLK_n, 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); /*player 4 default keyboard settings*/ m_player[3].setInput(KC_LEFT, IT_KEYBOARD, SDLK_j, 0, 0); @@ -179,8 +182,9 @@ void UserConfig::setDefaults() 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_PERIOD, 0, 0); - m_player[3].setInput(KC_FIRE, IT_KEYBOARD, SDLK_SLASH, 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 @@ -366,6 +370,7 @@ void UserConfig::loadConfig(const std::string& filename) 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]); } } catch(std::exception& e) @@ -392,6 +397,14 @@ void UserConfig::readInput(const lisp::Lisp* &r, // to the player. int id0 = -1, id1 = -1, id2 = -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); if (inputTypeName == "keyboard") { @@ -516,6 +529,7 @@ void UserConfig::saveConfig(const std::string& filename) 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]); writer.endList(temp); } // for i @@ -535,6 +549,10 @@ void UserConfig::writeInput(lisp::Writer &writer, const char *node, KartActions { const Input *INPUT = player.getInput(action); + // Write no entry if the input has no mapping. + if (INPUT->type == IT_NONE) + return; + writer.beginList(node); switch (INPUT->type) @@ -568,6 +586,8 @@ void UserConfig::writeInput(lisp::Writer &writer, const char *node, KartActions writer.write("type", "mousebutton"); writer.write("button", INPUT->id0); break; + default: + break; } writer.endList(node); @@ -582,6 +602,9 @@ std::string UserConfig::getInputAsString(int player_index, KartActions control) 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)); break; diff --git a/src/world.cpp b/src/world.cpp index dfafb1de7..c7672ca41 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -51,6 +51,8 @@ #include "translation.hpp" #include "highscore_manager.hpp" #include "scene.hpp" +#include "camera.hpp" + #include "robots/default_robot.hpp" #ifdef HAVE_GHOST_REPLAY # include "replay_player.hpp" @@ -145,10 +147,13 @@ World::World(const RaceSetup& raceSetup_) : m_race_setup(raceSetup_) if (std::find(m_race_setup.m_players.begin(), m_race_setup.m_players.end(), pos) != m_race_setup.m_players.end()) { + + Camera *cam = scene->createCamera(m_race_setup.getNumPlayers(), playerIndex); // the given position belongs to a player newkart = new PlayerKart (kart_properties_manager->getKart(*i), pos, - &(user_config->m_player[playerIndex++]), - init_pos); + &(user_config->m_player[playerIndex]), + init_pos, cam); + playerIndex++; } else {