XBOX/Gamepad Controller

Antworten
bastler
Beiträge: 10
Registriert: Sa 30. Jan 2016, 15:54

XBOX/Gamepad Controller

Beitrag von bastler »

Hallo,

ich habe wenig Programmier-Erfahrung. Ich würde gerne in meinem Programm unter Win10 ein Gamepad abfragen. Das Gamepad kann ich an der hardwareseitig so umschalten, dass es als normales Standard-Gamepad oder als XBOX-Controller von Windows erkannt wird. Was ich nun davon verende ist egal, Hauptsache es würde gehen. Habe schon einen Tag versucht was aus dem Netz zu finden. Hatte schon das dspack (https://code.google.com/archive/p/dspack/source) runtergeladen, jedoch kommt dann die Fehlermeldung, dass die DXTypes.pas ein unerwartetes Ende hat. Habt ihr noch andere Ideen oder wisst ihr was an dem Packet nicht stimmen könnte?

Würde natürlich als Anfänger eine einfache Variante bevorzugen.

Vielen Dank für die Antwort!

Der bastler

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6209
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: XBOX/Gamepad Controller

Beitrag von af0815 »

Ich bin mir nicht sicher, aber 2010 war von Windows 10 keine Rede. Zusätzlich finde ich keinen hinweis, das das kompatibel mit Lazarus bzw. Fpc ist. Delphi 5,6,7 findet man. Ausserdem ist das Paket sechs Jahre alt, schaut nicht unbedingt nach gepflegter Software aus.

Für was willst du das Gamepad abfragen?
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

bastler
Beiträge: 10
Registriert: Sa 30. Jan 2016, 15:54

Re: XBOX/Gamepad Controller

Beitrag von bastler »

Danke schon mal für deine Antwort.

Ich will etwas mit den Tinkerforge-Baukasten-Teilen www.tinkerforge.de (Servo-Brick) ein Modell-Schiff automatisieren. Als Fernbedienung will ich ein Windwos-Tablet mit dem oben beschrieben Controller verwenden. Daher will ich den Controller auslesen um damit dann Servos zu stellen.

Warf
Beiträge: 1909
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: XBOX/Gamepad Controller

Beitrag von Warf »

Man könnte die sdl verwenden, oder aber die Windows API mit der MMSystem Unit

Für MMSystem gibt es wrapper Klassen für Delphi sehr leicht zu finden, mit sdl ist es aber auch nicht so schwer

bastler
Beiträge: 10
Registriert: Sa 30. Jan 2016, 15:54

Re: XBOX/Gamepad Controller

Beitrag von bastler »

Hallo Warf,

danke für den tollen Tipp!

Ich habe es schon im Programm hinbekommen anzuzeigen wieviel Joysticks angeschlossen sind und viele Buttons, Axen etc. ein Joystick hat. Es werden auch alle 6 Achsen und 11 Buttons erkannt :-).

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
var a, b, c, d,e: Integer;
 
begin
  if SDL_Init(SDL_INIT_JOYSTICK) <> 0 then
    Edit1.Text:='SDL2 Initialisierung fehlgeschlagen!'
  else
    Edit1.Text:='SDL2 Joystick erfolgreich initialisiert!';
    a:=SDL_NumJoysticks();
    Edit2.Text:=inttostr(a);
 
    b:=SDL_JoystickNumAxes(SDL_JoystickOpen(0));
    Edit3.Text:=inttostr(b);
 
    c:=SDL_JoystickNumButtons(SDL_JoystickOpen(0));
    Edit4.Text:=inttostr(c);
 
    d:=SDL_JoystickNumBalls(SDL_JoystickOpen(0));
    Edit5.Text:=inttostr(d);
 
    e:=SDL_JoystickNumHats(SDL_JoystickOpen(0));
    Edit6.Text:=inttostr(e);
 
  end;
end.

Was ich noch nicht hinbekommen habe ist, die Axen, Hats und Buttons auszulesen. Habe nur eine Erklärung für C gefunden:

https://www.libsdl.org/release/SDL-1.2. ... input.html

Wie würdet ihr das machen?

Warf
Beiträge: 1909
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: XBOX/Gamepad Controller

Beitrag von Warf »

Ich würde im Idle Event die SDL Eventqueue überprüfen, etwa so (ungetestet):

Code: Alles auswählen

//OnCreate
Application.OnIdle := @CheckEvents;
//...
 
procedure Form1.CheckEvents(Sender: TObject; var Done: Boolean);
var event: TSDL_Event;
begin
  while LongBool(SDL_PollEvent(@event)) do
  begin 
        case event.type of
        SDL_KEYDOWN:
            // Key Event
       SDL_JOYAXISMOTION:
        if ( event.jaxis.value < -3200 ) Or (event.jaxis.value > 3200 ) then
          // Pad Axen Event   
       SDL_QUIT:
        Close;
      end;
  end;
  Done:=False;
end;


Eine TTimer Komponente statt onIdle sollte es auch tun

Wie der Rest geht findest du auf deinem Link

