pc.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. #pragma once
  2. #ifndef _XBOX
  3. #define DIRECTINPUT_VERSION 0x0800
  4. #include <dinput.h>
  5. #endif
  6. #include "..\..\common_h\controls.h"
  7. #include "ControlsIniParser.h"
  8. #include "Force.h"
  9. #define MAX_FILTERNAME 40
  10. // структура для хранения разобранного с модификаторами контрола
  11. struct Token
  12. {
  13. string name; //
  14. bool isInverted; //
  15. bool isReverse; //
  16. float scale; //
  17. bool addNext; // == true если следующий токен идет через "+"; == false если через ","
  18. };
  19. class Controls;
  20. // прослойка фильтрации raw-значений в соответствии с модификаторами
  21. class ControlFilter
  22. {
  23. struct ChainItem
  24. {
  25. long filter;
  26. float scale; // ограничитель максимального выдаваемого значения
  27. bool isInverted; // флаг инвертирования значения (value *= -1.0f)
  28. bool isSumNext;
  29. };
  30. //string m_name; // имя фильтра (используется для создания альясов)
  31. char m_fname[MAX_FILTERNAME]; // имя фильтра (используется для создания альясов)
  32. bool m_isMouseVorH;
  33. bool m_isMouseDeltaVorH;
  34. bool m_isInverted; // флаг инвертирования значения (value *= -1.0f)
  35. float m_scale; // ограничитель максимального выдаваемого значения
  36. long m_deviceIndex; // индекс девайса (-1 если неиспольуется)
  37. long m_controlIndex; // индекс контрола с которого брать raw значение (-1 если неиспольуется)
  38. array<ChainItem> m_Items;
  39. float m_curr; // последнее считанное значение
  40. float m_prev; // предыдущее считанное значение
  41. int frameUpdated;
  42. protected:
  43. Controls * m_ctrl;
  44. void SetName(const char * name);
  45. public:
  46. ControlFilter(Controls *ctrl, const char *name, float scale, bool isInverted);
  47. ControlFilter(Controls *ctrl = null);
  48. bool operator ==(const ControlFilter &other) const;
  49. bool operator !=(const ControlFilter &other) const
  50. {
  51. return !(*this == other);
  52. }
  53. const ControlFilter &operator =(const ControlFilter &);
  54. const char * GetName() const { return m_fname; }
  55. float GetValue(); // получить значение фильтра
  56. float GetValueLast(); // получить значение фильтра с предыдущего кадра
  57. void SetFilterParams(const char *name, float scale, bool isInverted)
  58. {
  59. SetName(name);
  60. //m_name = name;
  61. m_scale = scale;
  62. m_isInverted = isInverted;
  63. }
  64. void SetFilterParams(float scale, bool isInverted)
  65. {
  66. m_scale = scale;
  67. m_isInverted = isInverted;
  68. }
  69. void SetDataSource(long device, long control)
  70. {
  71. m_deviceIndex = device;
  72. m_controlIndex = control;
  73. }
  74. void AddItem(long index, bool isInverted, float scale, bool isSum)
  75. {
  76. ChainItem item;
  77. item.filter = index;
  78. item.isInverted = isInverted;
  79. item.scale = scale;
  80. item.isSumNext = isSum;
  81. m_Items.Add(item);
  82. }
  83. dword GetItemsCount() const
  84. {
  85. return m_Items.Size();
  86. }
  87. void SetItemSumFlag(dword index, bool isSumNext)
  88. {
  89. if( index < m_Items.Size())
  90. m_Items[index].isSumNext = isSumNext;
  91. }
  92. public:
  93. friend class Controls;
  94. long m_last;
  95. ImagePlace m_place;
  96. ImagePlace m_place_inv;
  97. };
  98. // прослойка логических контролов (выдаются через IControls)
  99. class GameControl : public ControlFilter
  100. {
  101. friend class Controls;
  102. private:
  103. int m_curFrame; // frame на котором обновлялся контрол
  104. ControlStateType m_stateType; // состояние контрола
  105. float m_fValue; // значение с плавающей точкой
  106. bool m_isReverse;
  107. bool m_isUpdated; // был ли обновлен на текущем кадре
  108. bool m_enabled; // включен/выключен
  109. bool m_locked;
  110. public:
  111. void Lock()
  112. {
  113. ControlStateType st = GetState();
  114. if( st == CST_ACTIVE ||
  115. st == CST_ACTIVATED )
  116. {
  117. m_locked = true;
  118. }
  119. }
  120. GameControl(Controls *ctrl, const string &name, bool isReverse);
  121. GameControl();
  122. ControlStateType GetState()
  123. {
  124. if( !IsUpdated())
  125. Update();
  126. return m_stateType;
  127. }
  128. float GetValue()
  129. {
  130. if( !IsUpdated())
  131. Update();
  132. return m_fValue;
  133. }
  134. void Update();
  135. __inline void ResetUpdated()
  136. {
  137. m_isUpdated = false;
  138. }
  139. __inline bool IsUpdated() const;
  140. __inline void Enable(bool enable)
  141. {
  142. m_enabled = enable;
  143. }
  144. };
  145. struct Item;
  146. class IDevice;
  147. class JoystickManager;
  148. class IRenderTarget;
  149. //////////////////////////////////
  150. // Controls service
  151. //////////////////////////////////
  152. class ControlsInstance;
  153. class Controls : public IControlsService
  154. {
  155. struct FakeForce
  156. {
  157. array<Vector> ls;
  158. array<Vector> rs;
  159. FakeForce() :
  160. ls(_FL_),
  161. rs(_FL_)
  162. {
  163. }
  164. };
  165. struct InstanceInfo
  166. {
  167. bool used;
  168. ControlsInstance *p;
  169. const char *file;
  170. long line;
  171. };
  172. struct ControlGroup
  173. {
  174. ControlGroup() : inds(_FL_)
  175. {
  176. }
  177. string name; // имя группы
  178. bool used; // используется
  179. array<long> inds; // индексы GameControl'ов
  180. };
  181. #ifndef _XBOX
  182. IDirectInput8 *m_DI; // DirectInput - только на PC
  183. friend BOOL __stdcall DeviceEnumer(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef);
  184. friend BOOL __stdcall JoystickEnumer(LPCDIDEVICEINSTANCEA lpddi, LPVOID pvRef);
  185. HWND m_h; // хендл главного окна
  186. POINT m_cursorPos; // позиция курсора перед захватом мыши
  187. #endif
  188. // группы контролов
  189. array<ControlGroup> m_groups;
  190. HashTable<long,128,64> m_tableGroups;
  191. // логические контролов с таблицей индексов для быстрого доступа
  192. mutable array<GameControl> m_gameControls;
  193. mutable HashTable<long,256,128> m_tableControls;
  194. // фильтры-модификаторы-альясы с таблицей индексов для быстрого доступа
  195. array<ControlFilter> m_controlFilters;
  196. HashTable<long,256,128> m_tableFilters;
  197. // девайсы
  198. array<IDevice*> m_devices;
  199. JoystickManager *m_joyMrg; // менеджер джойстиков
  200. array<KeyDescr> m_Keys; // буфер клавиш
  201. bool m_lockMouse; // лочить ли виндовый мышиный курсор
  202. ControlsIniParser m_iniParser;
  203. bool m_freeMouse; // разлочить на время текущего кадра
  204. bool m_showCursor; // состояние системного курсора
  205. bool m_clipCursor;
  206. bool m_prev_act; // предыдущее состояние активности
  207. bool m_preserve; // не трогать системный курсор
  208. int m_curFrame;
  209. ////////////////////////////
  210. ICoreStorageFloat *m_vibrate; // разрешить вибрацию джойпада
  211. bool m_forceVibrate; // форсировать вибрацию (в редакторе)
  212. struct Patcher
  213. {
  214. struct Group
  215. {
  216. struct Control
  217. {
  218. const char *name;
  219. int index;
  220. float val; // оригинальное значение
  221. Control()
  222. {
  223. }
  224. Control(const char *alias)
  225. {
  226. name = alias;
  227. }
  228. };
  229. array<Control> controls;
  230. const char *name;
  231. ICoreStorageFloat *p;
  232. bool isFlag; // признак переключателя
  233. Group()
  234. : controls(_FL_)
  235. {
  236. }
  237. Group(const char *variable, bool flag = false)
  238. : controls(_FL_)
  239. {
  240. name = variable; isFlag = flag;
  241. }
  242. };
  243. array<Group> groups;
  244. Patcher()
  245. : groups(_FL_)
  246. {
  247. }
  248. void Init (Controls *service);
  249. void Update(Controls *service);
  250. void Release();
  251. };
  252. Patcher m_patcher; // модификция контролов "на лету"
  253. ///////////////////////////
  254. virtual bool Init(); // инициализация
  255. void BuildFilterChain(ControlFilter &aliasFilter, const array<Token> &tokens);
  256. array<Force> forces; // действующие силы
  257. Force *GetFreeForce();
  258. void ApplyForces(float dltTime);
  259. IRenderTarget *target; // текстура для отрисовки контролов
  260. int m_version; // номер обновления текстуры
  261. IBaseTexture *images; // загруженный текстурный атлас
  262. int m_locked; // признак блокировки
  263. bool m_debug;
  264. array<InstanceInfo> m_inst;
  265. array<ForceData> m_forceList;
  266. FakeForce m_forceData; ForceData m_fakeData;
  267. htable<int> m_forceHash;
  268. string m_tempName;
  269. long m_mouseH;
  270. long m_mouseV;
  271. string m_profile; // путь к файлу дефолтных профилей
  272. long CreateGameControl(const char* name, bool isReverse);
  273. long CreateControlFilter(const char* name, float scale, bool isReverse);
  274. long CreateControlGroup(const char* name);
  275. public:
  276. void ReleaseForces(IControls *instance)
  277. {
  278. for( int i = 0 ; i < forces ; i++ )
  279. {
  280. Force &force = forces[i];
  281. if( force.busy )
  282. {
  283. if( force.instance == instance )
  284. {
  285. force.time = FORCE_STOP;
  286. force.instance = null;
  287. force.busy = false;
  288. }
  289. }
  290. }
  291. }
  292. void Reset()
  293. {
  294. for( int i = 0 ; i < m_gameControls ; i++ )
  295. {
  296. if( i != m_mouseH && i != m_mouseV )
  297. m_gameControls[i].Lock();
  298. }
  299. }
  300. Controls();
  301. virtual ~Controls();
  302. // вывод локализованной ошибки в лог
  303. void Error(long id, const char *errorEnglish);
  304. void CreateForceData();
  305. void ReadIni();
  306. void SetCurrentProfile(long player, bool single, long group, const char *name);
  307. void BuildImages();
  308. __inline int GetCurFrame() { return m_curFrame; }
  309. void AddAlias(const array<Token> &tokens);
  310. void AddControl(long group, const array<Token> &tokens);
  311. long AddGroup(const char *name);
  312. long AddFilter(const ControlFilter &filter);
  313. __inline ControlFilter &GetFilter (long index) { return m_controlFilters[index]; }
  314. __inline GameControl &GetControl(long index) { return m_gameControls[index]; }
  315. long GetFilterNode(long index, bool &inverted);
  316. bool HandleFilter(int i, array<Item> &map);
  317. long FindFilterByName(const char *name);
  318. float GetDeviceValue(long deviceIndex, long controlIndex) const;
  319. //////////////////////////////////////////////////////////////////////////
  320. // Service
  321. //////////////////////////////////////////////////////////////////////////
  322. //Исполнение в начале кадра
  323. virtual void StartFrame(float dltTime);
  324. //Исполнение в конце кадра
  325. virtual void EndFrame (float dltTime);
  326. //////////////////////////////////////////////////////////////////////////
  327. // IControls
  328. //////////////////////////////////////////////////////////////////////////
  329. //---------------------------------------------------------------------------
  330. // Работа с изображениями контролов
  331. //---------------------------------------------------------------------------
  332. // получить общую текстуру с изображениями контролов
  333. virtual IBaseTexture *GetControlsImage();
  334. virtual int GetControlsImageVersion();
  335. // получить координаты изображения контрола в общей текстуре
  336. virtual ImagePlace GetControlImagePlace(const char *control_name);
  337. //---------------------------------------------------------------------------
  338. // Управление контролами
  339. //---------------------------------------------------------------------------
  340. // найти контрол по его имени
  341. virtual long FindControlByName(const char *control_name) const;
  342. virtual long FindGroupByName (const char *group_name);
  343. //---------------------------------------------------------------------------
  344. // управление группами контролов
  345. //---------------------------------------------------------------------------
  346. // включить/выключить группу контролов
  347. virtual void EnableControlGroup(long group_num, bool bEnable = true);
  348. virtual void EnableControlGroup(const char *group_name, bool bEnable = true);
  349. //---------------------------------------------------------------------------
  350. // Опрос и управление состоянием контролов
  351. //---------------------------------------------------------------------------
  352. // получить состояние активности контрола
  353. virtual ControlStateType GetControlStateType(long control_code) /*const*/;
  354. virtual ControlStateType GetControlStateType(const char *control_name) /*const*/;
  355. // получить значение контрола в формате с плавающей точкой
  356. virtual float GetControlStateFloat(long control_code) /*const*/;
  357. virtual float GetControlStateFloat(const char* control_name) /*const*/;
  358. // получить значение контрола в формате bool
  359. virtual bool GetControlStateBool(long control_code) /*const*/;
  360. virtual bool GetControlStateBool(const char* control_name) /*const*/;
  361. // разрешить/запретить обработку контролов
  362. virtual void Lock();
  363. virtual void Unlock();
  364. // получить состояние болкировки
  365. virtual bool Locked();
  366. virtual long LockCount();
  367. // получить алиас активного контрола
  368. virtual const char *GetPressedControl(const char *alias_name);
  369. virtual const char *GetActiveControl(const char *alias_name);
  370. virtual const char *GetReleasedControl(const char *alias_name);
  371. // обновить значение алиаса
  372. virtual const char *UpdateAlias(const char *alias_name, const char *name, bool buildImages = true);
  373. // загрузить профайл
  374. virtual bool LoadProfile(
  375. long player, bool single, long group, const char *name, bool reset = false, bool buildImages = true);
  376. // получить имя текущего профайла
  377. virtual const char *CurrentProfile(long player, bool single, long group);
  378. //----------------------------------------------------------------------------
  379. // Использование возможности Force feedback
  380. //----------------------------------------------------------------------------
  381. // получить интерфейс
  382. virtual IForce *CreateForce(const IControls *instance, const char *profile,
  383. bool autoDelete = true, long deviceIndex = 0);
  384. virtual IForce *CreateForce(array<Vector> &ls, array<Vector> &rs,
  385. bool autoDelete = true, long deviceIndex = 0);
  386. // получить количество групп
  387. virtual long GetControlGroupsQuantity() const;
  388. // выполнить системно-зависимую команду
  389. virtual void ExecuteCommand(InputSrvCommand &cmd);
  390. // работа с буфером клавиш
  391. void AddKey(const KeyDescr &desc);
  392. virtual unsigned int GetKeyBufferLength() const;
  393. virtual const KeyDescr *GetKeyBuffer() const;
  394. virtual void ClearKeyBuffer();
  395. // разлочить мышь на один кадр
  396. virtual void FreeMouse();
  397. //----------------------------------------------------------------------------
  398. // ControlsService
  399. //----------------------------------------------------------------------------
  400. // создать экземпляр
  401. virtual IControls *CreateInstance(const char *file, long line);
  402. ////
  403. void RegInstance(ControlsInstance *p, const char *file, long line);
  404. void DelInstance(ControlsInstance *p);
  405. };
  406. /////////////////////////////////////////
  407. // Controls instance
  408. /////////////////////////////////////////
  409. class ControlsInstance : public IControls
  410. {
  411. Controls *m_base;
  412. bool m_active; bool IsActive() const { return m_active; }
  413. public:
  414. ControlsInstance(Controls *base, const char *file, long line)
  415. {
  416. m_base = base;
  417. Assert(m_base)
  418. m_active = true;
  419. m_base->RegInstance(this,file,line);
  420. }
  421. //////////////////////////////////////////////////////////////////////////
  422. // IControls
  423. //////////////////////////////////////////////////////////////////////////
  424. //---------------------------------------------------------------------------
  425. // Работа с изображениями контролов
  426. //---------------------------------------------------------------------------
  427. // получить общую текстуру с изображениями контролов
  428. virtual IBaseTexture *GetControlsImage()
  429. { return m_base->GetControlsImage(); }
  430. virtual int GetControlsImageVersion()
  431. { return m_base->GetControlsImageVersion(); }
  432. // получить координаты изображения контрола в общей текстуре
  433. virtual ImagePlace GetControlImagePlace(const char *control_name)
  434. { return m_base->GetControlImagePlace(control_name); }
  435. //---------------------------------------------------------------------------
  436. // Управление контролами
  437. //---------------------------------------------------------------------------
  438. // найти контрол по его имени
  439. virtual long FindControlByName(const char *control_name) const
  440. { return m_base->FindControlByName(control_name); }
  441. virtual long FindGroupByName (const char *group_name) const
  442. { return m_base->FindGroupByName (group_name); }
  443. //---------------------------------------------------------------------------
  444. // управление группами контролов
  445. //---------------------------------------------------------------------------
  446. // включить/выключить группу контролов
  447. virtual void EnableControlGroup(long group_num, bool bEnable = true)
  448. { m_base->EnableControlGroup(group_num,bEnable); }
  449. virtual void EnableControlGroup(const char *group_name, bool bEnable = true)
  450. { m_base->EnableControlGroup(group_name,bEnable); }
  451. //---------------------------------------------------------------------------
  452. // Опрос и управление состоянием контролов
  453. //---------------------------------------------------------------------------
  454. // получить состояние активности контрола
  455. virtual ControlStateType GetControlStateType(long control_code) /*const*/
  456. { return IsActive() ? m_base->GetControlStateType(control_code) : CST_INACTIVE; }
  457. virtual ControlStateType GetControlStateType(const char *control_name) /*const*/
  458. { return IsActive() ? m_base->GetControlStateType(control_name) : CST_INACTIVE; }
  459. // получить значение контрола в формате с плавающей точкой
  460. virtual float GetControlStateFloat(long control_code) /*const*/
  461. { return IsActive() ? m_base->GetControlStateFloat(control_code) : 0.0f; }
  462. virtual float GetControlStateFloat(const char* control_name) /*const*/
  463. { return IsActive() ? m_base->GetControlStateFloat(control_name) : 0.0f; }
  464. // получить значение контрола в формате bool
  465. virtual bool GetControlStateBool(long control_code) /*const*/
  466. { return IsActive() ? m_base->GetControlStateBool(control_code) : false; }
  467. virtual bool GetControlStateBool(const char* control_name) /*const*/
  468. { return IsActive() ? m_base->GetControlStateBool(control_name) : false; }
  469. // разрешить/запретить обработку контролов
  470. virtual void Lock()
  471. { m_base->Lock(); }
  472. virtual void Unlock()
  473. { m_base->Unlock(); }
  474. // получить состояние болкировки
  475. virtual bool Locked()
  476. { return m_base->Locked(); }
  477. virtual long LockCount()
  478. { return m_base->LockCount(); }
  479. // получить алиас активного контрола
  480. virtual const char *GetPressedControl(const char *alias_name)
  481. { return m_base->GetPressedControl(alias_name); }
  482. virtual const char *GetActiveControl(const char *alias_name)
  483. { return m_base->GetActiveControl(alias_name); }
  484. virtual const char *GetReleasedControl(const char *alias_name)
  485. { return m_base->GetReleasedControl(alias_name); }
  486. // обновить значение алиаса
  487. virtual const char *UpdateAlias(const char *alias_name, const char *name, bool buildImages = true)
  488. { return m_base->UpdateAlias(alias_name,name,buildImages); }
  489. // загрузить профайл
  490. virtual bool LoadProfile(
  491. long player, bool single, long group, const char *name, bool reset = false, bool buildImages = true)
  492. { return m_base->LoadProfile(player,single,group,name,reset,buildImages); }
  493. // получить имя текущего профайла
  494. virtual const char *CurrentProfile(long player, bool single, long group)
  495. { return m_base->CurrentProfile(player,single,group); }
  496. //----------------------------------------------------------------------------
  497. // Использование возможности Force feedback
  498. //----------------------------------------------------------------------------
  499. // получить интерфейс
  500. virtual IForce *CreateForce(const char *profile,
  501. bool autoDelete = true, long deviceIndex = 0)
  502. { return m_base->CreateForce(this,profile,autoDelete,deviceIndex); }
  503. virtual IForce *CreateForce(array<Vector> &ls, array<Vector> &rs,
  504. bool autoDelete = true, long deviceIndex = 0)
  505. { return m_base->CreateForce(ls,rs,autoDelete,deviceIndex); }
  506. // получить количество групп
  507. virtual long GetControlGroupsQuantity() const
  508. { return m_base->GetControlGroupsQuantity(); }
  509. // выполнить системно-зависимую команду
  510. virtual void ExecuteCommand(InputSrvCommand &cmd)
  511. { m_base->ExecuteCommand(cmd); }
  512. // работа с буфером клавиш
  513. virtual unsigned int GetKeyBufferLength() const
  514. { return m_base->GetKeyBufferLength(); }
  515. virtual const KeyDescr *GetKeyBuffer() const
  516. { return m_base->GetKeyBuffer(); }
  517. virtual void ClearKeyBuffer()
  518. { m_base->ClearKeyBuffer(); }
  519. // разлочить мышь на один кадр
  520. virtual void FreeMouse()
  521. { m_base->FreeMouse(); }
  522. //----------------------------------------------------------------------------
  523. // ControlInstance
  524. //----------------------------------------------------------------------------
  525. // изменить состояние активности
  526. virtual void Activate(bool isActive = true)
  527. {
  528. m_active = isActive;
  529. m_base->Reset();
  530. }
  531. virtual bool IsInactive() const
  532. {
  533. return IsActive() == false;
  534. }
  535. // удалить
  536. virtual void Release()
  537. {
  538. m_base->ReleaseForces(this);
  539. m_base->DelInstance(this);
  540. delete this;
  541. }
  542. };