1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen...

23
1

Transcript of 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen...

Page 1: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

1

Page 2: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

2

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

Page 3: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

3

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.

Page 4: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

4

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:

Page 5: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

5

Spielsteuerungs-DemoprogrammZur 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.

Page 6: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

6

Globale Variablen, Definitionen, Header-Dateien und Funktionsprototypen Folgende Zeiger werden für die Arbeit mit dem DirectInput-Hauptinterface sowie mit den Tastatur-, Maus- undJoystick-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:

Page 7: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

7

Initialisierung des DirectInput-Hauptinterface

Für die Initialisierung des DirectInput-Hauptinterfacesowie der einzelnen DirectInput-Objekte verwenden wirdie Funktion InitDirectInput(). Als Parameterübergeben wir das Handle der Instanz unsererWindows-Anwendung sowie das Handle deszugehörigen Windows-Fensters.

Für die Erzeugung des DirectInput-Hauptinterface stehtdie Funktion DirectInput8Create() zur Verfügung. AlsParameter erwartet diese Funktion das Handle unsererAnwendungsinstanz hinstance,die in der Datei dinput.hdefinierte Konstante IID_IDirectInput8 sowieden Zeiger g_pDI, der nach Erzeugung des DirectInput-Hauptinterface auf dessen Speicheradresse zeigt.

Nachdem das Hauptinterface erfolgreich erzeugt wurde,werden nacheinander das Tastatur-, Maus- undJoystick-Objekt initialisiert.

Bei erfolgreicher Initialisierung gibt die Funktion denRückgabewert S_OK ,andernfalls S_FALSE zurück.

Page 8: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

8

Initialisierung eines Tastatur-ObjektsFü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.

Page 9: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

9

I Schritt

II Schritt

III Schritt

IV Schritt

Page 10: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

10

Initialisierung eines Maus-ObjektsDie 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

Page 11: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

11

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.

Page 12: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

12

Page 13: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

13

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.

Page 14: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

14

Page 15: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

15

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.

Page 16: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

16

Page 17: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

17

Abfrage der Tastatur-NachrichtenIm 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 DirectInput vordefinierten Tastatur-

Konstanten erleichtert.

Page 18: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

18

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.

Page 19: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

19

Page 20: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

20

Abfrage der Maus-Nachrichten-analog zu Abfrage der Tastatur-Nachrichten

- als Datenformat zum Zwischenspeichern der Nachrichten wird die DIMOUSESTATE2-Struktur:

Page 21: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

21

Soll bei gedrückt gehaltener Taste nur einmal auf

die Nachricht reagiert werden, verwenden wir

folgenden Code:

Page 22: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

22

Abfrage von Joystick-NachrichtenAls 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.

Page 23: 1. 2 Heute entwickeln wir eine kleine DirectInput-Bibliothek,auf die wir bei unseren zukünftigen Projekten immer wieder zurückgreifen werden. Die Themen.

23

Freigabe aller DirectInput-ObjekteDie 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.