Wenn das funktioniert hat wäre es Cool wenn du ein Beispielprojekt hochladen könntest, ich denke mehrere Suchen nach einer solchen Lösung, vor allem da es Crossplattform ist

bastler
Beiträge: 10
Registriert: Sa 30. Jan 2016, 15:54

Re: XBOX/Gamepad Controller

Beitrag von bastler »

Also habe ein Testprogramm geschrieben, das alle 11 Buttons, 6 Achsen und einen Hat abfragt. Glaubt man gar nicht, was an so einem XBOX-Controller alles dran ist. Ob das schön ist weiß ich als Anfänger nicht, aber es funktioniert sehr gut. Und in Windows 10 stürzt nichts ab und es sind keine Prozesse mit einem gewaltigen Ressourcenbedarf zu sehen. Hier ist der Code:

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, SDL2;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Label1: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    Label13: TLabel;
    Label14: TLabel;
    Label15: TLabel;
    Label16: TLabel;
    Label17: TLabel;
    Label18: TLabel;
    Label19: TLabel;
    Label2: TLabel;
    Label20: TLabel;
    Label21: TLabel;
    Label22: TLabel;
    Label23: TLabel;
    Label24: TLabel;
    Label25: TLabel;
    Label26: TLabel;
    Label27: TLabel;
    Label28: TLabel;
    Label29: TLabel;
    Label3: TLabel;
    Label30: TLabel;
    Label31: TLabel;
    Label32: TLabel;
    Label33: TLabel;
    Label34: TLabel;
    Label35: TLabel;
    Label36: TLabel;
    Label37: TLabel;
    Label38: TLabel;
    Label39: TLabel;
    Label4: TLabel;
    Label40: TLabel;
    Label41: TLabel;
    Label42: TLabel;
    Label43: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    Timer1: TTimer;
    Timer2: TTimer;
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormCreate(Sender: TObject);
 
 
    procedure Timer2Timer(Sender: TObject);
 
 
  private
    i: integer;
    myjoystick: ^integer;
  public
 
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.FormCreate(Sender: TObject);
var n: integer;
 
begin
  i:=1;
  if SDL_Init(SDL_INIT_JOYSTICK) <> 0 then
    Label1.Caption:='SDL2 Initialisierung fehlgeschlagen!'
  else
    Label1.Caption:='SDL2 erfolgreich initialisiert!';
 
  n:=SDL_NumJoysticks();
  Label2.Caption:=inttostr(n);
 
  SDL_JoystickEventState(SDL_ENABLE);
  myjoystick:=SDL_JoystickOpen(0);             //Öffnet ersten Joystick
 
end;
 
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  SDL_JoystickClose(myjoystick);
end;
 
 
procedure TForm1.Timer2Timer(Sender: TObject);
var event: TSDL_Event;
    x: integer;
    b: byte;
 
begin
  while LongBool(SDL_PollEvent(@event)) do
  begin
    i:=i+1;
    Label3.Caption:=inttostr(i);
    case event.type_ of
 
     SDL_JOYHATMOTION:
      begin
        Label4.Caption:='Hat bewegung';
        b:=SDL_JoystickGetHat(myjoystick,0);
        Label19.Caption:=inttostr(b);
      end;
 
     SDL_JOYBUTTONDOWN:
      begin
        Label4.Caption:='Button gedrückt';
        b:=SDL_JoystickGetButton(myjoystick,0);
        Label8.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,1);
        Label9.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,2);
        Label10.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,3);
        Label11.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,4);
        Label12.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,5);
        Label13.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,6);
        Label14.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,7);
        Label15.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,8);
        Label16.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,9);
        Label17.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,10);
        Label18.Caption:=inttostr(b);
       end;
 
     SDL_JOYBUTTONUP:
      begin
        Label4.Caption:='Button losgelassen';
        b:=SDL_JoystickGetButton(myjoystick,0);
        Label8.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,1);
        Label9.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,2);
        Label10.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,3);
        Label11.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,4);
        Label12.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,5);
        Label13.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,6);
        Label14.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,7);
        Label15.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,8);
        Label16.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,9);
        Label17.Caption:=inttostr(b);
        b:=SDL_JoystickGetButton(myjoystick,10);
        Label18.Caption:=inttostr(b);
       end;
 
     SDL_JOYAXISMOTION:
      begin
         Label4.Caption:='Axenbewegung';
         x:=SDL_JoystickGetAxis(myjoystick, 0);
         Label7.Caption:=inttostr(x);
         x:=SDL_JoystickGetAxis(myjoystick, 1);
         Label34.Caption:=inttostr(x);
         x:=SDL_JoystickGetAxis(myjoystick, 2);
         Label36.Caption:=inttostr(x);
         x:=SDL_JoystickGetAxis(myjoystick, 3);
         Label38.Caption:=inttostr(x);
         x:=SDL_JoystickGetAxis(myjoystick, 4);
         Label40.Caption:=inttostr(x);
         x:=SDL_JoystickGetAxis(myjoystick, 5);
         Label42.Caption:=inttostr(x);
      end;
    end;
  end;
 
end;

Antworten