Zachyťte své vstupy DirectInput

Rozhraní Direct Input I. díl Jedním z nejdynamičtěji se rozvíjejících oborů softwarového průmyslu je tvorba her a ...


Rozhraní Direct Input I. díl
Jedním z nejdynamičtěji se rozvíjejících oborů softwarového průmyslu je tvorba
her a multimediálních aplikací, kterých se každým rokem objeví na trhu tisíce.
Bohužel, ne všechny jsou dobré a jen malá část funguje tak, aby nadchla srdce
milionů hráčů, kteří u ní pak tráví dlouhé bezesné noci. Jedním z klíčových
prvků je i rozhraní DirectX, konkrétně část DirectInput, která obstarává
interakci s uživatelem programu a právě jí se budeme věnovat v našem dvoudílném
miniseriálu.
DirectInput (dále jen DInput) je komponenta DirectX, která je určena k ovládání
vstupních zařízení, jako je klávesnice, myš, joystick, volant apod. DInput
funguje na jiném principu než Win32 API. Zatímco Win32 API při každé změně
stavu vstupního zařízení pošle zprávu (WM_něco), při použití DInput aplikace
sama žádá o informace o změnách. To je jednak rychlejší, protože odpadá nemalá
režie systému spojená s posíláním zpráv, a navíc výhodnější, jak ukazuje
následující příklad.
Moderní hry běžně využívají hardware na maximum. Rychlost hry obvykle měříme
tak, že sledujeme počet obrázků za sekundu, které na daném počítači hra
průměrně nakreslí. Může to být 100 obrázků na rychlém počítači, ale taky méně
než 10 obrázků na pomalejším stroji. V takových situacích je stav klávesnice,
myši nebo joysticku sledován vždy po nakreslení každého snímku na obrazovku.
Čili na rychlém počítači sledujeme myš častěji, ale na pomalejším pouze málokdy.
DInput také dovoluje ovládat speciální funkce herních zařízení, jako je force
feedback apod.
Programovací jazyk
Pro práci s DirectX potřebujete programovací jazyk, který toto podporuje.
Microsoft dodává knihovny k C++, ovšem od DirectX 7 už i k Visual Basicu. My
budeme pracovat s C++, protože Basic je pro svou pomalost méně vhodný. Tabulka
ukazuje, jakou verzi DirectX podporují běžné programovací nástroje.
Nejnovější knihovny DirectX 7a SDK jsou ke stažení na adrese
www.microsoft.com/directx (balíček 130 MB, pro instalaci potřebuje 380 MB).
Co se týče operačního systému, problém je jen s Windows NT 4.0, které mají
pouze DirectX 3. Pro ostatní systémy Windows 95/98/ /2000 nabízí Microsoft
zdarma upgrade na nejnovější verzi DirectX.
DirectInput a jeho použití
Pro použití DirectInput musíte do projektu přidat soubor lib/DInput.lib.
Jelikož budeme potřebovat HINSTANCE aplikace, nemůžeme jednoduše použít
konzolovou aplikaci. Na začátku si tedy můžete ve VC++ vytvořit pomocí
příslušeného wizardu "Win32 Application". Pro testování je pochopitelně
doporučeno využít MFC nebo VCL pro vygenerování kostry aplikace, do které pouze
přidáme funkčnosti DInput. Především je třeba mít na paměti, že pro
inicializaci DInput je třeba hinstance a hwnd aplikace. Hinstance je handle
aplikace a je to první parametr funkce WinMain, hwnd je handle hlavního okna
aplikace. Získat tyto dvě hodnoty pomocí funkcí MFC či VCL by neměl být pro
zkušeného programátora problém.
#include <DInput.h>
LPDIRECTINPUT dinput;
LPDIRECTINPUTDEVICE di_keyboard,di_mouse;
LPDIRECTINPUTDEVICE2 di_joystick;
int create_device(LPDIRECTINPUT DEVICE &device, REFGUID guid, LPCDIDATAFORMAT
dataformat, HWND hwnd, DWORD cooplevel)
{
//
//pomocná funkce pro vytvoření
//DInput device HRESULT hr; //vytvoříme COM objekt
if(FAILED(hr=dinput->CreateDevice(guid,&device,0))) { msg("CreateDevice
failed",hr); return 1; //chyba } //nastavíme data format
if(FAILED(hr=device->SetDataFormat(dataformat))) { msg("SetDataFormat failed",
hr); return 1; } //nastavíme cooperative level
if(FAILED(hr=device->SetCooperativeLevel(hwnd,cooplevel)))
{ msg("SetCooperativeLevel failed",hr); return 1; }
}
int init_dinput(HINSTANCE instance, HWND hwnd) {
//
//vrací nenulové číslo při chybě
// HRESULT hr; close_dinput(); //nejprve vytvoříme hlavní DInput objekt
if(FAILED(hr=DirectInputCreate(
instance,DIRECTINPUT_VERSION,&dinput,0))) { msg("DirectInputCreate failed",hr);
return 1; //chyba není přítomno DInput } //vytvoříme objekt klávesnice
if(create_device(di_keyboard, GUID_SysKeyboard, &c_dfDIKeyboard,hwnd,
DISCL_BACKGROUND|DISCL_NONEXCLUSIVE)) return 1; //chyba //nastaví buffer
klávesnice (standardně žádný neexistuje) #define KBD_BUFSIZE 8 //velikost
bufferu klávesnice DIPROPDWORD dipdw;
dipdw.diph.dwSize=sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize=sizeof(DIPROPHEADER); dipdw.diph.dwObj=0;
dipdw.diph.dwHow=DIPH_DEVICE; dipdw.dwData=KBD_BUFSIZE;
if(FAILED(hr=di_keyboard->SetProperty(
DIPROP_BUFFERSIZE,&dipdw.diph))) { msg("keyboard->setproperty failed",hr); }
if(FAILED(hr=di_keyboard->Acquire())) { msg("keyboard->Acquire failed",hr); }
return 0; //bez chyby
}
void close_dinput() { //nejprve uvolníme zařízení DEV_RELEASE(di_keyboard);
DEV_RELEASE(di_mouse); DEV_RELEASE(di_joystick); //na závěr uvolníme Direct
//Input RELEASE(dinput);
}
V kódu je použita pomocná funkce msg(char*,int) pro výpis chybových hlášení.
Mějte na paměti, že chyby mohou nastat kdykoliv.
Funkce DirectInputCreate volaná v init_dinput provede inicializaci DInput a
předá nám pointer na hlavní objekt DInput. Tento objekt budeme používat pro
vytváření dalších objektů. Jedním z parametrů zmíněné funkce je konstanta
DIRECTINPUT_ VERSION, která určuje, že chceme používat nejnovější verzi
DirectX. Chcete-li např. používat DX3 pro kompatibilitu s Windows NT, musíte
program pozměnit takto:
#define DIRECTINPUT_VERSION 0x 300
#include <DInput.h>
Makro RELEASE je obecně používáno pro uvolnění COM objektů. Makro DEV_RELEASE
je speciální makro pro uvolňování vstupních zařízení. Před vlastním uvolněním
zařízení ještě zavolá nutnou metodu Unacquire().
#define RELEASE(p) { if(p) { p->Release(); p=0; }}
#define DEV_RELEASE(p) { if(p) { p->Unacquire(); p->Release(); p=0;}}
Režimy práce
Pomocí metody SetCooperativeLevel se nastavuje způsob práce s každým zařízením.
Specifikuje se vždy jedna z dvojice konstant DISCL_EXCLUSIVE/DISCL_NONEXCLUSIVE
a DISCL_FOREGROUND/ DISCL_BACKGROUND. Dále je možno specifikovat konstantu
DISCL_ NOWINKEY. Význam jednotlivých konstant popisuje tabulka.
Obvyklý způsob práce s klávesnicí je DISCL_FOREGROUND | DISCL_NONEXCLUSIVE. Při
DISCL_EXCLUSIVE nedochází k posílání zpráv o stisku kláves do aplikace! Podobně
to platí pro myš, čili při režimu DISCL_ EXCLUSIVE není vidět kurzor myši a
aplikace nedostává zprávy WM_ MOUSE... Toto je užitečné pro celoobrazovkové
aplikace, kdy systém stejně nedokáže kreslit kurzor myši.
Příště
Ve druhé části si ukážeme, jak se pracuje s klávesnicí a podíváme se také na
ovládání myši a joysticku.
0 1763 / alsn
Význam konstant
DISCL_EXCLUSIVEvstup pro ostatní aplikace je znemožněn (výhradní režim)
DISCL_NONEXCLUSIVEvstup pro ostatní aplikace je umožněn (sdílený režim)
DISCL_FOREGROUNDvstup pouze když je aplikace aktivní (na popředí)
DISCL_BACKGROUNDvstup běží i když je aplikace na pozadí
DISCL_NOWINKEYaplikace bude ignorovat klávesu Windows

PřekladačVerze
Visual C++ 5.0 (97)DirectX 3
C++ Builder 3DirectX 3
Visual C++ 6.0 (98)DirectX 5
C++ Builder 4DirectX 5
Zajímavé odkazyNe pro všechny je C++ ten nejoblíbenější nástroj a proto jsou
zde následující odkazy, svědčící o tom, že s DirectX se dá pracovat i v jiných
jazycích např. v Delphi:
http://www.delphi-jedi.org/DelphiGraphics/DirectX.htm
http://www.wrapx.suite.dk/
http://www.ex.ac.uk/~PMBearne/DGC.html
http://members.xoom.com/delphi_dx/
http://www.eldermage.com/index.html









Komentáře
K tomuto článku není připojena žádná diskuze, nebo byla zakázána.