Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

09.08.2009, 17:22

[gelöst]DirectInput Problem

Hallo!
Ich habe ein Problem mit der Tastaturabfrage.
Zwar werden alle Tasten korrekt abgefragt, aber wenn ich eine Taste zu lange gedrückt halte, dann ertönt dieses Ping- Geräusch (laut Systemsteuerung: "Programmereignis: 'Standardton Warnsignal'
Sound: 'Windows XP-Ping.wav' ".

Ich kann mir nicht helfen...
Zumal ich nicht weiß, ob es an irgendwelchen States (Foreground/Background,etc)oder an meinen Abfragen oder an meinem Fenster /usw.... liegt.

Ich verwende Dev-CPP, Win XP SP3

hier noch ein Code-Auszug:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bool keyState(int Key)
{
 bool bKey[256];
    HRESULT r = dKey->GetDeviceState(sizeof(bKey),&bKey);
    if(r == DIERR_INPUTLOST) dKey->Acquire(); //Zugriff verloren, versuchen wiederzuholen


    if(FAILED(r))
    {
                 //ging nicht! vermutlich Fenster nicht aktiv!

                 MessageBox(NULL,"Fehler beim Abfragen der Eingabedaten!.","OK",MB_OK|MB_ICONINFORMATION);
                 return -1;
    }  
    if(bKey[Key] & 0x80)
    return true;
    else return false;
return false;
}       

Dies ruf ich in der Main- Schleife regelmäßig auf.

hier noch die Initialisierung der Tastatur:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
     LPDIRECTINPUT8 dInput = NULL;
     LPDIRECTINPUTDEVICE8 dKey = NULL;
     LPDIRECTINPUTDEVICE8 dMouse = NULL;
     
bool initKeyboard(HINSTANCE hInst, HWND hw)
{     
if(FAILED(DirectInput8Create(hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, reinterpret_cast<LPVOID*>(&dInput), NULL)))
{
MessageBox(NULL,"IDirectInput8-Objekt konnte nicht angelegt werden!","Fehler",MB_OK|MB_ICONEXCLAMATION);
return false;
}
if (FAILED(dInput->CreateDevice(GUID_SysKeyboard, &dKey, NULL)))
{     
     MessageBox(NULL,"Tastatur konnte nicht initialisiert werden!@CreateDevice","Fehler",MB_OK|MB_ICONEXCLAMATION);
     return false;
}       
if (FAILED(dKey->SetDataFormat(&c_dfDIKeyboard)))
{
     MessageBox(NULL,"Tastatur konnte nicht initialisiert werden!@SetDataFormat","Fehler",MB_OK|MB_ICONEXCLAMATION);
     return false;
}
if (FAILED(dKey->SetCooperativeLevel(hw, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND)))
{
     MessageBox(NULL,"Tastatur konnte nicht initialisiert werden!@SetCooperativeLevel","Fehler",MB_OK|MB_ICONEXCLAMATION);
     return false;
}
    // MessageBox(NULL,"Tastatur wurde initialisiert.","OK",MB_OK|MB_ICONINFORMATION);  

     dKey->Acquire();
     return true;
}

Wenn Ihr noch mehr relevanten Code braucht, ist das ok.
Ich hoffe ihr könnt mir helfen,

Vielen Dank schon einmal,
kickerxy123

2

09.08.2009, 18:34

Hallo kickerxy123 und Willkommen im Forum!

Zunächst würde ich folgende Einstellung verwenden:

C-/C++-Quelltext

1
dKey->SetCooperativeLevel(hw, DISCL_FOREGROUND|DISCL_NONEXCLUSIVE);


Wird in der WndProc noch eine Tastatur-Nachricht bearbeitet?
Oder gibt es sonst noch irgendwelche Tastaturabfragen?

Zeig bitte mal den Aufruf von keyState aus deiner Game-Loop.
fka tm

3

10.08.2009, 00:02

Hallo, danke für dein Willkommen und die Antwort =)
Sobald ich das auf FOREGROUND umstelle springt er immer in die if(FAILED(r)) {} Schleife rein ...
So nun zu meinem Programmablauf:

