ControlsManager.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  1. #include "ControlsManager.h"
  2. /*
  3. static char _key[] = "Profile.Controls.active1";
  4. static long _key_index = 23;
  5. */
  6. static const char *not_binded = "[[]";
  7. ControlsManager:: ControlsManager() :
  8. items (_FL_),
  9. profiles(_FL_)
  10. {
  11. }
  12. ControlsManager::~ControlsManager()
  13. {
  14. }
  15. bool ControlsManager::Create (MOPReader &reader)
  16. {
  17. InitParams(reader);
  18. Show(true);
  19. return true;
  20. }
  21. bool ControlsManager::EditMode_Update(MOPReader &reader)
  22. {
  23. InitParams(reader);
  24. return true;
  25. }
  26. void ControlsManager::Show(bool isShow)
  27. {
  28. MissionObject::Show(isShow);
  29. if( isShow )
  30. SetUpdate(&ControlsManager::Draw,ML_ALPHA5);
  31. else
  32. DelUpdate(&ControlsManager::Draw);
  33. }
  34. void ControlsManager::Update()
  35. {
  36. if( !profile )
  37. {
  38. LogicDebugError("Can't update profile: no active profile.");
  39. return;
  40. }
  41. Profile &prof = profiles[curProfile];
  42. if( prof.stat )
  43. {
  44. LogicDebugError("Can't update profile: profile %s is static.",profile);
  45. return;
  46. }
  47. /* string name = "resource\\ini\\controls\\profiles\\";
  48. name += profile;
  49. name += ".ini";
  50. #ifndef _XBOX
  51. char path[MAX_PATH];
  52. GetCurrentDirectory(MAX_PATH,path);
  53. crt_strcat(path,MAX_PATH,"\\");
  54. crt_strcat(path,MAX_PATH,name);
  55. // api->Trace(path);
  56. SetFileAttributes(path,FILE_ATTRIBUTE_NORMAL);
  57. #endif
  58. IEditableIniFile *file = Files().OpenEditableIniFile(name,file_create_always,_FL_);
  59. const char *section = "aliases";
  60. if( file )
  61. file->AddSection(section);
  62. int index = 0;
  63. const array<long> &ctls = prof.ctls;
  64. // for( int i = 0 ; i < items ; i++ )
  65. for( int i = 0 ; i < ctls ; i++ )
  66. {
  67. long k = ctls[i];
  68. if( k >= items )
  69. {
  70. LogicDebugError("Invalid control index %d in profile %s.",k,profile);
  71. continue;
  72. }
  73. // Item &item = items[i];
  74. Item &item = items[k];
  75. if( Controls().UpdateAlias(item.alias,item.name))
  76. {
  77. static char buf[100];
  78. if( file )
  79. {
  80. if( item.name && item.name[0] == '[' )
  81. sprintf_s(buf,100,"%s, %s",item.alias,item.name + 1);
  82. else
  83. sprintf_s(buf,100,"%s, %s",item.alias,item.name);
  84. file->SetString(section,"assign",buf,index++);
  85. }
  86. }
  87. }
  88. if( file )
  89. file->Release();*/
  90. static char buf[128];
  91. crt_snprintf(buf,128,"Game.Controls.single.%s",profile);
  92. ICoreStorageFolder *folder = api->Storage().GetItemFolder(buf,_FL_);
  93. const array<long> &ctls = prof.ctls;
  94. // for( int i = 0 ; i < items ; i++ )
  95. for( int i = 0 ; i < ctls ; i++ )
  96. {
  97. long k = ctls[i];
  98. if( k >= items )
  99. {
  100. LogicDebugError("Invalid control index %d in profile %s.",k,profile);
  101. continue;
  102. }
  103. // Item &item = items[i];
  104. Item &item = items[k];
  105. if( Controls().UpdateAlias(item.alias.c_str(),item.name))
  106. {
  107. if( item.name && item.name[0] == '[' )
  108. folder->SetString(item.alias.c_str(),item.name + 1);
  109. else
  110. folder->SetString(item.alias.c_str(),item.name);
  111. }
  112. }
  113. folder->Release();
  114. }
  115. void ControlsManager::Activate(bool isActive)
  116. {
  117. MissionObject::Activate(isActive);
  118. //
  119. }
  120. void _cdecl ControlsManager::Draw(float dltTime, long level)
  121. {
  122. if( !updated )
  123. {
  124. SetProfile(profile,number); updated = true;
  125. }
  126. if( curItem < 0 )
  127. {
  128. if( Controls().Locked() && m_locked && !Controls().GetActiveControl(null))
  129. Controls().Unlock();
  130. }
  131. else
  132. {
  133. if( IsActive() && !EditMode_IsOn())
  134. {
  135. Item &item = items[curItem];
  136. // if( Controls().GetReleasedControl(null))
  137. // Controls().Lock();
  138. const char *name = Controls().GetPressedControl(item.alias.c_str());
  139. if( m_locked && Controls().LockCount() < 2 && name &&
  140. !string::IsEqual(name,"MouseDeltaH") &&
  141. !string::IsEqual(name,"MouseDeltaV") &&
  142. !string::IsEqual(name,"MouseLDouble"))
  143. {
  144. Assert(profile)
  145. Profile &prof = profiles[curProfile];
  146. // long index = -1;
  147. for( int i = 0 ; i < prof.ctls ; i++ )
  148. {
  149. long n = prof.ctls[i];
  150. if( n >= 0 && n < items )
  151. {
  152. if( n != curItem )
  153. {
  154. const char *alias = Controls().UpdateAlias(items[n].alias.c_str(),null);
  155. if( alias && string::IsEqual(alias,name))
  156. {
  157. // index = n;
  158. Item &prev = items[n];
  159. const char *s = not_binded;
  160. Controls().UpdateAlias(prev.alias.c_str(),s + 1);
  161. MOSafePointer p;
  162. if( FindObject(ConstString(prev.value),p))
  163. {
  164. p.Ptr()->Command("SetString",1,&s);
  165. }
  166. else
  167. LogicDebugError("Object %s not found.",prev.value.c_str());
  168. prev.name = s;
  169. }
  170. }
  171. }
  172. else
  173. {
  174. LogicDebugError(
  175. "Profile %s: control[%d] has invalid value (%d).",profile,i,n);
  176. }
  177. }
  178. /* if( index >= 0 )
  179. {
  180. // пытаемся прибиндить уже используемый контрол
  181. // ;
  182. // return;
  183. Item &prev = items[index];
  184. const char *s = not_binded;
  185. Controls().UpdateAlias(prev.alias,s + 1);
  186. MissionObject *p = (MissionObject *)FindObject(prev.value);
  187. if( p )
  188. {
  189. p->Command("SetString",1,&s);
  190. }
  191. else
  192. LogicDebugError("Object %s not found.",prev.value.c_str());
  193. prev.name = s;
  194. }*/
  195. // else
  196. {
  197. newTrigger.Activate(Mission(),false);
  198. LogicDebug("Set alias: %s = %s.",item.alias.c_str(),name);
  199. const char *tt = Controls().UpdateAlias(item.alias.c_str(),name);
  200. // api->Trace(" GET: %s = %s, %s",item.alias,name,tt);
  201. MOSafePointer p;
  202. if( FindObject(ConstString(item.value),p))
  203. {
  204. static char buf[100];
  205. // sprintf_s(buf,100,"[%s] %s",name,name);
  206. sprintf_s(buf,100,"[%s]",name);
  207. const char *s = buf;
  208. p.Ptr()->Command("SetString",1,&s);
  209. }
  210. else
  211. LogicDebugError("Object %s not found.",item.value.c_str());
  212. item.name = name;
  213. curItem = -1;
  214. }
  215. }
  216. else
  217. {
  218. MOSafePointer p;
  219. if( FindObject(ConstString(item.value),p))
  220. {
  221. curTime += dltTime;
  222. if( curTime > 1.0f )
  223. curTime = curTime - 1.0f;
  224. const char *s = curTime < 0.5f ? "" : " _";
  225. p.Ptr()->Command("SetString",1,&s);
  226. }
  227. }
  228. }
  229. }
  230. }
  231. void ControlsManager::SetProfile(const char *name, int index, bool reset)
  232. {
  233. if( name )
  234. {
  235. const Profile &prof = profiles[curProfile];
  236. if( Controls().LoadProfile(prof.player,prof.single,index,name,reset))
  237. profile = name;
  238. else
  239. profile = null;
  240. }
  241. else
  242. profile = null;
  243. /* _key[_key_index] = '0' + index;
  244. if( profile )
  245. {
  246. GameState().SetString(_key,profile ? profile : "");
  247. api->Trace("SETSTATE: %s = %s",_key,profile ? profile : "[none]");
  248. }*/
  249. // api->Trace("\n MANAGER: set profile %s.\n",name);
  250. for( int i = 0 ; i < items ; i++ )
  251. {
  252. Item &item = items[i];
  253. MOSafePointer p;
  254. if( FindObject(ConstString(item.value),p))
  255. {
  256. const char *name = profile ? Controls().UpdateAlias(item.alias.c_str(),null) : null;
  257. if( name && name[0] == '_' )
  258. {
  259. name = not_binded;
  260. p.Ptr()->Command("SetString",1,&name);
  261. }
  262. else
  263. {
  264. static char buf[100];
  265. // sprintf_s(buf,100,name ? "[%s] %s" : " _ERROR_",name,name);
  266. sprintf_s(buf,100,name ? "[%s]" : " _ERROR_",name);
  267. const char *s = buf;
  268. p.Ptr()->Command("SetString",1,&s);
  269. // api->Trace(" %s = %s",item.value,name);
  270. }
  271. item.name = name;
  272. }
  273. }
  274. MOSafePointer p;
  275. if( FindObject(ConstString(title),p))
  276. {
  277. if( name )
  278. {
  279. const char *s = profiles[curProfile].title;
  280. p.Ptr()->Command("SetString",1,&s);
  281. }
  282. }
  283. }
  284. void ControlsManager::Command(const char *id, dword numParams, const char **params)
  285. {
  286. if( string::IsEmpty(id))
  287. return;
  288. if( string::IsEqual(id,"select"))
  289. {
  290. // long index = numParams ? atol(params[0]) : 0;
  291. if( numParams < 3 )
  292. {
  293. LogicDebugError("Command <select> error. Not enought parameters.");
  294. return;
  295. }
  296. long player = atol(params[0]);
  297. bool single = atol(params[1]) == 0;
  298. long index = atol(params[2]);
  299. /* _key[_key_index] = '0' + (char)index;
  300. const char *name = GameState().GetString(_key,"");
  301. api->Trace("GETSTATE: %s = %s",_key,name[0] ? name : "[none]");*/
  302. const char *curr = Controls().CurrentProfile(player,single,index);
  303. for( int i = 0 ; i < profiles ; i++ )
  304. {
  305. Profile &prof = profiles[i];
  306. // if( Controls().CurrentProfile() == prof.name )
  307. // if( string::IsEqual(name,prof.name))
  308. if( prof.player == player &&
  309. prof.single == single &&
  310. prof.index == index && string::IsEqual(curr,prof.name))
  311. {
  312. curProfile = i;
  313. prof.onSelect.Activate(Mission(),false);
  314. // profile = profiles[curProfile].name;
  315. // number = profiles[curProfile].index;
  316. // api->Trace("PROFILE: %s",profiles[curProfile].name);
  317. return;
  318. }
  319. }
  320. defTrigger.Activate(Mission(),false);
  321. }
  322. else
  323. if( string::IsEqual(id,"set"))
  324. {
  325. if( numParams < 1 )
  326. {
  327. LogicDebugError("Command <set> error. Not enought parameters.");
  328. return;
  329. }
  330. if( !params[0] )
  331. {
  332. LogicDebugError("Command <set> error. Index not specified.");
  333. }
  334. long index = atol(params[0]);
  335. if( index < profiles && profiles[index].name[0] )
  336. {
  337. curProfile = index;
  338. profile = profiles[curProfile].name;
  339. number = profiles[curProfile].index;
  340. SetProfile(profile,number);
  341. LogicDebug(
  342. "Command <set>. Setting profile %s as active.",profile);
  343. }
  344. else
  345. {
  346. LogicDebugError(
  347. "Command <set> error. Index value %i is not in range [0, %i].",
  348. index,profiles.Size() - 1);
  349. return;
  350. }
  351. }
  352. else
  353. if( string::IsEqual(id,"set_default"))
  354. {
  355. if( numParams < 3 )
  356. {
  357. LogicDebugError("Command <set_default> error. Not enought parameters.");
  358. return;
  359. }
  360. long player = atol(params[0]);
  361. bool single = atol(params[1]) == 0;
  362. long index = atol(params[2]);
  363. const char *name = Controls().CurrentProfile(player,single,index);
  364. if( Controls().LoadProfile(player,single,index,name))
  365. {
  366. LogicDebug(
  367. "Command <set_default>. Loading profile %s to group [%d].",name,index);
  368. }
  369. else
  370. {
  371. LogicDebugError(
  372. "Command <set_default> error. No default profile in group [%d].",index);
  373. }
  374. }
  375. else
  376. if( string::IsEqual(id,"dec"))
  377. {
  378. if( curProfile >= 0 )
  379. {
  380. if( curProfile )
  381. {
  382. curProfile--;
  383. profile = profiles[curProfile].name;
  384. number = profiles[curProfile].index;
  385. SetProfile(profile,number);
  386. LogicDebug(
  387. "Command <dec>. Setting profile %s as active.",profile);
  388. }
  389. }
  390. }
  391. else
  392. if( string::IsEqual(id,"inc"))
  393. {
  394. if( curProfile >= 0 )
  395. {
  396. if( curProfile < profiles - 1 )
  397. {
  398. curProfile++;
  399. profile = profiles[curProfile].name;
  400. number = profiles[curProfile].index;
  401. SetProfile(profile,number);
  402. LogicDebug(
  403. "Command <inc>. Setting profile %s as active.",profile);
  404. }
  405. }
  406. }
  407. else
  408. if( string::IsEqual(id,"get"))
  409. {
  410. if( numParams < 1 )
  411. {
  412. LogicDebugError("Command <get> error. Not enought parameters.");
  413. return;
  414. }
  415. if( !params[0] )
  416. {
  417. LogicDebugError("Command <get> error. Index not specified.");
  418. }
  419. long index = atol(params[0]);
  420. if( index < items )
  421. {
  422. if( curItem < 0 )
  423. {
  424. if( profile && !profiles[curProfile].stat )
  425. {
  426. Controls().Lock(); m_locked = true;
  427. curItem = index;
  428. LogicDebug(
  429. "Command <get>. Setting %s to %s.",
  430. items[index].alias.c_str(),"###");
  431. }
  432. }
  433. else
  434. LogicDebugError(
  435. "Command <get> error. Is alrady in waiting state.");
  436. }
  437. else
  438. {
  439. LogicDebugError(
  440. "Command <get> error. Index value %i is not in range [0, %i].",
  441. index,items.Size() - 1);
  442. return;
  443. }
  444. }
  445. else
  446. if( string::IsEqual(id,"update"))
  447. {
  448. if( profile )
  449. {
  450. Update();
  451. LogicDebug("Command <update>. Profile %s update complete.",profile);
  452. }
  453. else
  454. LogicDebugError("Command <update> error. No active profile.");
  455. }
  456. else
  457. if( string::IsEqual(id,"cancel"))
  458. {
  459. if( curProfile >= 0 && curProfile < profiles && profiles[curProfile].name[0] )
  460. {
  461. profile = profiles[curProfile].name;
  462. number = profiles[curProfile].index;
  463. SetProfile(profile,number);
  464. LogicDebug(
  465. "Command <cancel>. Profile %s is restored to previous settings.",profile);
  466. }
  467. else
  468. LogicDebugError("Command <cancel> error. No active profile.");
  469. }
  470. else
  471. if( string::IsEqual(id,"default"))
  472. {
  473. if( curProfile >= 0 && curProfile < profiles && profiles[curProfile].name[0] )
  474. {
  475. profile = profiles[curProfile].name;
  476. number = profiles[curProfile].index;
  477. SetProfile(profile,number,true);
  478. LogicDebug(
  479. "Command <default>. Profile %s is reseted to default settings.",profile);
  480. }
  481. else
  482. LogicDebugError("Command <default> error. No active profile.");
  483. }
  484. else
  485. {
  486. LogicDebugError("Unknown command \"%s\".",id);
  487. }
  488. }
  489. void __declspec(dllexport) ControlsManager::InitParams(MOPReader &reader)
  490. {
  491. items.DelAll();
  492. int n = reader.Array();
  493. for( int i = 0 ; i < n ; i++ )
  494. {
  495. Item &item = items[items.Add()];
  496. item.alias = reader.String();
  497. item.value = reader.String();
  498. }
  499. profiles.DelAll();
  500. n = reader.Array();
  501. for( int i = 0 ; i < n ; i++ )
  502. {
  503. Profile &prof = profiles[profiles.Add()];
  504. prof.player = reader.Long();
  505. prof.single = reader.Bool();
  506. prof.index = reader.Long();
  507. prof.name = reader.String().c_str();
  508. prof.title = reader.String().c_str();
  509. prof.stat = reader.Bool();
  510. int k = reader.Array();
  511. for( int j = 0 ; j < k ; j++ )
  512. {
  513. prof.ctls.Add(reader.Long());
  514. }
  515. prof.onSelect.Init(reader);
  516. }
  517. defTrigger.Init(reader);
  518. newTrigger.Init(reader);
  519. title = reader.String().c_str();
  520. curProfile = reader.Long();
  521. if( curProfile >= 0 && curProfile < profiles && profiles[curProfile].name[0] )
  522. {
  523. profile = profiles[curProfile].name;
  524. number = profiles[curProfile].index;
  525. }
  526. else
  527. {
  528. profile = null;
  529. number = 0;
  530. }
  531. Activate(reader.Bool());
  532. curItem = -1;
  533. curTime = 0.0f;
  534. updated = false;
  535. m_locked = false;
  536. // SetProfile(profile);
  537. }
  538. static char desc[] =
  539. "ControlsManager\n\n"
  540. " Use to setup character controller\n\n"
  541. "Commands:\n\n"
  542. " select - select default profile\n\n"
  543. " param[0] - player index\n"
  544. " param[1] - single/second (0/1)\n"
  545. " param[2] - group index\n\n"
  546. " set - set current profile\n\n"
  547. " param[0] - profile index\n\n"
  548. " set_default - select default profile (inner init only)\n\n"
  549. " param[0] - player index\n"
  550. " param[1] - single/second (0/1)\n"
  551. " param[2] - group index\n\n"
  552. " get - get control value\n\n"
  553. " param[0] - control index\n\n"
  554. " update - save changes to current profile\n\n"
  555. " cancel - cancel last changes\n\n"
  556. " defaut - load default settings";
  557. MOP_BEGINLISTCG(ControlsManager, "ControlsManager", '1.00', 2000, desc, "Interface")
  558. MOP_ARRAYBEG("Controls", 0, 100)
  559. MOP_STRING("Alias", "")
  560. MOP_STRING("Value", "")
  561. MOP_ARRAYEND
  562. MOP_ARRAYBEG("Profiles", 0, 100)
  563. MOP_LONGEX("Player", 0, 0, 10)
  564. MOP_BOOL ("Single", true)
  565. MOP_LONGEX("Index", 0, 0, 100)
  566. MOP_STRING("Name" , "")
  567. MOP_STRING("Title", "")
  568. MOP_BOOL("Static", true)
  569. MOP_ARRAYBEG("Controls", 0, 100)
  570. MOP_LONGEX("Index", 0, 0, 100)
  571. MOP_ARRAYEND
  572. MOP_MISSIONTRIGGER("OnSelect")
  573. MOP_ARRAYEND
  574. MOP_MISSIONTRIGGER("Default")
  575. MOP_MISSIONTRIGGER("Defined")
  576. MOP_STRING("Title widget", "")
  577. MOP_LONG("Start profile", 0)
  578. MOP_BOOL("Active", false)
  579. MOP_ENDLIST(ControlsManager)