.[ ČeskéHry.cz ].
WM_INPUT a balistika kurzoru myši

 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> Obecné
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
Crypton



Založen: 14. 05. 2009
Příspěvky: 306
Bydliště: The Void

PříspěvekZaslal: 16. prosinec 2011, 16:27:46    Předmět: WM_INPUT a balistika kurzoru myši Odpovědět s citátem

Zdravím,

věděl by někdo jak nasimulovat balistiku kurzoru myši ve Windows? Přes WndProc totiž dostávám zprávu WM_INPUT, a získávám "hrubou" pozici myši (přes funkci GetRawInputData), tedy bez transformací.

Zkouším teď emulovat DirectInput (a DirectDraw), a potřeboval bych, aby ten pohyb by stejně "rychlý" jako ve Windows. Můj problém je právě ten, že se mi kurzor ve hře pohybuje jinou rychlostí než ve Windows.

Našel jsem tyto odkazy:
MSDN: Pointer Ballistics for Windows XP
MSDN: Taking Advantage of High-Definition Mouse Movement

Pokud jsem to pochopil správně, tak ta pozice co dostávám je transformovaná podle toho prvního vzorce v tom prvním odkaze, takže by mělo jen stačit dokončit tu transformaci podle toho druhého vzorce.

Zkouším tu rychlost vypočítat takto...
kód:
fCursorXVel = ((FLOAT(dm.dmDisplayFrequency) / ::GetDeviceCaps(hDC, LOGPIXELSX)));
fCursorYVel = ((FLOAT(dm.dmDisplayFrequency) / ::GetDeviceCaps(hDC, LOGPIXELSY)));


..a pak transformovat tu pozici ve WM_INPUT takto:
kód:

POINT& pCursorPos = directDraw->m_pCursorPos;

if ((rawMouse.usFlags & MOUSE_MOVE_RELATIVE) == MOUSE_MOVE_RELATIVE)
{
   if (rawMouse.lLastX != 0)
      pCursorPos.x += INT((FLOAT(rawMouse.lLastX) * fCursorXVel) /*+ 0.5f*/);

   if (rawMouse.lLastY != 0)
      pCursorPos.y += INT((FLOAT(rawMouse.lLastY) * fCursorYVel) /*+ 0.5f*/);
}
else if ((rawMouse.usFlags & MOUSE_MOVE_ABSOLUTE) == MOUSE_MOVE_ABSOLUTE)
{
   POINT& pWindowCenter = directDraw->m_pWindowCenter;
   pCursorPos.x = pWindowCenter.x + rawMouse.lLastX;
   pCursorPos.y = pWindowCenter.y + rawMouse.lLastY;
}


Věděl by si s tím někdo rady? Zkoušel to už někdo? Rolling Eyes
_________________
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Al



Založen: 23. 10. 2007
Příspěvky: 196

PříspěvekZaslal: 17. prosinec 2011, 00:01:49    Předmět: Odpovědět s citátem

Zkoušel jsi stackoverflow?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Crypton



Založen: 14. 05. 2009
Příspěvky: 306
Bydliště: The Void

PříspěvekZaslal: 17. prosinec 2011, 06:31:41    Předmět: Odpovědět s citátem

Al napsal:
Zkoušel jsi stackoverflow?

Tam jsem se zatím nezkoušel zeptat, hledal jsem ale hodiny přes google a nic k tomu jsem právě nenašel, zdá se že nikdo se nesnaží zachovávat stejnou rychlost, a rovnou používají ty hrubé data. Sad
_________________
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Mnemonic



Založen: 28. 07. 2007
Příspěvky: 93

PříspěvekZaslal: 17. prosinec 2011, 13:55:39    Předmět: Odpovědět s citátem

No a nedosáhneš stejného efektu použitím WM_MOUSEMOVE?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Crypton



Založen: 14. 05. 2009
Příspěvky: 306
Bydliště: The Void

PříspěvekZaslal: 17. prosinec 2011, 14:33:33    Předmět: Odpovědět s citátem

