mirror of
https://github.com/red-prig/fpPS4.git
synced 2024-10-07 03:33:20 +00:00
pad interface refractored
This commit is contained in:
parent
a30de1b295
commit
0511675791
@ -17,7 +17,7 @@ type
|
||||
end;
|
||||
|
||||
TKbmPadInterface=class(TScePadInterface)
|
||||
class function Open(index:Integer;var handle:TScePadHandle):Integer; override;
|
||||
class function Open(var handle:TScePadHandle):Integer; override;
|
||||
end;
|
||||
|
||||
TMouseAsTouchpad=class
|
||||
@ -30,16 +30,10 @@ type
|
||||
|
||||
implementation
|
||||
|
||||
class function TKbmPadInterface.Open(index:Integer;var handle:TScePadHandle):Integer;
|
||||
class function TKbmPadInterface.Open(var handle:TScePadHandle):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
if (index<0) or (index>15) then Exit(SCE_PAD_ERROR_INVALID_ARG);
|
||||
if (pad_opened[index]<>nil) then Exit(SCE_PAD_ERROR_ALREADY_OPENED);
|
||||
|
||||
handle:=TKbmPadHandle.Create;
|
||||
TKbmPadHandle(handle).index:=index;
|
||||
|
||||
pad_opened[index]:=handle;
|
||||
end;
|
||||
|
||||
function GetAsyncKeyState(vKey:longint):Boolean; inline;
|
||||
|
@ -6,13 +6,16 @@ interface
|
||||
|
||||
uses
|
||||
sce_pad_types,
|
||||
ps4_handles;
|
||||
ps4_handles,
|
||||
spinlock;
|
||||
|
||||
type
|
||||
TScePadHandle=class(TClassHandle)
|
||||
var
|
||||
userID:Integer;
|
||||
_type :Integer;
|
||||
index :Integer;
|
||||
handle:Integer;
|
||||
index:Integer;
|
||||
function ReadState(data:PScePadData):Integer; virtual;
|
||||
function SetLightBar(data:pScePadLightBarParam):Integer; virtual;
|
||||
function ResetLightBar():Integer; virtual;
|
||||
@ -24,7 +27,7 @@ type
|
||||
class procedure Unload; virtual;
|
||||
class function Init:Integer; virtual;
|
||||
class function Done:Integer; virtual;
|
||||
class function Open(index:Integer;var handle:TScePadHandle):Integer; virtual;
|
||||
class function Open(var handle:TScePadHandle):Integer; virtual;
|
||||
end;
|
||||
|
||||
TAbstractScePadInterface=class of TScePadInterface;
|
||||
@ -32,9 +35,49 @@ type
|
||||
var
|
||||
pad_handles:TIntegerHandles;
|
||||
pad_opened :array[0..15] of TScePadHandle;
|
||||
pad_lock :Pointer;
|
||||
|
||||
function FindPadByParam(userID,_type,index:Integer):TScePadHandle;
|
||||
Procedure SavePadHandle(handle:TScePadHandle);
|
||||
|
||||
implementation
|
||||
|
||||
function FindPadByParam(userID,_type,index:Integer):TScePadHandle;
|
||||
var
|
||||
i:Integer;
|
||||
begin
|
||||
Result:=nil;
|
||||
spin_lock(pad_lock);
|
||||
For i:=Low(pad_opened) to High(pad_opened) do
|
||||
if (pad_opened[i]<>nil) then
|
||||
if (pad_opened[i].userID=userID) and
|
||||
(pad_opened[i]._type =_type ) and
|
||||
(pad_opened[i].index =index ) then
|
||||
begin
|
||||
Result:=pad_opened[i];
|
||||
Result.Acqure;
|
||||
spin_unlock(pad_lock);
|
||||
Exit;
|
||||
end;
|
||||
spin_unlock(pad_lock);
|
||||
end;
|
||||
|
||||
Procedure SavePadHandle(handle:TScePadHandle);
|
||||
var
|
||||
i:Integer;
|
||||
begin
|
||||
spin_lock(pad_lock);
|
||||
For i:=Low(pad_opened) to High(pad_opened) do
|
||||
if (pad_opened[i]=nil) then
|
||||
begin
|
||||
pad_opened[i]:=handle;
|
||||
spin_unlock(pad_lock);
|
||||
Exit;
|
||||
end;
|
||||
spin_unlock(pad_lock);
|
||||
end;
|
||||
|
||||
|
||||
function TScePadHandle.ReadState(data:PScePadData):Integer;
|
||||
begin
|
||||
Result:=SCE_PAD_ERROR_INVALID_HANDLE;
|
||||
@ -51,11 +94,16 @@ begin
|
||||
end;
|
||||
|
||||
destructor TScePadHandle.Destroy;
|
||||
var
|
||||
i:Integer;
|
||||
begin
|
||||
if (index>=0) and (index<16) then
|
||||
begin
|
||||
pad_opened[index]:=nil;
|
||||
end;
|
||||
For i:=Low(pad_opened) to High(pad_opened) do
|
||||
if (pad_opened[i]=Self) then
|
||||
begin
|
||||
pad_opened[i]:=nil;
|
||||
Break;
|
||||
end;
|
||||
//
|
||||
inherited;
|
||||
end;
|
||||
|
||||
@ -80,7 +128,7 @@ begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
class function TScePadInterface.Open(index:Integer;var handle:TScePadHandle):Integer;
|
||||
class function TScePadInterface.Open(var handle:TScePadHandle):Integer;
|
||||
begin
|
||||
handle:=nil;
|
||||
Result:=SCE_PAD_ERROR_NOT_INITIALIZED;
|
||||
|
@ -6,6 +6,7 @@ interface
|
||||
|
||||
uses
|
||||
sysutils,
|
||||
spinlock,
|
||||
sdl2,
|
||||
sce_pad_types,
|
||||
sce_pad_interface,
|
||||
@ -29,7 +30,7 @@ type
|
||||
class procedure Unload; override;
|
||||
class function Init:Integer; override;
|
||||
class function Done:Integer; override;
|
||||
class function Open(index:Integer;var handle:TScePadHandle):Integer; override;
|
||||
class function Open(var handle:TScePadHandle):Integer; override;
|
||||
class function FindOpened(device_index:Integer;prev:PSDL_GameController):Boolean;
|
||||
class function FindDevice(prev:PSDL_GameController):PSDL_GameController;
|
||||
end;
|
||||
@ -105,6 +106,7 @@ var
|
||||
h:TSdl2PadHandle;
|
||||
begin
|
||||
Result:=False;
|
||||
spin_lock(pad_lock);
|
||||
For i:=0 to 15 do
|
||||
if (pad_opened[i]<>nil) then
|
||||
if (pad_opened[i].InheritsFrom(TSdl2PadHandle)) then
|
||||
@ -117,6 +119,7 @@ begin
|
||||
if Result then Break;
|
||||
end;
|
||||
end;
|
||||
spin_unlock(pad_lock);
|
||||
end;
|
||||
|
||||
class function TSdl2PadInterface.FindDevice(prev:PSDL_GameController):PSDL_GameController;
|
||||
@ -155,23 +158,18 @@ begin
|
||||
SDL_UnlockJoysticks;
|
||||
end;
|
||||
|
||||
class function TSdl2PadInterface.Open(index:Integer;var handle:TScePadHandle):Integer;
|
||||
class function TSdl2PadInterface.Open(var handle:TScePadHandle):Integer;
|
||||
var
|
||||
game_controller:PSDL_GameController;
|
||||
begin
|
||||
Result:=0;
|
||||
if not sdl2_init then Exit(SCE_PAD_ERROR_NOT_INITIALIZED);
|
||||
if (index<0) or (index>15) then Exit(SCE_PAD_ERROR_INVALID_ARG);
|
||||
if (pad_opened[index]<>nil) then Exit(SCE_PAD_ERROR_ALREADY_OPENED);
|
||||
|
||||
game_controller:=FindDevice(nil);
|
||||
|
||||
handle:=TSdl2PadHandle.Create;
|
||||
TSdl2PadHandle(handle).index:=index;
|
||||
TSdl2PadHandle(handle).game_controller:=game_controller;
|
||||
|
||||
pad_opened[index]:=handle;
|
||||
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('SDL2: Game Controller loaded!');
|
||||
|
@ -6,6 +6,7 @@ interface
|
||||
|
||||
uses
|
||||
sysutils,
|
||||
spinlock,
|
||||
XInput,
|
||||
sce_pad_types,
|
||||
sce_pad_interface,
|
||||
@ -14,6 +15,7 @@ uses
|
||||
type
|
||||
TXInputPadHandle=class(TScePadHandle)
|
||||
var
|
||||
UserIndex :Integer;
|
||||
connected :Boolean;
|
||||
connectedCount:Byte;
|
||||
function ReadState(data:PScePadData):Integer; override;
|
||||
@ -26,7 +28,9 @@ type
|
||||
class procedure Unload; override;
|
||||
class function Init:Integer; override;
|
||||
class function Done:Integer; override;
|
||||
class function Open(index:Integer;var handle:TScePadHandle):Integer; override;
|
||||
class function FindOpened(UserIndex,prev:Integer):Boolean;
|
||||
class function FindDevice(prev:Integer):Integer;
|
||||
class function Open(var handle:TScePadHandle):Integer; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -79,52 +83,136 @@ begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
class function TXInputPadInterface.Open(index:Integer;var handle:TScePadHandle):Integer;
|
||||
class function TXInputPadInterface.FindOpened(UserIndex,prev:Integer):Boolean;
|
||||
var
|
||||
i:Integer;
|
||||
h:TXInputPadHandle;
|
||||
begin
|
||||
Result:=False;
|
||||
spin_lock(pad_lock);
|
||||
For i:=0 to 15 do
|
||||
if (pad_opened[i]<>nil) then
|
||||
if (pad_opened[i].InheritsFrom(TXInputPadHandle)) then
|
||||
begin
|
||||
h:=TXInputPadHandle(pad_opened[i]);
|
||||
if (h.UserIndex<>prev) then
|
||||
begin
|
||||
Result:=(UserIndex=h.UserIndex);
|
||||
if Result then Break;
|
||||
end;
|
||||
end;
|
||||
spin_unlock(pad_lock);
|
||||
end;
|
||||
|
||||
class function TXInputPadInterface.FindDevice(prev:Integer):Integer;
|
||||
var
|
||||
cs:TXInputState;
|
||||
i:Integer;
|
||||
first,compared:Integer;
|
||||
begin
|
||||
Result:=-1;
|
||||
first:=-1;
|
||||
compared:=-1;
|
||||
cs:=Default(TXInputState);
|
||||
For i:=0 to XUSER_MAX_COUNT-1 do
|
||||
if (XInputGetState(i, cs)=0) then
|
||||
if not FindOpened(i,prev) then
|
||||
begin
|
||||
if (first=-1) then first:=i;
|
||||
if (prev=-1) then
|
||||
begin
|
||||
compared:=i;
|
||||
Break;
|
||||
end else
|
||||
if (i=prev) then
|
||||
begin
|
||||
compared:=i;
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
//
|
||||
if (compared=-1) then compared:=first;
|
||||
if (compared<>-1) then
|
||||
begin
|
||||
Result:=compared;
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TXInputPadInterface.Open(var handle:TScePadHandle):Integer;
|
||||
var
|
||||
UserIndex:Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
if (index<0) or (index>15) then Exit(SCE_PAD_ERROR_INVALID_ARG);
|
||||
if (pad_opened[index]<>nil) then Exit(SCE_PAD_ERROR_ALREADY_OPENED);
|
||||
|
||||
UserIndex:=FindDevice(-1);
|
||||
|
||||
handle:=TXInputPadHandle.Create;
|
||||
TXInputPadHandle(handle).index:=index;
|
||||
|
||||
pad_opened[index]:=handle;
|
||||
TXInputPadHandle(handle).UserIndex:=UserIndex;
|
||||
end;
|
||||
|
||||
function TXInputPadHandle.ReadState(data:PScePadData):Integer;
|
||||
var
|
||||
cs:TXInputState;
|
||||
controllerIndex:DWORD;
|
||||
new:Integer;
|
||||
stateResult:DWORD;
|
||||
|
||||
procedure DoConnect(new:DWORD); inline;
|
||||
begin
|
||||
UserIndex:=new;
|
||||
if not connected then
|
||||
begin
|
||||
connected:=True;
|
||||
Inc(connectedCount);
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
if (index>=XUSER_MAX_COUNT) then
|
||||
if (UserIndex=-1) then //not attached
|
||||
begin
|
||||
data^.connected :=False;
|
||||
data^.connectedCount:=0;
|
||||
Exit;
|
||||
new:=TXInputPadInterface.FindDevice(UserIndex);
|
||||
if (new<>-1) then
|
||||
begin
|
||||
//connect
|
||||
DoConnect(new);
|
||||
end else
|
||||
begin
|
||||
//not connected
|
||||
data^.connected :=False;
|
||||
data^.connectedCount:=0;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
cs:=Default(TXInputState);
|
||||
stateResult:=XInputGetState(index, cs);
|
||||
stateResult:=XInputGetState(UserIndex, cs);
|
||||
|
||||
if (stateResult=ERROR_DEVICE_NOT_CONNECTED) then
|
||||
begin
|
||||
//disconnect
|
||||
connected:=False;
|
||||
//
|
||||
new:=TXInputPadInterface.FindDevice(UserIndex);
|
||||
if (new<>-1) then
|
||||
begin
|
||||
//connect
|
||||
DoConnect(new);
|
||||
end else
|
||||
begin
|
||||
//not connected
|
||||
data^.connected :=False;
|
||||
data^.connectedCount:=0;
|
||||
Exit;
|
||||
end;
|
||||
//
|
||||
data^.connected :=connected;
|
||||
data^.connectedCount:=connectedCount;
|
||||
Exit;
|
||||
end else
|
||||
begin
|
||||
//connect
|
||||
if not connected then
|
||||
begin
|
||||
connected:=True;
|
||||
Inc(connectedCount);
|
||||
end;
|
||||
DoConnect(UserIndex);
|
||||
end;
|
||||
|
||||
data^.connected :=connected;
|
||||
|
@ -85,11 +85,29 @@ var
|
||||
begin
|
||||
if (ScePadInterface=nil) then Exit(SCE_PAD_ERROR_NOT_INITIALIZED);
|
||||
|
||||
if (_type<>SCE_PAD_PORT_TYPE_STANDARD) then Exit(SCE_PAD_ERROR_INVALID_ARG);
|
||||
if (index<0) or (index>15) then Exit(SCE_PAD_ERROR_INVALID_ARG);
|
||||
case _type of
|
||||
SCE_PAD_PORT_TYPE_STANDARD :;
|
||||
SCE_PAD_PORT_TYPE_SPECIAL :;
|
||||
SCE_PAD_PORT_TYPE_REMOTE_CONTROL:;
|
||||
else
|
||||
Exit(SCE_PAD_ERROR_INVALID_ARG);
|
||||
end;
|
||||
|
||||
if (_type=SCE_PAD_PORT_TYPE_REMOTE_CONTROL) and
|
||||
(userID<>$FF) then {SCE_USER_SERVICE_USER_ID_SYSTEM}
|
||||
begin
|
||||
Exit(SCE_PAD_ERROR_INVALID_ARG);
|
||||
end;
|
||||
|
||||
sce_handle:=FindPadByParam(userID,_type,index);
|
||||
if (sce_handle<>nil) then
|
||||
begin
|
||||
sce_handle.Release;
|
||||
Exit(SCE_PAD_ERROR_ALREADY_OPENED);
|
||||
end;
|
||||
|
||||
sce_handle:=nil;
|
||||
Result:=ScePadInterface.Open(index,sce_handle);
|
||||
Result:=ScePadInterface.Open(sce_handle);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
sce_handle.SetLightBar(@DefaultPadLightBar);
|
||||
@ -97,8 +115,15 @@ begin
|
||||
key:=0;
|
||||
if pad_handles.New(sce_handle,key) then
|
||||
begin
|
||||
sce_handle.userID:=userID;
|
||||
sce_handle._type :=_type;
|
||||
sce_handle.index :=index;
|
||||
sce_handle.handle:=key;
|
||||
//
|
||||
SavePadHandle(sce_handle);
|
||||
//
|
||||
sce_handle.Release;
|
||||
//
|
||||
Result:=key;
|
||||
end else
|
||||
begin
|
||||
@ -107,16 +132,18 @@ begin
|
||||
end;
|
||||
|
||||
function ps4_scePadGetHandle(userID,_type,index:Integer):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
sce_handle:TScePadHandle;
|
||||
begin
|
||||
if (ScePadInterface=nil) then Exit(SCE_PAD_ERROR_NOT_INITIALIZED);
|
||||
|
||||
if (_type<>SCE_PAD_PORT_TYPE_STANDARD) then Exit(SCE_PAD_ERROR_INVALID_ARG);
|
||||
sce_handle:=FindPadByParam(userID,_type,index);
|
||||
|
||||
if (index<0) or (index>15) then Exit(SCE_PAD_ERROR_INVALID_ARG);
|
||||
if (sce_handle=nil) then Exit(SCE_PAD_ERROR_NO_HANDLE);
|
||||
|
||||
if (pad_opened[index]=nil) then Exit(SCE_PAD_ERROR_NO_HANDLE);
|
||||
Result:=sce_handle.handle;
|
||||
|
||||
Result:=pad_opened[index].handle;
|
||||
sce_handle.Release;
|
||||
end;
|
||||
|
||||
function ps4_scePadClose(handle:Integer):Integer; SysV_ABI_CDecl;
|
||||
|
Loading…
Reference in New Issue
Block a user