From 520cb4343b52cad6acc2496d7a4933958368b721 Mon Sep 17 00:00:00 2001
From: Pavel <68122101+red-prig@users.noreply.github.com>
Date: Fri, 18 Jul 2025 14:59:35 +0300
Subject: [PATCH] new_mount_system
---
fpPS4.lpi | 8 +
gui/cfg_edit.lfm | 422 ++++++++++++++++++++----------------
gui/cfg_edit.pas | 351 +++++++++++++-----------------
gui/form_filler.pas | 262 ++++++++++++++++++++++
gui/game_edit.lfm | 381 ++++++++++++++++++++++++++------
gui/game_edit.pas | 421 +++++++++++++----------------------
gui/game_info.pas | 91 ++++----
gui/game_mount.pas | 248 +++++++++++++++++++++
gui/game_run.pas | 107 +++++----
gui/main.lfm | 29 ++-
gui/main.pas | 86 +++++---
icons/Add_04_16.png | Bin 0 -> 369 bytes
icons/Folder_19_16.png | Bin 0 -> 606 bytes
icons/Remove_01_16.png | Bin 0 -> 233 bytes
sys/kern/kern_exec.pas | 14 +-
sys/kern/subr_backtrace.pas | 11 +-
sys/vfs/vfs_mount.pas | 23 +-
sys/vfs/vfs_mountroot.pas | 25 ++-
18 files changed, 1603 insertions(+), 876 deletions(-)
create mode 100644 gui/form_filler.pas
create mode 100644 gui/game_mount.pas
create mode 100644 icons/Add_04_16.png
create mode 100644 icons/Folder_19_16.png
create mode 100644 icons/Remove_01_16.png
diff --git a/fpPS4.lpi b/fpPS4.lpi
index e61286e3..ac90d60e 100644
--- a/fpPS4.lpi
+++ b/fpPS4.lpi
@@ -1643,6 +1643,14 @@
+
+
+
+
+
+
+
+
diff --git a/gui/cfg_edit.lfm b/gui/cfg_edit.lfm
index cb0de1f8..d3dd412a 100644
--- a/gui/cfg_edit.lfm
+++ b/gui/cfg_edit.lfm
@@ -1,28 +1,36 @@
object frmCfgEditor: TfrmCfgEditor
- Left = 448
- Height = 319
- Top = 198
- Width = 400
+ Left = 629
+ Height = 339
+ Top = 127
+ Width = 459
Caption = 'Config Editor'
- ClientHeight = 319
- ClientWidth = 400
+ ClientHeight = 339
+ ClientWidth = 459
Position = poMainFormCenter
- LCLVersion = '3.6.0.0'
+ LCLVersion = '3.8.0.0'
object EditPages: TPageControl
- Left = 0
- Height = 270
- Top = 0
- Width = 397
- ActivePage = Tab_PS4System
+ AnchorSideLeft.Control = Owner
+ AnchorSideTop.Control = Owner
+ AnchorSideRight.Control = Owner
+ AnchorSideRight.Side = asrBottom
+ AnchorSideBottom.Control = BtnOk
+ Left = 5
+ Height = 289
+ Top = 5
+ Width = 449
+ ActivePage = Tab_MainInfo
Align = alCustom
Anchors = [akTop, akLeft, akRight, akBottom]
+ BorderSpacing.Left = 5
+ BorderSpacing.Top = 5
+ BorderSpacing.Right = 5
BorderSpacing.Bottom = 10
- TabIndex = 5
+ TabIndex = 0
TabOrder = 0
object Tab_MainInfo: TTabSheet
Caption = 'Main'
- ClientHeight = 242
- ClientWidth = 389
+ ClientHeight = 261
+ ClientWidth = 441
object Label1: TLabel
AnchorSideLeft.Control = Tab_MainInfo
AnchorSideTop.Control = Tab_MainInfo
@@ -31,7 +39,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 15
Top = 10
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -42,35 +50,16 @@ object frmCfgEditor: TfrmCfgEditor
AnchorSideLeft.Control = Tab_MainInfo
AnchorSideTop.Control = Label1
AnchorSideTop.Side = asrBottom
- AnchorSideRight.Control = Tab_MainInfo
- AnchorSideRight.Side = asrBottom
+ AnchorSideRight.Control = BtnExpLog
Left = 10
Height = 23
Top = 35
- Width = 369
+ Width = 396
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
- BorderSpacing.Right = 10
TabOrder = 0
end
- object Edt_MainInfo_fork_proc: TCheckBox
- AnchorSideLeft.Control = Tab_MainInfo
- AnchorSideTop.Control = Edt_MainInfo_data
- AnchorSideTop.Side = asrBottom
- AnchorSideRight.Control = Tab_MainInfo
- AnchorSideRight.Side = asrBottom
- Left = 10
- Height = 19
- Top = 184
- Width = 369
- Anchors = [akTop, akLeft, akRight]
- BorderSpacing.Left = 10
- BorderSpacing.Top = 10
- BorderSpacing.Right = 10
- Caption = 'Run in a separate process'
- TabOrder = 4
- end
object Label2: TLabel
AnchorSideLeft.Control = Tab_MainInfo
AnchorSideTop.Control = Edt_MainInfo_LogFile
@@ -80,60 +69,12 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 15
Top = 68
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
BorderSpacing.Right = 10
- Caption = 'Default System Firmware folder:'
- end
- object Edt_MainInfo_system: TEdit
- AnchorSideLeft.Control = Tab_MainInfo
- AnchorSideTop.Control = Label2
- AnchorSideTop.Side = asrBottom
- AnchorSideRight.Control = Tab_MainInfo
- AnchorSideRight.Side = asrBottom
- Left = 10
- Height = 23
- Top = 93
- Width = 369
- Anchors = [akTop, akLeft, akRight]
- BorderSpacing.Left = 10
- BorderSpacing.Top = 10
- BorderSpacing.Right = 10
- TabOrder = 2
- end
- object Label3: TLabel
- AnchorSideLeft.Control = Tab_MainInfo
- AnchorSideTop.Control = Edt_MainInfo_system
- AnchorSideTop.Side = asrBottom
- AnchorSideRight.Control = Tab_MainInfo
- AnchorSideRight.Side = asrBottom
- Left = 10
- Height = 15
- Top = 126
- Width = 369
- Anchors = [akTop, akLeft, akRight]
- BorderSpacing.Left = 10
- BorderSpacing.Top = 10
- BorderSpacing.Right = 10
- Caption = 'Default System data folder:'
- end
- object Edt_MainInfo_data: TEdit
- AnchorSideLeft.Control = Tab_MainInfo
- AnchorSideTop.Control = Label3
- AnchorSideTop.Side = asrBottom
- AnchorSideRight.Control = Tab_MainInfo
- AnchorSideRight.Side = asrBottom
- Left = 10
- Height = 23
- Top = 151
- Width = 369
- Anchors = [akTop, akLeft, akRight]
- BorderSpacing.Left = 10
- BorderSpacing.Top = 10
- BorderSpacing.Right = 10
- TabOrder = 3
+ Caption = 'Default Firmware folder:'
end
object BtnLogOpen: TButton
AnchorSideTop.Control = Edt_MainInfo_LogFile
@@ -141,7 +82,7 @@ object frmCfgEditor: TfrmCfgEditor
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Edt_MainInfo_LogFile
AnchorSideBottom.Side = asrBottom
- Left = 343
+ Left = 370
Height = 21
Top = 36
Width = 35
@@ -154,49 +95,140 @@ object frmCfgEditor: TfrmCfgEditor
TabOrder = 1
OnClick = BtnLogOpenClick
end
- object BtnSysOpen: TButton
- AnchorSideTop.Control = Edt_MainInfo_system
- AnchorSideRight.Control = Edt_MainInfo_system
+ object BtnExpLog: TSpeedButton
+ AnchorSideLeft.Side = asrBottom
+ AnchorSideTop.Control = Edt_MainInfo_LogFile
+ AnchorSideTop.Side = asrCenter
+ AnchorSideRight.Control = Tab_MainInfo
AnchorSideRight.Side = asrBottom
- AnchorSideBottom.Control = Edt_MainInfo_system
- AnchorSideBottom.Side = asrBottom
- Left = 343
- Height = 21
- Top = 94
- Width = 35
- Anchors = [akTop, akRight, akBottom]
+ AnchorSideBottom.Control = Edt_MainInfo_LogFile
+ AnchorSideBottom.Side = asrCenter
+ Left = 411
+ Height = 20
+ Top = 36
+ Width = 20
+ Anchors = [akTop, akRight]
AutoSize = True
- BorderSpacing.Top = 1
- BorderSpacing.Right = 1
- BorderSpacing.Bottom = 1
- Caption = '...'
- TabOrder = 5
- OnClick = BtnSysOpenClick
+ BorderSpacing.Left = 5
+ BorderSpacing.Right = 10
+ Images = frmMain.SmallImageList
+ ImageIndex = 0
+ OnClick = BtnExpLogClick
end
- object BtnDataOpen: TButton
- AnchorSideTop.Control = Edt_MainInfo_data
- AnchorSideRight.Control = Edt_MainInfo_data
+ object Edt_MainInfo_FirmwareList: TListBox
+ AnchorSideLeft.Control = Tab_MainInfo
+ AnchorSideTop.Control = BtnAddFw
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = Tab_MainInfo
AnchorSideRight.Side = asrBottom
- AnchorSideBottom.Control = Edt_MainInfo_data
+ AnchorSideBottom.Control = Tab_MainInfo
AnchorSideBottom.Side = asrBottom
- Left = 343
- Height = 21
- Top = 152
- Width = 35
- Anchors = [akTop, akRight, akBottom]
+ Left = 10
+ Height = 102
+ Top = 149
+ Width = 421
+ Anchors = [akTop, akLeft, akRight, akBottom]
+ BorderSpacing.Left = 10
+ BorderSpacing.Top = 3
+ BorderSpacing.Right = 10
+ BorderSpacing.Bottom = 10
+ ItemHeight = 0
+ TabOrder = 3
+ end
+ object BtnAddFw: TSpeedButton
+ AnchorSideLeft.Control = Edt_MainInfo_FirmwareList
+ AnchorSideTop.Control = Edt_MainInfo_DefaultFirmware
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = Tab_MainInfo
+ AnchorSideRight.Side = asrBottom
+ AnchorSideBottom.Control = Edt_MainInfo_FirmwareList
+ Left = 10
+ Height = 20
+ Top = 126
+ Width = 20
AutoSize = True
- BorderSpacing.Top = 1
- BorderSpacing.Right = 1
- BorderSpacing.Bottom = 1
- Caption = '...'
- TabOrder = 6
- OnClick = BtnDataOpenClick
+ BorderSpacing.Top = 10
+ BorderSpacing.Right = 5
+ Images = frmMain.SmallImageList
+ ImageIndex = 1
+ OnClick = BtnAddFwClick
+ end
+ object BtnRemFw: TSpeedButton
+ AnchorSideLeft.Control = BtnAddFw
+ AnchorSideLeft.Side = asrBottom
+ AnchorSideTop.Control = BtnAddFw
+ AnchorSideTop.Side = asrCenter
+ AnchorSideRight.Control = Tab_MainInfo
+ AnchorSideRight.Side = asrBottom
+ AnchorSideBottom.Control = Edt_MainInfo_FirmwareList
+ Left = 35
+ Height = 20
+ Top = 126
+ Width = 20
+ AutoSize = True
+ Images = frmMain.SmallImageList
+ ImageIndex = 2
+ OnClick = BtnRemFwClick
+ end
+ object Label3: TLabel
+ AnchorSideLeft.Control = BtnRemFw
+ AnchorSideLeft.Side = asrBottom
+ AnchorSideTop.Control = Edt_MainInfo_LogFile
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = Tab_MainInfo
+ AnchorSideRight.Side = asrBottom
+ AnchorSideBottom.Control = Edt_MainInfo_FirmwareList
+ Left = 65
+ Height = 15
+ Top = 124
+ Width = 366
+ Anchors = [akLeft, akRight, akBottom]
+ BorderSpacing.Left = 10
+ BorderSpacing.Right = 10
+ BorderSpacing.Bottom = 10
+ Caption = 'Firmware folder list:'
+ end
+ object Edt_MainInfo_DefaultFirmware: TComboBox
+ AnchorSideLeft.Control = Tab_MainInfo
+ AnchorSideTop.Control = Label2
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = BtnExpSys
+ Left = 10
+ Height = 23
+ Top = 93
+ Width = 396
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 10
+ BorderSpacing.Top = 10
+ ItemHeight = 15
+ TabOrder = 2
+ OnGetItems = Edt_MainInfo_DefaultFirmwareGetItems
+ end
+ object BtnExpSys: TSpeedButton
+ AnchorSideLeft.Side = asrBottom
+ AnchorSideTop.Control = Edt_MainInfo_DefaultFirmware
+ AnchorSideTop.Side = asrCenter
+ AnchorSideRight.Control = Tab_MainInfo
+ AnchorSideRight.Side = asrBottom
+ AnchorSideBottom.Control = Edt_MainInfo_LogFile
+ AnchorSideBottom.Side = asrCenter
+ Left = 411
+ Height = 20
+ Top = 94
+ Width = 20
+ Anchors = [akTop, akRight]
+ AutoSize = True
+ BorderSpacing.Left = 5
+ BorderSpacing.Right = 10
+ Images = frmMain.SmallImageList
+ ImageIndex = 0
+ OnClick = BtnExpSysClick
end
end
object Tab_BootparamInfo: TTabSheet
Caption = 'Bootparam'
- ClientHeight = 242
- ClientWidth = 389
+ ClientHeight = 261
+ ClientWidth = 441
object Edt_BootparamInfo_neo: TCheckBox
AnchorSideLeft.Control = Tab_BootparamInfo
AnchorSideTop.Control = Tab_BootparamInfo
@@ -205,7 +237,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 19
Top = 10
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -222,7 +254,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 19
Top = 39
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -239,7 +271,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 19
Top = 68
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -256,7 +288,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 19
Top = 97
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -273,7 +305,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 19
Top = 126
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -290,7 +322,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 19
Top = 155
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -307,7 +339,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 19
Top = 184
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -318,8 +350,8 @@ object frmCfgEditor: TfrmCfgEditor
end
object Tab_JIT: TTabSheet
Caption = 'JIT'
- ClientHeight = 242
- ClientWidth = 389
+ ClientHeight = 261
+ ClientWidth = 441
object Edt_JITInfo_print_asm: TCheckBox
AnchorSideLeft.Control = Tab_JIT
AnchorSideTop.Control = Tab_JIT
@@ -328,7 +360,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 19
Top = 10
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -345,7 +377,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 19
Top = 39
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -362,7 +394,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 19
Top = 68
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -379,7 +411,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 19
Top = 97
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -390,23 +422,24 @@ object frmCfgEditor: TfrmCfgEditor
end
object Tab_Misc: TTabSheet
Caption = 'Misc'
- ClientHeight = 242
- ClientWidth = 389
+ ClientHeight = 261
+ ClientWidth = 441
object Edt_MiscInfo_strict_ps4_freq: TCheckBox
AnchorSideLeft.Control = Tab_Misc
- AnchorSideTop.Control = Tab_Misc
+ AnchorSideTop.Control = Edt_MiscInfo_fork_proc
+ AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Tab_Misc
AnchorSideRight.Side = asrBottom
Left = 10
Height = 19
- Top = 10
- Width = 369
+ Top = 39
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
BorderSpacing.Right = 10
Caption = 'Strict rdtsc timer frequency'
- TabOrder = 0
+ TabOrder = 1
end
object Edt_MiscInfo_renderdoc_capture: TCheckBox
AnchorSideLeft.Control = Tab_Misc
@@ -416,20 +449,39 @@ object frmCfgEditor: TfrmCfgEditor
AnchorSideRight.Side = asrBottom
Left = 10
Height = 19
- Top = 39
- Width = 369
+ Top = 68
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
BorderSpacing.Right = 10
Caption = 'Use renderdoc capture'
- TabOrder = 1
+ TabOrder = 2
+ end
+ object Edt_MiscInfo_fork_proc: TCheckBox
+ AnchorSideLeft.Control = Tab_Misc
+ AnchorSideTop.Control = Tab_Misc
+ AnchorSideRight.Control = Tab_Misc
+ AnchorSideRight.Side = asrBottom
+ AnchorSideBottom.Control = Tab_MainInfo
+ AnchorSideBottom.Side = asrBottom
+ Left = 10
+ Height = 19
+ Top = 10
+ Width = 421
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 10
+ BorderSpacing.Top = 10
+ BorderSpacing.Right = 10
+ BorderSpacing.Bottom = 10
+ Caption = 'Run in a separate process'
+ TabOrder = 0
end
end
object Tab_Vulkan: TTabSheet
Caption = 'Vulkan'
- ClientHeight = 242
- ClientWidth = 389
+ ClientHeight = 261
+ ClientWidth = 441
object Edt_VulkanInfo_device_cmb: TComboBox
AnchorSideLeft.Control = Tab_Vulkan
AnchorSideTop.Control = Label4
@@ -439,7 +491,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 23
Top = 35
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -456,7 +508,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 15
Top = 10
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -472,7 +524,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 165
Top = 68
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
AutoFill = True
AutoSize = True
@@ -489,7 +541,7 @@ object frmCfgEditor: TfrmCfgEditor
ChildSizing.Layout = cclTopToBottomThenLeftToRight
ChildSizing.ControlsPerLine = 7
ClientHeight = 145
- ClientWidth = 365
+ ClientWidth = 417
ColumnLayout = clVerticalThenHorizontal
Columns = 2
Items.Strings = (
@@ -516,22 +568,36 @@ object frmCfgEditor: TfrmCfgEditor
end
object Tab_PS4System: TTabSheet
Caption = 'PS4 System'
- ClientHeight = 242
- ClientWidth = 389
+ ClientHeight = 261
+ ClientWidth = 441
object PanelHalf: TPanel
AnchorSideLeft.Control = Tab_PS4System
AnchorSideLeft.Side = asrCenter
- AnchorSideRight.Control = Tab_PS4System
AnchorSideRight.Side = asrCenter
- Left = 188
- Height = 49
- Top = 64
+ Left = 214
+ Height = 26
+ Top = 151
Width = 12
- Anchors = [akTop, akLeft, akRight]
BevelOuter = bvNone
Enabled = False
TabOrder = 0
end
+ object Label5: TLabel
+ AnchorSideLeft.Control = Tab_PS4System
+ AnchorSideTop.Control = Edt_PS4SystemService_SystemName
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = Tab_PS4System
+ AnchorSideRight.Side = asrBottom
+ Left = 10
+ Height = 15
+ Top = 68
+ Width = 421
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 10
+ BorderSpacing.Top = 10
+ BorderSpacing.Right = 10
+ Caption = 'Language:'
+ end
object Edt_PS4SystemService_Language: TComboBox
AnchorSideLeft.Control = Tab_PS4System
AnchorSideTop.Control = Label5
@@ -541,7 +607,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 23
Top = 93
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -591,7 +657,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 23
Top = 151
- Width = 168
+ Width = 194
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -613,7 +679,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 15
Top = 126
- Width = 168
+ Width = 194
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -627,10 +693,10 @@ object frmCfgEditor: TfrmCfgEditor
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Tab_PS4System
AnchorSideRight.Side = asrBottom
- Left = 210
+ Left = 236
Height = 23
Top = 151
- Width = 169
+ Width = 195
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -650,10 +716,10 @@ object frmCfgEditor: TfrmCfgEditor
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Tab_PS4System
AnchorSideRight.Side = asrBottom
- Left = 210
+ Left = 236
Height = 15
Top = 126
- Width = 169
+ Width = 195
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -668,7 +734,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 15
Top = 184
- Width = 168
+ Width = 194
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -683,7 +749,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 23
Top = 209
- Width = 168
+ Width = 194
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -704,29 +770,13 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 15
Top = 10
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
BorderSpacing.Right = 10
Caption = 'System Name:'
end
- object Label5: TLabel
- AnchorSideLeft.Control = Tab_PS4System
- AnchorSideTop.Control = Edt_PS4SystemService_SystemName
- AnchorSideTop.Side = asrBottom
- AnchorSideRight.Control = Tab_PS4System
- AnchorSideRight.Side = asrBottom
- Left = 10
- Height = 15
- Top = 68
- Width = 369
- Anchors = [akTop, akLeft, akRight]
- BorderSpacing.Left = 10
- BorderSpacing.Top = 10
- BorderSpacing.Right = 10
- Caption = 'Language:'
- end
object Edt_PS4SystemService_SystemName: TEdit
AnchorSideLeft.Control = Tab_PS4System
AnchorSideTop.Control = Label9
@@ -736,7 +786,7 @@ object frmCfgEditor: TfrmCfgEditor
Left = 10
Height = 23
Top = 35
- Width = 369
+ Width = 421
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
@@ -752,9 +802,9 @@ object frmCfgEditor: TfrmCfgEditor
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
- Left = 315
+ Left = 374
Height = 25
- Top = 284
+ Top = 304
Width = 75
Anchors = [akRight, akBottom]
AutoSize = True
@@ -772,7 +822,7 @@ object frmCfgEditor: TfrmCfgEditor
AnchorSideBottom.Side = asrBottom
Left = 10
Height = 25
- Top = 284
+ Top = 304
Width = 75
Anchors = [akLeft, akBottom]
AutoSize = True
diff --git a/gui/cfg_edit.pas b/gui/cfg_edit.pas
index 90b78175..877972a3 100644
--- a/gui/cfg_edit.pas
+++ b/gui/cfg_edit.pas
@@ -6,12 +6,15 @@ interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, StdCtrls,
- ExtCtrls,
+ ExtCtrls, Buttons,
+
+ lclintf,
Vulkan,
vDevice,
- game_info;
+ game_info,
+ form_filler;
type
TVulkanDevGuid=class(TComponent)
@@ -31,11 +34,14 @@ type
{ TfrmCfgEditor }
TfrmCfgEditor = class(TForm)
+ BtnExpSys: TSpeedButton;
+ BtnRemFw: TSpeedButton;
BtnCancel: TButton;
- BtnSysOpen: TButton;
+ BtnAddFw: TSpeedButton;
BtnOk: TButton;
BtnLogOpen: TButton;
- BtnDataOpen: TButton;
+ Edt_MainInfo_DefaultFirmware: TComboBox;
+ Edt_MiscInfo_fork_proc: TCheckBox;
Edt_PS4SystemService_SystemName: TEdit;
Edt_PS4SystemService_ButtonAssign: TComboBox;
Edt_PS4SystemService_TimeFormat: TComboBox;
@@ -54,12 +60,9 @@ type
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;
@@ -70,20 +73,23 @@ type
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
+ Edt_MainInfo_FirmwareList: TListBox;
PanelHalf: TPanel;
+ BtnExpLog: TSpeedButton;
Tab_PS4System: TTabSheet;
Tab_Vulkan: TTabSheet;
Tab_Misc: TTabSheet;
Tab_JIT: TTabSheet;
Tab_MainInfo: TTabSheet;
Tab_BootparamInfo: TTabSheet;
+ procedure BtnAddFwClick(Sender: TObject);
procedure BtnCancelClick(Sender: TObject);
- procedure BtnDataOpenClick(Sender: TObject);
+ procedure BtnExpLogClick(Sender: TObject);
+ procedure BtnExpSysClick(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 BtnRemFwClick(Sender: TObject);
+ procedure Edt_MainInfo_DefaultFirmwareGetItems(Sender: TObject);
procedure VulkanInit;
procedure FormInit;
procedure FormSave;
@@ -108,6 +114,7 @@ uses
TypInfo,
Rtti,
+ ms_shell_hack,
ps4_libSceSystemService;
var
@@ -142,71 +149,120 @@ begin
Close;
end;
-procedure DoOpenFile(Edit:TEdit);
+function DoOpenFile(const Input,InitialDir:RawByteString):RawByteString;
var
d:TOpenDialog;
+ Cookie:Pointer;
begin
+ Cookie:=RegisterDllHack;
+
+ Result:=Input;
d:=nil;
try
d:=TOpenDialog.Create(nil);
- d.InitialDir:=Edit.Text;
+ d.InitialDir:=InitialDir;
d.Options:=[ofPathMustExist,ofEnableSizing,ofViewDetail];
if d.Execute then
begin
- Edit.Text:=d.FileName;
+ Result:=d.FileName;
end;
except
//
end;
FreeAndNil(d);
+
+ UnregisterDllHack(Cookie);
end;
-procedure DoOpenDir(Edit:TEdit);
+function DoOpenDir(const Input,InitialDir:RawByteString):RawByteString;
var
d:TSelectDirectoryDialog;
+ Cookie:Pointer;
begin
+ Cookie:=RegisterDllHack;
+
+ Result:=Input;
d:=nil;
try
d:=TSelectDirectoryDialog.Create(nil);
- d.InitialDir:=Edit.Text;
+ d.InitialDir:=InitialDir;
d.Options:=[ofPathMustExist,ofEnableSizing,ofViewDetail];
if d.Execute then
begin
- Edit.Text:=d.FileName;
+ Result:=d.FileName;
end;
except
//
end;
FreeAndNil(d);
+
+ UnregisterDllHack(Cookie);
end;
procedure TfrmCfgEditor.BtnLogOpenClick(Sender: TObject);
begin
- DoOpenFile(Edt_MainInfo_LogFile);
+ Edt_MainInfo_LogFile.Text:=DoOpenFile(Edt_MainInfo_LogFile.Text,Edt_MainInfo_LogFile.Text);
end;
-procedure TfrmCfgEditor.BtnSysOpenClick(Sender: TObject);
+procedure TfrmCfgEditor.BtnAddFwClick(Sender:TObject);
+var
+ new:RawByteString;
begin
- DoOpenDir(Edt_MainInfo_system);
+ new:=DoOpenDir('','');
+ if (new='') then Exit;
+
+ Edt_MainInfo_FirmwareList .Items.Add(new);
+ Edt_MainInfo_DefaultFirmware.Items.Add(new);
end;
-procedure TfrmCfgEditor.BtnDataOpenClick(Sender: TObject);
+procedure TfrmCfgEditor.BtnRemFwClick(Sender: TObject);
+var
+ i:Integer;
begin
- DoOpenDir(Edt_MainInfo_data);
+ i:=Edt_MainInfo_FirmwareList.ItemIndex;
+ if (i>=0) and (i0) then
+ begin
+ //preload
+ For i:=0 to Edt_MainInfo_FirmwareList.Items.Count-1 do
+ begin
+ S:=Edt_MainInfo_FirmwareList.Items.Strings[i];
+ Edt_MainInfo_DefaultFirmware.Items.Add(S);
+ end;
end;
+end;
- TMyButtonControl=class(TButtonControl)
- public
- property Checked;
+function OpenFolderOfFile(APath:RawByteString): Boolean;
+begin
+ APath:=ExtractFilePath(APath);
+ if (Trim(APath)='') then
+ begin
+ APath:=GetCurrentDir;
end;
+ Result:=OpenDocument(APath);
+end;
-//src: TComboBox;
+procedure TfrmCfgEditor.BtnExpLogClick(Sender: TObject);
+begin
+ OpenFolderOfFile(Edt_MainInfo_LogFile.Text);
+end;
+
+procedure TfrmCfgEditor.BtnExpSysClick(Sender: TObject);
+begin
+ OpenDocument(Edt_MainInfo_DefaultFirmware.Text);
+end;
Function TVulkanDevGuid.GetText:RawByteString;
var
@@ -279,8 +335,19 @@ begin
end;
//
+type
+ TCfgFormData=class(TFormDataProvider)
+ procedure SetText (control:TComponent;const Text:RawByteString); override;
+ function GetText (control:TComponent):RawByteString; override;
+ procedure SetInteger(control:TComponent;i:Integer); override;
+ function GetInteger(control:TComponent):Integer; override;
+ procedure SetBool (control:TComponent;B:Boolean); override;
+ function GetBool (control:TComponent):Boolean; override;
+ procedure SetClass (control:TComponent;Obj:TObject); override;
+ procedure GetClass (control:TComponent;Obj:TObject); override;
+ end;
-procedure SetText(control:TComponent;const Text:RawByteString);
+procedure TCfgFormData.SetText(control:TComponent;const Text:RawByteString);
begin
if (control is TVulkanDevGuid) then
begin
@@ -292,7 +359,7 @@ begin
end;
end;
-function GetText(control:TComponent):RawByteString;
+function TCfgFormData.GetText(control:TComponent):RawByteString;
begin
Result:='';
if (control is TVulkanDevGuid) then
@@ -307,7 +374,7 @@ end;
//
-procedure SetInteger(control:TComponent;i:Integer);
+procedure TCfgFormData.SetInteger(control:TComponent;i:Integer);
begin
if (control is TVulkanAppFlags) then
begin
@@ -337,7 +404,7 @@ begin
end;
end;
-function GetInteger(control:TComponent):Integer;
+function TCfgFormData.GetInteger(control:TComponent):Integer;
begin
Result:=0;
if (control is TVulkanAppFlags) then
@@ -352,7 +419,7 @@ end;
//
-procedure SetBool(control:TComponent;B:Boolean);
+procedure TCfgFormData.SetBool(control:TComponent;B:Boolean);
begin
if control.InheritsFrom(TButtonControl) then
begin
@@ -360,7 +427,7 @@ begin
end;
end;
-function GetBool(control:TComponent):Boolean;
+function TCfgFormData.GetBool(control:TComponent):Boolean;
begin
Result:=False;
if control.InheritsFrom(TButtonControl) then
@@ -369,114 +436,48 @@ begin
end;
end;
+procedure TCfgFormData.SetClass(control:TComponent;Obj:TObject);
+var
+ A:TStringArray;
+ i:Integer;
+begin
+ if control.InheritsFrom(TListBox) then
+ begin
+ A:=TStringArray(Obj);
+
+ if (Length(A.values)>0) then
+ For i:=0 to High(A.values) do
+ begin
+ TListBox(control).Items.Add(A.values[i]);
+ end;
+
+ end;
+end;
+
+procedure TCfgFormData.GetClass(control:TComponent;Obj:TObject);
+var
+ A:TStringArray;
+ i,c:Integer;
+begin
+ if control.InheritsFrom(TListBox) then
+ begin
+ A:=TStringArray(Obj);
+
+ c:=TListBox(control).Items.Count;
+
+ SetLength(A.values,c);
+
+ if (c>0) then
+ For i:=0 to c-1 do
+ begin
+ A.values[i]:=TListBox(control).Items.Strings[i];
+ end;
+
+ 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))+'.'+
@@ -561,80 +562,30 @@ end;
procedure TfrmCfgEditor.FormInit;
var
- i:TRttiPropertyIterator;
- p:TRttiProperty;
- obj:TObject;
+ Provider:TCfgFormData;
begin
VulkanInit;
EditPages.ActivePageIndex:=0;
- i:=FConfigInfo.GetPropertyIterator;
- try
- while (i.GetProperty<>nil) do
- begin
+ Provider:=TCfgFormData.Create;
- p:=i.GetProperty;
+ FormLoad(Self,Provider,FConfigInfo);
- 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;
+ Provider.Free;
Show;
end;
procedure TfrmCfgEditor.FormSave;
var
- i:TRttiPropertyIterator;
- p:TRttiProperty;
- obj:TObject;
+ Provider:TCfgFormData;
begin
- i:=FConfigInfo.GetPropertyIterator;
- try
- while (i.GetProperty<>nil) do
- begin
+ Provider:=TCfgFormData.Create;
- p:=i.GetProperty;
+ form_filler.FormSave(Self,Provider,FConfigInfo);
- 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;
+ Provider.Free;
end;
end.
diff --git a/gui/form_filler.pas b/gui/form_filler.pas
new file mode 100644
index 00000000..18e7fcc6
--- /dev/null
+++ b/gui/form_filler.pas
@@ -0,0 +1,262 @@
+unit form_filler;
+
+{$mode ObjFPC}{$H+}
+
+interface
+
+uses
+ Classes,
+ SysUtils,
+ Controls,
+ StdCtrls,
+ TypInfo,
+ Rtti,
+ game_info;
+
+type
+ TFormDataProvider=class
+ procedure SetText (control:TComponent;const Text:RawByteString); virtual; abstract;
+ function GetText (control:TComponent):RawByteString; virtual; abstract;
+ procedure SetInteger(control:TComponent;i:Integer); virtual; abstract;
+ function GetInteger(control:TComponent):Integer; virtual; abstract;
+ procedure SetBool (control:TComponent;B:Boolean); virtual; abstract;
+ function GetBool (control:TComponent):Boolean; virtual; abstract;
+ procedure SetClass (control:TComponent;Obj:TObject); virtual; abstract;
+ procedure GetClass (control:TComponent;Obj:TObject); virtual; abstract;
+ end;
+
+type
+ TMyControl=class(TControl)
+ public
+ property Text;
+ end;
+
+ TMyButtonControl=class(TButtonControl)
+ public
+ property Checked;
+ end;
+
+procedure PageLoad(Parent:TComponent;
+ const TabName:RawByteString;
+ Provider:TFormDataProvider;
+ src:TAbstractObject);
+
+procedure FormLoad(Parent:TComponent;
+ Provider:TFormDataProvider;
+ src:TAbstractObject);
+
+procedure PageSave(Parent:TComponent;
+ const TabName:RawByteString;
+ Provider:TFormDataProvider;
+ dst:TAbstractObject);
+
+procedure FormSave(Parent:TComponent;
+ Provider:TFormDataProvider;
+ dst:TAbstractObject);
+
+implementation
+
+procedure PageLoad(Parent:TComponent;
+ const TabName:RawByteString;
+ Provider:TFormDataProvider;
+ src:TAbstractObject);
+var
+ i:TRttiPropertyIterator;
+ p:TRttiProperty;
+ TypeKind:TTypeKind;
+
+ cname:RawByteString;
+ control:TComponent;
+begin
+
+ i:=src.GetPropertyIterator;
+ try
+ while (i.GetProperty<>nil) do
+ begin
+
+ p:=i.GetProperty;
+
+ cname:='Edt_'+TabName+'_'+p.Name;
+ control:=Parent.FindComponent(cname);
+ Assert(control<>nil,'Control:'+cname+' not found!');
+ if (control=nil) then Exit;
+
+ TypeKind:=p.PropertyType.TypeKind;
+ case TypeKind of
+
+ tkSString,
+ tkLString,
+ tkAString:
+ begin
+ Provider.SetText(control,p.GetValue(src).AsString);
+ end;
+
+ tkInteger:
+ begin
+ Provider.SetInteger(control,p.GetValue(src).AsInteger);
+ end;
+
+ tkBool:
+ begin
+ Provider.SetBool(control,p.GetValue(src).AsBoolean);
+ end;
+
+ tkClass:
+ begin
+ Provider.SetClass(control,p.GetValue(src).AsObject);
+ end;
+
+ else
+ Assert(false);
+ end;
+
+ i.Next;
+ end;
+ finally
+ i.free;
+ end;
+end;
+
+procedure FormLoad(Parent:TComponent;
+ Provider:TFormDataProvider;
+ src:TAbstractObject);
+var
+ i:TRttiPropertyIterator;
+ p:TRttiProperty;
+ obj:TObject;
+begin
+ i:=src.GetPropertyIterator;
+ try
+ while (i.GetProperty<>nil) do
+ begin
+
+ p:=i.GetProperty;
+
+ case p.PropertyType.TypeKind of
+
+ tkClass:
+ begin
+ obj:=p.GetValue(src).AsObject;
+
+ if (obj<>nil) then
+ if obj.InheritsFrom(TAbstractObject) then
+ begin
+ PageLoad(Parent,p.Name,Provider,TAbstractObject(obj));
+ end;
+ end;
+
+ else;
+ end;
+
+ i.Next;
+ end;
+ finally
+ i.free;
+ end;
+
+end;
+
+//////////////
+
+procedure PageSave(Parent:TComponent;
+ const TabName:RawByteString;
+ Provider:TFormDataProvider;
+ dst:TAbstractObject);
+var
+ i:TRttiPropertyIterator;
+ p:TRttiProperty;
+ TypeKind:TTypeKind;
+
+ cname:RawByteString;
+ control:TComponent;
+begin
+
+ i:=dst.GetPropertyIterator;
+ try
+ while (i.GetProperty<>nil) do
+ begin
+
+ p:=i.GetProperty;
+
+ cname:='Edt_'+TabName+'_'+p.Name;
+ control:=Parent.FindComponent(cname);
+ Assert(control<>nil,cname);
+ if (control=nil) then Exit;
+
+ TypeKind:=p.PropertyType.TypeKind;
+ case TypeKind of
+
+ tkSString,
+ tkLString,
+ tkAString:
+ begin
+ p.SetValue(dst,Provider.GetText(control));
+ end;
+
+ tkInteger:
+ begin
+ p.SetValue(dst,Provider.GetInteger(control));
+ end;
+
+ tkBool:
+ begin
+ p.SetValue(dst,Provider.GetBool(control));
+ end;
+
+ tkClass:
+ begin
+ Provider.GetClass(control,p.GetValue(dst).AsObject);
+ end;
+
+ else
+ Assert(false);
+ end;
+
+ i.Next;
+ end;
+ finally
+ i.free;
+ end;
+end;
+
+procedure FormSave(Parent:TComponent;
+ Provider:TFormDataProvider;
+ dst:TAbstractObject);
+var
+ i:TRttiPropertyIterator;
+ p:TRttiProperty;
+ obj:TObject;
+begin
+ i:=dst.GetPropertyIterator;
+ try
+ while (i.GetProperty<>nil) do
+ begin
+
+ p:=i.GetProperty;
+
+ case p.PropertyType.TypeKind of
+
+ tkClass:
+ begin
+ obj:=p.GetValue(dst).AsObject;
+
+ if (obj<>nil) then
+ if obj.InheritsFrom(TAbstractObject) then
+ begin
+ PageSave(Parent,p.Name,Provider,TAbstractObject(obj));
+ end;
+ end;
+
+ else;
+ end;
+
+ i.Next;
+ end;
+ finally
+ i.free;
+ end;
+end;
+
+
+end.
+
diff --git a/gui/game_edit.lfm b/gui/game_edit.lfm
index 0f5bacfe..d251fc91 100644
--- a/gui/game_edit.lfm
+++ b/gui/game_edit.lfm
@@ -1,85 +1,342 @@
object frmGameEditor: TfrmGameEditor
- Left = 501
- Height = 319
- Top = 124
- Width = 397
+ Left = 318
+ Height = 311
+ Top = 113
+ Width = 467
Caption = 'Game editor'
- ClientHeight = 319
- ClientWidth = 397
+ ClientHeight = 311
+ ClientWidth = 467
OnClose = FormClose
Position = poMainFormCenter
- LCLVersion = '3.6.0.0'
+ LCLVersion = '3.8.0.0'
object EditPages: TPageControl
AnchorSideBottom.Control = BtnOk
Left = 0
- Height = 274
+ Height = 266
Top = 0
- Width = 397
- ActivePage = TabMain
+ Width = 467
+ ActivePage = TabFolders
Align = alCustom
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Bottom = 10
- TabIndex = 0
+ TabIndex = 1
TabOrder = 0
object TabMain: TTabSheet
Caption = 'Main'
- ClientHeight = 246
- ClientWidth = 389
- object GridMain: TStringGrid
- Left = 0
- Height = 246
- Top = 0
- Width = 389
- Align = alClient
- AutoFillColumns = True
- ColCount = 2
- FixedRows = 0
- Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goEditing, goThumbTracking, goSmoothScroll]
- RowCount = 1
+ ClientHeight = 238
+ ClientWidth = 459
+ object Label1: TLabel
+ AnchorSideLeft.Control = TabMain
+ AnchorSideTop.Control = TabMain
+ AnchorSideRight.Control = TabMain
+ AnchorSideRight.Side = asrBottom
+ Left = 10
+ Height = 15
+ Top = 10
+ Width = 439
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 10
+ BorderSpacing.Top = 10
+ BorderSpacing.Right = 10
+ Caption = 'Name:'
+ end
+ object Edt_GameInfo_Name: TEdit
+ AnchorSideLeft.Control = TabMain
+ AnchorSideTop.Control = Label1
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = TabMain
+ AnchorSideRight.Side = asrBottom
+ Left = 10
+ Height = 23
+ Top = 35
+ Width = 439
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 10
+ BorderSpacing.Top = 10
+ BorderSpacing.Right = 10
+ MaxLength = 65
TabOrder = 0
- TitleStyle = tsNative
- OnEditingDone = GridEditingDone
- OnSelectEditor = GridSelectEditor
- ColWidths = (
- 64
- 321
- )
+ end
+ object Label2: TLabel
+ AnchorSideLeft.Control = TabMain
+ AnchorSideTop.Control = Edt_GameInfo_Name
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = TabMain
+ AnchorSideRight.Side = asrBottom
+ Left = 10
+ Height = 15
+ Top = 68
+ Width = 439
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 10
+ BorderSpacing.Top = 10
+ BorderSpacing.Right = 10
+ Caption = 'TitleId:'
+ end
+ object Edt_GameInfo_TitleId: TEdit
+ AnchorSideLeft.Control = TabMain
+ AnchorSideTop.Control = Label2
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = TabMain
+ AnchorSideRight.Side = asrBottom
+ Left = 10
+ Height = 23
+ Top = 93
+ Width = 439
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 10
+ BorderSpacing.Top = 10
+ BorderSpacing.Right = 10
+ MaxLength = 65
+ ReadOnly = True
+ TabOrder = 1
+ end
+ object Label3: TLabel
+ AnchorSideLeft.Control = TabMain
+ AnchorSideTop.Control = Edt_GameInfo_TitleId
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = PanelHalf
+ Left = 10
+ Height = 15
+ Top = 126
+ Width = 203
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 10
+ BorderSpacing.Top = 10
+ BorderSpacing.Right = 10
+ Caption = 'Master version:'
+ end
+ object Edt_GameInfo_Version: TEdit
+ AnchorSideLeft.Control = TabMain
+ AnchorSideTop.Control = Label3
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = PanelHalf
+ Left = 10
+ Height = 23
+ Top = 151
+ Width = 203
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 10
+ BorderSpacing.Top = 10
+ BorderSpacing.Right = 10
+ MaxLength = 65
+ ReadOnly = True
+ TabOrder = 2
+ end
+ object Label4: TLabel
+ AnchorSideLeft.Control = TabMain
+ AnchorSideTop.Control = Edt_GameInfo_Version
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = TabMain
+ AnchorSideRight.Side = asrBottom
+ Left = 10
+ Height = 15
+ Top = 184
+ Width = 439
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 10
+ BorderSpacing.Top = 10
+ BorderSpacing.Right = 10
+ Caption = 'Exec command:'
+ end
+ object Edt_GameInfo_Exec: TEdit
+ AnchorSideLeft.Control = TabMain
+ AnchorSideTop.Control = Label4
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = TabMain
+ AnchorSideRight.Side = asrBottom
+ Left = 10
+ Height = 23
+ Top = 209
+ Width = 439
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 10
+ BorderSpacing.Top = 10
+ BorderSpacing.Right = 10
+ MaxLength = 65
+ TabOrder = 5
+ end
+ object PanelHalf: TPanel
+ AnchorSideLeft.Control = TabMain
+ AnchorSideLeft.Side = asrCenter
+ AnchorSideRight.Side = asrCenter
+ Left = 223
+ Height = 23
+ Top = 151
+ Width = 12
+ BevelOuter = bvNone
+ Enabled = False
+ TabOrder = 4
+ TabStop = True
+ end
+ object Label7: TLabel
+ AnchorSideLeft.Control = PanelHalf
+ AnchorSideLeft.Side = asrBottom
+ AnchorSideTop.Control = Edt_GameInfo_TitleId
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = TabMain
+ AnchorSideRight.Side = asrBottom
+ Left = 245
+ Height = 15
+ Top = 126
+ Width = 204
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 10
+ BorderSpacing.Top = 10
+ BorderSpacing.Right = 10
+ Caption = 'Application version:'
+ end
+ object Edt_GameInfo_AppVer: TEdit
+ AnchorSideLeft.Control = PanelHalf
+ AnchorSideLeft.Side = asrBottom
+ AnchorSideTop.Control = Label3
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = TabMain
+ AnchorSideRight.Side = asrBottom
+ Left = 245
+ Height = 23
+ Top = 151
+ Width = 204
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 10
+ BorderSpacing.Top = 10
+ BorderSpacing.Right = 10
+ MaxLength = 65
+ ReadOnly = True
+ TabOrder = 3
end
end
- object TabMounts: TTabSheet
- Caption = 'Mounts'
- ClientHeight = 246
- ClientWidth = 389
- object GridMounts: TStringGrid
- Left = 0
- Height = 246
- Top = 0
- Width = 389
- Align = alClient
- AutoFillColumns = True
- ColCount = 2
- FixedRows = 0
- Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goEditing, goThumbTracking, goSmoothScroll]
- RowCount = 1
+ object TabFolders: TTabSheet
+ Caption = 'Folders'
+ ClientHeight = 238
+ ClientWidth = 459
+ object Label5: TLabel
+ AnchorSideLeft.Control = TabFolders
+ AnchorSideTop.Control = TabFolders
+ AnchorSideRight.Control = TabFolders
+ AnchorSideRight.Side = asrBottom
+ Left = 10
+ Height = 15
+ Top = 10
+ Width = 439
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 10
+ BorderSpacing.Top = 10
+ BorderSpacing.Right = 10
+ Caption = 'Game:'
+ end
+ object Edt_MountList_game: TEdit
+ AnchorSideLeft.Control = TabFolders
+ AnchorSideTop.Control = Label5
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = BtnExpGame
+ Left = 10
+ Height = 23
+ Top = 35
+ Width = 414
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 10
+ BorderSpacing.Top = 10
TabOrder = 0
- TitleStyle = tsNative
- OnEditingDone = GridEditingDone
- OnSelectEditor = GridSelectEditor
- ColWidths = (
- 64
- 304
- )
+ OnExit = Edt_MountList_gameExit
+ end
+ object BtnGameOpen: TButton
+ AnchorSideTop.Control = Edt_MountList_game
+ AnchorSideRight.Control = Edt_MountList_game
+ AnchorSideRight.Side = asrBottom
+ AnchorSideBottom.Control = Edt_MountList_game
+ AnchorSideBottom.Side = asrBottom
+ Left = 388
+ Height = 21
+ Top = 36
+ Width = 35
+ Anchors = [akTop, akRight, akBottom]
+ AutoSize = True
+ BorderSpacing.Top = 1
+ BorderSpacing.Right = 1
+ BorderSpacing.Bottom = 1
+ Caption = '...'
+ TabOrder = 1
+ OnClick = BtnGameOpenClick
+ end
+ object BtnExpGame: TSpeedButton
+ AnchorSideLeft.Side = asrBottom
+ AnchorSideTop.Control = Edt_MountList_game
+ AnchorSideTop.Side = asrCenter
+ AnchorSideRight.Control = TabFolders
+ AnchorSideRight.Side = asrBottom
+ AnchorSideBottom.Side = asrCenter
+ Left = 429
+ Height = 20
+ Top = 36
+ Width = 20
+ Anchors = [akTop, akRight]
+ AutoSize = True
+ BorderSpacing.Left = 5
+ BorderSpacing.Right = 10
+ Images = frmMain.SmallImageList
+ ImageIndex = 0
+ OnClick = BtnExpGameClick
+ end
+ object Label6: TLabel
+ AnchorSideTop.Control = Edt_MountList_game
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Side = asrBottom
+ Left = 8
+ Height = 15
+ Top = 68
+ Width = 451
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 10
+ BorderSpacing.Top = 10
+ BorderSpacing.Right = 10
+ Caption = 'Firmware:'
+ end
+ object Edt_MountList_firmware: TComboBox
+ AnchorSideLeft.Control = TabFolders
+ AnchorSideTop.Control = Label6
+ AnchorSideTop.Side = asrBottom
+ AnchorSideRight.Control = BtnExpFw
+ Left = 10
+ Height = 23
+ Top = 93
+ Width = 414
+ Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 10
+ BorderSpacing.Top = 10
+ ItemHeight = 15
+ TabOrder = 2
+ OnGetItems = Edt_MountList_firmwareGetItems
+ end
+ object BtnExpFw: TSpeedButton
+ AnchorSideLeft.Side = asrBottom
+ AnchorSideTop.Control = Edt_MountList_firmware
+ AnchorSideTop.Side = asrCenter
+ AnchorSideRight.Control = TabFolders
+ AnchorSideRight.Side = asrBottom
+ AnchorSideBottom.Side = asrCenter
+ Left = 429
+ Height = 20
+ Top = 94
+ Width = 20
+ Anchors = [akTop, akRight]
+ AutoSize = True
+ BorderSpacing.Left = 5
+ BorderSpacing.Right = 10
+ Images = frmMain.SmallImageList
+ ImageIndex = 0
+ OnClick = BtnExpFwClick
end
end
object TabParamSfo: TTabSheet
Caption = 'param.sfo'
- ClientHeight = 246
- ClientWidth = 389
+ ClientHeight = 238
+ ClientWidth = 459
object GridParamSfo: TStringGrid
Left = 0
- Height = 246
+ Height = 238
Top = 0
- Width = 389
+ Width = 459
Align = alClient
AutoFillColumns = True
ColCount = 2
@@ -88,11 +345,9 @@ object frmGameEditor: TfrmGameEditor
RowCount = 1
TabOrder = 0
TitleStyle = tsNative
- OnEditingDone = GridEditingDone
- OnSelectEditor = GridSelectEditor
ColWidths = (
64
- 304
+ 374
)
end
end
@@ -103,7 +358,7 @@ object frmGameEditor: TfrmGameEditor
AnchorSideBottom.Side = asrBottom
Left = 10
Height = 25
- Top = 284
+ Top = 276
Width = 75
Anchors = [akLeft, akBottom]
AutoSize = True
@@ -121,9 +376,9 @@ object frmGameEditor: TfrmGameEditor
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
- Left = 312
+ Left = 382
Height = 25
- Top = 284
+ Top = 276
Width = 75
Anchors = [akRight, akBottom]
AutoSize = True
diff --git a/gui/game_edit.pas b/gui/game_edit.pas
index f3c457c1..cd3e6c9e 100644
--- a/gui/game_edit.pas
+++ b/gui/game_edit.pas
@@ -6,11 +6,14 @@ interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, ExtCtrls,
- StdCtrls, Grids,
+ StdCtrls, Grids, Buttons,
+
+ LCLIntf,
ms_shell_hack,
game_info,
+ form_filler,
param_sfo_gui;
type
@@ -18,34 +21,49 @@ type
{ TfrmGameEditor }
TfrmGameEditor = class(TForm)
+ BtnExpGame: TSpeedButton;
+ BtnExpFw: TSpeedButton;
+ BtnGameOpen: TButton;
BtnOk: TButton;
BtnCancel: TButton;
EditPages: TPageControl;
- GridMain: TStringGrid;
- GridMounts: TStringGrid;
+ Edt_GameInfo_Name: TEdit;
+ Edt_GameInfo_Exec: TEdit;
+ Edt_GameInfo_TitleId: TEdit;
+ Edt_GameInfo_Version: TEdit;
+ Edt_GameInfo_AppVer: TEdit;
+ Edt_MountList_game: TEdit;
+ Edt_MountList_firmware: TComboBox;
GridParamSfo: TStringGrid;
+ Label1: TLabel;
+ Label2: TLabel;
+ Label3: TLabel;
+ Label4: TLabel;
+ Label5: TLabel;
+ Label6: TLabel;
+ Label7: TLabel;
+ PanelHalf: TPanel;
TabMain: TTabSheet;
- TabMounts: TTabSheet;
+ TabFolders: TTabSheet;
TabParamSfo: TTabSheet;
+ procedure BtnExpFwClick(Sender: TObject);
+ procedure BtnExpGameClick(Sender: TObject);
+ procedure BtnGameOpenClick(Sender: TObject);
procedure BtnOkClick(Sender: TObject);
procedure BtnCancelClick(Sender: TObject);
+ procedure Edt_MountList_firmwareGetItems(Sender: TObject);
+ procedure Edt_MountList_gameExit(Sender: TObject);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormInit(UpdateTitle:Boolean);
procedure FormSave;
procedure LoadParamSfo(UpdateTitle:Boolean);
- procedure GridSelectEditor(Sender:TObject;aCol,aRow:Integer;var Editor:TWinControl);
- procedure GridEditingDone(Sender: TObject);
private
- Fapp0_row :Integer;
- FName_row :Integer;
- FTitleId_row:Integer;
- FVersion_row:Integer;
-
- Fapp0p:RawByteString;
+ Fgame:RawByteString;
public
- OnSave :TNotifyEvent;
- Item :TGameItem;
- ParamSfo:TParamSfoFile;
+ OnSave :TNotifyEvent;
+ FConfigInfo:TConfigInfo;
+ FItem :TGameItem;
+ FParamSfo :TParamSfoFile;
end;
var
@@ -61,147 +79,32 @@ uses
{ TfrmGameEditor }
-type
- TFieldInfo=class(TComponent)
- procedure SelectEditor(Grid:TStringGrid;aCol,aRow:Integer;var Editor:TWinControl); virtual; abstract;
- end;
-
- TFieldInfoPath=class(TFieldInfo)
- procedure SelectEditor(Grid:TStringGrid;aCol,aRow:Integer;var Editor:TWinControl); override;
- end;
-
- TButtonPath=class(TButton)
- public
- aRow:Integer;
- Form :TWinControl;
- Editor:TWinControl;
- procedure EditorExit(Sender:TObject);
- procedure OpenDir(Sender:TObject);
- end;
-
-procedure TButtonPath.EditorExit(Sender:TObject);
-begin
- Editor.OnEnter:=nil;
- Editor.OnExit :=nil;
- if not Focused then
- begin
- Hide;
- end;
-end;
-
-type
- TMyStringGrid=class(TStringGrid)
- function NewBtn:TButtonPath;
- procedure EditorDirEnter(Sender:TObject);
- end;
-
-procedure TButtonPath.OpenDir(Sender:TObject);
+function DoOpenDir(const Input,InitialDir:RawByteString):RawByteString;
var
d:TSelectDirectoryDialog;
Cookie:Pointer;
begin
Cookie:=RegisterDllHack;
+ Result:=Input;
d:=nil;
-
try
d:=TSelectDirectoryDialog.Create(nil);
-
- with TMyStringGrid(Editor.Parent) do
- begin
- d.InitialDir:=Cells[1,aRow];
- end;
-
+ d.InitialDir:=InitialDir;
d.Options:=[ofPathMustExist,ofEnableSizing,ofViewDetail];
-
if d.Execute then
- with TMyStringGrid(Editor.Parent) do
begin
- Cells[1,aRow]:=d.FileName;
+ Result:=d.FileName;
end;
-
except
//
end;
FreeAndNil(d);
UnregisterDllHack(Cookie);
-
- TfrmGameEditor(Self.Form).LoadParamSfo(True);
-
- Hide;
end;
-function TMyStringGrid.NewBtn:TButtonPath;
-var
- i:Integer;
- btn:TButtonPath;
-begin
- btn:=nil;
-
- if (ComponentCount<>0) then
- for i:=0 to ComponentCount-1 do
- begin
- if Components[i] is TButtonPath then
- begin
- btn:=TButtonPath(Components[i]);
- Break;
- end;
- end;
-
- if (btn=nil) then
- begin
- btn:=TButtonPath.Create(Self);
-
- btn.Form:=TWinControl(Self.Tag);
-
- btn.AutoSize:=True;
- btn.Caption:='...';
-
- btn.Parent:=Self;
-
- btn.BorderSpacing.Top :=-3;
- btn.BorderSpacing.Right :=-3;
- btn.BorderSpacing.Bottom:=-3;
- end;
-
- btn.aRow:=Self.Row;
-
- btn.AnchorSide[akTop].Side:=asrTop;
- btn.AnchorSide[akTop].Control:=Editor;
-
- btn.AnchorSide[akRight].Side:=asrBottom;
- btn.AnchorSide[akRight].Control:=Editor;
-
- btn.AnchorSide[akBottom].Side:=asrBottom;
- btn.AnchorSide[akBottom].Control:=Editor;
-
- btn.Anchors:=[akTop,akRight,akBottom];
-
- btn.Editor:=Editor;
-
- Result:=btn;
-end;
-
-procedure TMyStringGrid.EditorDirEnter(Sender:TObject);
-var
- btn:TButtonPath;
-begin
- btn:=NewBtn;
-
- btn.OnClick:=@btn.OpenDir;
-
- Editor.OnExit:=@btn.EditorExit;
-
- btn.Show;
-end;
-
-procedure TFieldInfoPath.SelectEditor(Grid:TStringGrid;aCol,aRow:Integer;var Editor:TWinControl);
-begin
- Editor.OnEnter:=@TMyStringGrid(Grid).EditorDirEnter;
-end;
-
-procedure AddRow(Grid:TStringGrid;const name,value:RawByteString;info:TFieldInfo);
+procedure AddRow(Grid:TStringGrid;const name,value:RawByteString;obj:TObject);
var
i:Integer;
begin
@@ -209,69 +112,45 @@ begin
Grid.RowCount:=i+1;
Grid.Cells[0,i]:=name;
Grid.Cells[1,i]:=value;
- Grid.Objects[0,i]:=info;
+ Grid.Objects[0,i]:=obj;
+end;
+
+type
+ TGameFormData=class(TFormDataProvider)
+ procedure SetText(control:TComponent;const Text:RawByteString); override;
+ function GetText(control:TComponent):RawByteString; override;
+ end;
+
+procedure TGameFormData.SetText(control:TComponent;const Text:RawByteString);
+begin
+ if control.InheritsFrom(TControl) then
+ begin
+ TMyControl(control).Text:=Text;
+ end;
+end;
+
+function TGameFormData.GetText(control:TComponent):RawByteString;
+begin
+ Result:='';
+ if control.InheritsFrom(TControl) then
+ begin
+ Result:=TMyControl(control).Text;
+ end;
end;
procedure TfrmGameEditor.FormInit(UpdateTitle:Boolean);
var
- fip:TFieldInfoPath;
-
- i:TRttiPropertyIterator;
- p:TRttiProperty;
+ Provider:TGameFormData;
begin
EditPages.ActivePageIndex:=0;
- GridMain.Clear;
- GridMounts.Clear;
+ Provider:=TGameFormData.Create;
- //TypInfo.SetRawByteStrProp();
+ FormLoad(Self,Provider,FItem);
- //AddRow(GridMain,'Name:',nil);
+ Provider.Free;
- //
- fip:=TFieldInfoPath.Create(Self);
- //
-
- i:=Item.FGameInfo.GetPropertyIterator;
- try
- while (i.GetProperty<>nil) do
- begin
-
- p:=i.GetProperty;
- case p.Name of
- 'Name' :FName_row :=GridMain.RowCount;
- 'TitleId':FTitleId_row:=GridMain.RowCount;
- 'Version':FVersion_row:=GridMain.RowCount;
- else;
- end;
-
- AddRow(GridMain,p.Name+':',p.GetValue(Item.FGameInfo).AsString,nil);
-
- i.Next;
- end;
- finally
- i.free;
- end;
-
- i:=Item.FMountList.GetPropertyIterator;
- try
- while (i.GetProperty<>nil) do
- begin
-
- p:=i.GetProperty;
-
- case p.Name of
- 'app0':Fapp0_row:=GridMounts.RowCount;
- else;
- end;
-
- AddRow(GridMounts,'/'+p.Name,p.GetValue(Item.FMountList).AsString,fip);
-
- i.Next;
- end;
- finally
- i.free;
- end;
+ //////
LoadParamSfo(UpdateTitle);
@@ -280,52 +159,13 @@ end;
procedure TfrmGameEditor.FormSave;
var
- i:TRttiPropertyIterator;
- p:TRttiProperty;
+ Provider:TGameFormData;
begin
- i:=Item.FGameInfo.GetPropertyIterator;
- try
- while (i.GetProperty<>nil) do
- begin
+ Provider:=TGameFormData.Create;
- p:=i.GetProperty;
- p.SetValue(Item.FGameInfo,GridMain.Cells[1,i.i]);
+ form_filler.FormSave(Self,Provider,FItem);
- i.Next;
- end;
- finally
- i.free;
- end;
-
- i:=Item.FMountList.GetPropertyIterator;
- try
- while (i.GetProperty<>nil) do
- begin
-
- p:=i.GetProperty;
- p.SetValue(Item.FMountList,GridMounts.Cells[1,i.i]);
-
- i.Next;
- end;
- finally
- i.free;
- end;
-
-end;
-
-function GetGridVal(Grid:TStringGrid;ARow:Integer):RawByteString;
-begin
- Result:='';
- if (ARow<0) and (ARow>=Grid.RowCount) then Exit;
- //
- Result:=Grid.Cells[1,ARow];
-end;
-
-procedure SetGridVal(Grid:TStringGrid;ARow:Integer;const value:RawByteString);
-begin
- if (ARow<0) and (ARow>=Grid.RowCount) then Exit;
- //
- Grid.Cells[1,ARow]:=value;
+ Provider.Free;
end;
procedure TfrmGameEditor.LoadParamSfo(UpdateTitle:Boolean);
@@ -333,40 +173,39 @@ var
i:Integer;
V:RawByteString;
begin
- V:=GetGridVal(GridMounts,Fapp0_row);
+ V:=Edt_MountList_game.Text;
+ if (Fgame=V) then Exit;
- if (Fapp0p=V) then Exit;
+ FreeAndNil(FParamSfo);
- FreeAndNil(ParamSfo);
+ FParamSfo:=LoadParamSfoFile(ExcludeTrailingPathDelimiter(V)+
+ DirectorySeparator+
+ 'sce_sys'+
+ DirectorySeparator+
+ 'param.sfo');
- ParamSfo:=LoadParamSfoFile(ExcludeTrailingPathDelimiter(V)+
- DirectorySeparator+
- 'sce_sys'+
- DirectorySeparator+
- 'param.sfo');
-
- Fapp0p:=V;
+ Fgame:=V;
GridParamSfo.Clear;
- if (ParamSfo=nil) then
+ if (FParamSfo=nil) then
begin
- SetGridVal(GridMain,FTitleId_row,'???');
- SetGridVal(GridMain,FVersion_row,'???');
+ Edt_GameInfo_TitleId.Text:='???';
+ Edt_GameInfo_Version.Text:='???';
Exit;
end;
- if (Length(ParamSfo.params)=0) then Exit;
- For i:=0 to High(ParamSfo.params) do
+ if (Length(FParamSfo.params)=0) then Exit;
+ For i:=0 to High(FParamSfo.params) do
begin
- if (ParamSfo.params[i].format=SFO_FORMAT_UINT32) then
+ if (FParamSfo.params[i].format=SFO_FORMAT_UINT32) then
begin
- V:='0x'+HexStr(ParamSfo.params[i].GetUInt,8);
+ V:='0x'+HexStr(FParamSfo.params[i].GetUInt,8);
end else
begin
- V:=Trim(ParamSfo.params[i].GetString);
+ V:=Trim(FParamSfo.params[i].GetString);
end;
- AddRow(GridParamSfo,ParamSfo.params[i].name,V,nil);
+ AddRow(GridParamSfo,FParamSfo.params[i].name,V,nil);
end;
GridParamSfo.AutoSizeColumn(0);
@@ -374,34 +213,45 @@ begin
//
if not UpdateTitle then Exit;
- V:=ParamSfo.GetString('TITLE');
- SetGridVal(GridMain,FName_row,V);
+ V:=FParamSfo.GetString('TITLE');
+ Edt_GameInfo_Name.Text:=V;
- V:=ParamSfo.GetString('TITLE_ID');
- SetGridVal(GridMain,FTitleId_row,V);
+ V:=FParamSfo.GetString('TITLE_ID');
+ Edt_GameInfo_TitleId.Text:=V;
- V:=ParamSfo.GetString('APP_VER');
- SetGridVal(GridMain,FVersion_row,V);
+ V:=FParamSfo.GetString('VERSION');
+ Edt_GameInfo_Version.Text:=V;
+
+ V:=FParamSfo.GetString('APP_VER');
+ Edt_GameInfo_AppVer.Text:=V;
end;
-procedure TfrmGameEditor.GridSelectEditor(Sender:TObject;aCol,aRow:Integer;var Editor:TWinControl);
-var
- obj:TObject;
-begin
- obj:=TStringGrid(Sender).Objects[0,aRow];
- if (obj=nil) then Exit;
- if not obj.InheritsFrom(TFieldInfo) then Exit;
- //
- TStringGrid(Sender).Tag:=PtrInt(Self);
- //
- TFieldInfo(obj).SelectEditor(TStringGrid(Sender),aCol,aRow,Editor);
-end;
-
-procedure TfrmGameEditor.GridEditingDone(Sender: TObject);
+procedure TfrmGameEditor.Edt_MountList_gameExit(Sender: TObject);
begin
LoadParamSfo(True);
end;
+procedure TfrmGameEditor.BtnGameOpenClick(Sender: TObject);
+var
+ new:RawByteString;
+begin
+ new:=DoOpenDir('',Edt_MountList_game.Text);
+ if (new='') then Exit;
+
+ Edt_MountList_game.Text:=new;
+ LoadParamSfo(True);
+end;
+
+procedure TfrmGameEditor.BtnExpGameClick(Sender: TObject);
+begin
+ OpenDocument(Edt_MountList_game.Text);
+end;
+
+procedure TfrmGameEditor.BtnExpFwClick(Sender: TObject);
+begin
+ OpenDocument(Edt_MountList_firmware.Text);
+end;
+
procedure TfrmGameEditor.BtnOkClick(Sender: TObject);
begin
FormSave;
@@ -418,20 +268,41 @@ begin
Close;
end;
+procedure TfrmGameEditor.Edt_MountList_firmwareGetItems(Sender: TObject);
+var
+ i,c:Integer;
+ S:RawByteString;
+begin
+ if (FConfigInfo<>nil) then
+ begin
+ c:=FConfigInfo.MainInfo.FirmwareList.GetArrayCount;
+ if (c<>0) and (Edt_MountList_firmware.Items.Count<>c) then
+ begin
+ Edt_MountList_firmware.Items.Clear;
+ //preload
+ For i:=0 to c-1 do
+ begin
+ S:=FConfigInfo.MainInfo.FirmwareList.values[i];
+ Edt_MountList_firmware.Items.Add(S);
+ end;
+ end;
+ end;
+end;
+
procedure TfrmGameEditor.FormClose(Sender:TObject;var CloseAction:TCloseAction);
begin
- if (Item<>nil) then
+ if (FItem<>nil) then
begin
- if Item.FLock then
+ if FItem.FLock then
begin
- Item.FLock:=False;
+ FItem.FLock:=False;
end else
begin
- FreeAndNil(Item);
+ FreeAndNil(FItem);
end;
end;
//
- FreeAndNil(ParamSfo);
+ FreeAndNil(FParamSfo);
//
CloseAction:=caFree;
end;
diff --git a/gui/game_info.pas b/gui/game_info.pas
index 79cc413a..85edb7d3 100644
--- a/gui/game_info.pas
+++ b/gui/game_info.pas
@@ -99,6 +99,18 @@ type
Destructor Destroy(); override;
end;
+ TStringArray=class(TAbstractArray)
+ values:array of RawByteString;
+ //
+ Destructor Destroy; override;
+ //
+ Function GetArrayCount:SizeInt; override;
+ Function GetArrayItem(i:SizeInt):TValue; override;
+ Function AddObject:TAbstractObject; override;
+ Function AddArray :TAbstractArray; override;
+ procedure AddValue(Value:TValue); override;
+ end;
+
TBootParamInfo=class(TAbstractObject)
private
FNeo :Boolean;
@@ -135,26 +147,28 @@ type
TMainInfo=class(TAbstractObject)
private
- FLogFile :RawByteString;
- Fsystem :RawByteString;
- Fdata :RawByteString;
- Ffork_proc:Boolean;
+ FLogFile :RawByteString;
+ FDefaultFirmware:RawByteString;
+ FFirmwareList :TStringArray;
published
- property LogFile :RawByteString read FLogFile write FLogFile;
- property system :RawByteString read Fsystem write Fsystem;
- property data :RawByteString read Fdata write Fdata;
- property fork_proc:Boolean read Ffork_proc write Ffork_proc;
+ property LogFile :RawByteString read FLogFile write FLogFile;
+ property DefaultFirmware:RawByteString read FDefaultFirmware write FDefaultFirmware;
+ property FirmwareList :TStringArray read FFirmwareList write FFirmwareList;
public
Constructor Create; override;
end;
TMiscInfo=class(TAbstractObject)
private
+ Ffork_proc :Boolean;
Fstrict_ps4_freq :Boolean;
Frenderdoc_capture:Boolean;
published
+ property fork_proc :Boolean read Ffork_proc write Ffork_proc;
property strict_ps4_freq :Boolean read Fstrict_ps4_freq write Fstrict_ps4_freq;
property renderdoc_capture:Boolean read Frenderdoc_capture write Frenderdoc_capture;
+ public
+ Constructor Create; override;
end;
TVulkanInfo=class(TAbstractObject)
@@ -183,18 +197,6 @@ type
Constructor Create; override;
end;
- TStringArray=class(TAbstractArray)
- values:array of RawByteString;
- //
- Destructor Destroy; override;
- //
- Function GetArrayCount:SizeInt; override;
- Function GetArrayItem(i:SizeInt):TValue; override;
- Function AddObject:TAbstractObject; override;
- Function AddArray :TAbstractArray; override;
- procedure AddValue(Value:TValue); override;
- end;
-
TPS4LoadExec=class(TAbstractObject)
private
FPath:RawByteString;
@@ -227,27 +229,25 @@ type
FName :RawByteString;
FTitleId:RawByteString;
FVersion:RawByteString;
+ FAppVer :RawByteString;
FExec :RawByteString;
- FParam :RawByteString;
published
property Name :RawByteString read FName write FName;
property TitleId:RawByteString read FTitleId write FTitleId;
property Version:RawByteString read FVersion write FVersion;
+ property AppVer :RawByteString read FAppVer write FAppVer;
property Exec :RawByteString read FExec write FExec;
- property Param :RawByteString read FParam write FParam;
public
Constructor Create; override;
end;
TMountList=class(TAbstractObject)
private
- Fapp0 :RawByteString;
- Fsystem:RawByteString;
- Fdata :RawByteString;
+ Fgame :RawByteString;
+ Ffirmware:RawByteString;
published
- property app0 :RawByteString read Fapp0 write Fapp0 ;
- property system:RawByteString read Fsystem write Fsystem;
- property data :RawByteString read Fdata write Fdata ;
+ property game :RawByteString read Fgame write Fgame ;
+ property firmware:RawByteString read Ffirmware write Ffirmware;
public
Constructor Create; override;
end;
@@ -264,10 +264,16 @@ type
TGameStartupInfo=class(TAbstractObject)
public
- FReader :Boolean;
- FPipe :THandle;
- FConfInfo:TConfigInfo;
- FGameItem:TGameItem;
+ FReader :Boolean;
+ FPipe :THandle;
+ FConfInfo :TConfigInfo;
+ FGameItem :TGameItem;
+ FLocalDir :RawByteString;
+ FhasParamSfo:Integer;
+ published
+ property Pipe :THandle read FPipe write FPipe;
+ property LocalDir:RawByteString read FLocalDir write FLocalDir;
+ property hasParamSfo:Integer read FhasParamSfo write FhasParamSfo;
public
Constructor Create(Reader:Boolean); reintroduce;
Destructor Destroy; override;
@@ -1091,9 +1097,13 @@ end;
Constructor TMainInfo.Create;
begin
inherited;
- FLogFile:='log.txt';
- Fsystem :=DirectorySeparator+'system';
- Fdata :=DirectorySeparator+'data';
+ FLogFile :='log.txt';
+ FDefaultFirmware:=DirectorySeparator+'firmware';
+end;
+
+Constructor TMiscInfo.Create;
+begin
+ inherited;
Ffork_proc:=True;
end;
@@ -1152,14 +1162,14 @@ begin
FExec:='/app0/eboot.bin';
FTitleId:='???';
FVersion:='???';
+ FAppVer :='???';
end;
Constructor TMountList.Create;
begin
inherited;
- Fapp0 :=DirectorySeparator;
- Fsystem:=DirectorySeparator+'system';
- Fdata :=DirectorySeparator+'data';
+ Fgame :=DirectorySeparator;
+ Ffirmware:=DirectorySeparator+'firmware';
end;
//
@@ -1187,15 +1197,14 @@ end;
Procedure TGameStartupInfo.Serialize(Stream:TStream);
begin
- Stream.Write(FPipe,SizeOf(THandle));
+ inherited Serialize(Stream);
FConfInfo.Serialize(Stream);
FGameItem.Serialize(Stream);
end;
Procedure TGameStartupInfo.Deserialize(Stream:TStream);
begin
- FPipe:=0;
- Stream.Read(FPipe,SizeOf(THandle));
+ inherited Deserialize(Stream);
FConfInfo.Deserialize(Stream);
FGameItem.Deserialize(Stream);
end;
diff --git a/gui/game_mount.pas b/gui/game_mount.pas
new file mode 100644
index 00000000..2b5d40f0
--- /dev/null
+++ b/gui/game_mount.pas
@@ -0,0 +1,248 @@
+unit game_mount;
+
+{$mode ObjFPC}{$H+}
+
+interface
+
+uses
+ game_info;
+
+var
+ g_LocalDir:RawByteString='';
+
+procedure InitMount(GameStartupInfo:TGameStartupInfo);
+
+implementation
+
+uses
+ sysutils,
+ errno,
+ vfs_mountroot,
+ subr_backtrace;
+
+function get_errno_str(err:Integer):RawByteString;
+begin
+ case err of
+ EPERM :Result:='Operation not permitted';
+ ENOENT :Result:='No such file or directory';
+ EACCES :Result:='Permission denied';
+ EEXIST :Result:='Directory exists';
+ ENOTDIR:Result:='Not a directory';
+ else
+ Result:=IntToStr(err);
+ end;
+end;
+
+function mount_mkdir(path:PChar):Integer;
+begin
+ Result:=vfs_mountroot.mount_mkdir(path);
+ if (Result<>0) then
+ begin
+ print_error_td('[mkdir error]'+#13#10+
+ ' path:"'+path+'"'#13#10+
+ ' err:'+get_errno_str(Result)
+ ,True);
+ end;
+end;
+
+function mount_into_sandbox(fstype,fspath,from,opts:PChar;flags:QWORD;ignore:Boolean):Integer;
+begin
+ Result:=vfs_mountroot.mount_into_sandbox(fstype,fspath,from,opts,flags);
+ if (Result<>0) and (not ignore) then
+ begin
+ print_error_td('[mount error]'+#13#10+
+ ' from:"'+from+'"'#13#10+
+ ' to:"'+fspath+'"'#13#10+
+ ' err:'+get_errno_str(Result)
+ ,True);
+ end;
+end;
+
+function unix_to_host(const name:RawByteString):RawByteString;
+var
+ i:Integer;
+begin
+ Result:=name;
+ if (DirectorySeparator<>'/') then
+ For i:=1 to Length(Result) do
+ begin
+ if (Result[i]='/') then
+ begin
+ Result[i]:=DirectorySeparator;
+ end;
+ end;
+end;
+
+const
+ MM_CREATE =-1;
+ MM_GAME =0;
+ MM_FIRMWARE=1;
+ MM_LOCAL =2;
+ MM_LAST =2;
+
+type
+ t_mnt_flags=Set of (mfReadOnly,mfIgnoreErr,mfForceDir);
+
+type
+ pp_mount_dir=^p_mount_dir;
+ p_mount_dir=^t_mount_dir;
+ t_mount_dir=object
+ dst :pchar;
+ src :pchar;
+ mode :Shortint;
+ flags :t_mnt_flags;
+ term :Boolean;
+ childs:p_mount_dir;
+ end;
+
+ t_mount_dir_iterator=object
+ _curr:pp_mount_dir;
+ stack:array[0..3] of p_mount_dir;
+ function curr:p_mount_dir; inline;
+ procedure init(dir:p_mount_dir); inline;
+ function next(err:Integer):Boolean; inline;
+ end;
+
+function t_mount_dir_iterator.curr:p_mount_dir; inline;
+begin
+ Result:=_curr^;
+end;
+
+procedure t_mount_dir_iterator.init(dir:p_mount_dir); inline;
+begin
+ stack[0]:=dir;
+ _curr:=@stack[0];
+end;
+
+function t_mount_dir_iterator.next(err:Integer):Boolean; inline;
+var
+ prev:p_mount_dir;
+begin
+ if (_curr=nil) then Exit(False);
+
+ prev:=_curr^;
+
+ if (err=0) and (prev^.childs<>nil) then
+ begin
+ _curr:=_curr+1; //down
+ _curr^:=prev^.childs;
+ end else
+ begin
+ _curr^:=prev+1; //next
+ end;
+
+ repeat
+
+ if (_curr^^.term) then
+ begin
+ if (_curr=@stack[0]) then
+ begin
+ _curr:=nil;
+ Exit(False);
+ end else
+ begin
+ _curr :=_curr -1; //up
+ _curr^:=_curr^+1; //next
+ end;
+ end else
+ begin
+ Exit(True);
+ end;
+
+ until false;
+
+end;
+
+const
+ SYSTEM_COMMON_DIRS:array[0..12] of t_mount_dir=(
+ (dst:'/%s/common/cert' ;src:'%s/system/common/cert' ;mode:MM_FIRMWARE;flags:[mfReadOnly]), // CA_LIST.cer
+ (dst:'/%s/common/etc' ;src:'%s/system/common/etc' ;mode:MM_FIRMWARE;flags:[mfReadOnly,mfIgnoreErr]),
+ (dst:'/%s/common/font' ;src:'%s/preinst/common/font' ;mode:MM_FIRMWARE;flags:[mfReadOnly]), // *.ttf
+ (dst:'/%s/common/font2' ;src:'%s/system/common/font2' ;mode:MM_FIRMWARE;flags:[mfReadOnly]),
+ (dst:'/%s/common/httpcache' ;src:'%s/system_data/common/httpcache';mode:MM_LOCAL ;flags:[mfForceDir]),
+ (dst:'/%s/common/lib' ;src:'%s/system/common/lib' ;mode:MM_FIRMWARE;flags:[mfReadOnly]),
+ (dst:'/%s/common/mms' ;src:'%s/system_data/common/mms/' ;mode:MM_LOCAL ;flags:[mfForceDir]), // av_content.db
+ (dst:'/%s/common/mms_ro' ;src:'%s/system/common/mms_ro' ;mode:MM_FIRMWARE;flags:[mfReadOnly,mfIgnoreErr]), // template_content.db
+ (dst:'/%s/common/playready' ;src:'%s/user/common/playready' ;mode:MM_LOCAL ;flags:[mfReadOnly,mfForceDir ]),
+ (dst:'/%s/common/text_layout' ;src:'%s/system/common/text_layout' ;mode:MM_FIRMWARE;flags:[mfReadOnly,mfIgnoreErr]),
+ (dst:'/%s/common/text_to_speech';src:'%s/system/common/text_to_speech';mode:MM_FIRMWARE;flags:[mfReadOnly,mfIgnoreErr]),
+ (dst:'/%s/common/webkit' ;src:'%s/system/common/webkit' ;mode:MM_FIRMWARE;flags:[mfReadOnly,mfIgnoreErr]),
+ (term:True)
+ );
+
+ SYSTEM_DIRS:array[0..5] of t_mount_dir=(
+ (dst:'/%s/becore' ;src:'' ;mode:MM_CREATE ;flags:[]), // system app only
+ (dst:'/%s/common' ;src:'' ;mode:MM_CREATE ;flags:[];childs:@SYSTEM_COMMON_DIRS),
+ (dst:'/%s/common_temp';src:'' ;mode:MM_CREATE ;flags:[]),
+ (dst:'/%s/priv' ;src:'%s/system/priv';mode:MM_FIRMWARE;flags:[mfReadOnly]), // system app only
+ (dst:'/%s/sqlite' ;src:'' ;mode:MM_CREATE ;flags:[]),
+ (term:True)
+ );
+
+ SANDBOX_DIRS:array[0..7] of t_mount_dir=(
+ (dst:'/app0' ;src:'%s' ;mode:MM_GAME ;flags:[mfReadOnly]),
+ (dst:'/av_contents';src:'%s/user/av_contents';mode:MM_LOCAL ;flags:[mfForceDir]),
+ (dst:'/data' ;src:'%s/user/data' ;mode:MM_LOCAL ;flags:[mfForceDir]),
+ (dst:'/host' ;src:'' ;mode:MM_CREATE;flags:[mfReadOnly]),
+ (dst:'/hostapp' ;src:'' ;mode:MM_CREATE;flags:[mfReadOnly]),
+ (dst:'/system_tmp' ;src:'%s/system_tmp' ;mode:MM_LOCAL ;flags:[mfForceDir]),
+ (dst:'/%s' ;src:'' ;mode:MM_CREATE;flags:[mfReadOnly];childs:@SYSTEM_DIRS),
+ (term:True)
+ );
+
+procedure InitMount(GameStartupInfo:TGameStartupInfo);
+var
+ err:Integer;
+
+ fs_iterator:t_mount_dir_iterator;
+
+ fs_source:array[0..MM_LAST] of RawByteString;
+ fs_dst:RawByteString;
+ fs_src:RawByteString;
+begin
+
+ //temp hack
+ err:=mount_into_sandbox('ufs','/savedata0','savedata',nil,0,True);
+
+ fs_source[MM_GAME ]:=ExcludeTrailingPathDelimiter(GameStartupInfo.FGameItem.FMountList.game );
+ fs_source[MM_FIRMWARE]:=ExcludeTrailingPathDelimiter(GameStartupInfo.FGameItem.FMountList.firmware);
+ fs_source[MM_LOCAL ]:=ExcludeTrailingPathDelimiter(GameStartupInfo.LocalDir);
+
+ g_LocalDir:=GameStartupInfo.LocalDir;
+
+ //--sandbox--
+ fs_iterator.init(@SANDBOX_DIRS);
+ repeat
+
+ with fs_iterator.curr^ do
+ begin
+
+ fs_dst:=Format(dst,['system']);
+
+ if (mode=MM_CREATE) then
+ begin
+ err:=mount_mkdir(pchar(fs_dst));
+ end else
+ begin
+ fs_src:=Format(unix_to_host(src),[fs_source[mode]]);
+
+ if (mfForceDir in flags) then
+ begin
+ ForceDirectories(fs_src);
+ end;
+
+ err:=mount_into_sandbox('ufs',pchar(fs_dst),pchar(fs_src),nil,ord(mfReadOnly in flags)*MNT_RDONLY,mfIgnoreErr in flags);
+ end;
+
+ end;
+
+ until (not fs_iterator.next(err));
+ //--sandbox--
+
+ //UPDATE: sandbox root IS NOT read-only
+ //err:=vfs_mount_path('ufs','/','/',nil,MNT_RDONLY or MNT_UPDATE);
+
+end;
+
+end.
+
diff --git a/gui/game_run.pas b/gui/game_run.pas
index 9bd86728..ad241db1 100644
--- a/gui/game_run.pas
+++ b/gui/game_run.pas
@@ -16,7 +16,8 @@ uses
host_ipc,
host_ipc_interface,
md_host_ipc,
- game_info;
+ game_info,
+ game_mount;
type
TGameRunConfig=record
@@ -25,6 +26,7 @@ type
FConfInfo:TConfigInfo;
FGameItem:TGameItem;
+ FhasParamSfo:Integer;
end;
TGameProcessSimple=class(TGameProcess)
@@ -39,10 +41,9 @@ function run_item(const cfg:TGameRunConfig):TGameProcess;
implementation
uses
+ errno,
sys_sysinit,
- kern_param,
kern_exec,
- vfs_mountroot,
sys_crt, //<- init writeln redirect
sys_tty,
md_exception, //<- install custom
@@ -200,7 +201,7 @@ var
curr:PPChar;
begin
if (argv=nil) then Exit;
- curr:=argv+1; //skip exec
+ curr:=argv;
while (curr^<>nil) do
begin
FreeMem(curr^);
@@ -253,10 +254,9 @@ begin
Result:=1;
//init
- argc:=1;
+ argc:=0;
argv:=AllocMem(SizeOf(Pointer)*2);
- argv[0]:=nil; //exec place
- argv[1]:=nil; //truncate
+ argv[0]:=nil; //truncate
curr:=@params[1];
last:=curr;
@@ -336,11 +336,22 @@ begin
Result:=argc;
end;
+function get_errno_str(err:Integer):RawByteString;
+begin
+ case err of
+ EPERM :Result:='Operation not permitted';
+ ENOENT :Result:='No such file or directory';
+ EACCES :Result:='Permission denied';
+ EEXIST :Result:='Directory exists';
+ ENOTDIR:Result:='Not a directory';
+ else
+ Result:=IntToStr(err);
+ end;
+end;
+
procedure prepare(GameStartupInfo:TGameStartupInfo); SysV_ABI_CDecl;
var
err:Integer;
- len:Integer;
- exec:array[0..PATH_MAX] of Char;
argv:PPChar;
i,argc:Integer;
Item:TGameItem;
@@ -367,8 +378,8 @@ begin
Item:=GameStartupInfo.FGameItem;
g_appinfo.mmap_flags:=1; //is_big_app ???
- g_appinfo.CUSANAME:=Item.FGameInfo.TitleId;
- //g_appinfo.hasParamSfo:=1; TODO: check
+ g_appinfo.CUSANAME :=Item.FGameInfo.TitleId;
+ g_appinfo.hasParamSfo:=GameStartupInfo.hasParamSfo;
//g_appinfo.debug_level:=1;
g_appinfo.titleWorkaround.version:=69;
@@ -383,51 +394,23 @@ begin
kern_reserve_2mb_page(0,M2MB_DEFAULT);
///
- Writeln('Name :',Item.FGameInfo.Name );
- Writeln('TitleId:',Item.FGameInfo.TitleId);
- Writeln('Version:',Item.FGameInfo.Version);
- Writeln('Exec :',Item.FGameInfo.Exec );
- Writeln('Param :',Item.FGameInfo.Param );
+ Writeln('Name :',Item.FGameInfo.Name );
+ Writeln('TitleId :',Item.FGameInfo.TitleId );
+ Writeln('Version :',Item.FGameInfo.Version );
+ Writeln('AppVer :',Item.FGameInfo.AppVer );
+ Writeln('Exec :',Item.FGameInfo.Exec );
- Writeln('app0 :',Item.FMountList.app0 );
- Writeln('system :',Item.FMountList.system);
- Writeln('data :',Item.FMountList.data );
+ Writeln('game :',Item.FMountList.game );
+ Writeln('firmware:',Item.FMountList.firmware );
- //temp hack
- err:=vfs_mount_mkdir('ufs','/savedata0' ,'savedata',nil,0);
+ Writeln('LocalDir:',GameStartupInfo.LocalDir );
- //fs guest host
- err:=vfs_mount_mkdir('ufs','/app0' ,pchar(Item.FMountList.app0 ),nil,MNT_RDONLY);
- if (err<>0) then
- begin
- print_error_td('error mount "'+Item.FMountList.app0+'" to "/app0" code='+IntToStr(err));
- end;
-
- err:=vfs_mount_mkdir('ufs','/system',pchar(Item.FMountList.system),nil,MNT_RDONLY);
- if (err<>0) then
- begin
- print_error_td('error mount "'+Item.FMountList.system+'" to "/system" code='+IntToStr(err));
- end;
-
- err:=vfs_mount_mkdir('ufs','/data' ,pchar(Item.FMountList.data ),nil,0);
- if (err<>0) then
- begin
- print_error_td('error mount "'+Item.FMountList.data+'" to "/data" code='+IntToStr(err));
- end;
+ InitMount(GameStartupInfo);
///argv
argv:=nil;
- argc:=parse_params(Item.FGameInfo.Param,argv);
-
- FillChar(exec,SizeOf(exec),0);
-
- len:=Length(Item.FGameInfo.Exec);
- if (len>PATH_MAX) then len:=PATH_MAX;
-
- Move(pchar(Item.FGameInfo.Exec)^,exec,len);
-
- argv[0]:=@exec;
+ argc:=parse_params(Item.FGameInfo.Exec,argv);
Writeln('main_thread:',HexStr(curkthread));
@@ -443,19 +426,28 @@ begin
Flush(stdout);
- err:=main_execve(argv[0],argv,nil);
-
- //free data
- free_params(argv);
+ if (argv[0]=nil) then
+ begin
+ err:=ENOENT;
+ end else
+ begin
+ err:=main_execve(argv[0],argv,nil);
+ end;
if (err=0) then
begin
+ //free data
+ free_params(argv);
+
//jump to code
main_switch_context;
end else
if (err<>0) then
begin
- print_error_td('error execve "'+exec+'" code='+IntToStr(err));
+ print_error_td('[execve error]'+#13#10+
+ ' cmd:"'+argv[0]+'"'#13#10+
+ ' err:'+get_errno_str(err)
+ ,False);
end;
//
@@ -529,7 +521,7 @@ begin
parent:=md_pidfd_open(md_getppid);
- pipefd:=GameStartupInfo.FPipe;
+ pipefd:=GameStartupInfo.Pipe;
pipefd:=md_pidfd_getfd(parent,pipefd);
kipc:=THostIpcPipeKERN.Create;
@@ -575,12 +567,15 @@ begin
GameStartupInfo.FConfInfo:=cfg.FConfInfo;
GameStartupInfo.FGameItem:=cfg.FGameItem;
+ GameStartupInfo.LocalDir :=GetAppConfigDir(False);
+ GameStartupInfo.hasParamSfo:=cfg.FhasParamSfo;
+
SetStdHandle(STD_OUTPUT_HANDLE,cfg.hOutput);
SetStdHandle(STD_ERROR_HANDLE ,cfg.hError );
fork_info:=Default(t_fork_proc);
- if cfg.FConfInfo.MainInfo.fork_proc then
+ if cfg.FConfInfo.MiscInfo.fork_proc then
begin
Result:=TGameProcessPipe.Create;
Result.g_fork:=True;
diff --git a/gui/main.lfm b/gui/main.lfm
index f3a545fb..8728fd13 100644
--- a/gui/main.lfm
+++ b/gui/main.lfm
@@ -1,7 +1,7 @@
object frmMain: TfrmMain
- Left = 334
+ Left = 682
Height = 343
- Top = 200
+ Top = 344
Width = 623
Caption = 'fpPS4'
ClientHeight = 343
@@ -293,4 +293,29 @@ object frmMain: TfrmMain
57E7E20D65ED54000000000000000000C8C8FF01EBADDADA
}
end
+ object SmallImageList: TImageList
+ AllocBy = 3
+ Left = 320
+ Top = 144
+ Bitmap = {
+ 4C7A030000001000000010000000290200000000000078DAED93CB4B1B5114C6
+ 071F8821A96EBA145CF40F9042ABD82E04DDB40B77FE012E2A0ABA75D5AE440A
+ 2E9A165C145C088281C49828BED0344C7C558AF8689399D816A241F0912E9A68
+ 20A966F279CFD4C943329371845221073EEEBD33F777CF771F0700873B48743F
+ 782F4C94A7020E0E8A4497E94870708FF4F0C44AC97D20F52BA388BFFF3277BD
+ 42224E74D75AA99FCBEA9594082130517E699427295E6E7E3FDE7A05C159A1ED
+ DF59C95475ADCABC7F419705527409385F5195F47B81F92F93457DB579E9331E
+ 91DD2EFC98AD933D517BBAD3C9D6F764FD6BB021EF6384575F2219139096FEB0
+ 3680C38D0E843E3514E5292FB114F1080F765F724B115E7991D9B71A4F5E292F
+ 317BD30FE5B9D4D23819F5B37766D6E4697DF21C110719E393E7524BE3B494A4
+ FB67EFA82CA5767E7FF307A0849CEB3A12D16F2CBF85EDC96CA535D4EE38BCD6
+ 9E61BECFD567FAFB7C0B8293E675ADDAF8ECE0AA597D6D1FF8DAE2B45FDA0BE5
+ 3DF0B5C683EE9A4D9EE72A8AD517CD11274D6F44B7E544AE1997E5988D5F2BEC
+ FF1AB69EA6D878D7933489FAB7E589C3CF3576E8CBA0BE213EE8058425E3BC7F
+ 1EF83AA38BCFDD2FC9DEF7FC023B53C09613F6DE6717B9FF6C3D8D31AD7C0A87
+ 4D3BF0651CD81803D64781D51160F963413F325F84033F0C783F14E4C9539E7F
+ E659E1ECBDCDF9FEBB1B63BACE4F239F2EDEF30E581C32CE2FBC05E6060CF1B6
+ EEA7D9F7CBFA5C294A718BFAD7D27DA87F4DFF3AEABF14FF26AE007B18885F
+ }
+ end
end
diff --git a/gui/main.pas b/gui/main.pas
index d1668978..ab0f12d0 100644
--- a/gui/main.pas
+++ b/gui/main.pas
@@ -30,6 +30,9 @@ uses
cfg_edit,
game_run,
+ param_sfo_gui,
+ playgo_chunk_gui,
+
host_ipc_interface;
type
@@ -77,6 +80,7 @@ type
TfrmMain = class(TForm)
MainImageList: TImageList;
+ SmallImageList: TImageList;
MIFind: TMenuItem;
MIShowExplorer: TMenuItem;
MIDevide3: TMenuItem;
@@ -132,6 +136,7 @@ type
FGameList :TGameList;
FGameProcess:TGameProcess;
FGameItem :TGameItem;
+ FParamSfo :TParamSfoFile;
FConfigInfo:TConfigInfo;
@@ -183,8 +188,6 @@ var
implementation
uses
- param_sfo_gui,
- playgo_chunk_gui,
game_find,
@@ -491,6 +494,15 @@ begin
end;
end;
+function LoadParamSfoFile2(const game:RawByteString):TParamSfoFile;
+begin
+ Result:=LoadParamSfoFile(ExcludeTrailingPathDelimiter(game)+
+ DirectorySeparator+
+ 'sce_sys'+
+ DirectorySeparator+
+ 'param.sfo');
+end;
+
function TfrmMain.OnParamSfoInit(mlen:DWORD;buf:Pointer):Ptruint; //PARAM_SFO_INIT
var
ParamSfo:TParamSfoFile;
@@ -500,13 +512,14 @@ begin
if (FGameItem=nil) then Exit;
- V:=FGameItem.MountList.app0;
-
- ParamSfo:=LoadParamSfoFile(ExcludeTrailingPathDelimiter(V)+
- DirectorySeparator+
- 'sce_sys'+
- DirectorySeparator+
- 'param.sfo');
+ if (FParamSfo=nil) then
+ begin
+ ParamSfo:=LoadParamSfoFile2(FGameItem.MountList.game);
+ FParamSfo:=ParamSfo;
+ end else
+ begin
+ ParamSfo:=FParamSfo;
+ end;
if (ParamSfo=nil) then
begin
@@ -540,7 +553,7 @@ begin
if (FGameItem=nil) then Exit;
- V:=FGameItem.MountList.app0;
+ V:=FGameItem.MountList.game;
playgo_file:=LoadPlaygoFile(ExcludeTrailingPathDelimiter(V)+
DirectorySeparator+
@@ -646,8 +659,7 @@ begin
Item:=TGameItem.Create;
FGameItem.CopyTo(Item);
- Item.GameInfo.Exec :=data.Path;
- Item.GameInfo.Param:=encode_shell(data.argv);
+ Item.GameInfo.Exec:=encode_shell(data.Path)+' '+encode_shell(data.argv);
cfg.hOutput:=FAddHandle;
cfg.hError :=FAddHandle;
@@ -717,7 +729,7 @@ begin
//
FGrid.Cells[0,i]:=Item.FGameInfo.Name;
FGrid.Cells[1,i]:=Item.FGameInfo.TitleId;
- FGrid.Cells[2,i]:=Item.FGameInfo.Version;
+ FGrid.Cells[2,i]:=Item.FGameInfo.AppVer;
//
FGrid.Objects[0,i]:=Item;
end;
@@ -734,7 +746,7 @@ begin
//
FGrid.Cells[0,i]:=Item.FGameInfo.Name;
FGrid.Cells[1,i]:=Item.FGameInfo.TitleId;
- FGrid.Cells[2,i]:=Item.FGameInfo.Version;
+ FGrid.Cells[2,i]:=Item.FGameInfo.AppVer;
//
FGrid.Objects[0,i]:=Item;
//
@@ -752,7 +764,7 @@ begin
//
FGrid.Cells[0,i]:=Item.FGameInfo.Name;
FGrid.Cells[1,i]:=Item.FGameInfo.TitleId;
- FGrid.Cells[2,i]:=Item.FGameInfo.Version;
+ FGrid.Cells[2,i]:=Item.FGameInfo.AppVer;
end;
procedure TGameList.UpdateItem(Item:TGameItem);
@@ -764,7 +776,7 @@ begin
//
FGrid.Cells[0,i]:=Item.FGameInfo.Name;
FGrid.Cells[1,i]:=Item.FGameInfo.TitleId;
- FGrid.Cells[2,i]:=Item.FGameInfo.Version;
+ FGrid.Cells[2,i]:=Item.FGameInfo.AppVer;
end;
procedure TGameList.DelItem(Item:TGameItem);
@@ -1163,7 +1175,7 @@ begin
TITLE :=FGameItem.FGameInfo.Name;
TITLE_ID:=FGameItem.FGameInfo.TitleId;
- APP_VER :=FGameItem.FGameInfo.Version;
+ APP_VER :=FGameItem.FGameInfo.AppVer;
if (TITLE='') then
begin
@@ -1241,10 +1253,10 @@ var
begin
form:=TfrmGameEditor.Create(Self);
- form.Item:=TGameItem.Create;
+ form.FConfigInfo:=FConfigInfo;
+ form.FItem :=TGameItem.Create;
- form.Item.FMountList.system:=FConfigInfo.MainInfo.system;
- form.Item.FMountList.data :=FConfigInfo.MainInfo.data;
+ form.FItem.FMountList.firmware:=FConfigInfo.MainInfo.DefaultFirmware;
form.OnSave:=@Self.DoAdd;
@@ -1270,12 +1282,12 @@ begin
begin
form:=TfrmGameEditor.Create(Self);
- form.Item:=TGameItem.Create;
+ form.FConfigInfo:=FConfigInfo;
+ form.FItem :=TGameItem.Create;
- form.Item.FMountList.system:=FConfigInfo.MainInfo.system;
- form.Item.FMountList.data :=FConfigInfo.MainInfo.data;
+ form.FItem.FMountList.firmware:=FConfigInfo.MainInfo.DefaultFirmware;
- form.Item.FMountList.app0:=d.FileName;
+ form.FItem.FMountList.game:=d.FileName;
form.OnSave:=@Self.DoAdd;
@@ -1304,13 +1316,14 @@ begin
form:=TfrmGameEditor.Create(Self);
- form.Item:=Item;
+ form.FConfigInfo:=FConfigInfo;
+ form.FItem:=Item;
Item.FLock:=True;
form.OnSave:=@Self.DoEdit;
- form.FormInit(False);
+ form.FormInit(True);
end;
procedure TfrmMain.TBConfigClick(Sender: TObject);
@@ -1376,10 +1389,10 @@ begin
if Length(S)nil);
if Item.FLock then Exit;
@@ -1419,6 +1436,8 @@ begin
begin
Item.FLock:=True;
FGameItem:=Item;
+ FParamSfo:=ParamSfo;
+ ParamSfo:=nil;
SetButtonsState(mdsStarted);
@@ -1427,6 +1446,8 @@ begin
FGameProcess.g_ipc.FHandler:=IpcHandler;
end;
end;
+
+ FreeAndNil(ParamSfo);
end;
procedure TfrmMain.TBPlayClick(Sender: TObject);
@@ -1487,6 +1508,7 @@ begin
FGameItem.FLock:=False;
FGameItem:=nil;
end;
+ FreeAndNil(FParamSfo);
//
CloseMainWindows;
//
@@ -1577,9 +1599,9 @@ var
begin
form:=TfrmGameEditor(Sender);
- Item:=form.Item;
+ Item:=form.FItem;
- form.Item:=nil;
+ form.FItem:=nil;
FGameList.InsertItem(Item);
//
@@ -1593,11 +1615,11 @@ var
begin
form:=TfrmGameEditor(Sender);
- Item:=form.Item;
+ Item:=form.FItem;
Item.FLock:=False;
- form.Item:=nil;
+ form.FItem:=nil;
FGameList.UpdateItem(Item);
//
diff --git a/icons/Add_04_16.png b/icons/Add_04_16.png
new file mode 100644
index 0000000000000000000000000000000000000000..2e984c0fa05f3ee309237f9d8f15bc585cd65778
GIT binary patch
literal 369
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf4nJ
z@ErkR#;MwT(m+AU64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq=1UvdAc};
zSoEHqXq$D|L7?^iny?_%8mUJAq~^Ozf(jn$Svqh{KekliftrH2nacH!lbL72rlo~x
zetGQ@q#*I;`k76?e@y$%wqxsx_lbLM%ys$1z#!9pCf!E5^k<2@g9^Xdd1E1No3-VR
z^Vf?rFr>2`;j>)FnUT)MaR2%oqnK?C&olWJFLBdsKeO@861I*f2TyN0p(B>S{rwC>
z^n*gX!qe6rtlK;bP0l+XkKvt*L&
literal 0
HcmV?d00001
diff --git a/icons/Folder_19_16.png b/icons/Folder_19_16.png
new file mode 100644
index 0000000000000000000000000000000000000000..c268b9b08d93c23e6f7cb7b3db54f3b2955b5b19
GIT binary patch
literal 606
zcmV-k0-^nhP)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10qaRb
zK~y-6rBh976JZ#f_hUD4leJYEl41x7ZLkW(lNkJHk=}|I!5;hzet?JvbMq$cL7{l|
zSZEYfEcMVsE+z*HDz$E%1w^TvAa
zD7xzti38G*e8W|Ajc%P=>t?`2VOg!+I4k0kx5+8XR+HAI40{xe`KDyk471S=|ez(3<#mm4?q1vN*DNW
zHG_e;j@8|LJo#?p(c*6aKxm0G>vg1bfw?OgY_=4V?^a;96lO1_(XR_=oP`_AR~nca
zPNHZ#m?&4!@B&PfD=69yCWn)VbTgOM71gl1yN~=(qRovYVi-xpu(aKTAvmNV+4T6r%Dv#w77n0shWt_uZ!c#60H4nJ
z@ErkR#;MwT(m+AU64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq=1UjJY5_^
zEP9g@Bv_gGB@%hM&!o!#|M&O2caNG{+OhNM%iTX38yFaDIKToDy*)$v=#TI6%!lvS
z^YGMP$VmBiXX)t&VjC4^|9Q<{*J~gpd4M+|Decc4t6IszxP+uXK0Uhv9rPI(wlJG7
USLU5i1+0) then
+ if (error<>0) and (mode=0) then
begin
- print_error_td('error execve "'+args^.fname+'" code='+IntToStr(error));
+ print_error_td('error execve "'+args^.fname+'" code='+IntToStr(error),True);
exec_free_args(args);
@@ -1829,7 +1829,7 @@ done2:
Exit(error);
end;
-function kern_execve(td:p_kthread;args:p_image_args):Integer;
+function kern_execve(td:p_kthread;args:p_image_args;mode:Integer=0):Integer;
var
error:Integer;
begin
@@ -1837,7 +1837,7 @@ begin
Assert((td^.td_pflags and TDP_EXECVMSPC)=0,'nested execve');
- error:=do_execve(td, args);
+ error:=do_execve(td, args, mode);
if ((td^.td_pflags and TDP_EXECVMSPC)<>0) then
begin
@@ -1857,7 +1857,7 @@ begin
if (error=0) then
begin
- error:=kern_execve(curkthread, @args);
+ error:=kern_execve(curkthread, @args, 1);
end;
Result:=(error);
diff --git a/sys/kern/subr_backtrace.pas b/sys/kern/subr_backtrace.pas
index 3eea0d86..2f194928 100644
--- a/sys/kern/subr_backtrace.pas
+++ b/sys/kern/subr_backtrace.pas
@@ -13,7 +13,7 @@ procedure print_frame(var f:text;frame:Pointer);
procedure print_backtrace(var f:text;rip,rbp:Pointer;skipframes:sizeint);
procedure print_backtrace_td(var f:text);
-procedure print_error_td(const str:shortstring);
+procedure print_error_td(const str:shortstring;resumable:Boolean=False);
implementation
@@ -315,14 +315,19 @@ begin
print_backtrace(stderr,Pointer(td^.td_frame.tf_rip),Pointer(td^.td_frame.tf_rbp),0);
end;
-procedure print_error_td(const str:shortstring);
+procedure print_error_td(const str:shortstring;resumable:Boolean=False);
begin
thread_suspend_all(p_host_ipc_td);
Writeln(StdErr,str);
+ print_backtrace_td(StdErr);
+
p_host_ipc.error(str);
- print_backtrace_td(StdErr);
+ if resumable then
+ begin
+ thread_resume_all(p_host_ipc_td);
+ end;
end;
end.
diff --git a/sys/vfs/vfs_mount.pas b/sys/vfs/vfs_mount.pas
index 7daee9f0..b7a63c2a 100644
--- a/sys/vfs/vfs_mount.pas
+++ b/sys/vfs/vfs_mount.pas
@@ -92,10 +92,10 @@ function vfs_donmount(fsflags:QWORD;fsoptions:p_uio):Integer;
function dounmount(mp:p_mount;flags:Integer):Integer;
-function mount_argb(ma:p_mntarg;flag:Integer;name:PChar):p_mntarg;
-function mount_argf(ma:p_mntarg;name,fmt:PChar;const Args:Array of const):p_mntarg; register;
+function mount_argb (ma:p_mntarg;flag:Integer;name:PChar):p_mntarg;
+function mount_argf (ma:p_mntarg;name,fmt:PChar;const Args:Array of const):p_mntarg; register;
function mount_argsu(ma:p_mntarg;name:PChar;val:Pointer;len:Integer):p_mntarg;
-function mount_arg(ma:p_mntarg;name:PChar;val:Pointer;len:Integer):p_mntarg;
+function mount_arg (ma:p_mntarg;name:PChar;val:Pointer;len:Integer):p_mntarg;
procedure free_mntarg(ma:p_mntarg);
function kernel_nmount(ma:p_mntarg;flags:QWORD):Integer;
@@ -1028,6 +1028,7 @@ begin
vput(vp);
Exit(EINVAL);
end;
+
mp:=vp^.v_mount;
{
* We only allow the filesystem to be reloaded if it
@@ -1050,11 +1051,13 @@ begin
vput(vp);
Exit(error);
end;
+
if (vfs_busy(mp, MBF_NOWAIT)<>0) then
begin
vput(vp);
Exit(EBUSY);
end;
+
VI_LOCK(vp);
if ((vp^.v_iflag and VI_MOUNT)<>0) or (vp^.v_mountedhere<>nil) then
begin
@@ -1063,19 +1066,27 @@ begin
vput(vp);
Exit(EBUSY);
end;
+
vp^.v_iflag:=vp^.v_iflag or VI_MOUNT;
VI_UNLOCK(vp);
VOP_UNLOCK(vp, 0);
MNT_ILOCK(mp);
mp^.mnt_flag:=mp^.mnt_flag and (not MNT_UPDATEMASK);
- mp^.mnt_flag:=(mp^.mnt_flag or fsflags) and (MNT_RELOAD or MNT_FORCE or MNT_UPDATE or
- MNT_SNAPSHOT or MNT_ROOTFS or MNT_UPDATEMASK or MNT_RDONLY);
+ mp^.mnt_flag:=(mp^.mnt_flag or fsflags) and
+ (MNT_RELOAD or
+ MNT_FORCE or
+ MNT_UPDATE or
+ MNT_SNAPSHOT or
+ MNT_ROOTFS or
+ MNT_UPDATEMASK or
+ MNT_RDONLY);
if ((mp^.mnt_flag and MNT_ASYNC)=0) then
begin
mp^.mnt_kern_flag:=mp^.mnt_kern_flag and (not MNTK_ASYNC);
end;
+
MNT_IUNLOCK(mp);
mp^.mnt_optnew:=optlist^;
vfs_mergeopts(mp^.mnt_optnew, mp^.mnt_opt);
@@ -1143,6 +1154,7 @@ begin
begin
vfs_freeopts(mp^.mnt_opt);
end;
+
mp^.mnt_opt:=mp^.mnt_optnew;
optlist^:=nil;
VFS_STATFS(mp, @mp^.mnt_stat);
@@ -1224,6 +1236,7 @@ begin
NDFREE(@nd, NDF_ONLY_PNBUF);
vp:=nd.ni_vp;
+
if ((fsflags and MNT_UPDATE)=0) then
begin
pathbuf:=Default(t_mname);
diff --git a/sys/vfs/vfs_mountroot.pas b/sys/vfs/vfs_mountroot.pas
index 29e31213..1993c2d8 100644
--- a/sys/vfs/vfs_mountroot.pas
+++ b/sys/vfs/vfs_mountroot.pas
@@ -11,11 +11,14 @@ uses
const
MNT_RDONLY=vmount.MNT_RDONLY;
+ MNT_UPDATE=vmount.MNT_UPDATE;
procedure vfs_mountroot();
-function vfs_mount_path (fstype,fspath,from,opts:PChar;flags:QWORD):Integer;
-function vfs_mount_mkdir (fstype,fspath,from,opts:PChar;flags:QWORD):Integer;
-function vfs_unmount_rmdir(path:PChar;flags:Integer):Integer;
+function vfs_mount_path (fstype,fspath,from,opts:PChar;flags:QWORD):Integer;
+function mount_mkdir (path:PChar):Integer;
+function mount_rmdir (path:PChar):Integer;
+function mount_into_sandbox (fstype,fspath,from,opts:PChar;flags:QWORD):Integer;
+function unmount_from_sandbox(path:PChar;flags:Integer):Integer;
implementation
@@ -357,16 +360,26 @@ begin
Result:=kernel_nmount(ma,flags);
end;
-function vfs_mount_mkdir(fstype,fspath,from,opts:PChar;flags:QWORD):Integer;
+function mount_mkdir(path:PChar):Integer;
+begin
+ Result:=kern_mkdir(path,UIO_SYSSPACE,&777);
+end;
+
+function mount_rmdir(path:PChar):Integer;
+begin
+Result:=kern_rmdir(path,UIO_SYSSPACE);
+end;
+
+function mount_into_sandbox(fstype,fspath,from,opts:PChar;flags:QWORD):Integer;
begin
Result:=kern_mkdir(fspath,UIO_SYSSPACE,&777);
- if (Result=0) then
+ if (Result=0) or (Result=EEXIST) then
begin
Result:=vfs_mount_path(fstype,fspath,from,opts,flags);
end;
end;
-function vfs_unmount_rmdir(path:PChar;flags:Integer):Integer;
+function unmount_from_sandbox(path:PChar;flags:Integer):Integer;
begin
Result:=kern_unmount(path,flags);
if (Result=0) then