| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- #include "ControlsIniParser.h"
- #include "..\..\common_h\fileservice.h"
- #include "pc.h"
- ControlsIniParser::ControlsIniParser() :
- m_mappingTables(__FILE__, __LINE__)
- {
- }
- // выбирает из строки ini-файла элементы разделенные запятой или знаком плюс.
- string ControlsIniParser::GetToken(const char* str, unsigned int startPosition, const char* separators, char * separator)
- {
- string result;
- if (separator)
- *separator = 0;
- unsigned int inputStrLen = strlen(str);
- unsigned int sepStrLen = strlen(separators);
- for (unsigned int i = startPosition; i < inputStrLen; ++i)
- {
- for (unsigned int j = 0; j < sepStrLen; ++j)
- {
- if (str[i] == separators[j])
- {
- if (separator)
- *separator = separators[j];
- return result;
- }
- }
- result += str[i];
- }
- return result;
- }
- void ControlsIniParser::ParseToken(const char* token, Token& parsedToken)
- {
- // формат
- // [-|!][(scale)]name
- // примеры
- // kb_down
- // -kb_up
- // -(0.75)kb_up
- // !gp_A0
- // (10)gp_b0
- // -!(0.75)kb_up
- parsedToken.scale = 1.0f;
- parsedToken.isInverted = false;
- parsedToken.isReverse = false;
- parsedToken.name.Empty();
- bool scaleSection = false;
- string scale;
- unsigned int tokenLen = strlen(token);
- for (unsigned int i = 0; i < tokenLen; ++i)
- {
- if (scaleSection)
- {
- if (token[i] == ')')
- {
- scaleSection = false;
- parsedToken.scale = (float)atof(&scale[0]);
- }
- else
- scale += token[i];
- }
- else
- switch (token[i])
- {
- case '-':
- parsedToken.isInverted = true;
- break;
- case '(':
- scaleSection = true;
- break;
- case '!':
- parsedToken.isReverse = true;
- break;
- case ' ':
- case '\t':
- break;
- default:
- parsedToken.name += token[i];
- }
- }
- }
- void ControlsIniParser::ParseAliases(Controls& ctrls, const array<string>& values)
- {
- char sep;
- string seps(",+"), token;
- TokenOperation temp;
- array<TokenOperation> tokens(__FILE__, __LINE__);
- for (unsigned int i = 0; i < values.Size(); ++i)
- {
- tokens.DelAll();
- unsigned int pos = 0;
- while ( true )
- {
- token = GetToken(values[i], pos, seps, &sep);
- pos += token.Len() + 1;
- token.Trim();
- if (!token.Len())
- break;
- temp.token = token;
- temp.addNext = sep == '+';
- tokens.Add(temp);
- }
- if (tokens.Size() < 2) // алиас как минимум 1:1
- {
- api->Trace("Invalid alias format: \"%s\"\n", values[i].GetBuffer());
- continue;
- }
- Token parsedToken;
- array<Token> parsedTokens(__FILE__, __LINE__);
- for (unsigned int i = 0; i < tokens.Size(); ++i)
- {
- ParseToken(tokens[i].token, parsedToken);
- parsedToken.addNext = tokens[i].addNext;
- parsedTokens.Add(parsedToken);
- }
- ctrls.AddAlias(parsedTokens);
- }
- }
- void ControlsIniParser::ParseControls(Controls& ctrls, const array<string>& values)
- {
- long curGroupIndex = -1;
- char sep;
- string seps(",+"), token;
- TokenOperation temp;
- array<TokenOperation> tokens(__FILE__, __LINE__);
- for (unsigned int i = 0; i < values.Size(); ++i)
- {
- tokens.DelAll();
- unsigned int pos = 0;
- while ( true )
- {
- token = GetToken(values[i], pos, seps, &sep);
- pos += token.Len() + 1;
- token.Trim();
- if (!token.Len())
- break;
- temp.token = token;
- temp.addNext = sep == '+';
- tokens.Add(temp);
- }
- if (tokens.Size() < 2) // алиас как минимум 1:1
- {
- api->Trace("Invalid control format: \"%s\"\n", values[i].GetBuffer());
- continue;
- }
- if (tokens[0].token != "group")
- {
- Token parsedToken;
- array<Token> parsedTokens(__FILE__, __LINE__);
- for (unsigned int i = 0; i < tokens.Size(); ++i)
- {
- ParseToken(tokens[i].token, parsedToken);
- parsedToken.addNext = tokens[i].addNext;
- parsedTokens.Add(parsedToken);
- }
- ctrls.AddControl(curGroupIndex, parsedTokens);
- }
- else
- curGroupIndex = ctrls.AddGroup(tokens[1].token);
- }
- }
- void ControlsIniParser::Parse(Controls& ctrls)
- {
- IFileService* fileService = (IFileService*)api->GetService("FileService");
- Assert(fileService);
- array<IIniFile*> iniFiles(__FILE__, __LINE__);
- IIniFile* iniFile = fileService->OpenIniFile("resource\\ini\\controls.ini", _FL_);
- if (iniFile) iniFiles.Add(iniFile);
- IFinder* finder = fileService->CreateFinder("resource\\ini\\controls\\", "*.ini",
- find_all_files_no_mirrors | find_no_recursive, _FL_);
- for(dword i = 0; i < finder->Count(); i++ )
- {
- iniFile = fileService->OpenIniFile(finder->FilePath(i), _FL_);
- if (iniFile) iniFiles.Add(iniFile);
- // api->Trace(" LOADING: %s",finder->FilePath(i));
- }
- finder->Release();
- /* finder = fileService->CreateFinder("resource\\ini\\controls\\profiles\\", "*.ini", find_all_files_no_mirrors, _FL_);
- for(dword i = 0; i < finder->Count(); i++ )
- {
- iniFile = fileService->OpenIniFile(finder->FilePath(i), _FL_);
- if (iniFile) iniFiles.Add(iniFile);
- }
- finder->Release();*/
- /* IIniFile* profiles = fileService->OpenIniFile("resource\\ini\\controls\\profiles\\profiles.ini",_FL_);
- if( profiles )
- {
- char key[16];
- for( int i = 0 ; i < 10 ; i++ )
- {
- sprintf_s(key,16,"active%d",i);
- // const char *s = profiles->GetString("profiles","active");
- const char *s = profiles->GetString("profiles",key);
- if( s[0] )
- {
- string name = "resource\\ini\\controls\\profiles\\";
- name += s;
- name += ".ini";
- iniFile = fileService->OpenIniFile(name,_FL_);
- if( iniFile )
- {
- iniFiles.Add(iniFile); ctrls.SetCurrentProfile(s,i);
- // api->Trace("CONTROLS: Profile '%s' was loaded.",name);
- }
- }
- else
- break;
- }
- profiles->Release();
- }*/
- //
- for (unsigned int i = 0; i < iniFiles.Size(); ++i)
- {
- array<string> controls(__FILE__, __LINE__);
- array<string> aliases(__FILE__, __LINE__);
-
- iniFiles[i]->GetStrings("aliases", "assign", aliases);
- iniFiles[i]->GetStrings("controls", "assign", controls);
- ParseAliases(ctrls, aliases);
- ParseControls(ctrls, controls);
- }
- for(unsigned int i = 0; i < iniFiles.Size(); ++i)
- iniFiles[i]->Release();
- }
- const ControlsIniParser::Table& ControlsIniParser::GetMappingTable( const char* mappingTable) const
- {
- for (unsigned int i = 0; i < m_mappingTables.Size(); ++i)
- if ( m_mappingTables[i].tableName == mappingTable )
- return m_mappingTables[i];
- if (mappingTable != "Default")
- return GetMappingTable("Default");
- Assert(!"Bad joystick mapping ini-file! (no default mapping)");
- return *(const Table*)NULL;
- }
- void ControlsIniParser::ClearMappings()
- {
- m_mappingTables.DelAll();
- }
- void ControlsIniParser::MakeMapping(const array<string>& strings, Table& mappings)
- {
- string seps(",");
- for (unsigned int i = 0; i < strings.Size(); ++i)
- {
- unsigned int pos = 0;
- Table::Item item;
- item.logName = GetToken(strings[i], pos, seps, NULL);
- pos += item.logName.Len() + 1;
- item.hwName = GetToken(strings[i], pos, seps, NULL);
- item.logName.Trim();
- item.hwName.Trim();
- mappings.items.Add(item);
- }
- }
- void ControlsIniParser::ParseJoystickMappings()
- {
- IFileService* fileService = (IFileService*)api->GetService("FileService");
- Assert(fileService);
- IIniFile* iniFile = fileService->OpenIniFile("resource\\ini\\controls.ini", _FL_);
- if(!iniFile) return;
-
- for (unsigned int k = 0; k < m_mappingTables.Size(); ++k)
- {
- array<string> mappingStrings(__FILE__, __LINE__);
- iniFile->GetStrings(m_mappingTables[k].tableName, "assign", mappingStrings);
- MakeMapping(mappingStrings, m_mappingTables[k]);
- }
- iniFile->Release();
- }
|