QTfrontend/util/SDLInteraction.cpp
changeset 6165 6fe3e922246e
parent 6164 62aa418ed214
child 6166 701c5b8fac56
equal deleted inserted replaced
6164:62aa418ed214 6165:6fe3e922246e
       
     1 /*
       
     2  * Hedgewars, a free turn based strategy game
       
     3  * Copyright (c) 2007-2011 Andrey Korotaev <unC0Rr@gmail.com>
       
     4  *
       
     5  * This program is free software; you can redistribute it and/or modify
       
     6  * it under the terms of the GNU General Public License as published by
       
     7  * the Free Software Foundation; version 2 of the License
       
     8  *
       
     9  * This program is distributed in the hope that it will be useful,
       
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    12  * GNU General Public License for more details.
       
    13  *
       
    14  * You should have received a copy of the GNU General Public License
       
    15  * along with this program; if not, write to the Free Software
       
    16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
       
    17  */
       
    18 
       
    19 
       
    20 #include "SDL.h"
       
    21 #include "SDL_mixer.h"
       
    22 
       
    23 #include "HWDataManager.h"
       
    24 
       
    25 #include "HWApplication.h"
       
    26 
       
    27 #include "SDLInteraction.h"
       
    28 
       
    29 extern char sdlkeys[1024][2][128];
       
    30 extern char xb360buttons[][128];
       
    31 extern char xb360dpad[128];
       
    32 extern char xbox360axes[][128];
       
    33 
       
    34 
       
    35 SDLInteraction & SDLInteraction::instance()
       
    36 {
       
    37     static SDLInteraction instance;
       
    38     return instance;
       
    39 }
       
    40 
       
    41 
       
    42 SDLInteraction::SDLInteraction()
       
    43 {
       
    44 
       
    45     SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK);
       
    46 
       
    47     musicInitialized = 0;
       
    48     music = NULL;
       
    49     if(SDL_NumJoysticks())
       
    50         addGameControllerKeys();
       
    51     SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
       
    52 
       
    53     soundMap = new QMap<QString,Mix_Chunk*>();
       
    54 }
       
    55 
       
    56 SDLInteraction::~SDLInteraction()
       
    57 {
       
    58     stopMusic();
       
    59     if (musicInitialized == 1) {
       
    60         if (music != NULL)
       
    61             Mix_FreeMusic(music);
       
    62         Mix_CloseAudio();
       
    63     }
       
    64     SDL_Quit();
       
    65 
       
    66     delete soundMap;
       
    67 }
       
    68 
       
    69 QStringList SDLInteraction::getResolutions() const
       
    70 {
       
    71     QStringList result;
       
    72 
       
    73     SDL_Rect **modes;
       
    74 
       
    75     modes = SDL_ListModes(NULL, SDL_FULLSCREEN);
       
    76 
       
    77     if((modes == (SDL_Rect **)0) || (modes == (SDL_Rect **)-1))
       
    78     {
       
    79         result << "640x480";
       
    80     } else
       
    81     {
       
    82         for(int i = 0; modes[i]; ++i)
       
    83             if ((modes[i]->w >= 640) && (modes[i]->h >= 480))
       
    84                 result << QString("%1x%2").arg(modes[i]->w).arg(modes[i]->h);
       
    85     }
       
    86 
       
    87     return result;
       
    88 }
       
    89 
       
    90 void SDLInteraction::addGameControllerKeys() const
       
    91 {
       
    92     QStringList result;
       
    93 
       
    94     int i = 0;
       
    95     while(i < 1024 && sdlkeys[i][1][0] != '\0')
       
    96         i++;
       
    97 
       
    98     // Iterate through all game controllers
       
    99     for(int jid = 0; jid < SDL_NumJoysticks(); jid++)
       
   100     {
       
   101         SDL_Joystick* joy = SDL_JoystickOpen(jid);
       
   102 
       
   103         // Retrieve the game controller's name and strip "Controller (...)" that's added by some drivers (English only)
       
   104         QString joyname = QString(SDL_JoystickName(jid)).replace(QRegExp("^Controller \\((.*)\\)$"), "\\1");
       
   105 
       
   106         // Connected Xbox 360 controller? Use specific button names then
       
   107         // Might be interesting to add 'named' buttons for the most often used gamepads
       
   108         bool isxb = joyname.contains("Xbox 360");
       
   109 
       
   110         // This part of the string won't change for multiple keys/hats, so keep it
       
   111         QString prefix = QString("%1 (%2): ").arg(joyname).arg(jid + 1);
       
   112 
       
   113         // Register entries for missing axes not assigned to sticks of this joystick/gamepad
       
   114         for(int aid = 0; aid < SDL_JoystickNumAxes(joy) && i < 1021; aid++)
       
   115         {
       
   116             // Again store the part of the string not changing for multiple uses
       
   117             QString axis = prefix + HWApplication::translate("binds (keys)", "Axis") + QString(" %1 ").arg(aid + 1);
       
   118 
       
   119             // Entry for "Axis Up"
       
   120             sprintf(sdlkeys[i][0], "j%da%du", jid, aid);
       
   121             sprintf(sdlkeys[i++][1], "%s", ((isxb && aid < 5) ? (prefix + HWApplication::translate("binds (keys)", xbox360axes[aid * 2])) : axis + HWApplication::translate("binds (keys)", "(Up)")).toUtf8().constData());
       
   122 
       
   123             // Entry for "Axis Down"
       
   124             sprintf(sdlkeys[i][0], "j%da%dd", jid, aid);
       
   125             sprintf(sdlkeys[i++][1], "%s", ((isxb && aid < 5) ? (prefix + HWApplication::translate("binds (keys)", xbox360axes[aid * 2 + 1])) : axis + HWApplication::translate("binds (keys)", "(Down)")).toUtf8().constData());
       
   126         }
       
   127 
       
   128         // Register entries for all coolie hats of this joystick/gamepad
       
   129         for(int hid = 0; hid < SDL_JoystickNumHats(joy) && i < 1019; hid++)
       
   130         {
       
   131             // Again store the part of the string not changing for multiple uses
       
   132             QString hat = prefix + (isxb ? (HWApplication::translate("binds (keys)", xb360dpad) + QString(" ")) : HWApplication::translate("binds (keys)", "Hat") + QString(" %1 ").arg(hid + 1));
       
   133 
       
   134             // Entry for "Hat Up"
       
   135             sprintf(sdlkeys[i][0], "j%dh%du", jid, hid);
       
   136             sprintf(sdlkeys[i++][1], "%s", (hat + HWApplication::translate("binds (keys)", "(Up)")).toUtf8().constData());
       
   137 
       
   138             // Entry for "Hat Down"
       
   139             sprintf(sdlkeys[i][0], "j%dh%dd", jid, hid);
       
   140             sprintf(sdlkeys[i++][1], "%s", (hat + HWApplication::translate("binds (keys)", "(Down)")).toUtf8().constData());
       
   141 
       
   142             // Entry for "Hat Left"
       
   143             sprintf(sdlkeys[i][0], "j%dh%dl", jid, hid);
       
   144             sprintf(sdlkeys[i++][1], "%s", (hat + HWApplication::translate("binds (keys)", "(Left)")).toUtf8().constData());
       
   145 
       
   146             // Entry for "Hat Right"
       
   147             sprintf(sdlkeys[i][0], "j%dh%dr", jid, hid);
       
   148             sprintf(sdlkeys[i++][1], "%s", (hat + HWApplication::translate("binds (keys)", "(Right)")).toUtf8().constData());
       
   149         }
       
   150 
       
   151         // Register entries for all buttons of this joystick/gamepad
       
   152         for(int bid = 0; bid < SDL_JoystickNumButtons(joy) && i < 1022; bid++)
       
   153         {
       
   154             // Buttons
       
   155             sprintf(sdlkeys[i][0], "j%db%d", jid, bid);
       
   156             sprintf(sdlkeys[i++][1], "%s", (prefix + ((isxb && bid < 10) ? (HWApplication::translate("binds (keys)", xb360buttons[bid]) + QString(" ")) : HWApplication::translate("binds (keys)", "Button") + QString(" %1").arg(bid + 1))).toUtf8().constData());
       
   157         }
       
   158         // Close the game controller as we no longer need it
       
   159         SDL_JoystickClose(joy);
       
   160     }
       
   161 
       
   162     // Terminate the list
       
   163     sdlkeys[i][0][0] = '\0';
       
   164     sdlkeys[i][1][0] = '\0';
       
   165 }
       
   166 
       
   167 void SDLInteraction::SDLSoundInit()
       
   168 {
       
   169     if (musicInitialized == 0) {
       
   170         SDL_Init(SDL_INIT_AUDIO);
       
   171         Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024);
       
   172         musicInitialized = 1;
       
   173     }
       
   174 }
       
   175 
       
   176 void SDLInteraction::playSoundFile(const QString & soundFile)
       
   177 {
       
   178     SDLSoundInit();
       
   179     if (!soundMap->contains(soundFile))
       
   180         soundMap->insert(soundFile, Mix_LoadWAV(soundFile.toLocal8Bit().constData()));
       
   181 
       
   182     Mix_PlayChannel(-1, soundMap->value(soundFile), 0);
       
   183 }
       
   184 
       
   185 void SDLInteraction::startMusic()
       
   186 {
       
   187     SDLSoundInit();
       
   188     QFile * tmpFile = HWDataManager::instance().findFileForRead("Music/main_theme.ogg");
       
   189 
       
   190     if (music == NULL)
       
   191         music = Mix_LoadMUS(tmpFile->fileName().toLocal8Bit().constData());
       
   192 
       
   193     // this QFile isn't needed any further
       
   194     delete tmpFile;
       
   195 
       
   196     Mix_VolumeMusic(MIX_MAX_VOLUME - 28);
       
   197     Mix_FadeInMusic(music, -1, 1750);
       
   198 }
       
   199 
       
   200 void SDLInteraction::stopMusic()
       
   201 {
       
   202     if (music != NULL) {
       
   203         // fade out music to finish 0,5 seconds from now
       
   204         while(!Mix_FadeOutMusic(1000) && Mix_PlayingMusic()) {
       
   205             SDL_Delay(100);
       
   206         }
       
   207     }
       
   208 }
       
   209