Mnemonic napsal:
No a nedosáhneš stejného efektu použitím WM_MOUSEMOVE?


Právě že zprávu WM_MOUSEMOVE vůbec nedostávám, a když už jí náhodou dostanu, tak je pořád stejná, tj. ukazuje na střed okna.

Způsobuje to právě DirectInput, který si ty zprávy odchytává na nižší úrovni, a jediný způsob jak přinutit Windows předávávat zprávy o uživatelském vstupu hostující aplikaci, je právě přes RegisterRawInputDevices. (Funkce SetWindowsHookEx nepřipadá v úvahu...)
_________________
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Crypton



Založen: 14. 05. 2009
Příspěvky: 306
Bydliště: The Void

PříspěvekZaslal: 18. prosinec 2011, 11:20:47    Předmět: Odpovědět s citátem

Vypadá to, že musím akumulovat tu pozici včetně toho zbytku po "dělení", takže bych měl zřejmě ukládat tu pozici do floatu. V tom prvním odkaze se zmiňují že Windows použivá datový typ s fixní desetinnou čárkou, takže to tam určitě taky akumulují.

Edit: Tak jsem upravil ten kód tak aby se nikde nic nezaokrouhlovalo, a ta rychlost kurzoru je teď hodně podobná té ve Windows, ale stále to není ono.

V tom vzorci buď něco chybí, a nebo nedostávám všechny zprávy WM_INPUT, těžko říct... Rolling Eyes
_________________
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
if.then



Založen: 13. 04. 2008
Příspěvky: 579

PříspěvekZaslal: 18. prosinec 2011, 15:49:39    Předmět: Re: WM_INPUT a balistika kurzoru myši Odpovědět s citátem

Crypton napsal:
Pokud jsem to pochopil správně, tak ta pozice co dostávám je transformovaná podle toho prvního vzorce v tom prvním odkaze, takže by mělo jen stačit dokončit tu transformaci podle toho druhého vzorce.


citace:
The disadvantage is that WM_INPUT has no ballistics applied to its data, so if you want to drive a cursor with this data, extra effort will be required to make the cursor behave like it does in Windows. For more information about applying pointer ballistics, see Pointer Ballistics for Windows XP


citace:
Internally, DirectInput creates a second thread to read WM_INPUT data, and using the DirectInput APIs will add more overhead than simply reading WM_INPUT directly. Overall, using DirectInput offers no advantages when reading data from mouse or keyboard devices, and the use of DirectInput in these scenarios is discouraged.


Tudíž DirectInput je jenom obalení WM_INPUT a potřebuješ aplikovat nastavení popsaná v tvém prvním odkaze.
_________________
For guns and glory, go to www.ceske-hry.cz.
For work and worry, execute VC++.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Mnemonic



Založen: 28. 07. 2007
Příspěvky: 93

PříspěvekZaslal: 18. prosinec 2011, 16:12:12    Předmět: Odpovědět s citátem

Otázka je, proč teda vůbec používat pro myš DirectInput, když stejně ta surová data chceš přepočítat na to, co vrací WinAPI.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Crypton



Založen: 14. 05. 2009
Příspěvky: 306
Bydliště: The Void

PříspěvekZaslal: 18. prosinec 2011, 16:46:38    Předmět: Re: WM_INPUT a balistika kurzoru myši Odpovědět s citátem

if.then napsal:
Tudíž DirectInput je jenom obalení WM_INPUT a potřebuješ aplikovat nastavení popsaná v tvém prvním odkaze.

To já ale přeci už vím Wink Potřebuju s tím ale trochu pomoct s těmi výpočty...

[url="Mnemonic"]Otázka je, proč teda vůbec používat pro myš DirectInput, když stejně ta surová data chceš přepočítat na to, co vrací WinAPI.[/url]
Už jsem to psal v prvním postu: Snažím se emulovat DirectDraw.

Píšu svou vlastní implementaci knihovny DirectDraw (ddraw.dll), která nahrazuje tu původní, ale místo DirectX používá OpenGL.

