src/controls.cc

Go to the documentation of this file.
00001 /* vim: set noexpandtab shiftwidth=8 cino=:
00002  ***************************************************************************
00003  *            controls.cc
00004  *
00005  *  Sat Jun  4 08:18:38 2005
00006  *  Copyright  2005  Joe Venzon
00007  *  joe@venzon.net
00008  ****************************************************************************/
00009 
00010 /*
00011  *  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version.
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU General Public License
00022  *  along with this program; if not, write to the Free Software
00023  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00024  */
00025  
00026 #include "controls.h"
00027 
00028 void CONTROL::Dump()
00029 {
00030         cout << "Name: " << controlname << endl;
00031         cout << "Type: " << (int) controltype << " = ";
00032         if (controltype == Joy)
00033         {
00034                 cout << "Joy" << endl;
00035                 cout << "Joy number: " << joynum << endl;
00036                 cout << "Input type: ";
00037                 if (joytype == Button)
00038                 {
00039                         cout << "Button" << endl;
00040                         cout << "Button number: " << joybutton << endl;
00041                         cout << "One time: " << onetime << endl;
00042                 }
00043                 else if (joytype == Axis)
00044                 {
00045                         cout << "Axis" << endl;
00046                         cout << "Axis number: " << joyaxis << endl;
00047                         cout << "Axis type: " << joyaxistype << endl;
00048                 }
00049                 else
00050                         cout << "Unknown" << endl;
00051         }
00052         else if (controltype == Key)
00053         {
00054                 cout << "Key" << endl;
00055                 cout << "Keycode: " << keycode << endl;
00056                 cout << "One time: " << onetime << endl;
00057         }
00058         else if( controltype == Mouse )
00059         {
00060                 cout << "Mouse" << endl;
00061                 if( mousetype == MButton )
00062                 {
00063                         cout << "Button: " << mbutton << endl;
00064                         cout << "One time: " << onetime << endl;
00065                 }
00066                 else if( mousetype == Motion )
00067                 {
00068                         cout << "Direction: " << mdir << endl;
00069                 }
00070                 else
00071                 {
00072                         cout << "unknown" << endl;
00073                 }
00074         }
00075         else
00076                 cout << "Unknown" << endl;
00077 }
00078 
00079 
00080 void GAMECONTROLS::LoadControls(string fname)
00081 {
00082         UpdateSettings();
00083 
00084         error_log.open((settings.GetSettingsDir() + "/logs/controls.log").c_str());
00085         
00086         LoadCalibration();
00087         
00088         ifstream controlfile(fname.c_str());
00089         
00090         if (!controlfile)
00091                 error_log << "Couldn't open control file: " << fname << endl;
00092         
00093         //first pass to get the number of lines
00094         string input;
00095         input = utility.sGetLine(controlfile);
00096         int numcontrols = 0;
00097         while (input != "!!!END OF FILE!!!")
00098         {
00099                 input = utility.sGetLine(controlfile);
00100                 if(input.find("joysticktype") == string::npos && input.find("!!!END OF FILE!!!") == string::npos)
00101                         numcontrols++;
00102         }
00103         
00104         //delete [] controls;
00105         controls.clear();
00106         
00107         //controls = new CONTROL [numcontrols];
00108         
00109         controlfile.close();
00110         controlfile.open(fname.c_str());
00111         controlfile.clear();
00112         
00113         //second pass to actually read the file
00114         
00115         int i;
00116         for (i = 0; i < numcontrols; i++)
00117         {
00118                 input = utility.sGetParam(controlfile);
00119                 if (input == "joysticktype")
00120                 {
00121 
00122                         joysticktype = utility.sGetParam(controlfile);
00123                         //input = utility.sGetParam(controlfile);
00124                         compensation = utility.sGetParam(controlfile);
00125                         deadzone = utility.sGetParam(controlfile);
00126                         if (joysticktype != "wheel" && joysticktype != "joystick")
00127                         {
00128                                 cout << "invalid joystick type in " + settings.GetSettingsDir() + "/controls: " << joysticktype << endl;
00129                                 joysticktype = "joystick";
00130                         }
00131                         if (compensation != "off" && compensation != "low" && compensation != "med" && compensation != "high" && compensation != "900to200" && compensation != "speed1" && compensation != "speed2")
00132                         {
00133                                 cout << "invalid joystick touchiness compensation in " + settings.GetSettingsDir() + "/controls: " << compensation << endl;
00134                                 compensation = "off";
00135                         }
00136                         if (deadzone != "off" && deadzone != "low" && deadzone != "med" && deadzone != "high")
00137                         {
00138                                 cout << "invalid joystick deadzone in " + settings.GetSettingsDir() + "/controls: " << deadzone << endl;
00139                                 deadzone = "off";
00140                         }
00141                         i--;
00142                 }
00143                 else
00144                 {
00145                         CONTROL newctrl;
00146                         newctrl.SetName(input);
00147                         //controls[i].SetName(utility.sGetParam(controlfile));
00148                         newctrl.SetType(utility.sGetParam(controlfile));
00149                         if (newctrl.GetType() == Joy)
00150                         {
00151                                 newctrl.SetJoyNum(utility.iGetParam(controlfile));
00152                                 newctrl.SetJoyType(utility.sGetParam(controlfile));
00153                                 if (newctrl.GetJoyType() == Button)
00154                                 {
00155                                         newctrl.SetJoyButton(utility.iGetParam(controlfile));
00156                                         newctrl.SetOneTime(utility.bGetParam(controlfile));
00157                                         
00158                                         //if (controls[i].GetOneTime())
00159                                                 newctrl.SetJoyPushDown(utility.bGetParam(controlfile));
00160                                 }
00161                                 else if (newctrl.GetJoyType() == Axis)
00162                                 {
00163                                         newctrl.SetJoyAxis(utility.iGetParam(controlfile));
00164                                         string axis_type = utility.sGetParam(controlfile);
00165                                         if (axis_type == "positive")
00166                                                 newctrl.SetJoyAxisType(Positive);
00167                                         else if (axis_type == "negative")
00168                                                 newctrl.SetJoyAxisType(Negative);
00169                                         else if (axis_type == "both")
00170                                                 newctrl.SetJoyAxisType(Both);
00171                                         else
00172                                         {
00173                                                 ControlParseError(i, controlfile);
00174                                                 i = numcontrols; //exit loop
00175                                         }
00176                                 }
00177                                 else
00178                                 {
00179                                         ControlParseError(i, controlfile);
00180                                         i = numcontrols; //exit loop
00181                                 }
00182                         }
00183                         else if (newctrl.GetType() == Key)
00184                         {
00185                                 newctrl.SetKeyCode(keyman.GetKey(utility.sGetParam(controlfile)));
00186                                 newctrl.SetOneTime(utility.bGetParam(controlfile));
00187                                 newctrl.SetKeyPushDown(utility.bGetParam(controlfile));
00188                         }
00189                         else if( newctrl.GetType() == Mouse )
00190                         {
00191                                 newctrl.SetMouseType( utility.sGetParam( controlfile ) );
00192                                 if( newctrl.GetMouseType() == MButton )
00193                                 {
00194                                         newctrl.SetMouseButton( utility.sGetParam( controlfile ) );
00195                                         newctrl.SetOneTime( utility.bGetParam( controlfile ) );
00196                                         newctrl.SetMousePushDown( utility.bGetParam( controlfile ) );
00197                                 }
00198                                 else if( newctrl.GetMouseType() == Motion )
00199                                 {
00200                                         newctrl.SetMouseDirection( utility.sGetParam( controlfile ) );
00201                                 }
00202                                 else
00203                                 {
00204                                         ControlParseError( i, controlfile );
00205                                         i = numcontrols; // exit loop
00206                                 }
00207                         }
00208                         else
00209                         {
00210                                 ControlParseError(i, controlfile);
00211                                 i = numcontrols; //exit loop
00212                         }
00213                         
00214                         controls.push_back(newctrl);
00215                 }
00216         }
00217 
00218 /*
00219         //for debugging
00220         for( list<CONTROL>::iterator i = controls.begin(); i != controls.end(); ++i )
00221         {
00222                 i->Dump();
00223                 cout << endl;
00224         }
00225 */
00226 }
00227 
00228 void GAMECONTROLS::ControlParseError(int line, ifstream & ffrom)
00229 {
00230         error_log << "Error parsing control number " << line << endl;
00231         ffrom.unget();
00232         ffrom.unget();
00233         ffrom.unget();
00234         ffrom.unget();
00235         ffrom.unget();
00236         string errorword;
00237         ffrom >> errorword;
00238         ffrom.seekg(0, ios_base::beg);
00239         string errorline;
00240         int i;
00241         for (i = 0; i <= line; i++)
00242                 errorline = utility.sGetLine(ffrom);
00243         error_log << "The line was: " << errorline << endl;
00244         //error_log << "The error is in the vicinity of: " << errorword << endl;
00245 }
00246 
00247 GAMECONTROLS::GAMECONTROLS()
00248 {
00249         controls.clear();
00250         //numcontrols = 0;
00251         
00252         joysticktype = "joystick";
00253         
00254         int i;
00255         for (i = 0; i < MAX_JOYSTICKS; i++)
00256         {
00257                 int m;
00258                 for (m = 0; m < MAX_AXES; m++)
00259                 {
00260                         calibration[i][m][0] = -1;
00261                         calibration[i][m][1] = 1;
00262                 }
00263         }
00264 }
00265 
00266 extern bool verbose_output;
00267 GAMECONTROLS::~GAMECONTROLS()
00268 {
00269         if (verbose_output)
00270                 cout << "gamecontrols deinit" << endl;
00271         
00272         //delete [] controls;
00273         controls.clear();
00274         error_log.close();
00275 }
00276 
00277 /*list <CONTROL> & GAMECONTROLS::GetControls()
00278 {
00279         return controls;
00280 }*/
00281 
00282 int GAMECONTROLS::GetNumControls()
00283 {
00284         //return numcontrols;
00285         return controls.size();
00286 }
00287 
00288 void GAMECONTROLS::SetControls(CONTROL * newcontrols, int newnum)
00289 {
00290         /*delete [] controls;
00291         controls = newcontrols;
00292         numcontrols = newnum;*/
00293         
00294         controls.clear();
00295         for (int i = 0; i < newnum; i++)
00296                 controls.push_back(newcontrols[i]);
00297 }
00298 
00299 void GAMECONTROLS::WriteControlFile()
00300 {
00301         WriteControlFile(settings.GetSettingsDir() + "/controls");
00302 }
00303 
00304 void GAMECONTROLS::WriteControlFile(string fname)
00305 {
00306         CONFIGFILE c;
00307         
00308         ofstream controlfile(fname.c_str());
00309         
00310         if (!controlfile)
00311                 error_log << "Couldn't open control file for writing: " << fname << endl;
00312         
00313         controlfile << "#Generated by VDrift, feel free to edit manually" << endl << endl;
00314 
00315         controlfile << "# joystick type:  wheel or joystick, touchiness compensation" << endl;  
00316         controlfile << "joysticktype " << joysticktype << " " << compensation << " " << deadzone << endl << endl;
00317 
00318 
00319         // save settings in config file
00320         settings.Set( "joystick.type", joysticktype );
00321         settings.Set( "joystick.touchcomp", compensation );
00322         settings.Set( "joystick.deadzone", deadzone );
00323 
00324         controlfile << "# for a joystick button:" << endl << "# [function name] joy [joystick number] button [button number] [true for not held down, false for held down] [true to trigger when button is pressed, false to trigger when button is released]" << endl << endl;
00325 
00326         controlfile << "# for a joystick axis:" << endl << "# [function name] joy [joystick number] axis [axis number] [true for positive axis, false for negative axis]" << endl << endl;
00327 
00328         controlfile << "# for a keyboard key:" << endl << "# [fuction name] key [key name as defined in lists/keys] [true for keys that aren't held down, false for keys that are]  [true to trigger when key is pressed, false to trigger when key is released]" << endl << endl;
00329 
00330         //int i;
00331         //for (i = 0; i < numcontrols; i++)
00332         for (ControlIteratorReset(); ControlIteratorGetControl() != NULL; ControlIteratorIncrement())
00333         {
00334                 CONTROL & curctrl = *(ControlIteratorGetControl());
00335                 controlfile << curctrl.GetName() << " ";
00336                 if (curctrl.GetType() == Joy)
00337                 {
00338                         controlfile << "joy ";
00339                         controlfile << curctrl.GetJoyNum() << " ";
00340                         
00341                         if (curctrl.GetJoyType() == Axis)
00342                         {
00343                                 controlfile << "axis ";
00344                                 controlfile << curctrl.GetJoyAxis() << " ";
00345                                 switch (curctrl.GetJoyAxisType()) {
00346                                         case Positive:
00347                                                 controlfile << "positive";
00348                                                 break;
00349                                         case Negative:
00350                                                 controlfile << "negative";
00351                                                 break;
00352                                         case Both:
00353                                                 controlfile << "both";
00354                                                 break;
00355                                 }
00356                         }
00357                         else if (curctrl.GetJoyType() == Button)
00358                         {
00359                                 controlfile << "button ";
00360                                 controlfile << curctrl.GetJoyButton() << " ";
00361                                 if (curctrl.GetOneTime())
00362                                         controlfile << "true ";
00363                                 else
00364                                         controlfile << "false ";
00365                                 if (curctrl.GetJoyPushDown())
00366                                         controlfile << "true";
00367                                 else
00368                                         controlfile << "false";
00369                         }
00370                 }
00371                 else if (curctrl.GetType() == Key)
00372                 {
00373                         controlfile << "key ";
00374                         controlfile << keyman.GetKeyName(curctrl.GetKeyCode()) << " ";
00375                         if (curctrl.GetOneTime())
00376                                 controlfile << "true ";
00377                         else
00378                                 controlfile << "false ";
00379                         if (curctrl.GetKeyPushDown())
00380                                 controlfile << "true";
00381                         else
00382                                 controlfile << "false";
00383                 }
00384                 else if( curctrl.GetType() == Mouse )
00385                 {
00386                         controlfile << "mouse ";
00387                         if( curctrl.GetMouseType() == MButton )
00388                         {
00389                                 controlfile << "button ";
00390                                 controlfile << curctrl.GetMouseButton() << " ";
00391                                 if( curctrl.GetOneTime() )
00392                                         controlfile << "true ";
00393                                 else
00394                                         controlfile << "false ";
00395                                 if( curctrl.GetMousePushDown() )
00396                                         controlfile << "true ";
00397                                 else
00398                                         controlfile << "false ";
00399                         }
00400                         else if( curctrl.GetMouseType() == Motion )
00401                         {
00402                                 string direction;
00403                                 int mdir = curctrl.GetMouseDirection();
00404                                 if( mdir == Up )
00405                                         direction = "up";
00406                                 else if( mdir == Down )
00407                                         direction = "down";
00408                                 else if( mdir == Left )
00409                                         direction = "left";
00410                                 else if( mdir == Right )
00411                                         direction = "right";
00412 
00413                                 controlfile << "motion " << direction;
00414                         }
00415                 }
00416                 controlfile << endl;
00417         }
00418         
00419         controlfile.close();
00420 }
00421 
00422 void GAMECONTROLS::LoadCalibration()
00423 {
00424         ifstream cf;
00425         cf.open((settings.GetSettingsDir() + "/calibration").c_str());
00426         if (cf)
00427         {
00428                 int i, m;
00429                 for (i = 0; i < MAX_JOYSTICKS; i++)
00430                 {
00431                         for (m = 0; m < MAX_AXES; m++)
00432                         {
00433                                 calibration[i][m][0] = utility.fGetParam(cf);
00434                                 calibration[i][m][1] = utility.fGetParam(cf);
00435                                 
00436                                 if (calibration[i][m][0] > -0.1)
00437                                         calibration[i][m][0] = -0.1;
00438                                 if (calibration[i][m][1] < 0.1)
00439                                         calibration[i][m][1] = 0.1;
00440                         }
00441                 }
00442         
00443                 cf.close();
00444         }
00445 }
00446 
00447 void GAMECONTROLS::WriteCalibration()
00448 {
00449         ofstream cf;
00450         cf.open((settings.GetSettingsDir() + "/calibration").c_str());
00451         if (cf)
00452         {
00453                 cf << "# VDrift joystick calibration file.\n#Each line is an axis with the format [min] [max]" << endl << endl;
00454                 int i, m;
00455                 for (i = 0; i < MAX_JOYSTICKS; i++)
00456                 {
00457                         for (m = 0; m < MAX_AXES; m++)
00458                                 cf << calibration[i][m][0] << " " << calibration[i][m][1] << endl;
00459                 }
00460                 
00461                 cf.close();
00462         }
00463         else
00464                 cout << "Error writing calibration file to " + settings.GetSettingsDir() + "/calibration" << endl;
00465 }
00466 
00467 float GAMECONTROLS::GetCalibration(int joynum, int joyaxis, bool max)
00468 {
00469         float c;
00470         
00471         if (joynum >= MAX_JOYSTICKS || joyaxis >= MAX_AXES)
00472         {
00473                 if (max)
00474                         return 1;
00475                 else
00476                         return -1;
00477         }
00478 
00479         if (max)
00480                 c = calibration[joynum][joyaxis][1];
00481         else
00482                 c = calibration[joynum][joyaxis][0];
00483         
00484         return c;
00485 }
00486 
00487 void GAMECONTROLS::InitJoy()
00488 {
00489         int j;
00490         for (j = 0; j < SDL_NumJoysticks(); j++)
00491         {
00492                 js[j] = SDL_JoystickOpen(j);
00493         }
00494 }
00495 
00496 void GAMECONTROLS::DeinitJoy()
00497 {
00498         int j;
00499         for (j = 0; j < SDL_NumJoysticks(); j++)
00500                 SDL_JoystickClose(js[j]);
00501 }
00502 
00503 void GAMECONTROLS::MinimizeCalibration()
00504 {
00505         int i;
00506         for (i = 0; i < MAX_JOYSTICKS; i++)
00507         {
00508                 int m;
00509                 for (m = 0; m < MAX_AXES; m++)
00510                 {
00511                         calibration[i][m][0] = -0.1;
00512                         calibration[i][m][1] = 0.1;
00513                 }
00514         }
00515 }
00516 
00517 void GAMECONTROLS::SetCalibrationPoint(int joynum, int joyaxis, float val)
00518 {
00519         if (val < calibration[joynum][joyaxis][0])
00520                 calibration[joynum][joyaxis][0] = val;
00521         if (val > calibration[joynum][joyaxis][1])
00522                 calibration[joynum][joyaxis][1] = val;
00523 }
00524 
00525 void GAMECONTROLS::UpdateSettings()
00526 {
00527         bool got_type = settings.Get( "joystick.type", joysticktype );
00528         bool got_comp = settings.Get( "joystick.touchcomp", compensation );
00529         bool got_zone = settings.Get( "joystick.deadzone", deadzone );
00530 
00531         if( !got_type || ( joysticktype != "wheel" && joysticktype != "joystick" ) )
00532         {
00533                 cout << "controls: invalid joystick type, default to joystick." << endl;
00534                 joysticktype = "joystick";
00535         }
00536 
00537         if( !got_comp || ( compensation != "off" && compensation != "low" && compensation != "med" && compensation != "high" && compensation != "900to200" && compensation != "speed1" && compensation != "speed2") )
00538         {
00539                 cout << "controls: invalid joystick touchiness compensation, default to off." << endl;
00540                 compensation = "off";
00541         }
00542 
00543         if( !got_zone || ( deadzone != "off" && deadzone != "low" && deadzone != "med" && deadzone != "high" ) )
00544         {
00545                 cout << "controls: invalid joystick deadzone, default to off." << endl;
00546                 deadzone = "off";
00547         }
00548 }
00549 
00550 void GAMECONTROLS::DeleteControlsWithAction(string actionstr)
00551 {
00552         list <CONTROL>::iterator i;
00553         bool found;
00554         bool done = false;
00555         
00556         while( !done )
00557         {
00558                 found = false;
00559                 for( i = controls.begin(); i != controls.end(); ++i )
00560                 {
00561                         if( i->GetName() == actionstr )
00562                         {
00563                                 found = true;
00564                                 break;
00565                         }
00566                 }
00567 
00568                 if( found )
00569                 {
00570                         controls.erase( i );
00571                 }
00572                 else if( i == controls.end() )
00573                 {
00574                         done = true;
00575                 }
00576         }
00577 }
00578 
00579 void GAMECONTROLS::AddControl(CONTROL & other)
00580 {
00581         controls.push_back(other);
00582 }

Generated on Thu Oct 19 04:05:48 2006 by  doxygen 1.4.6