C-/C++-Quelltext

1
initKeyboard(hThisInstance,hwnd);
wird in der main aufgerufen, nachdem alle Fenster erzeugt wurden.
In der Nachrichtenverwaltung (Translate und Dispatch) wird dann jedesmal

C-/C++-Quelltext

1
Render(global_time,pcmd);
aufgerufen (pcmd ist egal..)
Render sieht (stark verkürzt dann so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
bool Render(float secsPassed, string* cmd)
{
if(GetAsyncKeyState((int)steuerung.rotateX[0])) 
  {
  press_key = true;
  D3DXMatrixRotationX(&matrixRotateX,0.05f);
  }
//so habe ich es erst versucht, bin aber dann auf DirectInput gewechselt, also:

 if( keyState(DIK_ESCAPE) && g_time > 0.5)
  {
                                 
  secsPassed = 0;
  press_key = false;
}
  if(keyState(DIK_W))
  {
  camerapos.x -= trash;
  press_key = true;
  D3DXMatrixTranslation(&matrixTrans,trash,0.0f,0.0f);
  } 

//...

D3DXMatrixMultiply(&matrixView,&matrixView,&matrixRotateX);
D3DXMatrixMultiply(&matrixView,&matrixView,&matrixRotateY);
D3DXMatrixMultiply(&matrixView,&matrixView,&matrixRotateZ);
D3DXMatrixMultiply(&matrixView,&matrixView,&matrixTrans);
 pD3DDevice->SetTransform(D3DTS_VIEW, &matrixView);//(D3DMATRIX*)(&mCamera));   

Matrix mProjection = matrixProjection(fov, aspect, 0.1f, 250.0f);
pD3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)(&mProjection));
//...





pD3DDevice->BeginScene();
DWORD fvvf;
DWORD* gg = & fvvf;
 pD3DDevice->GetFVF(gg);
pD3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
pD3DDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
pD3DDevice->SetRenderState(D3DRS_ZENABLE,FALSE);
pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE,FALSE);
pD3DDevice->SetTexture(0, pSky);
pD3DDevice->SetTexture(1, NULL);
pD3DDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
pD3DDevice->LightEnable(0,FALSE);
if(FAILED(pD3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST,
                             0,
                             8,
                             12,
                             g_index_sky,
                             D3DFMT_INDEX16,
                             vertex,
                             sizeof(SVertex))))
{
        ccout("Fehler beim Zeichnen. Ungültige Vertices oder Formate?");
        writeToLog("Fehler beim Zeichnen. Ungültige Vertices oder Formate? Oder Szene wurde nicht ordnungsgemäß geöffnet/ geschlossen!", TRUE, 0);
        return false;              
}
//...



pD3DDevice->EndScene();
pD3DDevice->Present(NULL, NULL, NULL, NULL);
first_call = false;
press_key = false;
return true;
}

also ich habe im moment beides drinne... GetAsyncKeyState und meine Funktion

Mein Spiel ist leider etwas verworren... ich habe bereits 34 Dateien (.cpp und .hpp) und mehr als 5000 Zeilen Code, da verliert man/ich den Überblick.

Achja, in der WinProc wird nichts dergleichen abgefragt (keine "case WM_KEYDOWN" o.ä.)

Vielleicht liegt es ja an dem FOREGROUND, nur warum geht das denn nicht?

Naja.. ich hoffe, dass du mit meinen Angaben weiterkommst....

ansonsten sehen wir weiter ;=)
Auf jeden Fall schon einmal danke!

Mfg
kickerxy123


#edit: ich habe grade hier im Forum etwas gefunden, was vielleicht etwas weiterhilft:
https://www.spieleprogrammierer.de/phpBB…pic.php?t=11530 dort steht:

Zitat


