| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893 |
- #include "pc.h"
- #include "..\..\common_h\systemmsg.h"
- #include "XBoxDevice.h"
- #include "..\..\common_h\InputSrvCmds.h"
- #include "XBoxKeyboard.h"
- const unsigned int XBoxGamepadCount = 4;
- CREATE_SERVICE_NAMED("ControlsService", Controls, 25)
- #ifndef _XBOX
- #pragma comment (lib, "dinput8.lib")
- #pragma comment (lib, "dxguid.lib")
- #include <XInput.h>
- #pragma comment(lib, "Xinput.lib")
- #include "MouseDevice.h"
- #include "KeyboardDevice.h"
- #include "JoystickDevice.h"
- #include <delayimp.h>
- #include <cmath>
- #else // _XBOX
- #include <xtl.h>
- #endif // _XBOX
- #include "JoystickManager.h"
- #include "utils.h"
- #include "..\..\common_h\FileService.h"
- #include "..\..\common_h\Render.h"
- #include "..\..\common_h\LocStrings.h"
- #include "..\..\common_h\data_swizzle.h"
- static IFileService *storage;
- static IRender *render;
- //////////////////////////////////////////////////////////////////////////
- // ControlFilter
- //////////////////////////////////////////////////////////////////////////
- dword mmmax = 0;
- const ConstString MouseV("MouseV");
- const ConstString MouseH("MouseH");
- const ConstString MouseDeltaH("MouseDeltaH");
- const ConstString MouseDeltaV("MouseDeltaV");
- const ConstString MouseLDouble("mouseldouble");
- const ConstString MouseRDouble("mouserdouble");
- ControlFilter::ControlFilter(Controls *ctrl, const char *name, float scale, bool isInverted) : m_Items(_FL_)
- {
- m_ctrl = ctrl;
- SetName(name);
- //m_name = name;
- //mmmax = Max(m_name.Len(), mmmax);
- m_scale = scale;
- m_isInverted = isInverted;
- m_deviceIndex = INVALID_CODE;
- m_controlIndex = INVALID_CODE;
- m_prev = 0.0f;
- m_curr = 0.0f;
- m_last = -1;
- }
- ControlFilter::ControlFilter(Controls *ctrl) : m_Items(_FL_)
- {
- m_ctrl = ctrl;
- m_scale = 1.0f;
- m_isInverted = false;
- m_deviceIndex = INVALID_CODE;
- m_controlIndex = INVALID_CODE;
- m_prev = 0.0f;
- m_curr = 0.0f;
- m_last = -1;
- }
- void ControlFilter::SetName(const char * name)
- {
- crt_strcpy(m_fname, sizeof(m_fname), name);
- m_isMouseVorH = string::IsEqual(m_fname, "MouseV") || string::IsEqual(m_fname, "MouseH");
- m_isMouseDeltaVorH = string::IsEqual(m_fname, "MouseDeltaV") || string::IsEqual(m_fname, "MouseDeltaH");
- }
- bool ControlFilter::operator ==(const ControlFilter &other) const
- {
- return (string::IsEqual(m_fname, other.m_fname));
- }
- const ControlFilter &ControlFilter::operator =(const ControlFilter &other)
- {
- m_ctrl = other.m_ctrl;
- SetName(other.m_fname);
- //m_name = other.m_name;
- //mmmax = Max(m_name.Len(), mmmax);
- m_isInverted = other.m_isInverted;
- m_scale = other.m_scale;
- m_deviceIndex = other.m_deviceIndex;
- m_controlIndex = other.m_controlIndex;
- m_Items = other.m_Items;
- return *this;
- }
- float ControlFilter::GetValue()
- {
- Assert(m_ctrl);
- bool isUpdated = frameUpdated == m_ctrl->GetCurFrame();
- if( !isUpdated )
- m_prev = m_curr;
- float value = 0.0f;
- if( m_deviceIndex != INVALID_CODE &&
- m_controlIndex != INVALID_CODE )
- {
- value = m_ctrl->GetDeviceValue(m_deviceIndex, m_controlIndex);
- value *= m_scale;
- if( m_isInverted )
- value *= -1.0f;
- m_last = -1;
- if (!isUpdated)
- m_curr = value;
- frameUpdated = m_ctrl->GetCurFrame();
- return value;
- }
- bool addNext = false;
- for( dword i = 0; i < m_Items.Size() ; i++ )
- {
- ControlFilter &f = m_ctrl->GetFilter(m_Items[i].filter);
- float next_value = 0.0f;
- if( string::IsEqual(m_fname, f.m_fname) && !m_isMouseVorH)
- {
- api->Trace("CONTROLS: alias '%s' is looped!!!",m_fname);
- }
- else
- {
- next_value = f.GetValue();
- }
- if( m_Items[i].isInverted )
- next_value *= -1.0f;
- next_value *= m_Items[i].scale;
- if( addNext )
- {
- value *= next_value;
- }
- else
- {
- value = next_value;
- }
- addNext = m_Items[i].isSumNext;
- if( fabs(value) > 0.0222f && !addNext )
- {
- m_last = i; break;
- }
- }
- value *= m_scale;
- if( m_isInverted )
- value *= -1;
- if (!isUpdated)
- m_curr = value;
- frameUpdated = m_ctrl->GetCurFrame();
- return value;
- }
- float ControlFilter::GetValueLast()
- {
- Assert(m_ctrl);
- float value = 0.0f;
- if( m_deviceIndex != INVALID_CODE &&
- m_controlIndex != INVALID_CODE )
- {
- value = (frameUpdated == m_ctrl->GetCurFrame()) ? m_prev : m_curr;
- return value;
- }
- bool addNext = false;
-
- for( dword i = 0; i < m_Items.Size() ; i++ )
- {
- #ifdef _XBOX
- // оптимизация на прекеширование следующего фильтра из списка
- if (i+1 < m_Items.Size())
- {
- ControlFilter & nextFilter = m_ctrl->GetFilter(m_Items[i].filter);
- __dcbt(0, &nextFilter);
- }
- #endif
- ControlFilter &f = m_ctrl->GetFilter(m_Items[i].filter);
- float next_value = 0.0f;
- if( string::IsEqual(m_fname, f.m_fname) && !m_isMouseVorH)
- {
- api->Trace("CONTROLS: alias '%s' is looped!!!", m_fname);
- }
- else
- {
- next_value = f.GetValueLast();
- }
- if( m_Items[i].isInverted )
- next_value *= -1.0f;
- next_value *= m_Items[i].scale;
- if( addNext )
- {
- value *= next_value;
- }
- else
- {
- value = next_value;
- }
- addNext = m_Items[i].isSumNext;
- if( fabs(value) > 0.0222f && !addNext )
- {
- break;
- }
- }
- value *= m_scale;
- if( m_isInverted )
- value *= -1;
- return value;
- }
- //////////////////////////////////////////////////////////////////////////
- // GameControl
- //////////////////////////////////////////////////////////////////////////
- GameControl::GameControl(Controls* ctrl, const string & name, bool isReverse) :
- ControlFilter(ctrl,name,1.0f,false)
- {
- m_isReverse = isReverse;
- m_stateType = CST_INACTIVE;
- m_fValue = 0.0f;
- //m_isUpdated = false;
- m_enabled = true;
- m_locked = false;
- m_curFrame = -1;
- }
- GameControl::GameControl() :
- ControlFilter(NULL)
- {
- m_isReverse = false;
- m_stateType = CST_INACTIVE;
- m_fValue = 0.0f;
- //m_isUpdated = false;
- m_enabled = true;
- m_locked = false;
- m_curFrame = -1;
- }
- __inline bool GameControl::IsUpdated() const
- {
- return (m_curFrame == m_ctrl->GetCurFrame());
- }
- void GameControl::Update()
- {
- //m_isUpdated = true;
- m_curFrame = m_ctrl->GetCurFrame();
- if( !m_enabled )
- {
- m_fValue = 0.0f;
- m_stateType = CST_INACTIVE;
- return;
- }
- float oldValue = ControlFilter::GetValueLast();
- float newValue = ControlFilter::GetValue();
- const float thr = 0.6f; // порог срабатывания
- bool oldBoolState = oldValue > thr;
- bool newBoolState = newValue > thr;
- if( m_locked )
- {
- if( !newBoolState )
- m_locked = false;
- newValue = 0.0f;
- m_stateType = CST_INACTIVE;
- }
- else
- {
- if( newBoolState && oldBoolState )
- m_stateType = m_isReverse ? CST_INACTIVE : CST_ACTIVE;
- if( !newBoolState && oldBoolState )
- m_stateType = m_isReverse ? CST_ACTIVATED : CST_INACTIVATED;
- if( newBoolState && !oldBoolState )
- m_stateType = m_isReverse ? CST_INACTIVATED : CST_ACTIVATED;
- if( !newBoolState && !oldBoolState )
- m_stateType = m_isReverse ? CST_ACTIVE : CST_INACTIVE;
- }
- m_fValue = newValue;
- }
- //////////////////////////////////////////////////////////////////////////
- // Controls
- //////////////////////////////////////////////////////////////////////////
- const int forces_count = 32;
- // получить свободную силу мз пула
- Force *Controls::GetFreeForce()
- {
- // профайл не джойстик - тогда ничего не даем. джойстику незачем вибрировать
- const char* pcCurProfileName = api->Storage().GetString("game.controls.single.land");
- if( !pcCurProfileName || (pcCurProfileName[0]!='j' && pcCurProfileName[0]!='J') )
- return null;
- for( int i = 0 ; i < forces ; i++ )
- if( !forces[i].busy )
- return &forces[i];
- if( forces < forces_count )
- return &forces[forces.Add()];
- return null;
- }
- Controls::Controls() : forces(_FL_,forces_count),
- #ifndef _XBOX
- m_DI(NULL),
- #endif
- m_groups (_FL_, 16),
- m_devices (_FL_),
- m_gameControls (_FL_, 224),
- m_tableControls (_FL_),
- m_controlFilters(_FL_, 512),
- m_tableFilters (_FL_),
- m_Keys (_FL_),
- m_forceList (_FL_, 48),
- m_forceHash (_FL_),
- m_inst (_FL_),
- m_tableGroups (_FL_)
- {
- m_curFrame = 0;
- m_lockMouse = false;
- m_freeMouse = false;
- m_showCursor = true;
- m_clipCursor = false;
- m_prev_act = false;
- m_preserve = false;
- m_joyMrg = null;
- target = null;
-
- m_version = 0;
- images = null;
- m_locked = 0;
- m_debug = false;
- m_vibrate = null;
- m_forceVibrate = false;
- }
- Controls::~Controls()
- {
- if( m_joyMrg )
- {
- // стопорим все моторы
- for( long i = 0 ; i < 4 ; i++ )
- {
- float sp[] = {0.0f,0.0f};
- m_joyMrg->SetJoystickValues(IJoystick::FFRotorSpeed,sp,2*sizeof(float),i);
- }
- }
- for( int i = 0; i < m_devices ; i++ )
- {
- delete m_devices[i];
- m_devices[i] = null;
- }
- for( int i = 0 ; i < m_forceList ; i++ )
- {
- m_forceList[i].Release();
- }
- m_devices.DelAll();
- #ifndef _XBOX
- if( m_DI )
- {
- m_DI->Release();
- m_DI = null;
- }
- ClipCursor(null);
- #endif
- RELEASE(target)
- RELEASE(images)
- bool empty = true;
- bool first = true;
- api->Trace("\n=============================");
- api->Trace("\nControls service shutdown start");
- for( int i = 0 ; i < m_inst ; i++ )
- {
- InstanceInfo &info = m_inst[i];
- if( info.used )
- {
- if( first )
- {
- api->Trace("");
- first = false;
- empty = false;
- }
- api->Trace(" Unreleased instance: %s [%d]",info.file,info.line);
- }
- }
- if( !empty )
- api->Trace("");
- api->Trace("Controls service shutdown end");
- api->Trace("\n=============================\n");
- RELEASE(m_vibrate)
- m_patcher.Release();
- }
- #ifndef _XBOX
- BOOL __stdcall DeviceEnumer(LPCDIDEVICEINSTANCEA lpddi, LPVOID pvRef)
- {
- Controls *ctrls = (Controls *)pvRef;
- if(((lpddi->dwDevType & 0xFF) == DI8DEVTYPE_MOUSE))
- ctrls->m_devices.Add(
- NEW MouseDevice(ctrls->m_DI,*lpddi));
- if(((lpddi->dwDevType & 0xFF) == DI8DEVTYPE_KEYBOARD))
- ctrls->m_devices.Add(
- NEW KeyboardDevice(*ctrls,ctrls->m_DI,*lpddi));
- if(((lpddi->dwDevType & 0xFF) == DI8DEVTYPE_JOYSTICK ||
- (lpddi->dwDevType & 0xFF) == DI8DEVTYPE_GAMEPAD) && !IsXInputDevice(&lpddi->guidProduct))
- ctrls->m_joyMrg->AddJoystick(
- NEW JoystickDevice(ctrls->m_DI,*lpddi,ctrls->m_iniParser));
- return DIENUM_CONTINUE;
- }
- BOOL __stdcall JoystickEnumer(LPCDIDEVICEINSTANCEA lpddi, LPVOID pvRef)
- {
- Controls *ctrls = (Controls *)pvRef;
- if( !IsXInputDevice(&lpddi->guidProduct))
- ctrls->m_iniParser.AddJoystickMappingTable(lpddi->tszProductName);
- return DIENUM_CONTINUE;
- }
- static LONG WINAPI DelayLoadDllExceptionFilter(PEXCEPTION_POINTERS pep, int &error)
- {
- // If this is a Delay-load problem, ExceptionInformation[0] points
- // to a DelayLoadInfo structure that has detailed error info
- PDelayLoadInfo pdli = PDelayLoadInfo(pep->ExceptionRecord->ExceptionInformation[0]);
- switch( pep->ExceptionRecord->ExceptionCode )
- {
- case VcppException(ERROR_SEVERITY_ERROR,ERROR_MOD_NOT_FOUND):
- // The DLL was not found
- error = 1;
- return EXCEPTION_EXECUTE_HANDLER;
- case VcppException(ERROR_SEVERITY_ERROR,ERROR_PROC_NOT_FOUND):
- // The DLL was found but it doesn't contain the function
- error = 2;
- return EXCEPTION_EXECUTE_HANDLER;
- default:
- // We don't recognize this exception
- error = 3;
- return EXCEPTION_CONTINUE_SEARCH;
- break;
- }
- }
- static bool TryInitXInput()
- {
- int errorCode = 0; bool res = true;
- __try
- {
- XINPUT_STATE state; XInputGetState(0,&state);
- }
- __except( DelayLoadDllExceptionFilter(GetExceptionInformation(),errorCode))
- {
- res = false;
- }
- return res;
- }
- #endif // !_XBOX
- bool Controls::Init()
- {
- storage = (IFileService *)api->GetService("FileService");
- render = (IRender *) api->GetService("DX9Render");
- for( int i = 0 ; i < m_devices ; i++ )
- {
- delete m_devices[i];
- m_devices[i] = NULL;
- }
- m_devices.DelAll();
- if( !render )
- {
- const char *err = "ControlsService: Render service not found.";
- api->Trace(err);
- Error(1000302,err);
- return false;
- }
- // добавляем группу дефолтного маппинга (на случай если нету таблицы для какого-то джойстика)
- m_iniParser.AddJoystickMappingTable("Default");
- m_joyMrg = NEW JoystickManager();
- m_devices.Add(m_joyMrg);
- #ifndef _XBOX
- // выясняем какие джойстики подключены, сохраняем их названия в парсере маппинга
- HINSTANCE hInst = (HINSTANCE)api->Storage().GetLong("system.hInstance");
- HRESULT hr = DirectInput8Create(hInst,DIRECTINPUT_VERSION,IID_IDirectInput8A,(void**)&m_DI,NULL);
- if( FAILED(hr))
- {
- const char *err = "ControlsService: Can't create DirectInput8 device.";
- api->Trace(err);
- Error(1000300,err);
- return false;
- }
- if( TryInitXInput() == false )
- {
- const char *err = "ControlsService: Can't initialize XInput library. Install the latest version of DirectX.";
- api->Trace(err);
- Error(1000301,err);
- return false;
- }
- m_DI->EnumDevices(DI8DEVCLASS_GAMECTRL,JoystickEnumer,this,DIEDFL_ALLDEVICES);
- #endif
-
- // выясняем есть ли девайсы XBox 360 и если есть добавляем их в маппинг
- m_iniParser.AddJoystickMappingTable(XBOX360_DEVICE);
- // парсим таблицы маппинга джойстиков
- m_iniParser.ParseJoystickMappings();
- // добавляем все XBox360 джойстики в менеджер
- for( dword i = 0 ; i < XBoxGamepadCount ; i++ )
- m_joyMrg->AddJoystick(NEW XBoxDevice(i,m_iniParser));
- #ifndef _XBOX
- // добавляем прочие джойстики и другие девайсы в сервис
- m_DI->EnumDevices(DI8DEVCLASS_ALL,DeviceEnumer,this,DIEDFL_ALLDEVICES);
- m_h = (HWND)api->Storage().GetLong("system.hwnd");
- #else
- m_devices.Add(NEW XBoxKeyboard(*this));
- #endif
- // вытаскиваем все девайсовые контролы в общий набор
- for( int i = 0 ; i < m_devices ; i++ )
- for( dword j = 0; j < m_devices[i]->GetControlsCount() ; j++ )
- {
- long idxFilter = CreateControlFilter( m_devices[i]->GetControlName(j), 1.0f, false );
- GetFilter(idxFilter).SetDataSource(i,j);
- }
- long mouseHfilter;
- long mouseVfilter;
- if((mouseHfilter = FindFilterByName("MouseH")) != INVALID_CODE &&
- (mouseVfilter = FindFilterByName("MouseV")) != INVALID_CODE)
- {
- long idx = CreateGameControl("MouseH",false);
- GetControl(idx).AddItem(mouseHfilter,false,1.0f,false);
- idx = CreateGameControl("MouseV",false);
- GetControl(idx).AddItem(mouseVfilter,false,1.0f,false);
- }
- // парсим все инишники контролов
- ReadIni();
- IFileService *storage = (IFileService *)api->GetService("FileService");
- Assert(storage)
- IIniFile *ini = storage->SystemIni();
- if( ini )
- {
- ////
- m_debug = (ini->GetLong("Controls","DebugInfo",0) != 0);
- ////
- m_profile = "resource\\ini\\controls\\profiles\\";
- m_profile += ini->GetString("controls","profiles","profiles.ini");
- }
- const char *prof;
-
- prof = CurrentProfile(0,true,0); if( prof[0] != '[' ) LoadProfile(0,true,0,prof,false,false);
- prof = CurrentProfile(0,true,1); if( prof[0] != '[' ) LoadProfile(0,true,1,prof,false,false);
- prof = CurrentProfile(0,true,2); if( prof[0] != '[' ) LoadProfile(0,true,2,prof,false,false);
- prof = CurrentProfile(0,true,3); if( prof[0] != '[' ) LoadProfile(0,true,3,prof,false,false);
- api->SetStartFrameLevel(this,Core_DefaultExecuteLevel + 10);
- api->SetEndFrameLevel (this,Core_DefaultExecuteLevel + 0x1000 - 1);
-
- BuildImages();
- CreateForceData();
- m_mouseH = FindControlByName("MouseH");
- m_mouseV = FindControlByName("MouseV");
- //////////////////////
- m_vibrate = api->Storage().GetItemFloat("Options.controls.vibrate",_FL_);
- //////////////////////
- Patcher::Group *group;
- //// инверсия
- group = &m_patcher.groups[m_patcher.groups.Add(Patcher::Group("Options.controls.inv_mouse",true))];
- group->controls.Add(Patcher::Group::Control("_Mouse_V"));
- group = &m_patcher.groups[m_patcher.groups.Add(Patcher::Group("Options.controls.inv_joy_x",true))];
- group->controls.Add(Patcher::Group::Control("_Joy_H"));
- group = &m_patcher.groups[m_patcher.groups.Add(Patcher::Group("Options.controls.inv_joy_y",true))];
- group->controls.Add(Patcher::Group::Control("_Joy_V"));
- //// сенсивити
- group = &m_patcher.groups[m_patcher.groups.Add(Patcher::Group("Options.controls.sen_mouse_land"))];
- group->controls.Add(Patcher::Group::Control("_MsUp"));
- group->controls.Add(Patcher::Group::Control("_MsDown"));
- group->controls.Add(Patcher::Group::Control("_MsLeft"));
- group->controls.Add(Patcher::Group::Control("_MsRight"));
- group = &m_patcher.groups[m_patcher.groups.Add(Patcher::Group("Options.controls.sen_mouse_shooter"))];
- group->controls.Add(Patcher::Group::Control("_Mouse_H"));
- group->controls.Add(Patcher::Group::Control("_Mouse_V"));
- group = &m_patcher.groups[m_patcher.groups.Add(Patcher::Group("Options.controls.sen_joy"))];
- group->controls.Add(Patcher::Group::Control("_Joy_H"));
- group->controls.Add(Patcher::Group::Control("_Joy_V"));
- m_patcher.Init(this);
- /////////////////
- return true;
- }
- ///////////////////////////////////////////////////////
- void Controls::Patcher::Init(Controls *service)
- {
- for( int i = 0 ; i < groups ; i++ )
- {
- Group &group = groups[i];
- group.p = api->Storage().GetItemFloat(group.name,_FL_);
- for( int j = 0 ; j < group.controls ; j++ )
- {
- Group::Control &control = group.controls[j];
- control.index = service->FindFilterByName(control.name);
- if( control.index >= 0 )
- {
- control.val = service->GetFilter(control.index).m_scale;
- }
- }
- }
- }
- void Controls::Patcher::Update(Controls *service)
- {
- for( int i = 0 ; i < groups ; i++ )
- {
- const Group &group = groups[i];
- for( int j = 0 ; j < group.controls ; j++ )
- {
- const Group::Control &control = group.controls[j];
- if( control.index >= 0 )
- {
- service->GetFilter(control.index).m_scale = control.val;
- }
- }
- }
- for( int i = 0 ; i < groups ; i++ )
- {
- const Group &group = groups[i];
- if( group.p )
- {
- float k = 1.0;
- if( group.isFlag )
- {
- k = group.p->Get(0.0f) > 0.1f ? -1.0f : 1.0f;
- }
- else
- {
- k = group.p->Get(1.0f);
- }
- for( int j = 0 ; j < group.controls ; j++ )
- {
- const Group::Control &control = group.controls[j];
- if( control.index >= 0 )
- {
- service->GetFilter(control.index).m_scale *= k;
- }
- }
- }
- }
- }
- void Controls::Patcher::Release()
- {
- for( int i = 0 ; i < groups ; i++ )
- {
- Group &group = groups[i];
- RELEASE(group.p)
- }
- }
- ///////////////////////////////////////////////////////
- void Controls::Error(long id, const char *errorEnglish)
- {
- ILocStrings *locStrings = (ILocStrings *)api->GetService("LocStrings");
- ICoreStorageString *st = api->Storage().GetItemString("system.error",_FL_);
- if( !st )
- return;
- const char *errorString = locStrings->GetString(id);
- st->Set(errorString ? errorString : errorEnglish);
- st->Release();
- }
- void Controls::CreateForceData()
- {
- m_forceHash.SetBadFind(-1);
- #ifndef _XBOX
- const char *name = "Resource\\forces.pkx";
- #else
- const char *name = "forces.pkx";
- #endif
- IPackFile *pack = storage->LoadPack(name,_FL_);
- IFinder* finder = storage->CreateFinder(IForce_force_path,"*.ffe",
- find_all_files_no_mirrors|find_no_recursive,_FL_);
- api->Trace("Create forces:\n");
- dword count = finder->Count();
- bool all_ok = true;
- for( dword i = 0 ; i < count ; i++ )
- {
- IDataFile *file = storage->OpenDataFile(finder->FilePath(i), file_open_any,_FL_);
- if( file )
- {
- Head h;
- file->Read(h,h.Size());
- XSwizzleLong(h.ln);
- XSwizzleLong(h.rn);
- if( h.ln > 0 && h.ln < 100 &&
- h.rn > 0 && h.rn < 100 )
- {
- Data d(h);
- file->Read(d,d.Size());
- bool ok = true;
- for( int j = 0 ; j < h.ln ; j++ )
- {
- Node &node = d.lp[j];
- XSwizzleFloat(node.x);
- XSwizzleFloat(node.y);
- XSwizzleFloat(node.z);
- if( node.x < 0.0f || node.x > 100.0f ||
- node.y < 0.0f || node.y > 1.0f )
- {
- ok = false; break;
- }
- }
- if( ok )
- {
- for( int i = 0 ; i < h.rn ; i++ )
- {
- Node &node = d.rp[i];
- XSwizzleFloat(node.x);
- XSwizzleFloat(node.y);
- XSwizzleFloat(node.z);
- if( node.x < 0.0f || node.x > 100.0f ||
- node.y < 0.0f || node.y > 1.0f )
- {
- ok = false; break;
- }
- }
- }
- if( ok )
- {
- int index;
- ForceData &data = m_forceList[index = m_forceList.Add()];
- data.ls = d.lp; data.ln = h.ln;
- data.rs = d.rp; data.rn = h.rn;
- m_forceHash.Add(finder->Name(i),index);
- }
- else
- {
- d.Release();
- api->Trace(" bad file (skipped) - %s",finder->Name(i));
- all_ok = false;
- }
- }
- file->Release();
- }
- }
- if( all_ok )
- api->Trace(" well done");
- api->Trace("");
- finder->Release();
- if( pack )
- pack->Release();
- }
- long Controls::GetFilterNode(long index, bool &inverted)
- {
- if( index < 0 || index > m_controlFilters )
- return -1; // невалидный алиас
- ControlFilter &filter = m_controlFilters[index];
- if( !filter.m_Items )
- {
- if( filter.m_controlIndex >= 0 && filter.m_deviceIndex >= 0 )
- return index;
- else
- return -1; // невалидный алиас
- }
- else
- {
- if( string::IsEqual(filter.m_fname, GetFilter(filter.m_Items[0].filter).m_fname) )
- {
- api->Trace("CONTROLS: alias '%s' is looped!!!",filter.m_fname);
- return -1;
- }
- if( filter.m_Items[0].isInverted )
- inverted = !inverted;
- return GetFilterNode(filter.m_Items[0].filter,inverted);
- }
- }
- struct Rec
- {
- IBaseTexture *t; bool used;
- IBaseTexture *z;
- long i;
- Rec() : t(null),z(null),used(false)
- {
- i = -1;
- }
- ~Rec()
- {
- if( t )
- t->Release();
- if( z )
- z->Release();
- }
- };
- void Controls::BuildImages()
- {
-
- if( images )
- return;
- RELEASE(target)
- #ifdef _XBOX
- IIniFile *info = storage->OpenIniFile("resource\\ini\\controls_map.ini",_FL_);
- if( info )
- {
- images = render->CreateTextureFullQuality(_FL_,"controls.txx");
- if( images )
- {
- bool ok = true;
- api->Trace("\nLoading controls atlas:\n");
- ImagePlace p = {0};
- for( int i = 0 ; i < m_controlFilters ; i++ )
- {
- ControlFilter &f = GetFilter(i);
- f.m_place = f.m_place_inv = p;
- }
- dword cx = images->GetWidth();
- dword cy = images->GetHeight();
- if( cx > 0 && cy > 0 )
- {
- int bw = info->GetLong("Image","hsize"); // ширина блока в пикселах
- int bh = info->GetLong("Image","vsize"); // высота блока в пикселах
- if( bw > 0 && bh > 0 )
- {
- float kx = bw/(float)cx;
- float ky = bh/(float)cy;
- char name[32];
- int x; // позиция блока в строке
- int y; // номер строки
- int w; // ширина в блоках
- int h; // высота в блоках
- dword n = info->GetKeysCount("Image","place");
- for( dword i = 0 ; i < n ; i++ )
- {
- const char *s = info->GetString("Image","place","",i);
- int args = sscanf_s(s,"%s %d %d %d %d",name,sizeof(name),&y,&x,&w,&h);
- if( args == 5 )
- {
- // api->Trace(name);
- const char *control = name; bool inv = control[0] == '-';
- if( inv )
- control++;
- long index = FindFilterByName(control);
- if( index >= 0 )
- {
- p.u = x*kx; p.w = w*kx;
- p.v = y*ky; p.h = h*ky;
- // api->Trace("%11s %f %f %f %f",control,p.u,p.v,p.w,p.h);
- ControlFilter &f = GetFilter(index);
- if( inv )
- f.m_place_inv = p;
- else
- f.m_place = p;
- if( control[0] == 'g' &&
- control[1] == 'p' &&
- control[2] == '_' )
- {
- if( inv )
- {
- GetFilter(index + 26*1).m_place_inv = p;
- GetFilter(index + 26*2).m_place_inv = p;
- GetFilter(index + 26*3).m_place_inv = p;
- }
- else
- {
- GetFilter(index + 26*1).m_place = p;
- GetFilter(index + 26*2).m_place = p;
- GetFilter(index + 26*3).m_place = p;
- }
- }
- }
- else
- {
- api->Trace(" Control [%s] not found.",control);
- ok = false;
- }
- }
- else
- {
- api->Trace(" Invalid place format [%s].",s);
- ok = false;
- }
- }
- }
- else
- {
- api->Trace(" Invalid block size [%dx%d].",bw,bh);
- ok = false;
- }
- }
- else
- {
- api->Trace(" Invalid image size [%dx%d].",cx,cy);
- ok = false;
- }
- // api->Trace(ok ? " done.\n" : "");
- api->Trace("");
- info->Release();
- return;
- }
- }
- if( info )
- info->Release();
- #endif // _XBOX
- api->Trace("\nCreate controls atlas:\n");
- bool inScene = render->IsInsideBeginScene();
- array<Rec> map(_FL_);
- map.AddElements(m_controlFilters.Size());
- for( int i = 0 ; i < m_groups ; i++ )
- {
- ControlGroup &group = m_groups[i];
- for( int j = 0 ; j < group.inds ; j++ )
- {
- GameControl &control = GetControl(group.inds[j]);
- if( !control.m_Items )
- continue;
- bool inverted = control.m_Items[0].isInverted;
- long n = GetFilterNode(control.m_Items[0].filter,inverted);
- if( n < 0 ) // невалидный или зацикленный алиас
- continue;
- if( !map[n].used || inverted && !map[n].z || !inverted && !map[n].t )
- {
- const ConstString s(GetFilter(n).GetName());
- //const string &s = GetFilter(n).GetName();
- if( s == MouseDeltaH || s == MouseLDouble ||
- s == MouseDeltaV || s == MouseRDouble )
- continue;
- static char name[128]; const char *str = s.c_str(); const char *p = null;
- // для всех [gp*_...] используем одинаковые текстуры
- if( str[0] == 'g' &&
- str[1] == 'p' && (p = strchr(str,'_')))
- {
- if( str[2] == '_' )
- {
- sprintf_s(name,128,"Controls\\%sgp%s.txx",inverted ? "-" : "",p);
- map[n].i = -1;
- }
- else
- {
- name[0] = 0;
- map[n].i = n - 26*(str[2] - '1');
- }
- }
- else
- {
- sprintf_s(name,128,"Controls\\%s%s.txx",inverted ? "-" : "",str);
- }
- if( map[n].i < 0 )
- {
- if( inverted )
- map[n].z = render->CreateTextureFullQuality(_FL_,name);
- else
- map[n].t = render->CreateTextureFullQuality(_FL_,name);
- }
- if( map[n].z || map[n].t || map[n].i >= 0 )
- map[n].used = true;
- }
- }
- }
- const float max_r = 2048.0f;
- const float max_b = 2048.0f;
- float x = 0.0f;
- float y = 0.0f;
- float b = 0.0f;
- float r = 0.0f;
- for( int i = 0 ; i < m_controlFilters ; i++ )
- {
- ControlFilter &f = GetFilter(i);
- ImagePlace &p = f.m_place;
- ImagePlace &z = f.m_place_inv;
- p.u = 0.0f;
- p.v = 0.0f;
- p.w = 0.0f;
- p.h = 0.0f;
- z.u = 0.0f;
- z.v = 0.0f;
- z.w = 0.0f;
- z.h = 0.0f;
- if( map[i].used )
- {
- if( map[i].i < 0 )
- {
- if( map[i].t )
- {
- p.w = (float)map[i].t->GetWidth ();
- p.h = (float)map[i].t->GetHeight();
- if( x + p.w > max_r )
- {
- p.u = 0.0f; y = b;
- p.v = y;
- }
- else
- {
- p.u = x;
- p.v = y;
- }
- x = p.u + p.w;
- if( b < y + p.h )
- b = y + p.h;
- if( r < x )
- r = x;
- Assert(b < max_b)
- }
- if( map[i].z )
- {
- z.w = (float)map[i].z->GetWidth ();
- z.h = (float)map[i].z->GetHeight();
- if( x + z.w > max_r )
- {
- z.u = 0.0f; y = b;
- z.v = y;
- }
- else
- {
- z.u = x;
- z.v = y;
- }
- x = z.u + z.w;
- if( b < y + z.h )
- b = y + z.h;
- if( r < x )
- r = x;
- Assert(b < max_b)
- }
- }
- else
- {
- ControlFilter &g = GetFilter(map[i].i);
- p = g.m_place;
- z = g.m_place_inv;
- }
- }
- }
- dword cx = (dword)r;
- dword cy = (dword)b;
- if( cx > 0 && cy > 0 )
- {
- target = render->CreateRenderTarget(cx,cy,_FL_,FMT_A8R8G8B8);
- }
- if( !target )
- return;
- IEditableIniFile *table = null;
- IVariable *Tex = render->GetTechniqueGlobalVariable("NativeTexture",_FL_);
- RENDERVIEWPORT wp;
- wp.X = 0; wp.Width = cx;
- wp.Y = 0; wp.Height = cy;
- wp.MinZ = 0.0f;
- wp.MaxZ = 1.0f;
- if( inScene )
- {
- render->EndScene();
- render->PushViewport();
- }
- ShaderId simpleQuad_id;
- render->GetShaderId("SimpleQuad_", simpleQuad_id);
- render->PushRenderTarget();
- render->SetRenderTarget(RTO_DONTOCH_CONTEXT,target);
- render->SetViewport(wp);
- render->BeginScene();
- render->Clear(0,null,CLEAR_TARGET,0,0.0f,0);
- char text[256]; long index = 0;
- for( int i = 0 ; i < m_controlFilters ; i++ )
- {
- if( map[i].used || map[i].i >= 0 )
- {
- ControlFilter &f = GetFilter(i);
- ImagePlace &p = f.m_place;
- ImagePlace &z = f.m_place_inv;
- if( p.h )
- {
- p.u = (p.u + 0.5f)/cx; p.w = (p.w - 1.0f)/cx;
- p.v = (p.v + 0.5f)/cy; p.h = (p.h - 1.0f)/cy;
- }
- if( map[i].t )
- {
- float l = p.u*2.0f - 1.0f; float r = l + p.w*2.0f;
- float t = 1.0f - p.v*2.0f; float b = t - p.h*2.0f;
- float buf[] = {
- r,b,1.0f,1.0f,
- l,b,0.0f,1.0f,
- r,t,1.0f,0.0f,
- l,t,0.0f,0.0f};
- if( Tex )
- Tex->SetTexture(map[i].t);
- render->DrawPrimitiveUP(simpleQuad_id, PT_TRIANGLESTRIP,2,buf,4*sizeof(float));
- }
- if( z.h )
- {
- z.u = (z.u + 0.5f)/cx; z.w = (z.w - 1.0f)/cx;
- z.v = (z.v + 0.5f)/cy; z.h = (z.h - 1.0f)/cy;
- }
- if( map[i].z )
- {
- float l = z.u*2.0f - 1.0f; float r = l + z.w*2.0f;
- float t = 1.0f - z.v*2.0f; float b = t - z.h*2.0f;
- float buf[] = {
- r,b,1.0f,1.0f,
- l,b,0.0f,1.0f,
- r,t,1.0f,0.0f,
- l,t,0.0f,0.0f};
- if( Tex )
- Tex->SetTexture(map[i].z);
- render->DrawPrimitiveUP(simpleQuad_id, PT_TRIANGLESTRIP,2,buf,4*sizeof(float));
- }
- if( table )
- {
- sprintf_s(text,sizeof(text),
- "%11s %f %f %f %f %f %f %f %f",f.GetName(),
- p.u,p.v,p.w,p.h,
- z.u,z.v,z.w,z.h);
- table->SetString("Image","place",text,index++);
- }
- }
- }
- if( table )
- table->Release();
- render->EndScene();
- render->PopRenderTarget(RTO_RESTORE_CONTEXT);
- if( inScene )
- {
- render->PopViewport();
- render->BeginScene();
- }
- #ifndef _XBOX
- if( m_debug )
- render->SaveTexture2File(target->AsTexture(),"controls.dds");
- #endif
- Tex = NULL;
- m_version++;
- }
- void Controls::ReadIni()
- {
- m_groups.DelAll();
- m_iniParser.Parse(*this);
- }
- long Controls::FindFilterByName(const char *name)
- {
- long * p = m_tableFilters.Find(name);
- if( p )
- return *p;
- return INVALID_CODE;
- }
- void Controls::BuildFilterChain(ControlFilter &aliasFilter, const array<Token> &tokens)
- {
- for( int i = 1 ; i < tokens ; i++ )
- {
- long filter = FindFilterByName(tokens[i].name);
- if( filter != INVALID_CODE )
- {
- aliasFilter.AddItem(filter,tokens[i].isInverted,tokens[i].scale,tokens[i].addNext);
- }
- else
- {
- #ifndef _XBOX
- if( tokens[i].name != "null" )
- {
- api->Trace("Control/alias [%s] not found. Can't create alias",tokens[i].name.GetBuffer());
- }
- #endif
- aliasFilter.SetItemSumFlag(aliasFilter.GetItemsCount() - 1,tokens[i].addNext);
- }
- }
- }
- void Controls::AddAlias(const array<Token> &tokens)
- {
- Assert(tokens.Size() >= 2);
- long n = FindFilterByName(tokens[0].name);
- // альяс с таким именем уже существует, повторно не добавляем, существующий не меняем
- // да, повторно не добавляем, но все-таки меняем
- if( n != INVALID_CODE )
- {
- ControlFilter &f = GetFilter(n);
- f.m_Items.DelAll();
- BuildFilterChain(f,tokens);
- return;
- }
- n = CreateControlFilter( tokens[0].name, 1.f, false );
- BuildFilterChain( GetFilter(n), tokens );
- }
- void Controls::AddControl(long group, const array<Token> &tokens)
- {
- if( group >= m_groups )
- return;
- Assert(tokens.Size() >= 2);
-
- long index = FindControlByName(tokens[0].name);
- if( index != INVALID_CODE )
- {
- api->Trace("Control [%s] already exists. Not changed.",tokens[0].name.GetBuffer());
- return;
- }
-
- long ctrlIndex = CreateGameControl( tokens[0].name.c_str(), tokens[0].isReverse );
- BuildFilterChain(GetControl(ctrlIndex),tokens);
- if( group != INVALID_CODE )
- m_groups[group].inds.Add(ctrlIndex);
- }
- long Controls::AddGroup(const char *groupName)
- {
- long index = FindGroupByName(groupName);
- if( index != INVALID_CODE )
- return index;
- index = CreateControlGroup(groupName);
- return index;
- }
- //////////////////////////////////////////////////////////////////////////
- static bool _mustUpdate = false;
- void Controls::StartFrame(float dltTime)
- {
- m_curFrame++;
- long active = api->IsActive() ? 1 : 0;
- m_patcher.Update(this);
- // заливаем в "драйверы" данные с устройств
- for( int i = 0 ; i < m_devices ; i++ )
- m_devices[i]->Update(dltTime);
- if( active )
- {
- // говорим, что на текущем кадре состояния контролов непересчитаны
- //for( int i = 0; i < m_gameControls ; i++ )
- // m_gameControls[i].ResetUpdated();
- //for( int i = 0; i < m_controlFilters ; i++ )
- // m_controlFilters[i].m_updated = false;
- }
- #ifndef _XBOX
- bool show = true;
- bool clip = false;
- if( active )
- {
- if( m_prev_act == false )
- {
- if( GetAsyncKeyState(VK_LBUTTON) < 0 )
- {
- TITLEBARINFO tbi;
- tbi.cbSize = sizeof(tbi); GetTitleBarInfo(m_h,&tbi);
- POINT p; GetCursorPos(&p);
- if( PtInRect(&tbi.rcTitleBar,p))
- {
- m_preserve = true;
- }
- }
- }
- else
- {
- if( m_preserve )
- {
- if( GetAsyncKeyState(VK_LBUTTON) >= 0 )
- m_preserve = false;
- }
- }
- if( m_preserve == false )
- {
- // лочим перемещение виндового курсора если надо
- if( m_lockMouse && !m_freeMouse )
- {
- show = false;
- clip = true;
- RECT r; GetWindowRect(m_h,&r);
- SetCursorPos(
- (r.left + r.right)/2,
- (r.top + r.bottom)/2);
- }
- }
- m_freeMouse = false;
- }
- else
- {
- m_preserve = false;
- }
- m_prev_act = (active != 0);
- if( render->GetScreenInfo3D().bWindowed )
- {
- if( m_clipCursor != clip )
- {
- if( clip )
- {
- RECT r; GetClientRect(m_h,&r);
- r.right -= r.left;
- r.bottom -= r.top;
- r.left = 0;
- r.top = 0;
- ClientToScreen(m_h,(LPPOINT)&r);
- r.right += r.left;
- r.bottom += r.top;
- ClipCursor(&r);
- }
- else
- {
- ClipCursor(null);
- }
- m_clipCursor = clip;
- }
- if( m_showCursor != show )
- {
- ShowCursor(m_showCursor = show);
- }
- }
- #endif
- if( _mustUpdate )
- {
- BuildImages();
- _mustUpdate = false;
- }
- if( render->IsRenderReseted())
- {
- _mustUpdate = true;
- RELEASE(target)
- }
- }
- struct Item
- {
- bool on;
- Item() : on(false)
- {
- }
- };
- bool Controls::HandleFilter(int i, array<Item> &map)
- {
- ControlFilter &f = m_controlFilters[i];
- if( f.m_Items < 2 )
- {
- long n = f.m_Items[0].filter;
- ControlFilter &g = m_controlFilters[n];
- if( g.m_last < 0 )
- {
- map[n].on = false;
- return true;
- }
- else
- {
- if( HandleFilter(n,map))
- {
- map[n].on = false;
- return true;
- }
- }
- }
- return false;
- }
- #ifdef ENABLE_STRING_PROFILE
- #include "..\..\common_h\corecmds.h"
- #endif
- //Исполнение в конце кадра
- void Controls::EndFrame(float dltTime)
- {
- for( int i = 0 ; i < m_devices ; i++ )
- m_devices[i]->EndFrame();
- ApplyForces(dltTime);
- #ifdef ENABLE_STRING_PROFILE
- CoreCommand_GetMemStat stats("string.h",-1);
- api->ExecuteCoreCommand(stats);
- render->Print(0,0,0xffffffff,"%d %d",stats.totalAllocSize,stats.numBlocks);
- #endif
- for( i = 0; i < m_gameControls.Len() ; i++ )
- if( !m_gameControls[i].IsUpdated() )
- {
- #ifdef _XBOX
- if (i + 1 < m_gameControls.Len())
- {
- const GameControl & gc = m_gameControls[i + 1];
- if (gc.m_Items.Len())
- {
- ControlFilter & nextFilter = GetFilter(gc.m_Items[0].filter);
- __dcbt(0, &nextFilter);
- }
- }
- #endif
- m_gameControls[i].Update();
- }
- if( m_debug == false )
- return;
- //// определение нажатого контрола ////
- array<Item> map(_FL_);
- map.AddElements(m_controlFilters.Size());
- for( i = 0 ; i < m_controlFilters ; i++ )
- {
- ControlFilter &f = m_controlFilters[i];
- if( !f.m_isMouseVorH && !f.m_isMouseDeltaVorH)
- //f.m_cname != MouseH && f.m_cname != MouseDeltaH &&
- //f.m_cname != MouseV && f.m_cname != MouseDeltaV )
- {
- float v = f.GetValue();
- if( v > 0.3f && f.m_fname[0] != '_' )
- {
- if( f.m_last < 0 )
- {
- map[i].on = true;
- }
- else
- {
- if( HandleFilter(i,map))
- map[i].on = true;
- }
- }
- }
- }
- float x = 515.0f;
- float y = 50.0f;
- string s;
- for( i = 0 ; i < m_controlFilters ; i++ )
- {
- if( map[i].on )
- {
- bool inverted = false;
- long node = GetFilterNode(i,inverted);
- if( node < 0 )
- continue;
- ControlFilter &f = GetFilter(node);
- if( f.GetValue() < 0.0f && !inverted || f.GetValue() >= 0.0f && inverted || f.m_curr < 0 )
- s = "-";
- else
- s = "";
- s += f.m_fname;
- render->Print(x,y,-1,s);
- x += render->GetSystemFont()->GetLength(s);
- x += 10;
- }
- }
- if( !target )
- return;
- IVariable *Tex = render->GetTechniqueGlobalVariable("NativeTexture",_FL_);
- if( Tex )
- Tex->SetTexture(target->AsTexture());
- float off = 0.0f;
- dword cx = render->GetScreenInfo3D().dwWidth;
- dword cy = render->GetScreenInfo3D().dwHeight;
- IBaseTexture *image = target->AsTexture();
- dword imageW = image->GetWidth ();
- dword imageH = image->GetHeight();
- for( int i = 0 ; i < /*256*/m_controlFilters ; i++ )
- {
- if( map[i].on )
- {
- bool inverted = false;
- int n = GetFilterNode(i,inverted);
- if( n < 0 )
- continue;
- ControlFilter &f = GetFilter(n);
- ImagePlace &p = inverted ? f.m_place_inv : f.m_place;
- if( p.w )
- {
- float l = p.u; float r = l + p.w;
- float t = p.v; float b = t + p.h;
- float d = imageW*p.w/cx;
- float c = imageH*p.h/cy;
- float buf[] = {
- off + d,0.0f - c,r,b,
- off - d,0.0f - c,l,b,
- off + d,0.0f + c,r,t,
- off - d,0.0f + c,l,t};
- ShaderId simpleQuad_id;
- render->GetShaderId("SimpleQuad", simpleQuad_id);
- render->DrawPrimitiveUP(simpleQuad_id, PT_TRIANGLESTRIP,2,buf,4*sizeof(float));
- off += d + d;
- }
- }
- }
- Tex = NULL;
- }
- void Controls::ApplyForces(float dltTime)
- {
- if( !forces )
- return;
- float _ls[4] = {0.0f,0.0f,0.0f,0.0f};
- float _rs[4] = {0.0f,0.0f,0.0f,0.0f};
- long active = api->IsActive() ? 1 : 0;
- /////////////////////////////////////////////////
- //bool vibrate = m_vibrate ? m_vibrate->Get(1.0f) > 0.1f : true;
- bool vibrate = api->Storage().GetFloat("Options.controls.vibrate") > 0.1f ? true : false;
- if( active &&( vibrate || m_forceVibrate ))
- {
- for( int i = 0 ; i < forces ; i++ )
- {
- Force &force = forces[i]; const ForceData &data = *force.data;
- float &ls = _ls[force.deviceIndex];
- float &rs = _rs[force.deviceIndex];
- if( force.stopped )
- {
- force.stopped = false;
- continue;
- }
- if( !force.busy || force.time < 0.0f )
- continue;
- if( force.instance &&
- force.instance->IsInactive())
- continue;
- if( force.time == 0.0f )
- {
- ls += coremax(0.0f,data.ls[0].y);
- rs += coremax(0.0f,data.rs[0].y);
- force.time += dltTime;
- }
- else
- {
- force.time += dltTime;
- if( force.time > data.ls[data.ln - 1].x )
- {
- force.time = FORCE_STOP;
- if( force.autoRelease )
- force.busy = false;
- }
- else
- {
- for( int j = 0 ; j < data.ln ; j++ )
- {
- if( data.ls[j].x >= force.time )
- {
- Vector node = data.ls[j];
- Vector prev = data.ls[j - 1];
- ls += coremax(0.0f,Lerp(prev.y,node.y,(force.time - prev.x)/(node.x - prev.x)));
- break;
- }
- }
- for( int j = 0 ; j < data.rn ; j++ )
- {
- if( data.rs[j].x >= force.time )
- {
- Vector node = data.rs[j];
- Vector prev = data.rs[j - 1];
- rs += coremax(0.0f,Lerp(prev.y,node.y,(force.time - prev.x)/(node.x - prev.x)));
- break;
- }
- }
- }
- }
- }
- }
- for( int i = 0 ; i < 4 ; i++ )
- {
- float sp[] = {_ls[i],_rs[i]};
- m_joyMrg->SetJoystickValues(IJoystick::FFRotorSpeed,sp,2*sizeof(float),i);
- }
- }
- //////////////////////////////////////////////////////////////////////////
- IBaseTexture *Controls::GetControlsImage()
- {
- if( images )
- return images;
- return target ? target->AsTexture() : null;
- }
- int Controls::GetControlsImageVersion()
- {
- return m_version;
- }
- ImagePlace Controls::GetControlImagePlace(const char *control_name)
- {
- ImagePlace p;
- p.u = 0.0f;
- p.v = 0.0f;
- p.w = 0.0f;
- p.h = 0.0f;
- if( string::IsEmpty(control_name))
- return p;
- bool inv = control_name[0] == '-';
- if( inv )
- control_name++;
- long n = FindControlByName(control_name);
- if( n != INVALID_CODE )
- {
- GameControl &c = GetControl(n);
- if( !c.m_Items )
- {
- return p;
- }
- else
- {
- if( c.m_Items[0].isInverted )
- inv = !inv;
- bool inverted = inv;
- long node = GetFilterNode(c.m_Items[0].filter,inverted);
- if( node < 0 )
- return p;
- ControlFilter &f = GetFilter(node);
- return inverted ? f.m_place_inv : f.m_place;
- }
- }
- else
- {
- long n = FindFilterByName(control_name);
- if( n == INVALID_CODE )
- {
- return p;
- }
- else
- {
- bool inverted = inv;
- long node = GetFilterNode(n,inverted);
- if( node < 0 )
- return p;
- ControlFilter &f = GetFilter(node);
- return inverted ? f.m_place_inv : f.m_place;
- }
- }
- }
- // найти контрол по его имени
- long Controls::FindControlByName(const char *control_name) const
- {
- long* pIdx = m_tableControls.Find(control_name);
- if( pIdx )
- return *pIdx;
- return INVALID_CODE;
- }
- long Controls::FindGroupByName(const char *group_name)
- {
- long* pIdx = m_tableGroups.Find(group_name);
- if( pIdx )
- return *pIdx;
- return INVALID_CODE;
- }
- // включить/выключить группу контролов
- void Controls::EnableControlGroup(long group_num, bool bEnable)
- {
- if((dword)group_num >= m_groups.Size())
- return;
- ControlGroup &group = m_groups[group_num];
- group.used = bEnable;
- for( int i = 0 ; i < group.inds ; i++ )
- {
- m_gameControls[m_groups[group_num].inds[i]].Enable(bEnable);
- }
- }
- void Controls::EnableControlGroup(const char *group_name, bool bEnable)
- {
- EnableControlGroup(FindGroupByName(group_name),bEnable);
- }
- float Controls::GetDeviceValue(long deviceIndex, long controlIndex) const
- {
- if( deviceIndex >= (long)m_devices.Size())
- return 0.0f;
- return m_devices[deviceIndex]->GetRawValue(controlIndex);
- }
- // получить состояние активности контрола
- ControlStateType Controls::GetControlStateType(long control_code) //const
- {
- if((dword)control_code >= m_gameControls.Size())
- return CST_INACTIVE;
- // if( m_locked )
- if( Locked())
- return CST_INACTIVE;
- return m_gameControls[control_code].GetState();
- }
- ControlStateType Controls::GetControlStateType(const char *control_name) //const
- {
- return GetControlStateType(FindControlByName(control_name));
- }
- // получить значение контрола в формате целого числа
- bool Controls::GetControlStateBool(long control_code) //const
- {
- if( m_locked )
- return 0;
- if((dword)control_code >= m_gameControls.Size())
- return 0;
-
- return abs(m_gameControls[control_code].GetValue()) > 0.3f;
- }
- bool Controls::GetControlStateBool(const char *control_name) //const
- {
- return GetControlStateBool(FindControlByName(control_name));
- }
- // получить значение контрола в формате с плавающей точкой
- float Controls::GetControlStateFloat(long control_code) //const
- {
- if( m_locked && control_code > 1 )
- return 0.0f;
- if((dword)control_code >= m_gameControls.Size())
- return 0.0f;
- return m_gameControls[control_code].GetValue();
- }
- float Controls::GetControlStateFloat(const char *control_name) //const
- {
- return GetControlStateFloat(FindControlByName(control_name));
- }
- // разрешить/запретить обработку контролов
- void Controls::Lock()
- {
- m_locked++;
- }
- void Controls::Unlock()
- {
- Assert(m_locked)
- m_locked--;
- }
- bool Controls::Locked()
- {
- return m_locked > 0;
- }
- long Controls::LockCount()
- {
- return m_locked;
- }
- // получить алиас активного контрола
- const char *Controls::GetPressedControl(const char *alias_name)
- {
- // параметр не используется!!!
- // Item map[256];
- /* Item map[512];
- Assert(m_controlFilters < 512)*/
- array<Item> map(_FL_);
- map.AddElements(m_controlFilters.Size());
- for( int i = 0 ; i < m_controlFilters ; i++ )
- {
- ControlFilter &f = m_controlFilters[i];
- if( !f.m_isMouseVorH )//m_cname != MouseH && f.m_cname != MouseV )
- {
- float v = f.GetValue();
- if( v > 0.3f )
- {
- if( f.m_last < 0 )
- {
- map[i].on = true;
- }
- else
- {
- if( HandleFilter(i,map))
- map[i].on = true;
- }
- }
- }
- }
- for( int i = 0 ; i < m_controlFilters ; i++ )
- {
- if( map[i].on )
- {
- ControlFilter &f = m_controlFilters[i];
- if( f.m_prev <= 0.0f &&
- f.m_curr > 0.0f )
- {
- if( f.m_fname[0] == '_' )
- return GetFilter(f.m_Items[0].filter).GetName();
- else
- return f.m_fname;
- }
- }
- }
- return null;
- }
- const char *Controls::GetActiveControl(const char *alias_name)
- {
- array<Item> map(_FL_);
- map.AddElements(m_controlFilters.Size());
- for( int i = 0 ; i < m_controlFilters ; i++ )
- {
- ControlFilter &f = m_controlFilters[i];
- if( !f.m_isMouseVorH )//f.m_cname != MouseH && f.m_cname != MouseV )
- {
- float v = f.GetValue();
- if( f.m_last < 0 )
- {
- if( (v) > 0.3f )
- map[i].on = true;
- }
- else
- {
- if( v > 0.3f )
- if( HandleFilter(i,map))
- map[i].on = true;
- }
- }
- }
- for( int i = 0 ; i < m_controlFilters ; i++ )
- {
- if( map[i].on )
- {
- ControlFilter &f = m_controlFilters[i];
- return f.m_fname;
- }
- }
- return null;
- }
- const char *Controls::GetReleasedControl(const char *alias_name)
- {
- array<Item> map(_FL_);
- map.AddElements(m_controlFilters.Size());
- for( int i = 0 ; i < m_controlFilters ; i++ )
- {
- ControlFilter &f = m_controlFilters[i];
- if( !f.m_isMouseVorH ) //f.m_cname != MouseH && f.m_cname != MouseV )
- {
- float v = f.GetValue();
- if( f.m_last < 0 )
- {
- if( (v) > 0.3f )
- map[i].on = true;
- }
- else
- {
- if( v > 0.3f )
- if( HandleFilter(i,map))
- map[i].on = true;
- }
- }
- }
- for( int i = 0 ; i < m_controlFilters ; i++ )
- {
- if( map[i].on )
- {
- ControlFilter &f = m_controlFilters[i];
- if( f.m_prev > 0.0f &&
- f.m_curr <= 0.0f )
- return f.m_fname;
- }
- }
- return null;
- }
- // обновить значение алиаса
- const char *Controls::UpdateAlias(const char *alias_name, const char *name, bool buildImages)
- {
- Assert(alias_name)
- for( int i = 0 ; i < m_controlFilters ; i++ )
- {
- ControlFilter &f = m_controlFilters[i];
- if( string::IsEqual(f.m_fname, alias_name) )
- {
- long n = FindFilterByName(name);
- if( f.m_Items && f.m_Items[0].filter == n )
- {
- return name;
- }
- else
- {
- if( n != INVALID_CODE ) // устанавливаем новое значение
- {
- f.m_Items.DelAll();
- ControlFilter::ChainItem &item = f.m_Items[f.m_Items.Add()];
- item.filter = n;
- item.isInverted = false;
- item.isSumNext = false;
- item.scale = 1.0f;
- if( buildImages )
- {
- BuildImages(); // обновить изображения контролов
- }
- return name;
- }
- else // возвращаем старое значение
- {
- if( name == null )
- {
- if( f.m_Items )
- return GetFilter(f.m_Items[0].filter).GetName();
- else
- return alias_name;
- }
- else
- api->Trace("CONTROLS: %s = %s: invalid alias name - [%s].",alias_name,name,name);
- }
- }
- }
- }
- return null;
- }
- void Controls::SetCurrentProfile(long player, bool single, long index, const char *name)
- {
- static char buf[128]; const char *group; const char *type = single ? "single" : "second";
- switch( index )
- {
- case 0:
- group = "Land";
- break;
- case 1:
- group = "Sea";
- break;
- case 2:
- group = "Shooter";
- break;
- case 3:
- group = "Menu";
- break;
- default:
- api->Trace("CONTROLS: SetCurrentProfile: invalid group index [%d].",index);
- return;
- }
- crt_snprintf(buf,128,"game.controls.%s.%s",type,group);
- api->Storage().SetString(buf,name);
- }
- // загрузить профайл
- bool Controls::LoadProfile(long player, bool single, long index, const char *name, bool reset, bool buildImages)
- {
- if( !name )
- return false;
- static char buf[128]; const char *type = single ? "single" : "second";
- crt_snprintf(buf,128,"game.controls.%s.%s",type,name);
- ICoreStorageFolder *folder = api->Storage().GetItemFolder(buf,_FL_);
- reset = reset || (folder->GetLong("loaded",0) != 1);
- if( reset )
- {
- string s = "resource\\ini\\controls\\profiles\\";
- s += name;
- s += ".ini";
- IIniFile *file = storage->OpenIniFile(s,_FL_);
- if( file )
- {
- array<string> items(_FL_);
- file->GetStrings("aliases","assign",items);
- m_iniParser.ParseAliases(*this,items);
- file->Release();
- SetCurrentProfile(player,single,index,name);
- folder->Release();
- if( buildImages )
- {
- BuildImages(); // обновить изображения контролов
- }
- return true;
- }
- else
- {
- folder->Release();
- return false;
- }
- }
- else
- {
- long count = folder->GetItemsCount();
- for( long i = 1 ; i < count ; i++ )
- {
- const char *alias = folder->GetNameByIndex(i);
- const char *value = folder->GetString(alias);
- const char *tt = UpdateAlias(alias,value,false);
- }
- folder->Release();
- SetCurrentProfile(player,single,index,name);
- if( buildImages )
- {
- BuildImages(); // обновить изображения контролов
- }
- return true;
- }
- }
- // получить имя текущего профайла
- const char *Controls::CurrentProfile(long player, bool single, long index)
- {
- static char buf[128]; const char *group; const char *def = "[PROFILE_NAME]";
- switch( index )
- {
- case 0:
- group = "Land";
- break;
- case 1:
- group = "Sea";
- break;
- case 2:
- group = "Shooter";
- break;
- case 3:
- group = "Menu";
- break;
- default:
- api->Trace("CONTROLS: CurrentProfile: invalid group index [%d].",index);
- return def;
- }
- const char *type = single ? "single" : "second";
- crt_snprintf(buf,128,"game.controls.%s.%s",type,group);
- const char *curr = api->Storage().GetString(buf,def);
- if( curr[0] == '[' )
- {
- IIniFile* profiles = storage->OpenIniFile(m_profile,_FL_);
- if( profiles )
- {
- char key[16];
- crt_snprintf(key,16,single ? "active%d" : "second%d",index);
- const char *s = profiles->GetString("profiles",key);
- if( s[0] )
- {
- api->Storage().SetString(buf,s);
- }
- else
- api->Trace("CONTROLS: default profile for group [%s] not specified (%s).",group,m_profile.c_str());
- profiles->Release();
- }
- else
- api->Trace("CONTROLS: default profile for group [%s] not specified (%s).",group,m_profile.c_str());
- }
- return api->Storage().GetString(buf,def);
- }
- #ifdef ndef
- // создать силу на основе данных из файла
- IForce *Controls::CreateForce(const char *profile, bool autoDelete, long deviceIndex)
- {
- Assert(profile)
- Force *force = GetFreeForce();
- if( force )
- {
- force->autoRelease = autoDelete;
- force->deviceIndex = deviceIndex;
- force->busy = true;
- force->time = FORCE_STOP;
- string name = forcePath + profile;
- if( !strchr(profile,'.'))
- name += ".ffe";
- // IFile *file = storage->OpenFile(name.c_str(),file_open_existing_for_read,_FL_);
- // Assert(file)
- IDataFile *file = storage->OpenDataFile(name.c_str(),_FL_);
- if( !file )
- {
- force->Release();
- return NULL;
- }
- force->ls.DelAll();
- force->rs.DelAll();
- Head h;
- file->Read(h,h.Size());
- XSwizzleLong(h.ln);
- XSwizzleLong(h.rn);
- Data d(h);
- file->Read(d,d.Size());
- bool ok = true;
- for( int i = 0 ; i < h.ln ; i++ )
- {
- Node &node = d.lp[i];
- XSwizzleFloat(node.x);
- XSwizzleFloat(node.y);
- XSwizzleFloat(node.z);
- if( node.x < 0.0f || node.x > 100.0f ||
- node.y < 0.0f || node.y > 1.0f )
- {
- ok = false; break;
- }
- force->ls.Add(node);
- }
- if( ok )
- {
- for( int i = 0 ; i < h.rn ; i++ )
- {
- Node &node = d.rp[i];
- XSwizzleFloat(node.x);
- XSwizzleFloat(node.y);
- XSwizzleFloat(node.z);
- if( node.x < 0.0f || node.x > 100.0f ||
- node.y < 0.0f || node.y > 1.0f )
- {
- ok = false; break;
- }
- force->rs.Add(node);
- }
- }
- if( !ok )
- {
- force->ls.DelAll();
- force->rs.DelAll();
- force->Release();
- force = NULL;
- }
- /* for( int i = 0 ; i < h.ln ; i++ )
- force->ls.Add(d.lp[i]);
- for( int i = 0 ; i < h.rn ; i++ )
- force->rs.Add(d.rp[i]);*/
- file->Release();
- }
- return force;
- }
- #endif
- IForce *Controls::CreateForce(const IControls *instance, const char *profile, bool autoDelete, long deviceIndex)
- {
- Assert(profile)
- Force *force = GetFreeForce();
- if( force )
- {
- force->instance = instance;
- force->autoRelease = autoDelete;
- force->deviceIndex = deviceIndex;
- force->busy = true;
- force->time = FORCE_STOP;
- m_tempName = profile;
- if( !strchr(profile,'.'))
- m_tempName += ".ffe";
- int index = m_forceHash[m_tempName];
- if( index >= 0 )
- {
- force->data = &m_forceList[index];
- return force;
- }
- api->Trace("CONTROLS: force \"%s\" not found.",profile);
- force->Release();
- return null;
- }
- return force;
- }
- // создать силу на основе данных из массивов
- IForce *Controls::CreateForce(array<Vector> &ls, array<Vector> &rs, bool autoDelete, long deviceIndex)
- {
- m_forceVibrate = true;
- long ln = ls.Size();
- long rn = rs.Size();
- if( ln > 0 && rn > 0 )
- {
- Force *force = GetFreeForce();
- if( force )
- {
- force->instance = null;
- force->autoRelease = autoDelete;
- force->deviceIndex = deviceIndex;
- force->busy = true;
- force->time = FORCE_STOP;
- m_forceData.ls = ls;
- m_forceData.rs = rs;
- m_fakeData.ls = m_forceData.ls.GetBuffer();
- m_fakeData.rs = m_forceData.rs.GetBuffer();
- m_fakeData.ln = ln;
- m_fakeData.rn = rn;
- force->data = &m_fakeData;
- }
- return force;
- }
- else
- return null;
- }
- // получить количество групп
- long Controls::GetControlGroupsQuantity() const
- {
- return m_groups.Size();
- }
- // выполнить системно-зависимую команду
- void Controls::ExecuteCommand(InputSrvCommand &cmd)
- {
- switch( cmd.id )
- {
- #ifndef _XBOX
- case LockMouseCursorPos:
- if( render->GetScreenInfo3D().bWindowed )
- {
- bool lock = ((InputSrvLockMouse &)cmd).isLock;
- if( m_lockMouse != lock )
- {
- if( lock )
- {
- GetCursorPos(&m_cursorPos);
- }
- else
- {
- SetCursorPos(
- m_cursorPos.x,
- m_cursorPos.y);
- }
- m_lockMouse = lock;
- }
- }
- break;
- #endif
- case QueryNeedPause:
- ((InputSrvQueryNeedPause &)cmd).needPause = m_joyMrg->IsPaused();
- break;
- case QueryJoypadConnect:
- ((InputSrvQueryJoypadConnect &)cmd).isConnect = m_joyMrg->IsConnected( ((InputSrvQueryJoypadConnect &)cmd).joypadIndex );
- break;
- case QueryJoypadAssignIndex:
- ((InputSrvQueryAssignIndex &)cmd).assignIndex = m_joyMrg->GetAssignIndex( ((InputSrvQueryAssignIndex &)cmd).joypadIndex );
- break;
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void Controls::AddKey(const KeyDescr &desc)
- {
- m_Keys.Add(desc);
- }
- unsigned int Controls::GetKeyBufferLength() const
- {
- if( m_locked > 0 )
- return 0;
- return m_Keys.Size();
- }
- const KeyDescr *Controls::GetKeyBuffer() const
- {
- if( m_locked > 0 )
- return null;
- if( m_Keys.Size())
- return &m_Keys[0];
- return null;
- }
- void Controls::ClearKeyBuffer()
- {
- m_Keys.DelAll();
- }
- void Controls::FreeMouse()
- {
- #ifndef _XBOX
- m_freeMouse = true;
- #endif
- }
- ////
- IControls *Controls::CreateInstance(const char *file, long line)
- {
- return NEW ControlsInstance(this,file,line);
- }
- void Controls::RegInstance(ControlsInstance *p, const char *file, long line)
- {
- InstanceInfo *info = null;
- for( int i = 0 ; i < m_inst ; i++ )
- {
- InstanceInfo *q = &m_inst[i];
- if( !q->used )
- {
- info = q; break;
- }
- }
- if( !info )
- info = &m_inst[m_inst.Add()];
- info->used = true;
- info->p = p;
- info->file = file;
- info->line = line;
- }
- void Controls::DelInstance(ControlsInstance *p)
- {
- for( int i = 0 ; i < m_inst ; i++ )
- {
- InstanceInfo *q = &m_inst[i];
- if( q->p == p )
- {
- q->used = false; break;
- }
- }
- }
- long Controls::CreateGameControl(const char* name, bool isReverse)
- {
- long idx = m_gameControls.Add( GameControl(this,name,isReverse) );
- m_tableControls.AddObj( name, idx );
- return idx;
- }
- long Controls::CreateControlFilter(const char* name, float scale, bool isReverse)
- {
- long idx = m_controlFilters.Add( ControlFilter(this,name,scale,isReverse) );
- m_tableFilters.AddObj( name, idx );
- return idx;
- }
- long Controls::CreateControlGroup(const char* name)
- {
- long idx = m_groups.Add( ControlGroup() );
- m_groups[idx].name = name;
- m_groups[idx].used = true;
- m_tableGroups.AddObj( name, idx );
- return idx;
- }
|