unit cfg_edit; {$mode ObjFPC}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, StdCtrls, ExtCtrls, Vulkan, vDevice, game_info; type TVulkanDevGuid=class(TComponent) src: TComboBox; // Function GetText:RawByteString; procedure SetText(const s:RawByteString); end; TVulkanAppFlags=class(TComponent) src: TCheckGroup; // Function GetInteger:Integer; procedure SetInteger(v:Integer); end; { TfrmCfgEditor } TfrmCfgEditor = class(TForm) BtnCancel: TButton; BtnSysOpen: TButton; BtnOk: TButton; BtnLogOpen: TButton; BtnDataOpen: TButton; Edt_PS4SystemService_SystemName: TEdit; Edt_PS4SystemService_ButtonAssign: TComboBox; Edt_PS4SystemService_TimeFormat: TComboBox; Edt_PS4SystemService_Language: TComboBox; Edt_PS4SystemService_DateFormat: TComboBox; GrAppFlags: TCheckGroup; Edt_VulkanInfo_device_cmb: TComboBox; Edt_BootparamInfo_halt_on_exit: TCheckBox; Edt_BootparamInfo_print_gpu_ops: TCheckBox; Edt_BootparamInfo_print_gpu_hint: TCheckBox; Edt_JITInfo_debug_info: TCheckBox; Edt_MiscInfo_strict_ps4_freq: TCheckBox; Edt_JITInfo_relative_analize: TCheckBox; Edt_JITInfo_print_asm: TCheckBox; Edt_BootparamInfo_print_guest_syscall: TCheckBox; Edt_BootparamInfo_print_pmap: TCheckBox; Edt_BootparamInfo_print_jit_preload: TCheckBox; Edt_JITInfo_memory_guard: TCheckBox; Edt_MainInfo_fork_proc: TCheckBox; Edt_MainInfo_LogFile: TEdit; Edt_BootparamInfo_neo: TCheckBox; EditPages: TPageControl; Edt_MainInfo_system: TEdit; Edt_MainInfo_data: TEdit; Edt_MiscInfo_renderdoc_capture: TCheckBox; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; Label6: TLabel; Label7: TLabel; Label8: TLabel; Label9: TLabel; PanelHalf: TPanel; Tab_PS4System: TTabSheet; Tab_Vulkan: TTabSheet; Tab_Misc: TTabSheet; Tab_JIT: TTabSheet; Tab_MainInfo: TTabSheet; Tab_BootparamInfo: TTabSheet; procedure BtnCancelClick(Sender: TObject); procedure BtnDataOpenClick(Sender: TObject); procedure BtnOkClick(Sender: TObject); procedure BtnLogOpenClick(Sender: TObject); procedure BtnSysOpenClick(Sender: TObject); procedure PageInit(const TabName:RawByteString;obj:TAbstractObject); procedure PageSave(const TabName:RawByteString;obj:TAbstractObject); procedure VulkanInit; procedure FormInit; procedure FormSave; private public VulkanInfo_device :TVulkanDevGuid; VulkanInfo_app_flags:TVulkanAppFlags; // OnSave :TNotifyEvent; FConfigInfo:TConfigInfo; end; var frmCfgEditor: TfrmCfgEditor; implementation {$R *.lfm} uses TypInfo, Rtti, ps4_libSceSystemService; var FVulkanDeviceInit:Boolean=False; FVulkanDeviceList:APhysicalDeviceProperties=nil; Procedure InitVulkanDeviceList; begin if FVulkanDeviceInit then Exit; if vDevice.LoadVulkan then begin FVulkanDeviceList:=GetPhysicalDeviceList(); end; FVulkanDeviceInit:=True; end; procedure TfrmCfgEditor.BtnCancelClick(Sender: TObject); begin Close; end; procedure TfrmCfgEditor.BtnOkClick(Sender: TObject); begin FormSave; Hide; if Assigned(OnSave) then begin OnSave(Self); end; Close; end; procedure DoOpenFile(Edit:TEdit); var d:TOpenDialog; begin d:=nil; try d:=TOpenDialog.Create(nil); d.InitialDir:=Edit.Text; d.Options:=[ofPathMustExist,ofEnableSizing,ofViewDetail]; if d.Execute then begin Edit.Text:=d.FileName; end; except // end; FreeAndNil(d); end; procedure DoOpenDir(Edit:TEdit); var d:TSelectDirectoryDialog; begin d:=nil; try d:=TSelectDirectoryDialog.Create(nil); d.InitialDir:=Edit.Text; d.Options:=[ofPathMustExist,ofEnableSizing,ofViewDetail]; if d.Execute then begin Edit.Text:=d.FileName; end; except // end; FreeAndNil(d); end; procedure TfrmCfgEditor.BtnLogOpenClick(Sender: TObject); begin DoOpenFile(Edt_MainInfo_LogFile); end; procedure TfrmCfgEditor.BtnSysOpenClick(Sender: TObject); begin DoOpenDir(Edt_MainInfo_system); end; procedure TfrmCfgEditor.BtnDataOpenClick(Sender: TObject); begin DoOpenDir(Edt_MainInfo_data); end; type TMyControl=class(TControl) public property Text; end; TMyButtonControl=class(TButtonControl) public property Checked; end; //src: TComboBox; Function TVulkanDevGuid.GetText:RawByteString; var i:Integer; ptr:PVkPhysicalDeviceProperties; begin Result:=''; if (src=nil) then Exit; i:=src.ItemIndex; if (i=-1) then Exit; ptr:=PVkPhysicalDeviceProperties(src.Items.Objects[i]); if (ptr=nil) then Exit; Result:=GUIDToString(TGUID(ptr^.pipelineCacheUUID)); end; procedure TVulkanDevGuid.SetText(const s:RawByteString); var i:Integer; Guid:TGUID; ptr:PVkPhysicalDeviceProperties; begin if (src=nil) then Exit; Guid:=Default(TGUID); TryStringToGUID(s,Guid); For i:=0 to src.Items.Count-1 do begin ptr:=PVkPhysicalDeviceProperties(src.Items.Objects[i]); if (ptr<>nil) then if CompareByte(Guid,TGUID(ptr^.pipelineCacheUUID),SizeOf(TGUID))=0 then begin src.ItemIndex:=i; Exit; end; end; end; // Function TVulkanAppFlags.GetInteger:Integer; var i:Integer; begin Result:=0; if (src=nil) then Exit; For i:=0 to src.Items.Count-1 do if src.Checked[i] then begin Result:=Result or (1 shl i); end; end; procedure TVulkanAppFlags.SetInteger(v:Integer); var i:Integer; begin if (src=nil) then Exit; For i:=0 to src.Items.Count-1 do begin src.Checked[i]:=(v and (1 shl i))<>0; end; end; // procedure SetText(control:TComponent;const Text:RawByteString); begin if (control is TVulkanDevGuid) then begin TVulkanDevGuid(control).SetText(Text); end else if control.InheritsFrom(TControl) then begin TMyControl(control).Text:=Text; end; end; function GetText(control:TComponent):RawByteString; begin Result:=''; if (control is TVulkanDevGuid) then begin Result:=TVulkanDevGuid(control).GetText; end else if control.InheritsFrom(TControl) then begin Result:=TMyControl(control).Text; end; end; // procedure SetInteger(control:TComponent;i:Integer); begin if (control is TVulkanAppFlags) then begin TVulkanAppFlags(control).SetInteger(i); end else if control.InheritsFrom(TCustomComboBox) then begin if (i=-1) then begin //preload default if (control.Name='Edt_PS4SystemService_Language') then begin i:=GetHostSystemLang; end else if (control.Name='Edt_PS4SystemService_DateFormat') then begin i:=GetHostSystemDateFormat; end else if (control.Name='Edt_PS4SystemService_TimeFormat') then begin i:=GetHostSystemTimeFormat; end; //preload default end; TCustomComboBox(control).ItemIndex:=i; end; end; function GetInteger(control:TComponent):Integer; begin Result:=0; if (control is TVulkanAppFlags) then begin Result:=TVulkanAppFlags(control).GetInteger; end else if control.InheritsFrom(TCustomComboBox) then begin Result:=TCustomComboBox(control).ItemIndex; end; end; // procedure SetBool(control:TComponent;B:Boolean); begin if control.InheritsFrom(TButtonControl) then begin TMyButtonControl(control).Checked:=B; end; end; function GetBool(control:TComponent):Boolean; begin Result:=False; if control.InheritsFrom(TButtonControl) then begin Result:=TMyButtonControl(control).Checked; end; end; // procedure TfrmCfgEditor.PageInit(const TabName:RawByteString;obj:TAbstractObject); var i:TRttiPropertyIterator; p:TRttiProperty; TypeKind:TTypeKind; cname:RawByteString; control:TComponent; begin i:=obj.GetPropertyIterator; try while (i.GetProperty<>nil) do begin p:=i.GetProperty; cname:='Edt_'+TabName+'_'+p.Name; control:=FindComponent(cname); Assert(control<>nil,cname); if (control=nil) then Exit; TypeKind:=p.PropertyType.TypeKind; case TypeKind of tkSString, tkLString, tkAString: begin SetText(control,p.GetValue(obj).AsString); end; tkInteger: begin SetInteger(control,p.GetValue(obj).AsInteger); end; tkBool: begin SetBool(control,p.GetValue(obj).AsBoolean); end; else Assert(false); end; i.Next; end; finally i.free; end; end; procedure TfrmCfgEditor.PageSave(const TabName:RawByteString;obj:TAbstractObject); var i:TRttiPropertyIterator; p:TRttiProperty; TypeKind:TTypeKind; cname:RawByteString; control:TComponent; begin i:=obj.GetPropertyIterator; try while (i.GetProperty<>nil) do begin p:=i.GetProperty; cname:='Edt_'+TabName+'_'+p.Name; control:=FindComponent(cname); Assert(control<>nil,cname); if (control=nil) then Exit; TypeKind:=p.PropertyType.TypeKind; case TypeKind of tkSString, tkLString, tkAString: begin p.SetValue(obj,GetText(control)); end; tkInteger: begin p.SetValue(obj,GetInteger(control)); end; tkBool: begin p.SetValue(obj,GetBool(control)); end; else Assert(false); end; i.Next; end; finally i.free; end; end; Function GetApiVersionStr(apiVersion:TVkUInt32):RawByteString; begin Result:=IntToStr(VK_API_VERSION_MAJOR(apiVersion))+'.'+ IntToStr(VK_API_VERSION_MINOR(apiVersion))+'.'+ IntToStr(VK_API_VERSION_PATCH(apiVersion)); end; Function GetDrvVersionStr(driverVersion,vendorID:TVkUInt32):RawByteString; begin case vendorid of // NVIDIA 4318: begin Result:=IntToStr((driverVersion shr 22) and $3ff)+'.'+ IntToStr((driverVersion shr 14) and $0ff)+'.'+ IntToStr((driverVersion shr 6) and $0ff)+'.'+ IntToStr((driverVersion ) and $03f); Exit; end; // Intel {$IFDEF WINDOWS} $8086: begin Result:=IntToStr((driverVersion shr 14) )+'.'+ IntToStr((driverVersion ) and $3fff); Exit; end; {$ENDIF} else; end; // Use Vulkan version conventions if vendor mapping is not available Result:=IntToStr(VK_VERSION_MAJOR(driverVersion))+'.'+ IntToStr(VK_VERSION_MINOR(driverVersion))+'.'+ IntToStr(VK_VERSION_PATCH(driverVersion)); end; procedure TfrmCfgEditor.VulkanInit; var i:Integer; deviceName:RawByteString; begin InitVulkanDeviceList; if (VulkanInfo_device=nil) then begin VulkanInfo_device:=TVulkanDevGuid.Create(Self); VulkanInfo_device.Name:='Edt_VulkanInfo_device'; //FindComponent VulkanInfo_device.src :=Edt_VulkanInfo_device_cmb; end; if (VulkanInfo_app_flags=nil) then begin VulkanInfo_app_flags:=TVulkanAppFlags.Create(Self); VulkanInfo_app_flags.Name:='Edt_VulkanInfo_app_flags'; //FindComponent VulkanInfo_app_flags.src :=GrAppFlags; ////// end; Edt_VulkanInfo_device_cmb.Clear; Edt_VulkanInfo_device_cmb.ItemIndex:=-1; if Length(FVulkanDeviceList)=0 then Exit; Edt_VulkanInfo_device_cmb.AddItem('Auto',nil); Edt_VulkanInfo_device_cmb.ItemIndex:=0; For i:=0 to High(FVulkanDeviceList) do if (VK_API_VERSION_VARIANT(FVulkanDeviceList[i].apiVersion)=0) then begin deviceName:=RawByteString(FVulkanDeviceList[i].deviceName); deviceName:=deviceName+' ('+GetApiVersionStr(FVulkanDeviceList[i].apiVersion)+')'; deviceName:=deviceName+' ('+GetDrvVersionStr(FVulkanDeviceList[i].driverVersion, FVulkanDeviceList[i].vendorID)+')'; Edt_VulkanInfo_device_cmb.AddItem(deviceName,TObject(@FVulkanDeviceList[i])); end; end; procedure TfrmCfgEditor.FormInit; var i:TRttiPropertyIterator; p:TRttiProperty; obj:TObject; begin VulkanInit; EditPages.ActivePageIndex:=0; i:=FConfigInfo.GetPropertyIterator; try while (i.GetProperty<>nil) do begin p:=i.GetProperty; case p.PropertyType.TypeKind of tkClass: begin obj:=p.GetValue(FConfigInfo).AsObject; if (obj<>nil) then if obj.InheritsFrom(TAbstractObject) then begin PageInit(p.Name,TAbstractObject(obj)); end; end; else; end; i.Next; end; finally i.free; end; Show; end; procedure TfrmCfgEditor.FormSave; var i:TRttiPropertyIterator; p:TRttiProperty; obj:TObject; begin i:=FConfigInfo.GetPropertyIterator; try while (i.GetProperty<>nil) do begin p:=i.GetProperty; case p.PropertyType.TypeKind of tkClass: begin obj:=p.GetValue(FConfigInfo).AsObject; if (obj<>nil) then if obj.InheritsFrom(TAbstractObject) then begin PageSave(p.Name,TAbstractObject(obj)); end; end; else; end; i.Next; end; finally i.free; end; end; end.