mirror of https://github.com/red-prig/fpPS4.git
parent
27aff1b54c
commit
d6d45ba1a2
31
fpPS4.lpi
31
fpPS4.lpi
|
@ -31,7 +31,7 @@
|
||||||
<PackageName Value="LCL"/>
|
<PackageName Value="LCL"/>
|
||||||
</Item1>
|
</Item1>
|
||||||
</RequiredPackages>
|
</RequiredPackages>
|
||||||
<Units Count="117">
|
<Units Count="120">
|
||||||
<Unit0>
|
<Unit0>
|
||||||
<Filename Value="fpPS4.lpr"/>
|
<Filename Value="fpPS4.lpr"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
|
@ -513,21 +513,42 @@
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
</Unit112>
|
</Unit112>
|
||||||
<Unit113>
|
<Unit113>
|
||||||
<Filename Value="kernel\mm_adr_direct.pas"/>
|
<Filename Value="src\inputs\formcontroller.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
|
<ComponentName Value="FormControllers"/>
|
||||||
|
<HasResources Value="True"/>
|
||||||
|
<ResourceBaseClass Value="Form"/>
|
||||||
|
<UnitName Value="formController"/>
|
||||||
</Unit113>
|
</Unit113>
|
||||||
<Unit114>
|
<Unit114>
|
||||||
<Filename Value="kernel\mm_adr_virtual.pas"/>
|
<Filename Value="src\inputs\umappableinputs.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="uMappableInputs"/>
|
||||||
</Unit114>
|
</Unit114>
|
||||||
<Unit115>
|
<Unit115>
|
||||||
<Filename Value="kernel\mm_adr_name.pas"/>
|
<Filename Value="src\inputs\formbindbutton.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
|
<ComponentName Value="FormBindButtons"/>
|
||||||
|
<HasResources Value="True"/>
|
||||||
|
<ResourceBaseClass Value="Form"/>
|
||||||
|
<UnitName Value="formBindButton"/>
|
||||||
</Unit115>
|
</Unit115>
|
||||||
<Unit116>
|
<Unit116>
|
||||||
<Filename Value="rtl\trace_manager.pas"/>
|
<Filename Value="kernel\mm_adr_virtual.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
</Unit116>
|
</Unit116>
|
||||||
|
<Unit117>
|
||||||
|
<Filename Value="kernel\mm_adr_direct.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
</Unit117>
|
||||||
|
<Unit118>
|
||||||
|
<Filename Value="rtl\trace_manager.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
</Unit118>
|
||||||
|
<Unit119>
|
||||||
|
<Filename Value="kernel\mm_adr_name.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
</Unit119>
|
||||||
</Units>
|
</Units>
|
||||||
</ProjectOptions>
|
</ProjectOptions>
|
||||||
<CompilerOptions>
|
<CompilerOptions>
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
object FormBindButtons: TFormBindButtons
|
||||||
|
Left = 701
|
||||||
|
Height = 401
|
||||||
|
Top = 433
|
||||||
|
Width = 929
|
||||||
|
Caption = 'Button Binding'
|
||||||
|
ClientHeight = 401
|
||||||
|
ClientWidth = 929
|
||||||
|
DesignTimePPI = 192
|
||||||
|
OnShow = FormShow
|
||||||
|
LCLVersion = '2.3.0.0'
|
||||||
|
object BitBtn1: TBitBtn
|
||||||
|
Left = 388
|
||||||
|
Height = 60
|
||||||
|
Top = 272
|
||||||
|
Width = 150
|
||||||
|
Caption = 'Cancel'
|
||||||
|
OnClick = BitBtn1Click
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
object BitBtn2: TBitBtn
|
||||||
|
Left = 328
|
||||||
|
Height = 60
|
||||||
|
Top = 176
|
||||||
|
Width = 272
|
||||||
|
Caption = 'Unbind this button'
|
||||||
|
OnClick = BitBtn2Click
|
||||||
|
TabOrder = 1
|
||||||
|
end
|
||||||
|
object Label1: TLabel
|
||||||
|
Left = 208
|
||||||
|
Height = 32
|
||||||
|
Top = 72
|
||||||
|
Width = 526
|
||||||
|
Caption = 'Press a button or move a joystick / analog trigger'
|
||||||
|
end
|
||||||
|
object CheckInput: TTimer
|
||||||
|
Interval = 100
|
||||||
|
OnTimer = CheckInputTimer
|
||||||
|
Left = 736
|
||||||
|
Top = 216
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,76 @@
|
||||||
|
unit formBindButton;
|
||||||
|
|
||||||
|
{$mode ObjFPC}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Buttons, StdCtrls,
|
||||||
|
ExtCtrls, uMappableInputs, Windows;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
{ TFormBindButtons }
|
||||||
|
|
||||||
|
TFormBindButtons = class(TForm)
|
||||||
|
BitBtn1: TBitBtn;
|
||||||
|
BitBtn2: TBitBtn;
|
||||||
|
CheckInput: TTimer;
|
||||||
|
Label1: TLabel;
|
||||||
|
procedure BitBtn1Click(Sender: TObject);
|
||||||
|
procedure BitBtn2Click(Sender: TObject);
|
||||||
|
procedure CheckInputTimer(Sender: TObject);
|
||||||
|
procedure FormShow(Sender: TObject);
|
||||||
|
private
|
||||||
|
|
||||||
|
public
|
||||||
|
XInputKey: EnumXInputButtons;
|
||||||
|
ResetToDefault: boolean;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
FormBindButtons: TFormBindButtons;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses XInput;
|
||||||
|
|
||||||
|
{$R *.lfm}
|
||||||
|
|
||||||
|
{ TFormBindButtons }
|
||||||
|
|
||||||
|
procedure TFormBindButtons.CheckInputTimer(Sender: TObject);
|
||||||
|
var
|
||||||
|
i: integer;
|
||||||
|
state: TXInputState;
|
||||||
|
key: EnumXInputButtons;
|
||||||
|
begin
|
||||||
|
ZeroMemory(@state, SizeOf(TXInputState));
|
||||||
|
if XInputGetState(0, state) = ERROR_SUCCESS then
|
||||||
|
begin
|
||||||
|
key := MappableInputs.XInputStateToKey(state);
|
||||||
|
if key <> EnumXInputButtons.xiUnbound then
|
||||||
|
begin
|
||||||
|
XInputKey := key;
|
||||||
|
ModalResult := mrOk;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFormBindButtons.BitBtn2Click(Sender: TObject);
|
||||||
|
begin
|
||||||
|
XInputKey := xiUnbound;
|
||||||
|
ModalResult := mrOk;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFormBindButtons.BitBtn1Click(Sender: TObject);
|
||||||
|
begin
|
||||||
|
ModalResult := mrCancel;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFormBindButtons.FormShow(Sender: TObject);
|
||||||
|
begin
|
||||||
|
XInputKey := xiUnbound;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
|
@ -0,0 +1,671 @@
|
||||||
|
object FormControllers: TFormControllers
|
||||||
|
Left = 502
|
||||||
|
Height = 1123
|
||||||
|
Top = 247
|
||||||
|
Width = 1873
|
||||||
|
Caption = 'XInput to PS4 Controller Config'
|
||||||
|
ClientHeight = 1123
|
||||||
|
ClientWidth = 1873
|
||||||
|
DesignTimePPI = 192
|
||||||
|
OnClose = FormClose
|
||||||
|
OnCreate = FormCreate
|
||||||
|
OnShow = FormShow
|
||||||
|
LCLVersion = '2.3.0.0'
|
||||||
|
object GroupBox1: TGroupBox
|
||||||
|
Left = 24
|
||||||
|
Height = 328
|
||||||
|
Top = 312
|
||||||
|
Width = 640
|
||||||
|
Caption = 'Left Joystick'
|
||||||
|
ClientHeight = 291
|
||||||
|
ClientWidth = 636
|
||||||
|
TabOrder = 0
|
||||||
|
object Shape1: TShape
|
||||||
|
Left = 240
|
||||||
|
Height = 130
|
||||||
|
Top = 72
|
||||||
|
Width = 130
|
||||||
|
Shape = stCircle
|
||||||
|
end
|
||||||
|
object LJoyUp: TBitBtn
|
||||||
|
Tag = 1
|
||||||
|
Left = 200
|
||||||
|
Height = 43
|
||||||
|
Top = 24
|
||||||
|
Width = 212
|
||||||
|
Caption = 'UP'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
object LJoyRight: TBitBtn
|
||||||
|
Tag = 4
|
||||||
|
Left = 400
|
||||||
|
Height = 43
|
||||||
|
Top = 120
|
||||||
|
Width = 212
|
||||||
|
Caption = 'RIGHT'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 1
|
||||||
|
end
|
||||||
|
object LJoyDown: TBitBtn
|
||||||
|
Tag = 2
|
||||||
|
Left = 200
|
||||||
|
Height = 43
|
||||||
|
Top = 240
|
||||||
|
Width = 212
|
||||||
|
Caption = 'DOWN'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 2
|
||||||
|
end
|
||||||
|
object LJoyLeft: TBitBtn
|
||||||
|
Tag = 3
|
||||||
|
Left = 8
|
||||||
|
Height = 43
|
||||||
|
Top = 120
|
||||||
|
Width = 212
|
||||||
|
Caption = 'LEFT'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 3
|
||||||
|
end
|
||||||
|
object Label1: TLabel
|
||||||
|
Left = 480
|
||||||
|
Height = 32
|
||||||
|
Top = 80
|
||||||
|
Width = 56
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Right'
|
||||||
|
end
|
||||||
|
object Label2: TLabel
|
||||||
|
Left = 288
|
||||||
|
Height = 32
|
||||||
|
Top = -16
|
||||||
|
Width = 30
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Up'
|
||||||
|
end
|
||||||
|
object Label3: TLabel
|
||||||
|
Left = 88
|
||||||
|
Height = 32
|
||||||
|
Top = 80
|
||||||
|
Width = 40
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Left'
|
||||||
|
end
|
||||||
|
object Label4: TLabel
|
||||||
|
Left = 272
|
||||||
|
Height = 32
|
||||||
|
Top = 200
|
||||||
|
Width = 62
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Down'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object GroupBox6: TGroupBox
|
||||||
|
Left = 464
|
||||||
|
Height = 258
|
||||||
|
Top = 8
|
||||||
|
Width = 578
|
||||||
|
Caption = 'Shoulder buttons / Triggers'
|
||||||
|
ClientHeight = 221
|
||||||
|
ClientWidth = 574
|
||||||
|
TabOrder = 1
|
||||||
|
object R3: TBitBtn
|
||||||
|
Tag = 25
|
||||||
|
Left = 344
|
||||||
|
Height = 60
|
||||||
|
Top = 16
|
||||||
|
Width = 184
|
||||||
|
Caption = 'L3'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
object L3: TBitBtn
|
||||||
|
Tag = 22
|
||||||
|
Left = 56
|
||||||
|
Height = 60
|
||||||
|
Top = 16
|
||||||
|
Width = 184
|
||||||
|
Caption = 'L3'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 1
|
||||||
|
end
|
||||||
|
object R2: TBitBtn
|
||||||
|
Tag = 24
|
||||||
|
Left = 344
|
||||||
|
Height = 60
|
||||||
|
Top = 80
|
||||||
|
Width = 184
|
||||||
|
Caption = 'L2'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 2
|
||||||
|
end
|
||||||
|
object L2: TBitBtn
|
||||||
|
Tag = 21
|
||||||
|
Left = 56
|
||||||
|
Height = 60
|
||||||
|
Top = 80
|
||||||
|
Width = 184
|
||||||
|
Caption = 'L2'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 3
|
||||||
|
end
|
||||||
|
object L1: TBitBtn
|
||||||
|
Tag = 20
|
||||||
|
Left = 56
|
||||||
|
Height = 60
|
||||||
|
Top = 144
|
||||||
|
Width = 184
|
||||||
|
Caption = 'L1'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 4
|
||||||
|
end
|
||||||
|
object R1: TBitBtn
|
||||||
|
Tag = 23
|
||||||
|
Left = 344
|
||||||
|
Height = 60
|
||||||
|
Top = 144
|
||||||
|
Width = 184
|
||||||
|
Caption = 'L1'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 5
|
||||||
|
end
|
||||||
|
object Label17: TLabel
|
||||||
|
Left = 16
|
||||||
|
Height = 32
|
||||||
|
Top = 24
|
||||||
|
Width = 24
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'L3'
|
||||||
|
end
|
||||||
|
object Label18: TLabel
|
||||||
|
Left = 16
|
||||||
|
Height = 32
|
||||||
|
Top = 88
|
||||||
|
Width = 24
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'L2'
|
||||||
|
end
|
||||||
|
object Label19: TLabel
|
||||||
|
Left = 16
|
||||||
|
Height = 32
|
||||||
|
Top = 160
|
||||||
|
Width = 24
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'L1'
|
||||||
|
end
|
||||||
|
object Label20: TLabel
|
||||||
|
Left = 280
|
||||||
|
Height = 32
|
||||||
|
Top = 24
|
||||||
|
Width = 27
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'R3'
|
||||||
|
end
|
||||||
|
object Label21: TLabel
|
||||||
|
Left = 280
|
||||||
|
Height = 32
|
||||||
|
Top = 88
|
||||||
|
Width = 27
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'R2'
|
||||||
|
end
|
||||||
|
object Label22: TLabel
|
||||||
|
Left = 280
|
||||||
|
Height = 32
|
||||||
|
Top = 160
|
||||||
|
Width = 27
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'R1'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object BitBtn17: TBitBtn
|
||||||
|
Tag = 19
|
||||||
|
Left = 1480
|
||||||
|
Height = 60
|
||||||
|
Top = 112
|
||||||
|
Width = 182
|
||||||
|
Caption = 'Start'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 2
|
||||||
|
end
|
||||||
|
object BitBtn18: TBitBtn
|
||||||
|
Tag = 17
|
||||||
|
Left = 1064
|
||||||
|
Height = 60
|
||||||
|
Top = 112
|
||||||
|
Width = 184
|
||||||
|
Caption = 'Share'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 3
|
||||||
|
end
|
||||||
|
object BitBtn19: TBitBtn
|
||||||
|
Tag = 18
|
||||||
|
Left = 1272
|
||||||
|
Height = 60
|
||||||
|
Top = 112
|
||||||
|
Width = 184
|
||||||
|
Caption = 'Touch Screen'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 4
|
||||||
|
end
|
||||||
|
object GroupBox3: TGroupBox
|
||||||
|
Left = 24
|
||||||
|
Height = 328
|
||||||
|
Top = 664
|
||||||
|
Width = 640
|
||||||
|
Caption = 'DPAD'
|
||||||
|
ClientHeight = 291
|
||||||
|
ClientWidth = 636
|
||||||
|
TabOrder = 5
|
||||||
|
object DPadUp: TBitBtn
|
||||||
|
Tag = 9
|
||||||
|
Left = 200
|
||||||
|
Height = 43
|
||||||
|
Top = 24
|
||||||
|
Width = 212
|
||||||
|
Caption = 'UP'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
object DPadRight: TBitBtn
|
||||||
|
Tag = 12
|
||||||
|
Left = 400
|
||||||
|
Height = 43
|
||||||
|
Top = 120
|
||||||
|
Width = 212
|
||||||
|
Caption = 'RIGHT'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 1
|
||||||
|
end
|
||||||
|
object DPadDown: TBitBtn
|
||||||
|
Tag = 10
|
||||||
|
Left = 200
|
||||||
|
Height = 43
|
||||||
|
Top = 240
|
||||||
|
Width = 212
|
||||||
|
Caption = 'DOWN'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 2
|
||||||
|
end
|
||||||
|
object DPadLeft: TBitBtn
|
||||||
|
Tag = 11
|
||||||
|
Left = 8
|
||||||
|
Height = 43
|
||||||
|
Top = 120
|
||||||
|
Width = 212
|
||||||
|
Caption = 'LEFT'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 3
|
||||||
|
end
|
||||||
|
object Label5: TLabel
|
||||||
|
Left = 480
|
||||||
|
Height = 32
|
||||||
|
Top = 80
|
||||||
|
Width = 56
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Right'
|
||||||
|
end
|
||||||
|
object Label6: TLabel
|
||||||
|
Left = 288
|
||||||
|
Height = 32
|
||||||
|
Top = -16
|
||||||
|
Width = 30
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Up'
|
||||||
|
end
|
||||||
|
object Label7: TLabel
|
||||||
|
Left = 88
|
||||||
|
Height = 32
|
||||||
|
Top = 80
|
||||||
|
Width = 40
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Left'
|
||||||
|
end
|
||||||
|
object Label8: TLabel
|
||||||
|
Left = 272
|
||||||
|
Height = 32
|
||||||
|
Top = 200
|
||||||
|
Width = 62
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Down'
|
||||||
|
end
|
||||||
|
object Shape2: TShape
|
||||||
|
Left = 283
|
||||||
|
Height = 34
|
||||||
|
Top = 80
|
||||||
|
Width = 39
|
||||||
|
Shape = stTriangle
|
||||||
|
end
|
||||||
|
object Shape5: TShape
|
||||||
|
Left = 283
|
||||||
|
Height = 34
|
||||||
|
Top = 160
|
||||||
|
Width = 39
|
||||||
|
Shape = stTriangleDown
|
||||||
|
end
|
||||||
|
object Shape6: TShape
|
||||||
|
Left = 331
|
||||||
|
Height = 34
|
||||||
|
Top = 120
|
||||||
|
Width = 39
|
||||||
|
Shape = stTriangleRight
|
||||||
|
end
|
||||||
|
object Shape7: TShape
|
||||||
|
Left = 235
|
||||||
|
Height = 34
|
||||||
|
Top = 120
|
||||||
|
Width = 39
|
||||||
|
Shape = stTriangleLeft
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object GroupBox4: TGroupBox
|
||||||
|
Left = 712
|
||||||
|
Height = 328
|
||||||
|
Top = 664
|
||||||
|
Width = 640
|
||||||
|
Caption = 'Right joystick'
|
||||||
|
ClientHeight = 291
|
||||||
|
ClientWidth = 636
|
||||||
|
TabOrder = 6
|
||||||
|
object Shape3: TShape
|
||||||
|
Left = 240
|
||||||
|
Height = 130
|
||||||
|
Top = 72
|
||||||
|
Width = 130
|
||||||
|
Shape = stCircle
|
||||||
|
end
|
||||||
|
object RJoyUp: TBitBtn
|
||||||
|
Tag = 5
|
||||||
|
Left = 200
|
||||||
|
Height = 43
|
||||||
|
Top = 24
|
||||||
|
Width = 212
|
||||||
|
Caption = 'UP'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
object RJoyRight: TBitBtn
|
||||||
|
Tag = 8
|
||||||
|
Left = 400
|
||||||
|
Height = 43
|
||||||
|
Top = 120
|
||||||
|
Width = 212
|
||||||
|
Caption = 'RIGHT'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 1
|
||||||
|
end
|
||||||
|
object RJoyDown: TBitBtn
|
||||||
|
Tag = 6
|
||||||
|
Left = 200
|
||||||
|
Height = 43
|
||||||
|
Top = 240
|
||||||
|
Width = 212
|
||||||
|
Caption = 'DOWN'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 2
|
||||||
|
end
|
||||||
|
object RJoyLeft: TBitBtn
|
||||||
|
Tag = 7
|
||||||
|
Left = 8
|
||||||
|
Height = 43
|
||||||
|
Top = 120
|
||||||
|
Width = 212
|
||||||
|
Caption = 'LEFT'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 3
|
||||||
|
end
|
||||||
|
object Label9: TLabel
|
||||||
|
Left = 488
|
||||||
|
Height = 32
|
||||||
|
Top = 80
|
||||||
|
Width = 56
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Right'
|
||||||
|
end
|
||||||
|
object Label10: TLabel
|
||||||
|
Left = 288
|
||||||
|
Height = 32
|
||||||
|
Top = -16
|
||||||
|
Width = 30
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Up'
|
||||||
|
end
|
||||||
|
object Label11: TLabel
|
||||||
|
Left = 88
|
||||||
|
Height = 32
|
||||||
|
Top = 80
|
||||||
|
Width = 40
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Left'
|
||||||
|
end
|
||||||
|
object Label12: TLabel
|
||||||
|
Left = 272
|
||||||
|
Height = 32
|
||||||
|
Top = 200
|
||||||
|
Width = 62
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Down'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object GroupBox5: TGroupBox
|
||||||
|
Left = 712
|
||||||
|
Height = 328
|
||||||
|
Top = 312
|
||||||
|
Width = 640
|
||||||
|
Caption = 'Buttons'
|
||||||
|
ClientHeight = 291
|
||||||
|
ClientWidth = 636
|
||||||
|
TabOrder = 7
|
||||||
|
object Triangle: TBitBtn
|
||||||
|
Tag = 16
|
||||||
|
Left = 200
|
||||||
|
Height = 43
|
||||||
|
Top = 24
|
||||||
|
Width = 212
|
||||||
|
Caption = 'UP'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
object Circle: TBitBtn
|
||||||
|
Tag = 14
|
||||||
|
Left = 400
|
||||||
|
Height = 43
|
||||||
|
Top = 120
|
||||||
|
Width = 212
|
||||||
|
Caption = 'RIGHT'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 1
|
||||||
|
end
|
||||||
|
object Cross: TBitBtn
|
||||||
|
Tag = 13
|
||||||
|
Left = 200
|
||||||
|
Height = 43
|
||||||
|
Top = 240
|
||||||
|
Width = 212
|
||||||
|
Caption = 'DOWN'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 2
|
||||||
|
end
|
||||||
|
object Square: TBitBtn
|
||||||
|
Tag = 15
|
||||||
|
Left = 8
|
||||||
|
Height = 43
|
||||||
|
Top = 120
|
||||||
|
Width = 212
|
||||||
|
Caption = 'LEFT'
|
||||||
|
OnClick = ChangeKeyBiding
|
||||||
|
TabOrder = 3
|
||||||
|
end
|
||||||
|
object Label13: TLabel
|
||||||
|
Left = 480
|
||||||
|
Height = 32
|
||||||
|
Top = 80
|
||||||
|
Width = 59
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Circle'
|
||||||
|
end
|
||||||
|
object Label14: TLabel
|
||||||
|
Left = 264
|
||||||
|
Height = 32
|
||||||
|
Top = -16
|
||||||
|
Width = 84
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Triangle'
|
||||||
|
end
|
||||||
|
object Label15: TLabel
|
||||||
|
Left = 72
|
||||||
|
Height = 32
|
||||||
|
Top = 80
|
||||||
|
Width = 74
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Square'
|
||||||
|
end
|
||||||
|
object Label16: TLabel
|
||||||
|
Left = 272
|
||||||
|
Height = 32
|
||||||
|
Top = 200
|
||||||
|
Width = 57
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Cross'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object Label23: TLabel
|
||||||
|
Left = 1128
|
||||||
|
Height = 32
|
||||||
|
Top = 72
|
||||||
|
Width = 60
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Share'
|
||||||
|
end
|
||||||
|
object Label24: TLabel
|
||||||
|
Left = 1296
|
||||||
|
Height = 32
|
||||||
|
Top = 72
|
||||||
|
Width = 143
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Touch Screen'
|
||||||
|
end
|
||||||
|
object Label25: TLabel
|
||||||
|
Left = 1528
|
||||||
|
Height = 32
|
||||||
|
Top = 72
|
||||||
|
Width = 84
|
||||||
|
Alignment = taCenter
|
||||||
|
Caption = 'Options'
|
||||||
|
end
|
||||||
|
object Save: TBitBtn
|
||||||
|
Left = 1352
|
||||||
|
Height = 60
|
||||||
|
Top = 1032
|
||||||
|
Width = 226
|
||||||
|
Caption = 'Save'
|
||||||
|
OnClick = SaveClick
|
||||||
|
TabOrder = 8
|
||||||
|
end
|
||||||
|
object Cancel: TBitBtn
|
||||||
|
Left = 1618
|
||||||
|
Height = 60
|
||||||
|
Top = 1032
|
||||||
|
Width = 226
|
||||||
|
Caption = 'Cancel'
|
||||||
|
OnClick = CancelClick
|
||||||
|
TabOrder = 9
|
||||||
|
end
|
||||||
|
object SavePreset: TBitBtn
|
||||||
|
Left = 56
|
||||||
|
Height = 60
|
||||||
|
Top = 104
|
||||||
|
Width = 226
|
||||||
|
Caption = 'Save as preset'
|
||||||
|
OnClick = SavePresetClick
|
||||||
|
TabOrder = 10
|
||||||
|
end
|
||||||
|
object LoadPreset: TBitBtn
|
||||||
|
Left = 56
|
||||||
|
Height = 60
|
||||||
|
Top = 184
|
||||||
|
Width = 226
|
||||||
|
Caption = 'Load preset'
|
||||||
|
OnClick = LoadPresetClick
|
||||||
|
TabOrder = 11
|
||||||
|
end
|
||||||
|
object CheckEnabled: TCheckBox
|
||||||
|
Left = 64
|
||||||
|
Height = 36
|
||||||
|
Top = 32
|
||||||
|
Width = 193
|
||||||
|
Caption = 'XInput Enabled'
|
||||||
|
Checked = True
|
||||||
|
OnChange = SaveConfig
|
||||||
|
State = cbChecked
|
||||||
|
TabOrder = 12
|
||||||
|
end
|
||||||
|
object GroupBox2: TGroupBox
|
||||||
|
Left = 1377
|
||||||
|
Height = 282
|
||||||
|
Top = 368
|
||||||
|
Width = 434
|
||||||
|
Caption = 'Dead zones'
|
||||||
|
ClientHeight = 245
|
||||||
|
ClientWidth = 430
|
||||||
|
TabOrder = 13
|
||||||
|
object dzLeft: TTrackBar
|
||||||
|
Left = 112
|
||||||
|
Height = 50
|
||||||
|
Top = 24
|
||||||
|
Width = 280
|
||||||
|
OnChange = SaveConfig
|
||||||
|
Position = 0
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
object dzRight: TTrackBar
|
||||||
|
Left = 112
|
||||||
|
Height = 50
|
||||||
|
Top = 96
|
||||||
|
Width = 280
|
||||||
|
OnChange = SaveConfig
|
||||||
|
Position = 0
|
||||||
|
TabOrder = 1
|
||||||
|
end
|
||||||
|
object Label26: TLabel
|
||||||
|
Left = 16
|
||||||
|
Height = 32
|
||||||
|
Top = 24
|
||||||
|
Width = 40
|
||||||
|
Caption = 'Left'
|
||||||
|
end
|
||||||
|
object Label27: TLabel
|
||||||
|
Left = 16
|
||||||
|
Height = 32
|
||||||
|
Top = 96
|
||||||
|
Width = 56
|
||||||
|
Caption = 'Right'
|
||||||
|
end
|
||||||
|
object Label28: TLabel
|
||||||
|
Left = 16
|
||||||
|
Height = 32
|
||||||
|
Top = 168
|
||||||
|
Width = 84
|
||||||
|
Caption = 'Triggers'
|
||||||
|
end
|
||||||
|
object dzTriggers: TTrackBar
|
||||||
|
Left = 112
|
||||||
|
Height = 50
|
||||||
|
Top = 168
|
||||||
|
Width = 280
|
||||||
|
OnChange = SaveConfig
|
||||||
|
Position = 0
|
||||||
|
TabOrder = 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object OpenDialog1: TOpenDialog
|
||||||
|
Filter = 'Ini files|*.ini'
|
||||||
|
Left = 328
|
||||||
|
Top = 66
|
||||||
|
end
|
||||||
|
object SaveDialog1: TSaveDialog
|
||||||
|
Filter = 'Ini file|*.ini'
|
||||||
|
Left = 328
|
||||||
|
Top = 184
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,246 @@
|
||||||
|
unit formController;
|
||||||
|
|
||||||
|
{$mode ObjFPC}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
|
||||||
|
Buttons, Interfaces, LResources, ComCtrls;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
{ TFormControllers }
|
||||||
|
|
||||||
|
TFormControllers = class(TForm)
|
||||||
|
CheckEnabled: TCheckBox;
|
||||||
|
GroupBox2: TGroupBox;
|
||||||
|
Label26: TLabel;
|
||||||
|
Label27: TLabel;
|
||||||
|
Label28: TLabel;
|
||||||
|
LJoyUp: TBitBtn;
|
||||||
|
OpenDialog1: TOpenDialog;
|
||||||
|
RJoyRight: TBitBtn;
|
||||||
|
RJoyDown: TBitBtn;
|
||||||
|
RJoyLeft: TBitBtn;
|
||||||
|
dzLeft: TTrackBar;
|
||||||
|
dzRight: TTrackBar;
|
||||||
|
dzTriggers: TTrackBar;
|
||||||
|
SaveDialog1: TSaveDialog;
|
||||||
|
Triangle: TBitBtn;
|
||||||
|
Circle: TBitBtn;
|
||||||
|
Cross: TBitBtn;
|
||||||
|
Square: TBitBtn;
|
||||||
|
BitBtn17: TBitBtn;
|
||||||
|
BitBtn18: TBitBtn;
|
||||||
|
BitBtn19: TBitBtn;
|
||||||
|
LJoyLeft: TBitBtn;
|
||||||
|
L1: TBitBtn;
|
||||||
|
L2: TBitBtn;
|
||||||
|
L3: TBitBtn;
|
||||||
|
R1: TBitBtn;
|
||||||
|
R2: TBitBtn;
|
||||||
|
R3: TBitBtn;
|
||||||
|
Save: TBitBtn;
|
||||||
|
Cancel: TBitBtn;
|
||||||
|
SavePreset: TBitBtn;
|
||||||
|
LoadPreset: TBitBtn;
|
||||||
|
LJoyRight: TBitBtn;
|
||||||
|
LJoyDown: TBitBtn;
|
||||||
|
DPadUp: TBitBtn;
|
||||||
|
DPadRight: TBitBtn;
|
||||||
|
DPadDown: TBitBtn;
|
||||||
|
DPadLeft: TBitBtn;
|
||||||
|
RJoyUp: TBitBtn;
|
||||||
|
GroupBox1: TGroupBox;
|
||||||
|
GroupBox3: TGroupBox;
|
||||||
|
GroupBox4: TGroupBox;
|
||||||
|
GroupBox5: TGroupBox;
|
||||||
|
GroupBox6: TGroupBox;
|
||||||
|
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;
|
||||||
|
Label3: TLabel;
|
||||||
|
Label4: TLabel;
|
||||||
|
Label5: TLabel;
|
||||||
|
Label6: TLabel;
|
||||||
|
Label7: TLabel;
|
||||||
|
Label8: TLabel;
|
||||||
|
Label9: TLabel;
|
||||||
|
Shape1: TShape;
|
||||||
|
Shape2: TShape;
|
||||||
|
Shape3: TShape;
|
||||||
|
Shape5: TShape;
|
||||||
|
Shape6: TShape;
|
||||||
|
Shape7: TShape;
|
||||||
|
procedure CancelClick(Sender: TObject);
|
||||||
|
procedure ChangeKeyBiding(Sender: TObject);
|
||||||
|
procedure LoadPresetClick(Sender: TObject);
|
||||||
|
procedure SaveConfig(Sender: TObject);
|
||||||
|
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
|
||||||
|
procedure FormCreate(Sender: TObject);
|
||||||
|
procedure FormShow(Sender: TObject);
|
||||||
|
procedure SaveClick(Sender: TObject);
|
||||||
|
procedure SavePresetClick(Sender: TObject);
|
||||||
|
private
|
||||||
|
ShouldSaveConfig: boolean;
|
||||||
|
function FindControlByTag(control: TWinControl; pTag: integer): TWinControl;
|
||||||
|
public
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
FormControllers: TFormControllers;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
{$R *.lfm}
|
||||||
|
|
||||||
|
uses formBindButton, uMappableInputs;
|
||||||
|
|
||||||
|
{ TFormControllers }
|
||||||
|
|
||||||
|
procedure TFormControllers.ChangeKeyBiding(Sender: TObject);
|
||||||
|
var
|
||||||
|
keyToChange: integer;
|
||||||
|
begin
|
||||||
|
if Sender is TBitBtn then
|
||||||
|
begin
|
||||||
|
keyToChange := TBitBtn(Sender).Tag;
|
||||||
|
FormBindButtons := TFormBindButtons.Create(Self);
|
||||||
|
Application.CreateForm(TFormBindButtons, FormBindButtons);
|
||||||
|
FormBindButtons.ShowModal;
|
||||||
|
|
||||||
|
if FormBindButtons.ModalResult = mrOk then
|
||||||
|
begin
|
||||||
|
MappableInputs.SetXInputMapping(EnumPS4Buttons(keyToChange), FormBindButtons.XInputKey);
|
||||||
|
TBitBtn(Sender).Caption := MappableInputs.XInputButtonsNames[Ord(FormBindButtons.XInputKey)];
|
||||||
|
end;
|
||||||
|
|
||||||
|
FormBindButtons.Release;
|
||||||
|
FormBindButtons.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFormControllers.LoadPresetClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
//
|
||||||
|
OpenDialog1.InitialDir:='config';
|
||||||
|
if OpenDialog1.Execute then
|
||||||
|
begin
|
||||||
|
MappableInputs.LoadFromFile(OpenDialog1.FileName);
|
||||||
|
ShowMessage('Config loaded from ' + OpenDialog1.FileName);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFormControllers.SaveConfig(Sender: TObject);
|
||||||
|
begin
|
||||||
|
if ShouldSaveConfig then
|
||||||
|
begin
|
||||||
|
MappableInputs.XInputEnabled := CheckEnabled.Checked;
|
||||||
|
MappableInputs.XInputDeadzoneLeft := dzLeft.Position;
|
||||||
|
MappableInputs.XInputDeadzoneRight := dzRight.Position;
|
||||||
|
MappableInputs.XInputDeadzoneTrigger := dzTriggers.Position;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFormControllers.FormClose(Sender: TObject; var CloseAction: TCloseAction);
|
||||||
|
begin
|
||||||
|
MappableInputs.LoadFromFile(XINPUT_CONFIG_FILE);
|
||||||
|
CloseAction := TCloseAction.caHide;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFormControllers.CancelClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
Self.Close;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFormControllers.FindControlByTag(control: TWinControl; pTag: integer): TWinControl;
|
||||||
|
var
|
||||||
|
i: integer;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
for i := 0 to control.ControlCount - 1 do
|
||||||
|
begin
|
||||||
|
if control.Controls[i] is TWinControl then
|
||||||
|
begin
|
||||||
|
if control.Controls[i].Tag = pTag then
|
||||||
|
begin
|
||||||
|
Result := TWinControl(control.Controls[i]);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
// recursively check children
|
||||||
|
Result := FindControlByTag(TWinControl(control.Controls[i]), pTag);
|
||||||
|
if Result <> nil then
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFormControllers.FormCreate(Sender: TObject);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFormControllers.FormShow(Sender: TObject);
|
||||||
|
var
|
||||||
|
i: integer;
|
||||||
|
btn: TWinControl;
|
||||||
|
begin
|
||||||
|
// Load mapped buttons into UI
|
||||||
|
ShouldSaveConfig := False;
|
||||||
|
MappableInputs.LoadFromFile(XINPUT_CONFIG_FILE);
|
||||||
|
CheckEnabled.Checked := MappableInputs.XInputEnabled;
|
||||||
|
|
||||||
|
dzTriggers.Max := 255;
|
||||||
|
|
||||||
|
dzLeft.Max := smallint.MaxValue;
|
||||||
|
dzRight.Max := smallint.MaxValue;
|
||||||
|
|
||||||
|
dzLeft.Position := MappableInputs.XInputDeadzoneLeft;
|
||||||
|
dzRight.Position := MappableInputs.XInputDeadzoneRight;
|
||||||
|
dzTriggers.Position := MappableInputs.XInputDeadzoneTrigger;
|
||||||
|
|
||||||
|
for i := 1 to NUM_PS4_BUTTONS do
|
||||||
|
begin
|
||||||
|
btn := FindControlByTag(Self, i);
|
||||||
|
if btn <> nil then
|
||||||
|
begin
|
||||||
|
btn.Caption := MappableInputs.XInputButtonsNames[Ord(MappableInputs.PS4toXInput[i])];
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
ShouldSaveConfig := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFormControllers.SaveClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
MappableInputs.SaveToFile(XINPUT_CONFIG_FILE);
|
||||||
|
Self.Close;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFormControllers.SavePresetClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
//
|
||||||
|
SaveDialog1.InitialDir:='config';
|
||||||
|
if SaveDialog1.Execute then
|
||||||
|
begin
|
||||||
|
MappableInputs.SaveToFile(SaveDialog1.FileName);
|
||||||
|
ShowMessage('Config saved to ' + SaveDialog1.FileName);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
|
@ -0,0 +1,382 @@
|
||||||
|
unit uMappableInputs;
|
||||||
|
|
||||||
|
{$mode ObjFPC}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, XInput, IniFiles, Math;
|
||||||
|
|
||||||
|
const
|
||||||
|
NUM_PS4_BUTTONS = 25;
|
||||||
|
NUM_XINPUT_BUTTONS = 25;
|
||||||
|
XINPUT_CONFIG_FILE = 'config/xinput.ini';
|
||||||
|
|
||||||
|
type
|
||||||
|
// Mappable inputs of the PS4 controller
|
||||||
|
EnumPS4Buttons = (
|
||||||
|
miUnbound = 0,
|
||||||
|
miLJoyUp = 1,
|
||||||
|
miLJoyDown = 2,
|
||||||
|
miLJoyLeft = 3,
|
||||||
|
miLJoyRight = 4,
|
||||||
|
|
||||||
|
miRJoyUp = 5,
|
||||||
|
miRJoyDown = 6,
|
||||||
|
miRJoyLeft = 7,
|
||||||
|
miRJoyRight = 8,
|
||||||
|
|
||||||
|
miDPadUp = 9,
|
||||||
|
miDPadDown = 10,
|
||||||
|
miDPadLeft = 11,
|
||||||
|
miDPadRight = 12,
|
||||||
|
|
||||||
|
miCross = 13,
|
||||||
|
miCircle = 14,
|
||||||
|
miSquare = 15,
|
||||||
|
miTriangle = 16,
|
||||||
|
|
||||||
|
miShare = 17,
|
||||||
|
miTouchPad = 18,
|
||||||
|
miOptions = 19,
|
||||||
|
|
||||||
|
miL1 = 20,
|
||||||
|
miL2 = 21,
|
||||||
|
miL3 = 22,
|
||||||
|
|
||||||
|
miR1 = 23,
|
||||||
|
miR2 = 24,
|
||||||
|
miR3 = 25
|
||||||
|
);
|
||||||
|
|
||||||
|
// XInput buttons enum
|
||||||
|
EnumXInputButtons = (
|
||||||
|
xiUnbound = 0,
|
||||||
|
xiLJoyUp = 1,
|
||||||
|
xiLJoyDown = 2,
|
||||||
|
xiLJoyLeft = 3,
|
||||||
|
xiLJoyRight = 4,
|
||||||
|
|
||||||
|
xiRJoyUp = 5,
|
||||||
|
xiRJoyDown = 6,
|
||||||
|
xiRJoyLeft = 7,
|
||||||
|
xiRJoyRight = 8,
|
||||||
|
|
||||||
|
xiDPadUp = 9,
|
||||||
|
xiDPadDown = 10,
|
||||||
|
xiDPadLeft = 11,
|
||||||
|
xiDPadRight = 12,
|
||||||
|
|
||||||
|
xiA = 13,
|
||||||
|
xiB = 14,
|
||||||
|
xiX = 15,
|
||||||
|
xiY = 16,
|
||||||
|
|
||||||
|
xiSelect = 17,
|
||||||
|
xiUnused01 = 18,
|
||||||
|
xiStart = 19,
|
||||||
|
|
||||||
|
xiL1 = 20,
|
||||||
|
xiL2 = 21,
|
||||||
|
xiL3 = 22,
|
||||||
|
|
||||||
|
xiR1 = 23,
|
||||||
|
xiR2 = 24,
|
||||||
|
xiR3 = 25
|
||||||
|
);
|
||||||
|
|
||||||
|
type
|
||||||
|
TMappableInputs = class(TObject)
|
||||||
|
public
|
||||||
|
XInputEnabled: boolean;
|
||||||
|
|
||||||
|
PS4toXInput: array[0..NUM_PS4_BUTTONS] of EnumXInputButtons;
|
||||||
|
XInputToPS4: array[0..NUM_XINPUT_BUTTONS] of EnumPS4Buttons;
|
||||||
|
|
||||||
|
XInputButtonsNames: array[0..NUM_XINPUT_BUTTONS] of string;
|
||||||
|
XInputDeadzoneLeft, XInputDeadzoneRight: integer;
|
||||||
|
XInputDeadzoneTrigger : Byte;
|
||||||
|
|
||||||
|
function GetAnalog(input : EnumPS4Buttons; s : TXInputState) : Single;
|
||||||
|
function PS4IsPressed(input: EnumPS4Buttons; s : TXInputState): boolean;
|
||||||
|
|
||||||
|
function XInputStateToKey(state: TXInputState): EnumXInputButtons;
|
||||||
|
function XInputIsTriggered(input: EnumXInputButtons; state: TXInputState): boolean;
|
||||||
|
function XInputIsAnalog(input: EnumXInputButtons): boolean;
|
||||||
|
procedure SetXInputMapping(mappableInput: EnumPS4Buttons; xinput: EnumXInputButtons);
|
||||||
|
|
||||||
|
// Save / load
|
||||||
|
function LoadFromFile(filePath: string): boolean;
|
||||||
|
function SaveToFile(filePath: string): boolean;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
MappableInputs: TMappableInputs;
|
||||||
|
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses TypInfo;
|
||||||
|
|
||||||
|
procedure TMappableInputs.SetXInputMapping(mappableInput: EnumPS4Buttons; xinput: EnumXInputButtons);
|
||||||
|
begin
|
||||||
|
XInputToPS4[Ord(xinput)] := mappableInput;
|
||||||
|
PS4toXInput[Ord(mappableInput)] := xinput;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TMappableInputs.XInputStateToKey(state: TXInputState): EnumXInputButtons;
|
||||||
|
var
|
||||||
|
i: integer;
|
||||||
|
begin
|
||||||
|
Result := xiUnbound;
|
||||||
|
for i := 1 to NUM_XINPUT_BUTTONS do
|
||||||
|
begin
|
||||||
|
if XInputIsTriggered(EnumXInputButtons(i), state) then
|
||||||
|
begin
|
||||||
|
Result := EnumXInputButtons(i);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TMappableInputs.XInputIsAnalog(input: EnumXInputButtons): boolean;
|
||||||
|
begin
|
||||||
|
case (input) of
|
||||||
|
xiLJoyUp, xiLJoyLeft, xiLJoyRight, xiLJoyDown: Result := True;
|
||||||
|
xiRJoyUp, xiRJoyLeft, xiRJoyRight, xiRJoyDown: Result := True;
|
||||||
|
xiL2, xiR2: Result := True;
|
||||||
|
else Result := false;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TMappableInputs.GetAnalog(input : EnumPS4Buttons; s : TXInputState) : Single;
|
||||||
|
var
|
||||||
|
xinputButton : EnumXInputButtons;
|
||||||
|
outOfDeadzoneL, outOfDeadzoneR, outOfDeadzoneT : single;
|
||||||
|
begin
|
||||||
|
xInputButton := PS4toXInput[Ord(input)];
|
||||||
|
|
||||||
|
if XInputIsAnalog(xInputButton) then
|
||||||
|
begin
|
||||||
|
outOfDeadzoneL := IfThen(Trunc(sqrt(s.Gamepad.sThumbLX*s.Gamepad.sThumbLX+s.Gamepad.sThumbLY*s.Gamepad.sThumbLY)) > XInputDeadzoneLeft, 1, 0);
|
||||||
|
outOfDeadzoneR := IfThen(Trunc(sqrt(s.Gamepad.sThumbRX*s.Gamepad.sThumbRX+s.Gamepad.sThumbRY*s.Gamepad.sThumbRY)) > XInputDeadzoneRight, 1, 0);
|
||||||
|
outOfDeadzoneT := IfThen(s.Gamepad.bLeftTrigger > XInputDeadzoneTrigger, 1, 0);
|
||||||
|
|
||||||
|
case (xInputButton) of
|
||||||
|
xiLJoyUp: Result := Max(s.Gamepad.sThumbLY, 0) * outOfDeadzoneL / 32767.0;
|
||||||
|
xiLJoyDown: Result := Min(s.Gamepad.sThumbLY, 0) * outOfDeadzoneL / 32767.0;
|
||||||
|
xiLJoyRight: Result := Max(s.Gamepad.sThumbLX, 0) * outOfDeadzoneL / 32767.0;
|
||||||
|
xiLJoyLeft: Result := Min(s.Gamepad.sThumbLX, 0) * outOfDeadzoneL / 32767.0;
|
||||||
|
|
||||||
|
xiRJoyUp: Result := s.Gamepad.sThumbRY * outOfDeadzoneR / 32767.0;
|
||||||
|
xiRJoyDown: Result := s.Gamepad.sThumbRY * outOfDeadzoneR / 32767.0;
|
||||||
|
xiRJoyRight: Result := s.Gamepad.sThumbRX * outOfDeadzoneR / 32767.0;
|
||||||
|
xiRJoyLeft: Result := s.Gamepad.sThumbRX * outOfDeadzoneR / 32767.0;
|
||||||
|
|
||||||
|
xiL2: Result := IfThen(s.Gamepad.bLeftTrigger > XInputDeadzoneTrigger, s.Gamepad.bLeftTrigger / 255.0, 0);
|
||||||
|
xiR2: Result := IfThen(s.Gamepad.bRightTrigger > XInputDeadzoneTrigger, s.Gamepad.bLeftTrigger / 255.0, 0);
|
||||||
|
else Result := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
// is button
|
||||||
|
Result := IfThen(XInputIsTriggered(xinputButton, s), 1.0, 0.0);
|
||||||
|
end;
|
||||||
|
|
||||||
|
// clamp between 0 and 1
|
||||||
|
Result := Max(Min(Abs(Result), 1.0), 0.00);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TMappableInputs.PS4IsPressed(input: EnumPS4Buttons; s: TXInputState): boolean;
|
||||||
|
begin
|
||||||
|
Result := XInputIsTriggered(PS4toXInput[Ord(input)], s);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TMappableInputs.LoadFromFile(filePath: string): boolean;
|
||||||
|
var
|
||||||
|
iniFile: TIniFile;
|
||||||
|
i: integer;
|
||||||
|
xInputButton : Integer;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
|
||||||
|
if not FileExists(filePath) then exit;
|
||||||
|
|
||||||
|
iniFile := TIniFile.Create(filePath);
|
||||||
|
Self.XInputEnabled := iniFile.ReadBool('XInput', 'XInputEnabled', True);
|
||||||
|
Self.XInputDeadzoneLeft := iniFile.ReadInteger('XInput', 'XInputDeadzoneLeft', XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
|
||||||
|
Self.XInputDeadzoneRight := iniFile.ReadInteger('XInput', 'XInputDeadzoneRight', XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE);
|
||||||
|
Self.XInputDeadzoneTrigger := iniFile.ReadInteger('XInput', 'XInputDeadzoneTrigger', XINPUT_GAMEPAD_TRIGGER_THRESHOLD);
|
||||||
|
for i := 1 to NUM_PS4_BUTTONS do
|
||||||
|
begin
|
||||||
|
xInputButton := iniFile.ReadInteger('XInput', GetEnumName(TypeInfo(EnumPS4Buttons), i), 0);
|
||||||
|
SetXInputMapping(EnumPS4Buttons(i), EnumXInputButtons(xInputButton));
|
||||||
|
end;
|
||||||
|
iniFile.Free;
|
||||||
|
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TMappableInputs.SaveToFile(filePath: string): boolean;
|
||||||
|
var
|
||||||
|
iniFile: TIniFile;
|
||||||
|
i: integer;
|
||||||
|
xInputButton : Integer;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
|
||||||
|
iniFile := TIniFile.Create(filePath);
|
||||||
|
iniFile.WriteBool('XInput', 'XInputEnabled', Self.XInputEnabled);
|
||||||
|
iniFile.WriteInteger('XInput', 'XInputDeadzoneLeft', Self.XInputDeadzoneLeft);
|
||||||
|
iniFile.WriteInteger('XInput', 'XInputDeadzoneRight', Self.XInputDeadzoneRight);
|
||||||
|
iniFile.WriteInteger('XInput', 'XInputDeadzoneTrigger', Self.XInputDeadzoneTrigger);
|
||||||
|
for i := 1 to NUM_PS4_BUTTONS do
|
||||||
|
begin
|
||||||
|
xInputButton := Ord(PS4toXInput[i]);
|
||||||
|
iniFile.WriteInteger('XInput', GetEnumName(TypeInfo(EnumPS4Buttons), i), xInputButton);
|
||||||
|
end;
|
||||||
|
iniFile.Free;
|
||||||
|
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TMappableInputs.XInputIsTriggered(input: EnumXInputButtons; state: TXInputState): boolean;
|
||||||
|
begin
|
||||||
|
case (input) of
|
||||||
|
xiLJoyUp: Result := state.Gamepad.sThumbLY > self.XInputDeadzoneLeft;
|
||||||
|
xiLJoyDown: Result := state.Gamepad.sThumbLY < -self.XInputDeadzoneLeft;
|
||||||
|
xiLJoyLeft: Result := state.Gamepad.sThumbLX < -self.XInputDeadzoneLeft;
|
||||||
|
xiLJoyRight: Result := state.Gamepad.sThumbLX > self.XInputDeadzoneLeft;
|
||||||
|
|
||||||
|
xiRJoyUp: Result := state.Gamepad.sThumbRY > self.XInputDeadzoneRight;
|
||||||
|
xiRJoyDown: Result := state.Gamepad.sThumbRY < -self.XInputDeadzoneRight;
|
||||||
|
xiRJoyLeft: Result := state.Gamepad.sThumbRX < -self.XInputDeadzoneRight;
|
||||||
|
xiRJoyRight: Result := state.Gamepad.sThumbRX > self.XInputDeadzoneRight;
|
||||||
|
|
||||||
|
xiA: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_A) <> 0;
|
||||||
|
xiB: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_B) <> 0;
|
||||||
|
xiX: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_X) <> 0;
|
||||||
|
xiY: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_Y) <> 0;
|
||||||
|
|
||||||
|
xiDPadUp: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_UP) <> 0;
|
||||||
|
xiDPadDown: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_DOWN) <> 0;
|
||||||
|
xiDPadLeft: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_LEFT) <> 0;
|
||||||
|
xiDPadRight: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_RIGHT) <> 0;
|
||||||
|
|
||||||
|
xiSelect: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_BACK) <> 0;
|
||||||
|
xiStart: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_START) <> 0;
|
||||||
|
|
||||||
|
xiL1: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_LEFT_SHOULDER) <> 0;
|
||||||
|
xiL2: Result := state.Gamepad.bLeftTrigger > self.XInputDeadzoneTrigger;
|
||||||
|
xiL3: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_LEFT_THUMB) <> 0;
|
||||||
|
xiR1: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_RIGHT_SHOULDER) <> 0;
|
||||||
|
xiR2: Result := state.Gamepad.bRightTrigger > self.XInputDeadzoneTrigger;
|
||||||
|
xiR3: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_RIGHT_THUMB) <> 0;
|
||||||
|
else Result := false;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
initialization
|
||||||
|
|
||||||
|
MappableInputs := TMappableInputs.Create;
|
||||||
|
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiUnbound)] := 'Unbound';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiLJoyUp)] := 'LJOY_UP';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiLJoyDown)] := 'LJOY_DOWN';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiLJoyLeft)] := 'LJOY_LEFT';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiLJoyRight)] := 'LJOY_RIGHT';
|
||||||
|
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiRJoyUp)] := 'RJOY_UP';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiRJoyDown)] := 'RJOY_DOWN';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiRJoyLeft)] := 'RJOY_LEFT';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiRJoyRight)] := 'RJOY_RIGHT';
|
||||||
|
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiDPadUp)] := 'DPAD_UP';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiDPadDown)] := 'DPAD_DOWN';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiDPadLeft)] := 'DPAD_LEFT';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiDPadRight)] := 'DPAD_RIGHT';
|
||||||
|
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiA)] := 'A';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiB)] := 'B';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiX)] := 'X';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiY)] := 'Y';
|
||||||
|
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiSelect)] := 'SELECT';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiUnused01)] := 'UNUSED01';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiStart)] := 'START';
|
||||||
|
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiL1)] := 'L1';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiL2)] := 'L2';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiL3)] := 'L3';
|
||||||
|
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiR1)] := 'R1';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiR2)] := 'R2';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiR3)] := 'R3';
|
||||||
|
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiUnbound)] := 'Unbound';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiLJoyUp)] := 'LJOY_UP';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiLJoyDown)] := 'LJOY_DOWN';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiLJoyLeft)] := 'LJOY_LEFT';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiLJoyRight)] := 'LJOY_RIGHT';
|
||||||
|
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiRJoyUp)] := 'RJOY_UP';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiRJoyDown)] := 'RJOY_DOWN';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiRJoyLeft)] := 'RJOY_LEFT';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiRJoyRight)] := 'RJOY_RIGHT';
|
||||||
|
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiDPadUp)] := 'DPAD_UP';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiDPadDown)] := 'DPAD_DOWN';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiDPadLeft)] := 'DPAD_LEFT';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiDPadRight)] := 'DPAD_RIGHT';
|
||||||
|
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiA)] := 'A';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiB)] := 'B';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiX)] := 'X';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiY)] := 'Y';
|
||||||
|
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiSelect)] := 'SELECT';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiUnused01)] := 'UNUSED01';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiStart)] := 'START';
|
||||||
|
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiL1)] := 'L1';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiL2)] := 'L2';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiL3)] := 'L3';
|
||||||
|
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiR1)] := 'R1';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiR2)] := 'R2';
|
||||||
|
MappableInputs.XInputButtonsNames[Ord(xiR3)] := 'R3';
|
||||||
|
|
||||||
|
// Default mapping
|
||||||
|
MappableInputs.XInputEnabled := True;
|
||||||
|
MappableInputs.XInputDeadzoneLeft := XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE;
|
||||||
|
MappableInputs.XInputDeadzoneRight := XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE;
|
||||||
|
MappableInputs.XInputDeadzoneTrigger := XINPUT_GAMEPAD_TRIGGER_THRESHOLD;
|
||||||
|
MappableInputs.SetXInputMapping(miUnbound, xiUnbound);
|
||||||
|
MappableInputs.SetXInputMapping(miLJoyUp, xiLJoyUp);
|
||||||
|
MappableInputs.SetXInputMapping(miLJoyDown, xiLJoyDown);
|
||||||
|
MappableInputs.SetXInputMapping(miLJoyLeft, xiLJoyLeft);
|
||||||
|
MappableInputs.SetXInputMapping(miLJoyRight, xiLJoyRight);
|
||||||
|
MappableInputs.SetXInputMapping(miRJoyUp, xiRJoyUp);
|
||||||
|
MappableInputs.SetXInputMapping(miRJoyDown, xiRJoyDown);
|
||||||
|
MappableInputs.SetXInputMapping(miRJoyLeft, xiRJoyLeft);
|
||||||
|
MappableInputs.SetXInputMapping(miRJoyRight, xiRJoyRight);
|
||||||
|
MappableInputs.SetXInputMapping(miDPadUp, xiDPadUp);
|
||||||
|
MappableInputs.SetXInputMapping(miDPadDown, xiDPadDown);
|
||||||
|
MappableInputs.SetXInputMapping(miDPadLeft, xiDPadLeft);
|
||||||
|
MappableInputs.SetXInputMapping(miDPadRight, xiDPadRight);
|
||||||
|
MappableInputs.SetXInputMapping(miCross, xiA);
|
||||||
|
MappableInputs.SetXInputMapping(miCircle, xiB);
|
||||||
|
MappableInputs.SetXInputMapping(miSquare, xiX);
|
||||||
|
MappableInputs.SetXInputMapping(miTriangle, xiY);
|
||||||
|
MappableInputs.SetXInputMapping(miShare, xiUnbound);
|
||||||
|
MappableInputs.SetXInputMapping(miTouchPad, xiSelect);
|
||||||
|
MappableInputs.SetXInputMapping(miOptions, xiStart);
|
||||||
|
MappableInputs.SetXInputMapping(miL1, xiL1);
|
||||||
|
MappableInputs.SetXInputMapping(miL2, xiL2);
|
||||||
|
MappableInputs.SetXInputMapping(miL3, xiL3);
|
||||||
|
MappableInputs.SetXInputMapping(miR1, xiR1);
|
||||||
|
MappableInputs.SetXInputMapping(miR2, xiR2);
|
||||||
|
MappableInputs.SetXInputMapping(miR3, xiR3);
|
||||||
|
|
||||||
|
MappableInputs.LoadFromFile(XINPUT_CONFIG_FILE);
|
||||||
|
end.
|
|
@ -11,12 +11,13 @@ uses
|
||||||
sys_signal,
|
sys_signal,
|
||||||
Classes,
|
Classes,
|
||||||
SysUtils,
|
SysUtils,
|
||||||
xinput;
|
xinput,
|
||||||
|
formController;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
ps4_libSceVideoOut;
|
ps4_libSceVideoOut, uMappableInputs;
|
||||||
|
|
||||||
const
|
const
|
||||||
SCE_PAD_ERROR_INVALID_ARG =-2137915391; // 0x80920001
|
SCE_PAD_ERROR_INVALID_ARG =-2137915391; // 0x80920001
|
||||||
|
@ -313,7 +314,7 @@ end;
|
||||||
function ps4_scePadReadState(handle:Integer;data:PScePadData):Integer; SysV_ABI_CDecl;
|
function ps4_scePadReadState(handle:Integer;data:PScePadData):Integer; SysV_ABI_CDecl;
|
||||||
var
|
var
|
||||||
mPoint,delta:TPoint;
|
mPoint,delta:TPoint;
|
||||||
controllerState:TXInputState;
|
cs:TXInputState;
|
||||||
controllerIndex,stateResult:DWORD;
|
controllerIndex,stateResult:DWORD;
|
||||||
|
|
||||||
function GetAsyncKeyState(vKey:longint):Boolean; inline;
|
function GetAsyncKeyState(vKey:longint):Boolean; inline;
|
||||||
|
@ -354,7 +355,7 @@ begin
|
||||||
if GetTickCount64 > xinput_last_poll + 10000 then
|
if GetTickCount64 > xinput_last_poll + 10000 then
|
||||||
begin
|
begin
|
||||||
for controllerIndex := 0 to XUSER_MAX_COUNT - 1 do
|
for controllerIndex := 0 to XUSER_MAX_COUNT - 1 do
|
||||||
xinput_controllers_connected[controllerIndex] := XInputGetState(controllerIndex, controllerState) <> ERROR_DEVICE_NOT_CONNECTED;
|
xinput_controllers_connected[controllerIndex] := XInputGetState(controllerIndex, cs) <> ERROR_DEVICE_NOT_CONNECTED;
|
||||||
|
|
||||||
xinput_last_poll := GetTickCount64;
|
xinput_last_poll := GetTickCount64;
|
||||||
end;
|
end;
|
||||||
|
@ -362,63 +363,58 @@ begin
|
||||||
// xinput for controllers
|
// xinput for controllers
|
||||||
for controllerIndex := 0 to XUSER_MAX_COUNT - 1 do
|
for controllerIndex := 0 to XUSER_MAX_COUNT - 1 do
|
||||||
begin
|
begin
|
||||||
|
if not MappableInputs.XInputEnabled then break;
|
||||||
if not xinput_controllers_connected[controllerIndex] then
|
if not xinput_controllers_connected[controllerIndex] then
|
||||||
continue;
|
continue;
|
||||||
ZeroMemory(@controllerState, SizeOf(controllerState));
|
ZeroMemory(@cs, SizeOf(cs));
|
||||||
stateResult := XInputGetState(controllerIndex, controllerState);
|
stateResult := XInputGetState(controllerIndex, cs);
|
||||||
|
|
||||||
if stateResult = ERROR_SUCCESS then
|
if stateResult = ERROR_SUCCESS then
|
||||||
begin
|
begin
|
||||||
if (controllerState.Gamepad.wButtons and XINPUT_GAMEPAD_A) <> 0 then
|
if MappableInputs.PS4IsPressed(miCross, cs) then
|
||||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_CROSS;
|
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_CROSS;
|
||||||
if (controllerState.Gamepad.wButtons and XINPUT_GAMEPAD_B) <> 0 then
|
if MappableInputs.PS4IsPressed(miCircle, cs) then
|
||||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_CIRCLE;
|
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_CIRCLE;
|
||||||
if (controllerState.Gamepad.wButtons and XINPUT_GAMEPAD_X) <> 0 then
|
if MappableInputs.PS4IsPressed(miSquare, cs) then
|
||||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_SQUARE;
|
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_SQUARE;
|
||||||
if (controllerState.Gamepad.wButtons and XINPUT_GAMEPAD_Y) <> 0 then
|
if MappableInputs.PS4IsPressed(miTriangle, cs) then
|
||||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_TRIANGLE;
|
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_TRIANGLE;
|
||||||
|
|
||||||
if (controllerState.Gamepad.wButtons and XINPUT_GAMEPAD_START) <> 0 then
|
if MappableInputs.PS4IsPressed(miOptions, cs) then
|
||||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_OPTIONS;
|
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_OPTIONS;
|
||||||
if (controllerState.Gamepad.wButtons and XINPUT_GAMEPAD_BACK) <> 0 then
|
if MappableInputs.PS4IsPressed(miTouchPad, cs) then
|
||||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_TOUCH_PAD;
|
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_TOUCH_PAD;
|
||||||
|
|
||||||
if (controllerState.Gamepad.wButtons and XINPUT_GAMEPAD_LEFT_SHOULDER) <> 0 then
|
if MappableInputs.PS4IsPressed(miL1, cs) then
|
||||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_L1;
|
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_L1;
|
||||||
if (controllerState.Gamepad.wButtons and XINPUT_GAMEPAD_RIGHT_SHOULDER) <> 0 then
|
if MappableInputs.PS4IsPressed(miR1, cs) then
|
||||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_R1;
|
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_R1;
|
||||||
if (controllerState.Gamepad.wButtons and XINPUT_GAMEPAD_LEFT_THUMB) <> 0 then
|
if MappableInputs.PS4IsPressed(miL3, cs) then
|
||||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_L3;
|
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_L3;
|
||||||
if (controllerState.Gamepad.wButtons and XINPUT_GAMEPAD_RIGHT_THUMB) <> 0 then
|
if MappableInputs.PS4IsPressed(miR3, cs) then
|
||||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_R3;
|
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_R3;
|
||||||
|
|
||||||
if (controllerState.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_UP) <> 0 then
|
if MappableInputs.PS4IsPressed(miDPadUp, cs) then
|
||||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_UP;
|
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_UP;
|
||||||
if (controllerState.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_DOWN) <> 0 then
|
if MappableInputs.PS4IsPressed(miDPadDown, cs) then
|
||||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_DOWN;
|
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_DOWN;
|
||||||
if (controllerState.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_LEFT) <> 0 then
|
if MappableInputs.PS4IsPressed(miDPadLeft, cs) then
|
||||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_LEFT;
|
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_LEFT;
|
||||||
if (controllerState.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_RIGHT) <> 0 then
|
if MappableInputs.PS4IsPressed(miDPadRight, cs) then
|
||||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_RIGHT;
|
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_RIGHT;
|
||||||
|
|
||||||
if (Abs(controllerState.Gamepad.sThumbLX) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) then
|
data^.leftStick.x:=Trunc(128+(MappableInputs.GetAnalog(miLJoyRight, cs)-MappableInputs.GetAnalog(miLJoyLeft, cs))*127);
|
||||||
data^.leftStick.x:=Trunc(((controllerState.Gamepad.sThumbLX / 32767.0)*0.5+0.5)*255);
|
data^.leftStick.y:=Trunc(128+(MappableInputs.GetAnalog(miLJoyDown, cs)-MappableInputs.GetAnalog(miLJoyUp, cs))*127);
|
||||||
if (Abs(controllerState.Gamepad.sThumbLY) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) then
|
|
||||||
data^.leftStick.y:=Trunc(255-((controllerState.Gamepad.sThumbLY / 32767.0)*0.5+0.5)*255);
|
|
||||||
|
|
||||||
if (Abs(controllerState.Gamepad.sThumbRX) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) then
|
data^.rightStick.x:=Trunc(128+(MappableInputs.GetAnalog(miRJoyRight, cs)-MappableInputs.GetAnalog(miRJoyLeft, cs))*127);
|
||||||
data^.rightStick.x:=Trunc(((controllerState.Gamepad.sThumbRX / 32767.0)*0.5+0.5)*255);
|
data^.rightStick.y:=Trunc(128+(MappableInputs.GetAnalog(miLJoyDown, cs)-MappableInputs.GetAnalog(miLJoyUp, cs))*127);
|
||||||
if (Abs(controllerState.Gamepad.sThumbRY) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) then
|
|
||||||
data^.rightStick.y:=Trunc(255-((controllerState.Gamepad.sThumbRY / 32767.0)*0.5+0.5)*255);
|
|
||||||
|
|
||||||
if (controllerState.Gamepad.bLeftTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD) then
|
data^.analogButtons.l2:=Trunc(MappableInputs.GetAnalog(miL2, cs)*255);
|
||||||
data^.analogButtons.l2:=controllerState.Gamepad.bLeftTrigger;
|
data^.analogButtons.r2:=Trunc(MappableInputs.GetAnalog(miR2, cs)*255);
|
||||||
if (controllerState.Gamepad.bRightTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD) then
|
|
||||||
data^.analogButtons.r2:=controllerState.Gamepad.bRightTrigger;
|
|
||||||
|
|
||||||
if (controllerState.Gamepad.bLeftTrigger > 250) then
|
if MappableInputs.PS4IsPressed(miL2, cs) then
|
||||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_L2;
|
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_L2;
|
||||||
if (controllerState.Gamepad.bRightTrigger > 250) then
|
if MappableInputs.PS4IsPressed(miR2, cs) then
|
||||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_R2;
|
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_R2;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
|
@ -257,7 +257,8 @@ uses
|
||||||
ps4_time,
|
ps4_time,
|
||||||
spinlock,
|
spinlock,
|
||||||
hamt,
|
hamt,
|
||||||
param_sfo;
|
param_sfo,
|
||||||
|
formController;
|
||||||
|
|
||||||
type
|
type
|
||||||
PQNode=^TQNode;
|
PQNode=^TQNode;
|
||||||
|
@ -542,6 +543,11 @@ begin
|
||||||
|
|
||||||
UnlockRealizeBounds;
|
UnlockRealizeBounds;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if Key = VK_ESCAPE then
|
||||||
|
begin
|
||||||
|
FormControllers.Show;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TVideoOut.OnVblank(Sender:TObject);
|
procedure TVideoOut.OnVblank(Sender:TObject);
|
||||||
|
@ -585,10 +591,13 @@ begin
|
||||||
FForm.SetCaptionFPS(0);
|
FForm.SetCaptionFPS(0);
|
||||||
FForm.OnClose:=@FForm.CloseEvent;
|
FForm.OnClose:=@FForm.CloseEvent;
|
||||||
FForm.OnKeyDown:=@FForm.KeyEvent;
|
FForm.OnKeyDown:=@FForm.KeyEvent;
|
||||||
|
FForm.Position:=poScreenCenter;
|
||||||
|
|
||||||
Application.UpdateMainForm(FForm);
|
Application.UpdateMainForm(FForm);
|
||||||
FForm.Show;
|
FForm.Show;
|
||||||
|
|
||||||
|
Application.CreateForm(TFormControllers, FormControllers);
|
||||||
|
|
||||||
FGpuFlip:=TvFlip.Create(FForm.Handle);
|
FGpuFlip:=TvFlip.Create(FForm.Handle);
|
||||||
FGpuFlip.FNeoMode:=ps4_sceKernelIsNeoMode<>0;
|
FGpuFlip.FNeoMode:=ps4_sceKernelIsNeoMode<>0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue