CConfigHandler.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. //#define BOOST_SPIRIT_DEBUG
  2. #include "CConfigHandler.h"
  3. #include <boost/bind.hpp>
  4. #include <boost/function.hpp>
  5. #include <boost/spirit.hpp>
  6. #include <fstream>
  7. using namespace config;
  8. using namespace boost::spirit;
  9. using namespace phoenix;
  10. CConfigHandler conf;
  11. GUIOptions *current = NULL;
  12. std::pair<int,int> curRes;
  13. ButtonInfo *currentButton;
  14. int gnb=-1;
  15. struct lerror
  16. {
  17. std::string txt;
  18. lerror(const std::string & TXT):txt(TXT){};
  19. void operator()() const
  20. {
  21. tlog1 << txt << std::endl;
  22. }
  23. template<typename IteratorT>
  24. void operator()(IteratorT t1, IteratorT t2) const
  25. {
  26. tlog1 << txt << std::endl;
  27. }
  28. };
  29. struct SetCurButton
  30. {
  31. template<typename IteratorT>
  32. void operator()(IteratorT t1, IteratorT t2) const
  33. {
  34. std::string str(t1,t2);
  35. if(str=="KingdomOv")
  36. currentButton = &current->ac.kingOverview;
  37. else if(str=="Underground")
  38. currentButton = &current->ac.underground;
  39. else if(str=="QuestLog")
  40. currentButton = &current->ac.questlog;
  41. else if(str=="SleepWake")
  42. currentButton = &current->ac.sleepWake;
  43. else if(str=="MoveHero")
  44. currentButton = &current->ac.moveHero;
  45. else if(str=="Spellbook")
  46. currentButton = &current->ac.spellbook;
  47. else if(str=="AdvOptions")
  48. currentButton = &current->ac.advOptions;
  49. else if(str=="SysOptions")
  50. currentButton = &current->ac.sysOptions;
  51. else if(str=="NextHero")
  52. currentButton = &current->ac.nextHero;
  53. else if(str=="EndTurn")
  54. currentButton = &current->ac.endTurn;
  55. }
  56. };
  57. struct lerror2
  58. {
  59. std::string txt;
  60. lerror2(const std::string & TXT):txt(TXT){};
  61. template<typename IteratorT>
  62. void operator()(IteratorT t1, IteratorT t2) const
  63. {
  64. std::string txt2(t1,t2);
  65. tlog1 << txt << txt2 << std::endl;
  66. }
  67. };
  68. struct dummy
  69. {
  70. boost::function<void()> func;
  71. dummy(const boost::function<void()> & F)
  72. :func(F){}
  73. template<typename IteratorT>
  74. void operator()(IteratorT t1, IteratorT t2) const
  75. {
  76. func();
  77. }
  78. };
  79. template<typename T>struct SetButtonProp
  80. {
  81. T point;
  82. SetButtonProp(T p)
  83. :point(p){}
  84. template <typename Z>
  85. void operator()(const Z & val) const
  86. {
  87. currentButton->*point = val;
  88. }
  89. };
  90. template<typename T> SetButtonProp<T> SetButtonProp_a(T p)
  91. {
  92. return SetButtonProp<T>(p);
  93. }
  94. struct SetButtonStr
  95. {
  96. std::string ButtonInfo::*point;
  97. SetButtonStr(std::string ButtonInfo::* p)
  98. :point(p){}
  99. template <typename Z>
  100. void operator()(const Z first, const Z last) const
  101. {
  102. std::string str(first,last);
  103. currentButton->*point = str;
  104. }
  105. };
  106. template<typename T>struct SetAdventureProp
  107. {
  108. T point;
  109. SetAdventureProp(T p)
  110. :point(p){}
  111. template <typename Z>
  112. void operator()(const Z & val) const
  113. {
  114. current->ac.*point = val;
  115. }
  116. };
  117. template<typename T> SetAdventureProp<T> SetAdventureProp_a(T p)
  118. {
  119. return SetAdventureProp<T>(p);
  120. }
  121. struct SetAdventureStr
  122. {
  123. std::string AdventureMapConfig::*point;
  124. SetAdventureStr(std::string AdventureMapConfig::* p)
  125. :point(p){}
  126. template <typename Z>
  127. void operator()(const Z first, const Z last) const
  128. {
  129. std::string str(first,last);
  130. current->ac.*point = str;
  131. }
  132. };
  133. struct AddDefForButton
  134. {
  135. template <typename Z>
  136. void operator()(const Z first, const Z last) const
  137. {
  138. std::string str(first,last);
  139. currentButton->additionalDefs.push_back(str);
  140. }
  141. };
  142. void addGRes()
  143. {
  144. if(current)
  145. conf.guiOptions[curRes] = *current; //we'll use by default settings from previous resolution
  146. current = &conf.guiOptions[curRes];
  147. }
  148. void setGem(int x, int val)
  149. {
  150. if(x)
  151. current->ac.gemX[gnb] = val;
  152. else
  153. current->ac.gemY[gnb] = val;
  154. }
  155. struct AddGemName
  156. {
  157. template <typename Z>
  158. void operator()(const Z first, const Z last) const
  159. {
  160. current->ac.gemG.push_back(std::string(first,last));
  161. }
  162. };
  163. struct SettingsGrammar : public grammar<SettingsGrammar>
  164. {
  165. template <typename ScannerT>
  166. struct definition
  167. {
  168. rule<ScannerT> r, clientOption, clientOptionsSequence, ClientSettings;
  169. rule<ScannerT> GUISettings, GUIOption, GUIOptionsSequence, AdvMapOptionsSequence, AdvMapOption;
  170. rule<ScannerT> GUIResolution, fname;
  171. definition(SettingsGrammar const& self)
  172. {
  173. fname = lexeme_d[+(alnum_p | '.')];
  174. clientOption
  175. = str_p("resolution=") >> (uint_p[assign_a(conf.cc.resx)] >> 'x' >> uint_p[assign_a(conf.cc.resy)] | eps_p[lerror("Wrong resolution!")])
  176. | str_p("port=") >> (uint_p[assign_a(conf.cc.port)] | eps_p[lerror("Wrong port!")])
  177. | str_p("bpp=") >> (uint_p[assign_a(conf.cc.bpp)] | eps_p[lerror("Wrong bpp!")])
  178. | str_p("localInformation=") >> (uint_p[assign_a(conf.cc.localInformation)] | eps_p[lerror("Wrong localInformation!")])
  179. | str_p("fullscreen=") >> (uint_p[assign_a(conf.cc.fullscreen)] | eps_p[lerror("Wrong fullscreen!")])
  180. | str_p("server=") >> ( ( +digit_p >> *('.' >> +digit_p) )[assign_a(conf.cc.server)] | eps_p[lerror("Wrong server!")])
  181. | str_p("defaultAI=") >> ((+(anychar_p - ';'))[assign_a(conf.cc.defaultAI)] | eps_p[lerror("Wrong defaultAI!")])
  182. | (+(anychar_p - '}'))[lerror2("Unrecognized client option: ")]
  183. ;
  184. clientOptionsSequence = *(clientOption >> (';' | eps_p[lerror("Semicolon lacking after client option!")]));
  185. ClientSettings = '{' >> clientOptionsSequence >> '}';
  186. AdvMapOption
  187. = str_p("Buttons") >> ((ch_p('{') >> '}') | eps_p[lerror("Wrong Buttons!")])
  188. | str_p("Minimap: ") >>
  189. *(
  190. "width=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::minimapW)]//[assign_a(current->ac.minimapW)]
  191. | "height=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::minimapH)]
  192. | "x=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::minimapX)]
  193. | "y=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::minimapY)]
  194. )
  195. | str_p("Statusbar:") >>
  196. *(
  197. ( "x=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::statusbarX)]
  198. | "y=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::statusbarY)]
  199. | "graphic=" >> fname[SetAdventureStr(&AdventureMapConfig::statusbarG)]
  200. )
  201. )
  202. | str_p("ResDataBar:") >>
  203. *(
  204. ( "x=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::resdatabarX)]
  205. | "y=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::resdatabarY)]
  206. | "offsetX=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::resOffsetX)]
  207. | "offsetY=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::resOffsetY)]
  208. | "resSpace=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::resDist)]
  209. | "resDateSpace=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::resDateDist)]
  210. | "graphic=" >> fname[SetAdventureStr(&AdventureMapConfig::resdatabarG)]
  211. )
  212. )
  213. | str_p("InfoBox:") >>
  214. *(
  215. ( "x=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::infoboxX)]
  216. | "y=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::infoboxY)]
  217. )
  218. )
  219. | str_p("AdvMap:") >>
  220. *(
  221. ( "x=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::advmapX)]
  222. | "y=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::advmapY)]
  223. | "trimX=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::advmapTrimX)]
  224. | "trimY=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::advmapTrimY)]
  225. | "tilesWidth=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::tilesW)]
  226. | "tilesHeight=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::tilesH)]
  227. )
  228. )
  229. | str_p("background=") >> fname[SetAdventureStr(&AdventureMapConfig::mainGraphic)]
  230. | str_p("Button") >> (+(anychar_p-':'))[SetCurButton()] >> ':' >>
  231. *(
  232. ( "x=" >> uint_p[SetButtonProp_a(&ButtonInfo::x)]
  233. | "y=" >> uint_p[SetButtonProp_a(&ButtonInfo::y)]
  234. | "playerColoured=" >> uint_p[SetButtonProp_a(&ButtonInfo::playerColoured)]
  235. | "graphic=" >> fname[SetButtonStr(&ButtonInfo::defName)]
  236. | "additionalDefs=" >> ch_p('(') >> fname[AddDefForButton()]
  237. >> *(',' >> fname[AddDefForButton()]) >> ')'
  238. )
  239. )
  240. | str_p("HeroList:") >>
  241. *(
  242. ( "x=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::hlistX)]
  243. | "y=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::hlistY)]
  244. | "size=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::hlistSize)]
  245. | "movePoints=" >> fname[SetAdventureStr(&AdventureMapConfig::hlistMB)]
  246. | "manaPoints=" >> fname[SetAdventureStr(&AdventureMapConfig::hlistMN)]
  247. | "arrowUp=" >> fname[SetAdventureStr(&AdventureMapConfig::hlistAU)]
  248. | "arrowDown=" >> fname[SetAdventureStr(&AdventureMapConfig::hlistAD)]
  249. )
  250. )
  251. | str_p("TownList:") >>
  252. *(
  253. ( "x=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::tlistX)]
  254. | "y=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::tlistY)]
  255. | "size=" >> uint_p[SetAdventureProp_a(&AdventureMapConfig::tlistSize)]
  256. | "arrowUp=" >> fname[SetAdventureStr(&AdventureMapConfig::tlistAU)]
  257. | "arrowDown=" >> fname[SetAdventureStr(&AdventureMapConfig::tlistAD)]
  258. )
  259. )
  260. | str_p("gem") >> uint_p[var(gnb) = arg1] >> ':' >>
  261. *(
  262. ( "x=" >> uint_p[bind(&setGem,1,_1)]
  263. | "y=" >> uint_p[bind(&setGem,0,_1)]
  264. | "graphic=" >> fname[AddGemName()]
  265. )
  266. )
  267. ;
  268. AdvMapOptionsSequence = *(AdvMapOption >> (';' | eps_p[lerror("Semicolon lacking in advmapopt!")]));
  269. GUIResolution = (uint_p[assign_a(curRes.first)] >> 'x' >> uint_p[assign_a(curRes.second)])
  270. [dummy(&addGRes)];
  271. GUIOption = str_p("AdventureMap") >> ('{' >> AdvMapOptionsSequence >> '}' | eps_p[lerror("Wrong AdventureMap!")]);
  272. GUIOptionsSequence = *(GUIOption >> (';' | eps_p[lerror("Semicolon after GUIOption lacking!")]));
  273. GUISettings = +(GUIResolution >> '{' >> GUIOptionsSequence >> '}');
  274. r
  275. = str_p("clientSettings") >> (ClientSettings | eps_p[lerror("Wrong clientSettings!")])
  276. >> str_p("GUISettings") >> ('{' >> GUISettings >> '}' | eps_p[lerror("Wrong GUISettings!")]);
  277. #ifdef BOOST_SPIRIT_DEBUG
  278. BOOST_SPIRIT_DEBUG_RULE(clientOption);
  279. BOOST_SPIRIT_DEBUG_RULE(clientOptionsSequence);
  280. BOOST_SPIRIT_DEBUG_RULE(ClientSettings);
  281. BOOST_SPIRIT_DEBUG_RULE(AdvMapOption);
  282. BOOST_SPIRIT_DEBUG_RULE(AdvMapOptionsSequence);
  283. BOOST_SPIRIT_DEBUG_RULE(GUIOption);
  284. BOOST_SPIRIT_DEBUG_RULE(GUIOptionsSequence);
  285. BOOST_SPIRIT_DEBUG_RULE(GUISettings);
  286. BOOST_SPIRIT_DEBUG_RULE(GUIResolution);
  287. BOOST_SPIRIT_DEBUG_RULE(r);
  288. #endif
  289. }
  290. rule<ScannerT> const& start() const { return r; }
  291. };
  292. };
  293. struct CommentsGrammar : public grammar<CommentsGrammar>
  294. {
  295. template <typename ScannerT>
  296. struct definition
  297. {
  298. rule<ScannerT> comment;
  299. definition(CommentsGrammar const& self)
  300. {
  301. comment = comment_p("//") | comment_p("/*","*/") | space_p;
  302. BOOST_SPIRIT_DEBUG_RULE(comment);
  303. }
  304. rule<ScannerT> const& start() const { return comment; }
  305. };
  306. };
  307. CConfigHandler::CConfigHandler(void)
  308. {
  309. }
  310. CConfigHandler::~CConfigHandler(void)
  311. {
  312. }
  313. void config::CConfigHandler::init()
  314. {
  315. std::vector<char> settings;
  316. std::ifstream ifs("config/settings.txt");
  317. if(!ifs)
  318. {
  319. tlog1 << "Cannot open config/settings.txt !\n";
  320. return;
  321. }
  322. ifs.unsetf(std::ios::skipws); // Turn of white space skipping on the stream
  323. std::copy(std::istream_iterator<char>(ifs),std::istream_iterator<char>(),std::back_inserter(settings));
  324. std::vector<char>::const_iterator first = settings.begin(), last = settings.end();
  325. SettingsGrammar sg;
  326. BOOST_SPIRIT_DEBUG_NODE(sg);
  327. CommentsGrammar cg;
  328. BOOST_SPIRIT_DEBUG_NODE(cg);
  329. parse_info<std::vector<char>::const_iterator> info = parse(first,last,sg,cg);
  330. if(!info.hit)
  331. tlog1 << "Cannot parse config/settings.txt file!\n";
  332. else if(!info.full)
  333. tlog2 << "Not entire config/settings.txt parsed!\n";
  334. }
  335. GUIOptions * config::CConfigHandler::go()
  336. {
  337. return &guiOptions[std::pair<int,int>(cc.resx,cc.resy)];
  338. }