Hookuju funkci WndProc hostitelské aplikace, takže můžu zpracovávat i zprávy o uživatelském vstupu (myš, klávesnice).

Problém je v tom, že některé hry používají DirectInput, který si ty zprávy odchytává na nižší úrovní, a do funkce WndProc je už nepřeposílá, a jak už jsem zmínil, "jediný" způsob jak přinutit Windows posílat ty zprávy o vstupu té funkci WndProc, je zaregistrováním vstupního zařízení přes funkci RegisterRawInputDevices.

No a "moje" rychlost pohybu kurzoru je jiná než ta u DirectInput, vím to protože se v testované hře vykresluje ten původní kurzor na pozici získané z DirectInput, a přes to pak vykresluju já svůj vlastní kurzor, který má pozici určenou z WM_INPUT, takže poznám kdy ty rychlosti budou zcela totožné.

Nechci zatím "plně" emulovat DirectInput, hlavně protože se chci věnovat implementaci DirectDraw (a taky se mi nechce smolit s force feedback, a těmi effekty).

Twisted Evil
_________________
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 18. prosinec 2011, 17:03:43    Předmět: Odpovědět s citátem

Daleko snažší implementace se dá udělat pomocí GetCursorPos a SetCursorPos.
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Crypton



Založen: 14. 05. 2009
Příspěvky: 306
Bydliště: The Void

PříspěvekZaslal: 18. prosinec 2011, 17:28:21    Předmět: Odpovědět s citátem

Marek napsal:
Daleko snažší implementace se dá udělat pomocí GetCursorPos a SetCursorPos.

To jsem zkoušel, dokonce jako první možnost, ale GetCursorPos taky vrací pořád tu stejnou pozici - již ten zmíněný střed okna. Rolling Eyes
_________________
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 19. prosinec 2011, 01:42:26    Předmět: Odpovědět s citátem

Samozřejmě ale bez zachytávání WM zpráv a bez DirectInput.
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Crypton



Založen: 14. 05. 2009
Příspěvky: 306
Bydliště: The Void

PříspěvekZaslal: 19. prosinec 2011, 04:04:29    Předmět: Odpovědět s citátem

Tak jsem to nakonec vyřešil přes hook té knihovny (dinput.dll), a to přímo z té mojí kníhovny (ddraw.dll).

Problém byl v tom, že ty hry běží ve fullscreenu, a nastavují si pomocí DirectInput přes metodu SetCooperativeLevel exkluzivní mód (vlajka DISCL_EXCLUSIVE), při kterém:
citace:
"If the system mouse is acquired in exclusive mode, the pointer is removed from the screen until the device is unacquired. This applies only to a mouse created by passing GUID_SysMouse to IDirectInput8::CreateDevice."


Takže ten kurzor není jen skrytý, ale rovnou odstraněný... a proto mi to pořád ukazovalo pozici na střed obrazovky.

No mělo by mi jen stačit hookovat tu metodu, a hlídat si tu vlajku DISCL_EXCLUSIVE, ale když už to hookuju, tak se na WM_INPUT asi úplně vykašlu. (Mordoval jsem se ale s tím dlouho, hlavně s hookem IAT, a virtuálních tabulek těch rozhraní...)

Stále by mě ale zajímalo jak by ten algoritmus měl správně vypadat... Twisted Evil
_________________
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
micky



Založen: 28. 02. 2008
Příspěvky: 348
Bydliště: Plzeň, Praha

PříspěvekZaslal: 19. prosinec 2011, 14:41:28    Předmět: Odpovědět s citátem

Kdysi jsem četl v internetovém magazínu s pochybným názvem Hakin9 článek o rekonstrukci pohybu kurzoru bezdrátové myši na základě odposlechu. Pro linux dokázali udělat skutečně téměř 1:1, pro Windows to přesně nedokázali. (Ale i tak se dalo odposlechnout leccos Smile )
_________________
https://www.bluepulsar.cz/
https://twitter.com/11thDream_Game/
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> Obecné Časy uváděny v GMT + 1 hodina
Strana 1 z 1

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna