fpPS4/ps4_libscepad.pas
2021-12-08 23:04:07 +03:00

309 lines
8.1 KiB
ObjectPascal

unit ps4_libScePad;
{$mode objfpc}{$H+}
interface
uses
windows,
ps4_program,
Classes, SysUtils;
implementation
const
SCE_PAD_ERROR_INVALID_ARG =-2137915391; // 0x80920001
SCE_PAD_ERROR_INVALID_PORT =-2137915390; // 0x80920002
SCE_PAD_ERROR_INVALID_HANDLE =-2137915389; // 0x80920003
SCE_PAD_ERROR_ALREADY_OPENED =-2137915388; // 0x80920004
SCE_PAD_ERROR_NOT_INITIALIZED =-2137915387; // 0x80920005
SCE_PAD_ERROR_INVALID_LIGHTBAR_SETTING=-2137915386; // 0x80920006
SCE_PAD_ERROR_DEVICE_NOT_CONNECTED =-2137915385; // 0x80920007
SCE_PAD_ERROR_NO_HANDLE =-2137915384; // 0x80920008
SCE_PAD_ERROR_FATAL =-2137915137; // 0x809200FF
function ps4_scePadInit():Integer; SysV_ABI_CDecl;
begin
Writeln('scePadInit');
Result:=0;
end;
function ps4_scePadOpen(userID,_type,index:Integer;param:Pointer):Integer; SysV_ABI_CDecl;
begin
//Writeln('scePadOpen:',userID);
Result:=222;
end;
const
ORBIS_PAD_PORT_TYPE_STANDARD=0;
SCE_PAD_BUTTON_L3 = $00000002;
SCE_PAD_BUTTON_R3 = $00000004;
SCE_PAD_BUTTON_OPTIONS = $00000008;
SCE_PAD_BUTTON_UP = $00000010;
SCE_PAD_BUTTON_RIGHT = $00000020;
SCE_PAD_BUTTON_DOWN = $00000040;
SCE_PAD_BUTTON_LEFT = $00000080;
SCE_PAD_BUTTON_L2 = $00000100;
SCE_PAD_BUTTON_R2 = $00000200;
SCE_PAD_BUTTON_L1 = $00000400;
SCE_PAD_BUTTON_R1 = $00000800;
SCE_PAD_BUTTON_TRIANGLE = $00001000;
SCE_PAD_BUTTON_CIRCLE = $00002000;
SCE_PAD_BUTTON_CROSS = $00004000;
SCE_PAD_BUTTON_SQUARE = $00008000;
SCE_PAD_BUTTON_TOUCH_PAD = $00100000;
SCE_PAD_BUTTON_INTERCEPTED = $80000000;
SCE_PAD_MAX_TOUCH_NUM=2;
SCE_PAD_MAX_DEVICE_UNIQUE_DATA_SIZE=12;
type
Tvec_float3=packed record
x,y,z:Single;
end;
Tvec_float4=packed record
x,y,z,w:Single;
end;
ScePadAnalogStick=packed record
x,y:Byte;
end;
ScePadAnalogButtons=packed record
l2,r2:Byte;
padding :Word;
end;
ScePadTouch=packed record
x:Word;
y:Word;
id:Byte;
reserve:array[0..2] of Byte;
end;
ScePadTouchData=packed record
touchNum:Byte;
reserve:array[0..2] of Byte;
reserve1:DWORD;
touch:array[0..SCE_PAD_MAX_TOUCH_NUM-1] of ScePadTouch;
end;
ScePadExtensionUnitData=packed record
extensionUnitId:DWORD;
reserve:Byte;
dataLength:Byte;
data:array[0..9] of Byte;
end;
PScePadData=^ScePadData;
ScePadData=packed record
buttons :DWORD;
leftStick :ScePadAnalogStick;
rightStick :ScePadAnalogStick;
analogButtons :ScePadAnalogButtons;
orientation :Tvec_float4;
acceleration :Tvec_float3;
angularVelocity :Tvec_float3;
touchData :ScePadTouchData;
connected :Boolean;
timestamp :QWORD;
extensionUnitData:ScePadExtensionUnitData;
connectedCount :Byte;
reserve:array[0..1] of Byte;
deviceUniqueDataLen:Byte;
deviceUniqueData:array[0..SCE_PAD_MAX_DEVICE_UNIQUE_DATA_SIZE-1] of Byte;
end;
TPadColor=packed record
r,g,b,a:Byte;
end;
PScePadVibrationParam=^ScePadVibrationParam;
ScePadVibrationParam=packed record
largeMotor:Byte;
smallMotor:Byte;
end;
ScePadColor=packed record
r:Byte;
g:Byte;
b:Byte;
reserve:Byte;
end;
ScePadLightBarParam=ScePadColor;
PScePadLightBarParam=^ScePadLightBarParam;
function ps4_scePadReadState(handle:Integer;data:PScePadData):Integer; SysV_ABI_CDecl;
begin
Result:=SCE_PAD_ERROR_INVALID_ARG;
if (data=nil) then Exit;
//Writeln(SizeOf(TPadData)); //184
data^:=Default(ScePadData);
//FillChar(data^,SizeOf(ScePadData),1);
data^.connected:=True;
data^.timestamp:=Sysutils.GetTickCount64;
data^.connectedCount:=1;
data^.leftStick.x:=$80;
data^.leftStick.y:=$80;
data^.rightStick.x:=$80;
data^.rightStick.y:=$80;
if GetAsyncKeyState(VK_W)<>0 then
data^.leftStick.y:=0;
if GetAsyncKeyState(VK_S)<>0 then
data^.leftStick.y:=$FF;
if GetAsyncKeyState(VK_A)<>0 then
data^.leftStick.x:=0;
if GetAsyncKeyState(VK_D)<>0 then
data^.leftStick.x:=$FF;
if GetAsyncKeyState(VK_RETURN)<>0 then
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_OPTIONS;
if GetAsyncKeyState(VK_UP)<>0 then
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_UP;
if GetAsyncKeyState(VK_RIGHT)<>0 then
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_RIGHT;
if GetAsyncKeyState(VK_DOWN)<>0 then
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_DOWN;
if GetAsyncKeyState(VK_LEFT)<>0 then
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_LEFT;
if GetAsyncKeyState(VK_NUMPAD1)<>0 then
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_TRIANGLE;
if GetAsyncKeyState(VK_NUMPAD2)<>0 then
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_CIRCLE;
if GetAsyncKeyState(VK_NUMPAD4)<>0 then
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_CROSS;
if GetAsyncKeyState(VK_NUMPAD5)<>0 then
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_SQUARE;
//data^.buttons:=not data^.buttons;
Result:=0;
end;
function ps4_scePadRead(handle:Integer;data:PScePadData;num:Integer):Integer; SysV_ABI_CDecl;
begin
ps4_scePadReadState(handle,data);
Result:=1;
end;
function ps4_scePadSetVibration(handle:Integer;pParam:PScePadVibrationParam):Integer; SysV_ABI_CDecl;
begin
Result:=0;
end;
function ps4_scePadResetLightBar(handle:Integer):Integer; assembler; nostackframe;
asm
xor %rax,%rax
end;
type
ScePadTouchPadInformation=packed record
pixelDensity:Single;
resolution:packed record
x,y:Word;
end;
end;
ScePadStickInformation=packed record
deadZoneLeft:Byte;
deadZoneRight:Byte;
end;
PScePadControllerInformation=^ScePadControllerInformation;
ScePadControllerInformation=packed record
touchPadInfo:ScePadTouchPadInformation;
stickInfo:ScePadStickInformation;
connectionType:Byte;
connectedCount:Byte;
connected:Boolean;
deviceClass:DWORD;
reserve:array[0..7] of Byte;
end;
const
SCE_PAD_CONNECTION_TYPE_LOCAL=0;
SCE_PAD_CONNECTION_TYPE_REMOTE=1;
SCE_PAD_CONNECTION_TYPE_REMOTE_VITA=SCE_PAD_CONNECTION_TYPE_REMOTE;
SCE_PAD_CONNECTION_TYPE_REMOTE_DUALSHOCK4=2;
SCE_PAD_DEVICE_CLASS_INVALID = -1;
SCE_PAD_DEVICE_CLASS_STANDARD = 0;
SCE_PAD_DEVICE_CLASS_GUITAR = 1;
SCE_PAD_DEVICE_CLASS_DRUM = 2;
SCE_PAD_DEVICE_CLASS_DJ_TURNTABLE = 3;
SCE_PAD_DEVICE_CLASS_DANCEMAT = 4;
SCE_PAD_DEVICE_CLASS_NAVIGATION = 5;
SCE_PAD_DEVICE_CLASS_STEERING_WHEEL = 6;
SCE_PAD_DEVICE_CLASS_STICK = 7;
SCE_PAD_DEVICE_CLASS_FLIGHT_STICK = 8;
SCE_PAD_DEVICE_CLASS_GUN = 9;
function ps4_scePadGetControllerInformation(handle:Integer;pInfo:PScePadControllerInformation):Integer; SysV_ABI_CDecl;
begin
//FillChar(pInfo^,SizeOf(ScePadControllerInformation),1);
//Exit(0);
if (pInfo=nil) then Exit(SCE_PAD_ERROR_INVALID_ARG);
pInfo^:=Default(ScePadControllerInformation);
pInfo^.touchPadInfo.pixelDensity := 1;
pInfo^.touchPadInfo.resolution.x := 256;
pInfo^.touchPadInfo.resolution.y := 256;
pInfo^.stickInfo.deadZoneLeft := 2;
pInfo^.stickInfo.deadZoneRight := 2;
pInfo^.connectionType := SCE_PAD_CONNECTION_TYPE_LOCAL;
pInfo^.connectedCount := 1;
pInfo^.connected := True;
pInfo^.deviceClass := SCE_PAD_DEVICE_CLASS_STANDARD;
Result:=0;
end;
function ps4_scePadSetMotionSensorState(handle:Integer;bEnable:Boolean):Integer; SysV_ABI_CDecl;
begin
Result:=0;
end;
function ps4_scePadSetLightBar(handle:Integer;pParam:PScePadLightBarParam):Integer; SysV_ABI_CDecl;
begin
Result:=0;
end;
function Load_libScePad(Const name:RawByteString):TElf_node;
var
lib:PLIBRARY;
begin
Result:=TElf_node.Create;
Result.pFileName:=name;
lib:=Result._add_lib('libScePad');
lib^.set_proc($86FD65BA226BA903,@ps4_scePadInit);
lib^.set_proc($C64D0071AACFDD5E,@ps4_scePadOpen);
lib^.set_proc($6277605EA41557B7,@ps4_scePadReadState);
lib^.set_proc($AB570735F1B270B2,@ps4_scePadRead);
lib^.set_proc($C8556739D1B1BD96,@ps4_scePadSetVibration);
lib^.set_proc($0EC703D62F475F5C,@ps4_scePadResetLightBar);
lib^.set_proc($8233FDFCA433A149,@ps4_scePadGetControllerInformation);
lib^.set_proc($72556F2F86439EDC,@ps4_scePadSetMotionSensorState);
lib^.set_proc($451E27A2F50410D6,@ps4_scePadSetLightBar);
end;
initialization
ps4_app.RegistredPreLoad('libScePad.prx',@Load_libScePad);
end.