pc.cpp 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893
  1. #include "pc.h"
  2. #include "..\..\common_h\systemmsg.h"
  3. #include "XBoxDevice.h"
  4. #include "..\..\common_h\InputSrvCmds.h"
  5. #include "XBoxKeyboard.h"
  6. const unsigned int XBoxGamepadCount = 4;
  7. CREATE_SERVICE_NAMED("ControlsService", Controls, 25)
  8. #ifndef _XBOX
  9. #pragma comment (lib, "dinput8.lib")
  10. #pragma comment (lib, "dxguid.lib")
  11. #include <XInput.h>
  12. #pragma comment(lib, "Xinput.lib")
  13. #include "MouseDevice.h"
  14. #include "KeyboardDevice.h"
  15. #include "JoystickDevice.h"
  16. #include <delayimp.h>
  17. #include <cmath>
  18. #else // _XBOX
  19. #include <xtl.h>
  20. #endif // _XBOX
  21. #include "JoystickManager.h"
  22. #include "utils.h"
  23. #include "..\..\common_h\FileService.h"
  24. #include "..\..\common_h\Render.h"
  25. #include "..\..\common_h\LocStrings.h"
  26. #include "..\..\common_h\data_swizzle.h"
  27. static IFileService *storage;
  28. static IRender *render;
  29. //////////////////////////////////////////////////////////////////////////
  30. // ControlFilter
  31. //////////////////////////////////////////////////////////////////////////
  32. dword mmmax = 0;
  33. const ConstString MouseV("MouseV");
  34. const ConstString MouseH("MouseH");
  35. const ConstString MouseDeltaH("MouseDeltaH");
  36. const ConstString MouseDeltaV("MouseDeltaV");
  37. const ConstString MouseLDouble("mouseldouble");
  38. const ConstString MouseRDouble("mouserdouble");
  39. ControlFilter::ControlFilter(Controls *ctrl, const char *name, float scale, bool isInverted) : m_Items(_FL_)
  40. {
  41. m_ctrl = ctrl;
  42. SetName(name);
  43. //m_name = name;
  44. //mmmax = Max(m_name.Len(), mmmax);
  45. m_scale = scale;
  46. m_isInverted = isInverted;
  47. m_deviceIndex = INVALID_CODE;
  48. m_controlIndex = INVALID_CODE;
  49. m_prev = 0.0f;
  50. m_curr = 0.0f;
  51. m_last = -1;
  52. }
  53. ControlFilter::ControlFilter(Controls *ctrl) : m_Items(_FL_)
  54. {
  55. m_ctrl = ctrl;
  56. m_scale = 1.0f;
  57. m_isInverted = false;
  58. m_deviceIndex = INVALID_CODE;
  59. m_controlIndex = INVALID_CODE;
  60. m_prev = 0.0f;
  61. m_curr = 0.0f;
  62. m_last = -1;
  63. }
  64. void ControlFilter::SetName(const char * name)
  65. {
  66. crt_strcpy(m_fname, sizeof(m_fname), name);
  67. m_isMouseVorH = string::IsEqual(m_fname, "MouseV") || string::IsEqual(m_fname, "MouseH");
  68. m_isMouseDeltaVorH = string::IsEqual(m_fname, "MouseDeltaV") || string::IsEqual(m_fname, "MouseDeltaH");
  69. }
  70. bool ControlFilter::operator ==(const ControlFilter &other) const
  71. {
  72. return (string::IsEqual(m_fname, other.m_fname));
  73. }
  74. const ControlFilter &ControlFilter::operator =(const ControlFilter &other)
  75. {
  76. m_ctrl = other.m_ctrl;
  77. SetName(other.m_fname);
  78. //m_name = other.m_name;
  79. //mmmax = Max(m_name.Len(), mmmax);
  80. m_isInverted = other.m_isInverted;
  81. m_scale = other.m_scale;
  82. m_deviceIndex = other.m_deviceIndex;
  83. m_controlIndex = other.m_controlIndex;
  84. m_Items = other.m_Items;
  85. return *this;
  86. }
  87. float ControlFilter::GetValue()
  88. {
  89. Assert(m_ctrl);
  90. bool isUpdated = frameUpdated == m_ctrl->GetCurFrame();
  91. if( !isUpdated )
  92. m_prev = m_curr;
  93. float value = 0.0f;
  94. if( m_deviceIndex != INVALID_CODE &&
  95. m_controlIndex != INVALID_CODE )
  96. {
  97. value = m_ctrl->GetDeviceValue(m_deviceIndex, m_controlIndex);
  98. value *= m_scale;
  99. if( m_isInverted )
  100. value *= -1.0f;
  101. m_last = -1;
  102. if (!isUpdated)
  103. m_curr = value;
  104. frameUpdated = m_ctrl->GetCurFrame();
  105. return value;
  106. }
  107. bool addNext = false;
  108. for( dword i = 0; i < m_Items.Size() ; i++ )
  109. {
  110. ControlFilter &f = m_ctrl->GetFilter(m_Items[i].filter);
  111. float next_value = 0.0f;
  112. if( string::IsEqual(m_fname, f.m_fname) && !m_isMouseVorH)
  113. {
  114. api->Trace("CONTROLS: alias '%s' is looped!!!",m_fname);
  115. }
  116. else
  117. {
  118. next_value = f.GetValue();
  119. }
  120. if( m_Items[i].isInverted )
  121. next_value *= -1.0f;
  122. next_value *= m_Items[i].scale;
  123. if( addNext )
  124. {
  125. value *= next_value;
  126. }
  127. else
  128. {
  129. value = next_value;
  130. }
  131. addNext = m_Items[i].isSumNext;
  132. if( fabs(value) > 0.0222f && !addNext )
  133. {
  134. m_last = i; break;
  135. }
  136. }
  137. value *= m_scale;
  138. if( m_isInverted )
  139. value *= -1;
  140. if (!isUpdated)
  141. m_curr = value;
  142. frameUpdated = m_ctrl->GetCurFrame();
  143. return value;
  144. }
  145. float ControlFilter::GetValueLast()
  146. {
  147. Assert(m_ctrl);
  148. float value = 0.0f;
  149. if( m_deviceIndex != INVALID_CODE &&
  150. m_controlIndex != INVALID_CODE )
  151. {
  152. value = (frameUpdated == m_ctrl->GetCurFrame()) ? m_prev : m_curr;
  153. return value;
  154. }
  155. bool addNext = false;
  156. for( dword i = 0; i < m_Items.Size() ; i++ )
  157. {
  158. #ifdef _XBOX
  159. // оптимизация на прекеширование следующего фильтра из списка
  160. if (i+1 < m_Items.Size())
  161. {
  162. ControlFilter & nextFilter = m_ctrl->GetFilter(m_Items[i].filter);
  163. __dcbt(0, &nextFilter);
  164. }
  165. #endif
  166. ControlFilter &f = m_ctrl->GetFilter(m_Items[i].filter);
  167. float next_value = 0.0f;
  168. if( string::IsEqual(m_fname, f.m_fname) && !m_isMouseVorH)
  169. {
  170. api->Trace("CONTROLS: alias '%s' is looped!!!", m_fname);
  171. }
  172. else
  173. {
  174. next_value = f.GetValueLast();
  175. }
  176. if( m_Items[i].isInverted )
  177. next_value *= -1.0f;
  178. next_value *= m_Items[i].scale;
  179. if( addNext )
  180. {
  181. value *= next_value;
  182. }
  183. else
  184. {
  185. value = next_value;
  186. }
  187. addNext = m_Items[i].isSumNext;
  188. if( fabs(value) > 0.0222f && !addNext )
  189. {
  190. break;
  191. }
  192. }
  193. value *= m_scale;
  194. if( m_isInverted )
  195. value *= -1;
  196. return value;
  197. }
  198. //////////////////////////////////////////////////////////////////////////
  199. // GameControl
  200. //////////////////////////////////////////////////////////////////////////
  201. GameControl::GameControl(Controls* ctrl, const string & name, bool isReverse) :
  202. ControlFilter(ctrl,name,1.0f,false)
  203. {
  204. m_isReverse = isReverse;
  205. m_stateType = CST_INACTIVE;
  206. m_fValue = 0.0f;
  207. //m_isUpdated = false;
  208. m_enabled = true;
  209. m_locked = false;
  210. m_curFrame = -1;
  211. }
  212. GameControl::GameControl() :
  213. ControlFilter(NULL)
  214. {
  215. m_isReverse = false;
  216. m_stateType = CST_INACTIVE;
  217. m_fValue = 0.0f;
  218. //m_isUpdated = false;
  219. m_enabled = true;
  220. m_locked = false;
  221. m_curFrame = -1;
  222. }
  223. __inline bool GameControl::IsUpdated() const
  224. {
  225. return (m_curFrame == m_ctrl->GetCurFrame());
  226. }
  227. void GameControl::Update()
  228. {
  229. //m_isUpdated = true;
  230. m_curFrame = m_ctrl->GetCurFrame();
  231. if( !m_enabled )
  232. {
  233. m_fValue = 0.0f;
  234. m_stateType = CST_INACTIVE;
  235. return;
  236. }
  237. float oldValue = ControlFilter::GetValueLast();
  238. float newValue = ControlFilter::GetValue();
  239. const float thr = 0.6f; // порог срабатывания
  240. bool oldBoolState = oldValue > thr;
  241. bool newBoolState = newValue > thr;
  242. if( m_locked )
  243. {
  244. if( !newBoolState )
  245. m_locked = false;
  246. newValue = 0.0f;
  247. m_stateType = CST_INACTIVE;
  248. }
  249. else
  250. {
  251. if( newBoolState && oldBoolState )
  252. m_stateType = m_isReverse ? CST_INACTIVE : CST_ACTIVE;
  253. if( !newBoolState && oldBoolState )
  254. m_stateType = m_isReverse ? CST_ACTIVATED : CST_INACTIVATED;
  255. if( newBoolState && !oldBoolState )
  256. m_stateType = m_isReverse ? CST_INACTIVATED : CST_ACTIVATED;
  257. if( !newBoolState && !oldBoolState )
  258. m_stateType = m_isReverse ? CST_ACTIVE : CST_INACTIVE;
  259. }
  260. m_fValue = newValue;
  261. }
  262. //////////////////////////////////////////////////////////////////////////
  263. // Controls
  264. //////////////////////////////////////////////////////////////////////////
  265. const int forces_count = 32;
  266. // получить свободную силу мз пула
  267. Force *Controls::GetFreeForce()
  268. {
  269. // профайл не джойстик - тогда ничего не даем. джойстику незачем вибрировать
  270. const char* pcCurProfileName = api->Storage().GetString("game.controls.single.land");
  271. if( !pcCurProfileName || (pcCurProfileName[0]!='j' && pcCurProfileName[0]!='J') )
  272. return null;
  273. for( int i = 0 ; i < forces ; i++ )
  274. if( !forces[i].busy )
  275. return &forces[i];
  276. if( forces < forces_count )
  277. return &forces[forces.Add()];
  278. return null;
  279. }
  280. Controls::Controls() : forces(_FL_,forces_count),
  281. #ifndef _XBOX
  282. m_DI(NULL),
  283. #endif
  284. m_groups (_FL_, 16),
  285. m_devices (_FL_),
  286. m_gameControls (_FL_, 224),
  287. m_tableControls (_FL_),
  288. m_controlFilters(_FL_, 512),
  289. m_tableFilters (_FL_),
  290. m_Keys (_FL_),
  291. m_forceList (_FL_, 48),
  292. m_forceHash (_FL_),
  293. m_inst (_FL_),
  294. m_tableGroups (_FL_)
  295. {
  296. m_curFrame = 0;
  297. m_lockMouse = false;
  298. m_freeMouse = false;
  299. m_showCursor = true;
  300. m_clipCursor = false;
  301. m_prev_act = false;
  302. m_preserve = false;
  303. m_joyMrg = null;
  304. target = null;
  305. m_version = 0;
  306. images = null;
  307. m_locked = 0;
  308. m_debug = false;
  309. m_vibrate = null;
  310. m_forceVibrate = false;
  311. }
  312. Controls::~Controls()
  313. {
  314. if( m_joyMrg )
  315. {
  316. // стопорим все моторы
  317. for( long i = 0 ; i < 4 ; i++ )
  318. {
  319. float sp[] = {0.0f,0.0f};
  320. m_joyMrg->SetJoystickValues(IJoystick::FFRotorSpeed,sp,2*sizeof(float),i);
  321. }
  322. }
  323. for( int i = 0; i < m_devices ; i++ )
  324. {
  325. delete m_devices[i];
  326. m_devices[i] = null;
  327. }
  328. for( int i = 0 ; i < m_forceList ; i++ )
  329. {
  330. m_forceList[i].Release();
  331. }
  332. m_devices.DelAll();
  333. #ifndef _XBOX
  334. if( m_DI )
  335. {
  336. m_DI->Release();
  337. m_DI = null;
  338. }
  339. ClipCursor(null);
  340. #endif
  341. RELEASE(target)
  342. RELEASE(images)
  343. bool empty = true;
  344. bool first = true;
  345. api->Trace("\n=============================");
  346. api->Trace("\nControls service shutdown start");
  347. for( int i = 0 ; i < m_inst ; i++ )
  348. {
  349. InstanceInfo &info = m_inst[i];
  350. if( info.used )
  351. {
  352. if( first )
  353. {
  354. api->Trace("");
  355. first = false;
  356. empty = false;
  357. }
  358. api->Trace(" Unreleased instance: %s [%d]",info.file,info.line);
  359. }
  360. }
  361. if( !empty )
  362. api->Trace("");
  363. api->Trace("Controls service shutdown end");
  364. api->Trace("\n=============================\n");
  365. RELEASE(m_vibrate)
  366. m_patcher.Release();
  367. }
  368. #ifndef _XBOX
  369. BOOL __stdcall DeviceEnumer(LPCDIDEVICEINSTANCEA lpddi, LPVOID pvRef)
  370. {
  371. Controls *ctrls = (Controls *)pvRef;
  372. if(((lpddi->dwDevType & 0xFF) == DI8DEVTYPE_MOUSE))
  373. ctrls->m_devices.Add(
  374. NEW MouseDevice(ctrls->m_DI,*lpddi));
  375. if(((lpddi->dwDevType & 0xFF) == DI8DEVTYPE_KEYBOARD))
  376. ctrls->m_devices.Add(
  377. NEW KeyboardDevice(*ctrls,ctrls->m_DI,*lpddi));
  378. if(((lpddi->dwDevType & 0xFF) == DI8DEVTYPE_JOYSTICK ||
  379. (lpddi->dwDevType & 0xFF) == DI8DEVTYPE_GAMEPAD) && !IsXInputDevice(&lpddi->guidProduct))
  380. ctrls->m_joyMrg->AddJoystick(
  381. NEW JoystickDevice(ctrls->m_DI,*lpddi,ctrls->m_iniParser));
  382. return DIENUM_CONTINUE;
  383. }
  384. BOOL __stdcall JoystickEnumer(LPCDIDEVICEINSTANCEA lpddi, LPVOID pvRef)
  385. {
  386. Controls *ctrls = (Controls *)pvRef;
  387. if( !IsXInputDevice(&lpddi->guidProduct))
  388. ctrls->m_iniParser.AddJoystickMappingTable(lpddi->tszProductName);
  389. return DIENUM_CONTINUE;
  390. }
  391. static LONG WINAPI DelayLoadDllExceptionFilter(PEXCEPTION_POINTERS pep, int &error)
  392. {
  393. // If this is a Delay-load problem, ExceptionInformation[0] points
  394. // to a DelayLoadInfo structure that has detailed error info
  395. PDelayLoadInfo pdli = PDelayLoadInfo(pep->ExceptionRecord->ExceptionInformation[0]);
  396. switch( pep->ExceptionRecord->ExceptionCode )
  397. {
  398. case VcppException(ERROR_SEVERITY_ERROR,ERROR_MOD_NOT_FOUND):
  399. // The DLL was not found
  400. error = 1;
  401. return EXCEPTION_EXECUTE_HANDLER;
  402. case VcppException(ERROR_SEVERITY_ERROR,ERROR_PROC_NOT_FOUND):
  403. // The DLL was found but it doesn't contain the function
  404. error = 2;
  405. return EXCEPTION_EXECUTE_HANDLER;
  406. default:
  407. // We don't recognize this exception
  408. error = 3;
  409. return EXCEPTION_CONTINUE_SEARCH;
  410. break;
  411. }
  412. }
  413. static bool TryInitXInput()
  414. {
  415. int errorCode = 0; bool res = true;
  416. __try
  417. {
  418. XINPUT_STATE state; XInputGetState(0,&state);
  419. }
  420. __except( DelayLoadDllExceptionFilter(GetExceptionInformation(),errorCode))
  421. {
  422. res = false;
  423. }
  424. return res;
  425. }
  426. #endif // !_XBOX
  427. bool Controls::Init()
  428. {
  429. storage = (IFileService *)api->GetService("FileService");
  430. render = (IRender *) api->GetService("DX9Render");
  431. for( int i = 0 ; i < m_devices ; i++ )
  432. {
  433. delete m_devices[i];
  434. m_devices[i] = NULL;
  435. }
  436. m_devices.DelAll();
  437. if( !render )
  438. {
  439. const char *err = "ControlsService: Render service not found.";
  440. api->Trace(err);
  441. Error(1000302,err);
  442. return false;
  443. }
  444. // добавляем группу дефолтного маппинга (на случай если нету таблицы для какого-то джойстика)
  445. m_iniParser.AddJoystickMappingTable("Default");
  446. m_joyMrg = NEW JoystickManager();
  447. m_devices.Add(m_joyMrg);
  448. #ifndef _XBOX
  449. // выясняем какие джойстики подключены, сохраняем их названия в парсере маппинга
  450. HINSTANCE hInst = (HINSTANCE)api->Storage().GetLong("system.hInstance");
  451. HRESULT hr = DirectInput8Create(hInst,DIRECTINPUT_VERSION,IID_IDirectInput8A,(void**)&m_DI,NULL);
  452. if( FAILED(hr))
  453. {
  454. const char *err = "ControlsService: Can't create DirectInput8 device.";
  455. api->Trace(err);
  456. Error(1000300,err);
  457. return false;
  458. }
  459. if( TryInitXInput() == false )
  460. {
  461. const char *err = "ControlsService: Can't initialize XInput library. Install the latest version of DirectX.";
  462. api->Trace(err);
  463. Error(1000301,err);
  464. return false;
  465. }
  466. m_DI->EnumDevices(DI8DEVCLASS_GAMECTRL,JoystickEnumer,this,DIEDFL_ALLDEVICES);
  467. #endif
  468. // выясняем есть ли девайсы XBox 360 и если есть добавляем их в маппинг
  469. m_iniParser.AddJoystickMappingTable(XBOX360_DEVICE);
  470. // парсим таблицы маппинга джойстиков
  471. m_iniParser.ParseJoystickMappings();
  472. // добавляем все XBox360 джойстики в менеджер
  473. for( dword i = 0 ; i < XBoxGamepadCount ; i++ )
  474. m_joyMrg->AddJoystick(NEW XBoxDevice(i,m_iniParser));
  475. #ifndef _XBOX
  476. // добавляем прочие джойстики и другие девайсы в сервис
  477. m_DI->EnumDevices(DI8DEVCLASS_ALL,DeviceEnumer,this,DIEDFL_ALLDEVICES);
  478. m_h = (HWND)api->Storage().GetLong("system.hwnd");
  479. #else
  480. m_devices.Add(NEW XBoxKeyboard(*this));
  481. #endif
  482. // вытаскиваем все девайсовые контролы в общий набор
  483. for( int i = 0 ; i < m_devices ; i++ )
  484. for( dword j = 0; j < m_devices[i]->GetControlsCount() ; j++ )
  485. {
  486. long idxFilter = CreateControlFilter( m_devices[i]->GetControlName(j), 1.0f, false );
  487. GetFilter(idxFilter).SetDataSource(i,j);
  488. }
  489. long mouseHfilter;
  490. long mouseVfilter;
  491. if((mouseHfilter = FindFilterByName("MouseH")) != INVALID_CODE &&
  492. (mouseVfilter = FindFilterByName("MouseV")) != INVALID_CODE)
  493. {
  494. long idx = CreateGameControl("MouseH",false);
  495. GetControl(idx).AddItem(mouseHfilter,false,1.0f,false);
  496. idx = CreateGameControl("MouseV",false);
  497. GetControl(idx).AddItem(mouseVfilter,false,1.0f,false);
  498. }
  499. // парсим все инишники контролов
  500. ReadIni();
  501. IFileService *storage = (IFileService *)api->GetService("FileService");
  502. Assert(storage)
  503. IIniFile *ini = storage->SystemIni();
  504. if( ini )
  505. {
  506. ////
  507. m_debug = (ini->GetLong("Controls","DebugInfo",0) != 0);
  508. ////
  509. m_profile = "resource\\ini\\controls\\profiles\\";
  510. m_profile += ini->GetString("controls","profiles","profiles.ini");
  511. }
  512. const char *prof;
  513. prof = CurrentProfile(0,true,0); if( prof[0] != '[' ) LoadProfile(0,true,0,prof,false,false);
  514. prof = CurrentProfile(0,true,1); if( prof[0] != '[' ) LoadProfile(0,true,1,prof,false,false);
  515. prof = CurrentProfile(0,true,2); if( prof[0] != '[' ) LoadProfile(0,true,2,prof,false,false);
  516. prof = CurrentProfile(0,true,3); if( prof[0] != '[' ) LoadProfile(0,true,3,prof,false,false);
  517. api->SetStartFrameLevel(this,Core_DefaultExecuteLevel + 10);
  518. api->SetEndFrameLevel (this,Core_DefaultExecuteLevel + 0x1000 - 1);
  519. BuildImages();
  520. CreateForceData();
  521. m_mouseH = FindControlByName("MouseH");
  522. m_mouseV = FindControlByName("MouseV");
  523. //////////////////////
  524. m_vibrate = api->Storage().GetItemFloat("Options.controls.vibrate",_FL_);
  525. //////////////////////
  526. Patcher::Group *group;
  527. //// инверсия
  528. group = &m_patcher.groups[m_patcher.groups.Add(Patcher::Group("Options.controls.inv_mouse",true))];
  529. group->controls.Add(Patcher::Group::Control("_Mouse_V"));
  530. group = &m_patcher.groups[m_patcher.groups.Add(Patcher::Group("Options.controls.inv_joy_x",true))];
  531. group->controls.Add(Patcher::Group::Control("_Joy_H"));
  532. group = &m_patcher.groups[m_patcher.groups.Add(Patcher::Group("Options.controls.inv_joy_y",true))];
  533. group->controls.Add(Patcher::Group::Control("_Joy_V"));
  534. //// сенсивити
  535. group = &m_patcher.groups[m_patcher.groups.Add(Patcher::Group("Options.controls.sen_mouse_land"))];
  536. group->controls.Add(Patcher::Group::Control("_MsUp"));
  537. group->controls.Add(Patcher::Group::Control("_MsDown"));
  538. group->controls.Add(Patcher::Group::Control("_MsLeft"));
  539. group->controls.Add(Patcher::Group::Control("_MsRight"));
  540. group = &m_patcher.groups[m_patcher.groups.Add(Patcher::Group("Options.controls.sen_mouse_shooter"))];
  541. group->controls.Add(Patcher::Group::Control("_Mouse_H"));
  542. group->controls.Add(Patcher::Group::Control("_Mouse_V"));
  543. group = &m_patcher.groups[m_patcher.groups.Add(Patcher::Group("Options.controls.sen_joy"))];
  544. group->controls.Add(Patcher::Group::Control("_Joy_H"));
  545. group->controls.Add(Patcher::Group::Control("_Joy_V"));
  546. m_patcher.Init(this);
  547. /////////////////
  548. return true;
  549. }
  550. ///////////////////////////////////////////////////////
  551. void Controls::Patcher::Init(Controls *service)
  552. {
  553. for( int i = 0 ; i < groups ; i++ )
  554. {
  555. Group &group = groups[i];
  556. group.p = api->Storage().GetItemFloat(group.name,_FL_);
  557. for( int j = 0 ; j < group.controls ; j++ )
  558. {
  559. Group::Control &control = group.controls[j];
  560. control.index = service->FindFilterByName(control.name);
  561. if( control.index >= 0 )
  562. {
  563. control.val = service->GetFilter(control.index).m_scale;
  564. }
  565. }
  566. }
  567. }
  568. void Controls::Patcher::Update(Controls *service)
  569. {
  570. for( int i = 0 ; i < groups ; i++ )
  571. {
  572. const Group &group = groups[i];
  573. for( int j = 0 ; j < group.controls ; j++ )
  574. {
  575. const Group::Control &control = group.controls[j];
  576. if( control.index >= 0 )
  577. {
  578. service->GetFilter(control.index).m_scale = control.val;
  579. }
  580. }
  581. }
  582. for( int i = 0 ; i < groups ; i++ )
  583. {
  584. const Group &group = groups[i];
  585. if( group.p )
  586. {
  587. float k = 1.0;
  588. if( group.isFlag )
  589. {
  590. k = group.p->Get(0.0f) > 0.1f ? -1.0f : 1.0f;
  591. }
  592. else
  593. {
  594. k = group.p->Get(1.0f);
  595. }
  596. for( int j = 0 ; j < group.controls ; j++ )
  597. {
  598. const Group::Control &control = group.controls[j];
  599. if( control.index >= 0 )
  600. {
  601. service->GetFilter(control.index).m_scale *= k;
  602. }
  603. }
  604. }
  605. }
  606. }
  607. void Controls::Patcher::Release()
  608. {
  609. for( int i = 0 ; i < groups ; i++ )
  610. {
  611. Group &group = groups[i];
  612. RELEASE(group.p)
  613. }
  614. }
  615. ///////////////////////////////////////////////////////
  616. void Controls::Error(long id, const char *errorEnglish)
  617. {
  618. ILocStrings *locStrings = (ILocStrings *)api->GetService("LocStrings");
  619. ICoreStorageString *st = api->Storage().GetItemString("system.error",_FL_);
  620. if( !st )
  621. return;
  622. const char *errorString = locStrings->GetString(id);
  623. st->Set(errorString ? errorString : errorEnglish);
  624. st->Release();
  625. }
  626. void Controls::CreateForceData()
  627. {
  628. m_forceHash.SetBadFind(-1);
  629. #ifndef _XBOX
  630. const char *name = "Resource\\forces.pkx";
  631. #else
  632. const char *name = "forces.pkx";
  633. #endif
  634. IPackFile *pack = storage->LoadPack(name,_FL_);
  635. IFinder* finder = storage->CreateFinder(IForce_force_path,"*.ffe",
  636. find_all_files_no_mirrors|find_no_recursive,_FL_);
  637. api->Trace("Create forces:\n");
  638. dword count = finder->Count();
  639. bool all_ok = true;
  640. for( dword i = 0 ; i < count ; i++ )
  641. {
  642. IDataFile *file = storage->OpenDataFile(finder->FilePath(i), file_open_any,_FL_);
  643. if( file )
  644. {
  645. Head h;
  646. file->Read(h,h.Size());
  647. XSwizzleLong(h.ln);
  648. XSwizzleLong(h.rn);
  649. if( h.ln > 0 && h.ln < 100 &&
  650. h.rn > 0 && h.rn < 100 )
  651. {
  652. Data d(h);
  653. file->Read(d,d.Size());
  654. bool ok = true;
  655. for( int j = 0 ; j < h.ln ; j++ )
  656. {
  657. Node &node = d.lp[j];
  658. XSwizzleFloat(node.x);
  659. XSwizzleFloat(node.y);
  660. XSwizzleFloat(node.z);
  661. if( node.x < 0.0f || node.x > 100.0f ||
  662. node.y < 0.0f || node.y > 1.0f )
  663. {
  664. ok = false; break;
  665. }
  666. }
  667. if( ok )
  668. {
  669. for( int i = 0 ; i < h.rn ; i++ )
  670. {
  671. Node &node = d.rp[i];
  672. XSwizzleFloat(node.x);
  673. XSwizzleFloat(node.y);
  674. XSwizzleFloat(node.z);
  675. if( node.x < 0.0f || node.x > 100.0f ||
  676. node.y < 0.0f || node.y > 1.0f )
  677. {
  678. ok = false; break;
  679. }
  680. }
  681. }
  682. if( ok )
  683. {
  684. int index;
  685. ForceData &data = m_forceList[index = m_forceList.Add()];
  686. data.ls = d.lp; data.ln = h.ln;
  687. data.rs = d.rp; data.rn = h.rn;
  688. m_forceHash.Add(finder->Name(i),index);
  689. }
  690. else
  691. {
  692. d.Release();
  693. api->Trace(" bad file (skipped) - %s",finder->Name(i));
  694. all_ok = false;
  695. }
  696. }
  697. file->Release();
  698. }
  699. }
  700. if( all_ok )
  701. api->Trace(" well done");
  702. api->Trace("");
  703. finder->Release();
  704. if( pack )
  705. pack->Release();
  706. }
  707. long Controls::GetFilterNode(long index, bool &inverted)
  708. {
  709. if( index < 0 || index > m_controlFilters )
  710. return -1; // невалидный алиас
  711. ControlFilter &filter = m_controlFilters[index];
  712. if( !filter.m_Items )
  713. {
  714. if( filter.m_controlIndex >= 0 && filter.m_deviceIndex >= 0 )
  715. return index;
  716. else
  717. return -1; // невалидный алиас
  718. }
  719. else
  720. {
  721. if( string::IsEqual(filter.m_fname, GetFilter(filter.m_Items[0].filter).m_fname) )
  722. {
  723. api->Trace("CONTROLS: alias '%s' is looped!!!",filter.m_fname);
  724. return -1;
  725. }
  726. if( filter.m_Items[0].isInverted )
  727. inverted = !inverted;
  728. return GetFilterNode(filter.m_Items[0].filter,inverted);
  729. }
  730. }
  731. struct Rec
  732. {
  733. IBaseTexture *t; bool used;
  734. IBaseTexture *z;
  735. long i;
  736. Rec() : t(null),z(null),used(false)
  737. {
  738. i = -1;
  739. }
  740. ~Rec()
  741. {
  742. if( t )
  743. t->Release();
  744. if( z )
  745. z->Release();
  746. }
  747. };
  748. void Controls::BuildImages()
  749. {
  750. if( images )
  751. return;
  752. RELEASE(target)
  753. #ifdef _XBOX
  754. IIniFile *info = storage->OpenIniFile("resource\\ini\\controls_map.ini",_FL_);
  755. if( info )
  756. {
  757. images = render->CreateTextureFullQuality(_FL_,"controls.txx");
  758. if( images )
  759. {
  760. bool ok = true;
  761. api->Trace("\nLoading controls atlas:\n");
  762. ImagePlace p = {0};
  763. for( int i = 0 ; i < m_controlFilters ; i++ )
  764. {
  765. ControlFilter &f = GetFilter(i);
  766. f.m_place = f.m_place_inv = p;
  767. }
  768. dword cx = images->GetWidth();
  769. dword cy = images->GetHeight();
  770. if( cx > 0 && cy > 0 )
  771. {
  772. int bw = info->GetLong("Image","hsize"); // ширина блока в пикселах
  773. int bh = info->GetLong("Image","vsize"); // высота блока в пикселах
  774. if( bw > 0 && bh > 0 )
  775. {
  776. float kx = bw/(float)cx;
  777. float ky = bh/(float)cy;
  778. char name[32];
  779. int x; // позиция блока в строке
  780. int y; // номер строки
  781. int w; // ширина в блоках
  782. int h; // высота в блоках
  783. dword n = info->GetKeysCount("Image","place");
  784. for( dword i = 0 ; i < n ; i++ )
  785. {
  786. const char *s = info->GetString("Image","place","",i);
  787. int args = sscanf_s(s,"%s %d %d %d %d",name,sizeof(name),&y,&x,&w,&h);
  788. if( args == 5 )
  789. {
  790. // api->Trace(name);
  791. const char *control = name; bool inv = control[0] == '-';
  792. if( inv )
  793. control++;
  794. long index = FindFilterByName(control);
  795. if( index >= 0 )
  796. {
  797. p.u = x*kx; p.w = w*kx;
  798. p.v = y*ky; p.h = h*ky;
  799. // api->Trace("%11s %f %f %f %f",control,p.u,p.v,p.w,p.h);
  800. ControlFilter &f = GetFilter(index);
  801. if( inv )
  802. f.m_place_inv = p;
  803. else
  804. f.m_place = p;
  805. if( control[0] == 'g' &&
  806. control[1] == 'p' &&
  807. control[2] == '_' )
  808. {
  809. if( inv )
  810. {
  811. GetFilter(index + 26*1).m_place_inv = p;
  812. GetFilter(index + 26*2).m_place_inv = p;
  813. GetFilter(index + 26*3).m_place_inv = p;
  814. }
  815. else
  816. {
  817. GetFilter(index + 26*1).m_place = p;
  818. GetFilter(index + 26*2).m_place = p;
  819. GetFilter(index + 26*3).m_place = p;
  820. }
  821. }
  822. }
  823. else
  824. {
  825. api->Trace(" Control [%s] not found.",control);
  826. ok = false;
  827. }
  828. }
  829. else
  830. {
  831. api->Trace(" Invalid place format [%s].",s);
  832. ok = false;
  833. }
  834. }
  835. }
  836. else
  837. {
  838. api->Trace(" Invalid block size [%dx%d].",bw,bh);
  839. ok = false;
  840. }
  841. }
  842. else
  843. {
  844. api->Trace(" Invalid image size [%dx%d].",cx,cy);
  845. ok = false;
  846. }
  847. // api->Trace(ok ? " done.\n" : "");
  848. api->Trace("");
  849. info->Release();
  850. return;
  851. }
  852. }
  853. if( info )
  854. info->Release();
  855. #endif // _XBOX
  856. api->Trace("\nCreate controls atlas:\n");
  857. bool inScene = render->IsInsideBeginScene();
  858. array<Rec> map(_FL_);
  859. map.AddElements(m_controlFilters.Size());
  860. for( int i = 0 ; i < m_groups ; i++ )
  861. {
  862. ControlGroup &group = m_groups[i];
  863. for( int j = 0 ; j < group.inds ; j++ )
  864. {
  865. GameControl &control = GetControl(group.inds[j]);
  866. if( !control.m_Items )
  867. continue;
  868. bool inverted = control.m_Items[0].isInverted;
  869. long n = GetFilterNode(control.m_Items[0].filter,inverted);
  870. if( n < 0 ) // невалидный или зацикленный алиас
  871. continue;
  872. if( !map[n].used || inverted && !map[n].z || !inverted && !map[n].t )
  873. {
  874. const ConstString s(GetFilter(n).GetName());
  875. //const string &s = GetFilter(n).GetName();
  876. if( s == MouseDeltaH || s == MouseLDouble ||
  877. s == MouseDeltaV || s == MouseRDouble )
  878. continue;
  879. static char name[128]; const char *str = s.c_str(); const char *p = null;
  880. // для всех [gp*_...] используем одинаковые текстуры
  881. if( str[0] == 'g' &&
  882. str[1] == 'p' && (p = strchr(str,'_')))
  883. {
  884. if( str[2] == '_' )
  885. {
  886. sprintf_s(name,128,"Controls\\%sgp%s.txx",inverted ? "-" : "",p);
  887. map[n].i = -1;
  888. }
  889. else
  890. {
  891. name[0] = 0;
  892. map[n].i = n - 26*(str[2] - '1');
  893. }
  894. }
  895. else
  896. {
  897. sprintf_s(name,128,"Controls\\%s%s.txx",inverted ? "-" : "",str);
  898. }
  899. if( map[n].i < 0 )
  900. {
  901. if( inverted )
  902. map[n].z = render->CreateTextureFullQuality(_FL_,name);
  903. else
  904. map[n].t = render->CreateTextureFullQuality(_FL_,name);
  905. }
  906. if( map[n].z || map[n].t || map[n].i >= 0 )
  907. map[n].used = true;
  908. }
  909. }
  910. }
  911. const float max_r = 2048.0f;
  912. const float max_b = 2048.0f;
  913. float x = 0.0f;
  914. float y = 0.0f;
  915. float b = 0.0f;
  916. float r = 0.0f;
  917. for( int i = 0 ; i < m_controlFilters ; i++ )
  918. {
  919. ControlFilter &f = GetFilter(i);
  920. ImagePlace &p = f.m_place;
  921. ImagePlace &z = f.m_place_inv;
  922. p.u = 0.0f;
  923. p.v = 0.0f;
  924. p.w = 0.0f;
  925. p.h = 0.0f;
  926. z.u = 0.0f;
  927. z.v = 0.0f;
  928. z.w = 0.0f;
  929. z.h = 0.0f;
  930. if( map[i].used )
  931. {
  932. if( map[i].i < 0 )
  933. {
  934. if( map[i].t )
  935. {
  936. p.w = (float)map[i].t->GetWidth ();
  937. p.h = (float)map[i].t->GetHeight();
  938. if( x + p.w > max_r )
  939. {
  940. p.u = 0.0f; y = b;
  941. p.v = y;
  942. }
  943. else
  944. {
  945. p.u = x;
  946. p.v = y;
  947. }
  948. x = p.u + p.w;
  949. if( b < y + p.h )
  950. b = y + p.h;
  951. if( r < x )
  952. r = x;
  953. Assert(b < max_b)
  954. }
  955. if( map[i].z )
  956. {
  957. z.w = (float)map[i].z->GetWidth ();
  958. z.h = (float)map[i].z->GetHeight();
  959. if( x + z.w > max_r )
  960. {
  961. z.u = 0.0f; y = b;
  962. z.v = y;
  963. }
  964. else
  965. {
  966. z.u = x;
  967. z.v = y;
  968. }
  969. x = z.u + z.w;
  970. if( b < y + z.h )
  971. b = y + z.h;
  972. if( r < x )
  973. r = x;
  974. Assert(b < max_b)
  975. }
  976. }
  977. else
  978. {
  979. ControlFilter &g = GetFilter(map[i].i);
  980. p = g.m_place;
  981. z = g.m_place_inv;
  982. }
  983. }
  984. }
  985. dword cx = (dword)r;
  986. dword cy = (dword)b;
  987. if( cx > 0 && cy > 0 )
  988. {
  989. target = render->CreateRenderTarget(cx,cy,_FL_,FMT_A8R8G8B8);
  990. }
  991. if( !target )
  992. return;
  993. IEditableIniFile *table = null;
  994. IVariable *Tex = render->GetTechniqueGlobalVariable("NativeTexture",_FL_);
  995. RENDERVIEWPORT wp;
  996. wp.X = 0; wp.Width = cx;
  997. wp.Y = 0; wp.Height = cy;
  998. wp.MinZ = 0.0f;
  999. wp.MaxZ = 1.0f;
  1000. if( inScene )
  1001. {
  1002. render->EndScene();
  1003. render->PushViewport();
  1004. }
  1005. ShaderId simpleQuad_id;
  1006. render->GetShaderId("SimpleQuad_", simpleQuad_id);
  1007. render->PushRenderTarget();
  1008. render->SetRenderTarget(RTO_DONTOCH_CONTEXT,target);
  1009. render->SetViewport(wp);
  1010. render->BeginScene();
  1011. render->Clear(0,null,CLEAR_TARGET,0,0.0f,0);
  1012. char text[256]; long index = 0;
  1013. for( int i = 0 ; i < m_controlFilters ; i++ )
  1014. {
  1015. if( map[i].used || map[i].i >= 0 )
  1016. {
  1017. ControlFilter &f = GetFilter(i);
  1018. ImagePlace &p = f.m_place;
  1019. ImagePlace &z = f.m_place_inv;
  1020. if( p.h )
  1021. {
  1022. p.u = (p.u + 0.5f)/cx; p.w = (p.w - 1.0f)/cx;
  1023. p.v = (p.v + 0.5f)/cy; p.h = (p.h - 1.0f)/cy;
  1024. }
  1025. if( map[i].t )
  1026. {
  1027. float l = p.u*2.0f - 1.0f; float r = l + p.w*2.0f;
  1028. float t = 1.0f - p.v*2.0f; float b = t - p.h*2.0f;
  1029. float buf[] = {
  1030. r,b,1.0f,1.0f,
  1031. l,b,0.0f,1.0f,
  1032. r,t,1.0f,0.0f,
  1033. l,t,0.0f,0.0f};
  1034. if( Tex )
  1035. Tex->SetTexture(map[i].t);
  1036. render->DrawPrimitiveUP(simpleQuad_id, PT_TRIANGLESTRIP,2,buf,4*sizeof(float));
  1037. }
  1038. if( z.h )
  1039. {
  1040. z.u = (z.u + 0.5f)/cx; z.w = (z.w - 1.0f)/cx;
  1041. z.v = (z.v + 0.5f)/cy; z.h = (z.h - 1.0f)/cy;
  1042. }
  1043. if( map[i].z )
  1044. {
  1045. float l = z.u*2.0f - 1.0f; float r = l + z.w*2.0f;
  1046. float t = 1.0f - z.v*2.0f; float b = t - z.h*2.0f;
  1047. float buf[] = {
  1048. r,b,1.0f,1.0f,
  1049. l,b,0.0f,1.0f,
  1050. r,t,1.0f,0.0f,
  1051. l,t,0.0f,0.0f};
  1052. if( Tex )
  1053. Tex->SetTexture(map[i].z);
  1054. render->DrawPrimitiveUP(simpleQuad_id, PT_TRIANGLESTRIP,2,buf,4*sizeof(float));
  1055. }
  1056. if( table )
  1057. {
  1058. sprintf_s(text,sizeof(text),
  1059. "%11s %f %f %f %f %f %f %f %f",f.GetName(),
  1060. p.u,p.v,p.w,p.h,
  1061. z.u,z.v,z.w,z.h);
  1062. table->SetString("Image","place",text,index++);
  1063. }
  1064. }
  1065. }
  1066. if( table )
  1067. table->Release();
  1068. render->EndScene();
  1069. render->PopRenderTarget(RTO_RESTORE_CONTEXT);
  1070. if( inScene )
  1071. {
  1072. render->PopViewport();
  1073. render->BeginScene();
  1074. }
  1075. #ifndef _XBOX
  1076. if( m_debug )
  1077. render->SaveTexture2File(target->AsTexture(),"controls.dds");
  1078. #endif
  1079. Tex = NULL;
  1080. m_version++;
  1081. }
  1082. void Controls::ReadIni()
  1083. {
  1084. m_groups.DelAll();
  1085. m_iniParser.Parse(*this);
  1086. }
  1087. long Controls::FindFilterByName(const char *name)
  1088. {
  1089. long * p = m_tableFilters.Find(name);
  1090. if( p )
  1091. return *p;
  1092. return INVALID_CODE;
  1093. }
  1094. void Controls::BuildFilterChain(ControlFilter &aliasFilter, const array<Token> &tokens)
  1095. {
  1096. for( int i = 1 ; i < tokens ; i++ )
  1097. {
  1098. long filter = FindFilterByName(tokens[i].name);
  1099. if( filter != INVALID_CODE )
  1100. {
  1101. aliasFilter.AddItem(filter,tokens[i].isInverted,tokens[i].scale,tokens[i].addNext);
  1102. }
  1103. else
  1104. {
  1105. #ifndef _XBOX
  1106. if( tokens[i].name != "null" )
  1107. {
  1108. api->Trace("Control/alias [%s] not found. Can't create alias",tokens[i].name.GetBuffer());
  1109. }
  1110. #endif
  1111. aliasFilter.SetItemSumFlag(aliasFilter.GetItemsCount() - 1,tokens[i].addNext);
  1112. }
  1113. }
  1114. }
  1115. void Controls::AddAlias(const array<Token> &tokens)
  1116. {
  1117. Assert(tokens.Size() >= 2);
  1118. long n = FindFilterByName(tokens[0].name);
  1119. // альяс с таким именем уже существует, повторно не добавляем, существующий не меняем
  1120. // да, повторно не добавляем, но все-таки меняем
  1121. if( n != INVALID_CODE )
  1122. {
  1123. ControlFilter &f = GetFilter(n);
  1124. f.m_Items.DelAll();
  1125. BuildFilterChain(f,tokens);
  1126. return;
  1127. }
  1128. n = CreateControlFilter( tokens[0].name, 1.f, false );
  1129. BuildFilterChain( GetFilter(n), tokens );
  1130. }
  1131. void Controls::AddControl(long group, const array<Token> &tokens)
  1132. {
  1133. if( group >= m_groups )
  1134. return;
  1135. Assert(tokens.Size() >= 2);
  1136. long index = FindControlByName(tokens[0].name);
  1137. if( index != INVALID_CODE )
  1138. {
  1139. api->Trace("Control [%s] already exists. Not changed.",tokens[0].name.GetBuffer());
  1140. return;
  1141. }
  1142. long ctrlIndex = CreateGameControl( tokens[0].name.c_str(), tokens[0].isReverse );
  1143. BuildFilterChain(GetControl(ctrlIndex),tokens);
  1144. if( group != INVALID_CODE )
  1145. m_groups[group].inds.Add(ctrlIndex);
  1146. }
  1147. long Controls::AddGroup(const char *groupName)
  1148. {
  1149. long index = FindGroupByName(groupName);
  1150. if( index != INVALID_CODE )
  1151. return index;
  1152. index = CreateControlGroup(groupName);
  1153. return index;
  1154. }
  1155. //////////////////////////////////////////////////////////////////////////
  1156. static bool _mustUpdate = false;
  1157. void Controls::StartFrame(float dltTime)
  1158. {
  1159. m_curFrame++;
  1160. long active = api->IsActive() ? 1 : 0;
  1161. m_patcher.Update(this);
  1162. // заливаем в "драйверы" данные с устройств
  1163. for( int i = 0 ; i < m_devices ; i++ )
  1164. m_devices[i]->Update(dltTime);
  1165. if( active )
  1166. {
  1167. // говорим, что на текущем кадре состояния контролов непересчитаны
  1168. //for( int i = 0; i < m_gameControls ; i++ )
  1169. // m_gameControls[i].ResetUpdated();
  1170. //for( int i = 0; i < m_controlFilters ; i++ )
  1171. // m_controlFilters[i].m_updated = false;
  1172. }
  1173. #ifndef _XBOX
  1174. bool show = true;
  1175. bool clip = false;
  1176. if( active )
  1177. {
  1178. if( m_prev_act == false )
  1179. {
  1180. if( GetAsyncKeyState(VK_LBUTTON) < 0 )
  1181. {
  1182. TITLEBARINFO tbi;
  1183. tbi.cbSize = sizeof(tbi); GetTitleBarInfo(m_h,&tbi);
  1184. POINT p; GetCursorPos(&p);
  1185. if( PtInRect(&tbi.rcTitleBar,p))
  1186. {
  1187. m_preserve = true;
  1188. }
  1189. }
  1190. }
  1191. else
  1192. {
  1193. if( m_preserve )
  1194. {
  1195. if( GetAsyncKeyState(VK_LBUTTON) >= 0 )
  1196. m_preserve = false;
  1197. }
  1198. }
  1199. if( m_preserve == false )
  1200. {
  1201. // лочим перемещение виндового курсора если надо
  1202. if( m_lockMouse && !m_freeMouse )
  1203. {
  1204. show = false;
  1205. clip = true;
  1206. RECT r; GetWindowRect(m_h,&r);
  1207. SetCursorPos(
  1208. (r.left + r.right)/2,
  1209. (r.top + r.bottom)/2);
  1210. }
  1211. }
  1212. m_freeMouse = false;
  1213. }
  1214. else
  1215. {
  1216. m_preserve = false;
  1217. }
  1218. m_prev_act = (active != 0);
  1219. if( render->GetScreenInfo3D().bWindowed )
  1220. {
  1221. if( m_clipCursor != clip )
  1222. {
  1223. if( clip )
  1224. {
  1225. RECT r; GetClientRect(m_h,&r);
  1226. r.right -= r.left;
  1227. r.bottom -= r.top;
  1228. r.left = 0;
  1229. r.top = 0;
  1230. ClientToScreen(m_h,(LPPOINT)&r);
  1231. r.right += r.left;
  1232. r.bottom += r.top;
  1233. ClipCursor(&r);
  1234. }
  1235. else
  1236. {
  1237. ClipCursor(null);
  1238. }
  1239. m_clipCursor = clip;
  1240. }
  1241. if( m_showCursor != show )
  1242. {
  1243. ShowCursor(m_showCursor = show);
  1244. }
  1245. }
  1246. #endif
  1247. if( _mustUpdate )
  1248. {
  1249. BuildImages();
  1250. _mustUpdate = false;
  1251. }
  1252. if( render->IsRenderReseted())
  1253. {
  1254. _mustUpdate = true;
  1255. RELEASE(target)
  1256. }
  1257. }
  1258. struct Item
  1259. {
  1260. bool on;
  1261. Item() : on(false)
  1262. {
  1263. }
  1264. };
  1265. bool Controls::HandleFilter(int i, array<Item> &map)
  1266. {
  1267. ControlFilter &f = m_controlFilters[i];
  1268. if( f.m_Items < 2 )
  1269. {
  1270. long n = f.m_Items[0].filter;
  1271. ControlFilter &g = m_controlFilters[n];
  1272. if( g.m_last < 0 )
  1273. {
  1274. map[n].on = false;
  1275. return true;
  1276. }
  1277. else
  1278. {
  1279. if( HandleFilter(n,map))
  1280. {
  1281. map[n].on = false;
  1282. return true;
  1283. }
  1284. }
  1285. }
  1286. return false;
  1287. }
  1288. #ifdef ENABLE_STRING_PROFILE
  1289. #include "..\..\common_h\corecmds.h"
  1290. #endif
  1291. //Исполнение в конце кадра
  1292. void Controls::EndFrame(float dltTime)
  1293. {
  1294. for( int i = 0 ; i < m_devices ; i++ )
  1295. m_devices[i]->EndFrame();
  1296. ApplyForces(dltTime);
  1297. #ifdef ENABLE_STRING_PROFILE
  1298. CoreCommand_GetMemStat stats("string.h",-1);
  1299. api->ExecuteCoreCommand(stats);
  1300. render->Print(0,0,0xffffffff,"%d %d",stats.totalAllocSize,stats.numBlocks);
  1301. #endif
  1302. for( i = 0; i < m_gameControls.Len() ; i++ )
  1303. if( !m_gameControls[i].IsUpdated() )
  1304. {
  1305. #ifdef _XBOX
  1306. if (i + 1 < m_gameControls.Len())
  1307. {
  1308. const GameControl & gc = m_gameControls[i + 1];
  1309. if (gc.m_Items.Len())
  1310. {
  1311. ControlFilter & nextFilter = GetFilter(gc.m_Items[0].filter);
  1312. __dcbt(0, &nextFilter);
  1313. }
  1314. }
  1315. #endif
  1316. m_gameControls[i].Update();
  1317. }
  1318. if( m_debug == false )
  1319. return;
  1320. //// определение нажатого контрола ////
  1321. array<Item> map(_FL_);
  1322. map.AddElements(m_controlFilters.Size());
  1323. for( i = 0 ; i < m_controlFilters ; i++ )
  1324. {
  1325. ControlFilter &f = m_controlFilters[i];
  1326. if( !f.m_isMouseVorH && !f.m_isMouseDeltaVorH)
  1327. //f.m_cname != MouseH && f.m_cname != MouseDeltaH &&
  1328. //f.m_cname != MouseV && f.m_cname != MouseDeltaV )
  1329. {
  1330. float v = f.GetValue();
  1331. if( v > 0.3f && f.m_fname[0] != '_' )
  1332. {
  1333. if( f.m_last < 0 )
  1334. {
  1335. map[i].on = true;
  1336. }
  1337. else
  1338. {
  1339. if( HandleFilter(i,map))
  1340. map[i].on = true;
  1341. }
  1342. }
  1343. }
  1344. }
  1345. float x = 515.0f;
  1346. float y = 50.0f;
  1347. string s;
  1348. for( i = 0 ; i < m_controlFilters ; i++ )
  1349. {
  1350. if( map[i].on )
  1351. {
  1352. bool inverted = false;
  1353. long node = GetFilterNode(i,inverted);
  1354. if( node < 0 )
  1355. continue;
  1356. ControlFilter &f = GetFilter(node);
  1357. if( f.GetValue() < 0.0f && !inverted || f.GetValue() >= 0.0f && inverted || f.m_curr < 0 )
  1358. s = "-";
  1359. else
  1360. s = "";
  1361. s += f.m_fname;
  1362. render->Print(x,y,-1,s);
  1363. x += render->GetSystemFont()->GetLength(s);
  1364. x += 10;
  1365. }
  1366. }
  1367. if( !target )
  1368. return;
  1369. IVariable *Tex = render->GetTechniqueGlobalVariable("NativeTexture",_FL_);
  1370. if( Tex )
  1371. Tex->SetTexture(target->AsTexture());
  1372. float off = 0.0f;
  1373. dword cx = render->GetScreenInfo3D().dwWidth;
  1374. dword cy = render->GetScreenInfo3D().dwHeight;
  1375. IBaseTexture *image = target->AsTexture();
  1376. dword imageW = image->GetWidth ();
  1377. dword imageH = image->GetHeight();
  1378. for( int i = 0 ; i < /*256*/m_controlFilters ; i++ )
  1379. {
  1380. if( map[i].on )
  1381. {
  1382. bool inverted = false;
  1383. int n = GetFilterNode(i,inverted);
  1384. if( n < 0 )
  1385. continue;
  1386. ControlFilter &f = GetFilter(n);
  1387. ImagePlace &p = inverted ? f.m_place_inv : f.m_place;
  1388. if( p.w )
  1389. {
  1390. float l = p.u; float r = l + p.w;
  1391. float t = p.v; float b = t + p.h;
  1392. float d = imageW*p.w/cx;
  1393. float c = imageH*p.h/cy;
  1394. float buf[] = {
  1395. off + d,0.0f - c,r,b,
  1396. off - d,0.0f - c,l,b,
  1397. off + d,0.0f + c,r,t,
  1398. off - d,0.0f + c,l,t};
  1399. ShaderId simpleQuad_id;
  1400. render->GetShaderId("SimpleQuad", simpleQuad_id);
  1401. render->DrawPrimitiveUP(simpleQuad_id, PT_TRIANGLESTRIP,2,buf,4*sizeof(float));
  1402. off += d + d;
  1403. }
  1404. }
  1405. }
  1406. Tex = NULL;
  1407. }
  1408. void Controls::ApplyForces(float dltTime)
  1409. {
  1410. if( !forces )
  1411. return;
  1412. float _ls[4] = {0.0f,0.0f,0.0f,0.0f};
  1413. float _rs[4] = {0.0f,0.0f,0.0f,0.0f};
  1414. long active = api->IsActive() ? 1 : 0;
  1415. /////////////////////////////////////////////////
  1416. //bool vibrate = m_vibrate ? m_vibrate->Get(1.0f) > 0.1f : true;
  1417. bool vibrate = api->Storage().GetFloat("Options.controls.vibrate") > 0.1f ? true : false;
  1418. if( active &&( vibrate || m_forceVibrate ))
  1419. {
  1420. for( int i = 0 ; i < forces ; i++ )
  1421. {
  1422. Force &force = forces[i]; const ForceData &data = *force.data;
  1423. float &ls = _ls[force.deviceIndex];
  1424. float &rs = _rs[force.deviceIndex];
  1425. if( force.stopped )
  1426. {
  1427. force.stopped = false;
  1428. continue;
  1429. }
  1430. if( !force.busy || force.time < 0.0f )
  1431. continue;
  1432. if( force.instance &&
  1433. force.instance->IsInactive())
  1434. continue;
  1435. if( force.time == 0.0f )
  1436. {
  1437. ls += coremax(0.0f,data.ls[0].y);
  1438. rs += coremax(0.0f,data.rs[0].y);
  1439. force.time += dltTime;
  1440. }
  1441. else
  1442. {
  1443. force.time += dltTime;
  1444. if( force.time > data.ls[data.ln - 1].x )
  1445. {
  1446. force.time = FORCE_STOP;
  1447. if( force.autoRelease )
  1448. force.busy = false;
  1449. }
  1450. else
  1451. {
  1452. for( int j = 0 ; j < data.ln ; j++ )
  1453. {
  1454. if( data.ls[j].x >= force.time )
  1455. {
  1456. Vector node = data.ls[j];
  1457. Vector prev = data.ls[j - 1];
  1458. ls += coremax(0.0f,Lerp(prev.y,node.y,(force.time - prev.x)/(node.x - prev.x)));
  1459. break;
  1460. }
  1461. }
  1462. for( int j = 0 ; j < data.rn ; j++ )
  1463. {
  1464. if( data.rs[j].x >= force.time )
  1465. {
  1466. Vector node = data.rs[j];
  1467. Vector prev = data.rs[j - 1];
  1468. rs += coremax(0.0f,Lerp(prev.y,node.y,(force.time - prev.x)/(node.x - prev.x)));
  1469. break;
  1470. }
  1471. }
  1472. }
  1473. }
  1474. }
  1475. }
  1476. for( int i = 0 ; i < 4 ; i++ )
  1477. {
  1478. float sp[] = {_ls[i],_rs[i]};
  1479. m_joyMrg->SetJoystickValues(IJoystick::FFRotorSpeed,sp,2*sizeof(float),i);
  1480. }
  1481. }
  1482. //////////////////////////////////////////////////////////////////////////
  1483. IBaseTexture *Controls::GetControlsImage()
  1484. {
  1485. if( images )
  1486. return images;
  1487. return target ? target->AsTexture() : null;
  1488. }
  1489. int Controls::GetControlsImageVersion()
  1490. {
  1491. return m_version;
  1492. }
  1493. ImagePlace Controls::GetControlImagePlace(const char *control_name)
  1494. {
  1495. ImagePlace p;
  1496. p.u = 0.0f;
  1497. p.v = 0.0f;
  1498. p.w = 0.0f;
  1499. p.h = 0.0f;
  1500. if( string::IsEmpty(control_name))
  1501. return p;
  1502. bool inv = control_name[0] == '-';
  1503. if( inv )
  1504. control_name++;
  1505. long n = FindControlByName(control_name);
  1506. if( n != INVALID_CODE )
  1507. {
  1508. GameControl &c = GetControl(n);
  1509. if( !c.m_Items )
  1510. {
  1511. return p;
  1512. }
  1513. else
  1514. {
  1515. if( c.m_Items[0].isInverted )
  1516. inv = !inv;
  1517. bool inverted = inv;
  1518. long node = GetFilterNode(c.m_Items[0].filter,inverted);
  1519. if( node < 0 )
  1520. return p;
  1521. ControlFilter &f = GetFilter(node);
  1522. return inverted ? f.m_place_inv : f.m_place;
  1523. }
  1524. }
  1525. else
  1526. {
  1527. long n = FindFilterByName(control_name);
  1528. if( n == INVALID_CODE )
  1529. {
  1530. return p;
  1531. }
  1532. else
  1533. {
  1534. bool inverted = inv;
  1535. long node = GetFilterNode(n,inverted);
  1536. if( node < 0 )
  1537. return p;
  1538. ControlFilter &f = GetFilter(node);
  1539. return inverted ? f.m_place_inv : f.m_place;
  1540. }
  1541. }
  1542. }
  1543. // найти контрол по его имени
  1544. long Controls::FindControlByName(const char *control_name) const
  1545. {
  1546. long* pIdx = m_tableControls.Find(control_name);
  1547. if( pIdx )
  1548. return *pIdx;
  1549. return INVALID_CODE;
  1550. }
  1551. long Controls::FindGroupByName(const char *group_name)
  1552. {
  1553. long* pIdx = m_tableGroups.Find(group_name);
  1554. if( pIdx )
  1555. return *pIdx;
  1556. return INVALID_CODE;
  1557. }
  1558. // включить/выключить группу контролов
  1559. void Controls::EnableControlGroup(long group_num, bool bEnable)
  1560. {
  1561. if((dword)group_num >= m_groups.Size())
  1562. return;
  1563. ControlGroup &group = m_groups[group_num];
  1564. group.used = bEnable;
  1565. for( int i = 0 ; i < group.inds ; i++ )
  1566. {
  1567. m_gameControls[m_groups[group_num].inds[i]].Enable(bEnable);
  1568. }
  1569. }
  1570. void Controls::EnableControlGroup(const char *group_name, bool bEnable)
  1571. {
  1572. EnableControlGroup(FindGroupByName(group_name),bEnable);
  1573. }
  1574. float Controls::GetDeviceValue(long deviceIndex, long controlIndex) const
  1575. {
  1576. if( deviceIndex >= (long)m_devices.Size())
  1577. return 0.0f;
  1578. return m_devices[deviceIndex]->GetRawValue(controlIndex);
  1579. }
  1580. // получить состояние активности контрола
  1581. ControlStateType Controls::GetControlStateType(long control_code) //const
  1582. {
  1583. if((dword)control_code >= m_gameControls.Size())
  1584. return CST_INACTIVE;
  1585. // if( m_locked )
  1586. if( Locked())
  1587. return CST_INACTIVE;
  1588. return m_gameControls[control_code].GetState();
  1589. }
  1590. ControlStateType Controls::GetControlStateType(const char *control_name) //const
  1591. {
  1592. return GetControlStateType(FindControlByName(control_name));
  1593. }
  1594. // получить значение контрола в формате целого числа
  1595. bool Controls::GetControlStateBool(long control_code) //const
  1596. {
  1597. if( m_locked )
  1598. return 0;
  1599. if((dword)control_code >= m_gameControls.Size())
  1600. return 0;
  1601. return abs(m_gameControls[control_code].GetValue()) > 0.3f;
  1602. }
  1603. bool Controls::GetControlStateBool(const char *control_name) //const
  1604. {
  1605. return GetControlStateBool(FindControlByName(control_name));
  1606. }
  1607. // получить значение контрола в формате с плавающей точкой
  1608. float Controls::GetControlStateFloat(long control_code) //const
  1609. {
  1610. if( m_locked && control_code > 1 )
  1611. return 0.0f;
  1612. if((dword)control_code >= m_gameControls.Size())
  1613. return 0.0f;
  1614. return m_gameControls[control_code].GetValue();
  1615. }
  1616. float Controls::GetControlStateFloat(const char *control_name) //const
  1617. {
  1618. return GetControlStateFloat(FindControlByName(control_name));
  1619. }
  1620. // разрешить/запретить обработку контролов
  1621. void Controls::Lock()
  1622. {
  1623. m_locked++;
  1624. }
  1625. void Controls::Unlock()
  1626. {
  1627. Assert(m_locked)
  1628. m_locked--;
  1629. }
  1630. bool Controls::Locked()
  1631. {
  1632. return m_locked > 0;
  1633. }
  1634. long Controls::LockCount()
  1635. {
  1636. return m_locked;
  1637. }
  1638. // получить алиас активного контрола
  1639. const char *Controls::GetPressedControl(const char *alias_name)
  1640. {
  1641. // параметр не используется!!!
  1642. // Item map[256];
  1643. /* Item map[512];
  1644. Assert(m_controlFilters < 512)*/
  1645. array<Item> map(_FL_);
  1646. map.AddElements(m_controlFilters.Size());
  1647. for( int i = 0 ; i < m_controlFilters ; i++ )
  1648. {
  1649. ControlFilter &f = m_controlFilters[i];
  1650. if( !f.m_isMouseVorH )//m_cname != MouseH && f.m_cname != MouseV )
  1651. {
  1652. float v = f.GetValue();
  1653. if( v > 0.3f )
  1654. {
  1655. if( f.m_last < 0 )
  1656. {
  1657. map[i].on = true;
  1658. }
  1659. else
  1660. {
  1661. if( HandleFilter(i,map))
  1662. map[i].on = true;
  1663. }
  1664. }
  1665. }
  1666. }
  1667. for( int i = 0 ; i < m_controlFilters ; i++ )
  1668. {
  1669. if( map[i].on )
  1670. {
  1671. ControlFilter &f = m_controlFilters[i];
  1672. if( f.m_prev <= 0.0f &&
  1673. f.m_curr > 0.0f )
  1674. {
  1675. if( f.m_fname[0] == '_' )
  1676. return GetFilter(f.m_Items[0].filter).GetName();
  1677. else
  1678. return f.m_fname;
  1679. }
  1680. }
  1681. }
  1682. return null;
  1683. }
  1684. const char *Controls::GetActiveControl(const char *alias_name)
  1685. {
  1686. array<Item> map(_FL_);
  1687. map.AddElements(m_controlFilters.Size());
  1688. for( int i = 0 ; i < m_controlFilters ; i++ )
  1689. {
  1690. ControlFilter &f = m_controlFilters[i];
  1691. if( !f.m_isMouseVorH )//f.m_cname != MouseH && f.m_cname != MouseV )
  1692. {
  1693. float v = f.GetValue();
  1694. if( f.m_last < 0 )
  1695. {
  1696. if( (v) > 0.3f )
  1697. map[i].on = true;
  1698. }
  1699. else
  1700. {
  1701. if( v > 0.3f )
  1702. if( HandleFilter(i,map))
  1703. map[i].on = true;
  1704. }
  1705. }
  1706. }
  1707. for( int i = 0 ; i < m_controlFilters ; i++ )
  1708. {
  1709. if( map[i].on )
  1710. {
  1711. ControlFilter &f = m_controlFilters[i];
  1712. return f.m_fname;
  1713. }
  1714. }
  1715. return null;
  1716. }
  1717. const char *Controls::GetReleasedControl(const char *alias_name)
  1718. {
  1719. array<Item> map(_FL_);
  1720. map.AddElements(m_controlFilters.Size());
  1721. for( int i = 0 ; i < m_controlFilters ; i++ )
  1722. {
  1723. ControlFilter &f = m_controlFilters[i];
  1724. if( !f.m_isMouseVorH ) //f.m_cname != MouseH && f.m_cname != MouseV )
  1725. {
  1726. float v = f.GetValue();
  1727. if( f.m_last < 0 )
  1728. {
  1729. if( (v) > 0.3f )
  1730. map[i].on = true;
  1731. }
  1732. else
  1733. {
  1734. if( v > 0.3f )
  1735. if( HandleFilter(i,map))
  1736. map[i].on = true;
  1737. }
  1738. }
  1739. }
  1740. for( int i = 0 ; i < m_controlFilters ; i++ )
  1741. {
  1742. if( map[i].on )
  1743. {
  1744. ControlFilter &f = m_controlFilters[i];
  1745. if( f.m_prev > 0.0f &&
  1746. f.m_curr <= 0.0f )
  1747. return f.m_fname;
  1748. }
  1749. }
  1750. return null;
  1751. }
  1752. // обновить значение алиаса
  1753. const char *Controls::UpdateAlias(const char *alias_name, const char *name, bool buildImages)
  1754. {
  1755. Assert(alias_name)
  1756. for( int i = 0 ; i < m_controlFilters ; i++ )
  1757. {
  1758. ControlFilter &f = m_controlFilters[i];
  1759. if( string::IsEqual(f.m_fname, alias_name) )
  1760. {
  1761. long n = FindFilterByName(name);
  1762. if( f.m_Items && f.m_Items[0].filter == n )
  1763. {
  1764. return name;
  1765. }
  1766. else
  1767. {
  1768. if( n != INVALID_CODE ) // устанавливаем новое значение
  1769. {
  1770. f.m_Items.DelAll();
  1771. ControlFilter::ChainItem &item = f.m_Items[f.m_Items.Add()];
  1772. item.filter = n;
  1773. item.isInverted = false;
  1774. item.isSumNext = false;
  1775. item.scale = 1.0f;
  1776. if( buildImages )
  1777. {
  1778. BuildImages(); // обновить изображения контролов
  1779. }
  1780. return name;
  1781. }
  1782. else // возвращаем старое значение
  1783. {
  1784. if( name == null )
  1785. {
  1786. if( f.m_Items )
  1787. return GetFilter(f.m_Items[0].filter).GetName();
  1788. else
  1789. return alias_name;
  1790. }
  1791. else
  1792. api->Trace("CONTROLS: %s = %s: invalid alias name - [%s].",alias_name,name,name);
  1793. }
  1794. }
  1795. }
  1796. }
  1797. return null;
  1798. }
  1799. void Controls::SetCurrentProfile(long player, bool single, long index, const char *name)
  1800. {
  1801. static char buf[128]; const char *group; const char *type = single ? "single" : "second";
  1802. switch( index )
  1803. {
  1804. case 0:
  1805. group = "Land";
  1806. break;
  1807. case 1:
  1808. group = "Sea";
  1809. break;
  1810. case 2:
  1811. group = "Shooter";
  1812. break;
  1813. case 3:
  1814. group = "Menu";
  1815. break;
  1816. default:
  1817. api->Trace("CONTROLS: SetCurrentProfile: invalid group index [%d].",index);
  1818. return;
  1819. }
  1820. crt_snprintf(buf,128,"game.controls.%s.%s",type,group);
  1821. api->Storage().SetString(buf,name);
  1822. }
  1823. // загрузить профайл
  1824. bool Controls::LoadProfile(long player, bool single, long index, const char *name, bool reset, bool buildImages)
  1825. {
  1826. if( !name )
  1827. return false;
  1828. static char buf[128]; const char *type = single ? "single" : "second";
  1829. crt_snprintf(buf,128,"game.controls.%s.%s",type,name);
  1830. ICoreStorageFolder *folder = api->Storage().GetItemFolder(buf,_FL_);
  1831. reset = reset || (folder->GetLong("loaded",0) != 1);
  1832. if( reset )
  1833. {
  1834. string s = "resource\\ini\\controls\\profiles\\";
  1835. s += name;
  1836. s += ".ini";
  1837. IIniFile *file = storage->OpenIniFile(s,_FL_);
  1838. if( file )
  1839. {
  1840. array<string> items(_FL_);
  1841. file->GetStrings("aliases","assign",items);
  1842. m_iniParser.ParseAliases(*this,items);
  1843. file->Release();
  1844. SetCurrentProfile(player,single,index,name);
  1845. folder->Release();
  1846. if( buildImages )
  1847. {
  1848. BuildImages(); // обновить изображения контролов
  1849. }
  1850. return true;
  1851. }
  1852. else
  1853. {
  1854. folder->Release();
  1855. return false;
  1856. }
  1857. }
  1858. else
  1859. {
  1860. long count = folder->GetItemsCount();
  1861. for( long i = 1 ; i < count ; i++ )
  1862. {
  1863. const char *alias = folder->GetNameByIndex(i);
  1864. const char *value = folder->GetString(alias);
  1865. const char *tt = UpdateAlias(alias,value,false);
  1866. }
  1867. folder->Release();
  1868. SetCurrentProfile(player,single,index,name);
  1869. if( buildImages )
  1870. {
  1871. BuildImages(); // обновить изображения контролов
  1872. }
  1873. return true;
  1874. }
  1875. }
  1876. // получить имя текущего профайла
  1877. const char *Controls::CurrentProfile(long player, bool single, long index)
  1878. {
  1879. static char buf[128]; const char *group; const char *def = "[PROFILE_NAME]";
  1880. switch( index )
  1881. {
  1882. case 0:
  1883. group = "Land";
  1884. break;
  1885. case 1:
  1886. group = "Sea";
  1887. break;
  1888. case 2:
  1889. group = "Shooter";
  1890. break;
  1891. case 3:
  1892. group = "Menu";
  1893. break;
  1894. default:
  1895. api->Trace("CONTROLS: CurrentProfile: invalid group index [%d].",index);
  1896. return def;
  1897. }
  1898. const char *type = single ? "single" : "second";
  1899. crt_snprintf(buf,128,"game.controls.%s.%s",type,group);
  1900. const char *curr = api->Storage().GetString(buf,def);
  1901. if( curr[0] == '[' )
  1902. {
  1903. IIniFile* profiles = storage->OpenIniFile(m_profile,_FL_);
  1904. if( profiles )
  1905. {
  1906. char key[16];
  1907. crt_snprintf(key,16,single ? "active%d" : "second%d",index);
  1908. const char *s = profiles->GetString("profiles",key);
  1909. if( s[0] )
  1910. {
  1911. api->Storage().SetString(buf,s);
  1912. }
  1913. else
  1914. api->Trace("CONTROLS: default profile for group [%s] not specified (%s).",group,m_profile.c_str());
  1915. profiles->Release();
  1916. }
  1917. else
  1918. api->Trace("CONTROLS: default profile for group [%s] not specified (%s).",group,m_profile.c_str());
  1919. }
  1920. return api->Storage().GetString(buf,def);
  1921. }
  1922. #ifdef ndef
  1923. // создать силу на основе данных из файла
  1924. IForce *Controls::CreateForce(const char *profile, bool autoDelete, long deviceIndex)
  1925. {
  1926. Assert(profile)
  1927. Force *force = GetFreeForce();
  1928. if( force )
  1929. {
  1930. force->autoRelease = autoDelete;
  1931. force->deviceIndex = deviceIndex;
  1932. force->busy = true;
  1933. force->time = FORCE_STOP;
  1934. string name = forcePath + profile;
  1935. if( !strchr(profile,'.'))
  1936. name += ".ffe";
  1937. // IFile *file = storage->OpenFile(name.c_str(),file_open_existing_for_read,_FL_);
  1938. // Assert(file)
  1939. IDataFile *file = storage->OpenDataFile(name.c_str(),_FL_);
  1940. if( !file )
  1941. {
  1942. force->Release();
  1943. return NULL;
  1944. }
  1945. force->ls.DelAll();
  1946. force->rs.DelAll();
  1947. Head h;
  1948. file->Read(h,h.Size());
  1949. XSwizzleLong(h.ln);
  1950. XSwizzleLong(h.rn);
  1951. Data d(h);
  1952. file->Read(d,d.Size());
  1953. bool ok = true;
  1954. for( int i = 0 ; i < h.ln ; i++ )
  1955. {
  1956. Node &node = d.lp[i];
  1957. XSwizzleFloat(node.x);
  1958. XSwizzleFloat(node.y);
  1959. XSwizzleFloat(node.z);
  1960. if( node.x < 0.0f || node.x > 100.0f ||
  1961. node.y < 0.0f || node.y > 1.0f )
  1962. {
  1963. ok = false; break;
  1964. }
  1965. force->ls.Add(node);
  1966. }
  1967. if( ok )
  1968. {
  1969. for( int i = 0 ; i < h.rn ; i++ )
  1970. {
  1971. Node &node = d.rp[i];
  1972. XSwizzleFloat(node.x);
  1973. XSwizzleFloat(node.y);
  1974. XSwizzleFloat(node.z);
  1975. if( node.x < 0.0f || node.x > 100.0f ||
  1976. node.y < 0.0f || node.y > 1.0f )
  1977. {
  1978. ok = false; break;
  1979. }
  1980. force->rs.Add(node);
  1981. }
  1982. }
  1983. if( !ok )
  1984. {
  1985. force->ls.DelAll();
  1986. force->rs.DelAll();
  1987. force->Release();
  1988. force = NULL;
  1989. }
  1990. /* for( int i = 0 ; i < h.ln ; i++ )
  1991. force->ls.Add(d.lp[i]);
  1992. for( int i = 0 ; i < h.rn ; i++ )
  1993. force->rs.Add(d.rp[i]);*/
  1994. file->Release();
  1995. }
  1996. return force;
  1997. }
  1998. #endif
  1999. IForce *Controls::CreateForce(const IControls *instance, const char *profile, bool autoDelete, long deviceIndex)
  2000. {
  2001. Assert(profile)
  2002. Force *force = GetFreeForce();
  2003. if( force )
  2004. {
  2005. force->instance = instance;
  2006. force->autoRelease = autoDelete;
  2007. force->deviceIndex = deviceIndex;
  2008. force->busy = true;
  2009. force->time = FORCE_STOP;
  2010. m_tempName = profile;
  2011. if( !strchr(profile,'.'))
  2012. m_tempName += ".ffe";
  2013. int index = m_forceHash[m_tempName];
  2014. if( index >= 0 )
  2015. {
  2016. force->data = &m_forceList[index];
  2017. return force;
  2018. }
  2019. api->Trace("CONTROLS: force \"%s\" not found.",profile);
  2020. force->Release();
  2021. return null;
  2022. }
  2023. return force;
  2024. }
  2025. // создать силу на основе данных из массивов
  2026. IForce *Controls::CreateForce(array<Vector> &ls, array<Vector> &rs, bool autoDelete, long deviceIndex)
  2027. {
  2028. m_forceVibrate = true;
  2029. long ln = ls.Size();
  2030. long rn = rs.Size();
  2031. if( ln > 0 && rn > 0 )
  2032. {
  2033. Force *force = GetFreeForce();
  2034. if( force )
  2035. {
  2036. force->instance = null;
  2037. force->autoRelease = autoDelete;
  2038. force->deviceIndex = deviceIndex;
  2039. force->busy = true;
  2040. force->time = FORCE_STOP;
  2041. m_forceData.ls = ls;
  2042. m_forceData.rs = rs;
  2043. m_fakeData.ls = m_forceData.ls.GetBuffer();
  2044. m_fakeData.rs = m_forceData.rs.GetBuffer();
  2045. m_fakeData.ln = ln;
  2046. m_fakeData.rn = rn;
  2047. force->data = &m_fakeData;
  2048. }
  2049. return force;
  2050. }
  2051. else
  2052. return null;
  2053. }
  2054. // получить количество групп
  2055. long Controls::GetControlGroupsQuantity() const
  2056. {
  2057. return m_groups.Size();
  2058. }
  2059. // выполнить системно-зависимую команду
  2060. void Controls::ExecuteCommand(InputSrvCommand &cmd)
  2061. {
  2062. switch( cmd.id )
  2063. {
  2064. #ifndef _XBOX
  2065. case LockMouseCursorPos:
  2066. if( render->GetScreenInfo3D().bWindowed )
  2067. {
  2068. bool lock = ((InputSrvLockMouse &)cmd).isLock;
  2069. if( m_lockMouse != lock )
  2070. {
  2071. if( lock )
  2072. {
  2073. GetCursorPos(&m_cursorPos);
  2074. }
  2075. else
  2076. {
  2077. SetCursorPos(
  2078. m_cursorPos.x,
  2079. m_cursorPos.y);
  2080. }
  2081. m_lockMouse = lock;
  2082. }
  2083. }
  2084. break;
  2085. #endif
  2086. case QueryNeedPause:
  2087. ((InputSrvQueryNeedPause &)cmd).needPause = m_joyMrg->IsPaused();
  2088. break;
  2089. case QueryJoypadConnect:
  2090. ((InputSrvQueryJoypadConnect &)cmd).isConnect = m_joyMrg->IsConnected( ((InputSrvQueryJoypadConnect &)cmd).joypadIndex );
  2091. break;
  2092. case QueryJoypadAssignIndex:
  2093. ((InputSrvQueryAssignIndex &)cmd).assignIndex = m_joyMrg->GetAssignIndex( ((InputSrvQueryAssignIndex &)cmd).joypadIndex );
  2094. break;
  2095. }
  2096. }
  2097. //////////////////////////////////////////////////////////////////////////
  2098. void Controls::AddKey(const KeyDescr &desc)
  2099. {
  2100. m_Keys.Add(desc);
  2101. }
  2102. unsigned int Controls::GetKeyBufferLength() const
  2103. {
  2104. if( m_locked > 0 )
  2105. return 0;
  2106. return m_Keys.Size();
  2107. }
  2108. const KeyDescr *Controls::GetKeyBuffer() const
  2109. {
  2110. if( m_locked > 0 )
  2111. return null;
  2112. if( m_Keys.Size())
  2113. return &m_Keys[0];
  2114. return null;
  2115. }
  2116. void Controls::ClearKeyBuffer()
  2117. {
  2118. m_Keys.DelAll();
  2119. }
  2120. void Controls::FreeMouse()
  2121. {
  2122. #ifndef _XBOX
  2123. m_freeMouse = true;
  2124. #endif
  2125. }
  2126. ////
  2127. IControls *Controls::CreateInstance(const char *file, long line)
  2128. {
  2129. return NEW ControlsInstance(this,file,line);
  2130. }
  2131. void Controls::RegInstance(ControlsInstance *p, const char *file, long line)
  2132. {
  2133. InstanceInfo *info = null;
  2134. for( int i = 0 ; i < m_inst ; i++ )
  2135. {
  2136. InstanceInfo *q = &m_inst[i];
  2137. if( !q->used )
  2138. {
  2139. info = q; break;
  2140. }
  2141. }
  2142. if( !info )
  2143. info = &m_inst[m_inst.Add()];
  2144. info->used = true;
  2145. info->p = p;
  2146. info->file = file;
  2147. info->line = line;
  2148. }
  2149. void Controls::DelInstance(ControlsInstance *p)
  2150. {
  2151. for( int i = 0 ; i < m_inst ; i++ )
  2152. {
  2153. InstanceInfo *q = &m_inst[i];
  2154. if( q->p == p )
  2155. {
  2156. q->used = false; break;
  2157. }
  2158. }
  2159. }
  2160. long Controls::CreateGameControl(const char* name, bool isReverse)
  2161. {
  2162. long idx = m_gameControls.Add( GameControl(this,name,isReverse) );
  2163. m_tableControls.AddObj( name, idx );
  2164. return idx;
  2165. }
  2166. long Controls::CreateControlFilter(const char* name, float scale, bool isReverse)
  2167. {
  2168. long idx = m_controlFilters.Add( ControlFilter(this,name,scale,isReverse) );
  2169. m_tableFilters.AddObj( name, idx );
  2170. return idx;
  2171. }
  2172. long Controls::CreateControlGroup(const char* name)
  2173. {
  2174. long idx = m_groups.Add( ControlGroup() );
  2175. m_groups[idx].name = name;
  2176. m_groups[idx].used = true;
  2177. m_tableGroups.AddObj( name, idx );
  2178. return idx;
  2179. }