Nachdem ich mal Winspector (ähnlich Spy++, aber kostenlos) auf mein Programm losgelassen hatte, stellte folgenden Sachverhalt (und wohl auch Grund für das Problem) fest: Es wird unmittelbar nach Tastendruck einmal WM_KEYDOWN gesendet. Hält man die Taste aber weiter durchgehend gedrückt, so fasst Windows nach dem Senden der ersten Nachricht für etwa eine halbe Sekunde alle weiteren zusammen und sendet erst nach Ablauf der halben Sekunde ein weiteres WM_KEYDOWN, bei dem dann eben (wie in der MSDN beschrieben) das untere Wort von lParam die Anzahl der zusammengefassten Nachrichten enthält. Man kann dieses Verhalten übrigens auch im Notepad beobachten, wenn man eine Taste gedrückt hält: Es wird sofort ein einzelner Buchstabe ausgegeben, dann folgt eine halbe Sekunde Pause und die weiteren Buchstaben folgen.

Und in meinem Programm ist es genauso: einmal "Ding" und dann nach ner halben Sekunde "Dauer-Ding".

4

10.08.2009, 10:09

Ding oder Beep, egal. ;)
Pufferüberlauf der Tastatur...

Du solltest dich schon für eines entscheiden.
WinApi (GetAsyncKeyState, WM_KEY... usw.) oder DirectInput.
Natürlich können beide auch in friedlicher Koexistenz leben.
Aber wie du schon sagtest, verworren - Überblick verlieren...

Warum machst du dir keinen Plan, räumst mal richtig auf?
Bei größeren Projekten ist es auch nicht schlecht, paralell ein weiteres zum Testen etc. anzulegen.
fka tm

5

10.08.2009, 14:10

Okay, ich versuche erstmal Ordnung zu schaffen ;=)

Wo liegen denn die Vor- und Nachteile von GetAsync und DirectInput?

lg
kickerxy

Das Gurke

Community-Fossil

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

6

10.08.2009, 14:16

Direct Input kann Geräte enumerieren, du könntest also mehrere Keyboards und Mäuse verwalten.

Davon mal abgesehen empfiehlt mittlerweile sogar Microsoft DirectInput nicht mehr zu nutzen (sorry, leider ohne Quelle, ich find die nicht mehr) , sondern entweder auf XInput oder die WinAPI zurückzugreifen. Mein Tipp: Vergiss XInput, der Aufwand lohnt nur wenn du mit den XBox Gamepads arbeiten willst / musst.

7

10.08.2009, 14:40

Okay, dann werde ich auf DirectInput verzichten. Mein Spiel soll keine Joystick Untersützung o.ä. haben, Maus und Tastatur reicht da vollkommen.
Außerdem ist die Verwendung von GetAsyncKeyState ja auch vollkommen problemlos und mit wenig Code verbunden!

Woher das piepen kommt ist ja nun auch klar, nur wie kann man das umgehen?^^

mfg
kickerxy123

GR-PA

Treue Seele

Beiträge: 326

Wohnort: Daheim

Beruf: Faulenzer

  • Private Nachricht senden

8

10.08.2009, 15:02

Zitat von »"Das Gurke"«

Davon mal abgesehen empfiehlt mittlerweile sogar Microsoft DirectInput nicht mehr zu nutzen

Das strimmt so nicht ganz. Microsoft empfiehlt (meines Wissens) nur, DirectInput nicht für Tastatur- und Mausabfragen zu verwenden

Zitat von »"DirectX Dokumentation März 2009"«


The DirectInput API is used to process data from a joystick, or other game controller. The use of DirectInput for keyboard and mouse input is not recommended, Windows messages should be used instead

dort steht aber auch:

Zitat

XInput is easier to use and requires less setup than DirectInput [...]
By supporting XInput only, your game will not work with legacy DirectInput devices. XInput will not recognize these devices.

=> verwende WinAPI für Maus und Tastatur, DirectInput für Joystick und XInput für XBox-Controller
Signaturen werden überbewertet

10

10.08.2009, 15:27

Amen! :)
fka tm

Werbeanzeige