diff --git a/fpPS4.lpi b/fpPS4.lpi index 7623ff0e..f25eae97 100644 --- a/fpPS4.lpi +++ b/fpPS4.lpi @@ -870,6 +870,10 @@ + + + + diff --git a/sys/dev/dev_hid.pas b/sys/dev/dev_hid.pas new file mode 100644 index 00000000..c984228e --- /dev/null +++ b/sys/dev/dev_hid.pas @@ -0,0 +1,311 @@ +unit dev_hid; + +{$mode ObjFPC}{$H+} +{$CALLING SysV_ABI_CDecl} + +interface + +uses + sys_conf; + +procedure hid_init(); + +implementation + +uses + errno, + systm, + vuio, + kern_thr, + subr_backtrace; + +var + pad_counter:Byte=0; + +function generateHandle(port_type,handle_id,proc_id:Byte):DWORD; +var + count:Byte; +begin + count:=pad_counter+1; + if (count=0) then + begin + count:=pad_counter+2; + end; + pad_counter:=count; + Result:=handle_id or + ((port_type and $f) shl 24) or + ((proc_id and $ff) shl 8) or + (count shl 16); +end; + +//case 0: Mouse +//case 1: Keyboard +//case 2: Status +//case 3: Controller +//case 5: Auth + +type + p_open_port_args=^t_open_port_args; + t_open_port_args=packed record + port_userid:Integer; + port_type :Integer; + port_index :Integer; + end; + + + t_pad_stick_info=packed record + deadZoneLeft :Byte; + deadZoneRight:Byte; + end; + + t_touch_pad_info=packed record + pixelDensity:DWORD; + x :word; + y :word; + end; + + p_pad_device_info=^t_pad_device_info; + t_pad_device_info=packed record + conn_type :Byte; + pad1 :array[0..2] of Byte; + connected :Integer; + unknow1 :QWORD; + unknow2 :word; + unknow3 :word; + unknow4 :array[0..11] of Byte; + pad_type :Byte; + pad2 :array[0..2] of Byte; + capability:Integer; + dev_class :Byte; + pad3 :array[0..2] of Byte; + unknow5 :QWORD; + touchpad :t_touch_pad_info; + stick_info:t_pad_stick_info; + unknow6 :word; + end; + {$IF sizeof(t_pad_device_info)<>64}{$STOP sizeof(t_pad_device_info)<>64}{$ENDIF} + + p_pad_dev_info_args=^t_pad_dev_info_args; + t_pad_dev_info_args=packed record + handle :Integer; + _align1 :Integer; + info :p_pad_device_info; //0x40 + end; + + + + t_analog_stick=packed record + x,y:Byte; + end; + + t_analog_buttons=packed record + l2,r2:Byte; + end; + + t_touch=packed record + id :Byte; + pad:array[0..2] of Byte; + x :word; + y :word; + end; + + t_touch_group=packed record + reserve1:DWORD; + touchNum:Byte; + pad :array[0..2] of Byte; + touch :array[0..1] of t_touch; + end; + + p_pad_state=^t_pad_state; + t_pad_state=packed record //0xA8 + timestamp :QWORD; + unk1 :DWORD; + buttons :DWORD; + leftStick :t_analog_stick; + rightStick :t_analog_stick; + analogButtons:t_analog_buttons; + unknow0 :Byte; + touch_gcount :Byte; //[0..3] + touch_groups :array[0..3] of t_touch_group; + unknow :array[0..39] of Byte; + unique_len :Byte; + unique_data :array[0..6] of Byte; + end; + {$IF sizeof(t_pad_state)<>168}{$STOP sizeof(t_pad_state)<>168}{$ENDIF} + + p_read_state_args=^t_read_state_args; + t_read_state_args=packed record + handle :Integer; + _align1 :Integer; + state :p_pad_state; //num*0xA8 + num :Integer; + unk1 :Integer; + connected:PInteger; + s_version:PInteger; + read_type:Integer; + unk3 :Integer; + end; + +const + //ScePadButtonDataOffset + 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; + +Function hidIoctl(dev:p_cdev;cmd:QWORD;data:Pointer;fflag:Integer):Integer; +var + td:p_kthread; + val:Integer; + _data:array[0..167] of Byte; +begin + Result:=0; + + td:=curkthread; + if (td=nil) then Exit(-1); + + case cmd of + + $800c4802: //sceHidOpenPortForUser + begin + with p_open_port_args(data)^ do + begin + if (port_userid<>-1) or //user_id + (port_type <> 3) or //port_type + (port_index <> 0) then //port_index + begin + Writeln('sceHidOpenPortForUser(',port_userid,',', + port_type ,',', + port_index ,')'); + + end; + + //handle + td^.td_retval[0]:=generateHandle(port_type,0,0); + end; + end; + + $80104801: //sceHidGetDeviceInfoForUser + begin + with p_pad_dev_info_args(data)^ do + begin + FillChar(_data,64,0); + + p_pad_device_info(@_data)^.conn_type:=0; + p_pad_device_info(@_data)^.connected:=1; + p_pad_device_info(@_data)^.pad_type :=0; + p_pad_device_info(@_data)^.dev_class:=0; + + Result:=copyout(@_data,info,64); + end; + end; + + $8030482E: //sceHidControllerRead2ForUser + begin + with p_read_state_args(data)^ do + begin + + FillChar(_data,168,0); + + p_pad_state(@_data)^.timestamp:=$101010; + p_pad_state(@_data)^.buttons:=SCE_PAD_BUTTON_UP or SCE_PAD_BUTTON_LEFT; + + p_pad_state(@_data)^.leftStick.x:=1; + p_pad_state(@_data)^.leftStick.y:=2; + + p_pad_state(@_data)^.rightStick.x:=3; + p_pad_state(@_data)^.rightStick.y:=4; + + p_pad_state(@_data)^.analogButtons.l2:=5; + p_pad_state(@_data)^.analogButtons.r2:=6; + + p_pad_state(@_data)^.touch_gcount:=1; + p_pad_state(@_data)^.touch_groups[0].touchNum:=2; + + + p_pad_state(@_data)^.touch_groups[0].touch[0].id:=1; + p_pad_state(@_data)^.touch_groups[0].touch[0].x :=2; + p_pad_state(@_data)^.touch_groups[0].touch[0].y :=3; + + p_pad_state(@_data)^.touch_groups[0].touch[1].id:=4; + p_pad_state(@_data)^.touch_groups[0].touch[1].x :=5; + p_pad_state(@_data)^.touch_groups[0].touch[1].y :=6; + + + p_pad_state(@_data)^.unique_len :=7; + p_pad_state(@_data)^.unique_data[6]:=7; + + + copyout(@_data,state,168); + + val:=1; + copyout(@val,connected,4); + + val:=0; + copyout(@val,s_version,4); + + //num * 0xa8 + + writeln; + + //num + td^.td_retval[0]:=1; + end; + end + + else + begin + print_error_td('hidIoctl(0x'+HexStr(cmd,8)+')'); + Assert(False); + Result:=EINVAL; + end; + end; + +end; + +Function hidRead(dev:p_cdev;uio:p_uio;ioflag:Integer):Integer; +begin + Result:=0; +end; + +const + hid_cdevsw:t_cdevsw=( + d_version :D_VERSION; + d_flags :D_TRACKCLOSE; + d_name :'hid'; + d_open :nil; + d_fdopen :nil; + d_close :nil; + d_read :@hidRead; + d_write :nil; + d_ioctl :@hidIoctl; + d_poll :nil; + d_mmap :nil; + d_strategy :nil; + d_dump :nil; + d_kqfilter :nil; + d_purge :nil; + d_mmap_single :nil; + d_mmap_single2:nil; + ); + +procedure hid_init(); +begin + make_dev(@hid_cdevsw,0,0,0,&666,'hid',[]); +end; + +end. + diff --git a/sys/kern/kern_exec.pas b/sys/kern/kern_exec.pas index 82636a4e..784cec20 100644 --- a/sys/kern/kern_exec.pas +++ b/sys/kern/kern_exec.pas @@ -234,6 +234,8 @@ var vmspace:p_vmspace; map:vm_map_t; //obj:vm_object_t; + shared_page_base:Pointer; + shared_page_len :QWORD; sv_minuser:QWORD; sv_maxuser:QWORD; stack_addr:QWORD; @@ -271,9 +273,12 @@ begin { Map a shared page } + shared_page_base:=vmspace^.sv_usrstack; + shared_page_len :=p_proc.p_sysent^.sv_shared_page_len; + //mapping shared page (sv_usrstack_len=0x4000) error:=vm_map_fixed(map,nil,0, - QWORD(vmspace^.sv_usrstack), p_proc.p_sysent^.sv_shared_page_len, + QWORD(shared_page_base), shared_page_len, VM_PROT_RW, VM_PROT_ALL, MAP_INHERIT_SHARE or MAP_ACC_NO_CHARGE, @@ -285,11 +290,18 @@ begin end; //copy sigcode - if (p_proc.p_sysent^.sv_sigcode<>nil) and - (p_proc.p_sysent^.sv_szsigcode<>nil) then - begin - copyout(p_proc.p_sysent^.sv_sigcode,vmspace^.sv_usrstack,p_proc.p_sysent^.sv_szsigcode^); - end; + with p_proc.p_sysent^ do + if (sv_sigcode<>nil) and + (sv_szsigcode<>nil) then + begin + copyout(sv_sigcode,shared_page_base,sv_szsigcode^); + end; + + vm_map_protect(map, + QWORD(shared_page_base), + QWORD(shared_page_base)+shared_page_len, + VM_PROT_READ or VM_PROT_EXECUTE, + True); { obj:=sv^.sv_shared_page_obj; diff --git a/sys/sys_sysinit.pas b/sys/sys_sysinit.pas index 72e1b9b8..e1612efd 100644 --- a/sys/sys_sysinit.pas +++ b/sys/sys_sysinit.pas @@ -52,7 +52,8 @@ uses dev_dipsw, dev_rng, dev_gc, - dev_dce; + dev_dce, + dev_hid; var daemon_thr:p_kthread; @@ -90,6 +91,7 @@ begin rng_init(); gc_initialize(); dce_initialize(); + hid_init(); end; //Manual order of lazy initialization diff --git a/sys/test/ps4_libscembus.pas b/sys/test/ps4_libscembus.pas index f4bf65bb..23e6e412 100644 --- a/sys/test/ps4_libscembus.pas +++ b/sys/test/ps4_libscembus.pas @@ -16,6 +16,16 @@ begin Result:=0; end; +function ps4_sceMbusAddHandleByUserId(unk1 :Integer; + handle:Integer; + userId:Integer; + _type :Integer; + index :Integer; + unk2 :qword):Integer; +begin + Result:=0; +end; + function Load_libSceMbus(name:pchar):p_lib_info; var lib:TLIBRARY; @@ -25,6 +35,7 @@ begin lib:=Result^.add_lib('libSceMbus'); lib.set_proc($C113D7306B643AAD,@ps4_sceMbusInit); + lib.set_proc($0B00D5B063BA5374,@ps4_sceMbusAddHandleByUserId); end; var