Эмуляция DirectInput

Тема в разделе "WASM.DirectX", создана пользователем float, 7 авг 2010.

  1. float

    float New Member

    Публикаций:
    0
    Регистрация:
    7 янв 2010
    Сообщения:
    113
    Есть стороннее приложение, работающее на directinput(7). Мне нужно немного изменить логику работы directinput в данном приложении. Контроллеры - только клавиатура и мышь.
    Вопрос первый - по какому принципу работает dinput? На сколько я понял - он читает очередь сообщений и возвращает инфо в удобном для приложения виде?

    Вопрос второй - в данном случае лучше хукать directinput или написать эмуляцию его?
     
  2. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    float
    Нет, откуда там очередь сообщений, оно читает состояние. Что значит эмуляция DI? Напиши обёртку.
     
  3. float

    float New Member

    Публикаций:
    0
    Регистрация:
    7 янв 2010
    Сообщения:
    113
    ну dinput зачем-то постоянно вызывает PeekMessage с PM_REMOVE, т.е. из очереди сообщений главного окна извлекает сообщения.

    Насчет состояния - там в нескольких местах вызывается GetAsyncKeyState. Вот не понятно, откуда изначально он берет данные о нажатиях.

    Насчет эмуляции - я наверное все же имел в виду обертку.
     
  4. keYMax

    keYMax New Member

    Публикаций:
    0
    Регистрация:
    2 июл 2003
    Сообщения:
    276
    Адрес:
    Новоуральск
    он просто заполняет буфер состояния (значения всех клавиш в текущий момент или данные о мыши, в какую сторону ее двинули и насколько + какие клавиши нажали) и программа его должна просматривать сама в цикле или еще как.
     
  5. float

    float New Member

    Публикаций:
    0
    Регистрация:
    7 янв 2010
    Сообщения:
    113
    это то понятно, вопрос откуда эти данные берет сам динпут. Насколько я понял (совершенно не уверен в этом), он берет из очереди сообщений главного окна и читает состояние через GetAsyncKeyState
     
  6. keYMax

    keYMax New Member

    Публикаций:
    0
    Регистрация:
    2 июл 2003
    Сообщения:
    276
    Адрес:
    Новоуральск
    честно говоря уверен что вы ошибаетесь.

    на скорую руку в отладчике посмотрел он при создании девайса усилено юзает hid.dll
    а вот при вызове метода c получением данных в буфер выдает ошибку так как предполагаю что фокус уходит с окна на отладчик. Глубже пока времени нет разбираться, а так да, я тоже заинтересовался откуда он их берет.

    Знатоки поделитесь.
     
  7. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Откуда такой инфо? Берёт оттуда же откуда и винда, запрашивает у драйвера.
     
  8. keYMax

    keYMax New Member

    Публикаций:
    0
    Регистрация:
    2 июл 2003
    Сообщения:
    276
    Адрес:
    Новоуральск
    мда, не думал что директ читает WM_INPUT
    http://msdn.microsoft.com/en-us/library/ee418864
     
  9. float

    float New Member

    Публикаций:
    0
    Регистрация:
    7 янв 2010
    Сообщения:
    113
    так он с помощью PeekMessage читает WM_INPUT?
     
  10. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    keYMax
    ткни где он так делает

     
  11. sn0w

    sn0w Active Member

    Публикаций:
    0
    Регистрация:
    27 фев 2010
    Сообщения:
    956
    для имитации например нажатия клавиши для динпута8 я писал вот такой вот код.
    отправная точка - перехват вызова DirectInput8Createб где определяется таблица интерфейсов, в которой перехватывается CreateDevice в которой (в свою очередь:)) перехватывается GetDeviceState. и в обработчике выставляется бит нажатия.

    Код (Text):
    1. ULONG oldGetDeviceData;//buffered method
    2. HRESULT WINAPI xGetDeviceData(DWORD d1, DWORD d2, DWORD d3, DWORD d4, DWORD d5)
    3. {
    4.     HRESULT hr = ((HRESULT(WINAPI*)(DWORD,DWORD,DWORD,DWORD,DWORD))oldGetDeviceData)(d1,d2,d3,d4,d5);
    5.  
    6.    
    7.     return hr;
    8. }
    9.  
    10. ULONG oldGetDeviceState;//immediate method
    11. HRESULT WINAPI xGetDeviceState(DWORD d1, DWORD bufsize, DWORD lpbuf)
    12. {
    13.     HRESULT hr = ((HRESULT(WINAPI*)(DWORD,DWORD,DWORD))oldGetDeviceState)(d1,bufsize,lpbuf);
    14.  
    15.     if(!FAILED(hr)){
    16.  
    17.         char *pkbbuf = (char*)lpbuf;
    18.         pkbbuf[0x3B] = pkbbuf[0x3B] | 0x80;
    19.            
    20.     }
    21.    
    22.     return hr;
    23. }
    24.  
    25.  
    26. ULONG oldCreateDevice;
    27. HRESULT WINAPI xCreateDevice(DWORD d1, DWORD d2, DWORD d3, DWORD d4)
    28. {
    29.     HRESULT hr = ((HRESULT(WINAPI*)(DWORD,DWORD,DWORD,DWORD))oldCreateDevice)(d1,d2,d3,d4);
    30.  
    31.     // hook only if keyboard requested
    32.     if(*(DWORD*)d2 != GUID_SysKeyboard)
    33.         return hr;
    34.    
    35.     DWORD dwKeybTable = *(DWORD*)(*(DWORD*)d3);
    36.  
    37.     DWORD oldprot;
    38.     VirtualProtect((LPVOID)dwKeybTable, 0x2C, PAGE_EXECUTE_READWRITE, &oldprot);
    39.  
    40.     // already hooked?
    41.     if((DWORD)xGetDeviceState == *((DWORD*)(dwKeybTable+0x24))) goto ex1;
    42.     // hook it!
    43.     oldGetDeviceState = *((DWORD*)(dwKeybTable+0x24));
    44.     *((DWORD*)(dwKeybTable+0x24)) = (DWORD)xGetDeviceState;
    45.  
    46. ex1:
    47.     // already hooked?
    48.     if((DWORD)xGetDeviceData == *((DWORD*)(dwKeybTable+0x28))) goto ex2;
    49.     // hook it!
    50.     oldGetDeviceData = *((DWORD*)(dwKeybTable+0x28));
    51.     *((DWORD*)(dwKeybTable+0x28)) = (DWORD)xGetDeviceData;
    52.  
    53. ex2:
    54.  
    55.     return hr;
    56.  
    57. }
    58.  
    59.  
    60. ULONG oldDirectInput8Create;
    61. HRESULT WINAPI xDirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, VOID **ppvOut, LPUNKNOWN punkOuter)
    62. {
    63.     HRESULT ret = ((HRESULT(WINAPI*)(HINSTANCE,DWORD,REFIID,VOID**,LPUNKNOWN))oldDirectInput8Create)(hinst,dwVersion,riidltf,ppvOut,punkOuter);
    64.  
    65.     DWORD dwFuncTable = (DWORD)*((DWORD*)*ppvOut);
    66.  
    67.     DWORD oldprot;
    68.     VirtualProtect((LPVOID)dwFuncTable, 0x10, PAGE_EXECUTE_READWRITE, &oldprot);
    69.    
    70.     //already hooked?
    71.     if((DWORD)xCreateDevice == *((DWORD*)(dwFuncTable+0x0c))) goto ex;
    72.     //hook it
    73.     oldCreateDevice = *((DWORD*)(dwFuncTable+0x0c));
    74.     *((DWORD*)(dwFuncTable+0x0c)) = (DWORD)xCreateDevice;
    75.  
    76. ex:
    77.     return ret;
    78. }