1 / 23

Verwendung der DirectInput-Bibliothek (1)

Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen heute: Initialisierung von DirectInput Initialisierung von Maus, Tastatur und Joystick Abfrage der Maus-, Tastatur- und Joystickdaten.

callie
Download Presentation

Verwendung der DirectInput-Bibliothek (1)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen heute: • Initialisierung von DirectInput • Initialisierung von Maus, Tastatur und Joystick • Abfrage der Maus-, Tastatur- und Joystickdaten

  2. Verwendung der DirectInput-Bibliothek (1) Am heutigen Tag werden wir ein einfaches Demoprogramm schreiben, in dem der Umgang mit DirectInput demonstriert wird. In diesem Zusammenhang werden wir eine einfache DirectInput-Bibliothek schreiben, welche in der Datei GiveInput.h implementiert ist. Um diese Datei nutzen zu können, muss die Datei in das entsprechende Projekt mit eingebunden und die folgende Initialisierungsfunktion aufgerufen werden: InitDirectInput (hinstance_app,main_window_handle); Diese Funktion übernimmt neben der eigentlichen Initialisierung von DirectInput auch die Initialisierung eines Tastatur-, Maus- und Joystick-Objekts. Der Aufruf erfolgt aus der Funktion GameInitialisierungsRoutine() heraus. Bei unseren Projekten werden wir die DirectInput Bibliothek immer in die Datei Space3D.h einbinden. // Standard-Includes //----------------------------------------------------------------------------- #include <io.h> #include <stdio.h> #include "d3dutil.h" #include "d3dfont.h" #include "dxutil.h" #include "DXSubstitutions.h" #include "GameExternals.h" #include "D3DGlobals.h" #include "CoolMath.h" #include "tempGlobals.h" #include "TextureClasses.h" #include "GameGlobals.h" #include "VertexFormats.h" #include "BillboardFunctions.h" //----------------------------------------------------------------------------- // Funktionsprototypen //----------------------------------------------------------------------------- void InitSpieleinstellungen(void); void CleanUpD3D(void); void InitD3D(void); void Init_View_and_Projection_Matrix(void); void Show_3D_Scenario(void); //----------------------------------------------------------------------------- // zusätzliche Includes //----------------------------------------------------------------------------- //Die Datei GiveInput.h sollte immer als #include "GiveInput.h" //letztes mit eingebunden werden. So //muss man alle für die Spielsteuerung //benötigten globalen Variablen nicht als //externe Variable deklarieren.

  3. Verwendung der DirectInput-Bibliothek (2) Bei Programmende muss die Funktion FreeDirectInput() aufgerufen werden, die dann alle Aufräumarbeiten erledigt. Der Aufruf erfolgt aus der Funktion GameCleanUpRoutine() heraus. Die Funktionen void ReadImmediateDataKeyboard(void); void ReadImmediateMouse(void); void ReadImmediateJoystick(void); werden zur Abfrage der ungepufferten Tastatur-, Maus- und Joystick-Eingaben verwendet. Ihr Aufruf erfolgt aus der Funktion GameMainRoutine() (die Game-Loop) heraus. Da alle Funktionalitäten der DirectInput-Bibliothek aus den in GameRoutines.cpp definierten Funktionen heraus aufgerufen werden, müssen die Bibliotheksfunktionen in der Datei GameRoutines.h als externe Funktionen deklariert werden:

  4. Spielsteuerungs-Demoprogramm Zur Demonstration der Arbeitsweise unserer DirectInput-Bibliothek werden wir ein kleines Programm schreiben, in dem Maus-, Tastatur- und Joystick-Nachrichten entgegengenommen und auf dem Bildschirm angezeigt werden. Die Tastatur-Nachrichten werden in eine Zeichenkettenvariable geschrieben und angezeigt. Bei gedrückt gehaltener Taste wird nur einmal auf die Nachricht reagiert.

  5. Globale Variablen, Definitionen, Header-Dateien und Funktionsprototypen Folgende Zeiger werden für die Arbeit mit dem DirectInput-Hauptinterface sowie mit den Tastatur-, Maus- und Joystick-Objekten verwendet: Weitere Variablen: DIDEVCAPS g_diDevCaps; // Eigenschaften der verwendeten Eingabegeräte HRESULT hr; // Rückgabewert der Initialisierung (S_OK/S_FALSE) static char buffer[256]; // Puffer für Tastatureingaben,256 Tasten DIMOUSESTATE2 dims2; // Datenformat für die Mause-Nachrichten DIJOYSTATE2 js; // Datenformat für die Joystick-Nachrichten Folgende Variablen werden für die Behandlung von Tastatur- Funktionsprototypen: Nachrichten verwendet, unter der Annahme, dass bei gedrückt Gehaltener Taste nur einmal auf die Nachricht reagiert wird:

  6. Initialisierung des DirectInput-Hauptinterface Für die Initialisierung des DirectInput-Hauptinterface sowie der einzelnen DirectInput-Objekte verwenden wir die Funktion InitDirectInput(). Als Parameter übergeben wir das Handle der Instanz unserer Windows-Anwendung sowie das Handle des zugehörigen Windows-Fensters. Für die Erzeugung des DirectInput-Hauptinterface steht die Funktion DirectInput8Create() zur Verfügung. Als Parameter erwartet diese Funktion das Handle unserer Anwendungsinstanz hinstance,die in der Datei dinput.h definierte Konstante IID_IDirectInput8 sowie den Zeiger g_pDI, der nach Erzeugung des DirectInput- Hauptinterface auf dessen Speicheradresse zeigt. Nachdem das Hauptinterface erfolgreich erzeugt wurde, werden nacheinander das Tastatur-, Maus- und Joystick-Objekt initialisiert. Bei erfolgreicher Initialisierung gibt die Funktion den Rückgabewert S_OK ,andernfalls S_FALSE zurück.

  7. Initialisierung eines Tastatur-Objekts Für die Initialisierung des Tastatur-Objekts sind vier Schritte erforderlich: I Schritt: Tastatur-Objekt erzeugen II Schritt: Datenformat festlegen III Schritt: Zugriffsrecht festlegen IV Schritt: Gerät akquirieren Im ersten Schritt wird mittels der DirectInput-Methode CreateDevice() das Tastatur-Objekt erzeugt. Als Parameter werden übergeben den Guid des zu erzeugenden Geräts und einen Zeiger, der nach erfolgreicher Initialisierung auf die Speicheradresse des Keyboard-Objekts zeigt. Der dritte Parameter ist nicht von Bedeutung und wird auf Null gesetzt. Im zweiten Schritt muss das Datenformat festgelegt werden, in welchen die empfangenen Daten zurückgegeben werden. Im dritten Schritt muss das Zugriffsrecht auf das Gerät festgelegt werden. In unserem Beispiel verfügt DirectInput über ein nichtexklusives Zugriffsrecht auf die Tastatur, wenn die Anwendung gerade aktiv ist. Die Anwendung wird über das Handle des Windows-Fensters identifiziert. Im vierten Schritt muss die Tastatur akquiriert werden, d.h. DirectInputübernimmt den Zugriff.

  8. I Schritt II Schritt III Schritt IV Schritt

  9. Initialisierung eines Maus-Objekts Die Initialisierung des Maus-Objekts verläuft analog zur Initialisierung des Tastatur-Objekts: I Schritt: Maus-Objekt erzeugen II Schritt: Datenformat festlegen III Schritt: Zugriffsrecht festlegen IV Schritt: Gerät akquirieren

  10. Initialisierung eines Joystick-Objektes Hierbei handelt es sich nicht um ein Standartgerät, deswegen ist mehr Arbeit erforderlich. Aus diesem Grund schreiben wir erst einmal zwei Callback-Funktionen, die uns bei der Initialisierung behilflich sein werden. Die erste Funktion EnumJoysticksCallback () initialisiert den ersten gefundenen Joystick. Bei einem Fehlschlag wird die Funktion zum zweiten Mal aufgerufen und versucht den zweiten Joystick zu initialisieren. Dies wird so lange wiederholt, bis keine weiteren Joysticks mehr gefunden werden.

  11. Die zweite Callback-Funktion EnumAxesCallback() hat die Aufgabe, joystickspezifische Eigenschaften der Achsen sowie deren Wertebereiche festzulegen. In unserem Beispiel wird den Achsen ein Wertebereich von -1000 bis +1000 zugeordnet. Hierzu wird eine Struktur vom Typ DIPROPRANGE benötigt. Weiterhin wird überprüft, ob der Joystick eine x- bzw. y-Achse hat. Wenn das der Fall ist, werden die Variablen JoystickXAxis bzw.JoystickYAxis auf TRUE gesetzt, was zur Folge hat, dass die jeweiligen Achsen-Informationen angezeigt werden.

  12. Die Initialisierung des Joysticks läuft vom Prinzip her genauso wie die der Standartgeräte. Im ersten Schritt wird zur Initialisierung des Joystick-Objekts nun aber die Callback-Funktion EnumJoysticksCallback() durch die DirectInput-Hauptinterface-Methode EnumDevices() aufgerufen. Im zweiten und dritten Schritt werden das Zugriffsrecht sowie das verwendete Datenformat festgelegt . Im vierten Schritt werden die joystickspezifischen Eigenschaften der Achsen sowie deren Bereiche festgelegt. Zu diesem Zweck wird jetzt die Callback-Funktion EnumAxesCallback() durch die DirectInput Hauptinterface- Methode EnumObjects() aufgerufen. Zum Schluss wird der Joystick akquiriert.

  13. Abfrage der Tastatur-Nachrichten Im ersten Schritt bei der Tastatur-Abfrage wird die Methode GetDeviceState() aufgerufen. Wenn dieser Aufruf fehlschlägt, das Tastatur-Objekt aber erfolgreich initialisiert wurde, hat DirectInput den Eingabefokus verloren und die Tastatur muss erneut akquiriert werden. Um den Status der 256 Tasten einer Tastatur abfragen zu können, hatten wir bereits einen Tastaturpuffer angelegt: static char buffer[256]. Der Umgang mit diesem Puffer wird uns durch die Verwendung der in DirectInputvordefinierten Tastatur- Konstanten erleichtert.

  14. Abfrage des Tastenzustands mit Hilfe der Tastatur-Konstanten und des bereits definierten Makros zur Behandlung von Tastatur-Nachrichten: Wenn bei gedrückten Taste nur einmal auf die Nachricht reagiert werden soll: Wenn die Taste A gedrückt wird und PressSameKeyA gleich FALSE ist, wird die betreffende Aktion ausgeführt und PressSameKeyA auf TRUE gesetzt. Dadurch wird das erneute Ausführen der Aktion so lange verhindert, bis PressSameKeyA wieder gleich FALSE ist.

  15. Abfrage der Maus-Nachrichten -analog zu Abfrage der Tastatur-Nachrichten - als Datenformat zum Zwischenspeichern der Nachrichten wird die DIMOUSESTATE2-Struktur:

  16. Soll bei gedrückt gehaltener Taste nur einmal auf die Nachricht reagiert werden, verwenden wir folgenden Code:

  17. Abfrage von Joystick-Nachrichten Als Datenformat zum Zwischenspeichern der Joystick-Nachrichten verwenden wir die DIJOYSTATE2-Struktur. Im Zusammenhang mit der Nachrichten-Abfrage lernen wir das so genannte Polling kennen. Polling bedeutet, ein Gerät in regelmäßigen Abständen nach seinem Zustand abzufragen. Mit der Methode Poll() werden die neuen Daten explizit aufgefordert. Falls der Aufruf fehlschlägt, das Joystick-Objekt aber erfolgreich initialisiert wurde, muss das Gerät neu akquiriert werden.

  18. Freigabe aller DirectInput-Objekte Die Freigabe aller DirectInput-Objekte übernimmt die Funktion FreeDirectInput(). Im ersten Schritt wird der Zugriff auf Tastatur, Maus und Joystick beendet, im Anschluss daran werden alle DirectInput-Objekte wieder freigegeben.

More Related