DInput: physisch gleiche Devices erkennen



  • Ich versuche mich gerade an einen universellen Wrapper für DInput, mit dem man auf alle Eingabegeräte über die gleiche Schnittstelle zugreifen kann. Also gehe ich her und enumeriere mir alle Devices und dann alle DeviceObjects. Soweit funktioniert es auch. Nur gibts das Problem, das meine Maus zweimal auftaucht, einmal als "Mouse" und einmal als "USB Microsoft blabla". Nun würde es mich ja nicht stören, diese paar Byte immer zusätzlich von der Hardware auszulesen und den Status der Maus zweimal abzuspeichern, aber da ist noch ein anderes Problem:

    Wenn man damit einen Konfigurationsmanager schreibt, wird es schief gehen! Wenn ich dem User sage "Drücke bitte eine Taste" und dann warte was passiert, werden beide Devices (sie sind ja physisch die gleiche Maus!) den Mausklick melden, und eines wird einen Tick schneller sein. Dieses wird dann als Eingabegerät angenommen. Dann ist es natürlich nicht nachvollziehbar, warum einmal ein Klick der "USB Maus" und einmal der von der "Mouse" erkannt wird und dann in der Liste mit den Konfigurationen das ein und dasselbe Gerät ständig anders heisst. Also: Kann ich erkennen, das zwei Devices physisch das gleiche Gerät sind?

    Ich nehme an, das man ähnliche Probleme bei USB Keyboards und vielleicht noch Anderem hat, also wäre eine universelle Lösung angebracht. Die GUID's der Devices sind unterschiedlich. Eigenschaften vergleichen möchte ich auch nicht, so wird dann von zwei baugleichen Gamepads evtl. nur eins erkannt. Ein Workaround wäre evtl. nach dem ersten Erkennen einer Eingabe noch 25 ms zu warten um weitere Eingaben aufzunehmen, danach wird dann die Eingabe, die in der Liste der DeviceObjects am weitesten vorn steht, gewählt. So müssten alle Eingaben der "ersten" Maus genommen werden, da diese in der Liste grundsätzlich alle weiter vorn liegen.

    Bye, TGGC



  • Keiner eine Idee oder Frage zu unverständlich? (Was will'n der TGGC schonewieder? ******! 😉



  • Wie genau listest Du die Eingabegerät auf?
    Es gibt da ein Flag namens DIEDFL_INCLUDEALIASES, hast Du das vielleicht angegeben?



  • In der Art:

    m_pDI->EnumDevices(  DI8DEVCLASS_ALL, 
                            EnumCallback,
                            this, 
                            DIEDFL_ATTACHEDONLY );
    

    Und auch in den Caps ist keines dieser Flags ("Phantom" gibts wohl auch noch) gesetzt.



  • Ich weiß nicht obs funktioniert, aber:
    du hast ja geschrieben, dass die Guids unterschiedlich sind. deshalb nehm ich einfach einmal an, dass du bei der auflistung der Mäuse zuerst die SystemMouse und dann die USB Microsoft bla bla auflistest.
    Vergleich einmal die Guid der Mäuse mit GUID_SysMouse und lösch die, wo's übereinstimmt. (dann hast du nur mehr eine)
    Weiß nicht, obs dir weiterhilft, war nur so ein Gedanke.



  • Und was passiert, wenn jemand nur eine (nämlich die Systemmaus) hat? Der kann dann ja garnix mehr mit Maus machen.



  • Du könntest die Geräteliste auch auf ein einziges Gerät der Klasse DI8DEVTYPE_MOUSE bzw. DI8DEVTYPE_SCREENPOINTER beschränken. Gleiches mit dem Gerätetyp DI8DEVTYPE_KEYBOARD. Wer schließt denn schon zwei Zeigegeräte an, mit denen man spielen möchte, oder zwei Keyboards?



  • Warum zählst du die Mäuse 😃

    Normalerweise hat jeder mindestens eine Maus. Die Systemmaus. Nimmt halt nur diese. Bei einem Joystick vestehe ich das ja, aber bei einer Maus ?!



  • Das soll eine allgemeine Klasse sein, die beliebig Geräte unterstützen kann. Darum ist eine Annahme ala "Ach, da ist ehh nur eine Maus" für mich unsinnig. Dann hat man nachher nur Ärger, wenn man doch zwei Mäuse hat. Ich möchte für möglichst alle Eventualitäten gerüstet sein.

    Und wer z.B. an einem Laptop spielt, will vielleicht wirklich nicht die "Systemmaus" (=Touchpad) benutzen, um nur mal einen (irrelevanten) Grund zu nennen.



  • Gut, dann bring' doch beim Konfigurieren der Steuerung eine Meldung wie: "Achtung! Ihr Tastendruck wurde auf zwei Geräten erkannt. Bitte wählen Sie aus, welches davon verwendet werden soll: [Liste der Geräte]". Das, was nicht verwendet werden soll, wird dann einfach aus der Liste gelöscht oder eben ignoriert.
    Das soll natürlich nur passieren, wenn der User beim Konfigurieren der Steuerung einen Knopf drückt, und dieser auf zwei DirectInput-Geräten registriert wird.



  • Im Fall vom Laptop sind es tatsächlich zwei Mäuse. Da müsste doch dein Wrapper richtig funktionieren. Am Computer zu Hause erkennt der Wrapper zwei Mäuse und benutzt die nächst Mögliche. Was ja kein Beinbruch ist, weil in real es nur eine Maus ist.

    Naja sind nur ein paar Gedanken. Vielleicht bringen sie dir was.



  • Original erstellt von <Gast>:
    Am Computer zu Hause erkennt der Wrapper zwei Mäuse und benutzt die nächst Mögliche. Was ja kein Beinbruch ist, weil in real es nur eine Maus ist.

    Aber die "nächstmögliche" ist eben immer eine "andere". Vielleicht brauch ich wirklich sowas, wie Tomas vorschlägt. Das bedeutet aber trotzdem unnötigen Aufwand, da man nach dem ersten Drücken noch einen Moment warten muss, ob noch woanders was registriert wird. Und ich fürchte auch öfters "Fehlalarme", wie eine Achse leicht bewegt. Aber wenns keine Möglichkeit gibt, das sicher festzustellen, brauchts wohl doch so'n "Hack".



  • Ich denke mal, dass ein Fehlalarm sehr unwahrscheinlich ist. Denn beide Geräte müssten ja bei DirectInput auch exakt dieselben Werte liefern, oder? Und bei Mäusen und Joysticks sind diese Werte ja immer so, dass man sie kaum mal durch Zufall erreichen kann.



  • Ich denke z.b. an einen Tastendruck, wo man ausversehen 2 Tasten erwischt. Maus schräg bewegen ist evtl. auch drin. Wasserdicht ist das also keinesfalls.



  • Verstehe ich nicht. Es ist doch egal, wie viele Knöpfe Du auf dem Gerät drückst. Hauptsache ist, dass der Wrapper merkt: Aha, auf dem Gerät X werden Knöpfe A, B und C gedrückt und die Achse D ist auf dem Wert 1481, und auf dem Gerät Y ist es genauso!



  • Könntest du nicht am Anfang irgendwie nen Test machen, und wenn sich bei einem simulierten Tastendruck mehr als ein Gerät meldet, dass du dann die anderen löschst?



  • Aber wie simuliert man eine Joystickbewegung?



  • Man könnte ja den benutzer auffordern alle Tasten/Bewegungen aller Eingabegeräte zu drücken/zu machen ;P



  • Also den Benutzer auffordern mal eben alles zu drücken ist ja wohl etwas umständlich!

    Original erstellt von DasPinsch:
    Könntest du nicht am Anfang irgendwie nen Test machen

    Eben, irgendsoetwas würde ich gerne tun. Wenn ich die DeviceObjekte gleich beim Init rausschmeisse, brauch ich mich später nirgendswo mehr drum zu kümmern. Irgendwelcher Code für 2 Tasten gleichzeitig fällt dann komplett flach. Wie man aber deinen speziellen Vorschlag nun genau umsetzen soll, weiss ich nicht. Habe noch nie bei DI eine Eingabe simuliert und wüsste auch nicht, wie das gehen soll.

    Werde wohl doch speziellen Code schreiben müssen, um diesen Fall immer zu umgehen.

    Bye, TGGC


Anmelden zum Antworten