Compare commits
307 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
04cefd43e6 | |
![]() |
ad0b0240a8 | |
![]() |
72a5a16616 | |
![]() |
b9eab2c9d4 | |
![]() |
791f68ee19 | |
![]() |
0f531ca74f | |
![]() |
3f1e0498b8 | |
![]() |
7fbfd64da7 | |
![]() |
19504b1676 | |
![]() |
5ffbdbbd76 | |
![]() |
d953b8bf9f | |
![]() |
56146e90e3 | |
![]() |
34a6f77bb4 | |
![]() |
79c2fef847 | |
![]() |
ae897da738 | |
![]() |
566abbaf61 | |
![]() |
d12d1fba90 | |
![]() |
091deb5409 | |
![]() |
97dd675031 | |
![]() |
2f6ac7d4db | |
![]() |
a3c7069484 | |
![]() |
3071dbe923 | |
![]() |
16778c491e | |
![]() |
7c7c04a90f | |
![]() |
2d97b84dc2 | |
![]() |
daa2ecbbad | |
![]() |
7a4119ad19 | |
![]() |
ae7e8038ec | |
![]() |
accf9ec255 | |
![]() |
97a133933a | |
![]() |
4a540f2a02 | |
![]() |
f8d9ad0f45 | |
![]() |
9e10d7ceea | |
![]() |
585d06fa7c | |
![]() |
9af004761d | |
![]() |
04344baa7e | |
![]() |
46d74e002d | |
![]() |
5948d7a7c4 | |
![]() |
5679192cb5 | |
![]() |
373a2e019a | |
![]() |
88e2bb17c3 | |
![]() |
4460e17647 | |
![]() |
d101c586ca | |
![]() |
81f56072d7 | |
![]() |
ebc62880e3 | |
![]() |
37263ee961 | |
![]() |
004ad25d21 | |
![]() |
cbd359ef8c | |
![]() |
4689608a0b | |
![]() |
d28e1d1698 | |
![]() |
6d8e9b9598 | |
![]() |
99d6fc00f1 | |
![]() |
2df1856444 | |
![]() |
8c6e05798d | |
![]() |
21ef724919 | |
![]() |
a6d0ebb1b1 | |
![]() |
fa694f6369 | |
![]() |
905a9a6de4 | |
![]() |
c46781caaf | |
![]() |
7a1d63b964 | |
![]() |
08a56cf3e5 | |
![]() |
f6e4ae465a | |
![]() |
000305d443 | |
![]() |
7711ac8dfc | |
![]() |
e255da8685 | |
![]() |
73e8b0cb7c | |
![]() |
fea4a0e3c8 | |
![]() |
2dc4d5304c | |
![]() |
302d832fc3 | |
![]() |
18e08ac658 | |
![]() |
981d350b76 | |
![]() |
c08117ce6a | |
![]() |
9b941dc99f | |
![]() |
7e2c7143e3 | |
![]() |
15bd8e6d37 | |
![]() |
b2d4c43379 | |
![]() |
d6eef26c85 | |
![]() |
441da1d040 | |
![]() |
74dc091e83 | |
![]() |
176d715d34 | |
![]() |
0511675791 | |
![]() |
a30de1b295 | |
![]() |
929e72b83a | |
![]() |
d39bc5d685 | |
![]() |
d0fd45eb63 | |
![]() |
408f8e5429 | |
![]() |
80474a8cb6 | |
![]() |
6f2637c07b | |
![]() |
1a0378f935 | |
![]() |
0728ca3242 | |
![]() |
24e4ad1a38 | |
![]() |
b1589191ac | |
![]() |
c2a42658d5 | |
![]() |
110109bac4 | |
![]() |
73410f9fe6 | |
![]() |
9ffe22f2eb | |
![]() |
3dfcab813e | |
![]() |
feacf7be06 | |
![]() |
5500113151 | |
![]() |
7b5bc68366 | |
![]() |
7adf907770 | |
![]() |
31840da2dd | |
![]() |
2b12d862b9 | |
![]() |
6e5a849f61 | |
![]() |
def590ce0e | |
![]() |
b214aee42f | |
![]() |
711bc11b47 | |
![]() |
fef3d27572 | |
![]() |
d9d8eef529 | |
![]() |
029a2935c1 | |
![]() |
151c067bac | |
![]() |
6b9d3965c2 | |
![]() |
865d4d6c97 | |
![]() |
af25023e5d | |
![]() |
72a39fe4e7 | |
![]() |
bd292df809 | |
![]() |
de0cc4bb52 | |
![]() |
e0db966865 | |
![]() |
7ec7187db0 | |
![]() |
5c5d9d418a | |
![]() |
35e26766f0 | |
![]() |
8c6a8b5313 | |
![]() |
a87a564809 | |
![]() |
0f23d6f2c0 | |
![]() |
fe4291863c | |
![]() |
76f2c3947f | |
![]() |
ebfbe572e1 | |
![]() |
13d96a7142 | |
![]() |
f2bf574e21 | |
![]() |
25a6ad85cb | |
![]() |
d41be42b84 | |
![]() |
1777ad1a07 | |
![]() |
54b6dd5767 | |
![]() |
821fc1b625 | |
![]() |
99cf86f39e | |
![]() |
13f5696ffc | |
![]() |
605c24ced4 | |
![]() |
5abb943e69 | |
![]() |
7544808274 | |
![]() |
9ac0e2ecf6 | |
![]() |
3292e17da1 | |
![]() |
5a994e312b | |
![]() |
241b31ec79 | |
![]() |
4f21129183 | |
![]() |
a2d29a180c | |
![]() |
224254aee9 | |
![]() |
23947a2662 | |
![]() |
28c3f82934 | |
![]() |
3078ef0ff5 | |
![]() |
be9ac8d979 | |
![]() |
6cdeaad6b6 | |
![]() |
348916bf9f | |
![]() |
f83f2f5bca | |
![]() |
a1fc249baf | |
![]() |
40b55bbf81 | |
![]() |
6b4dcf40f3 | |
![]() |
21170bba6b | |
![]() |
b496c3128d | |
![]() |
1ff3f04db6 | |
![]() |
7abee1f4a8 | |
![]() |
e050669e02 | |
![]() |
015a9aa3b9 | |
![]() |
6ee39b6f37 | |
![]() |
9effda6c54 | |
![]() |
56c21e523f | |
![]() |
a7990461fb | |
![]() |
70b1432eff | |
![]() |
174b491e44 | |
![]() |
240963aba2 | |
![]() |
5414971c2a | |
![]() |
c12ed274d0 | |
![]() |
5cd6d3c2b2 | |
![]() |
4b47ce1f9b | |
![]() |
a8fda5d367 | |
![]() |
84d064137a | |
![]() |
ae0851608d | |
![]() |
4c4445c9ba | |
![]() |
94274390f2 | |
![]() |
4877deb895 | |
![]() |
341db0ec0f | |
![]() |
cbcf47cac7 | |
![]() |
4501aa313e | |
![]() |
476be42e54 | |
![]() |
119c730859 | |
![]() |
ee09466a1a | |
![]() |
372d1663d5 | |
![]() |
5d5842dfdf | |
![]() |
00040613cf | |
![]() |
69471092fb | |
![]() |
22bcb198b8 | |
![]() |
5ea2c17ef0 | |
![]() |
a83915e939 | |
![]() |
b1903a3f3e | |
![]() |
b569d979e4 | |
![]() |
219e91e380 | |
![]() |
a6e0cd17b0 | |
![]() |
6f230469b0 | |
![]() |
1ba371dafa | |
![]() |
67a9d54224 | |
![]() |
88d2a1df7a | |
![]() |
6a6f296866 | |
![]() |
43da0027a0 | |
![]() |
c80b8e346a | |
![]() |
77973d5196 | |
![]() |
61761f251e | |
![]() |
be383e1af3 | |
![]() |
5eee3a20d3 | |
![]() |
ab46774872 | |
![]() |
2dc840503f | |
![]() |
c7edd69934 | |
![]() |
bdf93c6719 | |
![]() |
6dec6012b5 | |
![]() |
cb96613478 | |
![]() |
d8e95a3785 | |
![]() |
fcfd168c6a | |
![]() |
3d9cb9f454 | |
![]() |
379d5497d3 | |
![]() |
3efe0912ec | |
![]() |
592e819c93 | |
![]() |
0e78854da2 | |
![]() |
f2d4f52331 | |
![]() |
6771f25d42 | |
![]() |
11551a1816 | |
![]() |
85e8e21a5c | |
![]() |
38a18ed2c0 | |
![]() |
56cf06618d | |
![]() |
4dd8ad7ea2 | |
![]() |
6ebcbed847 | |
![]() |
eca77091a1 | |
![]() |
da297c899d | |
![]() |
51009e606b | |
![]() |
82f7cbd35f | |
![]() |
bb1a892ce5 | |
![]() |
67c62f746d | |
![]() |
5e4581ec0b | |
![]() |
ba9583a301 | |
![]() |
c646a621bf | |
![]() |
2e04d5d3fa | |
![]() |
32680423ef | |
![]() |
5123ee7f2a | |
![]() |
e84dd8c480 | |
![]() |
a1414b035c | |
![]() |
b3649ee064 | |
![]() |
61f581ece8 | |
![]() |
26fc53d6e9 | |
![]() |
f4a3d8adc2 | |
![]() |
594cd56cb6 | |
![]() |
9e3d998431 | |
![]() |
48fcef061f | |
![]() |
df7690ce9b | |
![]() |
1416e7997a | |
![]() |
64cd074fff | |
![]() |
00f5d0472b | |
![]() |
5c144b1327 | |
![]() |
d91819f4ff | |
![]() |
361dbd2f58 | |
![]() |
7882b646ea | |
![]() |
ae44cd497a | |
![]() |
66f585c245 | |
![]() |
29d0872599 | |
![]() |
34c5f3bdbb | |
![]() |
b9987cef5b | |
![]() |
5d1dfb67cb | |
![]() |
6400ceeb5e | |
![]() |
6a745deb16 | |
![]() |
d8324627a9 | |
![]() |
14ada4d2a9 | |
![]() |
4721d3d83b | |
![]() |
184368fb29 | |
![]() |
1fceadb87a | |
![]() |
4887a84782 | |
![]() |
1457a1d1d2 | |
![]() |
945663524e | |
![]() |
e78e73dc7c | |
![]() |
58c5374f93 | |
![]() |
40801a6f03 | |
![]() |
41b20dcda9 | |
![]() |
eff76314b1 | |
![]() |
33cca90740 | |
![]() |
18f0dc0c9d | |
![]() |
aefba2f66f | |
![]() |
ec2fbe98a4 | |
![]() |
92db24429a | |
![]() |
f6b6ece27c | |
![]() |
4b532b8d51 | |
![]() |
0077bfb258 | |
![]() |
d401f90ffa | |
![]() |
5ad0da7e64 | |
![]() |
713f38ac3a | |
![]() |
fb46442e1f | |
![]() |
ef9b510add | |
![]() |
a3b3bdb8f6 | |
![]() |
6299a733da | |
![]() |
036110d9df | |
![]() |
be570f1c63 | |
![]() |
a60e8a2126 | |
![]() |
53f69f8d20 | |
![]() |
4b7e4d37ec | |
![]() |
7f53558979 | |
![]() |
0a3d651d6b | |
![]() |
21464abe56 | |
![]() |
58ff3e7d6b | |
![]() |
07d736c7bc | |
![]() |
2bf7df0116 | |
![]() |
aaa34d36ea | |
![]() |
39a4e2cd9f | |
![]() |
3e8cc63d3a |
|
@ -1,5 +1,5 @@
|
|||
|
||||
name: CI
|
||||
name: Main CI
|
||||
|
||||
on:
|
||||
push:
|
||||
|
@ -7,56 +7,69 @@ on:
|
|||
- '*'
|
||||
tags:
|
||||
- '*'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build_windows:
|
||||
runs-on: self-hosted
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Lazarus
|
||||
uses: red-prig/setup-lazarus@v3
|
||||
with:
|
||||
lazarus-version: "3.6"
|
||||
with-cache: true
|
||||
|
||||
- name: Hash
|
||||
shell: cmd
|
||||
working-directory: ./
|
||||
run: echo '%GITHUB_SHA:~0,7%' > tag.inc
|
||||
- name: Hash
|
||||
shell: cmd
|
||||
working-directory: ./
|
||||
run: echo '%GITHUB_SHA:~0,7%' > tag.inc
|
||||
|
||||
- name: Tag
|
||||
shell: cmd
|
||||
working-directory: ./
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
run: echo '%GITHUB_REF_NAME%' > tag.inc
|
||||
- name: Tag
|
||||
shell: cmd
|
||||
working-directory: ./
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
run: echo '%GITHUB_REF_NAME%' > tag.inc
|
||||
|
||||
- name: Compile
|
||||
shell: cmd
|
||||
working-directory: ./
|
||||
run: |
|
||||
lazbuild -B fpPS4.lpi > nul
|
||||
strip fpPS4.exe
|
||||
- name: Compile
|
||||
shell: cmd
|
||||
working-directory: ./
|
||||
run: |
|
||||
lazbuild -B fpPS4.lpi > nul
|
||||
strip fpPS4.exe
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
||||
with:
|
||||
name: fpPS4
|
||||
path: fpPS4.exe
|
||||
if-no-files-found: warn
|
||||
- name: Download
|
||||
shell: cmd
|
||||
working-directory: ./
|
||||
run: |
|
||||
curl -k -L -s https://github.com/red-prig/fpps4-bin/raw/main/ffmpeg.zip -o ffmpeg.zip
|
||||
unzip ffmpeg.zip
|
||||
|
||||
- name: Pack
|
||||
shell: cmd
|
||||
working-directory: ./
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
run: |
|
||||
mkdir sce_module
|
||||
echo "Put libSceNgs2.prx and etc. here" > sce_module/info.txt
|
||||
zip -9 -qq -r "fpPS4_%GITHUB_REF_NAME%.zip" "fpPS4.exe" "sce_module/info.txt"
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
||||
with:
|
||||
name: fpPS4
|
||||
path: |
|
||||
fpPS4.exe
|
||||
*.dll
|
||||
if-no-files-found: warn
|
||||
|
||||
- name: Release
|
||||
uses: red-prig/action-gh-release@v1
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: ./fpPS4_${{ github.ref_name }}.zip
|
||||
- name: Pack
|
||||
shell: cmd
|
||||
working-directory: ./
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
run: |
|
||||
mkdir sce_module
|
||||
echo "Put libSceNgs2.prx and etc. here" > sce_module/info.txt
|
||||
zip -9 -qq -r "fpPS4_%GITHUB_REF_NAME%.zip" "fpPS4.exe" "*.dll" "sce_module/info.txt"
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: ./fpPS4_${{ github.ref_name }}.zip
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
name: PR CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build_windows:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Lazarus
|
||||
uses: red-prig/setup-lazarus@v3
|
||||
with:
|
||||
lazarus-version: "3.6"
|
||||
with-cache: true
|
||||
|
||||
- name: Hash
|
||||
shell: cmd
|
||||
working-directory: ./
|
||||
run: echo '%GITHUB_SHA:~0,7%' > tag.inc
|
||||
|
||||
- name: Compile
|
||||
shell: cmd
|
||||
working-directory: ./
|
||||
run: |
|
||||
lazbuild -B fpPS4.lpi > nul
|
||||
strip fpPS4.exe
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: fpPS4
|
||||
path: fpPS4.exe
|
||||
if-no-files-found: warn
|
|
@ -16,4 +16,5 @@ link.res
|
|||
lib/
|
||||
backup/
|
||||
shader_dump/*
|
||||
avplayer_dump/*
|
||||
savedata/*
|
||||
|
|
24
README.md
|
@ -1,18 +1,26 @@
|
|||
|
||||
# fpPS4 [](https://github.com/red-prig/fpPS4/actions) [<img src="https://img.shields.io/discord/1047920770225012769?color=5865F2&label=fpPS4&logo=discord&logoColor=white"/>](https://discord.gg/up9qatpX7M)
|
||||
|
||||
# Donate: [<img src="https://static.boosty.to/assets/images/logo.Ffjjd.svg"/>](https://boosty.to/fpps4)
|
||||
This emulator is still in the early stages of development and big games like the tripple A game still don't work, see the compatibility list for more details: https://github.com/red-prig/fpps4-game-compatibility/issues
|
||||
|
||||
If your game doesn't work don't create a new issue, check the compatibility list first.
|
||||
|
||||
If you want to know the details or just chat, welcome to the discord: https://discord.gg/up9qatpX7M
|
||||
|
||||
I am currently rewriting the emulator core in the [kern](https://github.com/red-prig/fpPS4/tree/kern) branch and until the work is completed, there will be no support for specific games.
|
||||
|
||||
# Donate: [<img src="icons/boosty.svg"/>](https://boosty.to/fpps4)
|
||||
|
||||

|
||||
|
||||
#
|
||||
|
||||
PS4 compatibility layer (emulator) on Free Pascal
|
||||
PS4 compatibility layer (emulator) written with Free Pascal
|
||||
|
||||
This project is at the beginning and started for fun.
|
||||
This project is currently at the beginning and started for fun.
|
||||
|
||||
### Building
|
||||
- Free pascal compiler: 3.3.1 (use fpcupdeluxe with trunk), x86_64 only.
|
||||
- Free Pascal compiler: 3.3.1 (use fpcupdeluxe with trunk), x86_64 only.
|
||||
- Lazarus: 2.0.0 and higher, x86_64 only.
|
||||
|
||||
### Minimum system requirements
|
||||
|
@ -27,11 +35,11 @@ https://github.com/red-prig/fpps4-game-compatibility/issues
|
|||
### Control layout
|
||||
To switch to borderless full screen mode, press Alt-Enter.
|
||||
|
||||
FPPS4 support XInput-compatible gamepads natively. You can remap buttons by pressing Esc on keyboard during emulation.
|
||||
Anyway you can use a keyboard input.
|
||||
A Dualshock4 touchpad is emulating by mouse.
|
||||
fpPS4 supports XInput-compatible gamepads natively. You can remap buttons by pressing Esc on the keyboard during emulation.
|
||||
Regardless, you can use a keyboard as a input.
|
||||
A DualShock4 touchpad is emulated by the mouse.
|
||||
|
||||
# KEYBOARD LAYOUT:
|
||||
# Keyboard layout:
|
||||
PS4 Gamepad button | Keyboard button
|
||||
:------------ | :------------
|
||||
Left Stick Up |W
|
||||
|
|
|
@ -7,8 +7,8 @@ interface
|
|||
uses
|
||||
Classes,
|
||||
SysUtils,
|
||||
half16,
|
||||
vulkan,
|
||||
Half16,
|
||||
Vulkan,
|
||||
vImage,
|
||||
bittype,
|
||||
pm4defs,
|
||||
|
@ -409,7 +409,10 @@ function _get_tsharp4_cformat(PT:PTSharpResource4):TVkFormat;
|
|||
function _get_tsharp4_min_lod(PT:PTSharpResource4):TVkImageViewMinLodCreateInfoEXT;
|
||||
|
||||
function _get_tsharp4_image_info(PT:PTSharpResource4):TvImageKey;
|
||||
function _get_tsharp8_image_info(PT:PTSharpResource8):TvImageKey;
|
||||
|
||||
function _get_tsharp4_image_view(PT:PTSharpResource4):TvImageViewKey;
|
||||
function _get_tsharp8_image_view(PT:PTSharpResource8):TvImageViewKey;
|
||||
|
||||
function _get_ssharp_info(PS:PSSharpResource4):TVkSamplerCreateInfo;
|
||||
|
||||
|
@ -1019,6 +1022,17 @@ begin
|
|||
else;
|
||||
end;
|
||||
|
||||
COLOR_10_11_11: //R:11 G:11 B:10
|
||||
Case NUMBER_TYPE of
|
||||
NUMBER_FLOAT :Result:=VK_FORMAT_B10G11R11_UFLOAT_PACK32;
|
||||
else;
|
||||
end;
|
||||
|
||||
COLOR_11_11_10: //R:10 G:11 B:11
|
||||
Case NUMBER_TYPE of
|
||||
NUMBER_FLOAT :Result:=VK_FORMAT_UNDEFINED; //Not directly handled to a vulkan
|
||||
else;
|
||||
end;
|
||||
|
||||
else;
|
||||
end;
|
||||
|
@ -1056,7 +1070,7 @@ begin
|
|||
Result.padded.Width :=(RENDER_TARGET[i].PITCH.TILE_MAX+1)*8;
|
||||
Result.padded.Height:=(RENDER_TARGET[i].SLICE.TILE_MAX+1)*8 div (RENDER_TARGET[i].PITCH.TILE_MAX+1);
|
||||
|
||||
Assert(RENDER_TARGET[i].INFO.ENDIAN=ENDIAN_NONE);
|
||||
Assert(RENDER_TARGET[i].INFO.ENDIAN=ENDIAN_NONE,'ENDIAN:'+IntToStr(RENDER_TARGET[i].INFO.ENDIAN));
|
||||
//Assert(RENDER_TARGET[i].INFO.COMPRESSION=0); //FMASK and MSAA
|
||||
|
||||
FORMAT :=RENDER_TARGET[i].INFO.FORMAT;
|
||||
|
@ -1168,10 +1182,13 @@ begin
|
|||
end
|
||||
|
||||
else
|
||||
Assert(false);
|
||||
{Assert(false)}; //TODO
|
||||
end;
|
||||
|
||||
//end;
|
||||
if (RENDER_TARGET[i].ATTRIB.FORCE_DST_ALPHA_1<>0) then
|
||||
begin
|
||||
Result.FImageView.dstSel.a:=ord(VK_COMPONENT_SWIZZLE_ONE);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
|
@ -1563,6 +1580,7 @@ begin
|
|||
BUF_DATA_FORMAT_16 :Result:=VK_FORMAT_R16_UNORM;
|
||||
BUF_DATA_FORMAT_16_16 :Result:=VK_FORMAT_R16G16_UNORM;
|
||||
BUF_DATA_FORMAT_16_16_16_16:Result:=VK_FORMAT_R16G16B16A16_UNORM;
|
||||
BUF_DATA_FORMAT_2_10_10_10 :Result:=VK_FORMAT_A2R10G10B10_UNORM_PACK32;
|
||||
else;
|
||||
end;
|
||||
|
||||
|
@ -1676,6 +1694,8 @@ begin
|
|||
IMG_DATA_FORMAT_BC1 :Result:=VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
|
||||
IMG_DATA_FORMAT_BC2 :Result:=VK_FORMAT_BC2_UNORM_BLOCK;
|
||||
IMG_DATA_FORMAT_BC3 :Result:=VK_FORMAT_BC3_UNORM_BLOCK;
|
||||
IMG_DATA_FORMAT_BC4 :Result:=VK_FORMAT_BC4_UNORM_BLOCK;
|
||||
IMG_DATA_FORMAT_BC5 :Result:=VK_FORMAT_BC5_UNORM_BLOCK;
|
||||
IMG_DATA_FORMAT_BC6 :Result:=VK_FORMAT_BC6H_UFLOAT_BLOCK;
|
||||
IMG_DATA_FORMAT_BC7 :Result:=VK_FORMAT_BC7_UNORM_BLOCK;
|
||||
|
||||
|
@ -1691,7 +1711,12 @@ begin
|
|||
IMG_DATA_FORMAT_BC1 :Result:=VK_FORMAT_BC1_RGBA_SRGB_BLOCK;
|
||||
IMG_DATA_FORMAT_BC2 :Result:=VK_FORMAT_BC2_SRGB_BLOCK;
|
||||
IMG_DATA_FORMAT_BC3 :Result:=VK_FORMAT_BC3_SRGB_BLOCK;
|
||||
IMG_DATA_FORMAT_BC4 :Result:=VK_FORMAT_BC4_UNORM_BLOCK;
|
||||
IMG_DATA_FORMAT_BC5 :Result:=VK_FORMAT_BC5_UNORM_BLOCK;
|
||||
IMG_DATA_FORMAT_BC6 :Result:=VK_FORMAT_BC6H_UFLOAT_BLOCK;
|
||||
IMG_DATA_FORMAT_BC7 :Result:=VK_FORMAT_BC7_SRGB_BLOCK;
|
||||
|
||||
IMG_DATA_FORMAT_2_10_10_10 :Result:=VK_FORMAT_A2R10G10B10_UNORM_PACK32;
|
||||
else;
|
||||
end;
|
||||
|
||||
|
@ -1774,6 +1799,9 @@ begin
|
|||
IMG_DATA_FORMAT_32_32 :Result:=VK_FORMAT_R32G32_SFLOAT;
|
||||
IMG_DATA_FORMAT_32_32_32 :Result:=VK_FORMAT_R32G32B32_SFLOAT;
|
||||
IMG_DATA_FORMAT_32_32_32_32:Result:=VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
|
||||
IMG_DATA_FORMAT_5_9_9_9 :Result:=VK_FORMAT_E5B9G9R9_UFLOAT_PACK32;
|
||||
IMG_DATA_FORMAT_10_11_11 :Result:=VK_FORMAT_B10G11R11_UFLOAT_PACK32;
|
||||
else;
|
||||
end;
|
||||
|
||||
|
@ -1811,12 +1839,12 @@ begin
|
|||
|
||||
if _img_is_msaa(PT^._type) then
|
||||
begin
|
||||
Result.params.samples :=PT^.last_level;
|
||||
Result.params.samples :=PT^.last_level+1;
|
||||
Result.params.mipLevels:=1;
|
||||
end else
|
||||
begin
|
||||
Result.params.samples :=1;
|
||||
Result.params.mipLevels:=PT^.last_level-PT^.base_level+1;
|
||||
Result.params.mipLevels:=PT^.last_level+1;
|
||||
end;
|
||||
|
||||
//Assert(Result.params.mipLevels=1,'TODO');
|
||||
|
@ -1825,6 +1853,29 @@ begin
|
|||
Result.params.arrayLayers:=1;
|
||||
end;
|
||||
|
||||
function _get_tsharp8_image_info(PT:PTSharpResource8):TvImageKey;
|
||||
begin
|
||||
Result:=_get_tsharp4_image_info(PTSharpResource4(PT));
|
||||
//
|
||||
Case PT^._type of
|
||||
SQ_RSRC_IMG_3D:
|
||||
begin
|
||||
Result.params.extend.depth:=PT^.depth+1;
|
||||
end;
|
||||
else;
|
||||
end;
|
||||
//
|
||||
Case PT^._type of
|
||||
SQ_RSRC_IMG_1D_ARRAY ,
|
||||
SQ_RSRC_IMG_2D_ARRAY ,
|
||||
SQ_RSRC_IMG_2D_MSAA_ARRAY:
|
||||
begin
|
||||
Result.params.arrayLayers:=PT^.last_array+1;
|
||||
end
|
||||
else;
|
||||
end;
|
||||
end;
|
||||
|
||||
function _get_dst_sel_swizzle(b:Byte):Byte;
|
||||
begin
|
||||
Case b of
|
||||
|
@ -1901,9 +1952,23 @@ begin
|
|||
|
||||
Result.base_level:=0; /////
|
||||
Result.last_level:=0; /////
|
||||
|
||||
end;
|
||||
|
||||
function _get_tsharp8_image_view(PT:PTSharpResource8):TvImageViewKey;
|
||||
begin
|
||||
Result:=_get_tsharp4_image_view(PTSharpResource4(PT));
|
||||
//
|
||||
Case PT^._type of
|
||||
SQ_RSRC_IMG_1D_ARRAY ,
|
||||
SQ_RSRC_IMG_2D_ARRAY ,
|
||||
SQ_RSRC_IMG_2D_MSAA_ARRAY:
|
||||
begin
|
||||
Result.base_array:=PT^.base_array;
|
||||
Result.last_array:=PT^.last_array;
|
||||
end
|
||||
else;
|
||||
end;
|
||||
end;
|
||||
|
||||
function _get_xy_filter(b:Byte):TVkFilter;
|
||||
begin
|
||||
|
|
|
@ -1227,7 +1227,7 @@ SOP1 32+
|
|||
SOPC 32+
|
||||
SOPP 32
|
||||
|
||||
SMRD 32
|
||||
SMRD 32+
|
||||
|
||||
VOP2 32+
|
||||
VOP1 32+
|
||||
|
@ -1412,7 +1412,8 @@ begin
|
|||
T:=H and LAST_5BIT;
|
||||
if (T=DW_SMRD) then //5
|
||||
begin
|
||||
pack4(TSMRD(H).OP);
|
||||
if (TSMRD(H).IMM=0) and
|
||||
(TSMRD(H).OFFSET=$FF) then pack8(TSMRD(H).OP) else pack4(TSMRD(H).OP);
|
||||
end else
|
||||
begin
|
||||
T:=H and LAST_4BIT;
|
||||
|
@ -1946,8 +1947,8 @@ begin
|
|||
|
||||
With SPI.SMRD do
|
||||
Case IMM of
|
||||
0:Write('s[',OFFSET,']');
|
||||
1:Write(OFFSET);
|
||||
0:_print_ssrc8(OFFSET,SPI.INLINE32);
|
||||
1:Write('0x',HexStr(OFFSET,2));
|
||||
end;
|
||||
|
||||
Writeln;
|
||||
|
|
|
@ -300,7 +300,7 @@ type
|
|||
pow2pad:bit1; //memory footprint is padded to power of 2 dimensions
|
||||
mtype_L1M:bit1;
|
||||
reserved:bit1;
|
||||
_type:bit4; //values [8..15] are 1D, 2D, 3D, Cube, 1D array, 2D array, 2D MSAA, 2D MSAA array; 0 is V#, 1-7 reserved
|
||||
_type:bit4; //values [8..15] are 1D, 2D, 3D, Cube, 1D array, 2D array, 2D MSAA, 2D MSAA array; 0 is V#, 1-7 reserved
|
||||
//32
|
||||
depth:bit13; //3D texture depth (0..8192)
|
||||
pitch:bit14; //texture pitch in texels (0..16383); defaults to width
|
||||
|
|
|
@ -25,7 +25,7 @@ uses
|
|||
|
||||
//ps4_Tiling,
|
||||
|
||||
vulkan,
|
||||
Vulkan,
|
||||
vDevice,
|
||||
vMemory,
|
||||
vShader,
|
||||
|
@ -319,21 +319,22 @@ end;
|
|||
const
|
||||
GpuCoreClockFrequency=800000000;
|
||||
|
||||
function mul_div_u64(m,d,v:QWORD):QWORD; sysv_abi_default; assembler; nostackframe;
|
||||
asm
|
||||
movq v,%rax
|
||||
mulq m
|
||||
divq d
|
||||
end;
|
||||
|
||||
function GetGpuTickCount:QWORD;
|
||||
var
|
||||
pc,pf:QWORD;
|
||||
DW0,DW1:QWORD;
|
||||
begin
|
||||
pc:=0;
|
||||
pf:=1;
|
||||
NtQueryPerformanceCounter(@pc,@pf);
|
||||
|
||||
//DW0*GF/pf + SHL_32* DW1*GF/pf
|
||||
|
||||
DW0:=(DWORD(pc shr 00)*GpuCoreClockFrequency) div pf;
|
||||
DW1:=(DWORD(pc shr 32)*GpuCoreClockFrequency) div pf;
|
||||
|
||||
Result:=DW0+(DW1 shl 32);
|
||||
Result:=mul_div_u64(GpuCoreClockFrequency,pf,pc);
|
||||
end;
|
||||
|
||||
Function me_eop(node:pvMeEopInfo):Boolean;
|
||||
|
@ -422,15 +423,56 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
type
|
||||
gfx_backoff_exp=object
|
||||
private
|
||||
Const
|
||||
lower_bound = 1000;
|
||||
upper_bound = 100000;
|
||||
Var
|
||||
m_nExpCur:SizeUInt;
|
||||
public
|
||||
Procedure Wait;
|
||||
Procedure Reset;
|
||||
end;
|
||||
|
||||
Procedure gfx_backoff_exp.Wait;
|
||||
Var
|
||||
time:Int64;
|
||||
begin
|
||||
if (m_nExpCur<=upper_bound) then
|
||||
begin
|
||||
m_nExpCur:=m_nExpCur*2;
|
||||
end;
|
||||
time:=-m_nExpCur;
|
||||
NtDelayExecution(True,@time);
|
||||
end;
|
||||
|
||||
Procedure gfx_backoff_exp.Reset; inline;
|
||||
begin
|
||||
m_nExpCur:=lower_bound;
|
||||
end;
|
||||
|
||||
Procedure WaitSubmit; inline;
|
||||
Var
|
||||
time:Int64;
|
||||
begin
|
||||
time:=Int64(NT_INFINITE);
|
||||
NtDelayExecution(True,@time);
|
||||
end;
|
||||
|
||||
function GFX_thread(p:pointer):ptrint;
|
||||
var
|
||||
time:Int64;
|
||||
backoff:gfx_backoff_exp;
|
||||
work_do:Boolean;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
sys_crt_init;
|
||||
|
||||
SetThreadDebugName(GetCurrentThreadId, 'GFX Thread');
|
||||
|
||||
backoff.Reset;
|
||||
repeat
|
||||
work_do:=False;
|
||||
|
||||
|
@ -450,24 +492,24 @@ begin
|
|||
//end;
|
||||
end else
|
||||
begin
|
||||
time:=-100000;
|
||||
NtDelayExecution(True,@time);
|
||||
backoff.Wait;
|
||||
Continue;
|
||||
end;
|
||||
work_do:=True;
|
||||
backoff.Reset;
|
||||
end;
|
||||
|
||||
if GFXMicroEngine.Next then
|
||||
begin
|
||||
me_node_submit(GFXMicroEngine.Current);
|
||||
work_do:=True;
|
||||
backoff.Reset;
|
||||
end;
|
||||
|
||||
if not work_do then
|
||||
begin
|
||||
SetEvent(FIdleEvent);
|
||||
time:=Int64(NT_INFINITE);
|
||||
NtDelayExecution(True,@time);
|
||||
WaitSubmit;
|
||||
end;
|
||||
|
||||
until false;
|
||||
|
@ -625,7 +667,7 @@ begin
|
|||
|
||||
ResetEvent(FIdleEvent);
|
||||
GFXRing.Queue.Push(node);
|
||||
NtQueueApcThread(_gfx_handle,@_apc_null,0,nil,0);
|
||||
NtQueueApcThread(_gfx_handle,@_apc_null,nil,nil,0);
|
||||
end;
|
||||
|
||||
procedure vSubmitDone;
|
||||
|
@ -1575,7 +1617,7 @@ const
|
|||
VK_IMAGE_USAGE_DEFAULT or
|
||||
ord(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||
|
||||
function VK_IMAGE_USAGE_DEFAULT_COLOR(cformat:TVkFormat):TVkFlags;
|
||||
function VK_IMAGE_USAGE_DEFAULT_COLOR(cformat:TVkFormat;rt:Boolean):TVkFlags;
|
||||
begin
|
||||
Case cformat of
|
||||
VK_FORMAT_R4G4_UNORM_PACK8..
|
||||
|
@ -1594,6 +1636,13 @@ begin
|
|||
Result:=VK_IMAGE_USAGE_DEFAULT or
|
||||
ord(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
end;
|
||||
|
||||
if rt then
|
||||
begin
|
||||
Result:=VK_IMAGE_USAGE_DEFAULT or
|
||||
ord(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
procedure ClearRenderTarget;
|
||||
|
@ -1611,7 +1660,7 @@ begin
|
|||
|
||||
ri:=FetchImage(GFXRing.CmdBuffer,
|
||||
RT_INFO.FImageInfo,
|
||||
VK_IMAGE_USAGE_DEFAULT_COLOR(RT_INFO.FImageInfo.cformat),
|
||||
VK_IMAGE_USAGE_DEFAULT_COLOR(RT_INFO.FImageInfo.cformat,true),
|
||||
TM_CLEAR
|
||||
);
|
||||
|
||||
|
@ -1647,13 +1696,13 @@ begin
|
|||
|
||||
ri_src:=FetchImage(GFXRing.CmdBuffer,
|
||||
RT_INFO_SRC.FImageInfo,
|
||||
VK_IMAGE_USAGE_DEFAULT_COLOR(RT_INFO_SRC.FImageInfo.cformat),
|
||||
VK_IMAGE_USAGE_DEFAULT_COLOR(RT_INFO_SRC.FImageInfo.cformat,true),
|
||||
{TM_READ}0
|
||||
);
|
||||
|
||||
ri_dst:=FetchImage(GFXRing.CmdBuffer,
|
||||
RT_INFO_DST.FImageInfo,
|
||||
VK_IMAGE_USAGE_DEFAULT_COLOR(RT_INFO_DST.FImageInfo.cformat),
|
||||
VK_IMAGE_USAGE_DEFAULT_COLOR(RT_INFO_DST.FImageInfo.cformat,true),
|
||||
TM_WRITE
|
||||
);
|
||||
|
||||
|
@ -1927,7 +1976,7 @@ begin
|
|||
|
||||
ri:=FetchImage(GFXRing.CmdBuffer,
|
||||
RT_INFO.FImageInfo,
|
||||
VK_IMAGE_USAGE_DEFAULT_COLOR(RT_INFO.FImageInfo.cformat),
|
||||
VK_IMAGE_USAGE_DEFAULT_COLOR(RT_INFO.FImageInfo.cformat,true),
|
||||
RT_INFO.IMAGE_USAGE
|
||||
);
|
||||
|
||||
|
@ -2137,7 +2186,7 @@ begin
|
|||
|
||||
ri:=FetchImage(GFXRing.CmdBuffer,
|
||||
FImage,
|
||||
VK_IMAGE_USAGE_DEFAULT_COLOR(FImage.cformat),
|
||||
VK_IMAGE_USAGE_DEFAULT_COLOR(FImage.cformat,false),
|
||||
TM_READ
|
||||
);
|
||||
|
||||
|
@ -2241,7 +2290,7 @@ begin
|
|||
|
||||
ri:=FetchImage(GFXRing.CmdBuffer,
|
||||
FImage,
|
||||
VK_IMAGE_USAGE_DEFAULT_COLOR(FImage.cformat),
|
||||
VK_IMAGE_USAGE_DEFAULT_COLOR(FImage.cformat,false),
|
||||
TM_READ
|
||||
);
|
||||
|
||||
|
|
|
@ -0,0 +1,371 @@
|
|||
{$POINTERMATH ON}
|
||||
{$MINENUMSIZE 4} (* use 4-byte enums *)
|
||||
{$WRITEABLECONST ON}
|
||||
|
||||
(*
|
||||
* FF_API_* defines may be placed below to indicate public API that will be
|
||||
* dropped at a future version bump. The defines themselves are not part of
|
||||
* the public API and may change, break or disappear at any time.
|
||||
*
|
||||
* @note, when bumping the major version it is recommended to manually
|
||||
* disable each FF_API_* in its own commit instead of disabling them all
|
||||
* at once through the bump. This improves the git bisect-ability of the change.
|
||||
*)
|
||||
const
|
||||
{$REGION 'libavutil'}
|
||||
LIBAVUTIL_VERSION_MAJOR = 56;
|
||||
LIBAVUTIL_VERSION_MAJOR_STR = '56';
|
||||
LIBAVUTIL_VERSION_MINOR = 31;
|
||||
LIBAVUTIL_VERSION_MICRO = 100;
|
||||
FFMPEG_VERSION = '4.2.2';
|
||||
LIBAVUTIL_VERSION_INT = ((LIBAVUTIL_VERSION_MAJOR shl 16) or (LIBAVUTIL_VERSION_MINOR shl 8) or LIBAVUTIL_VERSION_MICRO);
|
||||
|
||||
{$IFNDEF FF_API_VAAPI}
|
||||
{$IF LIBAVUTIL_VERSION_MAJOR < 57}
|
||||
{$DEFINE FF_API_VAAPI}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_FRAME_QP}
|
||||
{$IF LIBAVUTIL_VERSION_MAJOR < 57}
|
||||
{$DEFINE FF_API_FRAME_QP}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_PLUS1_MINUS1}
|
||||
{$IF LIBAVUTIL_VERSION_MAJOR < 57}
|
||||
{$DEFINE FF_API_PLUS1_MINUS1}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_ERROR_FRAME}
|
||||
{$IF LIBAVUTIL_VERSION_MAJOR < 57}
|
||||
{$DEFINE FF_API_ERROR_FRAME}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_PKT_PTS}
|
||||
{$IF LIBAVUTIL_VERSION_MAJOR < 57}
|
||||
{$DEFINE FF_API_PKT_PTS}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_CRYPTO_SIZE_T}
|
||||
{$IF LIBAVUTIL_VERSION_MAJOR < 57}
|
||||
{$DEFINE FF_API_CRYPTO_SIZE_T}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_FRAME_GET_SET}
|
||||
{$IF LIBAVUTIL_VERSION_MAJOR < 57}
|
||||
{$DEFINE FF_API_FRAME_GET_SET}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_PSEUDOPAL}
|
||||
{$IF LIBAVUTIL_VERSION_MAJOR < 57}
|
||||
{$DEFINE FF_API_PSEUDOPAL} // Отсутсвует
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$ENDREGION}
|
||||
{$REGION 'libswscale'}
|
||||
LIBSWSCALE_VERSION_MAJOR = 5;
|
||||
LIBSWSCALE_VERSION_MAJOR_STR = '5';
|
||||
LIBSWSCALE_VERSION_MINOR = 5;
|
||||
LIBSWSCALE_VERSION_MICRO = 100;
|
||||
{$ENDREGION}
|
||||
{$REGION 'libavcodec'}
|
||||
LIBAVCODEC_VERSION_MAJOR = 58;
|
||||
LIBAVCODEC_VERSION_MAJOR_STR = '58';
|
||||
LIBAVCODEC_VERSION_MINOR = 54;
|
||||
LIBAVCODEC_VERSION_MICRO = 100;
|
||||
|
||||
{$IFNDEF FF_API_LOWRES}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_LOWRES}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_DEBUG_MV}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 58}
|
||||
{$DEFINE FF_API_DEBUG_MV}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_AVCTX_TIMEBASE}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_AVCTX_TIMEBASE} // Отсутсвует
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_CODED_FRAME}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_CODED_FRAME}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_SIDEDATA_ONLY_PKT}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_SIDEDATA_ONLY_PKT}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_VDPAU_PROFILE}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_VDPAU_PROFILE} // Отсутсвует
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_CONVERGENCE_DURATION}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_CONVERGENCE_DURATION}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_AVPICTURE}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_AVPICTURE}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_AVPACKET_OLD_API}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_AVPACKET_OLD_API}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_RTP_CALLBACK}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_RTP_CALLBACK}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_VBV_DELAY}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_VBV_DELAY}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_CODER_TYPE}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_CODER_TYPE}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_STAT_BITS}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_STAT_BITS}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_PRIVATE_OPT}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_PRIVATE_OPT}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_ASS_TIMING}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_ASS_TIMING}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_OLD_BSF}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_OLD_BSF}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_COPY_CONTEXT}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_COPY_CONTEXT}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_GET_CONTEXT_DEFAULTS}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_GET_CONTEXT_DEFAULTS}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_NVENC_OLD_NAME}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_NVENC_OLD_NAME} // Отсутсвует
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_STRUCT_VAAPI_CONTEXT}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_STRUCT_VAAPI_CONTEXT}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_MERGE_SD_API}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_MERGE_SD_API}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_TAG_STRING}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_TAG_STRING}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_GETCHROMA}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_GETCHROMA}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_CODEC_GET_SET}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_CODEC_GET_SET}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_USER_VISIBLE_AVHWACCEL}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_USER_VISIBLE_AVHWACCEL}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_LOCKMGR}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_LOCKMGR}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_NEXT}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_NEXT}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_UNSANITIZED_BITRATES}
|
||||
{$IF LIBAVCODEC_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_UNSANITIZED_BITRATES}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$ENDREGION}
|
||||
{$REGION 'avdevice'}
|
||||
LIBAVDEVICE_VERSION_MAJOR = 58;
|
||||
LIBAVDEVICE_VERSION_MAJOR_STR = '58';
|
||||
LIBAVDEVICE_VERSION_MINOR = 8;
|
||||
LIBAVDEVICE_VERSION_MICRO = 100;
|
||||
{$ENDREGION}
|
||||
{$REGION 'avformat'}
|
||||
LIBAVFORMAT_VERSION_MAJOR = 58;
|
||||
LIBAVFORMAT_VERSION_MAJOR_STR = '58';
|
||||
LIBAVFORMAT_VERSION_MINOR = 29;
|
||||
LIBAVFORMAT_VERSION_MICRO = 100;
|
||||
|
||||
{$IFNDEF FF_API_COMPUTE_PKT_FIELDS2}
|
||||
{$IF LIBAVFORMAT_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_COMPUTE_PKT_FIELDS2} // Отсутсвует
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_OLD_OPEN_CALLBACKS}
|
||||
{$IF LIBAVFORMAT_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_OLD_OPEN_CALLBACKS}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_LAVF_AVCTX}
|
||||
{$IF LIBAVFORMAT_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_LAVF_AVCTX}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_HTTP_USER_AGENT}
|
||||
{$IF LIBAVFORMAT_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_HTTP_USER_AGENT} // Отсутсвует
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_HLS_WRAP}
|
||||
{$IF LIBAVFORMAT_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_HLS_WRAP} // Отсутсвует
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_HLS_USE_LOCALTIME}
|
||||
{$IF LIBAVFORMAT_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_HLS_USE_LOCALTIME} // Отсутсвует
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_LAVF_KEEPSIDE_FLAG}
|
||||
{$IF LIBAVFORMAT_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_LAVF_KEEPSIDE_FLAG} // Отсутсвует
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_OLD_ROTATE_API}
|
||||
{$IF LIBAVFORMAT_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_OLD_ROTATE_API} // Отсутсвует
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_FORMAT_GET_SET}
|
||||
{$IF LIBAVFORMAT_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_FORMAT_GET_SET}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_OLD_AVIO_EOF_0}
|
||||
{$IF LIBAVFORMAT_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_OLD_AVIO_EOF_0} // Отсутсвует
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_LAVF_FFSERVER}
|
||||
{$IF LIBAVFORMAT_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_LAVF_FFSERVER}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_FORMAT_FILENAME}
|
||||
{$IF LIBAVFORMAT_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_FORMAT_FILENAME}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_OLD_RTSP_OPTIONS}
|
||||
{$IF LIBAVFORMAT_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_OLD_RTSP_OPTIONS} // Отсутсвует
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_NEXT}
|
||||
{$IF LIBAVFORMAT_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_NEXT}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_DASH_MIN_SEG_DURATION}
|
||||
{$IF LIBAVFORMAT_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_DASH_MIN_SEG_DURATION} // Отсутсвует
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_LAVF_MP4A_LATM}
|
||||
{$IF LIBAVFORMAT_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_LAVF_MP4A_LATM} // Отсутсвует
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_AVIOFORMAT}
|
||||
{$IF LIBAVFORMAT_VERSION_MAJOR < 59}
|
||||
{$DEFINE FF_API_AVIOFORMAT}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_R_FRAME_RATE}
|
||||
FF_API_R_FRAME_RATE = 1;
|
||||
{$ENDIF}
|
||||
{$ENDREGION}
|
||||
{$REGION 'postproc'}
|
||||
LIBPOSTPROC_VERSION_MAJOR = 55;
|
||||
LIBPOSTPROC_VERSION_MAJOR_STR = '55';
|
||||
LIBPOSTPROC_VERSION_MINOR = 5;
|
||||
LIBPOSTPROC_VERSION_MICRO = 100;
|
||||
{$ENDREGION}
|
||||
{$REGION 'swresample.h'}
|
||||
LIBSWRESAMPLE_VERSION_MAJOR = 3;
|
||||
LIBSWRESAMPLE_VERSION_MAJOR_STR = '3';
|
||||
LIBSWRESAMPLE_VERSION_MINOR = 5;
|
||||
LIBSWRESAMPLE_VERSION_MICRO = 100;
|
||||
|
||||
{$IFNDEF FF_API_SWS_VECTOR}
|
||||
{$IF LIBSWSCALE_VERSION_MAJOR < 6}
|
||||
{$DEFINE FF_API_SWS_VECTOR}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$ENDREGION}
|
||||
{$REGION 'avfilter.h'}
|
||||
LIBAVFILTER_VERSION_MAJOR = 7;
|
||||
LIBAVFILTER_VERSION_MAJOR_STR = '7';
|
||||
LIBAVFILTER_VERSION_MINOR = 57;
|
||||
LIBAVFILTER_VERSION_MICRO = 100;
|
||||
|
||||
{$IFNDEF FF_API_OLD_FILTER_OPTS_ERROR}
|
||||
{$IF LIBAVFILTER_VERSION_MAJOR < 8}
|
||||
{$DEFINE FF_API_OLD_FILTER_OPTS_ERROR} // Отсутсвует
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_LAVR_OPTS}
|
||||
{$IF LIBAVFILTER_VERSION_MAJOR < 8}
|
||||
{$DEFINE FF_API_LAVR_OPTS}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_FILTER_GET_SET}
|
||||
{$IF LIBAVFILTER_VERSION_MAJOR < 8}
|
||||
{$DEFINE FF_API_FILTER_GET_SET}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFNDEF FF_API_NEXT}
|
||||
{$IF LIBAVFILTER_VERSION_MAJOR < 8}
|
||||
{$DEFINE FF_API_NEXT}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$DEFINE FF_INTERNAL_FIELDS}
|
||||
{$ENDREGION}
|
||||
swscale_dll = 'swscale-' + LIBSWSCALE_VERSION_MAJOR_STR + '.dll';
|
||||
avutil_dll = 'avutil-' + LIBAVUTIL_VERSION_MAJOR_STR + '.dll';
|
||||
avcodec_dll = 'avcodec-' + LIBAVCODEC_VERSION_MAJOR_STR + '.dll';
|
||||
avdevice_dll = 'avdevice-' + LIBAVDEVICE_VERSION_MAJOR_STR + '.dll';
|
||||
avformat_dll = 'avformat-' + LIBAVFORMAT_VERSION_MAJOR_STR + '.dll';
|
||||
postproc_dll = 'postproc-' + LIBPOSTPROC_VERSION_MAJOR_STR + '.dll';
|
||||
swresample_dll = 'swresample-' + LIBSWRESAMPLE_VERSION_MAJOR_STR + '.dll';
|
||||
avfilter_dll = 'avfilter-' + LIBAVFILTER_VERSION_MAJOR_STR + '.dll';
|
|
@ -0,0 +1,99 @@
|
|||
unit ffmpeg_types;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
Type
|
||||
Bool = WordBool;
|
||||
float = Single;
|
||||
ppDouble = ^pDouble;
|
||||
|
||||
size_t = NativeUInt;
|
||||
psize_t = ^size_t;
|
||||
ptrdiff_t = UInt32;
|
||||
uint32_t = Cardinal;
|
||||
unsigned = uint32_t;
|
||||
unsignedint = UInt32;
|
||||
UINT = unsigned;
|
||||
unsigned_int = UInt32;
|
||||
punsigned_int = ^unsigned_int;
|
||||
unsigned_long = Cardinal;
|
||||
|
||||
unsignedchar = Byte;
|
||||
unsigned_char = unsignedchar;
|
||||
punsignedchar = PByte; // ^unsignedchar;
|
||||
punsigned_char = punsignedchar;
|
||||
|
||||
Int = Integer;
|
||||
pint = ^Int;
|
||||
ppint = ^pint;
|
||||
|
||||
int8_t = Int8;
|
||||
pint8_t = ^int8_t;
|
||||
|
||||
uint8_t = Byte;
|
||||
puint8_t = PByte; // ^uint8_t;
|
||||
ppuint8_t = ^puint8_t;
|
||||
PPByte = ppuint8_t;
|
||||
|
||||
int16_t = int16;
|
||||
pint16_t = ^int16_t;
|
||||
uint16_t = UInt16;
|
||||
puint16_t = ^uint16_t;
|
||||
|
||||
int32_t = Int32;
|
||||
pint32_t = ^int32_t;
|
||||
ppint32_t = ^pint32_t;
|
||||
|
||||
int64_t = Int64;
|
||||
pint64_t = ^int64_t;
|
||||
uint64_t = UInt64;
|
||||
puint64_t = ^uint64_t;
|
||||
|
||||
array_uint8_t = array [0 .. 0] of uint8_t;
|
||||
parray_uint8_t = ^array_uint8_t;
|
||||
|
||||
array_int = array [0 .. 0] of Int;
|
||||
parray_int = ^array_int;
|
||||
|
||||
array4_int = array [0 .. 3] of Int;
|
||||
parray4_int = ^array4_int;
|
||||
|
||||
array4_puint8_t = array [0 .. 3] of puint8_t;
|
||||
parray4_puint8_t = ^array4_puint8_t;
|
||||
|
||||
array4_ptrdiff_t = array [0 .. 3] of ptrdiff_t;
|
||||
parray4_ptrdiff_t = ^array4_ptrdiff_t;
|
||||
|
||||
time_t = LongInt;
|
||||
|
||||
AnsiCharArray = array [0 .. 0] of pAnsiChar;
|
||||
pAnsiCharArray = ^AnsiCharArray;
|
||||
|
||||
(* MICROSOFT VC++ STDIO'S FILE DEFINITION *)
|
||||
_iobuf = record
|
||||
_ptr: pAnsiChar;
|
||||
_cnt: Integer;
|
||||
_base: pAnsiChar;
|
||||
_flag: Integer;
|
||||
_file: Integer;
|
||||
_charbuf: Integer;
|
||||
_bufsiz: Integer;
|
||||
_tmpfname: pAnsiChar;
|
||||
end;
|
||||
|
||||
PFile = ^TFile;
|
||||
TFile = _iobuf;
|
||||
|
||||
pAVHWAccel = Pointer;
|
||||
ppAVCodecHWConfigInternal = Pointer;
|
||||
|
||||
const
|
||||
max_unsigned = $FFFF;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
|
@ -0,0 +1,522 @@
|
|||
unit libavdevice;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
Uses
|
||||
ffmpeg_types, libavutil, libavcodec, libavformat;
|
||||
|
||||
{$I ffmpeg.inc}
|
||||
|
||||
(* *
|
||||
* @defgroup lavd libavdevice
|
||||
* Special devices muxing/demuxing library.
|
||||
*
|
||||
* Libavdevice is a complementary library to @ref libavf "libavformat". It
|
||||
* provides various "special" platform-specific muxers and demuxers, e.g. for
|
||||
* grabbing devices, audio capture and playback etc. As a consequence, the
|
||||
* (de)muxers in libavdevice are of the AVFMT_NOFILE type (they use their own
|
||||
* I/O functions). The filename passed to avformat_open_input() often does not
|
||||
* refer to an actually existing file, but has some special device-specific
|
||||
* meaning - e.g. for xcbgrab it is the display name.
|
||||
*
|
||||
* To use libavdevice, simply call avdevice_register_all() to register all
|
||||
* compiled muxers and demuxers. They all use standard libavformat API.
|
||||
*
|
||||
*)
|
||||
|
||||
(* *
|
||||
* Return the LIBAVDEVICE_VERSION_INT constant.
|
||||
*)
|
||||
// unsigned avdevice_version(void);
|
||||
function avdevice_version(): unsigned; cdecl; external avdevice_dll;
|
||||
|
||||
(* *
|
||||
* Return the libavdevice build-time configuration.
|
||||
*)
|
||||
// const char *avdevice_configuration(void);
|
||||
function avdevice_configuration(): pAnsiChar; cdecl; external avdevice_dll;
|
||||
|
||||
(* *
|
||||
* Return the libavdevice license.
|
||||
*)
|
||||
// const char *avdevice_license(void);
|
||||
function avdevice_license(): pAnsiChar; cdecl; external avdevice_dll;
|
||||
|
||||
(* *
|
||||
* Initialize libavdevice and register all the input and output devices.
|
||||
*)
|
||||
// void avdevice_register_all(void);
|
||||
procedure avdevice_register_all(); cdecl; external avdevice_dll;
|
||||
|
||||
(* *
|
||||
* Audio input devices iterator.
|
||||
*
|
||||
* If d is NULL, returns the first registered input audio/video device,
|
||||
* if d is non-NULL, returns the next registered input audio/video device after d
|
||||
* or NULL if d is the last one.
|
||||
*)
|
||||
// AVInputFormat *av_input_audio_device_next(AVInputFormat *d);
|
||||
function av_input_audio_device_next(d: pAVInputFormat): pAVInputFormat; cdecl; external avdevice_dll;
|
||||
|
||||
(* *
|
||||
* Video input devices iterator.
|
||||
*
|
||||
* If d is NULL, returns the first registered input audio/video device,
|
||||
* if d is non-NULL, returns the next registered input audio/video device after d
|
||||
* or NULL if d is the last one.
|
||||
*)
|
||||
// AVInputFormat *av_input_video_device_next(AVInputFormat *d);
|
||||
function av_input_video_device_next(d: pAVInputFormat): pAVInputFormat; cdecl; external avdevice_dll;
|
||||
|
||||
(* *
|
||||
* Audio output devices iterator.
|
||||
*
|
||||
* If d is NULL, returns the first registered output audio/video device,
|
||||
* if d is non-NULL, returns the next registered output audio/video device after d
|
||||
* or NULL if d is the last one.
|
||||
*)
|
||||
// AVOutputFormat *av_output_audio_device_next(AVOutputFormat *d);
|
||||
function av_output_audio_device_next(d: pAVOutputFormat): pAVOutputFormat; cdecl; external avdevice_dll;
|
||||
|
||||
(* *
|
||||
* Video output devices iterator.
|
||||
*
|
||||
* If d is NULL, returns the first registered output audio/video device,
|
||||
* if d is non-NULL, returns the next registered output audio/video device after d
|
||||
* or NULL if d is the last one.
|
||||
*)
|
||||
// AVOutputFormat *av_output_video_device_next(AVOutputFormat *d);
|
||||
function av_output_video_device_next(d: pAVOutputFormat): pAVOutputFormat; cdecl; external avdevice_dll;
|
||||
|
||||
type
|
||||
pAVDeviceRect = ^AVDeviceRect;
|
||||
|
||||
AVDeviceRect = record
|
||||
x: int; (* *< x coordinate of top left corner *)
|
||||
y: int; (* *< y coordinate of top left corner *)
|
||||
width: int; (* *< width *)
|
||||
height: int; (* *< height *)
|
||||
end;
|
||||
|
||||
(* *
|
||||
* Message types used by avdevice_app_to_dev_control_message().
|
||||
*)
|
||||
AVAppToDevMessageType = array [0 .. 3] of AnsiChar;
|
||||
|
||||
const
|
||||
(* *
|
||||
* Dummy message.
|
||||
*)
|
||||
AV_APP_TO_DEV_NONE: AVAppToDevMessageType = ('N', 'O', 'N', 'E');
|
||||
|
||||
(* *
|
||||
* Window size change message.
|
||||
*
|
||||
* Message is sent to the device every time the application changes the size
|
||||
* of the window device renders to.
|
||||
* Message should also be sent right after window is created.
|
||||
*
|
||||
* data: AVDeviceRect: new window size.
|
||||
*)
|
||||
AV_APP_TO_DEV_WINDOW_SIZE: AVAppToDevMessageType = ('G', 'E', 'O', 'M');
|
||||
|
||||
(* *
|
||||
* Repaint request message.
|
||||
*
|
||||
* Message is sent to the device when window has to be repainted.
|
||||
*
|
||||
* data: AVDeviceRect: area required to be repainted.
|
||||
* NULL: whole area is required to be repainted.
|
||||
*)
|
||||
AV_APP_TO_DEV_WINDOW_REPAINT: AVAppToDevMessageType = ('R', 'E', 'P', 'A');
|
||||
|
||||
(* *
|
||||
* Request pause/play.
|
||||
*
|
||||
* Application requests pause/unpause playback.
|
||||
* Mostly usable with devices that have internal buffer.
|
||||
* By default devices are not paused.
|
||||
*
|
||||
* data: NULL
|
||||
*)
|
||||
AV_APP_TO_DEV_PAUSE: AVAppToDevMessageType = ('P', 'A', 'U', ' ');
|
||||
AV_APP_TO_DEV_PLAY: AVAppToDevMessageType = ('P', 'L', 'A', 'Y');
|
||||
AV_APP_TO_DEV_TOGGLE_PAUSE: AVAppToDevMessageType = ('P', 'A', 'U', 'T');
|
||||
|
||||
(* *
|
||||
* Volume control message.
|
||||
*
|
||||
* Set volume level. It may be device-dependent if volume
|
||||
* is changed per stream or system wide. Per stream volume
|
||||
* change is expected when possible.
|
||||
*
|
||||
* data: double: new volume with range of 0.0 - 1.0.
|
||||
*)
|
||||
AV_APP_TO_DEV_SET_VOLUME: AVAppToDevMessageType = ('S', 'V', 'O', 'L');
|
||||
|
||||
(* *
|
||||
* Mute control messages.
|
||||
*
|
||||
* Change mute state. It may be device-dependent if mute status
|
||||
* is changed per stream or system wide. Per stream mute status
|
||||
* change is expected when possible.
|
||||
*
|
||||
* data: NULL.
|
||||
*)
|
||||
AV_APP_TO_DEV_MUTE: AVAppToDevMessageType = (' ', 'M', 'U', 'T');
|
||||
AV_APP_TO_DEV_UNMUTE: AVAppToDevMessageType = ('U', 'M', 'U', 'T');
|
||||
AV_APP_TO_DEV_TOGGLE_MUTE: AVAppToDevMessageType = ('T', 'M', 'U', 'T');
|
||||
|
||||
(* *
|
||||
* Get volume/mute messages.
|
||||
*
|
||||
* Force the device to send AV_DEV_TO_APP_VOLUME_LEVEL_CHANGED or
|
||||
* AV_DEV_TO_APP_MUTE_STATE_CHANGED command respectively.
|
||||
*
|
||||
* data: NULL.
|
||||
*)
|
||||
AV_APP_TO_DEV_GET_VOLUME: AVAppToDevMessageType = ('G', 'V', 'O', 'L');
|
||||
AV_APP_TO_DEV_GET_MUTE: AVAppToDevMessageType = ('G', 'M', 'U', 'T');
|
||||
|
||||
type
|
||||
AVDevToAppMessageType = array [0 .. 3] of AnsiChar;
|
||||
|
||||
const
|
||||
(* *
|
||||
* Message types used by avdevice_dev_to_app_control_message().
|
||||
*)
|
||||
(* *
|
||||
* Dummy message.
|
||||
*)
|
||||
AV_DEV_TO_APP_NONE: AVDevToAppMessageType = ('N', 'O', 'N', 'E');
|
||||
|
||||
(* *
|
||||
* Create window buffer message.
|
||||
*
|
||||
* Device requests to create a window buffer. Exact meaning is device-
|
||||
* and application-dependent. Message is sent before rendering first
|
||||
* frame and all one-shot initializations should be done here.
|
||||
* Application is allowed to ignore preferred window buffer size.
|
||||
*
|
||||
* @note: Application is obligated to inform about window buffer size
|
||||
* with AV_APP_TO_DEV_WINDOW_SIZE message.
|
||||
*
|
||||
* data: AVDeviceRect: preferred size of the window buffer.
|
||||
* NULL: no preferred size of the window buffer.
|
||||
*)
|
||||
AV_DEV_TO_APP_CREATE_WINDOW_BUFFER: AVDevToAppMessageType = ('B', 'C', 'R', 'E');
|
||||
|
||||
(* *
|
||||
* Prepare window buffer message.
|
||||
*
|
||||
* Device requests to prepare a window buffer for rendering.
|
||||
* Exact meaning is device- and application-dependent.
|
||||
* Message is sent before rendering of each frame.
|
||||
*
|
||||
* data: NULL.
|
||||
*)
|
||||
AV_DEV_TO_APP_PREPARE_WINDOW_BUFFER: AVDevToAppMessageType = ('B', 'P', 'R', 'E');
|
||||
|
||||
(* *
|
||||
* Display window buffer message.
|
||||
*
|
||||
* Device requests to display a window buffer.
|
||||
* Message is sent when new frame is ready to be displayed.
|
||||
* Usually buffers need to be swapped in handler of this message.
|
||||
*
|
||||
* data: NULL.
|
||||
*)
|
||||
AV_DEV_TO_APP_DISPLAY_WINDOW_BUFFER: AVDevToAppMessageType = ('B', 'D', 'I', 'S');
|
||||
|
||||
(* *
|
||||
* Destroy window buffer message.
|
||||
*
|
||||
* Device requests to destroy a window buffer.
|
||||
* Message is sent when device is about to be destroyed and window
|
||||
* buffer is not required anymore.
|
||||
*
|
||||
* data: NULL.
|
||||
*)
|
||||
AV_DEV_TO_APP_DESTROY_WINDOW_BUFFER: AVDevToAppMessageType = ('B', 'D', 'E', 'S');
|
||||
|
||||
(* *
|
||||
* Buffer fullness status messages.
|
||||
*
|
||||
* Device signals buffer overflow/underflow.
|
||||
*
|
||||
* data: NULL.
|
||||
*)
|
||||
AV_DEV_TO_APP_BUFFER_OVERFLOW: AVDevToAppMessageType = ('B', 'O', 'F', 'L');
|
||||
AV_DEV_TO_APP_BUFFER_UNDERFLOW: AVDevToAppMessageType = ('B', 'U', 'F', 'L');
|
||||
|
||||
(* *
|
||||
* Buffer readable/writable.
|
||||
*
|
||||
* Device informs that buffer is readable/writable.
|
||||
* When possible, device informs how many bytes can be read/write.
|
||||
*
|
||||
* @warning Device may not inform when number of bytes than can be read/write changes.
|
||||
*
|
||||
* data: int64_t: amount of bytes available to read/write.
|
||||
* NULL: amount of bytes available to read/write is not known.
|
||||
*)
|
||||
AV_DEV_TO_APP_BUFFER_READABLE: AVDevToAppMessageType = ('B', 'R', 'D', ' ');
|
||||
AV_DEV_TO_APP_BUFFER_WRITABLE: AVDevToAppMessageType = ('B', 'W', 'R', ' ');
|
||||
|
||||
(* *
|
||||
* Mute state change message.
|
||||
*
|
||||
* Device informs that mute state has changed.
|
||||
*
|
||||
* data: int: 0 for not muted state, non-zero for muted state.
|
||||
*)
|
||||
AV_DEV_TO_APP_MUTE_STATE_CHANGED: AVDevToAppMessageType = ('C', 'M', 'U', 'T');
|
||||
|
||||
(* *
|
||||
* Volume level change message.
|
||||
*
|
||||
* Device informs that volume level has changed.
|
||||
*
|
||||
* data: double: new volume with range of 0.0 - 1.0.
|
||||
*)
|
||||
AV_DEV_TO_APP_VOLUME_LEVEL_CHANGED: AVDevToAppMessageType = ('C', 'V', 'O', 'L');
|
||||
|
||||
(* *
|
||||
* Send control message from application to device.
|
||||
*
|
||||
* @param s device context.
|
||||
* @param type message type.
|
||||
* @param data message data. Exact type depends on message type.
|
||||
* @param data_size size of message data.
|
||||
* @return >= 0 on success, negative on error.
|
||||
* AVERROR(ENOSYS) when device doesn't implement handler of the message.
|
||||
*)
|
||||
// int avdevice_app_to_dev_control_message(struct AVFormatContext *s,
|
||||
// enum AVAppToDevMessageType type,
|
||||
// void *data, size_t data_size);
|
||||
function avdevice_app_to_dev_control_message(s: pAVFormatContext; _type: AVAppToDevMessageType; data: Pointer; data_size: size_t): int;
|
||||
cdecl; external avdevice_dll;
|
||||
(* *
|
||||
* Send control message from device to application.
|
||||
*
|
||||
* @param s device context.
|
||||
* @param type message type.
|
||||
* @param data message data. Can be NULL.
|
||||
* @param data_size size of message data.
|
||||
* @return >= 0 on success, negative on error.
|
||||
* AVERROR(ENOSYS) when application doesn't implement handler of the message.
|
||||
*)
|
||||
// int avdevice_dev_to_app_control_message(struct AVFormatContext *s,
|
||||
// enum AVDevToAppMessageType type,
|
||||
// void *data, size_t data_size);
|
||||
function avdevice_dev_to_app_control_message(s: pAVFormatContext; _type: AVDevToAppMessageType; data: Pointer; data_size: size_t): int;
|
||||
cdecl; external avdevice_dll;
|
||||
|
||||
(* *
|
||||
* Following API allows user to probe device capabilities (supported codecs,
|
||||
* pixel formats, sample formats, resolutions, channel counts, etc).
|
||||
* It is build on top op AVOption API.
|
||||
* Queried capabilities make it possible to set up converters of video or audio
|
||||
* parameters that fit to the device.
|
||||
*
|
||||
* List of capabilities that can be queried:
|
||||
* - Capabilities valid for both audio and video devices:
|
||||
* - codec: supported audio/video codecs.
|
||||
* type: AV_OPT_TYPE_INT (AVCodecID value)
|
||||
* - Capabilities valid for audio devices:
|
||||
* - sample_format: supported sample formats.
|
||||
* type: AV_OPT_TYPE_INT (AVSampleFormat value)
|
||||
* - sample_rate: supported sample rates.
|
||||
* type: AV_OPT_TYPE_INT
|
||||
* - channels: supported number of channels.
|
||||
* type: AV_OPT_TYPE_INT
|
||||
* - channel_layout: supported channel layouts.
|
||||
* type: AV_OPT_TYPE_INT64
|
||||
* - Capabilities valid for video devices:
|
||||
* - pixel_format: supported pixel formats.
|
||||
* type: AV_OPT_TYPE_INT (AVPixelFormat value)
|
||||
* - window_size: supported window sizes (describes size of the window size presented to the user).
|
||||
* type: AV_OPT_TYPE_IMAGE_SIZE
|
||||
* - frame_size: supported frame sizes (describes size of provided video frames).
|
||||
* type: AV_OPT_TYPE_IMAGE_SIZE
|
||||
* - fps: supported fps values
|
||||
* type: AV_OPT_TYPE_RATIONAL
|
||||
*
|
||||
* Value of the capability may be set by user using av_opt_set() function
|
||||
* and AVDeviceCapabilitiesQuery object. Following queries will
|
||||
* limit results to the values matching already set capabilities.
|
||||
* For example, setting a codec may impact number of formats or fps values
|
||||
* returned during next query. Setting invalid value may limit results to zero.
|
||||
*
|
||||
* Example of the usage basing on opengl output device:
|
||||
*
|
||||
* @code
|
||||
* AVFormatContext *oc = NULL;
|
||||
* AVDeviceCapabilitiesQuery *caps = NULL;
|
||||
* AVOptionRanges *ranges;
|
||||
* int ret;
|
||||
*
|
||||
* if ((ret = avformat_alloc_output_context2(&oc, NULL, "opengl", NULL)) < 0)
|
||||
* goto fail;
|
||||
* if (avdevice_capabilities_create(&caps, oc, NULL) < 0)
|
||||
* goto fail;
|
||||
*
|
||||
* //query codecs
|
||||
* if (av_opt_query_ranges(&ranges, caps, "codec", AV_OPT_MULTI_COMPONENT_RANGE)) < 0)
|
||||
* goto fail;
|
||||
* //pick codec here and set it
|
||||
* av_opt_set(caps, "codec", AV_CODEC_ID_RAWVIDEO, 0);
|
||||
*
|
||||
* //query format
|
||||
* if (av_opt_query_ranges(&ranges, caps, "pixel_format", AV_OPT_MULTI_COMPONENT_RANGE)) < 0)
|
||||
* goto fail;
|
||||
* //pick format here and set it
|
||||
* av_opt_set(caps, "pixel_format", AV_PIX_FMT_YUV420P, 0);
|
||||
*
|
||||
* //query and set more capabilities
|
||||
*
|
||||
* fail:
|
||||
* //clean up code
|
||||
* avdevice_capabilities_free(&query, oc);
|
||||
* avformat_free_context(oc);
|
||||
* @endcode
|
||||
*)
|
||||
type
|
||||
(* *
|
||||
* Structure describes device capabilities.
|
||||
*
|
||||
* It is used by devices in conjunction with av_device_capabilities AVOption table
|
||||
* to implement capabilities probing API based on AVOption API. Should not be used directly.
|
||||
*)
|
||||
pAVDeviceCapabilitiesQuery = ^AVDeviceCapabilitiesQuery;
|
||||
|
||||
AVDeviceCapabilitiesQuery = record
|
||||
av_class: pAVClass;
|
||||
device_context: pAVFormatContext;
|
||||
codec: AVCodecID;
|
||||
sample_format: AVSampleFormat;
|
||||
pixel_format: AVPixelFormat;
|
||||
sample_rate: int;
|
||||
channels: int;
|
||||
channel_layout: int64_t;
|
||||
window_width: int;
|
||||
window_height: int;
|
||||
frame_width: int;
|
||||
frame_height: int;
|
||||
fps: AVRational;
|
||||
end;
|
||||
|
||||
(* *
|
||||
* AVOption table used by devices to implement device capabilities API. Should not be used by a user.
|
||||
*)
|
||||
// extern const AVOption av_device_capabilities[];
|
||||
|
||||
(* *
|
||||
* Initialize capabilities probing API based on AVOption API.
|
||||
*
|
||||
* avdevice_capabilities_free() must be called when query capabilities API is
|
||||
* not used anymore.
|
||||
*
|
||||
* @param[out] caps Device capabilities data. Pointer to a NULL pointer must be passed.
|
||||
* @param s Context of the device.
|
||||
* @param device_options An AVDictionary filled with device-private options.
|
||||
* On return this parameter will be destroyed and replaced with a dict
|
||||
* containing options that were not found. May be NULL.
|
||||
* The same options must be passed later to avformat_write_header() for output
|
||||
* devices or avformat_open_input() for input devices, or at any other place
|
||||
* that affects device-private options.
|
||||
*
|
||||
* @return >= 0 on success, negative otherwise.
|
||||
*)
|
||||
// int avdevice_capabilities_create(AVDeviceCapabilitiesQuery **caps, AVFormatContext *s,
|
||||
// AVDictionary **device_options);
|
||||
function avdevice_capabilities_create(var caps: pAVDeviceCapabilitiesQuery; s: pAVFormatContext; var device_options: pAVDictionary): int;
|
||||
cdecl; external avdevice_dll;
|
||||
(* *
|
||||
* Free resources created by avdevice_capabilities_create()
|
||||
*
|
||||
* @param caps Device capabilities data to be freed.
|
||||
* @param s Context of the device.
|
||||
*)
|
||||
// void avdevice_capabilities_free(AVDeviceCapabilitiesQuery **caps, AVFormatContext *s);
|
||||
procedure avdevice_capabilities_free(var caps: pAVDeviceCapabilitiesQuery; s: pAVFormatContext); cdecl; external avdevice_dll;
|
||||
|
||||
type
|
||||
(* *
|
||||
* Structure describes basic parameters of the device.
|
||||
*)
|
||||
pAVDeviceInfo = ^AVDeviceInfo;
|
||||
ppAVDeviceInfo = ^pAVDeviceInfo;
|
||||
|
||||
AVDeviceInfo = record
|
||||
device_name: pAnsiChar; (* *< device name, format depends on device *)
|
||||
device_description: pAnsiChar; (* *< human friendly name *)
|
||||
end;
|
||||
|
||||
(* *
|
||||
* List of devices.
|
||||
*)
|
||||
pAVDeviceInfoList = ^AVDeviceInfoList;
|
||||
|
||||
AVDeviceInfoList = record
|
||||
devices: ppAVDeviceInfo; (* *< list of autodetected devices *)
|
||||
nb_devices: int; (* *< number of autodetected devices *)
|
||||
default_device: int; (* *< index of default device or -1 if no default *)
|
||||
end;
|
||||
|
||||
(* *
|
||||
* List devices.
|
||||
*
|
||||
* Returns available device names and their parameters.
|
||||
*
|
||||
* @note: Some devices may accept system-dependent device names that cannot be
|
||||
* autodetected. The list returned by this function cannot be assumed to
|
||||
* be always completed.
|
||||
*
|
||||
* @param s device context.
|
||||
* @param[out] device_list list of autodetected devices.
|
||||
* @return count of autodetected devices, negative on error.
|
||||
*)
|
||||
// int avdevice_list_devices(struct AVFormatContext *s, AVDeviceInfoList **device_list);
|
||||
function avdevice_list_devices(s: pAVFormatContext; var device_list: pAVDeviceInfoList): int; cdecl; external avdevice_dll;
|
||||
(* *
|
||||
* Convenient function to free result of avdevice_list_devices().
|
||||
*
|
||||
* @param devices device list to be freed.
|
||||
*)
|
||||
// void avdevice_free_list_devices(AVDeviceInfoList **device_list);
|
||||
procedure avdevice_free_list_devices(var device_list: pAVDeviceInfoList); cdecl; external avdevice_dll;
|
||||
(* *
|
||||
* List devices.
|
||||
*
|
||||
* Returns available device names and their parameters.
|
||||
* These are convinient wrappers for avdevice_list_devices().
|
||||
* Device context is allocated and deallocated internally.
|
||||
*
|
||||
* @param device device format. May be NULL if device name is set.
|
||||
* @param device_name device name. May be NULL if device format is set.
|
||||
* @param device_options An AVDictionary filled with device-private options. May be NULL.
|
||||
* The same options must be passed later to avformat_write_header() for output
|
||||
* devices or avformat_open_input() for input devices, or at any other place
|
||||
* that affects device-private options.
|
||||
* @param[out] device_list list of autodetected devices
|
||||
* @return count of autodetected devices, negative on error.
|
||||
* @note device argument takes precedence over device_name when both are set.
|
||||
*)
|
||||
// int avdevice_list_input_sources(struct AVInputFormat *device, const char *device_name,
|
||||
// AVDictionary *device_options, AVDeviceInfoList **device_list);
|
||||
function avdevice_list_input_sources(device: pAVInputFormat; const device_name: pAnsiChar; device_options: pAVDictionary;
|
||||
var device_list: pAVDeviceInfoList): int; cdecl; external avdevice_dll;
|
||||
|
||||
// int avdevice_list_output_sinks(struct AVOutputFormat *device, const char *device_name,
|
||||
// AVDictionary *device_options, AVDeviceInfoList **device_list);
|
||||
function avdevice_list_output_sinks(device: pAVOutputFormat; const device_name: pAnsiChar; device_options: pAVDictionary;
|
||||
var device_list: pAVDeviceInfoList): int; cdecl; external avdevice_dll;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
|
@ -0,0 +1,108 @@
|
|||
unit libpostproc;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
Uses
|
||||
ffmpeg_types;
|
||||
|
||||
{$I ffmpeg.inc}
|
||||
|
||||
(* *
|
||||
* Return the LIBPOSTPROC_VERSION_INT constant.
|
||||
*)
|
||||
// unsigned postproc_version(void);
|
||||
function postproc_version(): unsigned; cdecl; external postproc_dll;
|
||||
|
||||
(* *
|
||||
* Return the libpostproc build-time configuration.
|
||||
*)
|
||||
// const char *postproc_configuration(void);
|
||||
function postproc_configuration(): pAnsiChar; cdecl; external postproc_dll;
|
||||
(* *
|
||||
* Return the libpostproc license.
|
||||
*)
|
||||
// const char *postproc_license(void);
|
||||
function postproc_license(): pAnsiChar; cdecl; external postproc_dll;
|
||||
|
||||
const
|
||||
PP_QUALITY_MAX = 6;
|
||||
|
||||
// #include <inttypes.h>
|
||||
|
||||
type
|
||||
ppp_context = ^pp_context;
|
||||
|
||||
pp_context = record
|
||||
end;
|
||||
|
||||
ppp_mode = ^pp_mode;
|
||||
|
||||
pp_mode = record
|
||||
end;
|
||||
|
||||
Tpp_src_puint8_t = array [0 .. 2] of puint8_t;
|
||||
Tpp_dst_puint8_t = Tpp_src_puint8_t;
|
||||
Tpp_srcStride_int = array [0 .. 2] of int;
|
||||
Tpp_dstStride_int = Tpp_srcStride_int;
|
||||
|
||||
(*
|
||||
#if LIBPOSTPROC_VERSION_INT < (52<<16)
|
||||
typedef pp_context pp_context_t;
|
||||
typedef pp_mode pp_mode_t;
|
||||
extern const char *const pp_help; ///< a simple help text
|
||||
#else
|
||||
extern const char pp_help[]; ///< a simple help text
|
||||
#endif
|
||||
*)
|
||||
|
||||
// void pp_postprocess(const uint8_t * src[3], const int srcStride[3],
|
||||
// uint8_t * dst[3], const int dstStride[3],
|
||||
// int horizontalSize, int verticalSize,
|
||||
// const int8_t *QP_store, int QP_stride,
|
||||
// pp_mode *mode, pp_context *ppContext, int pict_type);
|
||||
|
||||
procedure pp_postprocess(const src: Tpp_src_puint8_t; const srcStride: Tpp_srcStride_int; dst: Tpp_dst_puint8_t;
|
||||
const dstStride: Tpp_dstStride_int; horizontalSize: int; verticalSize: int; const QP_store: pint8_t; QP_stride: int; mode: ppp_mode;
|
||||
ppContext: ppp_context; pict_type: int); cdecl; external postproc_dll;
|
||||
(* *
|
||||
* Return a pp_mode or NULL if an error occurred.
|
||||
*
|
||||
* @param name the string after "-pp" on the command line
|
||||
* @param quality a number from 0 to PP_QUALITY_MAX
|
||||
*)
|
||||
// pp_mode *pp_get_mode_by_name_and_quality(const char *name, int quality);
|
||||
function pp_get_mode_by_name_and_quality(const name: pAnsiChar; quality: int): ppp_mode; cdecl; external postproc_dll;
|
||||
|
||||
// void pp_free_mode(pp_mode *mode);
|
||||
procedure pp_free_mode(mode: ppp_mode); cdecl; external postproc_dll;
|
||||
|
||||
// pp_context *pp_get_context(int width, int height, int flags);
|
||||
function pp_get_context(width: int; height: int; flags: int): ppp_context; cdecl; external postproc_dll;
|
||||
|
||||
// void pp_free_context(pp_context *ppContext);
|
||||
procedure pp_free_context(ppContext: ppp_context); cdecl; external postproc_dll;
|
||||
|
||||
const
|
||||
PP_CPU_CAPS_MMX = $80000000;
|
||||
PP_CPU_CAPS_MMX2 = $20000000;
|
||||
PP_CPU_CAPS_3DNOW = $40000000;
|
||||
PP_CPU_CAPS_ALTIVEC = $10000000;
|
||||
PP_CPU_CAPS_AUTO = $00080000;
|
||||
|
||||
PP_FORMAT = $00000008;
|
||||
PP_FORMAT_420 = ($00000011 or PP_FORMAT);
|
||||
PP_FORMAT_422 = ($00000001 or PP_FORMAT);
|
||||
PP_FORMAT_411 = ($00000002 or PP_FORMAT);
|
||||
PP_FORMAT_444 = ($00000000 or PP_FORMAT);
|
||||
PP_FORMAT_440 = ($00000010 or PP_FORMAT);
|
||||
|
||||
PP_PICT_TYPE_QP2 = $00000010;
|
||||
/// < MPEG2 style QScale
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
|
@ -0,0 +1,564 @@
|
|||
unit libswresample;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
Uses
|
||||
ffmpeg_types, libavutil;
|
||||
|
||||
{$I ffmpeg.inc}
|
||||
|
||||
(* *
|
||||
* @defgroup lswr libswresample
|
||||
* @{
|
||||
*
|
||||
* Audio resampling, sample format conversion and mixing library.
|
||||
*
|
||||
* Interaction with lswr is done through SwrContext, which is
|
||||
* allocated with swr_alloc() or swr_alloc_set_opts(). It is opaque, so all parameters
|
||||
* must be set with the @ref avoptions API.
|
||||
*
|
||||
* The first thing you will need to do in order to use lswr is to allocate
|
||||
* SwrContext. This can be done with swr_alloc() or swr_alloc_set_opts(). If you
|
||||
* are using the former, you must set options through the @ref avoptions API.
|
||||
* The latter function provides the same feature, but it allows you to set some
|
||||
* common options in the same statement.
|
||||
*
|
||||
* For example the following code will setup conversion from planar float sample
|
||||
* format to interleaved signed 16-bit integer, downsampling from 48kHz to
|
||||
* 44.1kHz and downmixing from 5.1 channels to stereo (using the default mixing
|
||||
* matrix). This is using the swr_alloc() function.
|
||||
* @code
|
||||
* SwrContext *swr = swr_alloc();
|
||||
* av_opt_set_channel_layout(swr, "in_channel_layout", AV_CH_LAYOUT_5POINT1, 0);
|
||||
* av_opt_set_channel_layout(swr, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
|
||||
* av_opt_set_int(swr, "in_sample_rate", 48000, 0);
|
||||
* av_opt_set_int(swr, "out_sample_rate", 44100, 0);
|
||||
* av_opt_set_sample_fmt(swr, "in_sample_fmt", AV_SAMPLE_FMT_FLTP, 0);
|
||||
* av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
|
||||
* @endcode
|
||||
*
|
||||
* The same job can be done using swr_alloc_set_opts() as well:
|
||||
* @code
|
||||
* SwrContext *swr = swr_alloc_set_opts(NULL, // we're allocating a new context
|
||||
* AV_CH_LAYOUT_STEREO, // out_ch_layout
|
||||
* AV_SAMPLE_FMT_S16, // out_sample_fmt
|
||||
* 44100, // out_sample_rate
|
||||
* AV_CH_LAYOUT_5POINT1, // in_ch_layout
|
||||
* AV_SAMPLE_FMT_FLTP, // in_sample_fmt
|
||||
* 48000, // in_sample_rate
|
||||
* 0, // log_offset
|
||||
* NULL); // log_ctx
|
||||
* @endcode
|
||||
*
|
||||
* Once all values have been set, it must be initialized with swr_init(). If
|
||||
* you need to change the conversion parameters, you can change the parameters
|
||||
* using @ref AVOptions, as described above in the first example; or by using
|
||||
* swr_alloc_set_opts(), but with the first argument the allocated context.
|
||||
* You must then call swr_init() again.
|
||||
*
|
||||
* The conversion itself is done by repeatedly calling swr_convert().
|
||||
* Note that the samples may get buffered in swr if you provide insufficient
|
||||
* output space or if sample rate conversion is done, which requires "future"
|
||||
* samples. Samples that do not require future input can be retrieved at any
|
||||
* time by using swr_convert() (in_count can be set to 0).
|
||||
* At the end of conversion the resampling buffer can be flushed by calling
|
||||
* swr_convert() with NULL in and 0 in_count.
|
||||
*
|
||||
* The samples used in the conversion process can be managed with the libavutil
|
||||
* @ref lavu_sampmanip "samples manipulation" API, including av_samples_alloc()
|
||||
* function used in the following example.
|
||||
*
|
||||
* The delay between input and output, can at any time be found by using
|
||||
* swr_get_delay().
|
||||
*
|
||||
* The following code demonstrates the conversion loop assuming the parameters
|
||||
* from above and caller-defined functions get_input() and handle_output():
|
||||
* @code
|
||||
* uint8_t **input;
|
||||
* int in_samples;
|
||||
*
|
||||
* while (get_input(&input, &in_samples)) {
|
||||
* uint8_t *output;
|
||||
* int out_samples = av_rescale_rnd(swr_get_delay(swr, 48000) +
|
||||
* in_samples, 44100, 48000, AV_ROUND_UP);
|
||||
* av_samples_alloc(&output, NULL, 2, out_samples,
|
||||
* AV_SAMPLE_FMT_S16, 0);
|
||||
* out_samples = swr_convert(swr, &output, out_samples,
|
||||
* input, in_samples);
|
||||
* handle_output(output, out_samples);
|
||||
* av_freep(&output);
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* When the conversion is finished, the conversion
|
||||
* context and everything associated with it must be freed with swr_free().
|
||||
* A swr_close() function is also available, but it exists mainly for
|
||||
* compatibility with libavresample, and is not required to be called.
|
||||
*
|
||||
* There will be no memory leak if the data is not completely flushed before
|
||||
* swr_free().
|
||||
*)
|
||||
|
||||
// #include <stdint.h>
|
||||
// #include "libavutil/channel_layout.h"
|
||||
// #include "libavutil/frame.h"
|
||||
// #include "libavutil/samplefmt.h"
|
||||
|
||||
// #include "libswresample/version.h"
|
||||
|
||||
const
|
||||
(* *
|
||||
* @name Option constants
|
||||
* These constants are used for the @ref avoptions interface for lswr.
|
||||
* @{
|
||||
*
|
||||
*)
|
||||
|
||||
SWR_FLAG_RESAMPLE = 1;
|
||||
/// < Force resampling even if equal sample rate
|
||||
// TODO use int resample ?
|
||||
// long term TODO can we enable this dynamically?
|
||||
|
||||
type
|
||||
(* * Dithering algorithms *)
|
||||
SwrDitherType = ( //
|
||||
SWR_DITHER_NONE = 0, SWR_DITHER_RECTANGULAR, SWR_DITHER_TRIANGULAR, SWR_DITHER_TRIANGULAR_HIGHPASS,
|
||||
|
||||
SWR_DITHER_NS = 64,
|
||||
/// < not part of API/ABI
|
||||
SWR_DITHER_NS_LIPSHITZ, SWR_DITHER_NS_F_WEIGHTED, SWR_DITHER_NS_MODIFIED_E_WEIGHTED, SWR_DITHER_NS_IMPROVED_E_WEIGHTED,
|
||||
SWR_DITHER_NS_SHIBATA, SWR_DITHER_NS_LOW_SHIBATA, SWR_DITHER_NS_HIGH_SHIBATA, SWR_DITHER_NB
|
||||
/// < not part of API/ABI
|
||||
);
|
||||
|
||||
(* * Resampling Engines *)
|
||||
SwrEngine = ( //
|
||||
SWR_ENGINE_SWR, (* *< SW Resampler *)
|
||||
SWR_ENGINE_SOXR, (* *< SoX Resampler *)
|
||||
SWR_ENGINE_NB
|
||||
/// < not part of API/ABI
|
||||
);
|
||||
|
||||
(* * Resampling Filter Types *)
|
||||
SwrFilterType = ( //
|
||||
SWR_FILTER_TYPE_CUBIC, (* *< Cubic *)
|
||||
SWR_FILTER_TYPE_BLACKMAN_NUTTALL, (* *< Blackman Nuttall windowed sinc *)
|
||||
SWR_FILTER_TYPE_KAISER (* *< Kaiser windowed sinc *)
|
||||
);
|
||||
|
||||
type
|
||||
(* *
|
||||
* The libswresample context. Unlike libavcodec and libavformat, this structure
|
||||
* is opaque. This means that if you would like to set options, you must use
|
||||
* the @ref avoptions API and cannot directly set values to members of the
|
||||
* structure.
|
||||
*)
|
||||
pSwrContext = ^SwrContext;
|
||||
|
||||
SwrContext = record
|
||||
end;
|
||||
|
||||
(* *
|
||||
* Get the AVClass for SwrContext. It can be used in combination with
|
||||
* AV_OPT_SEARCH_FAKE_OBJ for examining options.
|
||||
*
|
||||
* @see av_opt_find().
|
||||
* @return the AVClass of SwrContext
|
||||
*)
|
||||
// const AVClass *swr_get_class(void);
|
||||
function swr_get_class(): pAVClass; cdecl; external swresample_dll;
|
||||
|
||||
(* *
|
||||
* @name SwrContext constructor functions
|
||||
* @{
|
||||
*)
|
||||
|
||||
(* *
|
||||
* Allocate SwrContext.
|
||||
*
|
||||
* If you use this function you will need to set the parameters (manually or
|
||||
* with swr_alloc_set_opts()) before calling swr_init().
|
||||
*
|
||||
* @see swr_alloc_set_opts(), swr_init(), swr_free()
|
||||
* @return NULL on error, allocated context otherwise
|
||||
*)
|
||||
// struct SwrContext *swr_alloc(void);
|
||||
function swr_alloc(): pSwrContext; cdecl; external swresample_dll;
|
||||
|
||||
(* *
|
||||
* Initialize context after user parameters have been set.
|
||||
* @note The context must be configured using the AVOption API.
|
||||
*
|
||||
* @see av_opt_set_int()
|
||||
* @see av_opt_set_dict()
|
||||
*
|
||||
* @param[in,out] s Swr context to initialize
|
||||
* @return AVERROR error code in case of failure.
|
||||
*)
|
||||
// int swr_init(struct SwrContext *s);
|
||||
function swr_init(s: pSwrContext): int; cdecl; external swresample_dll;
|
||||
|
||||
(* *
|
||||
* Check whether an swr context has been initialized or not.
|
||||
*
|
||||
* @param[in] s Swr context to check
|
||||
* @see swr_init()
|
||||
* @return positive if it has been initialized, 0 if not initialized
|
||||
*)
|
||||
// int swr_is_initialized(struct SwrContext *s);
|
||||
function swr_is_initialized(s: pSwrContext): int; cdecl; external swresample_dll;
|
||||
(* *
|
||||
* Allocate SwrContext if needed and set/reset common parameters.
|
||||
*
|
||||
* This function does not require s to be allocated with swr_alloc(). On the
|
||||
* other hand, swr_alloc() can use swr_alloc_set_opts() to set the parameters
|
||||
* on the allocated context.
|
||||
*
|
||||
* @param s existing Swr context if available, or NULL if not
|
||||
* @param out_ch_layout output channel layout (AV_CH_LAYOUT_* )
|
||||
* @param out_sample_fmt output sample format (AV_SAMPLE_FMT_* ).
|
||||
* @param out_sample_rate output sample rate (frequency in Hz)
|
||||
* @param in_ch_layout input channel layout (AV_CH_LAYOUT_* )
|
||||
* @param in_sample_fmt input sample format (AV_SAMPLE_FMT_* ).
|
||||
* @param in_sample_rate input sample rate (frequency in Hz)
|
||||
* @param log_offset logging level offset
|
||||
* @param log_ctx parent logging context, can be NULL
|
||||
*
|
||||
* @see swr_init(), swr_free()
|
||||
* @return NULL on error, allocated context otherwise
|
||||
*)
|
||||
// struct SwrContext *swr_alloc_set_opts(struct SwrContext *s,
|
||||
// int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate,
|
||||
// int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate,
|
||||
// int log_offset, void *log_ctx);
|
||||
function swr_alloc_set_opts(s: pSwrContext; out_ch_layout: int64_t; out_sample_fmt: AVSampleFormat; out_sample_rate: int;
|
||||
in_ch_layout: int64_t; in_sample_fmt: AVSampleFormat; in_sample_rate: int; log_offset: int; log_ctx: Pointer): pSwrContext; cdecl;
|
||||
external swresample_dll;
|
||||
(* *
|
||||
* @}
|
||||
*
|
||||
* @name SwrContext destructor functions
|
||||
* @{
|
||||
*)
|
||||
|
||||
(* *
|
||||
* Free the given SwrContext and set the pointer to NULL.
|
||||
*
|
||||
* @param[in] s a pointer to a pointer to Swr context
|
||||
*)
|
||||
// void swr_free(struct SwrContext **s);
|
||||
procedure swr_free(var s: pSwrContext); cdecl; external swresample_dll;
|
||||
(* *
|
||||
* Closes the context so that swr_is_initialized() returns 0.
|
||||
*
|
||||
* The context can be brought back to life by running swr_init(),
|
||||
* swr_init() can also be used without swr_close().
|
||||
* This function is mainly provided for simplifying the usecase
|
||||
* where one tries to support libavresample and libswresample.
|
||||
*
|
||||
* @param[in,out] s Swr context to be closed
|
||||
*)
|
||||
// void swr_close(struct SwrContext *s);
|
||||
procedure swr_close(s: pSwrContext); cdecl; external swresample_dll;
|
||||
(* *
|
||||
* @}
|
||||
*
|
||||
* @name Core conversion functions
|
||||
* @{
|
||||
*)
|
||||
|
||||
(* * Convert audio.
|
||||
*
|
||||
* in and in_count can be set to 0 to flush the last few samples out at the
|
||||
* end.
|
||||
*
|
||||
* If more input is provided than output space, then the input will be buffered.
|
||||
* You can avoid this buffering by using swr_get_out_samples() to retrieve an
|
||||
* upper bound on the required number of output samples for the given number of
|
||||
* input samples. Conversion will run directly without copying whenever possible.
|
||||
*
|
||||
* @param s allocated Swr context, with parameters set
|
||||
* @param out output buffers, only the first one need be set in case of packed audio
|
||||
* @param out_count amount of space available for output in samples per channel
|
||||
* @param in input buffers, only the first one need to be set in case of packed audio
|
||||
* @param in_count number of input samples available in one channel
|
||||
*
|
||||
* @return number of samples output per channel, negative value on error
|
||||
*)
|
||||
// int swr_convert(struct SwrContext *s, uint8_t **out, int out_count,
|
||||
// const uint8_t **in , int in_count);
|
||||
function swr_convert(s: pSwrContext; _out: ppuint8_t; out_count: int; const _in: ppuint8_t; in_count: int): int; cdecl; external swresample_dll;
|
||||
(* *
|
||||
* Convert the next timestamp from input to output
|
||||
* timestamps are in 1/(in_sample_rate * out_sample_rate) units.
|
||||
*
|
||||
* @note There are 2 slightly differently behaving modes.
|
||||
* @li When automatic timestamp compensation is not used, (min_compensation >= FLT_MAX)
|
||||
* in this case timestamps will be passed through with delays compensated
|
||||
* @li When automatic timestamp compensation is used, (min_compensation < FLT_MAX)
|
||||
* in this case the output timestamps will match output sample numbers.
|
||||
* See ffmpeg-resampler(1) for the two modes of compensation.
|
||||
*
|
||||
* @param s[in] initialized Swr context
|
||||
* @param pts[in] timestamp for the next input sample, INT64_MIN if unknown
|
||||
* @see swr_set_compensation(), swr_drop_output(), and swr_inject_silence() are
|
||||
* function used internally for timestamp compensation.
|
||||
* @return the output timestamp for the next output sample
|
||||
*)
|
||||
// int64_t swr_next_pts(struct SwrContext *s, int64_t pts);
|
||||
function swr_next_pts(s: pSwrContext; pts: int64_t): int64_t; cdecl; external swresample_dll;
|
||||
(* *
|
||||
* @}
|
||||
*
|
||||
* @name Low-level option setting functions
|
||||
* These functons provide a means to set low-level options that is not possible
|
||||
* with the AVOption API.
|
||||
* @{
|
||||
*)
|
||||
|
||||
(* *
|
||||
* Activate resampling compensation ("soft" compensation). This function is
|
||||
* internally called when needed in swr_next_pts().
|
||||
*
|
||||
* @param[in,out] s allocated Swr context. If it is not initialized,
|
||||
* or SWR_FLAG_RESAMPLE is not set, swr_init() is
|
||||
* called with the flag set.
|
||||
* @param[in] sample_delta delta in PTS per sample
|
||||
* @param[in] compensation_distance number of samples to compensate for
|
||||
* @return >= 0 on success, AVERROR error codes if:
|
||||
* @li @c s is NULL,
|
||||
* @li @c compensation_distance is less than 0,
|
||||
* @li @c compensation_distance is 0 but sample_delta is not,
|
||||
* @li compensation unsupported by resampler, or
|
||||
* @li swr_init() fails when called.
|
||||
*)
|
||||
// int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance);
|
||||
function swr_set_compensation(s: pSwrContext; sample_delta: int; compensation_distance: int): int; cdecl; external swresample_dll;
|
||||
(* *
|
||||
* Set a customized input channel mapping.
|
||||
*
|
||||
* @param[in,out] s allocated Swr context, not yet initialized
|
||||
* @param[in] channel_map customized input channel mapping (array of channel
|
||||
* indexes, -1 for a muted channel)
|
||||
* @return >= 0 on success, or AVERROR error code in case of failure.
|
||||
*)
|
||||
// int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map);
|
||||
function swr_set_channel_mapping(s: pSwrContext; const channel_map: pint): int; cdecl; external swresample_dll;
|
||||
(* *
|
||||
* Generate a channel mixing matrix.
|
||||
*
|
||||
* This function is the one used internally by libswresample for building the
|
||||
* default mixing matrix. It is made public just as a utility function for
|
||||
* building custom matrices.
|
||||
*
|
||||
* @param in_layout input channel layout
|
||||
* @param out_layout output channel layout
|
||||
* @param center_mix_level mix level for the center channel
|
||||
* @param surround_mix_level mix level for the surround channel(s)
|
||||
* @param lfe_mix_level mix level for the low-frequency effects channel
|
||||
* @param rematrix_maxval if 1.0, coefficients will be normalized to prevent
|
||||
* overflow. if INT_MAX, coefficients will not be
|
||||
* normalized.
|
||||
* @param[out] matrix mixing coefficients; matrix[i + stride * o] is
|
||||
* the weight of input channel i in output channel o.
|
||||
* @param stride distance between adjacent input channels in the
|
||||
* matrix array
|
||||
* @param matrix_encoding matrixed stereo downmix mode (e.g. dplii)
|
||||
* @param log_ctx parent logging context, can be NULL
|
||||
* @return 0 on success, negative AVERROR code on failure
|
||||
*)
|
||||
// int swr_build_matrix(uint64_t in_layout, uint64_t out_layout,
|
||||
// double center_mix_level, double surround_mix_level,
|
||||
// double lfe_mix_level, double rematrix_maxval,
|
||||
// double rematrix_volume, double *matrix,
|
||||
// int stride, enum AVMatrixEncoding matrix_encoding,
|
||||
// void *log_ctx);
|
||||
function swr_build_matrix(in_layout: uint64_t; out_layout: uint64_t; center_mix_level: double; surround_mix_level: double;
|
||||
lfe_mix_level: double; rematrix_maxval: double; rematrix_volume: double; var matrix: double; stride: int;
|
||||
matrix_encoding: AVMatrixEncoding; log_ctx: Pointer): int; cdecl; external swresample_dll;
|
||||
(* *
|
||||
* Set a customized remix matrix.
|
||||
*
|
||||
* @param s allocated Swr context, not yet initialized
|
||||
* @param matrix remix coefficients; matrix[i + stride * o] is
|
||||
* the weight of input channel i in output channel o
|
||||
* @param stride offset between lines of the matrix
|
||||
* @return >= 0 on success, or AVERROR error code in case of failure.
|
||||
*)
|
||||
// int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride);
|
||||
function swr_set_matrix(s: pSwrContext; const matrix: pdouble; stride: int): int; cdecl; external swresample_dll;
|
||||
(* *
|
||||
* @}
|
||||
*
|
||||
* @name Sample handling functions
|
||||
* @{
|
||||
*)
|
||||
|
||||
(* *
|
||||
* Drops the specified number of output samples.
|
||||
*
|
||||
* This function, along with swr_inject_silence(), is called by swr_next_pts()
|
||||
* if needed for "hard" compensation.
|
||||
*
|
||||
* @param s allocated Swr context
|
||||
* @param count number of samples to be dropped
|
||||
*
|
||||
* @return >= 0 on success, or a negative AVERROR code on failure
|
||||
*)
|
||||
// int swr_drop_output(struct SwrContext *s, int count);
|
||||
function swr_drop_output(s: pSwrContext; count: int): int; cdecl; external swresample_dll;
|
||||
(* *
|
||||
* Injects the specified number of silence samples.
|
||||
*
|
||||
* This function, along with swr_drop_output(), is called by swr_next_pts()
|
||||
* if needed for "hard" compensation.
|
||||
*
|
||||
* @param s allocated Swr context
|
||||
* @param count number of samples to be dropped
|
||||
*
|
||||
* @return >= 0 on success, or a negative AVERROR code on failure
|
||||
*)
|
||||
// int swr_inject_silence(struct SwrContext *s, int count);
|
||||
function swr_inject_silence(s: pSwrContext; count: int): int; cdecl; external swresample_dll;
|
||||
(* *
|
||||
* Gets the delay the next input sample will experience relative to the next output sample.
|
||||
*
|
||||
* Swresample can buffer data if more input has been provided than available
|
||||
* output space, also converting between sample rates needs a delay.
|
||||
* This function returns the sum of all such delays.
|
||||
* The exact delay is not necessarily an integer value in either input or
|
||||
* output sample rate. Especially when downsampling by a large value, the
|
||||
* output sample rate may be a poor choice to represent the delay, similarly
|
||||
* for upsampling and the input sample rate.
|
||||
*
|
||||
* @param s swr context
|
||||
* @param base timebase in which the returned delay will be:
|
||||
* @li if it's set to 1 the returned delay is in seconds
|
||||
* @li if it's set to 1000 the returned delay is in milliseconds
|
||||
* @li if it's set to the input sample rate then the returned
|
||||
* delay is in input samples
|
||||
* @li if it's set to the output sample rate then the returned
|
||||
* delay is in output samples
|
||||
* @li if it's the least common multiple of in_sample_rate and
|
||||
* out_sample_rate then an exact rounding-free delay will be
|
||||
* returned
|
||||
* @returns the delay in 1 / @c base units.
|
||||
*)
|
||||
// int64_t swr_get_delay(struct SwrContext *s, int64_t base);
|
||||
function swr_get_delay(s: pSwrContext; base: int64_t): int64_t; cdecl; external swresample_dll;
|
||||
(* *
|
||||
* Find an upper bound on the number of samples that the next swr_convert
|
||||
* call will output, if called with in_samples of input samples. This
|
||||
* depends on the internal state, and anything changing the internal state
|
||||
* (like further swr_convert() calls) will may change the number of samples
|
||||
* swr_get_out_samples() returns for the same number of input samples.
|
||||
*
|
||||
* @param in_samples number of input samples.
|
||||
* @note any call to swr_inject_silence(), swr_convert(), swr_next_pts()
|
||||
* or swr_set_compensation() invalidates this limit
|
||||
* @note it is recommended to pass the correct available buffer size
|
||||
* to all functions like swr_convert() even if swr_get_out_samples()
|
||||
* indicates that less would be used.
|
||||
* @returns an upper bound on the number of samples that the next swr_convert
|
||||
* will output or a negative value to indicate an error
|
||||
*)
|
||||
// int swr_get_out_samples(struct SwrContext *s, int in_samples);
|
||||
function swr_get_out_samples(s: pSwrContext; in_samples: int): int; cdecl; external swresample_dll;
|
||||
(* *
|
||||
* @}
|
||||
*
|
||||
* @name Configuration accessors
|
||||
* @{
|
||||
*)
|
||||
|
||||
(* *
|
||||
* Return the @ref LIBSWRESAMPLE_VERSION_INT constant.
|
||||
*
|
||||
* This is useful to check if the build-time libswresample has the same version
|
||||
* as the run-time one.
|
||||
*
|
||||
* @returns the unsigned int-typed version
|
||||
*)
|
||||
// unsigned swresample_version(void);
|
||||
function swresample_version(): unsigned; cdecl; external swresample_dll;
|
||||
(* *
|
||||
* Return the swr build-time configuration.
|
||||
*
|
||||
* @returns the build-time @c ./configure flags
|
||||
*)
|
||||
// const char *swresample_configuration(void);
|
||||
function swresample_configuration(): pAnsiChar; cdecl; external swresample_dll;
|
||||
(* *
|
||||
* Return the swr license.
|
||||
*
|
||||
* @returns the license of libswresample, determined at build-time
|
||||
*)
|
||||
// const char *swresample_license(void);
|
||||
function swresample_license(): pAnsiChar; cdecl; external swresample_dll;
|
||||
(* *
|
||||
* @}
|
||||
*
|
||||
* @name AVFrame based API
|
||||
* @{
|
||||
*)
|
||||
|
||||
(* *
|
||||
* Convert the samples in the input AVFrame and write them to the output AVFrame.
|
||||
*
|
||||
* Input and output AVFrames must have channel_layout, sample_rate and format set.
|
||||
*
|
||||
* If the output AVFrame does not have the data pointers allocated the nb_samples
|
||||
* field will be set using av_frame_get_buffer()
|
||||
* is called to allocate the frame.
|
||||
*
|
||||
* The output AVFrame can be NULL or have fewer allocated samples than required.
|
||||
* In this case, any remaining samples not written to the output will be added
|
||||
* to an internal FIFO buffer, to be returned at the next call to this function
|
||||
* or to swr_convert().
|
||||
*
|
||||
* If converting sample rate, there may be data remaining in the internal
|
||||
* resampling delay buffer. swr_get_delay() tells the number of
|
||||
* remaining samples. To get this data as output, call this function or
|
||||
* swr_convert() with NULL input.
|
||||
*
|
||||
* If the SwrContext configuration does not match the output and
|
||||
* input AVFrame settings the conversion does not take place and depending on
|
||||
* which AVFrame is not matching AVERROR_OUTPUT_CHANGED, AVERROR_INPUT_CHANGED
|
||||
* or the result of a bitwise-OR of them is returned.
|
||||
*
|
||||
* @see swr_delay()
|
||||
* @see swr_convert()
|
||||
* @see swr_get_delay()
|
||||
*
|
||||
* @param swr audio resample context
|
||||
* @param output output AVFrame
|
||||
* @param input input AVFrame
|
||||
* @return 0 on success, AVERROR on failure or nonmatching
|
||||
* configuration.
|
||||
*)
|
||||
// int swr_convert_frame(SwrContext *swr, AVFrame *output, const AVFrame *input);
|
||||
function swr_convert_frame(swr: pSwrContext; output: pAVFrame; const input: pAVFrame): int; cdecl; external swresample_dll;
|
||||
(* *
|
||||
* Configure or reconfigure the SwrContext using the information
|
||||
* provided by the AVFrames.
|
||||
*
|
||||
* The original resampling context is reset even on failure.
|
||||
* The function calls swr_close() internally if the context is open.
|
||||
*
|
||||
* @see swr_close();
|
||||
*
|
||||
* @param swr audio resample context
|
||||
* @param output output AVFrame
|
||||
* @param input input AVFrame
|
||||
* @return 0 on success, AVERROR on failure.
|
||||
*)
|
||||
// int swr_config_frame(SwrContext *swr, const AVFrame *out, const AVFrame *in);
|
||||
function swr_config_frame(swr: pSwrContext; const _out: pAVFrame; const _in: pAVFrame): int; cdecl; external swresample_dll;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
|
@ -0,0 +1,372 @@
|
|||
unit libswscale;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$MODE Delphi}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
Uses
|
||||
ffmpeg_types, libavutil;
|
||||
|
||||
{$I ffmpeg.inc}
|
||||
(*
|
||||
* @defgroup libsws libswscale
|
||||
* Color conversion and scaling library.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* Return the LIBSWSCALE_VERSION_INT constant.
|
||||
*)
|
||||
// unsigned swscale_version(void);
|
||||
function swscale_version(): unsigned; cdecl; external swscale_dll;
|
||||
|
||||
(*
|
||||
* Return the libswscale build-time configuration.
|
||||
*)
|
||||
// const char *swscale_configuration(void);
|
||||
function swscale_configuration(): pAnsiChar; cdecl; external swscale_dll;
|
||||
|
||||
(*
|
||||
* Return the libswscale license.
|
||||
*)
|
||||
// const char *swscale_license(void);
|
||||
function swscale_license(): pAnsiChar; cdecl; external swscale_dll;
|
||||
|
||||
const
|
||||
(* values for the flags, the stuff on the command line is different *)
|
||||
SWS_FAST_BILINEAR = 1;
|
||||
SWS_BILINEAR = 2;
|
||||
SWS_BICUBIC = 4;
|
||||
SWS_X = 8;
|
||||
SWS_POINT = $10;
|
||||
SWS_AREA = $20;
|
||||
SWS_BICUBLIN = $40;
|
||||
SWS_GAUSS = $80;
|
||||
SWS_SINC = $100;
|
||||
SWS_LANCZOS = $200;
|
||||
SWS_SPLINE = $400;
|
||||
|
||||
SWS_SRC_V_CHR_DROP_MASK = $30000;
|
||||
SWS_SRC_V_CHR_DROP_SHIFT = 16;
|
||||
|
||||
SWS_PARAM_DEFAULT = 123456;
|
||||
|
||||
SWS_PRINT_INFO = $1000;
|
||||
|
||||
// the following 3 flags are not completely implemented
|
||||
// internal chrominance subsampling info
|
||||
SWS_FULL_CHR_H_INT = $2000;
|
||||
// input subsampling info
|
||||
SWS_FULL_CHR_H_INP = $4000;
|
||||
SWS_DIRECT_BGR = $8000;
|
||||
SWS_ACCURATE_RND = $40000;
|
||||
SWS_BITEXACT = $80000;
|
||||
SWS_ERROR_DIFFUSION = $800000;
|
||||
|
||||
SWS_MAX_REDUCE_CUTOFF = 0.002;
|
||||
|
||||
SWS_CS_ITU709 = 1;
|
||||
SWS_CS_FCC = 4;
|
||||
SWS_CS_ITU601 = 5;
|
||||
SWS_CS_ITU624 = 5;
|
||||
SWS_CS_SMPTE170M = 5;
|
||||
SWS_CS_SMPTE240M = 7;
|
||||
SWS_CS_DEFAULT = 5;
|
||||
SWS_CS_BT2020 = 9;
|
||||
|
||||
(*
|
||||
* Return a pointer to yuv<->rgb coefficients for the given colorspace
|
||||
* suitable for sws_setColorspaceDetails().
|
||||
*
|
||||
* @param colorspace One of the SWS_CS_* macros. If invalid,
|
||||
* SWS_CS_DEFAULT is used.
|
||||
*)
|
||||
// const int *sws_getCoefficients(int colorspace);
|
||||
function sws_getCoefficients(colorspace: int): pInt; cdecl; external swscale_dll;
|
||||
|
||||
// when used for filters they must have an odd number of elements
|
||||
// coeffs cannot be shared between vectors
|
||||
|
||||
type
|
||||
SwsVector = record
|
||||
coeff: pdouble;
|
||||
/// < pointer to the list of coefficients
|
||||
length: int;
|
||||
/// < number of coefficients in the vector
|
||||
end;
|
||||
|
||||
pSwsVector = ^SwsVector;
|
||||
|
||||
// vectors can be shared
|
||||
SwsFilter = record
|
||||
lumH: pSwsVector;
|
||||
lumV: pSwsVector;
|
||||
chrH: pSwsVector;
|
||||
chrV: pSwsVector;
|
||||
End;
|
||||
|
||||
pSwsFilter = ^SwsFilter;
|
||||
|
||||
SwsContext = record
|
||||
end;
|
||||
|
||||
pSwsContext = ^SwsContext;
|
||||
|
||||
Tsws_array_uint8_t = array_uint8_t;
|
||||
psws_array_uint8_t = ^Tsws_array_uint8_t;
|
||||
|
||||
Tsws_array_int = array_int;
|
||||
psws_array_int = ^Tsws_array_int;
|
||||
|
||||
Tsws_array4_int = array4_int;
|
||||
psws_array4_int = ^Tsws_array4_int;
|
||||
|
||||
(*
|
||||
* Return a positive value if pix_fmt is a supported input format, 0
|
||||
* otherwise.
|
||||
*)
|
||||
// int sws_isSupportedInput(enum AVPixelFormat pix_fmt);
|
||||
function sws_isSupportedInput(pix_fmt: AVPixelFormat): int; cdecl; external swscale_dll;
|
||||
|
||||
(*
|
||||
* Return a positive value if pix_fmt is a supported output format, 0
|
||||
* otherwise.
|
||||
*)
|
||||
// int sws_isSupportedOutput(enum AVPixelFormat pix_fmt);
|
||||
function sws_isSupportedOutput(pix_fmt: AVPixelFormat): int; cdecl; external swscale_dll;
|
||||
|
||||
(*
|
||||
* @param[in] pix_fmt the pixel format
|
||||
* @return a positive value if an endianness conversion for pix_fmt is
|
||||
* supported, 0 otherwise.
|
||||
*)
|
||||
// int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt);
|
||||
function sws_isSupportedEndiannessConversion(pix_fmt: AVPixelFormat): int; cdecl; external swscale_dll;
|
||||
|
||||
(*
|
||||
* Allocate an empty SwsContext. This must be filled and passed to
|
||||
* sws_init_context(). For filling see AVOptions, options.c and
|
||||
* sws_setColorspaceDetails().
|
||||
*)
|
||||
// struct SwsContext *sws_alloc_context(void);
|
||||
function sws_alloc_context(): pSwsContext; cdecl; external swscale_dll;
|
||||
|
||||
(*
|
||||
* Initialize the swscaler context sws_context.
|
||||
*
|
||||
* @return zero or positive value on success, a negative value on
|
||||
* error
|
||||
*)
|
||||
// av_warn_unused_result
|
||||
// int sws_init_context(struct SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter);
|
||||
function sws_init_context(sws_context: pSwsContext; srcFilter: pSwsFilter; dstFilter: pSwsFilter): int; cdecl; external swscale_dll;
|
||||
|
||||
(*
|
||||
* Free the swscaler context swsContext.
|
||||
* If swsContext is NULL, then does nothing.
|
||||
*)
|
||||
// void sws_freeContext(struct SwsContext *swsContext);
|
||||
procedure sws_freeContext(SwsContext: pSwsContext); cdecl; external swscale_dll;
|
||||
|
||||
(*
|
||||
* Allocate and return an SwsContext. You need it to perform
|
||||
* scaling/conversion operations using sws_scale().
|
||||
*
|
||||
* @param srcW the width of the source image
|
||||
* @param srcH the height of the source image
|
||||
* @param srcFormat the source image format
|
||||
* @param dstW the width of the destination image
|
||||
* @param dstH the height of the destination image
|
||||
* @param dstFormat the destination image format
|
||||
* @param flags specify which algorithm and options to use for rescaling
|
||||
* @param param extra parameters to tune the used scaler
|
||||
* For SWS_BICUBIC param[0] and [1] tune the shape of the basis
|
||||
* function, param[0] tunes f(1) and param[1] f´(1)
|
||||
* For SWS_GAUSS param[0] tunes the exponent and thus cutoff
|
||||
* frequency
|
||||
* For SWS_LANCZOS param[0] tunes the width of the window function
|
||||
* @return a pointer to an allocated context, or NULL in case of error
|
||||
* @note this function is to be removed after a saner alternative is
|
||||
* written
|
||||
*)
|
||||
// struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat,
|
||||
// int dstW, int dstH, enum AVPixelFormat dstFormat,
|
||||
// int flags, SwsFilter *srcFilter,
|
||||
// SwsFilter *dstFilter, const double *param);
|
||||
|
||||
function sws_getContext(srcW: int; srcH: int; srcFormat: AVPixelFormat; dstW: int; dstH: int; dstFormat: AVPixelFormat; flags: int; srcFilter: pSwsFilter;
|
||||
dstFilter: pSwsFilter; const param: pdouble): pSwsContext; cdecl; external swscale_dll;
|
||||
|
||||
(*
|
||||
* Scale the image slice in srcSlice and put the resulting scaled
|
||||
* slice in the image in dst. A slice is a sequence of consecutive
|
||||
* rows in an image.
|
||||
*
|
||||
* Slices have to be provided in sequential order, either in
|
||||
* top-bottom or bottom-top order. If slices are provided in
|
||||
* non-sequential order the behavior of the function is undefined.
|
||||
*
|
||||
* @param c the scaling context previously created with
|
||||
* sws_getContext()
|
||||
* @param srcSlice the array containing the pointers to the planes of
|
||||
* the source slice
|
||||
* @param srcStride the array containing the strides for each plane of
|
||||
* the source image
|
||||
* @param srcSliceY the position in the source image of the slice to
|
||||
* process, that is the number (counted starting from
|
||||
* zero) in the image of the first row of the slice
|
||||
* @param srcSliceH the height of the source slice, that is the number
|
||||
* of rows in the slice
|
||||
* @param dst the array containing the pointers to the planes of
|
||||
* the destination image
|
||||
* @param dstStride the array containing the strides for each plane of
|
||||
* the destination image
|
||||
* @return the height of the output slice
|
||||
*)
|
||||
|
||||
// int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[],
|
||||
// const int srcStride[], int srcSliceY, int srcSliceH,
|
||||
// uint8_t *const dst[], const int dstStride[]);
|
||||
function sws_scale(c: pSwsContext; const srcSlice: psws_array_uint8_t; const srcStride: psws_array_int; srcSliceY: int; srcSliceH: int; dst: psws_array_uint8_t;
|
||||
const dstStride: psws_array_int): int; cdecl; overload; external swscale_dll;
|
||||
|
||||
(*
|
||||
* @param dstRange flag indicating the while-black range of the output (1=jpeg / 0=mpeg)
|
||||
* @param srcRange flag indicating the while-black range of the input (1=jpeg / 0=mpeg)
|
||||
* @param table the yuv2rgb coefficients describing the output yuv space, normally ff_yuv2rgb_coeffs[x]
|
||||
* @param inv_table the yuv2rgb coefficients describing the input yuv space, normally ff_yuv2rgb_coeffs[x]
|
||||
* @param brightness 16.16 fixed point brightness correction
|
||||
* @param contrast 16.16 fixed point contrast correction
|
||||
* @param saturation 16.16 fixed point saturation correction
|
||||
* @return -1 if not supported
|
||||
*)
|
||||
// int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4],
|
||||
// int srcRange, const int table[4], int dstRange,
|
||||
// int brightness, int contrast, int saturation);
|
||||
function sws_setColorspaceDetails(c: pSwsContext; const inv_table: psws_array4_int; srcRange: int; const table: psws_array4_int; dstRange: int; brightness: int;
|
||||
contrast: int; saturation: int): int; cdecl; external swscale_dll;
|
||||
|
||||
(*
|
||||
* @return -1 if not supported
|
||||
*)
|
||||
// int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table,
|
||||
// int *srcRange, int **table, int *dstRange,
|
||||
// int *brightness, int *contrast, int *saturation);
|
||||
function sws_getColorspaceDetails(c: pSwsContext; var inv_table: pInt; var srcRange: int; var table: pInt; var dstRange: int; var brightness: int;
|
||||
var contrast: int; var saturation: int): int; cdecl; external swscale_dll;
|
||||
|
||||
(*
|
||||
* Allocate and return an uninitialized vector with length coefficients.
|
||||
*)
|
||||
// SwsVector *sws_allocVec(int length);
|
||||
function sws_allocVec(length: int): pSwsVector; cdecl; external swscale_dll;
|
||||
|
||||
(*
|
||||
* Return a normalized Gaussian curve used to filter stuff
|
||||
* quality = 3 is high quality, lower is lower quality.
|
||||
*)
|
||||
// SwsVector *sws_getGaussianVec(double variance, double quality);
|
||||
function sws_getGaussianVec(variance: double; quality: double): pSwsVector; cdecl; external swscale_dll;
|
||||
|
||||
(*
|
||||
* Scale all the coefficients of a by the scalar value.
|
||||
*)
|
||||
// void sws_scaleVec(SwsVector *a, double scalar);
|
||||
procedure sws_scaleVec(a: pSwsVector; scalar: double); cdecl; external swscale_dll;
|
||||
|
||||
(*
|
||||
* Scale all the coefficients of a so that their sum equals height.
|
||||
*)
|
||||
// void sws_normalizeVec(SwsVector *a, double height);
|
||||
procedure sws_normalizeVec(a: pSwsVector; height: double); cdecl; external swscale_dll;
|
||||
|
||||
{$IFDEF FF_API_SWS_VECTOR}
|
||||
// attribute_deprecated SwsVector *sws_getConstVec(double c, int length);
|
||||
function sws_getConstVec(c: double; length: int): pSwsVector; cdecl; external swscale_dll;
|
||||
// attribute_deprecated SwsVector *sws_getIdentityVec(void);
|
||||
function sws_getIdentityVec(): pSwsVector; cdecl; external swscale_dll;
|
||||
// attribute_deprecated void sws_convVec(SwsVector *a, SwsVector *b);
|
||||
procedure sws_convVec(a: pSwsVector; b: pSwsVector); cdecl; external swscale_dll;
|
||||
// attribute_deprecated void sws_addVec(SwsVector *a, SwsVector *b);
|
||||
procedure sws_addVec(a: pSwsVector; b: pSwsVector); cdecl; external swscale_dll;
|
||||
// attribute_deprecated void sws_subVec(SwsVector *a, SwsVector *b);
|
||||
procedure sws_subVec(a: pSwsVector; b: pSwsVector); cdecl; external swscale_dll;
|
||||
// attribute_deprecated void sws_shiftVec(SwsVector *a, int shift);
|
||||
procedure sws_shiftVec(a: pSwsVector; shift: int); cdecl; external swscale_dll;
|
||||
// attribute_deprecated SwsVector *sws_cloneVec(SwsVector *a);
|
||||
function sws_cloneVec(a: pSwsVector): pSwsVector; cdecl; external swscale_dll;
|
||||
// attribute_deprecated void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level);
|
||||
procedure sws_printVec2(a: pSwsVector; log_ctx: pAVClass; log_level: int); cdecl; external swscale_dll;
|
||||
{$ENDIF}
|
||||
// void sws_freeVec(SwsVector *a);
|
||||
procedure sws_freeVec(a: pSwsVector); cdecl; external swscale_dll;
|
||||
|
||||
// SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur,
|
||||
// float lumaSharpen, float chromaSharpen,
|
||||
// float chromaHShift, float chromaVShift,
|
||||
// int verbose);
|
||||
function sws_getDefaultFilter(lumaGBlur: float; chromaGBlur: float; lumaSharpen: float; chromaSharpen: float; chromaHShift: float; chromaVShift: float;
|
||||
verbose: int): pSwsFilter; cdecl; external swscale_dll;
|
||||
|
||||
// void sws_freeFilter(SwsFilter *filter);
|
||||
procedure sws_freeFilter(filter: pSwsFilter); cdecl; external swscale_dll;
|
||||
|
||||
(*
|
||||
* Check if context can be reused, otherwise reallocate a new one.
|
||||
*
|
||||
* If context is NULL, just calls sws_getContext() to get a new
|
||||
* context. Otherwise, checks if the parameters are the ones already
|
||||
* saved in context. If that is the case, returns the current
|
||||
* context. Otherwise, frees context and gets a new context with
|
||||
* the new parameters.
|
||||
*
|
||||
* Be warned that srcFilter and dstFilter are not checked, they
|
||||
* are assumed to remain the same.
|
||||
*)
|
||||
// struct SwsContext *sws_getCachedContext(struct SwsContext *context,
|
||||
// int srcW, int srcH, enum AVPixelFormat srcFormat,
|
||||
// int dstW, int dstH, enum AVPixelFormat dstFormat,
|
||||
// int flags, SwsFilter *srcFilter,
|
||||
// SwsFilter *dstFilter, const double *param);
|
||||
function sws_getCachedContext(context: pSwsContext; srcW: int; srcH: int; srcFormat: AVPixelFormat; dstW: int; dstH: int; dstFormat: AVPixelFormat; flags: int;
|
||||
srcFilter: pSwsFilter; dstFilter: pSwsFilter; const param: pdouble): pSwsContext; cdecl; external swscale_dll;
|
||||
|
||||
(*
|
||||
* Convert an 8-bit paletted frame into a frame with a color depth of 32 bits.
|
||||
*
|
||||
* The output frame will have the same packed format as the palette.
|
||||
*
|
||||
* @param src source frame buffer
|
||||
* @param dst destination frame buffer
|
||||
* @param num_pixels number of pixels to convert
|
||||
* @param palette array with [256] entries, which must match color arrangement (RGB or BGR) of src
|
||||
*)
|
||||
// void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette);
|
||||
procedure sws_convertPalette8ToPacked32(const src: puint8_t; var dst: uint8_t; num_pixels: int; const palette: puint8_t); cdecl; external swscale_dll;
|
||||
|
||||
(*
|
||||
* Convert an 8-bit paletted frame into a frame with a color depth of 24 bits.
|
||||
*
|
||||
* With the palette format "ABCD", the destination frame ends up with the format "ABC".
|
||||
*
|
||||
* @param src source frame buffer
|
||||
* @param dst destination frame buffer
|
||||
* @param num_pixels number of pixels to convert
|
||||
* @param palette array with [256] entries, which must match color arrangement (RGB or BGR) of src
|
||||
*)
|
||||
// void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, int num_pixels, const uint8_t *palette);
|
||||
procedure sws_convertPalette8ToPacked24(const src: puint8_t; var dst: uint8_t; num_pixels: int; const palette: puint8_t); cdecl; external swscale_dll;
|
||||
|
||||
(*
|
||||
* Get the AVClass for swsContext. It can be used in combination with
|
||||
* AV_OPT_SEARCH_FAKE_OBJ for examining options.
|
||||
*
|
||||
* @see av_opt_find().
|
||||
*)
|
||||
// const AVClass *sws_get_class(void);
|
||||
function sws_get_class(): pAVClass; cdecl; external swscale_dll;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
BIN
fpPS4.ico
Before Width: | Height: | Size: 276 KiB After Width: | Height: | Size: 113 KiB |
120
fpPS4.lpi
|
@ -31,7 +31,7 @@
|
|||
<PackageName Value="LCL"/>
|
||||
</Item1>
|
||||
</RequiredPackages>
|
||||
<Units Count="120">
|
||||
<Units Count="144">
|
||||
<Unit0>
|
||||
<Filename Value="fpPS4.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
|
@ -337,6 +337,7 @@
|
|||
<Unit73>
|
||||
<Filename Value="src\ps4_libsceremoteplay.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceRemoteplay"/>
|
||||
</Unit73>
|
||||
<Unit74>
|
||||
<Filename Value="src\ps4_libscertc.pas"/>
|
||||
|
@ -389,6 +390,7 @@
|
|||
<Unit84>
|
||||
<Filename Value="src\np\ps4_libscenpmatching2.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceNpMatching2"/>
|
||||
</Unit84>
|
||||
<Unit85>
|
||||
<Filename Value="src\np\ps4_libscenpscore.pas"/>
|
||||
|
@ -475,7 +477,7 @@
|
|||
<IsPartOfProject Value="True"/>
|
||||
</Unit103>
|
||||
<Unit104>
|
||||
<Filename Value="src\ps4_libscenpwebapi.pas"/>
|
||||
<Filename Value="src\np\ps4_libscenpwebapi.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceNpWebApi"/>
|
||||
</Unit104>
|
||||
|
@ -549,6 +551,117 @@
|
|||
<Filename Value="kernel\mm_adr_name.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit119>
|
||||
<Unit120>
|
||||
<Filename Value="kernel\ps4_pthread_attr.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit120>
|
||||
<Unit121>
|
||||
<Filename Value="src\ps4_libsceavplayer.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceAvPlayer"/>
|
||||
</Unit121>
|
||||
<Unit122>
|
||||
<Filename Value="src\ps4_libscecomposite.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceComposite"/>
|
||||
</Unit122>
|
||||
<Unit123>
|
||||
<Filename Value="src\ps4_libSceSsl.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit123>
|
||||
<Unit124>
|
||||
<Filename Value="src\ps4_libsceult.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceUlt"/>
|
||||
</Unit124>
|
||||
<Unit125>
|
||||
<Filename Value="src\ps4_libscegamelivestreaming.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceGameLiveStreaming"/>
|
||||
</Unit125>
|
||||
<Unit126>
|
||||
<Filename Value="src\ps4_libsceshareplay.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceSharePlay"/>
|
||||
</Unit126>
|
||||
<Unit127>
|
||||
<Filename Value="src\ps4_libscesyscore.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceSysCore"/>
|
||||
</Unit127>
|
||||
<Unit128>
|
||||
<Filename Value="src\ps4_libscevideorecording.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceVideoRecording"/>
|
||||
</Unit128>
|
||||
<Unit129>
|
||||
<Filename Value="src\ps4_libscecontentexport.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceContentExport"/>
|
||||
</Unit129>
|
||||
<Unit130>
|
||||
<Filename Value="src\ps4_libsceusbd.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceUsbd"/>
|
||||
</Unit130>
|
||||
<Unit131>
|
||||
<Filename Value="src\np\ps4_libscenpcommon.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceNpCommon"/>
|
||||
</Unit131>
|
||||
<Unit132>
|
||||
<Filename Value="src\np\np_error.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit132>
|
||||
<Unit133>
|
||||
<Filename Value="src\audiodec\ps4_libsceaudiodec.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceAudiodec"/>
|
||||
</Unit133>
|
||||
<Unit134>
|
||||
<Filename Value="src\audiodec\ps4_libsceaudiodeccpu.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit134>
|
||||
<Unit135>
|
||||
<Filename Value="src\ps4_libscefiber.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceFiber"/>
|
||||
</Unit135>
|
||||
<Unit136>
|
||||
<Filename Value="src\ps4_libscedepth.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceDepth"/>
|
||||
</Unit136>
|
||||
<Unit137>
|
||||
<Filename Value="src\np\ps4_libscenptus.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceNpTus"/>
|
||||
</Unit137>
|
||||
<Unit138>
|
||||
<Filename Value="src\np\ps4_libscenpauth.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceNpAuth"/>
|
||||
</Unit138>
|
||||
<Unit139>
|
||||
<Filename Value="src\inputs\sce_pad_types.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit139>
|
||||
<Unit140>
|
||||
<Filename Value="src\inputs\sce_pad_interface.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit140>
|
||||
<Unit141>
|
||||
<Filename Value="src\inputs\sdl2_pad_interface.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit141>
|
||||
<Unit142>
|
||||
<Filename Value="src\inputs\kbm_pad_interface.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit142>
|
||||
<Unit143>
|
||||
<Filename Value="src\inputs\xinput_pad_interface.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit143>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
@ -560,7 +673,7 @@
|
|||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir);kernel;src\ajm;sys"/>
|
||||
<Libraries Value="static"/>
|
||||
<OtherUnitFiles Value="rtl;sys;vulkan;chip;spirv;kernel;src;src\ajm;src\audio;src\np;src\playgo;shaders;src\inputs;src\libcinternal"/>
|
||||
<OtherUnitFiles Value="rtl;sys;vulkan;chip;spirv;kernel;src;src\ajm;src\audio;src\np;src\playgo;shaders;src\inputs;src\libcinternal;ffmpeg;src\audiodec"/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<Parsing>
|
||||
|
@ -572,6 +685,7 @@
|
|||
<SmartLinkUnit Value="True"/>
|
||||
<RelocatableUnit Value="True"/>
|
||||
<TargetCPU Value="x86_64"/>
|
||||
<TargetOS Value="win64"/>
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
|
|
441
fpPS4.lpr
|
@ -4,6 +4,7 @@ uses
|
|||
cmem,
|
||||
cthreads,
|
||||
{$ENDIF}
|
||||
cpu,
|
||||
windows,
|
||||
seh64,
|
||||
Classes,
|
||||
|
@ -13,18 +14,22 @@ uses
|
|||
sys_types,
|
||||
sys_pthread,
|
||||
sys_path,
|
||||
sys_kernel,
|
||||
ps4libdoc,
|
||||
ps4_libkernel,
|
||||
ps4_libSceLibcInternal,
|
||||
ps4_libSceScreenShot,
|
||||
ps4_libSceRtc,
|
||||
ps4_libSceNpSessionSignaling,
|
||||
ps4_libSceNpSignaling,
|
||||
ps4_libSceNpMatching2,
|
||||
ps4_libSceRemoteplay,
|
||||
ps4_libSceAjm,
|
||||
ps4_libSceMouse,
|
||||
ps4_libSceIme,
|
||||
ps4_libSceLncUtil,
|
||||
ps4_libSceMove,
|
||||
ps4_libSceMoveTracker,
|
||||
ps4_libScePlayGo,
|
||||
ps4_libSceDiscMap,
|
||||
ps4_libSceAppContent,
|
||||
|
@ -34,26 +39,57 @@ uses
|
|||
ps4_libSceNpScore,
|
||||
ps4_libSceNpTrophy,
|
||||
ps4_libSceSystemService,
|
||||
ps4_libSceSystemGesture,
|
||||
ps4_libSceNpUtility,
|
||||
ps4_libSceNpCommon,
|
||||
ps4_libSceNpManager,
|
||||
ps4_libSceNpGameIntent,
|
||||
ps4_libSceNpAuth,
|
||||
ps4_libSceNpParty,
|
||||
ps4_libSceSaveData,
|
||||
ps4_libSceDialogs,
|
||||
ps4_libSceUserService,
|
||||
ps4_libSceAudioOut,
|
||||
ps4_libSceAudio3d,
|
||||
ps4_libSceVoice,
|
||||
ps4_libSceVideoOut,
|
||||
ps4_libSceAvPlayer,
|
||||
ps4_libSceAudiodec,
|
||||
ps4_libScePad,
|
||||
ps4_libSceNpWebApi,
|
||||
ps4_libSceRudp,
|
||||
ps4_libSceRandom,
|
||||
ps4_libSceComposite,
|
||||
ps4_libSceSysCore,
|
||||
ps4_libSceSsl,
|
||||
ps4_libSceFiber,
|
||||
ps4_libSceUlt,
|
||||
ps4_libSceGameLiveStreaming,
|
||||
ps4_libSceSharePlay,
|
||||
ps4_libSceShareUtility,
|
||||
ps4_libSceSocialScreen,
|
||||
ps4_libSceVideoRecording,
|
||||
ps4_libSceCompanionHttpd,
|
||||
ps4_libSceCompanionUtil,
|
||||
ps4_libSceContentExport,
|
||||
ps4_libSceConvertKeycode,
|
||||
ps4_libSceUsbd,
|
||||
ps4_libSceUsbStorage,
|
||||
ps4_libSceAudiodecCpu,
|
||||
ps4_libSceDepth,
|
||||
ps4_libSceNpTus,
|
||||
ps4_libSceLoginService,
|
||||
ps4_libSceHmd,
|
||||
ps4_libSceVrTracker,
|
||||
ps4_libSceCamera,
|
||||
ps4_elf,
|
||||
ps4_pthread,
|
||||
ps4_program,
|
||||
ps4_elf_tls,
|
||||
|
||||
ps4_videodrv,
|
||||
vMemory,
|
||||
vImageManager,
|
||||
vImageTiling,
|
||||
vFlip,
|
||||
|
||||
trace_manager;
|
||||
|
@ -68,21 +104,26 @@ begin
|
|||
begin
|
||||
promo:
|
||||
Writeln('fpPS4 (',{$I tag.inc},')');
|
||||
Writeln('Copyright (c) 2021-2022 by Red_prig');
|
||||
Writeln('PS4 compatibility layer (emulator) on Free Pascal '+{$I %FPCVERSION%});
|
||||
Writeln('Copyright (c) 2021-2023 by red-prig');
|
||||
Writeln('PS4 compatibility layer (emulator) written with Free Pascal '+{$I %FPCVERSION%});
|
||||
Writeln(' Parameters:');
|
||||
Writeln(' -e <name> //decrypted elf or self file name');
|
||||
Writeln(' -f <name> //folder of app (/app0)');
|
||||
Writeln(' -p <name> //folder of patch (/app1)');
|
||||
Writeln(' -s <name> //savedata path');
|
||||
Writeln(' -e <name> //Decrypted ELF or SELF file name');
|
||||
Writeln(' -f <name> //Folder of app (/app0)');
|
||||
Writeln(' -p <name> //Folder of patch (/app1)');
|
||||
Writeln(' -s <name> //Savedata path');
|
||||
Writeln(' -w //Fullscreen mode');
|
||||
Writeln(' -pad <name> //Gamepad interface selection (xinput,sdl2,keyboard) default:xinput');
|
||||
Writeln(' -led <clr> //Initial LED color of Gamepad ($rrggbb)');
|
||||
|
||||
Writeln(' -h <name> //enable hack');
|
||||
Writeln(' DEPTH_DISABLE_HACK //disable depth buffer');
|
||||
Writeln(' COMPUTE_DISABLE_HACK //disable compute shaders');
|
||||
Writeln(' MEMORY_BOUND_HACK //limit the amount of GPU allocated memory (iGPU)');
|
||||
Writeln(' IMAGE_TEST_HACK //always mark that the texture has changed');
|
||||
Writeln(' IMAGE_LOAD_HACK //never reload texture');
|
||||
Writeln(' DISABLE_SRGB_HACK //disables hacked display of SRGB');
|
||||
Writeln(' -h <name> //enable hack');
|
||||
Writeln(' DEPTH_DISABLE_HACK //Disables depth buffer');
|
||||
Writeln(' COMPUTE_DISABLE_HACK //Disables compute shaders');
|
||||
Writeln(' MEMORY_BOUND_HACK //Limits the amount of GPU allocated memory (iGPU)');
|
||||
Writeln(' IMAGE_TEST_HACK //Always marks that the texture has changed');
|
||||
Writeln(' IMAGE_LOAD_HACK //Never reload textures (improves performance on many games)');
|
||||
Writeln(' DISABLE_SRGB_HACK //Disables hacked SRGB display');
|
||||
Writeln(' DISABLE_FMV_HACK //Disables in-game movies');
|
||||
Writeln(' SKIP_UNKNOW_TILING //Skip unknown tiling texture types');
|
||||
|
||||
Exit(False);
|
||||
end;
|
||||
|
@ -91,11 +132,14 @@ begin
|
|||
For i:=1 to ParamCount do
|
||||
begin
|
||||
case LowerCase(ParamStr(i)) of
|
||||
'-e':n:=0;
|
||||
'-f':n:=1;
|
||||
'-p':n:=2;
|
||||
'-s':n:=3;
|
||||
'-h':n:=4;
|
||||
'-e':n:=0;
|
||||
'-f':n:=1;
|
||||
'-p':n:=2;
|
||||
'-s':n:=3;
|
||||
'-h':n:=4;
|
||||
'-w':ps4_libSceVideoOut.FULLSCREEN_MODE:=True;
|
||||
'-pad':n:=5;
|
||||
'-led':n:=6;
|
||||
else
|
||||
if (n<>-1) then
|
||||
begin
|
||||
|
@ -120,6 +164,12 @@ begin
|
|||
3:begin
|
||||
ps4_app.save_path:=Trim(ParamStr(i));
|
||||
end;
|
||||
5:begin
|
||||
select_pad_interface(Trim(ParamStr(i)));
|
||||
end;
|
||||
6:begin
|
||||
select_led_color(Trim(ParamStr(i)));
|
||||
end;
|
||||
4:begin
|
||||
case UpperCase(ParamStr(i)) of
|
||||
'DEPTH_DISABLE_HACK' :ps4_videodrv.DEPTH_DISABLE_HACK:=True;
|
||||
|
@ -128,6 +178,8 @@ begin
|
|||
'IMAGE_TEST_HACK' :vImageManager.IMAGE_TEST_HACK:=True;
|
||||
'IMAGE_LOAD_HACK' :vImageManager.IMAGE_LOAD_HACK:=True;
|
||||
'DISABLE_SRGB_HACK' :vFlip.SRGB_HACK:=False;
|
||||
'DISABLE_FMV_HACK' :ps4_libsceavplayer.DISABLE_FMV_HACK:=True;
|
||||
'SKIP_UNKNOW_TILING' :vImageTiling.SKIP_UNKNOW_TILING:=True;
|
||||
else;
|
||||
end;
|
||||
end;
|
||||
|
@ -203,36 +255,13 @@ end;
|
|||
|
||||
procedure print_stub(nid:QWORD;lib:PLIBRARY); MS_ABI_Default;
|
||||
begin
|
||||
Writeln(StdErr,'nop nid:',lib^.strName,':',HexStr(nid,16),':',ps4libdoc.GetFunctName(nid));
|
||||
Writeln(StdErr,SysLogPrefix,'nop nid:',lib^.strName,':',HexStr(nid,16),':',ps4libdoc.GetFunctName(nid));
|
||||
//DebugBreak;
|
||||
Sleep(INFINITE);
|
||||
//readln;
|
||||
//Print_libs(ps4_app.GetFile('libc.prx'));
|
||||
end;
|
||||
|
||||
function ps4_sceSslInit(poolSize:size_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln('sceSslInit:',poolSize);
|
||||
Result:=3;
|
||||
end;
|
||||
|
||||
function ps4_sceUltInitialize():Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceGameLiveStreamingInitialize(heapSize:qword):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln('sceGameLiveStreamingInitialize:',heapSize);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceSharePlayInitialize(pHeap:Pointer;heapSize:qword):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln('sceSharePlayInitialize:',HexStr(pHeap),':',heapSize);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ResolveImport(elf:Telf_file;Info:PResolveImportInfo;data:Pointer):Pointer;
|
||||
var
|
||||
lib:PLIBRARY;
|
||||
|
@ -255,33 +284,6 @@ begin
|
|||
|
||||
//Writeln('Resolve:',Info^.lib^.strName,':',ps4libdoc.GetFunctName(Info^.Nid));
|
||||
|
||||
if (Result=nil) then
|
||||
begin
|
||||
Case Info^.lib^.strName of
|
||||
|
||||
'libSceSsl':
|
||||
Case Info^.nid of
|
||||
QWORD($85DA551140C55B7B):Result:=@ps4_sceSslInit;
|
||||
end;
|
||||
|
||||
'libSceUlt':
|
||||
Case Info^.nid of
|
||||
QWORD($859220D44586B073):Result:=@ps4_sceUltInitialize;
|
||||
end;
|
||||
|
||||
'libSceGameLiveStreaming':
|
||||
Case Info^.nid of
|
||||
QWORD($92F604C369419DD9):Result:=@ps4_sceGameLiveStreamingInitialize;
|
||||
end;
|
||||
|
||||
'libSceSharePlay':
|
||||
Case Info^.nid of
|
||||
QWORD($8ACAEEAAD86961CC):Result:=@ps4_sceSharePlayInitialize;
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
{
|
||||
if (Result<>nil) and ((Info^.sType=STT_FUN) or (Info^.sType=STT_SCE)) then //trace
|
||||
begin
|
||||
|
@ -387,7 +389,7 @@ begin
|
|||
end else
|
||||
if (Info^.sBind<>STB_WEAK) then
|
||||
begin
|
||||
Writeln(StdErr,'Warn^:',Info^.lib^.strName,':',ps4libdoc.GetFunctName(Info^.Nid),':',HexStr(Info^.Nid,16));
|
||||
Writeln(StdWrn,'[Warn]:',Info^.lib^.strName,':',ps4libdoc.GetFunctName(Info^.Nid),':',HexStr(Info^.Nid,16));
|
||||
end;
|
||||
|
||||
end;
|
||||
|
@ -417,7 +419,7 @@ begin
|
|||
|
||||
if (Result=nil) then
|
||||
begin
|
||||
Writeln(StdErr,'Warn^:',Info^.lib^.strName,':',ps4libdoc.GetFunctName(Info^.Nid),':',HexStr(Info^.Nid,16));
|
||||
Writeln(StdWrn,'[Warn]:',Info^.lib^.strName,':',ps4libdoc.GetFunctName(Info^.Nid),':',HexStr(Info^.Nid,16));
|
||||
Exit(nil); //Don't reload!
|
||||
end;
|
||||
|
||||
|
@ -466,297 +468,19 @@ begin
|
|||
DefaultFileSystemCodePage:=CP_UTF8;
|
||||
DefaultRTLFileSystemCodePage:=CP_UTF8;
|
||||
UTF8CompareLocale:=CP_UTF8;
|
||||
|
||||
sys_crt_init;
|
||||
|
||||
if not cpu.AVX2Support then
|
||||
begin
|
||||
Writeln(StdErr,'AVX2 not support!');
|
||||
Assert(false,'AVX2 not supported!');
|
||||
Exit;
|
||||
end;
|
||||
|
||||
ps4_app.save_path:=IncludeTrailingPathDelimiter(GetCurrentDir)+'savedata';
|
||||
if not ParseCmd then Exit;
|
||||
|
||||
//ps4_app.app_path:='..\samples\api_gnm\simplet-single-triangle';
|
||||
//ps4_app.app_file:='..\samples\api_gnm\simplet-single-triangle\simplet-single-triangle_debug.elf';
|
||||
|
||||
//ps4_app.app_file:='..\samples\api_gnm\simplet-cmask\simplet-cmask_debug.elf';
|
||||
|
||||
//ps4_app.app_path:='..\samples\api_gnm\simplet-simple-fs\';
|
||||
//ps4_app.app_file:='..\samples\api_gnm\simplet-simple-fs\simplet-simple-fs_debug.elf';
|
||||
|
||||
//ps4_app.app_path:='..\samples\api_gnm\';
|
||||
//ps4_app.app_file:='..\samples\api_gnm\basic-sample\basic-sample_debug.elf';
|
||||
|
||||
//ps4_app.app_path:='..\samples\api_gnm\';
|
||||
//ps4_app.app_file:='..\samples\api_gnm\anisotropy-sample\anisotropy-sample_debug.elf';
|
||||
|
||||
//ps4_app.app_path:='..\samples\api_gnm\';
|
||||
//ps4_app.app_file:='..\samples\api_gnm\depth-mode-sample\depth-mode-sample_debug.elf';
|
||||
|
||||
//ps4_app.app_path:='..\samples\api_gnm\';
|
||||
//ps4_app.app_file:='..\samples\api_gnm\eqaa-sample\eqaa-sample_debug.elf';
|
||||
|
||||
//ps4_app.app_path:='..\samples\tutorial_graphics_programming\basic_quad\';
|
||||
//ps4_app.app_file:='..\samples\tutorial_graphics_programming\basic_quad\basic_quad_debug.elf';
|
||||
|
||||
//ps4_app.app_path:='..\samples\tutorial_anti-aliasing\';
|
||||
//ps4_app.app_file:='..\samples\tutorial_anti-aliasing\tutorial_anti-aliasing_debug.elf';
|
||||
|
||||
//ps4_app.app_path:='..\samples\tutorial_graphics_programming\basic-compute\';
|
||||
//ps4_app.app_file:='..\samples\tutorial_graphics_programming\basic-compute\basic-compute_debug.elf';
|
||||
|
||||
//ps4_app.app_path:='..\samples\api_gnm';
|
||||
//ps4_app.app_file:='..\samples\api_gnm\drawindirect-sample\drawindirect-sample_debug.elf';
|
||||
|
||||
//ps4_app.app_file:='..\samples\api_video_out\videoout_cursor.elf';
|
||||
//ps4_app.app_file:='..\samples\api_video_out\videoout_flip.elf';
|
||||
|
||||
//ps4_app.app_file:='..\samples\api_video_out\videoout_basic2.elf';
|
||||
|
||||
//ps4_app.app_file:='..\samples\api_video_out\videoout_basic3.elf';
|
||||
//ps4_app.app_file:='..\samples\api_video_out\videoout_basic5.elf';
|
||||
|
||||
//ps4_app.app_file:='..\samples\api_video_out\videoout_basic_1d.elf';
|
||||
|
||||
//ps4_app.app_path:='..\samples\http_get\';
|
||||
//ps4_app.app_file:='..\samples\http_get\simple5.elf';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\MOMODORA\CUSA05694\';
|
||||
//ps4_app.app_file:='G:\Games\MOMODORA\CUSA05694\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\MOMODORA\CUSA05694\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\MOMODORA\CUSA05694\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\We.Are.Doomed.PS4-PRELUDE\CUSA02394\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\We.Are.Doomed.PS4-PRELUDE\CUSA02394\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\We.Are.Doomed.PS4-PRELUDE\CUSA02394\';
|
||||
//ps4_app.app_file:='G:\Games\We.Are.Doomed.PS4-PRELUDE\CUSA02394\eboot.elf';
|
||||
//ps4_app.app_file:='G:\Games\We.Are.Doomed.PS4-PRELUDE\CUSA02394\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\We.Are.Doomed.PS4-PRELUDE\CUSA02394\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\We.Are.Doomed.PS4-PRELUDE\CUSA02394\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Organ.Trail.Complete.Edition\CUSA02791\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Organ.Trail.Complete.Edition\CUSA02791\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Organ.Trail.Complete.Edition\CUSA02791\';
|
||||
//ps4_app.app_file:='G:\Games\Organ.Trail.Complete.Edition\CUSA02791\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Bloodborne Game of the Year Edition v1.09 [RUS]\';
|
||||
//ps4_app.app_file:='G:\Games\Bloodborne Game of the Year Edition v1.09 [RUS]\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\BLAZING_CHROME\CUSA14656\';
|
||||
//ps4_app.app_file:='G:\Games\BLAZING_CHROME\CUSA14656\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\BLAZING_CHROME\CUSA14656';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\BLAZING_CHROME\CUSA14656\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Sonic Mania\CUSA07023\';
|
||||
//ps4_app.app_file:='G:\Games\Sonic Mania\CUSA07023\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Sonic Mania\CUSA07023\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Sonic Mania\CUSA07023\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Worms\CUSA04047\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Worms\CUSA04047\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Worms\CUSA04047\';
|
||||
//ps4_app.app_file:='G:\Games\Worms\CUSA04047\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Super Meat Boy\';
|
||||
//ps4_app.app_file:='G:\Games\Super Meat Boy\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Super Meat Boy\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Super Meat Boy\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Limbo\CUSA01369\';
|
||||
//ps4_app.app_file:='G:\Games\Limbo\CUSA01369\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Hue\CUSA05065\';
|
||||
//ps4_app.app_file:='G:\Games\Hue\CUSA05065\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Hue\CUSA05065\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Hue\CUSA05065\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\ps4-homebrew\creeperdiver-ps4\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\ps4-homebrew\creeperdiver-ps4\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\ps4-homebrew\SPELUNKYCLASSIC\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\ps4-homebrew\SPELUNKYCLASSIC\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Cursed Castilla v1.00 (ASIA)\CUSA07773\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Cursed Castilla v1.00 (ASIA)\CUSA07773\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Undertale\CUSA09415\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Undertale\CUSA09415\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Undertale\CUSA09415\';
|
||||
//ps4_app.app_file:='G:\Games\Undertale\CUSA09415\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Cladun Returns This Is Sengoku v1.00\CUSA06770\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Cladun Returns This Is Sengoku v1.00\CUSA06770\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Cladun Returns This Is Sengoku v1.00\CUSA06770\';
|
||||
//ps4_app.app_file:='G:\Games\Cladun Returns This Is Sengoku v1.00\CUSA06770\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\ps4-homebrew\Blue Boi Quickz\';
|
||||
//ps4_app.app_file:='G:\Games\ps4-homebrew\Blue Boi Quickz\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Shovel Knight\CUSA01867\';
|
||||
//ps4_app.app_file:='G:\Games\Shovel Knight\CUSA01867\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Stardew_Valley\CUSA06829\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Stardew_Valley\CUSA06829\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Stardew_Valley\CUSA06829\';
|
||||
//ps4_app.app_file:='G:\Games\Stardew_Valley\CUSA06829\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Super Exploding Zoo\CUSA00446\';
|
||||
//ps4_app.app_file:='G:\Games\Super Exploding Zoo\CUSA00446\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Super.Exploding.Zoo\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Super.Exploding.Zoo\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Untitled Goose Game\CUSA23079\';
|
||||
//ps4_app.app_file:='G:\Games\Untitled Goose Game\CUSA23079\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Untitled Goose Game\CUSA23079\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Untitled Goose Game\CUSA23079\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\JETPACKJOYRIDE\CUSA03633\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\JETPACKJOYRIDE\CUSA03633\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\JETPACKJOYRIDE\CUSA03633\';
|
||||
//ps4_app.app_file:='G:\Games\JETPACKJOYRIDE\CUSA03633\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Dont.Die.Mr.Robot\CUSA02782\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Dont.Die.Mr.Robot\CUSA02782\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Patapon\CUSA07184\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Patapon\CUSA07184\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Patapon\CUSA07184\';
|
||||
//ps4_app.app_file:='G:\Games\Patapon\CUSA07184\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Bards.Gold\CUSA05012\';
|
||||
//ps4_app.app_file:='G:\Games\Bards.Gold\CUSA05012\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Record of Lodoss War Deedlit in Wonder Labyrinth\CUSA29366\';
|
||||
//ps4_app.app_file:='G:\Games\Record of Lodoss War Deedlit in Wonder Labyrinth\CUSA29366\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\LODOSSWARDEEDLIT\CUSA29366\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\LODOSSWARDEEDLIT\CUSA29366\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Spelunky 2\CUSA20601\';
|
||||
//ps4_app.app_file:='G:\Games\Spelunky 2\CUSA20601\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\SPELUNKY2\CUSA20601\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\SPELUNKY2\CUSA20601\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Desert.Child\CUSA12744\';
|
||||
//ps4_app.app_file:='G:\Games\Desert.Child\CUSA12744\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Blackhole\CUSA06921\';
|
||||
//ps4_app.app_file:='G:\Games\Blackhole\CUSA06921\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Blackhole\CUSA06921\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Blackhole\CUSA06921\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Spelunky\CUSA00491\';
|
||||
//ps4_app.app_file:='G:\Games\Spelunky\CUSA00491\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Mega Man Legacy Collection v1.00\CUSA02516\';
|
||||
//ps4_app.app_file:='G:\Games\Mega Man Legacy Collection v1.00\CUSA02516\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\ps4-homebrew\PS4_Player\';
|
||||
//ps4_app.app_file:='G:\Games\ps4-homebrew\PS4_Player\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\ps4-homebrew\TEST_PAD\';
|
||||
//ps4_app.app_file:='G:\Games\ps4-homebrew\TEST_PAD\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\ps4-homebrew\TEST_PAD\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\ps4-homebrew\TEST_PAD\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Castlevania\SLUS00067\';
|
||||
//ps4_app.app_file:='G:\Games\Castlevania\SLUS00067\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Roombo First Blood\CUSA19205\';
|
||||
//ps4_app.app_file:='G:\Games\Roombo First Blood\CUSA19205\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\ps4-homebrew\PS4_Player_9.00\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\ps4-homebrew\PS4_Player_9.00\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\ps4-homebrew\Eboot_Give\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\ps4-homebrew\Eboot_Give\RayTracing3_eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Metal_Max_Xeno\CUSA12350\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Metal_Max_Xeno\CUSA12350\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Roombo First Blood\CUSA19205\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Roombo First Blood\CUSA19205\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\ps4-homebrew\pad\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\ps4-homebrew\pad\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Gem.Smashers\CUSA07572\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Gem.Smashers\CUSA07572\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Gem.Smashers\CUSA07572\';
|
||||
//ps4_app.app_file:='G:\Games\Gem.Smashers\CUSA07572\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='G:\Games\Taiko No Tatsujin\CUSA07515\';
|
||||
//ps4_app.app_file:='G:\Games\Taiko No Tatsujin\CUSA07515\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Taiko_No_Tatsujin\CUSA07515\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Taiko_No_Tatsujin\CUSA07515\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\ps4-homebrew\project_PM4_KernelEqueue\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\ps4-homebrew\project_PM4_KernelEqueue\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Shantae Riskys Revenge\CUSA01587\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Shantae Riskys Revenge\CUSA01587\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\OpenOrbis\IPNGDRAW\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\OpenOrbis\IPNGDRAW\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\ps4-homebrew\LAPY10018\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\ps4-homebrew\LAPY10018\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Super Star Wars\CUSA03292\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Super Star Wars\CUSA03292\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\VA-11.Hall-A\CUSA15402\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\VA-11.Hall-A\CUSA15402\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\ps4-homebrew\Quiz\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\ps4-homebrew\Quiz\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\namco\uroot\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\namco\uroot\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\ps4-homebrew\PS4-Xplorer\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\ps4-homebrew\PS4-Xplorer\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Chronicles_of_Teddy_Harmony_of_Exidus\CUSA03328\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Chronicles_of_Teddy_Harmony_of_Exidus\CUSA03328\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Another_World\CUSA00602\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Another_World\CUSA00602\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Dino.Dinis.Kick.Off.Revival\CUSA03453\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Dino.Dinis.Kick.Off.Revival\CUSA03453\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Cat.Quest\CUSA09499\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Cat.Quest\CUSA09499\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Kitten.Squad\CUSA04801\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Kitten.Squad\CUSA04801\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Mitsurugi.Kamui.Hikae\CUSA02166\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Mitsurugi.Kamui.Hikae\CUSA02166\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Prison_Architect\CUSA03487\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Prison_Architect\CUSA03487\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\Pumped.BMX.Plus.PS4-PRELUDE\CUSA02589\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\Pumped.BMX.Plus.PS4-PRELUDE\CUSA02589\eboot.bin';
|
||||
|
||||
ps4_app.resolve_cb:=@ResolveImport;
|
||||
ps4_app.reload_cb :=@ReloadImport;
|
||||
|
||||
|
@ -774,7 +498,6 @@ begin
|
|||
_pthread_run_entry(@main,GetSceUserMainThreadName,GetSceUserMainThreadStackSize);
|
||||
|
||||
ps4_libSceVideoOut.App_Run;
|
||||
|
||||
//KillALLThreads TODO
|
||||
//readln;
|
||||
end.
|
||||
|
|
|
@ -5,5 +5,5 @@
|
|||
\---------/
|
||||
|
||||
Basic icon theme:
|
||||
Author: SuriK#7587
|
||||
Author: https://github.com/Mou-Ikkai
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
/---------\
|
||||
|logo.png |
|
||||
|fpPS4.ico|
|
||||
\---------/
|
||||
|
||||
Basic icon theme:
|
||||
Author: SuriK#7587
|
||||
|
After Width: | Height: | Size: 276 KiB |
After Width: | Height: | Size: 4.2 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg width="145px" height="40px" viewBox="0 0 145 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient x1="61.5370404%" y1="13%" x2="34.2376801%" y2="129.365079%" id="linearGradient-1"><stop stop-color="#EF7829" offset="0%"/><stop stop-color="#F0692A" offset="28%"/><stop stop-color="#F15E2C" offset="63%"/><stop stop-color="#F15A2C" offset="100%"/></linearGradient></defs><g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g id="Blocks/Header_Unlogged" transform="translate(-15.000000, -15.000000)"><g id="icons/boosty_logo" transform="translate(15.000000, 15.000000)"><g id="Shape"><path d="M138.119363,13.14856 L132.002653,22.63144 L131.397878,13.14856 L122.575597,13.14856 C123.384615,10.366 124.037135,8.13256 124.037135,8.13256 L124.381963,7.01848 L117.6313,7.01848 L117.312997,8.13256 L115.851459,13.14856 L108.660477,13.14856 C102.750663,13.14856 99.4244032,14.8276 98.0503979,18.00352 C97.2546419,15.09952 94.6206897,13.14856 90.5782493,13.14856 C87.2902077,13.135208 84.1128672,14.3300173 81.6551724,16.504 C80.464191,14.45536 78.1061008,13.1512 74.8116711,13.1512 C71.2975199,13.1360778 67.9189855,14.5000837 65.4084881,16.94752 C64.3103448,14.656 61.8541114,13.14856 58.3262599,13.14856 C57.1586378,13.1510938 55.9961737,13.302814 54.867374,13.6 L55.397878,11.77312 C55.4066092,11.7439195 55.4181572,11.7156279 55.4323607,11.68864 L56.7904509,7 L50.066313,7 L45.7798408,21.73384 C45.668435,22.02952 45.5676393,22.32784 45.4801061,22.63144 C45.2902336,23.2752559 45.1623364,23.9355911 45.0981432,24.60352 C44.5384615,28.714 46.3474801,31.816 51.3660477,32.0272 C51.8475451,32.0843575 52.332067,32.1125687 52.8169761,32.11168 C56.2925823,32.0722669 59.6211655,30.7100879 62.1193634,28.3048 C63.1564987,30.6148 65.5676393,32.11168 69.2970822,32.11168 C72.5436452,32.0790306 75.6705362,30.8873894 78.1087533,28.7536 C79.2493369,30.80488 81.5862069,32.11168 85.061008,32.11168 L101.917772,32.11168 C107.143236,32.11168 110.095491,31.08472 111.6313,28.85392 C111.6313,30.98176 112.851459,32.11168 115.941645,32.11168 C118.437666,32.11168 121.777188,31.5652 126.366048,30.43792 L119.687003,39.9208 L126.411141,39.9208 L144.846154,13.14856 L138.119363,13.14856 Z M58.9310345,22.63144 C58.3023873,24.79096 56.2785146,26.53336 54.4217507,26.53336 C52.5649867,26.53336 51.5676393,24.79096 52.1962865,22.63144 C52.8249337,20.47192 54.8488064,18.72688 56.6923077,18.72688 C58.535809,18.72688 59.5596817,20.464 58.9310345,22.63144 Z M75.4164456,22.63144 C74.7877984,24.79096 72.7639257,26.53336 70.9071618,26.53336 C69.0503979,26.53336 68.0769231,24.79096 68.6923077,22.63144 C69.3076923,20.47192 71.3448276,18.72688 73.2015915,18.72688 C75.0583554,18.72688 76.0344828,20.464 75.4164456,22.63144 Z M84.4562334,22.63144 C85.0848806,20.46928 87.1087533,18.72688 88.9522546,18.72688 C90.795756,18.72688 91.8090186,20.46928 91.1803714,22.63144 C90.5517241,24.7936 88.5941645,26.4832 86.7586207,26.536 L86.6074271,26.536 C84.801061,26.4832 83.8355438,24.76192 84.4562334,22.63144 Z M106.127321,25.85752 C105.787798,26.64952 103.132626,26.53072 102.466844,26.54128 L95.928382,26.536 C96.8103436,25.360374 97.4758216,24.0383816 97.8938992,22.63144 C97.9363395,22.48888 97.9734748,22.34896 98.0079576,22.20904 C98.7108753,23.2096 100.201592,24.11248 103.100796,24.68536 C105.864721,25.216 106.3687,25.05496 106.127321,25.85752 Z M112.777188,23.7244 C112.204244,21.49624 109.721485,20.6224 106.241379,20.2 C104.785146,20.02576 103.965517,19.95712 104.148541,19.3288 C104.289125,18.8404 105.018568,18.73744 106.586207,18.73744 L114.230769,18.73744 L112.777188,23.7244 Z M119.496021,23.74552 C119.496021,23.70064 120.151194,21.4804 120.952255,18.72952 L125.217507,18.72952 L125.915119,25.8364 C118.888594,27.328 118.713528,26.92672 119.496021,23.74552 L119.496021,23.74552 Z" fill="#242B2C" fill-rule="nonzero"/><path d="M1.03841146,23.8920635 L7.81508464,0 L18.2158138,0 L16.1119922,7.40740741 C16.0897554,7.44994435 16.0716695,7.49460291 16.0579948,7.54074074 L10.5357227,27.1005291 L15.6903971,27.1005291 C13.537424,32.5848325 11.8524284,36.8846561 10.6354102,40 C1.12771484,39.8920635 -1.53892578,32.9481481 0.795423177,24.7322751 L1.03841146,23.8920635 Z M10.672793,40 L23.2084961,21.6 L17.8897526,21.6 L22.5169141,9.81375661 C30.4586849,10.6603175 34.1824284,17.0285714 31.993457,24.7301587 C29.6424935,33.015873 20.1285677,40 10.8659375,40 L10.672793,40 Z" fill="url(#linearGradient-1)" fill-rule="nonzero"/></g></g></g></g></svg>
|
After Width: | Height: | Size: 4.4 KiB |
BIN
icons/fpPS4.ico
Before Width: | Height: | Size: 276 KiB After Width: | Height: | Size: 113 KiB |
BIN
icons/logo.png
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 99 KiB |
|
@ -93,11 +93,11 @@ type
|
|||
Function Alloc(Size,Align:QWORD;mtype:Byte;var AdrOut:QWORD):Integer;
|
||||
Function Query(Offset:QWORD;next:Boolean;var ROut:TDirectAdrNode):Integer;
|
||||
Function QueryMType(Offset:QWORD;var ROut:TDirectAdrNode):Integer;
|
||||
Function CheckedAvailable(ss,se,Align:QWORD;var AdrOut,SizeOut:QWORD):Integer;
|
||||
Function CheckedAlloc(Offset,Size:QWORD):Integer;
|
||||
Function CheckedMMap(Offset,Size:QWORD):Integer;
|
||||
Function CheckedRelease(Offset,Size:QWORD):Integer;
|
||||
Function Release(Offset,Size:QWORD;inher:Boolean):Integer;
|
||||
Function QueryAvailable(ss,se,Align:QWORD;var AdrOut,SizeOut:QWORD):Integer;
|
||||
Function CheckAlloc(Offset,Size:QWORD):Integer;
|
||||
Function CheckMMap(Offset,Size:QWORD):Integer;
|
||||
Function CheckRelease(Offset,Size:QWORD):Integer;
|
||||
Function Release(Offset,Size:QWORD):Integer;
|
||||
Function mmap_addr(Offset,Size:QWORD;addr:Pointer;mtype:Integer=-1):Integer;
|
||||
Function mmap_type(Offset,Size:QWORD;mtype:Integer):Integer;
|
||||
Function unmap_addr(Offset,Size:QWORD):Integer;
|
||||
|
@ -525,17 +525,26 @@ begin
|
|||
ROut:=key;
|
||||
end;
|
||||
|
||||
Function TDirectManager.CheckedAvailable(ss,se,Align:QWORD;var AdrOut,SizeOut:QWORD):Integer;
|
||||
Function TDirectManager.QueryAvailable(ss,se,Align:QWORD;var AdrOut,SizeOut:QWORD):Integer;
|
||||
var
|
||||
It:TFreePoolNodeSet.Iterator;
|
||||
key:TDirectAdrNode;
|
||||
Offset:QWORD;
|
||||
Size:QWORD;
|
||||
Size :QWORD;
|
||||
|
||||
r:record
|
||||
Offset:QWORD;
|
||||
Size :QWORD;
|
||||
end;
|
||||
begin
|
||||
Result:=ENOMEM;
|
||||
|
||||
if (ss<Flo) or (ss>Fhi) then Exit(EINVAL);
|
||||
if (se<Flo) or (se<ss) then Exit(EINVAL);
|
||||
|
||||
r.Size :=0;
|
||||
r.Offset:=0;
|
||||
|
||||
key:=Default(TDirectAdrNode);
|
||||
key.Offset:=ss;
|
||||
|
||||
|
@ -547,21 +556,31 @@ begin
|
|||
if key.IsFree then
|
||||
begin
|
||||
Offset:=System.Align(Max(key.Offset,ss),Align);
|
||||
|
||||
if (se>=Offset) then
|
||||
begin
|
||||
Size:=key.Size-(Offset-key.Offset);
|
||||
AdrOut :=Offset;
|
||||
SizeOut:=Size;
|
||||
Exit(0);
|
||||
|
||||
if (Size>r.Size) then
|
||||
begin
|
||||
r.Size :=Size;
|
||||
r.Offset:=Offset;
|
||||
end;
|
||||
|
||||
Result:=0; //mark
|
||||
end;
|
||||
end;
|
||||
|
||||
It.Next
|
||||
It.Next;
|
||||
end;
|
||||
|
||||
if (Result=0) then //found
|
||||
begin
|
||||
AdrOut :=r.Offset;
|
||||
SizeOut:=r.Size;
|
||||
end;
|
||||
end;
|
||||
|
||||
Function TDirectManager.CheckedAlloc(Offset,Size:QWORD):Integer;
|
||||
Function TDirectManager.CheckAlloc(Offset,Size:QWORD):Integer;
|
||||
var
|
||||
It:TAllcPoolNodeSet.Iterator;
|
||||
key:TDirectAdrNode;
|
||||
|
@ -595,7 +614,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
Function TDirectManager.CheckedMMap(Offset,Size:QWORD):Integer;
|
||||
Function TDirectManager.CheckMMap(Offset,Size:QWORD):Integer;
|
||||
var
|
||||
It:TAllcPoolNodeSet.Iterator;
|
||||
key:TDirectAdrNode;
|
||||
|
@ -633,7 +652,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
Function TDirectManager.CheckedRelease(Offset,Size:QWORD):Integer;
|
||||
Function TDirectManager.CheckRelease(Offset,Size:QWORD):Integer;
|
||||
var
|
||||
It:TAllcPoolNodeSet.Iterator;
|
||||
key:TDirectAdrNode;
|
||||
|
@ -664,7 +683,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
Function TDirectManager.Release(Offset,Size:QWORD;inher:Boolean):Integer;
|
||||
Function TDirectManager.Release(Offset,Size:QWORD):Integer;
|
||||
var
|
||||
key:TDirectAdrNode;
|
||||
FEndN,FEndO:QWORD;
|
||||
|
@ -744,13 +763,7 @@ begin
|
|||
|
||||
if _fetch then
|
||||
begin
|
||||
if inher then
|
||||
begin
|
||||
Result:=0;
|
||||
end else
|
||||
begin
|
||||
Result:=_UnmapVirtual(key.addr,key.Size);
|
||||
end;
|
||||
Result:=_UnmapVirtual(key.addr,key.Size);
|
||||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
|
|
|
@ -179,6 +179,7 @@ type
|
|||
|
||||
procedure _mmap_sys(Offset:Pointer;Size:QWORD);
|
||||
|
||||
Function check_mmaped(Offset:Pointer;Size:QWORD):Integer;
|
||||
Function check_fixed(Offset:Pointer;Size:QWORD;flags,fd:Integer):Integer;
|
||||
Function mmap(Offset:Pointer;Size,Align:QWORD;prot,flags,fd:Integer;addr:QWORD;var AdrOut:Pointer):Integer;
|
||||
|
||||
|
@ -233,6 +234,12 @@ begin
|
|||
if (err<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'_VirtualReserve(',HexStr(FOffset),',',HexStr(ASize,16),'):',err);
|
||||
if (err=ERROR_COMMITMENT_LIMIT) then
|
||||
begin
|
||||
Writeln(StdErr,'Please increase the size of the paging file in your'+#13#10+
|
||||
' OS settings or make it automatic,'+#13#10+
|
||||
' you need at least:',(ASize/(1024*1024)):0:2,'MB');
|
||||
end;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
@ -1258,6 +1265,49 @@ begin
|
|||
//Test;
|
||||
end;
|
||||
|
||||
Function TVirtualManager.check_mmaped(Offset:Pointer;Size:QWORD):Integer;
|
||||
var
|
||||
It:TAllcPoolNodeSet.Iterator;
|
||||
key:TVirtualAdrNode;
|
||||
tmp,FEndO:Pointer;
|
||||
begin
|
||||
Result:=0;
|
||||
if (Offset<Flo) or (Offset>Fhi) then Exit(ENOMEM);
|
||||
|
||||
tmp:=AlignDw(Offset,PHYSICAL_PAGE_SIZE);
|
||||
Size:=Size+(Offset-tmp);
|
||||
|
||||
Offset:=tmp;
|
||||
Size:=AlignUp(Size,PHYSICAL_PAGE_SIZE);
|
||||
|
||||
FEndO:=Offset+Size;
|
||||
|
||||
key:=Default(TVirtualAdrNode);
|
||||
key.Offset:=Offset;
|
||||
|
||||
It:=FAllcSet.find_le(key);
|
||||
While (It.Item<>nil) do
|
||||
begin
|
||||
key:=It.Item^;
|
||||
|
||||
if (Offset>=key.Offset) then
|
||||
begin
|
||||
if key.IsFree then
|
||||
begin
|
||||
Exit(ENOMEM);
|
||||
end else
|
||||
if (key.F.reserv<>0) then //reserved?
|
||||
begin
|
||||
Exit(ENOMEM);
|
||||
end;
|
||||
end;
|
||||
|
||||
if (key.Offset>=FEndO) then Break;
|
||||
|
||||
It.Next;
|
||||
end;
|
||||
end;
|
||||
|
||||
Function TVirtualManager.check_fixed(Offset:Pointer;Size:QWORD;flags,fd:Integer):Integer;
|
||||
var
|
||||
It:TAllcPoolNodeSet.Iterator;
|
||||
|
|
|
@ -259,7 +259,7 @@ function ps4_sceKernelCreateEventFlag(
|
|||
attr,init:QWORD;
|
||||
pOptParam:PSceKernelEventFlagOptParam):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln('sceKernelCreateEventFlag:',pName);
|
||||
Writeln(SysLogPrefix, 'sceKernelCreateEventFlag:',pName);
|
||||
|
||||
if (pOptParam<>nil) then
|
||||
begin
|
||||
|
@ -588,7 +588,7 @@ begin
|
|||
Result:=ef_enter(ef);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
//Writeln('sceKernelClearEventFlag:',HexStr(ef),':',ef^.name,':',HexStr(bitPattern,16),':',ThreadID);
|
||||
//Writeln(SysLogPrefix, 'sceKernelClearEventFlag:',HexStr(ef),':',ef^.name,':',HexStr(bitPattern,16),':',ThreadID);
|
||||
|
||||
spin_lock(ef^.lock_list);
|
||||
fetch_and(ef^.bitPattern,bitPattern);
|
||||
|
|
|
@ -14,6 +14,37 @@ uses
|
|||
Classes,
|
||||
SysUtils;
|
||||
|
||||
const
|
||||
SCE_KERNEL_AIO_DISABLE_SPLIT=0;
|
||||
SCE_KERNEL_AIO_ENABLE_SPLIT =1;
|
||||
|
||||
SCE_KERNEL_AIO_SCHED_WINDOW_MAX =128;
|
||||
SCE_KERNEL_AIO_DELAYED_COUNT_MAX =128;
|
||||
SCE_KERNEL_AIO_SPLIT_SIZE_MAX =$1000000;
|
||||
SCE_KERNEL_AIO_SPLIT_CHUNK_SIZE_MAX=$1000000;
|
||||
|
||||
SCE_KERNEL_AIO_SCHED_WINDOW_DEFAULT =32;
|
||||
SCE_KERNEL_AIO_DELAYED_COUNT_DEFAULT =32;
|
||||
SCE_KERNEL_AIO_SPLIT_SIZE_DEFAULT =$100000;
|
||||
SCE_KERNEL_AIO_SPLIT_CHUNK_SIZE_DEFAULT=$100000;
|
||||
|
||||
type
|
||||
pSceKernelAioSchedulingParam=^SceKernelAioSchedulingParam;
|
||||
SceKernelAioSchedulingParam=packed record
|
||||
schedulingWindowSize:Integer;
|
||||
delayedCountLimit :Integer;
|
||||
enableSplit :DWORD;
|
||||
splitSize :DWORD;
|
||||
splitChunkSize :DWORD;
|
||||
end;
|
||||
|
||||
pSceKernelAioParam=^SceKernelAioParam;
|
||||
SceKernelAioParam=packed record
|
||||
low :SceKernelAioSchedulingParam;
|
||||
mid :SceKernelAioSchedulingParam;
|
||||
high:SceKernelAioSchedulingParam;
|
||||
end;
|
||||
|
||||
function ps4_open(path:PChar;flags,mode:Integer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelOpen(path:PChar;flags,mode:Integer):Integer; SysV_ABI_CDecl;
|
||||
|
||||
|
@ -32,12 +63,18 @@ function ps4_sceKernelPread(fd:Integer;buf:Pointer;nbytes,offset:Int64):Int64; S
|
|||
function ps4_readv(fd:Integer;vector:p_iovec;count:Integer):Int64; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelReadv(fd:Integer;iov:p_iovec;iovcnt:Integer):Int64; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_preadv(fd:Integer;vector:p_iovec;count:Integer;offset:Int64):Int64; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelPreadv(fd:Integer;iov:p_iovec;iovcnt:Integer;offset:Int64):Int64; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_write(fd:Integer;data:Pointer;size:Int64):Int64; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelWrite(fd:Integer;buf:Pointer;nbytes:Int64):Int64; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pwrite(fd:Integer;data:Pointer;size,offset:Int64):Int64; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelPwrite(fd:Integer;buf:Pointer;nbytes,offset:Int64):Int64; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_writev(fd:Integer;vector:p_iovec;count:Integer):Int64; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelWritev(fd:Integer;iov:p_iovec;iovcnt:Integer):Int64; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_ftruncate(fd:Integer;size:Int64):Integer; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelFtruncate(fd:Integer;size:Int64):Integer; SysV_ABI_CDecl;
|
||||
|
||||
|
@ -47,17 +84,22 @@ function ps4_sceKernelFstat(fd:Integer;stat:PSceKernelStat):Integer; SysV_ABI_CD
|
|||
function ps4_getdirentries(fd:Integer;buf:Pointer;nbytes:Int64;basep:PInt64):Int64; SysV_ABI_CDecl;
|
||||
function ps4_getdents(fd:Integer;buf:Pointer;nbytes:Int64):Int64; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelGetdirentries(fd:Integer;buf:Pointer;nbytes:Int64;basep:PInt64):Int64; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelGetdents(fd:Integer;buf:Pointer;nbytes:Int64):Int64; SysV_ABI_CDecl
|
||||
;
|
||||
function ps4_sceKernelGetdents(fd:Integer;buf:Pointer;nbytes:Int64):Int64; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_fsync(fd:Integer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelFsync(fd:Integer):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_fcntl(fd,cmd:Integer;param1:ptruint):Integer; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelFcntl(fd,cmd:Integer;param1:ptruint):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_ioctl(fd,cmd:Integer;param1:ptruint):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_stat(path:PChar;stat:PSceKernelStat):Integer; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelStat(path:PChar;stat:PSceKernelStat):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_truncate(path:PChar;length:Int64):Integer; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelTruncate(path:PChar;length:Int64):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_mkdir(path:PChar;mode:Integer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelMkdir(path:PChar;mode:Integer):Integer; SysV_ABI_CDecl;
|
||||
|
||||
|
@ -70,6 +112,9 @@ function ps4_sceKernelRmdir(path:PChar):Integer; SysV_ABI_CDecl;
|
|||
function ps4_rename(from,pto:PChar):Integer; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelRename(from,pto:PChar):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_chmod(path:PChar;mode:Integer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelChmod(path:PChar;mode:Integer):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_sceKernelCheckReachability(path:PChar):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_access(path:PChar;mode:Integer):Integer; SysV_ABI_CDecl;
|
||||
|
@ -77,6 +122,8 @@ function ps4_access(path:PChar;mode:Integer):Integer; SysV_ABI_CDecl;
|
|||
function ps4_getdtablesize:Integer; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelGetFsSandboxRandomWord:PChar; SysV_ABI_CDecl;
|
||||
|
||||
procedure ps4_sceKernelAioInitializeParam(param:pSceKernelAioParam); SysV_ABI_CDecl;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
|
@ -93,7 +140,7 @@ begin
|
|||
Result:=0;
|
||||
if (path=nil) then Exit(-EINVAL);
|
||||
|
||||
Writeln('open:',path,' ',flags,' (',OctStr(mode,3),')');
|
||||
Writeln(SysLogPrefix, 'open:',path,' 0x',HexStr(flags,4),' (',OctStr(mode,3),')');
|
||||
|
||||
if ((flags and WR_RDWR)=WR_RDWR) then
|
||||
begin
|
||||
|
@ -314,6 +361,38 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function ps4_preadv(fd:Integer;vector:p_iovec;count:Integer;offset:Int64):Int64; SysV_ABI_CDecl;
|
||||
begin
|
||||
_sig_lock;
|
||||
Result:=_sys_preadv(fd,vector,count,offset);
|
||||
_sig_unlock;
|
||||
|
||||
if (Result<0) then
|
||||
begin
|
||||
Result:=_set_errno(-Result);
|
||||
end else
|
||||
begin
|
||||
_set_errno(0);
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_sceKernelPreadv(fd:Integer;iov:p_iovec;iovcnt:Integer;offset:Int64):Int64; SysV_ABI_CDecl;
|
||||
begin
|
||||
_sig_lock;
|
||||
Result:=_sys_preadv(fd,iov,iovcnt,offset);
|
||||
_sig_unlock;
|
||||
|
||||
if (Result<0) then
|
||||
begin
|
||||
Result:=-Result;
|
||||
_set_errno(Result);
|
||||
Result:=px2sce(Result);
|
||||
end else
|
||||
begin
|
||||
_set_errno(0);
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_write(fd:Integer;data:Pointer;size:Int64):Int64; SysV_ABI_CDecl;
|
||||
begin
|
||||
_sig_lock;
|
||||
|
@ -378,6 +457,38 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function ps4_writev(fd:Integer;vector:p_iovec;count:Integer):Int64; SysV_ABI_CDecl;
|
||||
begin
|
||||
_sig_lock;
|
||||
Result:=_sys_writev(fd,vector,count);
|
||||
_sig_unlock;
|
||||
|
||||
if (Result<0) then
|
||||
begin
|
||||
Result:=_set_errno(-Result);
|
||||
end else
|
||||
begin
|
||||
_set_errno(0);
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_sceKernelWritev(fd:Integer;iov:p_iovec;iovcnt:Integer):Int64; SysV_ABI_CDecl;
|
||||
begin
|
||||
_sig_lock;
|
||||
Result:=_sys_writev(fd,iov,iovcnt);
|
||||
_sig_unlock;
|
||||
|
||||
if (Result<0) then
|
||||
begin
|
||||
Result:=-Result;
|
||||
_set_errno(Result);
|
||||
Result:=px2sce(Result);
|
||||
end else
|
||||
begin
|
||||
_set_errno(0);
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_ftruncate(fd:Integer;size:Int64):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
_sig_lock;
|
||||
|
@ -510,6 +621,13 @@ begin
|
|||
Result:=px2sce(Result);
|
||||
end;
|
||||
|
||||
function ps4_ioctl(fd,cmd:Integer;param1:ptruint):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
_sig_lock;
|
||||
Result:=_set_errno(_sys_ioctl(fd,cmd,param1));
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
function _sys_stat(path:PChar;stat:PSceKernelStat):Integer;
|
||||
var
|
||||
rp:RawByteString;
|
||||
|
@ -569,6 +687,65 @@ begin
|
|||
Result:=px2sce(Result);
|
||||
end;
|
||||
|
||||
function _sys_truncate(path:PChar;length:Int64):Integer;
|
||||
var
|
||||
fn:RawByteString;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
if (path=nil) then Exit(EINVAL);
|
||||
if (length<=0) then Exit(EINVAL);
|
||||
|
||||
if (path[0]=#0) then
|
||||
begin
|
||||
Exit(ENOENT);
|
||||
end;
|
||||
|
||||
Writeln(SysLogPrefix,'truncate:',path,' ',length);
|
||||
|
||||
fn:='';
|
||||
Result:=parse_filename(path,fn);
|
||||
|
||||
Case Result of
|
||||
PT_ROOT:Exit(EACCES); //TODO
|
||||
PT_FILE:;
|
||||
PT_DEV :Exit(EACCES);
|
||||
else
|
||||
Exit(EACCES);
|
||||
end;
|
||||
|
||||
if FileExists(fn) then
|
||||
begin
|
||||
Result:=_sys_file_trunc(fn,length);
|
||||
end else
|
||||
begin
|
||||
if DirectoryExists(fn) then
|
||||
begin
|
||||
Result:=EISDIR;
|
||||
end else
|
||||
begin
|
||||
Result:=ENOENT;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_truncate(path:PChar;length:Int64):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
_sig_lock;
|
||||
Result:=_set_errno(_sys_truncate(path,length));
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
function ps4_sceKernelTruncate(path:PChar;length:Int64):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
_sig_lock;
|
||||
Result:=_sys_truncate(path,length);
|
||||
_sig_unlock;
|
||||
|
||||
_set_errno(Result);
|
||||
Result:=px2sce(Result);
|
||||
end;
|
||||
|
||||
function _sys_mkdir(path:PChar;mode:Integer):Integer;
|
||||
var
|
||||
fn:RawByteString;
|
||||
|
@ -956,6 +1133,58 @@ begin
|
|||
Result:=px2sce(Result);
|
||||
end;
|
||||
|
||||
function _sys_chmod(path:PChar;mode:Integer):Integer;
|
||||
var
|
||||
fn:RawByteString;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
if (path=nil) then Exit(EINVAL);
|
||||
|
||||
if (path[0]=#0) then
|
||||
begin
|
||||
Exit(ENOENT);
|
||||
end;
|
||||
|
||||
Writeln(SysLogPrefix,'chmod:',path,' (',OctStr(mode,3),')');
|
||||
|
||||
fn:='';
|
||||
Result:=parse_filename(path,fn);
|
||||
|
||||
Case Result of
|
||||
PT_ROOT:Exit(EACCES); //TODO
|
||||
PT_FILE:;
|
||||
PT_DEV :Exit(EACCES);
|
||||
else
|
||||
Exit(EACCES);
|
||||
end;
|
||||
|
||||
if FileExists(fn) or DirectoryExists(fn) then
|
||||
begin
|
||||
Result:=0;
|
||||
end else
|
||||
begin
|
||||
Result:=ENOENT;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_chmod(path:PChar;mode:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
_sig_lock;
|
||||
Result:=_set_errno(_sys_chmod(path,mode));
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
function ps4_sceKernelChmod(path:PChar;mode:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
_sig_lock;
|
||||
Result:=_sys_chmod(path,mode);
|
||||
_sig_unlock;
|
||||
|
||||
_set_errno(Result);
|
||||
Result:=px2sce(Result);
|
||||
end;
|
||||
|
||||
function ps4_sceKernelCheckReachability(path:PChar):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
fn:RawByteString;
|
||||
|
@ -1016,6 +1245,8 @@ begin
|
|||
|
||||
if (path=nil) then Exit(EFAULT);
|
||||
|
||||
//Writeln('access:',path,' ',mode);
|
||||
|
||||
if (path[0]=#0) then
|
||||
begin
|
||||
Exit(ENOENT);
|
||||
|
@ -1069,5 +1300,24 @@ begin
|
|||
Result:=fs_word;
|
||||
end;
|
||||
|
||||
procedure ps4_sceKernelAioInitializeParam(param:pSceKernelAioParam); SysV_ABI_CDecl;
|
||||
begin
|
||||
param^.low.schedulingWindowSize :=$20;
|
||||
param^.low.delayedCountLimit :=$20;
|
||||
param^.low.enableSplit :=1;
|
||||
param^.low.splitSize :=$100000;
|
||||
param^.low.splitChunkSize :=$100000;
|
||||
param^.mid.schedulingWindowSize :=$20;
|
||||
param^.mid.delayedCountLimit :=$20;
|
||||
param^.mid.enableSplit :=1;
|
||||
param^.mid.splitSize :=$100000;
|
||||
param^.mid.splitChunkSize :=$100000;
|
||||
param^.high.schedulingWindowSize:=$20;
|
||||
param^.high.delayedCountLimit :=$20;
|
||||
param^.high.enableSplit :=0;
|
||||
param^.high.splitSize :=0;
|
||||
param^.high.splitChunkSize :=0;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ uses
|
|||
ps4_map_mm,
|
||||
ps4_mspace_internal,
|
||||
ps4_pthread,
|
||||
ps4_pthread_attr,
|
||||
ps4_pthread_key,
|
||||
ps4_signal,
|
||||
ps4_mutex,
|
||||
|
@ -22,6 +23,7 @@ uses
|
|||
ps4_kernel_file,
|
||||
ps4_queue,
|
||||
ps4_event_flag,
|
||||
ps4_scesocket,
|
||||
ps4_elf,
|
||||
ps4_program,
|
||||
|
||||
|
@ -42,10 +44,19 @@ function ps4_sceKernelGetModuleInfoFromAddr(Addr:Pointer;flags:DWORD;info:pSceK
|
|||
function ps4___elf_phdr_match_addr(phdr_info:pSceKernelModuleInfoEx;addr:Pointer):Integer; SysV_ABI_CDecl;
|
||||
procedure ps4___pthread_cxa_finalize(phdr_info:pSceKernelModuleInfoEx); SysV_ABI_CDecl;
|
||||
|
||||
const
|
||||
__progname:PChar='eboot.bin'; //argv[0]
|
||||
|
||||
g_argv:array[0..1] of PChar=('eboot.bin',nil);
|
||||
|
||||
_env:array[0..2] of PChar=('HOME=/','PWD=/',nil);
|
||||
environ:PPchar=@_env;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
atomic,
|
||||
sys_crt,
|
||||
sys_path,
|
||||
sys_kernel,
|
||||
sys_pthread,
|
||||
|
@ -84,7 +95,9 @@ Const
|
|||
procedure ps4_stack_chk_fail; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln(StdErr,GetCurrentThreadId,':Stack overflow detected! Aborting program.');
|
||||
DebugBreak;
|
||||
asm
|
||||
ud2
|
||||
end;
|
||||
end;
|
||||
|
||||
{$I StopNotificationReason.inc}
|
||||
|
@ -93,7 +106,9 @@ end;
|
|||
procedure ps4_sceKernelDebugRaiseException(dwStopReason,dwStopId:DWORD); SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln(StdErr,'RaiseException:',HexStr(dwStopReason,8),':',HexStr(dwStopId,8),':',GetStopReasonInfo(dwStopReason));
|
||||
DebugBreak;
|
||||
asm
|
||||
ud2
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure ps4_sceKernelDebugRaiseExceptionOnReleaseMode(dwStopReason,dwStopId:DWORD); SysV_ABI_CDecl;
|
||||
|
@ -103,7 +118,7 @@ end;
|
|||
|
||||
procedure ps4_sceKernelDebugOutText(dbg_id:Integer;text:Pchar); SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln(text);
|
||||
Writeln('[DBG]:',text);
|
||||
end;
|
||||
|
||||
//ps4 neo mode is support? (Ps4 Pro)
|
||||
|
@ -166,6 +181,25 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function ps4_sceKernelGetModuleInfoInternal(handle:Integer;info:pSceKernelModuleInfoEx):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
node:TElf_node;
|
||||
begin
|
||||
if (info=nil) then Exit(SCE_KERNEL_ERROR_EFAULT);
|
||||
_sig_lock;
|
||||
Writeln('sceKernelGetModuleInfoInternal:',handle,':',HexStr(info));
|
||||
node:=ps4_app.AcqureFileByHandle(handle);
|
||||
if (node=nil) then
|
||||
begin
|
||||
_sig_unlock;
|
||||
Exit(SCE_KERNEL_ERROR_ESRCH);
|
||||
end;
|
||||
info^:=node.GetModuleInfoEx;
|
||||
node.Release;
|
||||
_sig_unlock;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceKernelGetModuleInfo(handle:Integer;info:pSceKernelModuleInfo):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
node:TElf_node;
|
||||
|
@ -177,7 +211,7 @@ begin
|
|||
if (node=nil) then
|
||||
begin
|
||||
_sig_unlock;
|
||||
Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
Exit(SCE_KERNEL_ERROR_ESRCH);
|
||||
end;
|
||||
info^:=node.GetModuleInfo;
|
||||
node.Release;
|
||||
|
@ -185,6 +219,32 @@ begin
|
|||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceKernelGetModuleInfo2(handle:Integer;info:pSceKernelModuleInfo):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
node:TElf_node;
|
||||
begin
|
||||
Result:=0;
|
||||
//Almost the same sceKernelGetModuleInfo
|
||||
if (info=nil) then Exit(SCE_KERNEL_ERROR_EFAULT);
|
||||
_sig_lock;
|
||||
Writeln('sceKernelGetModuleInfo2:',handle,':',HexStr(info));
|
||||
node:=ps4_app.AcqureFileByHandle(handle);
|
||||
if (node=nil) then
|
||||
begin
|
||||
_sig_unlock;
|
||||
Exit(SCE_KERNEL_ERROR_ESRCH);
|
||||
end;
|
||||
info^:=node.GetModuleInfo;
|
||||
|
||||
if (info^.segmentCount=0) then
|
||||
begin
|
||||
Result:=SCE_KERNEL_ERROR_EPERM;
|
||||
end;
|
||||
|
||||
node.Release;
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
function ps4_sceKernelGetModuleInfoForUnwind(addr:Pointer;flags:DWORD;info:pSceModuleInfoForUnwind):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
node:TElf_node;
|
||||
|
@ -417,10 +477,12 @@ begin
|
|||
Result:=SCE_KERNEL_ERROR_EINVAL;
|
||||
end;
|
||||
|
||||
//get sdk version of game
|
||||
function ps4_sceKernelGetCompiledSdkVersion(sdkVersion:PDWORD):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
P:PSceProcParam;
|
||||
begin
|
||||
//sys_dynlib_get_proc_param
|
||||
Result:=SCE_KERNEL_ERROR_EINVAL;
|
||||
if (sdkVersion=nil) then Exit;
|
||||
P:=GetSceProcParam;
|
||||
|
@ -435,6 +497,31 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
type
|
||||
p_sw_version=^t_sw_version;
|
||||
t_sw_version=packed record
|
||||
size :QWORD; //(40)
|
||||
str :array[0..27] of Char;
|
||||
version:DWORD;
|
||||
end;
|
||||
|
||||
//get sdk version of system
|
||||
function ps4_sceKernelGetSystemSwVersion(p:p_sw_version):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
version:DWORD;
|
||||
begin
|
||||
//sysctlbyname:kern.sdk_version
|
||||
version:=$10508001; //10.50
|
||||
ps4_sceKernelGetCompiledSdkVersion(@version); //mirror of game version?
|
||||
|
||||
p^.version:=version;
|
||||
p^.str:=Format('%2x.%03x.%03x',[(version shr 24),
|
||||
((version shr 12) and $fff),
|
||||
(version and $fff)]);
|
||||
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
const
|
||||
//eLoadOptions
|
||||
LOAD_OPTIONS_DEFAULT =$0000;
|
||||
|
@ -457,7 +544,7 @@ type
|
|||
unk4:array[0.. 6] of Byte; //7
|
||||
end;
|
||||
|
||||
//sysctl to KERN_PROC_ENV
|
||||
//sysctl to CTL_KERN(1).KERN_PROC(14).KERN_PROC_APPINFO(35)
|
||||
function ps4_sceKernelGetAppInfo(pid:Integer;env:PSCE_APP_ENV):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
//ignore pid
|
||||
|
@ -520,6 +607,52 @@ begin
|
|||
Result:=0;
|
||||
end;
|
||||
|
||||
function _sysctlbyname(name :PChar;
|
||||
oldp :Pointer;
|
||||
oldlenp:Pptruint;
|
||||
newp :Pointer;
|
||||
newlen :ptruint
|
||||
):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
Case RawByteString(name) of
|
||||
'':Result:=EINVAL;
|
||||
|
||||
'kern.rng_pseudo':
|
||||
begin
|
||||
if (oldlenp=nil) then Exit(EFAULT);
|
||||
|
||||
Result:=BCryptGenRandom(nil,oldp,oldlenp^,BCRYPT_USE_SYSTEM_PREFERRED_RNG);
|
||||
if (Result<>0) then Result:=EFAULT;
|
||||
end;
|
||||
else
|
||||
begin
|
||||
Writeln(StdErr,'TODO sysctlbyname:',name);
|
||||
Assert(False);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_sysctlbyname(name :PChar;
|
||||
oldp :Pointer;
|
||||
oldlenp:Pptruint;
|
||||
newp :Pointer;
|
||||
newlen :ptruint
|
||||
):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
_sig_lock;
|
||||
Result:=_set_errno(_sysctlbyname(name,oldp,oldlenp,newp,newlen));
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
//SetFanThreshold
|
||||
function ps4_gpgi_GwE2Is(param:PByte):Integer; SysV_ABI_CDecl; //gpgi-GwE2Is
|
||||
begin
|
||||
Writeln('SetFanThreshold:',param[5]);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
//dynlib_get_obj_member(handle,8,&ptr); module param
|
||||
//dynlib_get_obj_member(handle,1,&ptr); init
|
||||
//dynlib_get_obj_member(handle,2,&ptr); fini
|
||||
|
@ -551,7 +684,7 @@ begin
|
|||
node:=ps4_app.AcqureFileByName(ExtractFileName(fn));
|
||||
if (node<>nil) then
|
||||
begin
|
||||
Writeln('File Loaded:',ExtractFileName(fn));
|
||||
Writeln(StdWrn,'File Loaded:',ExtractFileName(fn));
|
||||
|
||||
Result:=node.Handle;
|
||||
node.Release;
|
||||
|
@ -618,6 +751,25 @@ begin
|
|||
_sig_unlock;
|
||||
end;
|
||||
|
||||
function ps4_sceKernelLoadStartModuleForSysmodule(moduleFileName:Pchar;
|
||||
argc:size_t;
|
||||
argp:PPointer;
|
||||
flags:DWORD;
|
||||
pOpt:PSceKernelLoadModuleOpt;
|
||||
pRes:PInteger):SceKernelModule; SysV_ABI_CDecl;
|
||||
begin
|
||||
_sig_lock;
|
||||
|
||||
Result:=_sceKernelLoadStartModule(moduleFileName,
|
||||
argc,
|
||||
argp,
|
||||
flags or $10000,
|
||||
pOpt,
|
||||
pRes);
|
||||
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
Function ps4_sceKernelDlsym(handle:Integer;symbol:PChar;addrp:PPointer):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
node:TElf_node;
|
||||
|
@ -651,7 +803,7 @@ begin
|
|||
_sig_unlock;
|
||||
end;
|
||||
|
||||
Function ps4_sceKernelGetModuleList(list:PInteger;numArray:QWORD;actualNum:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
Function GetModuleList(list:PInteger;numArray:QWORD;actualNum:PQWORD):Integer;
|
||||
var
|
||||
i:QWORD;
|
||||
node:TElf_node;
|
||||
|
@ -680,8 +832,29 @@ begin
|
|||
|
||||
actualNum^:=i;
|
||||
if (i>numArray) then Result:=SCE_KERNEL_ERROR_ENOMEM;
|
||||
end;
|
||||
|
||||
Writeln('sceKernelGetModuleList:',HexStr(list),' ',numArray,' ',i);
|
||||
Function ps4_sceKernelGetModuleList(list:PInteger;numArray:QWORD;actualNum:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=GetModuleList(list,numArray,actualNum);
|
||||
|
||||
Writeln('sceKernelGetModuleList:',HexStr(list),' ',numArray);
|
||||
end;
|
||||
|
||||
Function ps4_sceKernelGetModuleList2(list:PInteger;numArray:QWORD;actualNum:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
//alias?
|
||||
Result:=GetModuleList(list,numArray,actualNum);
|
||||
|
||||
Writeln('sceKernelGetModuleList2:',HexStr(list),' ',numArray);
|
||||
end;
|
||||
|
||||
Function ps4_sceKernelGetModuleListInternal(list:PInteger;numArray:QWORD;actualNum:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
//alias?
|
||||
Result:=GetModuleList(list,numArray,actualNum);
|
||||
|
||||
Writeln('sceKernelGetModuleListInternal:',HexStr(list),' ',numArray);
|
||||
end;
|
||||
|
||||
const
|
||||
|
@ -708,6 +881,23 @@ begin
|
|||
Result:=0;
|
||||
end;
|
||||
|
||||
procedure ps4_sceKernelSetGPO(uiBits:DWORD); SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln('sceKernelSetGPO:',BinStr(uiBits,8));
|
||||
end;
|
||||
|
||||
function ps4_sceKernelGetGPI:QWORD; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceKernelGetCpuTemperature(temp:PDWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (temp=nil) then Exit(_set_errno(EINVAL));
|
||||
temp^:=36;
|
||||
Result:=_set_errno(0);
|
||||
end;
|
||||
|
||||
const
|
||||
RUSAGE_SELF = 0;
|
||||
RUSAGE_CHILDREN=-1;
|
||||
|
@ -812,9 +1002,6 @@ begin
|
|||
Result:=1;
|
||||
end;
|
||||
|
||||
const
|
||||
g_argv:array[0..1] of PChar=('eboot.bin',nil);
|
||||
|
||||
function ps4_getargv:PPChar; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=@g_argv;
|
||||
|
@ -854,6 +1041,213 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function GetCurrentHwGUID(var g:TGUID):Boolean;
|
||||
var
|
||||
HW:HW_PROFILE_INFOA;
|
||||
begin
|
||||
HW:=Default(HW_PROFILE_INFOA);
|
||||
Result:=GetCurrentHwProfileA(@HW);
|
||||
if Result then
|
||||
begin
|
||||
Result:=TryStringToGUID(HW.szHwProfileGuid,g);
|
||||
end;
|
||||
end;
|
||||
|
||||
type
|
||||
pSceKernelOpenPsId=^SceKernelOpenPsId;
|
||||
SceKernelOpenPsId=array[0..15] of Byte;
|
||||
|
||||
function ps4_sceKernelGetOpenPsId(id:pSceKernelOpenPsId):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
g:TGUID;
|
||||
begin
|
||||
//sysctlbyname:machdep.openpsid
|
||||
if (id=nil) then Exit(EINVAL);
|
||||
|
||||
g:=Default(TGUID);
|
||||
if GetCurrentHwGUID(g) then
|
||||
begin
|
||||
id^:=SceKernelOpenPsId(g);
|
||||
end else
|
||||
begin
|
||||
id^:=Default(SceKernelOpenPsId);
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_sceKernelGetOpenPsIdForSystem(id:pSceKernelOpenPsId):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
g:TGUID;
|
||||
begin
|
||||
//sysctlbyname:machdep.openpsid_for_sys
|
||||
if (id=nil) then Exit(EINVAL);
|
||||
|
||||
g:=Default(TGUID);
|
||||
if GetCurrentHwGUID(g) then
|
||||
begin
|
||||
id^:=SceKernelOpenPsId(g);
|
||||
end else
|
||||
begin
|
||||
id^:=Default(SceKernelOpenPsId);
|
||||
end;
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
const
|
||||
AF_INET = 2;
|
||||
AF_INET6=28;
|
||||
|
||||
function inet_ntop4(src,dst:PChar;size:Integer):PChar; SysV_ABI_CDecl;
|
||||
var
|
||||
S:RawByteString;
|
||||
begin
|
||||
S:=Format('%u.%u.%u.%u',[src[0], src[1], src[2], src[3]]);
|
||||
|
||||
if (Length(S)<=0) or (Length(S)>=size) then
|
||||
begin
|
||||
Exit(nil);
|
||||
end;
|
||||
|
||||
strlcopy(dst,PChar(S),Length(S));
|
||||
Exit(dst);
|
||||
end;
|
||||
|
||||
function inet_ntop6(src,dst:PChar;size:Integer):PChar; SysV_ABI_CDecl;
|
||||
const
|
||||
NS_IN6ADDRSZ=16;
|
||||
NS_INT16SZ =2;
|
||||
type
|
||||
t_cur=record
|
||||
base,len:Integer;
|
||||
end;
|
||||
var
|
||||
tp:PChar;
|
||||
tmp,s:RawByteString;
|
||||
best,cur:t_cur;
|
||||
words:array[0..(NS_IN6ADDRSZ div NS_INT16SZ)-1] of DWORD;
|
||||
i:Integer;
|
||||
begin
|
||||
FillChar(words,sizeof(words),0);
|
||||
|
||||
for i:=0 to NS_IN6ADDRSZ-1 do
|
||||
begin
|
||||
words[i div 2]:=words[i div 2] or (Byte(src[i]) shl ((1 - (i mod 2)) shl 3));
|
||||
end;
|
||||
|
||||
best.base:=-1;
|
||||
best.len :=0;
|
||||
cur.base :=-1;
|
||||
cur.len :=0;
|
||||
|
||||
for i:=0 to (NS_IN6ADDRSZ div NS_INT16SZ)-1 do
|
||||
begin
|
||||
if (words[i]=0) then
|
||||
begin
|
||||
if (cur.base=-1) then
|
||||
begin
|
||||
cur.base:=i;
|
||||
cur.len :=1;
|
||||
end else
|
||||
begin
|
||||
Inc(cur.len);
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
if (cur.base<>-1) then
|
||||
begin
|
||||
if (best.base=-1) or (cur.len > best.len) then
|
||||
begin
|
||||
best:=cur;
|
||||
end;
|
||||
cur.base:=-1;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
if (cur.base<>-1) then
|
||||
begin
|
||||
if (best.base=-1) or (cur.len > best.len) then
|
||||
begin
|
||||
best:=cur;
|
||||
end;
|
||||
end else
|
||||
if (best.base<>-1) and (best.len < 2) then
|
||||
begin
|
||||
best.base:=-1;
|
||||
end;
|
||||
|
||||
tmp:='ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255';
|
||||
tp:=PChar(tmp);
|
||||
|
||||
for i:=0 to (NS_IN6ADDRSZ div NS_INT16SZ)-1 do
|
||||
begin
|
||||
if (best.base<>-1) and
|
||||
(i >= best.base) and
|
||||
(i < (best.base + best.len)) then
|
||||
begin
|
||||
if (i=best.base) then
|
||||
begin
|
||||
tp^:=':';
|
||||
Inc(tp);
|
||||
end;
|
||||
continue;
|
||||
end;
|
||||
|
||||
if (i<>0) then
|
||||
begin
|
||||
tp^:=':';
|
||||
Inc(tp);
|
||||
end;
|
||||
|
||||
if (i=6) and
|
||||
(best.base=0) and
|
||||
(
|
||||
(best.len=6) or
|
||||
((best.len=7) and (words[7]<>$0001)) or
|
||||
((best.len=5) and (words[5]=$ffff))
|
||||
) then
|
||||
begin
|
||||
if (inet_ntop4(src+12, tp, Length(tmp) - (tp - PChar(tmp)) )=nil) then
|
||||
begin
|
||||
Exit(nil);
|
||||
end;
|
||||
tp:=tp+strlen(tp);
|
||||
break;
|
||||
end;
|
||||
s:=Format('%x',[words[i]]);
|
||||
Move(PChar(s)^,PChar(tp)^,Length(s));
|
||||
tp:=tp+Length(s);
|
||||
end;
|
||||
|
||||
if (best.base<>-1) and
|
||||
((best.base + best.len)=(NS_IN6ADDRSZ div NS_INT16SZ)) then
|
||||
begin
|
||||
tp^:=':';
|
||||
Inc(tp);
|
||||
end;
|
||||
|
||||
tp:=#0;
|
||||
Inc(tp);
|
||||
|
||||
if ((tp - PChar(tmp)) > size) then
|
||||
begin
|
||||
Exit(nil);
|
||||
end;
|
||||
|
||||
strcopy(dst, PChar(tmp));
|
||||
Exit(dst);
|
||||
end;
|
||||
|
||||
function ps4_inet_ntop(af:Integer;src,dst:PChar;size:Integer):PChar; SysV_ABI_CDecl;
|
||||
begin
|
||||
case af of
|
||||
AF_INET :Exit(inet_ntop4(src, dst, size));
|
||||
AF_INET6:Exit(inet_ntop6(src, dst, size));
|
||||
else
|
||||
Exit(nil);
|
||||
end;
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
{$I libsysmodule.inc}
|
||||
|
@ -863,7 +1257,7 @@ begin
|
|||
if (Word(id)=0) then Exit(SCE_SYSMODULE_ERROR_INVALID_VALUE);
|
||||
if ((Word(id)=$80) and (SDK_VERSION>=$3000000)) then Exit(SCE_SYSMODULE_ERROR_INVALID_VALUE);
|
||||
|
||||
Writeln('sceSysmoduleLoadModule:',GetSysmoduleName(id));
|
||||
Writeln(SysLogPrefix, 'sceSysmoduleLoadModule:',GetSysmoduleName(id));
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
|
@ -871,7 +1265,7 @@ function ps4_sceSysmoduleUnloadModule(id:DWord):Integer; SysV_ABI_CDecl;
|
|||
begin
|
||||
if (Word(id)=0) then Exit(SCE_SYSMODULE_ERROR_INVALID_VALUE);
|
||||
|
||||
Writeln('sceSysmoduleUnloadModule:',GetSysmoduleName(id));
|
||||
Writeln(SysLogPrefix, 'sceSysmoduleUnloadModule:',GetSysmoduleName(id));
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
|
@ -879,7 +1273,7 @@ function ps4_sceSysmoduleIsLoaded(id:DWord):Integer; SysV_ABI_CDecl;
|
|||
begin
|
||||
if (Word(id)=0) then Exit(SCE_SYSMODULE_ERROR_INVALID_VALUE);
|
||||
|
||||
Writeln('sceSysmoduleIsLoaded:',GetSysmoduleName(id));
|
||||
Writeln(SysLogPrefix, 'sceSysmoduleIsLoaded:',GetSysmoduleName(id));
|
||||
Result:=0; //0 -> loaded ; SCE_SYSMODULE_ERROR_UNLOADED -> not loaded
|
||||
end;
|
||||
|
||||
|
@ -889,7 +1283,7 @@ function ps4_sceSysmoduleIsLoadedInternal(id:DWord):Integer; SysV_ABI_CDecl;
|
|||
begin
|
||||
if ((id or $80000000)=$80000000) then Exit(SCE_SYSMODULE_ERROR_INVALID_VALUE);
|
||||
|
||||
Writeln('sceSysmoduleIsLoadedInternal:',GetSysmoduleInternalName(id));
|
||||
Writeln(SysLogPrefix, 'sceSysmoduleIsLoadedInternal:',GetSysmoduleInternalName(id));
|
||||
Result:=0; //0 -> loaded ; SCE_SYSMODULE_ERROR_UNLOADED -> not loaded
|
||||
end;
|
||||
|
||||
|
@ -898,7 +1292,7 @@ begin
|
|||
if ((id or $80000000)=$80000000) then Exit(SCE_SYSMODULE_ERROR_INVALID_VALUE);
|
||||
if ((Word(id)=$80) and (SDK_VERSION>=$3000000)) then Exit(SCE_SYSMODULE_ERROR_INVALID_VALUE);
|
||||
|
||||
Writeln('sceSysmoduleLoadModuleInternal:',GetSysmoduleInternalName(id));
|
||||
Writeln(SysLogPrefix, 'sceSysmoduleLoadModuleInternal:',GetSysmoduleInternalName(id));
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
|
@ -911,7 +1305,7 @@ begin
|
|||
if ((id or $80000000)=$80000000) or (flags<>0) then Exit(SCE_SYSMODULE_ERROR_INVALID_VALUE);
|
||||
if ((Word(id)=$80) and (SDK_VERSION>=$3000000)) then Exit(SCE_SYSMODULE_ERROR_INVALID_VALUE);
|
||||
|
||||
Writeln('sceSysmoduleLoadModuleInternalWithArg:',GetSysmoduleInternalName(id));
|
||||
Writeln(SysLogPrefix, 'sceSysmoduleLoadModuleInternalWithArg:',GetSysmoduleInternalName(id));
|
||||
if (pRes<>nil) then pRes^:=0;
|
||||
Result:=0;
|
||||
end;
|
||||
|
@ -920,7 +1314,7 @@ function ps4_sceSysmoduleUnloadModuleInternal(id:DWord):Integer; SysV_ABI_CDecl;
|
|||
begin
|
||||
if ((id or $80000000)=$80000000) then Exit(SCE_SYSMODULE_ERROR_INVALID_VALUE);
|
||||
|
||||
Writeln('sceSysmoduleUnloadModuleInternal:',GetSysmoduleInternalName(id));
|
||||
Writeln(SysLogPrefix,'sceSysmoduleUnloadModuleInternal:',GetSysmoduleInternalName(id));
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
|
@ -932,13 +1326,20 @@ function ps4_sceSysmoduleUnloadModuleInternalWithArg(id:DWord;
|
|||
begin
|
||||
if ((id or $80000000)=$80000000) or (flags<>0) then Exit(SCE_SYSMODULE_ERROR_INVALID_VALUE);
|
||||
|
||||
Writeln('sceSysmoduleUnloadModuleInternalWithArg:',GetSysmoduleInternalName(id));
|
||||
Writeln(SysLogPrefix,'sceSysmoduleUnloadModuleInternalWithArg:',GetSysmoduleInternalName(id));
|
||||
if (pRes<>nil) then pRes^:=0;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
const
|
||||
__progname:PChar='eboot.bin'; //argv[0]
|
||||
function ps4_sceSysmoduleLoadModuleByNameInternal(name:PChar;
|
||||
argc:size_t;
|
||||
argp:PPointer;
|
||||
flags:DWORD;
|
||||
pRes:PInteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln(StdWrn,SysLogPrefix,'sceSysmoduleLoadModuleByNameInternal:',name);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function Load_libSceSysmodule(Const name:RawByteString):TElf_node;
|
||||
var
|
||||
|
@ -959,6 +1360,8 @@ begin
|
|||
lib^.set_proc($BD7661AED2719067,@ps4_sceSysmoduleUnloadModuleInternal);
|
||||
lib^.set_proc($68A6BA61F04A66CE,@ps4_sceSysmoduleUnloadModuleInternalWithArg);
|
||||
|
||||
lib^.set_proc($094F26F90B3E1CDE,@ps4_sceSysmoduleLoadModuleByNameInternal);
|
||||
|
||||
lib^.set_proc($E1F539CAF3A4546E,@ps4_sceSysmoduleGetModuleInfoForUnwind);
|
||||
end;
|
||||
|
||||
|
@ -997,6 +1400,7 @@ begin
|
|||
|
||||
//signal
|
||||
|
||||
lib^.set_proc($F85EC2FE1764EFE1,@ps4_sigemptyset);
|
||||
lib^.set_proc($5644C0B2B643709D,@ps4_sigfillset);
|
||||
lib^.set_proc($2548A616D29ED0A7,@ps4_sigaddset);
|
||||
lib^.set_proc($68F732A6D6CE899B,@ps4_sigprocmask); //sigprocmask
|
||||
|
@ -1019,6 +1423,7 @@ begin
|
|||
lib^.set_proc($0262749A7DA5E253,@ps4_sceKernelGetLibkernelTextLocation);
|
||||
lib^.set_proc($FD84D6FAA5DCDC24,@ps4_sceKernelInternalMemoryGetModuleSegmentInfo);
|
||||
lib^.set_proc($7FB28139A7F2B17A,@ps4_sceKernelGetModuleInfoFromAddr);
|
||||
lib^.set_proc($1D93BBC4EA2CE317,@ps4_sceKernelGetModuleInfoInternal);
|
||||
lib^.set_proc($914A60AD722BCFB4,@ps4_sceKernelGetModuleInfo);
|
||||
lib^.set_proc($4694092552938853,@ps4_sceKernelGetModuleInfoForUnwind);
|
||||
|
||||
|
@ -1041,15 +1446,25 @@ begin
|
|||
lib^.set_proc($F1C0250B3A0E8A27,@ps4_sceKernelMapSanitizerShadowMemory);
|
||||
|
||||
lib^.set_proc($581EBA7AFBBC6EC5,@ps4_sceKernelGetCompiledSdkVersion);
|
||||
lib^.set_proc($32FD7350E6C7BD72,@ps4_sceKernelGetSystemSwVersion);
|
||||
lib^.set_proc($1BF318BF97AB5DA5,@ps4_sceKernelGetAppInfo);
|
||||
lib^.set_proc($8A031E7E9E1202FD,@ps4_get_authinfo);
|
||||
lib^.set_proc($3210B9DD32A68D50,@ps4_sysctlbyname);
|
||||
lib^.set_proc($829822FC6C04D88B,@ps4_gpgi_GwE2Is); //gpgi-GwE2Is
|
||||
|
||||
lib^.set_proc($C33BEA4F852A297F,@ps4_sceKernelLoadStartModule);
|
||||
lib^.set_proc($1A0DFEC962FA0D65,@ps4_sceKernelLoadStartModuleForSysmodule);
|
||||
|
||||
lib^.set_proc($22EC6752E5E4E818,@ps4_sceKernelGetModuleList);
|
||||
lib^.set_proc($BBE9A55245A95376,@ps4_sceKernelGetModuleListInternal);
|
||||
|
||||
lib^.set_proc($2F01BC8379E2AB00,@ps4_sceKernelDlsym);
|
||||
|
||||
lib^.set_proc($54EC7C3469875D3B,@ps4_sceKernelGetCpumode);
|
||||
lib^.set_proc($56306D83906D97DE,@ps4_sceKernelSetFsstParam);
|
||||
lib^.set_proc($71AEEFE82C6E973B,@ps4_sceKernelSetGPO);
|
||||
lib^.set_proc($E285D87BD5E69344,@ps4_sceKernelGetGPI);
|
||||
lib^.set_proc($AA22F87C539B0313,@ps4_sceKernelGetCpuTemperature);
|
||||
|
||||
//module
|
||||
|
||||
|
@ -1074,6 +1489,8 @@ begin
|
|||
lib^.set_proc($228F7E9D329766D0,@ps4_pthread_mutex_timedlock);
|
||||
lib^.set_proc($2BF8D785BB76827E,@ps4_pthread_mutex_trylock);
|
||||
|
||||
lib^.set_proc($9D3C59069F183467,@ps4_pthread_mutex_setname_np);
|
||||
|
||||
lib^.set_proc($17C6D41F0006DBCE,@ps4_scePthreadMutexattrInit);
|
||||
lib^.set_proc($B2658492D8B2C86D,@ps4_scePthreadMutexattrDestroy);
|
||||
lib^.set_proc($82AB84841AD2DA2C,@ps4_scePthreadMutexattrGettype);
|
||||
|
@ -1203,28 +1620,59 @@ begin
|
|||
lib^.set_proc($B46FBCD396F53639,@ps4_pthread_set_defaultstacksize_np);
|
||||
lib^.set_proc($A1567EFCA819246A,@ps4_scePthreadSetDefaultstacksize);
|
||||
|
||||
lib^.set_proc($9EC628351CB0C0D8,@ps4_scePthreadAttrInit);
|
||||
lib^.set_proc($EB6282C04326CDC3,@ps4_scePthreadAttrDestroy);
|
||||
lib^.set_proc($C2D92DFED791D6CA,@ps4_pthread_attr_init);
|
||||
lib^.set_proc($CC772163C7EDE699,@ps4_pthread_attr_destroy);
|
||||
lib^.set_proc($5135F325B5A18531,@ps4_scePthreadAttrSetstacksize);
|
||||
|
||||
lib^.set_proc($9EC628351CB0C0D8,@ps4_scePthreadAttrInit);
|
||||
lib^.set_proc($EB6282C04326CDC3,@ps4_scePthreadAttrDestroy);
|
||||
|
||||
lib^.set_proc($D90D33EAB9C1AD31,@ps4_pthread_attr_setstacksize);
|
||||
lib^.set_proc($FD6ADEA6BB6ED10B,@ps4_scePthreadAttrSetdetachstate);
|
||||
lib^.set_proc($5135F325B5A18531,@ps4_scePthreadAttrSetstacksize);
|
||||
|
||||
lib^.set_proc($13EB72A37969E4BC,@ps4_pthread_attr_setdetachstate);
|
||||
lib^.set_proc($FD6ADEA6BB6ED10B,@ps4_scePthreadAttrSetdetachstate);
|
||||
|
||||
lib^.set_proc($25AACC232F242846,@ps4_pthread_attr_setschedpolicy);
|
||||
lib^.set_proc($E3E87D133C0A1782,@ps4_scePthreadAttrSetschedpolicy);
|
||||
lib^.set_proc($0F3112F61405E1FE,@ps4_scePthreadAttrSetschedparam);
|
||||
lib^.set_proc($1573D61CD93C39FD,@ps4_scePthreadAttrGetschedparam);
|
||||
|
||||
lib^.set_proc($46D2D157FA414D36,@ps4_pthread_attr_getschedpolicy);
|
||||
lib^.set_proc($34CC8843D5A059B5,@ps4_scePthreadAttrGetschedpolicy);
|
||||
|
||||
lib^.set_proc($7AE291826D159F63,@ps4_pthread_attr_setschedparam);
|
||||
lib^.set_proc($0F3112F61405E1FE,@ps4_scePthreadAttrSetschedparam);
|
||||
|
||||
lib^.set_proc($AA593DA522EC5263,@ps4_pthread_attr_getschedparam);
|
||||
lib^.set_proc($1573D61CD93C39FD,@ps4_scePthreadAttrGetschedparam);
|
||||
|
||||
lib^.set_proc($ED99406A411FD108,@ps4_pthread_attr_setinheritsched);
|
||||
lib^.set_proc($7976D44A911A4EC0,@ps4_scePthreadAttrSetinheritsched);
|
||||
|
||||
lib^.set_proc($DEAC603387B31130,@ps4_scePthreadAttrSetaffinity);
|
||||
lib^.set_proc($F3EB39073663C528,@ps4_scePthreadAttrGetaffinity);
|
||||
lib^.set_proc($7976D44A911A4EC0,@ps4_scePthreadAttrSetinheritsched);
|
||||
|
||||
lib^.set_proc($24AC86DD25B2035D,@ps4_pthread_attr_setguardsize);
|
||||
lib^.set_proc($125F9C436D03CA75,@ps4_scePthreadAttrSetguardsize);
|
||||
|
||||
lib^.set_proc($24D91556C54398E9,@ps4_pthread_attr_getguardsize);
|
||||
lib^.set_proc($B711ED9E027E7B27,@ps4_scePthreadAttrGetguardsize);
|
||||
|
||||
lib^.set_proc($B2E0AB11BAF4C484,@ps4_pthread_attr_setstackaddr);
|
||||
lib^.set_proc($17EC9F99DB88041F,@ps4_scePthreadAttrSetstackaddr);
|
||||
|
||||
lib^.set_proc($0F198831443FC176,@ps4_pthread_attr_getstackaddr);
|
||||
lib^.set_proc($46EDFA7E24ED2730,@ps4_scePthreadAttrGetstackaddr);
|
||||
|
||||
lib^.set_proc($D2A3AD091FD91DC9,@ps4_pthread_attr_getstacksize);
|
||||
lib^.set_proc($FDF03EED99460D0B,@ps4_scePthreadAttrGetstacksize);
|
||||
|
||||
lib^.set_proc($FD2ADB5E9191D5FD,@ps4_pthread_attr_setstack);
|
||||
lib^.set_proc($06F9FBE2F8FAA0BA,@ps4_scePthreadAttrSetstack);
|
||||
|
||||
lib^.set_proc($BD09B87C312C5A2F,@ps4_pthread_attr_getstack);
|
||||
lib^.set_proc($FEAB8F6B8484254C,@ps4_scePthreadAttrGetstack);
|
||||
lib^.set_proc($25A44CCBE41CA5E5,@ps4_scePthreadAttrGetdetachstate);
|
||||
|
||||
lib^.set_proc($5544F5652AC74F42,@ps4_pthread_attr_getdetachstate);
|
||||
lib^.set_proc($25A44CCBE41CA5E5,@ps4_scePthreadAttrGetdetachstate);
|
||||
|
||||
lib^.set_proc($C755FBE9AAD83315,@ps4_scePthreadAttrGet);
|
||||
|
||||
|
@ -1247,7 +1695,12 @@ begin
|
|||
lib^.set_proc($DE483BAD3D0D408B,@ps4_scePthreadExit);
|
||||
lib^.set_proc($149AD3E4BB940405,@ps4_pthread_exit);
|
||||
|
||||
lib^.set_proc($A810E6A42C86B2C1,@ps4_scePthreadCancel);
|
||||
|
||||
lib^.set_proc($959CC5792C4F974F,@ps4_pthread_setcancelstate);
|
||||
lib^.set_proc($D9D121BEF8E5AB7D,@ps4_pthread_setcanceltype);
|
||||
lib^.set_proc($380996ABE3874A3C,@ps4_scePthreadSetcancelstate);
|
||||
lib^.set_proc($B0225DF7D3E172DD,@ps4_scePthreadSetcanceltype);
|
||||
|
||||
lib^.set_proc($128B51F1ADC049FE,@ps4_pthread_self);
|
||||
lib^.set_proc($688F8E782CFCC6B4,@ps4_scePthreadSelf);
|
||||
|
@ -1255,18 +1708,30 @@ begin
|
|||
lib^.set_proc($1E82D558D6A70417,@ps4_getpid);
|
||||
lib^.set_proc($108FF9FE396AD9D1,@ps4_scePthreadGetthreadid);
|
||||
|
||||
lib^.set_proc($F47CDF85DB444A2A,@ps4_pthread_getname_np);
|
||||
lib^.set_proc($1E8C3B07C39EB7A9,@ps4_scePthreadGetname);
|
||||
|
||||
lib^.set_proc($F6FC8FE99EDBAB37,@ps4_pthread_rename_np);
|
||||
lib^.set_proc($181518EF2C1D50B1,@ps4_scePthreadRename);
|
||||
|
||||
lib^.set_proc($A31329F2E3EA6BE5,@ps4_pthread_set_name_np);
|
||||
lib^.set_proc($5DE4EAC3ED19975D,@ps4_scePthreadSetName);
|
||||
|
||||
lib^.set_proc($6EDDC24C12A61B22,@ps4_scePthreadSetaffinity);
|
||||
lib^.set_proc($ADCAD5149B105916,@ps4_scePthreadGetaffinity);
|
||||
|
||||
lib^.set_proc($8345530717C9CAED,@ps4_sceKernelGetCurrentCpu);
|
||||
|
||||
lib^.set_proc($68EF964B6C56BA8E,@ps4_pthread_getprio);
|
||||
lib^.set_proc($D6D2B21BB465309A,@ps4_scePthreadGetprio);
|
||||
|
||||
lib^.set_proc($6B63FDC1819E66F7,@ps4_pthread_setprio);
|
||||
lib^.set_proc($5B41E99B65F4B8F1,@ps4_scePthreadSetprio);
|
||||
|
||||
lib^.set_proc($148B37FD4413F6C8,@ps4_pthread_getschedparam);
|
||||
lib^.set_proc($3F8D644D6512DC42,@ps4_scePthreadGetschedparam);
|
||||
|
||||
lib^.set_proc($5ECF617620FBB000,@ps4_pthread_setschedparam);
|
||||
lib^.set_proc($A084454E3A082DB8,@ps4_scePthreadSetschedparam);
|
||||
|
||||
lib^.set_proc($08136D5CEA1E7FF1,@ps4_sched_get_priority_max);
|
||||
|
@ -1340,8 +1805,13 @@ begin
|
|||
|
||||
lib^.set_proc($9930597C46A5D81C,@ps4_mlock);
|
||||
lib^.set_proc($386E11B03C0B82EA,@ps4_munlock);
|
||||
lib^.set_proc($C7B83B11B7A8F3F5,@ps4_mlockall);
|
||||
lib^.set_proc($3692C1A60555ECF5,@ps4_munlockall);
|
||||
|
||||
lib^.set_proc($DE4EA4C7FCCE3924,@ps4_sceKernelMlock);
|
||||
lib^.set_proc($C502087C9F3AD2C9,@ps4_sceKernelMunlock);
|
||||
lib^.set_proc($11FAA62A48AB245D,@ps4_sceKernelMlockall);
|
||||
lib^.set_proc($96F0FBD633F63279,@ps4_sceKernelMunlockall);
|
||||
|
||||
lib^.set_proc($B59638F9264D1610,@ps4_msync);
|
||||
lib^.set_proc($0E435E6F1989C952,@ps4_sceKernelMsync);
|
||||
|
@ -1351,6 +1821,7 @@ begin
|
|||
//queue
|
||||
|
||||
lib^.set_proc($0F439D14C8E9E3A2,@ps4_sceKernelCreateEqueue);
|
||||
lib^.set_proc($8E91639A0002E401,@ps4_sceKernelDeleteEqueue);
|
||||
lib^.set_proc($7F3C8C2ACF648A6D,@ps4_sceKernelWaitEqueue);
|
||||
|
||||
lib^.set_proc($E11EBF3AF2367040,@ps4_sceKernelAddUserEvent);
|
||||
|
@ -1384,6 +1855,9 @@ begin
|
|||
lib^.set_proc($9FCF2FC770B99D6F,@ps4_gettimeofday);
|
||||
lib^.set_proc($B26223EDEAB3644F,@ps4_clock_getres);
|
||||
lib^.set_proc($94B313F6F240724D,@ps4_clock_gettime);
|
||||
|
||||
lib^.set_proc($C1161503966896CA,@ps4_sceKernelClockGetres);
|
||||
|
||||
lib^.set_proc($7A37A471A35036AD,@ps4_sceKernelGettimeofday);
|
||||
lib^.set_proc($90E7277ABCA99D00,@ps4_sceKernelGettimezone);
|
||||
|
||||
|
@ -1419,8 +1893,10 @@ begin
|
|||
lib^.set_proc($A226FBE85FF5D9F9,@ps4_sceKernelLseek);
|
||||
lib^.set_proc($0A0E2CAD9E9329B5,@ps4_sceKernelRead);
|
||||
lib^.set_proc($FABDEB305C08B55E,@ps4_sceKernelPread);
|
||||
lib^.set_proc($C938FAD88EE4C38B,@ps4_sceKernelPreadv);
|
||||
lib^.set_proc($E304B37BDD8184B2,@ps4_sceKernelWrite);
|
||||
lib^.set_proc($9CA5A2FCDD87055E,@ps4_sceKernelPwrite);
|
||||
lib^.set_proc($900B7A5436C79ABA,@ps4_sceKernelWritev);
|
||||
lib^.set_proc($556DD355988CE3F1,@ps4_sceKernelFtruncate);
|
||||
lib^.set_proc($901C023EC617FE6E,@ps4_sceKernelFstat);
|
||||
|
||||
|
@ -1440,15 +1916,20 @@ begin
|
|||
lib^.set_proc($0D1B81B76A6F2029,@ps4_read); //_read
|
||||
lib^.set_proc($02A062A02DAF1772,@ps4_read); //read
|
||||
|
||||
lib^.set_proc($7B3BFF45204D2AA2,@ps4_pread); //pread
|
||||
lib^.set_proc($7B3BFF45204D2AA2,@ps4_pread);
|
||||
|
||||
lib^.set_proc($F9646590A8D9BDA8,@ps4_readv); //_readv
|
||||
lib^.set_proc($23B22670B76CFEE5,@ps4_readv); //readv
|
||||
|
||||
lib^.set_proc($65A47369AA406703,@ps4_preadv);
|
||||
|
||||
lib^.set_proc($171559A81000EE4B,@ps4_write); //_write
|
||||
lib^.set_proc($14DE2068F9AE155F,@ps4_write); //write
|
||||
|
||||
lib^.set_proc($0B6909FDBC92E6B3,@ps4_pwrite); //pwrite
|
||||
lib^.set_proc($0B6909FDBC92E6B3,@ps4_pwrite);
|
||||
|
||||
lib^.set_proc($6121D10512E7DA92,@ps4_writev); //_writev
|
||||
lib^.set_proc($67668A771CD2E0A1,@ps4_writev); //writev
|
||||
|
||||
lib^.set_proc($8A1E020FDFE08213,@ps4_ftruncate);
|
||||
lib^.set_proc($9AA40C875CCF3D3F,@ps4_fstat);
|
||||
|
@ -1460,9 +1941,15 @@ begin
|
|||
|
||||
lib^.set_proc($F27635F5B2A88999,@ps4_fcntl);
|
||||
|
||||
lib^.set_proc($3DF71C4FBA944581,@ps4_ioctl); //ioctl
|
||||
lib^.set_proc($C16FA4DB57266F04,@ps4_ioctl); //_ioctl
|
||||
|
||||
lib^.set_proc($13A6A8DF8C0FC3E5,@ps4_stat);
|
||||
lib^.set_proc($795F70003DAB8880,@ps4_sceKernelStat);
|
||||
|
||||
lib^.set_proc($6B2AEDB3323B1818,@ps4_truncate);
|
||||
lib^.set_proc($5A5C8403FB0B0DFD,@ps4_sceKernelTruncate);
|
||||
|
||||
lib^.set_proc($246322A3EDB52F87,@ps4_mkdir);
|
||||
lib^.set_proc($D7F2C52E6445C713,@ps4_sceKernelMkdir);
|
||||
|
||||
|
@ -1475,6 +1962,9 @@ begin
|
|||
lib^.set_proc($34DD35A8B4618AA5,@ps4_rename);
|
||||
lib^.set_proc($E7635C614F7E944A,@ps4_sceKernelRename);
|
||||
|
||||
lib^.set_proc($CF476D9CFC5882D8,@ps4_chmod);
|
||||
lib^.set_proc($7E022C435D316150,@ps4_sceKernelChmod);
|
||||
|
||||
lib^.set_proc($B96C96DEFF7CB14E,@ps4_sceKernelCheckReachability);
|
||||
|
||||
lib^.set_proc($F2F13A67A5446329,@ps4_access);
|
||||
|
@ -1482,28 +1972,72 @@ begin
|
|||
lib^.set_proc($B19BB06833C04CAB,@ps4_getdtablesize);
|
||||
lib^.set_proc($2467D330139D509A,@ps4_sceKernelGetFsSandboxRandomWord);
|
||||
|
||||
lib^.set_proc($9EEE1AD3F6AB422B,@ps4_sceKernelAioInitializeParam);
|
||||
|
||||
//file
|
||||
|
||||
//socket
|
||||
|
||||
lib^.set_proc($4D4FDDF4F7C81CF3,@ps4_socket);
|
||||
lib^.set_proc($2AE3A680AA2A09D6,@ps4_bind);
|
||||
lib^.set_proc($7C5C469311766D5A,@ps4_setsockopt);
|
||||
lib^.set_proc($4FC7C447EB481A09,@ps4_select);
|
||||
lib^.set_proc($95493AC2B197C8CC,@ps4_recvfrom);
|
||||
lib^.set_proc($A719C299A82BB5AA,@ps4_listen);
|
||||
lib^.set_proc($4D4BA2612DA413CB,@ps4_shutdown);
|
||||
lib^.set_proc($DDEFB822FEC827C5,@ps4_accept);
|
||||
lib^.set_proc($A01AF7D773E9A4D1,@ps4_sendto);
|
||||
lib^.set_proc($45E9C8D652F55859,@ps4_getsockname);
|
||||
lib^.set_proc($5D52FC4A8DD02549,@ps4_connect);
|
||||
|
||||
//socket
|
||||
|
||||
lib^.set_proc($BA5E7B86F9BA9817,@ps4_sceKernelGetOpenPsIdForSystem);
|
||||
|
||||
lib^.set_proc($E63442B366B1B6BE,@ps4_inet_ntop);
|
||||
|
||||
//
|
||||
|
||||
//mirror of libkernel
|
||||
px:=Result._add_lib('libScePosix');
|
||||
px^.MapSymbol:=lib^.MapSymbol;
|
||||
|
||||
//mirror of libkernel
|
||||
px:=Result._add_lib('libkernel_cpumode_platform');
|
||||
px^.MapSymbol:=lib^.MapSymbol;
|
||||
|
||||
//
|
||||
|
||||
lib:=Result._add_lib('libkernel_unity');
|
||||
|
||||
lib^.set_proc($5A4C0477737BC346,@ps4_sceKernelInstallExceptionHandler);
|
||||
lib^.set_proc($421BF90110283847,@ps4_sceKernelRemoveExceptionHandler);
|
||||
lib^.set_proc($8A5D379E5B8A7CC9,@ps4_sceKernelRaiseException);
|
||||
|
||||
//mirror of libkernel
|
||||
px:=Result._add_lib('libkernel_exception');
|
||||
px^.MapSymbol:=lib^.MapSymbol;
|
||||
|
||||
//
|
||||
|
||||
lib:=Result._add_lib('libSceCoredump');
|
||||
|
||||
lib^.set_proc($F332D27C47D6E405,@ps4_sceCoredumpRegisterCoredumpHandler);
|
||||
lib^.set_proc($7C59213A0CED8820,@ps4_sceCoredumpUnregisterCoredumpHandler);
|
||||
|
||||
//
|
||||
|
||||
lib:=Result._add_lib('libSceOpenPsId');
|
||||
|
||||
lib^.set_proc($0CB39172BA14A9B7,@ps4_sceKernelGetOpenPsId);
|
||||
|
||||
//
|
||||
|
||||
lib:=Result._add_lib('libkernel_module_info');
|
||||
|
||||
lib^.set_proc($420B0A1147E4A8C0,@ps4_sceKernelGetModuleInfo2);
|
||||
lib^.set_proc($673CC2DD91950247,@ps4_sceKernelGetModuleList2);
|
||||
|
||||
//
|
||||
_kernel_init;
|
||||
end;
|
||||
|
|
|
@ -8,6 +8,7 @@ uses
|
|||
Windows,
|
||||
RWLock,
|
||||
sys_types,
|
||||
sys_crt,
|
||||
mmap,
|
||||
mm_adr_direct,
|
||||
mm_adr_virtual,
|
||||
|
@ -40,8 +41,12 @@ User area : 0x0010 0000 0000 - 0x00FC 0000 0000 Size: 0x00EC 0000 0000
|
|||
System reserved area: 0x00FC 0000 0000 - 0x00FF FFFF FFFF Size: 0x0003 FFFF FFFF (15GB)
|
||||
}
|
||||
|
||||
//FFFF FF|FF FFFF FFFF
|
||||
//0000 00|FF FFFF FFFF
|
||||
//mirror |addr
|
||||
|
||||
var
|
||||
MMLock:TRWLock;
|
||||
MMLock:System.TRTLCriticalSection;
|
||||
|
||||
DirectManager :TDirectManager;
|
||||
VirtualManager:TVirtualManager;
|
||||
|
@ -245,8 +250,13 @@ function ps4_sceKernelBatchMap2(
|
|||
|
||||
function ps4_mlock(addr:Pointer;len:qword):Integer; SysV_ABI_CDecl;
|
||||
function ps4_munlock(addr:Pointer;len:qword):Integer; SysV_ABI_CDecl;
|
||||
function ps4_mlockall(flags:Integer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_munlockall:Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_sceKernelMlock(addr:Pointer;len:qword):Integer; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelMunlock(addr:Pointer;len:qword):Integer; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelMlockall(flags:Integer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelMunlockall:Integer; SysV_ABI_CDecl;
|
||||
|
||||
//
|
||||
|
||||
|
@ -288,6 +298,21 @@ uses
|
|||
sys_kernel,
|
||||
sys_signal;
|
||||
|
||||
Procedure INIT_MLOCK; inline;
|
||||
begin
|
||||
System.InitCriticalSection(MMLock);
|
||||
end;
|
||||
|
||||
Procedure MLOCK; inline;
|
||||
begin
|
||||
System.EnterCriticalSection(MMLock);
|
||||
end;
|
||||
|
||||
Procedure MUNLOCK; inline;
|
||||
begin
|
||||
System.LeaveCriticalSection(MMLock);
|
||||
end;
|
||||
|
||||
function IsPowerOfTwo(x:QWORD):Boolean; inline;
|
||||
begin
|
||||
Result:=(x and (x - 1))=0;
|
||||
|
@ -330,7 +355,7 @@ begin
|
|||
|
||||
pb:=nil;
|
||||
|
||||
rwlock_rdlock(MMLock);
|
||||
MLOCK;
|
||||
|
||||
if VirtualManager.TryGetMapBlockByAddr(addr,pb) then
|
||||
begin
|
||||
|
@ -351,7 +376,7 @@ begin
|
|||
end;
|
||||
|
||||
__exit:
|
||||
rwlock_unlock(MMLock);
|
||||
MUNLOCK;
|
||||
end;
|
||||
|
||||
function __free_block(block:PVirtualAdrBlock):Integer;
|
||||
|
@ -372,21 +397,21 @@ Procedure RegistredStack;
|
|||
//var
|
||||
// block:PBlock;
|
||||
begin
|
||||
//rwlock_wrlock(MMLock);
|
||||
//MLOCK;
|
||||
//block:=AllocMem(SizeOf(TBlock));
|
||||
//if (block=nil) then Exit;
|
||||
//block^.pAddr:=StackBottom;
|
||||
//block^.nSize:=StackLength;
|
||||
//block^.bType:=BT_STACK;
|
||||
//PageMM.FMapBlockSet.Insert(block);
|
||||
//rwlock_unlock(MMLock);
|
||||
//MUNLOCK;
|
||||
end;
|
||||
|
||||
Procedure UnRegistredStack;
|
||||
begin
|
||||
//rwlock_wrlock(MMLock);
|
||||
//MLOCK;
|
||||
//PageMM._DeleteBlockByAddr(StackBottom);
|
||||
//rwlock_unlock(MMLock);
|
||||
//MUNLOCK;
|
||||
end;
|
||||
|
||||
function ps4_sceKernelGetDirectMemorySize:Int64; SysV_ABI_CDecl;
|
||||
|
@ -413,11 +438,11 @@ begin
|
|||
end;
|
||||
|
||||
_sig_lock;
|
||||
rwlock_rdlock(MMLock); //r
|
||||
MLOCK;
|
||||
|
||||
flex:=VirtualManager.stat.flex;
|
||||
|
||||
rwlock_unlock(MMLock);
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
|
||||
if (flex<SceKernelFlexibleMemorySize) then
|
||||
|
@ -482,11 +507,11 @@ begin
|
|||
searchStart:=AlignUp(searchStart,LOGICAL_PAGE_SIZE);
|
||||
|
||||
_sig_lock;
|
||||
rwlock_wrlock(MMLock); //rw
|
||||
MLOCK;
|
||||
|
||||
Result:=DirectManager.Alloc(searchStart,searchEnd,length,alignment,Byte(memoryType),physicalAddrDest^);
|
||||
|
||||
rwlock_unlock(MMLock);
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
|
@ -513,11 +538,11 @@ begin
|
|||
if not _test_mtype(memoryType) then Exit;
|
||||
|
||||
_sig_lock;
|
||||
rwlock_wrlock(MMLock); //rw
|
||||
MLOCK;
|
||||
|
||||
Result:=DirectManager.Alloc(length,alignment,Byte(memoryType),physicalAddrDest^);
|
||||
|
||||
rwlock_unlock(MMLock);
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
|
@ -550,11 +575,11 @@ begin
|
|||
FSizeOut:=0;
|
||||
|
||||
_sig_lock;
|
||||
rwlock_rdlock(MMLock); //r
|
||||
MLOCK;
|
||||
|
||||
Result:=DirectManager.CheckedAvailable(searchStart,searchEnd,alignment,FAdrOut,FSizeOut);
|
||||
Result:=DirectManager.QueryAvailable(searchStart,searchEnd,alignment,FAdrOut,FSizeOut);
|
||||
|
||||
rwlock_unlock(MMLock);
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
|
||||
if (Result=0) then
|
||||
|
@ -587,11 +612,11 @@ begin
|
|||
ROut:=Default(TDirectAdrNode);
|
||||
|
||||
_sig_lock;
|
||||
rwlock_rdlock(MMLock); //r
|
||||
MLOCK;
|
||||
|
||||
Result:=DirectManager.Query(offset,(flags=SCE_KERNEL_DMQ_FIND_NEXT),ROut);
|
||||
|
||||
rwlock_unlock(MMLock);
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
|
||||
info^:=Default(SceKernelDirectMemoryQueryInfo);
|
||||
|
@ -623,11 +648,11 @@ begin
|
|||
ROut:=Default(TDirectAdrNode);
|
||||
|
||||
_sig_lock;
|
||||
rwlock_rdlock(MMLock); //r
|
||||
MLOCK;
|
||||
|
||||
Result:=DirectManager.QueryMType(start,ROut);
|
||||
|
||||
rwlock_unlock(MMLock);
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
|
||||
if (Result=0) then
|
||||
|
@ -646,15 +671,15 @@ begin
|
|||
if not IsAlign(len ,LOGICAL_PAGE_SIZE) then Exit;
|
||||
|
||||
_sig_lock;
|
||||
rwlock_rdlock(MMLock); //r
|
||||
MLOCK;
|
||||
|
||||
Result:=DirectManager.CheckedRelease(start,len);
|
||||
Result:=DirectManager.CheckRelease(start,len);
|
||||
if (Result=0) then
|
||||
begin
|
||||
Result:=DirectManager.Release(start,len,False);
|
||||
Result:=DirectManager.Release(start,len);
|
||||
end;
|
||||
|
||||
rwlock_unlock(MMLock);
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
|
@ -666,11 +691,11 @@ begin
|
|||
if not IsAlign(len ,LOGICAL_PAGE_SIZE) then Exit;
|
||||
|
||||
_sig_lock;
|
||||
rwlock_wrlock(MMLock); //rw
|
||||
MLOCK;
|
||||
|
||||
Result:=DirectManager.Release(start,len,False);
|
||||
Result:=DirectManager.Release(start,len);
|
||||
|
||||
rwlock_unlock(MMLock);
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
|
@ -694,7 +719,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelAllocateDirectMemory:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelAllocateDirectMemory:',Result);
|
||||
end;
|
||||
_set_errno(Result);
|
||||
|
||||
|
@ -715,7 +740,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelAllocateMainDirectMemory:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelAllocateMainDirectMemory:',Result);
|
||||
end;
|
||||
_set_errno(Result);
|
||||
|
||||
|
@ -738,7 +763,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelAvailableDirectMemorySize:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelAvailableDirectMemorySize:',Result);
|
||||
end;
|
||||
_set_errno(Result);
|
||||
|
||||
|
@ -759,7 +784,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelDirectMemoryQuery:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelDirectMemoryQuery:',Result);
|
||||
end;
|
||||
_set_errno(Result);
|
||||
|
||||
|
@ -781,7 +806,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelGetDirectMemoryType:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelGetDirectMemoryType:',Result);
|
||||
end;
|
||||
_set_errno(Result);
|
||||
|
||||
|
@ -795,7 +820,7 @@ begin
|
|||
if (Result<>0) then
|
||||
begin
|
||||
Result:=_sceKernelCheckedReleaseDirectMemory(start,len);
|
||||
Writeln(StdErr,'[WARN]:sceKernelCheckedReleaseDirectMemory:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelCheckedReleaseDirectMemory:',Result);
|
||||
end;
|
||||
_set_errno(Result);
|
||||
|
||||
|
@ -808,7 +833,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelReleaseDirectMemory:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelReleaseDirectMemory:',Result);
|
||||
end;
|
||||
_set_errno(Result);
|
||||
|
||||
|
@ -832,7 +857,7 @@ begin
|
|||
if (align<PHYSICAL_PAGE_SIZE) then align:=PHYSICAL_PAGE_SIZE;
|
||||
|
||||
_sig_lock;
|
||||
rwlock_wrlock(MMLock); //rw
|
||||
MLOCK;
|
||||
|
||||
if (flags and MAP_VOID)<>0 then //reserved
|
||||
begin
|
||||
|
@ -846,7 +871,7 @@ begin
|
|||
begin
|
||||
if (fd=0) then //direct (psevdo dmem fd=0)
|
||||
begin
|
||||
Result:=DirectManager.CheckedMMap(offset,len);
|
||||
Result:=DirectManager.CheckMMap(offset,len);
|
||||
|
||||
if (Result=0) then
|
||||
begin
|
||||
|
@ -865,7 +890,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
rwlock_unlock(MMLock);
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
|
@ -902,9 +927,9 @@ begin
|
|||
Result:=0;
|
||||
|
||||
_sig_lock;
|
||||
rwlock_wrlock(MMLock); //rw
|
||||
MLOCK;
|
||||
|
||||
Result:=DirectManager.CheckedMMap(physicalAddr,length);
|
||||
Result:=DirectManager.CheckMMap(physicalAddr,length);
|
||||
|
||||
if (Result=0) then
|
||||
begin
|
||||
|
@ -916,7 +941,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
rwlock_unlock(MMLock);
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
|
@ -930,9 +955,9 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function __release_direct(Offset,Size:QWORD):Integer;
|
||||
function __unmap_direct(Offset,Size:QWORD):Integer;
|
||||
begin
|
||||
Result:=DirectManager.Release(Offset,Size,True);
|
||||
Result:=DirectManager.unmap_addr(Offset,Size);
|
||||
end;
|
||||
|
||||
function __mtype_direct(Offset,Size:QWORD;mtype:Integer):Integer;
|
||||
|
@ -945,7 +970,7 @@ begin
|
|||
Result:=EINVAL;
|
||||
|
||||
_sig_lock;
|
||||
rwlock_wrlock(MMLock); //rw
|
||||
MLOCK;
|
||||
|
||||
Result:=VirtualManager.Release(addr,len,False);
|
||||
|
||||
|
@ -954,7 +979,7 @@ begin
|
|||
NamedManager.Mname(addr,len,nil);
|
||||
end;
|
||||
|
||||
rwlock_unlock(MMLock);
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
|
@ -963,11 +988,11 @@ begin
|
|||
Result:=EINVAL;
|
||||
|
||||
_sig_lock;
|
||||
rwlock_wrlock(MMLock); //rw
|
||||
MLOCK;
|
||||
|
||||
Result:=VirtualManager.Protect(addr,len,prot);
|
||||
|
||||
rwlock_unlock(MMLock);
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
|
@ -976,11 +1001,11 @@ begin
|
|||
Result:=EINVAL;
|
||||
|
||||
_sig_lock;
|
||||
rwlock_wrlock(MMLock); //rw
|
||||
MLOCK;
|
||||
|
||||
Result:=VirtualManager.Mtypeprotect(addr,len,mtype,prot);
|
||||
|
||||
rwlock_unlock(MMLock);
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
|
@ -995,11 +1020,11 @@ begin
|
|||
ROut:=Default(TVirtualAdrNode);
|
||||
|
||||
_sig_lock;
|
||||
rwlock_rdlock(MMLock); //r
|
||||
MLOCK;
|
||||
|
||||
Result:=VirtualManager.QueryProt(addr,ROut);
|
||||
|
||||
rwlock_unlock(MMLock);
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
|
||||
if (Result=0) then
|
||||
|
@ -1041,7 +1066,7 @@ begin
|
|||
Name:=Default(TName);
|
||||
|
||||
_sig_lock;
|
||||
rwlock_rdlock(MMLock); //r
|
||||
MLOCK;
|
||||
|
||||
Result:=VirtualManager.Query(addr,(flags=SCE_KERNEL_VQ_FIND_NEXT),VOut);
|
||||
|
||||
|
@ -1055,7 +1080,7 @@ begin
|
|||
NamedManager.Query(addr,@name);
|
||||
end;
|
||||
|
||||
rwlock_unlock(MMLock);
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
|
||||
info^:=Default(SceKernelVirtualQueryInfo);
|
||||
|
@ -1085,11 +1110,11 @@ begin
|
|||
if (StrLen(pname)>32) then Exit;
|
||||
|
||||
_sig_lock;
|
||||
rwlock_rdlock(MMLock); //r
|
||||
MLOCK;
|
||||
|
||||
Result:=NamedManager.Mname(addr,len,pname);
|
||||
|
||||
rwlock_unlock(MMLock);
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
|
@ -1118,7 +1143,7 @@ begin
|
|||
Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
end;
|
||||
flags:=flags and $ffffffef;
|
||||
Writeln('[WARNING] map(addr=0, flags=MAP_FIXED)');
|
||||
Writeln(StdWrn,'[WARNING] map(addr=0, flags=MAP_FIXED)');
|
||||
end;
|
||||
|
||||
if (((flags and MAP_FIXED)=0) and (addr=nil)) then
|
||||
|
@ -1370,7 +1395,7 @@ begin
|
|||
Result:=addr;
|
||||
end else
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:mmap:',err);
|
||||
Writeln(StdWrn,'[WARN]:mmap:',err);
|
||||
Result:=MAP_FAILED;
|
||||
end;
|
||||
end;
|
||||
|
@ -1395,7 +1420,7 @@ begin
|
|||
res^:=addr;
|
||||
end else
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelMmap:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelMmap:',Result);
|
||||
end;
|
||||
|
||||
Result:=px2sce(Result);
|
||||
|
@ -1408,7 +1433,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:munmap:',Result);
|
||||
Writeln(StdWrn,'[WARN]:munmap:',Result);
|
||||
end;
|
||||
|
||||
Result:=_set_errno(Result);
|
||||
|
@ -1421,7 +1446,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelMunmap:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelMunmap:',Result);
|
||||
end;
|
||||
|
||||
Result:=px2sce(Result);
|
||||
|
@ -1434,7 +1459,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelReleaseFlexibleMemory:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelReleaseFlexibleMemory:',Result);
|
||||
end;
|
||||
|
||||
Result:=px2sce(Result);
|
||||
|
@ -1449,7 +1474,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:mprotect:',Result);
|
||||
Writeln(StdWrn,'[WARN]:mprotect:',Result);
|
||||
end;
|
||||
|
||||
Result:=_set_errno(Result);
|
||||
|
@ -1464,7 +1489,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelMprotect:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelMprotect:',Result);
|
||||
end;
|
||||
|
||||
Result:=px2sce(Result);
|
||||
|
@ -1479,7 +1504,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelMtypeprotect:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelMtypeprotect:',Result);
|
||||
end;
|
||||
|
||||
Result:=px2sce(Result);
|
||||
|
@ -1494,7 +1519,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelQueryMemoryProtection:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelQueryMemoryProtection:',Result);
|
||||
end;
|
||||
|
||||
Result:=px2sce(Result);
|
||||
|
@ -1510,7 +1535,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelVirtualQuery:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelVirtualQuery:',Result);
|
||||
end;
|
||||
|
||||
Result:=px2sce(Result);
|
||||
|
@ -1523,7 +1548,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelSetVirtualRangeName:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelSetVirtualRangeName:',Result);
|
||||
end;
|
||||
|
||||
Result:=px2sce(Result);
|
||||
|
@ -1538,7 +1563,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelMapFlexibleMemory:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelMapFlexibleMemory:',Result);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -1556,7 +1581,7 @@ begin
|
|||
end else
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelMapNamedFlexibleMemory:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelMapNamedFlexibleMemory:',Result);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -1570,7 +1595,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelMapNamedSystemFlexibleMemory:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelMapNamedSystemFlexibleMemory:',Result);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -1584,7 +1609,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelReserveVirtualRange:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelReserveVirtualRange:',Result);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -1604,7 +1629,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelMapDirectMemory2:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelMapDirectMemory2:',Result);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -1624,7 +1649,7 @@ begin
|
|||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelMapDirectMemory:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelMapDirectMemory:',Result);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -1648,7 +1673,7 @@ begin
|
|||
_sys_mname(virtualAddrDest^,length,name);
|
||||
end else
|
||||
begin
|
||||
Writeln(StdErr,'[WARN]:sceKernelMapNamedDirectMemory:',Result);
|
||||
Writeln(StdWrn,'[WARN]:sceKernelMapNamedDirectMemory:',Result);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -1664,7 +1689,9 @@ begin
|
|||
entries,
|
||||
numberOfEntries,
|
||||
numberOfEntriesOut,
|
||||
0);
|
||||
MAP_FIXED);
|
||||
//There is a function with the same name exported from the libkernel_pre250mmap
|
||||
// library, it differs only in that the flag is 0x410 (MAP_FIXED or MAP_STACK)
|
||||
end;
|
||||
|
||||
function ps4_sceKernelBatchMap2(
|
||||
|
@ -1672,22 +1699,29 @@ function ps4_sceKernelBatchMap2(
|
|||
numberOfEntries:Integer;
|
||||
numberOfEntriesOut:PInteger;
|
||||
flags:Integer):Integer; SysV_ABI_CDecl;
|
||||
label
|
||||
_exit,_exit_lock;
|
||||
var
|
||||
i:Integer;
|
||||
begin
|
||||
if (entries=nil) then
|
||||
begin
|
||||
if (numberOfEntriesOut<>nil) then numberOfEntriesOut^:=0;
|
||||
numberOfEntries:=0;
|
||||
_set_errno(EFAULT);
|
||||
Exit(SCE_KERNEL_ERROR_EFAULT);
|
||||
Result:=SCE_KERNEL_ERROR_EFAULT;
|
||||
goto _exit;
|
||||
end;
|
||||
if (numberOfEntries=0) then
|
||||
begin
|
||||
if (numberOfEntriesOut<>nil) then numberOfEntriesOut^:=0;
|
||||
numberOfEntries:=0;
|
||||
_set_errno(EINVAL);
|
||||
Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
Result:=SCE_KERNEL_ERROR_EINVAL;
|
||||
goto _exit;
|
||||
end;
|
||||
|
||||
_sig_lock;
|
||||
MLOCK;
|
||||
|
||||
For i:=0 to numberOfEntries-1 do
|
||||
begin
|
||||
Case entries[i].operation of
|
||||
|
@ -1728,103 +1762,128 @@ begin
|
|||
end;
|
||||
else
|
||||
begin
|
||||
if (numberOfEntriesOut<>nil) then numberOfEntriesOut^:=i;
|
||||
numberOfEntries:=i;
|
||||
_set_errno(EINVAL);
|
||||
Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
Result:=SCE_KERNEL_ERROR_EINVAL;
|
||||
goto _exit_lock;
|
||||
end;
|
||||
end;
|
||||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
if (numberOfEntriesOut<>nil) then numberOfEntriesOut^:=i;
|
||||
Exit;
|
||||
numberOfEntries:=i;
|
||||
goto _exit_lock;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
_exit_lock:
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
_exit:
|
||||
if (numberOfEntriesOut<>nil) then numberOfEntriesOut^:=numberOfEntries;
|
||||
end;
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
function _sys_mlock(addr:Pointer;len:qword):Integer;
|
||||
var
|
||||
tmp:Pointer;
|
||||
function _sys_check_mmaped(addr:Pointer;len:qword):Integer;
|
||||
begin
|
||||
tmp:=AlignDw(addr,PHYSICAL_PAGE_SIZE);
|
||||
len:=len+(addr-tmp);
|
||||
_sig_lock;
|
||||
MLOCK;
|
||||
|
||||
addr:=tmp;
|
||||
len:=AlignUp(len,PHYSICAL_PAGE_SIZE);
|
||||
Result:=VirtualManager.check_mmaped(addr,len);
|
||||
|
||||
if VirtualLock(addr,len) then
|
||||
begin
|
||||
Result:=0;
|
||||
end else
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
function _sys_munlock(addr:Pointer;len:qword):Integer;
|
||||
var
|
||||
tmp:Pointer;
|
||||
function _sys_mlockall(flags:Integer):Integer;
|
||||
const
|
||||
MNALL=not Integer(MCL_CURRENT or MCL_FUTURE);
|
||||
begin
|
||||
tmp:=AlignDw(addr,PHYSICAL_PAGE_SIZE);
|
||||
len:=len+(addr-tmp);
|
||||
|
||||
addr:=tmp;
|
||||
len:=AlignUp(len,PHYSICAL_PAGE_SIZE);
|
||||
|
||||
if VirtualUnlock(addr,len) then
|
||||
begin
|
||||
Result:=0;
|
||||
end else
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
if (flags=0) or ((flags and MNALL)<>0) then Exit(EINVAL);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_mlock(addr:Pointer;len:qword):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=_set_errno(_sys_mlock(addr,len));
|
||||
Result:=_set_errno(_sys_check_mmaped(addr,len));
|
||||
end;
|
||||
|
||||
function ps4_munlock(addr:Pointer;len:qword):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=_set_errno(_sys_munlock(addr,len));
|
||||
Result:=_set_errno(_sys_check_mmaped(addr,len));
|
||||
end;
|
||||
|
||||
function ps4_mlockall(flags:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=_set_errno(_sys_mlockall(flags));
|
||||
end;
|
||||
|
||||
function ps4_munlockall:Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=_set_errno(0);
|
||||
end;
|
||||
|
||||
function ps4_sceKernelMlock(addr:Pointer;len:qword):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=_sys_mlock(addr,len);
|
||||
Result:=_sys_check_mmaped(addr,len);
|
||||
_set_errno(Result);
|
||||
Result:=px2sce(Result);
|
||||
end;
|
||||
|
||||
function ps4_sceKernelMunlock(addr:Pointer;len:qword):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=_sys_munlock(addr,len);
|
||||
Result:=_sys_check_mmaped(addr,len);
|
||||
_set_errno(Result);
|
||||
Result:=px2sce(Result);
|
||||
end;
|
||||
|
||||
function ps4_sceKernelMlockall(flags:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=_sys_mlockall(flags);
|
||||
_set_errno(Result);
|
||||
Result:=px2sce(Result);
|
||||
end;
|
||||
|
||||
function ps4_sceKernelMunlockall:Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
_set_errno(0);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
////
|
||||
////
|
||||
|
||||
function _sys_msync(addr:Pointer;len:size_t;flags:Integer):Integer;
|
||||
begin
|
||||
if not IsAlign(addr,PHYSICAL_PAGE_SIZE) then Exit(EINVAL);
|
||||
|
||||
if ((flags and MS_ASYNC)<>0) and ((flags and MS_INVALIDATE)<>0) then Exit(EINVAL);
|
||||
|
||||
_sig_lock;
|
||||
MLOCK;
|
||||
|
||||
Result:=VirtualManager.check_mmaped(addr,len);
|
||||
|
||||
MUNLOCK;
|
||||
_sig_unlock;
|
||||
|
||||
if (Result=0) then
|
||||
begin
|
||||
FlushViewOfFile(addr,len);
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_msync(addr:Pointer;len:size_t;flags:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
System.ReadWriteBarrier;
|
||||
Result:=0;
|
||||
Result:=_set_errno(_sys_msync(addr,len,flags));
|
||||
end;
|
||||
|
||||
function ps4_sceKernelMsync(addr:Pointer;len:size_t;flags:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
System.ReadWriteBarrier;
|
||||
Result:=0;
|
||||
Result:=_sys_msync(addr,len,flags);
|
||||
_set_errno(Result);
|
||||
Result:=px2sce(Result);
|
||||
end;
|
||||
|
||||
Procedure _mem_init;
|
||||
|
@ -1841,21 +1900,22 @@ end;
|
|||
|
||||
Procedure _mem_print;
|
||||
begin
|
||||
Writeln('---[Virtual]---');
|
||||
VirtualManager.Print;
|
||||
Writeln('---');
|
||||
Writeln('---[Named]---');
|
||||
NamedManager.Print;
|
||||
Writeln('---');
|
||||
Writeln('---[Direct]---');
|
||||
DirectManager.Print;
|
||||
end;
|
||||
|
||||
initialization
|
||||
rwlock_init(MMLock);
|
||||
INIT_MLOCK;
|
||||
|
||||
DirectManager :=TDirectManager .Create;
|
||||
DirectManager .OnMemoryUnmapCb:=@__munmap;
|
||||
|
||||
VirtualManager:=TVirtualManager.Create($400000,$FFFFFFFFFF);
|
||||
VirtualManager.OnDirectUnmapCb:=@__release_direct;
|
||||
VirtualManager.OnDirectUnmapCb:=@__unmap_direct;
|
||||
VirtualManager.OnDirectMtypeCb:=@__mtype_direct;
|
||||
VirtualManager.OnFreeBlockCb :=@__free_block;
|
||||
VirtualManager._mmap_sys(Pointer($400000),$7FFBFC000);
|
||||
|
|
|
@ -76,6 +76,8 @@ function ps4_pthread_mutex_unlock(pMutex:p_pthread_mutex):Integer; SysV_ABI_CDec
|
|||
function ps4_pthread_mutex_init(pMutex:p_pthread_mutex;pAttr:p_pthread_mutex_attr):Integer; SysV_ABI_CDecl;
|
||||
function ps4_pthread_mutex_destroy(pMutex:p_pthread_mutex):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_mutex_setname_np(pMutex:p_pthread_mutex;name:Pchar):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_scePthreadMutexattrInit(pAttr:p_pthread_mutex_attr):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadMutexattrDestroy(pAttr:p_pthread_mutex_attr):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadMutexattrGettype(pAttr:p_pthread_mutex_attr;t:PInteger):Integer; SysV_ABI_CDecl;
|
||||
|
@ -476,6 +478,21 @@ begin
|
|||
Result:=pthread_mutex_destroy(pMutex);
|
||||
end;
|
||||
|
||||
function ps4_pthread_mutex_setname_np(pMutex:p_pthread_mutex;name:Pchar):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
m:pthread_mutex;
|
||||
begin
|
||||
if (pMutex=nil) then Exit(EINVAL);
|
||||
m:=pMutex^;
|
||||
if (m=nil) then Exit(EINVAL);
|
||||
if (name<>nil) then
|
||||
begin
|
||||
FillChar(m^.name,32,0);
|
||||
MoveChar0(name^,m^.name,32);
|
||||
end;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
//---------------------------------------------------------
|
||||
//sce
|
||||
|
||||
|
|
|
@ -10,32 +10,6 @@ uses
|
|||
sys_pthread,
|
||||
sys_signal;
|
||||
|
||||
function ps4_pthread_set_defaultstacksize_np(size:QWORD):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadSetDefaultstacksize(size:QWORD):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_scePthreadAttrInit(pAttr:p_pthread_attr_t):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrDestroy(pAttr:p_pthread_attr_t):Integer; SysV_ABI_CDecl;
|
||||
function ps4_pthread_attr_init(pAttr:p_pthread_attr_t):Integer; SysV_ABI_CDecl;
|
||||
function ps4_pthread_attr_destroy(pAttr:p_pthread_attr_t):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrSetstacksize(pAttr:p_pthread_attr_t;size:size_t):Integer; SysV_ABI_CDecl;
|
||||
function ps4_pthread_attr_setstacksize(pAttr:p_pthread_attr_t;size:size_t):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrSetdetachstate(pAttr:p_pthread_attr_t;detachstate:Integer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_pthread_attr_setdetachstate(pAttr:p_pthread_attr_t;detachstate:Integer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrSetschedpolicy(pAttr:p_pthread_attr_t;policy:Integer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrSetschedparam(pAttr:p_pthread_attr_t;param:PInteger):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrGetschedparam(pAttr:p_pthread_attr_t;param:PInteger):Integer; SysV_ABI_CDecl;
|
||||
function ps4_pthread_attr_setschedparam(pAttr:p_pthread_attr_t;param:PInteger):Integer; SysV_ABI_CDecl;
|
||||
function ps4_pthread_attr_getschedparam(pAttr:p_pthread_attr_t;param:PInteger):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrSetaffinity(pAttr:p_pthread_attr_t;mask:QWORD):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrGetaffinity(pAttr:p_pthread_attr_t;mask:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrSetinheritsched(pAttr:p_pthread_attr_t;inheritSched:Integer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrGetguardsize(pAttr:p_pthread_attr_t;guardSize:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrGetstackaddr(pAttr:p_pthread_attr_t;stackAddr:PPointer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrGetstacksize(pAttr:p_pthread_attr_t;stackSize:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrGetstack(pAttr:p_pthread_attr_t;stackAddr:PPointer;stackSize:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrGetdetachstate(pAttr:p_pthread_attr_t;detachstate:Pinteger):Integer; SysV_ABI_CDecl;
|
||||
function ps4_pthread_attr_getdetachstate(pAttr:p_pthread_attr_t;detachstate:Pinteger):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_scePthreadAttrGet(pid:pthread;pAttr:p_pthread_attr_t):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_create_name_np(pthread:p_pthread;pAttr:p_pthread_attr_t;entry:Pointer;arg:Pointer;name:Pchar):Integer; SysV_ABI_CDecl;
|
||||
|
@ -56,7 +30,12 @@ function ps4_pthread_equal(t1,t2:pthread):Integer; SysV_ABI_CDecl;
|
|||
procedure ps4_scePthreadExit(value_ptr:Pointer); SysV_ABI_CDecl;
|
||||
procedure ps4_pthread_exit(value_ptr:Pointer); SysV_ABI_CDecl;
|
||||
|
||||
function ps4_scePthreadCancel(_pthread:pthread):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_setcancelstate(state:Integer;oldstate:PInteger):Integer; SysV_ABI_CDecl;
|
||||
function ps4_pthread_setcanceltype (_type:Integer;oldtype:PInteger):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadSetcancelstate(state:Integer;oldState:PInteger):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadSetcanceltype(_type:Integer;oldType:PInteger):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_self():pthread; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadSelf():pthread; SysV_ABI_CDecl;
|
||||
|
@ -64,18 +43,30 @@ function ps4_scePthreadSelf():pthread; SysV_ABI_CDecl;
|
|||
function ps4_getpid():Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadGetthreadid():Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_getname_np(_pthread:pthread;name:Pchar):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadGetname(_pthread:pthread;name:Pchar):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_rename_np(_pthread:pthread;name:Pchar):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadRename(_pthread:pthread;name:Pchar):Integer; SysV_ABI_CDecl;
|
||||
|
||||
procedure ps4_pthread_set_name_np(_pthread:pthread;name:Pchar); SysV_ABI_CDecl;
|
||||
procedure ps4_scePthreadSetName(_pthread:pthread;name:Pchar); SysV_ABI_CDecl;
|
||||
|
||||
function ps4_scePthreadSetaffinity(_pthread:pthread;mask:QWORD):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadGetaffinity(_pthread:pthread;mask:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_sceKernelGetCurrentCpu():Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_getprio(_pthread:pthread):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadGetprio(_pthread:pthread;prio:PInteger):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_setprio(_pthread:pthread;prio:Integer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadSetprio(_pthread:pthread;prio:Integer):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_getschedparam(_pthread:pthread;policy:PInteger;param:PSceKernelSchedParam):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadGetschedparam(_pthread:pthread;policy:PInteger;param:PSceKernelSchedParam):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_setschedparam(_pthread:pthread;policy:Integer;param:PSceKernelSchedParam):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadSetschedparam(_pthread:pthread;policy:Integer;param:PSceKernelSchedParam):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_sched_get_priority_max(policy:Integer):Integer; SysV_ABI_CDecl;
|
||||
|
@ -104,258 +95,16 @@ uses
|
|||
ps4_mutex,
|
||||
ps4_map_mm,
|
||||
ps4_program,
|
||||
ps4_elf;
|
||||
|
||||
|
||||
const
|
||||
default_name:Pchar='main';
|
||||
|
||||
var
|
||||
default_stack_size:QWORD=$10000;
|
||||
|
||||
function ps4_pthread_set_defaultstacksize_np(size:QWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=EINVAL;
|
||||
if (size>PTHREAD_STACK_MIN) then
|
||||
begin
|
||||
default_stack_size:=size;
|
||||
Result:=0;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadSetDefaultstacksize(size:QWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_set_defaultstacksize_np(size));
|
||||
end;
|
||||
|
||||
//struct pthread_attr _pthread_attr_default = {
|
||||
// .sched_policy = SCHED_OTHER,
|
||||
// .sched_inherit = PTHREAD_INHERIT_SCHED,
|
||||
// .prio = 0,
|
||||
// .suspend = THR_CREATE_RUNNING,
|
||||
// .flags = PTHREAD_SCOPE_SYSTEM,
|
||||
// .stackaddr_attr = NULL,
|
||||
// .stacksize_attr = THR_STACK_DEFAULT,
|
||||
// .guardsize_attr = 0,
|
||||
// .cpusetsize = 0,
|
||||
// .cpuset = NULL
|
||||
//};
|
||||
|
||||
function ps4_scePthreadAttrInit(pAttr:p_pthread_attr_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln('scePthreadAttrInit');
|
||||
if (pAttr=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
pAttr^:=SwAllocMem(SizeOf(tthread_attr_t));
|
||||
if (pAttr^=nil) then Exit(SCE_KERNEL_ERROR_ENOMEM);
|
||||
pAttr^^.stacksize_attr:=default_stack_size;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrDestroy(pAttr:p_pthread_attr_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln('scePthreadAttrDestroy');
|
||||
Result:=SCE_KERNEL_ERROR_EINVAL;
|
||||
if (pAttr=nil) then Exit;
|
||||
SwFreeMem(XCHG(pAttr^,nil));
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_init(pAttr:p_pthread_attr_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln('pthread_attr_init');
|
||||
if (pAttr=nil) then Exit(EINVAL);
|
||||
pAttr^:=SwAllocMem(SizeOf(tthread_attr_t));
|
||||
if (pAttr^=nil) then Exit(ENOMEM);
|
||||
pAttr^^.stacksize_attr:=default_stack_size;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_destroy(pAttr:p_pthread_attr_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln('pthread_attr_destroy');
|
||||
Result:=EINVAL;
|
||||
if (pAttr=nil) then Exit;
|
||||
SwFreeMem(XCHG(pAttr^,nil));
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrSetstacksize(pAttr:p_pthread_attr_t;size:size_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pAttr=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
if (pAttr^=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
if (size<PTHREAD_STACK_MIN) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
pAttr^^.stacksize_attr:=size;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_setstacksize(pAttr:p_pthread_attr_t;size:size_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pAttr=nil) then Exit(EINVAL);
|
||||
if (pAttr^=nil) then Exit(EINVAL);
|
||||
if (size<PTHREAD_STACK_MIN) then Exit(EINVAL);
|
||||
pAttr^^.stacksize_attr:=size;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrSetdetachstate(pAttr:p_pthread_attr_t;detachstate:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=SCE_KERNEL_ERROR_EINVAL;
|
||||
if (pAttr=nil) then Exit;
|
||||
if (pAttr^=nil) then Exit;
|
||||
|
||||
Case detachstate of
|
||||
PTHREAD_CREATE_JOINABLE:;
|
||||
PTHREAD_CREATE_DETACHED:;
|
||||
else
|
||||
Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
end;
|
||||
|
||||
pAttr^^.flags:=detachstate;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_setdetachstate(pAttr:p_pthread_attr_t;detachstate:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=EINVAL;
|
||||
if (pAttr=nil) then Exit;
|
||||
if (pAttr^=nil) then Exit;
|
||||
|
||||
Case detachstate of
|
||||
PTHREAD_CREATE_JOINABLE:;
|
||||
PTHREAD_CREATE_DETACHED:;
|
||||
else
|
||||
Exit(EINVAL);
|
||||
end;
|
||||
|
||||
pAttr^^.flags:=detachstate;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrSetschedpolicy(pAttr:p_pthread_attr_t;policy:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=SCE_KERNEL_ERROR_EINVAL;
|
||||
if (pAttr=nil) then Exit;
|
||||
if (pAttr^=nil) then Exit;
|
||||
pAttr^^.sched_policy:=policy;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrSetschedparam(pAttr:p_pthread_attr_t;param:PInteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=SCE_KERNEL_ERROR_EINVAL;
|
||||
if (pAttr=nil) or (param=nil) then Exit;
|
||||
if (pAttr^=nil) then Exit;
|
||||
pAttr^^.prio:=param^;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrGetschedparam(pAttr:p_pthread_attr_t;param:PInteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=SCE_KERNEL_ERROR_EINVAL;
|
||||
if (pAttr=nil) or (param=nil) then Exit;
|
||||
if (pAttr^=nil) then Exit;
|
||||
param^:=pAttr^^.prio;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_setschedparam(pAttr:p_pthread_attr_t;param:PInteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=EINVAL;
|
||||
if (pAttr=nil) or (param=nil) then Exit;
|
||||
if (pAttr^=nil) then Exit;
|
||||
pAttr^^.prio:=param^;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_getschedparam(pAttr:p_pthread_attr_t;param:PInteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=EINVAL;
|
||||
if (pAttr=nil) or (param=nil) then Exit;
|
||||
if (pAttr^=nil) then Exit;
|
||||
param^:=pAttr^^.prio;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrSetaffinity(pAttr:p_pthread_attr_t;mask:QWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=SCE_KERNEL_ERROR_EINVAL;
|
||||
if (pAttr=nil) then Exit;
|
||||
if (pAttr^=nil) then Exit;
|
||||
pAttr^^.cpuset:=mask;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrGetaffinity(pAttr:p_pthread_attr_t;mask:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=SCE_KERNEL_ERROR_EINVAL;
|
||||
if (pAttr=nil) or (mask=nil) then Exit;
|
||||
if (pAttr^=nil) then Exit;
|
||||
mask^:=pAttr^^.cpuset;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrSetinheritsched(pAttr:p_pthread_attr_t;inheritSched:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=SCE_KERNEL_ERROR_EINVAL;
|
||||
if (pAttr=nil) then Exit;
|
||||
if (pAttr^=nil) then Exit;
|
||||
pAttr^^.sched_inherit:=inheritSched;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrGetguardsize(pAttr:p_pthread_attr_t;guardSize:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pAttr=nil) or (guardSize=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
if (pAttr^=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
guardSize^:=pAttr^^.guardsize_attr;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrGetstackaddr(pAttr:p_pthread_attr_t;stackAddr:PPointer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pAttr=nil) or (stackAddr=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
if (pAttr^=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
stackAddr^:=pAttr^^.stackaddr_attr;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrGetstacksize(pAttr:p_pthread_attr_t;stackSize:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pAttr=nil) or (stackSize=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
if (pAttr^=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
stackSize^:=pAttr^^.stacksize_attr;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrGetstack(pAttr:p_pthread_attr_t;stackAddr:PPointer;stackSize:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pAttr=nil) or (stackAddr=nil) or (stackSize=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
if (pAttr^=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
stackAddr^:=pAttr^^.stackaddr_attr;
|
||||
stackSize^:=pAttr^^.stacksize_attr;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrGetdetachstate(pAttr:p_pthread_attr_t;detachstate:Pinteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pAttr=nil) or (detachstate=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
if (pAttr^=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
detachstate^:=pAttr^^.flags;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_getdetachstate(pAttr:p_pthread_attr_t;detachstate:Pinteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pAttr=nil) or (detachstate=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
if (pAttr^=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
detachstate^:=pAttr^^.flags;
|
||||
Result:=0;
|
||||
end;
|
||||
ps4_elf,
|
||||
ps4_pthread_attr;
|
||||
|
||||
procedure _free_pthread(data:pthread);
|
||||
begin
|
||||
_sig_lock;
|
||||
System.CloseThread(data^.handle);
|
||||
if (data^.handle<>0) then
|
||||
begin
|
||||
System.CloseThread(data^.handle);
|
||||
end;
|
||||
FreeMem(data);
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
@ -405,19 +154,21 @@ end;
|
|||
|
||||
function _pthread_run_entry(pthread:p_pthread;name:Pchar;stack:PDWORD):Integer;
|
||||
var
|
||||
init:Integer;
|
||||
attr:pthread_attr_t;
|
||||
begin
|
||||
if (name=nil) then
|
||||
begin
|
||||
name:=default_name;
|
||||
end;
|
||||
init:=THR_STACK_INITIAL;
|
||||
if (stack=nil) then
|
||||
begin
|
||||
stack:=@default_stack_size;
|
||||
stack:=@init;
|
||||
end else
|
||||
if (stack^<PTHREAD_STACK_MIN) then
|
||||
if (stack^<THR_STACK_INITIAL) then
|
||||
begin
|
||||
stack:=@default_stack_size;
|
||||
stack:=@init;
|
||||
end;
|
||||
|
||||
ps4_pthread_attr_init(@attr);
|
||||
|
@ -430,11 +181,6 @@ const
|
|||
_PREPARE_FREE=2;
|
||||
_PREPARE_JOIN=3;
|
||||
|
||||
procedure SetStackTop(p:Pointer); assembler; nostackframe;
|
||||
asm
|
||||
movq %rax,%gs:(8)
|
||||
end;
|
||||
|
||||
function on_ps4_run_thread(data:pthread):Longint; stdcall;
|
||||
type
|
||||
Tps4entry=function(arg:Pointer):Pointer; SysV_ABI_CDecl;
|
||||
|
@ -469,27 +215,28 @@ begin
|
|||
data^.Attr.stacksize_attr:=StackLength;
|
||||
//end;
|
||||
|
||||
writeln('BeginThread:',data^.name,':',HexStr(data^.entry));
|
||||
tcb_thread:=data;
|
||||
SetThreadDebugName(data^.ThreadId,'ps4:'+data^.name);
|
||||
WriteLn(SysLogPrefix, 'BeginThread:',HexStr(data^.entry));
|
||||
_thread_init;
|
||||
|
||||
wait_until_equal(data^.handle,0);
|
||||
|
||||
//init static tls in stack top
|
||||
//init static tls
|
||||
if (Telf_file(ps4_program.ps4_app.prog).pTls.full_size<>0) then
|
||||
begin
|
||||
base:=StackTop-SizeOf(Pointer);
|
||||
SetStackTop(base);
|
||||
PPointer(base)^:=Telf_file(ps4_program.ps4_app.prog)._get_tls;
|
||||
base:=Telf_file(ps4_program.ps4_app.prog)._get_tls;
|
||||
SetTlsBase(base);
|
||||
Assert(GetTlsBase=base);
|
||||
end;
|
||||
//init static tls in stack top
|
||||
//init static tls
|
||||
|
||||
//data^.arg:=Tps4entry(data^.entry)(data^.arg);
|
||||
data^.arg:=sysv_wrapper(data^.arg,data^.entry);
|
||||
ReadWriteBarrier;
|
||||
|
||||
_thread_cleanup;
|
||||
writeln('EndThread:',data^.name);
|
||||
writeln(SysLogPrefix,'EndThread:',data^.name);
|
||||
|
||||
if CAS(data^.detachstate,PTHREAD_CREATE_DETACHED,_PREPARE_FREE) then
|
||||
begin
|
||||
|
@ -513,13 +260,14 @@ end;
|
|||
|
||||
function ps4_pthread_create_name_np(pthread:p_pthread;pAttr:p_pthread_attr_t;entry:Pointer;arg:Pointer;name:Pchar):Integer; SysV_ABI_CDecl;
|
||||
Var
|
||||
attr:pthread_attr_t;
|
||||
data:pthread;
|
||||
Handle,ThreadId:TThreadID;
|
||||
sa:Pointer;
|
||||
ss:SizeUInt;
|
||||
creationFlags:dword;
|
||||
begin
|
||||
Writeln('pthread_create:',HexStr(entry),' ',name);
|
||||
Writeln(SysLogPrefix, 'pthread_create:',HexStr(entry),' ',name);
|
||||
|
||||
Result:=EINVAL;
|
||||
if (pthread=nil) then Exit;
|
||||
|
@ -536,65 +284,62 @@ begin
|
|||
|
||||
ReadWriteBarrier;
|
||||
|
||||
if (pAttr<>nil) and (pAttr^<>nil) then
|
||||
attr:=nil;
|
||||
if (pAttr<>nil) then
|
||||
begin
|
||||
data^.Attr:=pAttr^^;
|
||||
data^.detachstate:=pAttr^^.flags;
|
||||
ReadWriteBarrier;
|
||||
|
||||
creationFlags:=0;
|
||||
sa:=pAttr^^.stackaddr_attr;
|
||||
ss:=pAttr^^.stacksize_attr;
|
||||
|
||||
if (ss<PTHREAD_STACK_MIN) then
|
||||
begin
|
||||
ss:=PTHREAD_STACK_MIN;
|
||||
data^.Attr.stacksize_attr:=ss;
|
||||
end;
|
||||
|
||||
ThreadId:=0;
|
||||
_sig_lock;
|
||||
|
||||
Handle:=SysBeginThread(sa,ss,@on_ps4_run_thread,data,creationFlags,ThreadId);
|
||||
|
||||
_sig_unlock;
|
||||
if (Handle=0) then
|
||||
begin
|
||||
SwFreeMem(data);
|
||||
Exit(EAGAIN);
|
||||
end;
|
||||
|
||||
if (pAttr^^.cpuset<>0) then
|
||||
begin
|
||||
_sig_lock;
|
||||
SetThreadAffinityMask(Handle,pAttr^^.cpuset);
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
end else
|
||||
attr:=pAttr^;
|
||||
end;
|
||||
if (attr=nil) then
|
||||
begin
|
||||
ThreadId:=0;
|
||||
_sig_lock;
|
||||
|
||||
ss:=PTHREAD_STACK_MIN;
|
||||
data^.Attr.stacksize_attr:=ss;
|
||||
|
||||
Handle:=SysBeginThread(nil,ss,@on_ps4_run_thread,data,0,ThreadId);
|
||||
|
||||
_sig_unlock;
|
||||
if (Handle=0) then
|
||||
begin
|
||||
SwFreeMem(data);
|
||||
Exit(SCE_KERNEL_ERROR_EAGAIN);
|
||||
end;
|
||||
attr:=@_pthread_attr_default;
|
||||
end;
|
||||
|
||||
XCHG(data^.ThreadId,ThreadId);
|
||||
XCHG(data^.handle,Handle);
|
||||
data^.Attr:=attr^;
|
||||
data^.detachstate:=attr^.flags;
|
||||
ReadWriteBarrier;
|
||||
|
||||
creationFlags:=0;
|
||||
sa:=attr^.stackaddr_attr;
|
||||
ss:=attr^.stacksize_attr;
|
||||
|
||||
if (ss<PTHREAD_STACK_MIN) then
|
||||
begin
|
||||
ss:=PTHREAD_STACK_MIN;
|
||||
data^.Attr.stacksize_attr:=ss;
|
||||
end;
|
||||
|
||||
if (attr^.prio>767) or (attr^.prio<256) then //if not valid set default
|
||||
begin
|
||||
data^.Attr.prio:=SCE_KERNEL_PRIO_FIFO_DEFAULT;
|
||||
end;
|
||||
|
||||
ThreadId:=0;
|
||||
|
||||
_sig_lock;
|
||||
Handle:=SysBeginThread(sa,ss,@on_ps4_run_thread,data,creationFlags,ThreadId);
|
||||
_sig_unlock;
|
||||
|
||||
if (Handle=0) then
|
||||
begin
|
||||
SwFreeMem(data);
|
||||
Exit(EAGAIN);
|
||||
end;
|
||||
|
||||
if (data^.Attr.cpuset<>0) then
|
||||
begin
|
||||
_sig_lock;
|
||||
SetThreadAffinityMask(Handle,attr^.cpuset);
|
||||
_sig_unlock;
|
||||
end;
|
||||
sys_set_thread_prior(Handle,data^.Attr.prio);
|
||||
|
||||
pthread^:=data;
|
||||
end;
|
||||
|
||||
XCHG(data^.ThreadId,ThreadId);
|
||||
XCHG(data^.handle,Handle);
|
||||
|
||||
pthread^:=data;
|
||||
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
|
@ -635,7 +380,7 @@ end;
|
|||
function ps4_scePthreadJoin(_pthread:pthread;value:PPointer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (_pthread=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
Writeln('scePthreadJoin:',_pthread^.name);
|
||||
Writeln(SysLogPrefix, 'scePthreadJoin:',_pthread^.name);
|
||||
|
||||
if CAS(_pthread^.detachstate,PTHREAD_CREATE_JOINABLE,_PREPARE_FREE) then
|
||||
begin
|
||||
|
@ -699,13 +444,34 @@ begin
|
|||
Result:=ord(t1=t2);
|
||||
end;
|
||||
|
||||
function ps4_scePthreadCancel(_pthread:pthread):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if _pthread=nil then
|
||||
Exit(SCE_KERNEL_ERROR_ESRCH);
|
||||
Writeln(SysLogPrefix, 'scePthreadCancel');
|
||||
//Dirty thread termination
|
||||
if CAS(_pthread^.detachstate,PTHREAD_CREATE_DETACHED,_PREPARE_FREE) then
|
||||
begin
|
||||
_free_pthread(_pthread);
|
||||
end else
|
||||
begin
|
||||
CAS(_pthread^.detachstate,PTHREAD_CREATE_JOINABLE,_PREPARE_JOIN);
|
||||
_sig_lock;
|
||||
Windows.TerminateThread(_pthread^.handle,0);
|
||||
_pthread^.handle:=0;
|
||||
_sig_unlock;
|
||||
//_free_pthread(_pthread);
|
||||
end;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
procedure ps4_scePthreadExit(value_ptr:Pointer); SysV_ABI_CDecl;
|
||||
var
|
||||
data:pthread;
|
||||
begin
|
||||
data:=tcb_thread;
|
||||
if (data=nil) then Exit;
|
||||
Writeln('ExitThread:',data^.name);
|
||||
Writeln(SysLogPrefix, 'ExitThread');
|
||||
data^.arg:=value_ptr;
|
||||
|
||||
ReadWriteBarrier;
|
||||
|
@ -732,14 +498,33 @@ end;
|
|||
function ps4_pthread_setcancelstate(state:Integer;oldstate:PInteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
Case state of
|
||||
PTHREAD_CANCEL_DISABLE:{Writeln('PTHREAD_CANCEL_DISABLE')};
|
||||
PTHREAD_CANCEL_ENABLE :{Writeln('PTHREAD_CANCEL_ENABLE')};
|
||||
else
|
||||
Exit(EINVAL);
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_pthread_setcanceltype(_type:Integer;oldtype:PInteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
Case _type of
|
||||
PTHREAD_CANCEL_DEFERRED :;
|
||||
PTHREAD_CANCEL_ASYNCHRONOUS:;
|
||||
else
|
||||
Exit(EINVAL);
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadSetcancelstate(state:Integer;oldState:PInteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_setcancelstate(state,oldState));
|
||||
end;
|
||||
|
||||
function ps4_scePthreadSetcanceltype(_type:Integer;oldType:PInteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_setcanceltype(_type,oldType));
|
||||
end;
|
||||
|
||||
function ps4_pthread_self():pthread; SysV_ABI_CDecl;
|
||||
|
@ -762,18 +547,49 @@ begin
|
|||
Result:=tcb_thread^.ThreadId;
|
||||
end;
|
||||
|
||||
function ps4_pthread_getname_np(_pthread:pthread;name:Pchar):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (_pthread=nil) or (name=nil) then Exit(EINVAL);
|
||||
MoveChar0(_pthread^.name,name^,32);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadGetname(_pthread:pthread;name:Pchar):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (_pthread=nil) or (name=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
MoveChar0(_pthread^.name,name^,32);
|
||||
Result:=px2sce(ps4_pthread_getname_np(_pthread,name));
|
||||
end;
|
||||
|
||||
function ps4_pthread_rename_np(_pthread:pthread;name:Pchar):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (_pthread=nil) then Exit(EINVAL);
|
||||
FillChar(_pthread^.name,32,0);
|
||||
if (name<>nil) then
|
||||
begin
|
||||
MoveChar0(name^,_pthread^.name,32);
|
||||
end;
|
||||
SetThreadDebugName(_pthread^.ThreadId,'ps4:'+_pthread^.name);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadRename(_pthread:pthread;name:Pchar):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (_pthread=nil) or (name=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
MoveChar0(name^,_pthread^.name,32);
|
||||
Result:=0;
|
||||
Result:=px2sce(ps4_pthread_rename_np(_pthread,name));
|
||||
end;
|
||||
|
||||
procedure ps4_pthread_set_name_np(_pthread:pthread;name:Pchar); SysV_ABI_CDecl;
|
||||
begin
|
||||
if (_pthread=nil) then Exit;
|
||||
FillChar(_pthread^.name,32,0);
|
||||
if (name<>nil) then
|
||||
begin
|
||||
MoveChar0(name^,_pthread^.name,32);
|
||||
end;
|
||||
SetThreadDebugName(_pthread^.ThreadId,'ps4:'+_pthread^.name);
|
||||
end;
|
||||
|
||||
procedure ps4_scePthreadSetName(_pthread:pthread;name:Pchar); SysV_ABI_CDecl;
|
||||
begin
|
||||
ps4_pthread_set_name_np(_pthread,name);
|
||||
end;
|
||||
|
||||
function ps4_scePthreadSetaffinity(_pthread:pthread;mask:QWORD):Integer; SysV_ABI_CDecl;
|
||||
|
@ -811,124 +627,88 @@ begin
|
|||
mask^:=_pthread^.Attr.cpuset;
|
||||
end;
|
||||
|
||||
const
|
||||
PRIORITY_TABLE:array[0..30] of SmallInt=(
|
||||
{ 0} THREAD_PRIORITY_IDLE , //-15
|
||||
{ 1} THREAD_PRIORITY_IDLE , //-15
|
||||
{ 2} THREAD_PRIORITY_IDLE , //-15
|
||||
{ 3} THREAD_PRIORITY_LOWEST , // -2
|
||||
{ 4} THREAD_PRIORITY_LOWEST , // -2
|
||||
{ 5} THREAD_PRIORITY_LOWEST , // -2
|
||||
{ 6} THREAD_PRIORITY_LOWEST , // -2
|
||||
{ 7} THREAD_PRIORITY_LOWEST , // -2
|
||||
{ 8} THREAD_PRIORITY_BELOW_NORMAL , // -1
|
||||
{ 9} THREAD_PRIORITY_BELOW_NORMAL , // -1
|
||||
{10} THREAD_PRIORITY_BELOW_NORMAL , // -1
|
||||
{11} THREAD_PRIORITY_BELOW_NORMAL , // -1
|
||||
{12} THREAD_PRIORITY_BELOW_NORMAL , // -1
|
||||
{13} THREAD_PRIORITY_NORMAL , // 0
|
||||
{14} THREAD_PRIORITY_NORMAL , // 0
|
||||
{15} THREAD_PRIORITY_NORMAL , // 0
|
||||
{16} THREAD_PRIORITY_NORMAL , // 0
|
||||
{17} THREAD_PRIORITY_NORMAL , // 0
|
||||
{18} THREAD_PRIORITY_ABOVE_NORMAL , // 1
|
||||
{19} THREAD_PRIORITY_ABOVE_NORMAL , // 1
|
||||
{20} THREAD_PRIORITY_ABOVE_NORMAL , // 1
|
||||
{21} THREAD_PRIORITY_ABOVE_NORMAL , // 1
|
||||
{22} THREAD_PRIORITY_ABOVE_NORMAL , // 1
|
||||
{23} THREAD_PRIORITY_HIGHEST , // 2
|
||||
{24} THREAD_PRIORITY_HIGHEST , // 2
|
||||
{25} THREAD_PRIORITY_HIGHEST , // 2
|
||||
{26} THREAD_PRIORITY_HIGHEST , // 2
|
||||
{27} THREAD_PRIORITY_HIGHEST , // 2
|
||||
{28} THREAD_PRIORITY_TIME_CRITICAL, // 15
|
||||
{29} THREAD_PRIORITY_TIME_CRITICAL, // 15
|
||||
{30} THREAD_PRIORITY_TIME_CRITICAL // 15
|
||||
);
|
||||
function ps4_pthread_getprio(_pthread:pthread):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (_pthread=nil) then Exit(-1);
|
||||
Result:=_pthread^.Attr.prio;
|
||||
end;
|
||||
|
||||
//ThreadGetPriority = -15 and 15. :0..30
|
||||
//scePthreadGetprio = 767 and 256 :0..511
|
||||
function ps4_scePthreadGetprio(_pthread:pthread;prio:PInteger):Integer; SysV_ABI_CDecl;
|
||||
Var
|
||||
r:Integer;
|
||||
begin
|
||||
if (_pthread=nil) or (prio=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
_sig_lock;
|
||||
r:=System.ThreadGetPriority(_pthread^.handle);
|
||||
_sig_unlock;
|
||||
prio^:=767-(((r+15)*511) div 30);
|
||||
prio^:=_pthread^.Attr.prio;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_pthread_setprio(_pthread:pthread;prio:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (_pthread=nil) then Exit(EINVAL);
|
||||
|
||||
if (_pthread^.Attr.sched_policy=SCHED_OTHER) or
|
||||
(_pthread^.Attr.prio=prio) then
|
||||
begin
|
||||
_pthread^.Attr.prio:=prio;
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
Result:=sys_set_thread_prior(_pthread^.handle,prio);
|
||||
if (Result<>0) then
|
||||
begin
|
||||
_pthread^.Attr.prio:=prio;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadSetprio(_pthread:pthread;prio:Integer):Integer; SysV_ABI_CDecl;
|
||||
Var
|
||||
r:Integer;
|
||||
begin
|
||||
if (_pthread=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
|
||||
if (prio>767) then prio:=767;
|
||||
if (prio<256) then prio:=256;
|
||||
|
||||
//Writeln('scePthreadSetprio:',prio);
|
||||
r:=(((767-prio)*30) div 511);
|
||||
r:=PRIORITY_TABLE[r];
|
||||
|
||||
Result:=0;
|
||||
_sig_lock;
|
||||
if not System.ThreadSetPriority(_pthread^.handle,r) then
|
||||
begin
|
||||
Result:=SCE_KERNEL_ERROR_ESRCH;
|
||||
end;
|
||||
_sig_unlock;
|
||||
Result:=px2sce(ps4_pthread_setprio(_pthread,prio));
|
||||
end;
|
||||
|
||||
//ThreadGetPriority = -15 and 15. :0..30
|
||||
function ps4_scePthreadGetschedparam(_pthread:pthread;policy:PInteger;param:PSceKernelSchedParam):Integer; SysV_ABI_CDecl;
|
||||
Var
|
||||
r:Integer;
|
||||
function ps4_pthread_getschedparam(_pthread:pthread;policy:PInteger;param:PSceKernelSchedParam):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (_pthread=nil) or (policy=nil) or (param=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
if (_pthread=nil) or (policy=nil) or (param=nil) then Exit(EINVAL);
|
||||
|
||||
policy^:=SCE_KERNEL_SCHED_RR;
|
||||
|
||||
_sig_lock;
|
||||
r:=System.ThreadGetPriority(_pthread^.handle);
|
||||
_sig_unlock;
|
||||
param^.sched_priority:=(r+15);
|
||||
policy^:=_pthread^.Attr.sched_policy;
|
||||
param^.sched_priority:=_pthread^.Attr.prio;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadGetschedparam(_pthread:pthread;policy:PInteger;param:PSceKernelSchedParam):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_getschedparam(_pthread,policy,param));
|
||||
end;
|
||||
|
||||
function ps4_pthread_setschedparam(_pthread:pthread;policy:Integer;param:PSceKernelSchedParam):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (_pthread=nil) or (param=nil) then Exit(EINVAL);
|
||||
|
||||
if (_pthread^.Attr.sched_policy=policy) and
|
||||
((policy=SCHED_OTHER) or (_pthread^.Attr.prio=param^.sched_priority)) then
|
||||
begin
|
||||
_pthread^.Attr.prio:=param^.sched_priority;
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
Result:=sys_set_thread_prior(_pthread^.handle,param^.sched_priority);
|
||||
if (Result<>0) then
|
||||
begin
|
||||
_pthread^.Attr.sched_policy:=policy;
|
||||
_pthread^.Attr.prio:=param^.sched_priority;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadSetschedparam(_pthread:pthread;policy:Integer;param:PSceKernelSchedParam):Integer; SysV_ABI_CDecl;
|
||||
Var
|
||||
r:Integer;
|
||||
begin
|
||||
if (_pthread=nil) or (param=nil) then Exit(SCE_KERNEL_ERROR_EINVAL);
|
||||
|
||||
r:=param^.sched_priority;
|
||||
|
||||
if (r>30) then r:=30;
|
||||
if (r<0) then r:=0;
|
||||
|
||||
r:=PRIORITY_TABLE[r];
|
||||
|
||||
Result:=0;
|
||||
_sig_lock;
|
||||
if not System.ThreadSetPriority(_pthread^.handle,r) then
|
||||
begin
|
||||
Result:=SCE_KERNEL_ERROR_ESRCH;
|
||||
end;
|
||||
_sig_unlock;
|
||||
Result:=px2sce(ps4_pthread_setschedparam(_pthread,policy,param));
|
||||
end;
|
||||
|
||||
|
||||
function ps4_sched_get_priority_max(policy:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=30;
|
||||
Result:=SCE_KERNEL_PRIO_FIFO_HIGHEST;
|
||||
end;
|
||||
|
||||
function ps4_sched_get_priority_min(policy:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
Result:=SCE_KERNEL_PRIO_FIFO_LOWEST;
|
||||
end;
|
||||
|
||||
procedure ps4_scePthreadYield; SysV_ABI_CDecl;
|
||||
|
|
|
@ -0,0 +1,382 @@
|
|||
unit ps4_pthread_attr;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
atomic,
|
||||
sys_kernel,
|
||||
sys_pthread;
|
||||
|
||||
const
|
||||
default_name:Pchar='main';
|
||||
|
||||
var
|
||||
_pthread_attr_default:pthread_attr=(
|
||||
sched_policy :SCHED_OTHER;
|
||||
sched_inherit :PTHREAD_INHERIT_SCHED;
|
||||
prio :SCE_KERNEL_PRIO_FIFO_DEFAULT;
|
||||
suspend :THR_CREATE_RUNNING;
|
||||
flags :0{PTHREAD_SCOPE_SYSTEM};
|
||||
_align :0;
|
||||
stackaddr_attr:nil;
|
||||
stacksize_attr:$10000;
|
||||
guardsize_attr:0;
|
||||
cpuset :0;
|
||||
cpusetsize :0
|
||||
);
|
||||
|
||||
function ps4_pthread_set_defaultstacksize_np(size:QWORD):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadSetDefaultstacksize(size:QWORD):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_attr_init(pAttr:p_pthread_attr_t):Integer; SysV_ABI_CDecl;
|
||||
function ps4_pthread_attr_destroy(pAttr:p_pthread_attr_t):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_scePthreadAttrInit(pAttr:p_pthread_attr_t):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrDestroy(pAttr:p_pthread_attr_t):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_attr_setstacksize(pAttr:p_pthread_attr_t;size:size_t):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrSetstacksize(pAttr:p_pthread_attr_t;size:size_t):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_attr_setdetachstate(pAttr:p_pthread_attr_t;detachstate:Integer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrSetdetachstate(pAttr:p_pthread_attr_t;detachstate:Integer):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_attr_setschedpolicy(pAttr:p_pthread_attr_t;policy:Integer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrSetschedpolicy(pAttr:p_pthread_attr_t;policy:Integer):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_attr_getschedpolicy(pAttr:p_pthread_attr_t;policy:PInteger):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrGetschedpolicy(pAttr:p_pthread_attr_t;policy:PInteger):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_attr_setschedparam(pAttr:p_pthread_attr_t;param:PInteger):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrSetschedparam(pAttr:p_pthread_attr_t;param:PInteger):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_attr_getschedparam(pAttr:p_pthread_attr_t;param:PInteger):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrGetschedparam(pAttr:p_pthread_attr_t;param:PInteger):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_attr_setinheritsched(pAttr:p_pthread_attr_t;sched_inherit:Integer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrSetinheritsched(pAttr:p_pthread_attr_t;sched_inherit:Integer):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_scePthreadAttrSetaffinity(pAttr:p_pthread_attr_t;mask:QWORD):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrGetaffinity(pAttr:p_pthread_attr_t;mask:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_attr_setguardsize(pAttr:p_pthread_attr_t;guardSize:QWORD):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrSetguardsize(pAttr:p_pthread_attr_t;guardSize:QWORD):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_attr_getguardsize(pAttr:p_pthread_attr_t;guardSize:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrGetguardsize(pAttr:p_pthread_attr_t;guardSize:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_attr_setstackaddr(pAttr:p_pthread_attr_t;stackAddr:Pointer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrSetstackaddr(pAttr:p_pthread_attr_t;stackAddr:Pointer):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_attr_getstackaddr(pAttr:p_pthread_attr_t;stackAddr:PPointer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrGetstackaddr(pAttr:p_pthread_attr_t;stackAddr:PPointer):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_attr_getstacksize(pAttr:p_pthread_attr_t;stackSize:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrGetstacksize(pAttr:p_pthread_attr_t;stackSize:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_attr_setstack(pAttr:p_pthread_attr_t;stackAddr:Pointer;stackSize:QWORD):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrSetstack(pAttr:p_pthread_attr_t;stackAddr:Pointer;stackSize:QWORD):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_attr_getstack(pAttr:p_pthread_attr_t;stackAddr:PPointer;stackSize:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrGetstack(pAttr:p_pthread_attr_t;stackAddr:PPointer;stackSize:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_pthread_attr_getdetachstate(pAttr:p_pthread_attr_t;detachstate:Pinteger):Integer; SysV_ABI_CDecl;
|
||||
function ps4_scePthreadAttrGetdetachstate(pAttr:p_pthread_attr_t;detachstate:Pinteger):Integer; SysV_ABI_CDecl;
|
||||
|
||||
implementation
|
||||
|
||||
function ps4_pthread_set_defaultstacksize_np(size:QWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=EINVAL;
|
||||
if (size>PTHREAD_STACK_MIN) then
|
||||
begin
|
||||
_pthread_attr_default.stacksize_attr:=size;
|
||||
Result:=0;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadSetDefaultstacksize(size:QWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_set_defaultstacksize_np(size));
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_init(pAttr:p_pthread_attr_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln(SysLogPrefix, 'pthread_attr_init');
|
||||
if (pAttr=nil) then Exit(EINVAL);
|
||||
pAttr^:=SwAllocMem(SizeOf(pthread_attr));
|
||||
if (pAttr^=nil) then Exit(ENOMEM);
|
||||
pAttr^^:=_pthread_attr_default;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_destroy(pAttr:p_pthread_attr_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln(SysLogPrefix, 'pthread_attr_destroy');
|
||||
if (pAttr=nil) then Exit(EINVAL);
|
||||
if (pAttr^=nil) then Exit(EINVAL);
|
||||
SwFreeMem(XCHG(pAttr^,nil));
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrInit(pAttr:p_pthread_attr_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_attr_init(pAttr));
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrDestroy(pAttr:p_pthread_attr_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_attr_destroy(pAttr));
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_setstacksize(pAttr:p_pthread_attr_t;size:size_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pAttr=nil) then Exit(EINVAL);
|
||||
if (pAttr^=nil) then Exit(EINVAL);
|
||||
if (size<PTHREAD_STACK_MIN) then Exit(EINVAL);
|
||||
pAttr^^.stacksize_attr:=size;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrSetstacksize(pAttr:p_pthread_attr_t;size:size_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_attr_setstacksize(pAttr,size));
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_setdetachstate(pAttr:p_pthread_attr_t;detachstate:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=EINVAL;
|
||||
if (pAttr=nil) then Exit;
|
||||
if (pAttr^=nil) then Exit;
|
||||
|
||||
Case detachstate of
|
||||
PTHREAD_CREATE_JOINABLE:;
|
||||
PTHREAD_CREATE_DETACHED:;
|
||||
else
|
||||
Exit(EINVAL);
|
||||
end;
|
||||
|
||||
pAttr^^.flags:=detachstate;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrSetdetachstate(pAttr:p_pthread_attr_t;detachstate:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_attr_setdetachstate(pAttr,detachstate));
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_setschedpolicy(pAttr:p_pthread_attr_t;policy:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pAttr=nil) then Exit(EINVAL);
|
||||
if (pAttr^=nil) then Exit(EINVAL);
|
||||
if (policy<SCHED_FIFO) or (policy>SCHED_RR) then Exit(ENOTSUP);
|
||||
pAttr^^.sched_policy:=policy;
|
||||
pAttr^^.prio:=SCE_KERNEL_PRIO_FIFO_DEFAULT;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrSetschedpolicy(pAttr:p_pthread_attr_t;policy:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_attr_setschedpolicy(pAttr,policy));
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_getschedpolicy(pAttr:p_pthread_attr_t;policy:PInteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=EINVAL;
|
||||
if (pAttr=nil) or (policy=nil) then Exit;
|
||||
if (pAttr^=nil) then Exit;
|
||||
policy^:=pAttr^^.sched_policy;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrGetschedpolicy(pAttr:p_pthread_attr_t;policy:PInteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_attr_getschedpolicy(pAttr,policy));
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_setschedparam(pAttr:p_pthread_attr_t;param:PInteger):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
policy:Integer;
|
||||
begin
|
||||
if (pAttr=nil) then Exit(EINVAL);
|
||||
if (pAttr^=nil) then Exit(EINVAL);
|
||||
if (param=nil) then Exit(ENOTSUP);
|
||||
|
||||
policy:=pAttr^^.sched_policy;
|
||||
if (policy=SCHED_FIFO) or (policy=SCHED_RR) then
|
||||
begin
|
||||
if (param^>767) or (param^<256) then Exit(ENOTSUP);
|
||||
end;
|
||||
|
||||
pAttr^^.prio:=param^;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrSetschedparam(pAttr:p_pthread_attr_t;param:PInteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_attr_setschedparam(pAttr,param));
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_getschedparam(pAttr:p_pthread_attr_t;param:PInteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=EINVAL;
|
||||
if (pAttr=nil) or (param=nil) then Exit;
|
||||
if (pAttr^=nil) then Exit;
|
||||
param^:=pAttr^^.prio;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrGetschedparam(pAttr:p_pthread_attr_t;param:PInteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_attr_getschedparam(pAttr,param));
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_setinheritsched(pAttr:p_pthread_attr_t;sched_inherit:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
if (pAttr=nil) then Exit(EINVAL);
|
||||
if (pAttr^=nil) then Exit(EINVAL);
|
||||
|
||||
Case sched_inherit of
|
||||
PTHREAD_INHERIT_SCHED :;
|
||||
PTHREAD_EXPLICIT_SCHED:;
|
||||
else
|
||||
Exit(ENOTSUP);
|
||||
end;
|
||||
|
||||
pAttr^^.sched_inherit:=sched_inherit;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrSetinheritsched(pAttr:p_pthread_attr_t;sched_inherit:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_attr_setinheritsched(pAttr,sched_inherit));
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrSetaffinity(pAttr:p_pthread_attr_t;mask:QWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=SCE_KERNEL_ERROR_EINVAL;
|
||||
if (pAttr=nil) then Exit;
|
||||
if (pAttr^=nil) then Exit;
|
||||
pAttr^^.cpuset:=mask;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrGetaffinity(pAttr:p_pthread_attr_t;mask:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=SCE_KERNEL_ERROR_EINVAL;
|
||||
if (pAttr=nil) or (mask=nil) then Exit;
|
||||
if (pAttr^=nil) then Exit;
|
||||
mask^:=pAttr^^.cpuset;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_setguardsize(pAttr:p_pthread_attr_t;guardSize:QWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pAttr=nil) then Exit(EINVAL);
|
||||
if (pAttr^=nil) then Exit(EINVAL);
|
||||
pAttr^^.guardsize_attr:=guardSize;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrSetguardsize(pAttr:p_pthread_attr_t;guardSize:QWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_attr_setguardsize(pAttr,guardSize));
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_getguardsize(pAttr:p_pthread_attr_t;guardSize:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pAttr=nil) or (guardSize=nil) then Exit(EINVAL);
|
||||
if (pAttr^=nil) then Exit(EINVAL);
|
||||
guardSize^:=pAttr^^.guardsize_attr;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrGetguardsize(pAttr:p_pthread_attr_t;guardSize:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_attr_getguardsize(pAttr,guardSize));
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_setstackaddr(pAttr:p_pthread_attr_t;stackAddr:Pointer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pAttr=nil) or (stackAddr=nil) then Exit(EINVAL);
|
||||
if (pAttr^=nil) then Exit(EINVAL);
|
||||
pAttr^^.stackaddr_attr:=stackAddr;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrSetstackaddr(pAttr:p_pthread_attr_t;stackAddr:Pointer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_attr_setstackaddr(pAttr,stackAddr));
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_getstackaddr(pAttr:p_pthread_attr_t;stackAddr:PPointer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pAttr=nil) or (stackAddr=nil) then Exit(EINVAL);
|
||||
if (pAttr^=nil) then Exit(EINVAL);
|
||||
stackAddr^:=pAttr^^.stackaddr_attr;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrGetstackaddr(pAttr:p_pthread_attr_t;stackAddr:PPointer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_attr_getstackaddr(pAttr,stackAddr));
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_getstacksize(pAttr:p_pthread_attr_t;stackSize:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pAttr=nil) or (stackSize=nil) then Exit(EINVAL);
|
||||
if (pAttr^=nil) then Exit(EINVAL);
|
||||
stackSize^:=pAttr^^.stacksize_attr;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrGetstacksize(pAttr:p_pthread_attr_t;stackSize:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_attr_getstacksize(pAttr,stackSize));
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_setstack(pAttr:p_pthread_attr_t;stackAddr:Pointer;stackSize:QWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pAttr=nil) or (stackAddr=nil) or (stackSize<PTHREAD_STACK_MIN) then Exit(EINVAL);
|
||||
if (pAttr^=nil) then Exit(EINVAL);
|
||||
pAttr^^.stackaddr_attr:=stackAddr;
|
||||
pAttr^^.stacksize_attr:=stackSize;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrSetstack(pAttr:p_pthread_attr_t;stackAddr:Pointer;stackSize:QWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_attr_setstack(pAttr,stackAddr,stackSize));
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_getstack(pAttr:p_pthread_attr_t;stackAddr:PPointer;stackSize:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pAttr=nil) or (stackAddr=nil) or (stackSize=nil) then Exit(EINVAL);
|
||||
if (pAttr^=nil) then Exit(EINVAL);
|
||||
stackAddr^:=pAttr^^.stackaddr_attr;
|
||||
stackSize^:=pAttr^^.stacksize_attr;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrGetstack(pAttr:p_pthread_attr_t;stackAddr:PPointer;stackSize:PQWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_attr_getstack(pAttr,stackAddr,stackSize));
|
||||
end;
|
||||
|
||||
function ps4_pthread_attr_getdetachstate(pAttr:p_pthread_attr_t;detachstate:Pinteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pAttr=nil) or (detachstate=nil) then Exit(EINVAL);
|
||||
if (pAttr^=nil) then Exit(EINVAL);
|
||||
detachstate^:=pAttr^^.flags;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_scePthreadAttrGetdetachstate(pAttr:p_pthread_attr_t;detachstate:Pinteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=px2sce(ps4_pthread_attr_getdetachstate(pAttr,detachstate));
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
@ -129,6 +129,7 @@ type
|
|||
end;
|
||||
|
||||
function ps4_sceKernelCreateEqueue(outEq:PSceKernelEqueue;name:PChar):Integer; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelDeleteEqueue(eq:PSceKernelEqueue):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_sceKernelWaitEqueue(
|
||||
eq:SceKernelEqueue;
|
||||
|
@ -315,6 +316,11 @@ begin
|
|||
_sig_unlock;
|
||||
end;
|
||||
|
||||
function ps4_sceKernelDeleteEqueue(eq:PSceKernelEqueue):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function _post_event(eq:SceKernelEqueue;node:PKEventNode;cb:TKFetchEvent):Boolean;
|
||||
var
|
||||
i,t,wait:DWORD;
|
||||
|
@ -553,7 +559,7 @@ begin
|
|||
begin
|
||||
Result:=0;
|
||||
node:=P^;
|
||||
HAMT_delete32(@eq^.FUserEvents.hamt,id);
|
||||
HAMT_delete32(@eq^.FUserEvents.hamt,id,nil);
|
||||
_free_kevent_node(node);
|
||||
end else
|
||||
begin
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
unit ps4_scesocket;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
sys_kernel,
|
||||
ps4_libSceNet,
|
||||
ps4_program,
|
||||
Classes,
|
||||
SysUtils;
|
||||
|
||||
type
|
||||
pSceNetId=^SceNetId;
|
||||
SceNetId=Integer;
|
||||
|
||||
function ps4_socket(family,_type,protocol:Integer):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_bind(s:SceNetId;
|
||||
const addr:pSceNetSockaddr;
|
||||
addrlen:SceNetSocklen_t):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_setsockopt(s:SceNetId;
|
||||
level,optname:Integer;
|
||||
const optval:Pointer;
|
||||
optlen:SceNetSocklen_t):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_select(s:SceNetId;
|
||||
readfds :Pointer;
|
||||
writefds :Pointer;
|
||||
exceptfds:Pointer;
|
||||
timeout :Pointer
|
||||
):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_recvfrom(s:SceNetId;
|
||||
buf:Pointer;
|
||||
len:QWORD;
|
||||
flags:Integer;
|
||||
addr:pSceNetSockaddr;
|
||||
paddrlen:pSceNetSocklen_t):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_listen(s:SceNetId;backlog:Integer):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_shutdown(s:SceNetId;how:Integer):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_accept(s:SceNetId;
|
||||
addr:pSceNetSockaddr;
|
||||
paddrlen:pSceNetSocklen_t):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_sendto(s:SceNetId;
|
||||
const buf:Pointer;
|
||||
len:QWORD;
|
||||
flags:Integer;
|
||||
const addr:pSceNetSockaddr;
|
||||
paddrlen:pSceNetSocklen_t):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_getsockname(s:SceNetId;
|
||||
addr:pSceNetSockaddr;
|
||||
paddrlen:pSceNetSocklen_t):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_connect(s:SceNetId;
|
||||
const addr:pSceNetSockaddr;
|
||||
addrlen:SceNetSocklen_t):Integer; SysV_ABI_CDecl;
|
||||
|
||||
implementation
|
||||
|
||||
function ps4_socket(family,_type,protocol:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_bind(s:SceNetId;
|
||||
const addr:pSceNetSockaddr;
|
||||
addrlen:SceNetSocklen_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_setsockopt(s:SceNetId;
|
||||
level,optname:Integer;
|
||||
const optval:Pointer;
|
||||
optlen:SceNetSocklen_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_select(s:SceNetId;
|
||||
readfds :Pointer;
|
||||
writefds :Pointer;
|
||||
exceptfds:Pointer;
|
||||
timeout :Pointer
|
||||
):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_recvfrom(s:SceNetId;
|
||||
buf:Pointer;
|
||||
len:QWORD;
|
||||
flags:Integer;
|
||||
addr:pSceNetSockaddr;
|
||||
paddrlen:pSceNetSocklen_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_listen(s:SceNetId;backlog:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_shutdown(s:SceNetId;how:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_accept(s:SceNetId;
|
||||
addr:pSceNetSockaddr;
|
||||
paddrlen:pSceNetSocklen_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
sleep(200);
|
||||
Result:=0;
|
||||
if (addr<>nil) then
|
||||
begin
|
||||
addr^:=default_addr;
|
||||
end;
|
||||
if (paddrlen<>nil) then
|
||||
begin
|
||||
paddrlen^:=SizeOf(SceNetSockaddr);
|
||||
end;
|
||||
Result:=_set_errno(EAGAIN);
|
||||
end;
|
||||
|
||||
function ps4_sendto(s:SceNetId;
|
||||
const buf:Pointer;
|
||||
len:QWORD;
|
||||
flags:Integer;
|
||||
const addr:pSceNetSockaddr;
|
||||
paddrlen:pSceNetSocklen_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_getsockname(s:SceNetId;
|
||||
addr:pSceNetSockaddr;
|
||||
paddrlen:pSceNetSocklen_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
if (addr<>nil) then
|
||||
begin
|
||||
addr^:=default_addr;
|
||||
end;
|
||||
if (paddrlen<>nil) then
|
||||
begin
|
||||
paddrlen^:=SizeOf(SceNetSockaddr);
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_connect(s:SceNetId;
|
||||
const addr:pSceNetSockaddr;
|
||||
addrlen:SceNetSocklen_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
sleep(200);
|
||||
Result:=_set_errno(ECONNREFUSED);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
@ -8,6 +8,7 @@ uses
|
|||
Windows,
|
||||
sys_signal;
|
||||
|
||||
function ps4_sigemptyset(_set:p_sigset_t):Integer; SysV_ABI_CDecl;
|
||||
function ps4_sigfillset(_set:p_sigset_t):Integer; SysV_ABI_CDecl;
|
||||
function ps4_sigaddset(_set:p_sigset_t;signum:Integer):Integer; SysV_ABI_CDecl;
|
||||
function ps4_sigprocmask(how:Integer;_set,oldset:p_sigset_t):Integer; SysV_ABI_CDecl;
|
||||
|
@ -31,6 +32,14 @@ uses
|
|||
atomic,
|
||||
sys_kernel;
|
||||
|
||||
function ps4_sigemptyset(_set:p_sigset_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (_set=nil) then Exit(_set_errno(EINVAL));
|
||||
_set^.qwords[0]:=0;
|
||||
_set^.qwords[1]:=0;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sigfillset(_set:p_sigset_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (_set=nil) then Exit(_set_errno(EINVAL));
|
||||
|
|
|
@ -36,6 +36,8 @@ function ps4_gettimeofday(tv:Ptimeval;tz:Ptimezone):Integer; SysV_ABI_CDecl;
|
|||
function ps4_clock_getres(clock_id:Integer;tp:Ptimespec):Integer; SysV_ABI_CDecl;
|
||||
function ps4_clock_gettime(clock_id:Integer;tp:Ptimespec):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_sceKernelClockGetres(clock_id:Integer;tp:Ptimespec):Integer; SysV_ABI_CDecl;
|
||||
|
||||
function ps4_sceKernelGettimeofday(tv:Ptimeval):Integer; SysV_ABI_CDecl;
|
||||
function ps4_sceKernelGettimezone(tz:Ptimezone):Integer; SysV_ABI_CDecl;
|
||||
|
||||
|
@ -173,14 +175,11 @@ end;
|
|||
|
||||
function ps4_sceKernelSettimeofday(tv:Ptimeval;tz:Ptimezone):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=_set_errno(px2sce(EPERM));
|
||||
_set_errno(EPERM);
|
||||
Result:=px2sce(EPERM);
|
||||
end;
|
||||
|
||||
function ps4_clock_getres(clock_id:Integer;tp:Ptimespec):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
pc,pf:QWORD;
|
||||
TimeAdjustment,TimeIncrement:DWORD;
|
||||
TimeAdjustmentDisabled:BOOL;
|
||||
begin
|
||||
if (tp=nil) then Exit(_set_errno(EINVAL));
|
||||
|
||||
|
@ -200,40 +199,16 @@ begin
|
|||
CLOCK_REALTIME_PRECISE,
|
||||
CLOCK_REALTIME_FAST:
|
||||
begin
|
||||
|
||||
TimeAdjustment:=0;
|
||||
TimeIncrement:=0;
|
||||
TimeAdjustmentDisabled:=false;
|
||||
|
||||
_sig_lock;
|
||||
GetSystemTimeAdjustment(TimeAdjustment,TimeIncrement,TimeAdjustmentDisabled);
|
||||
_sig_unlock;
|
||||
|
||||
tp^.tv_sec :=0;
|
||||
tp^.tv_nsec:=TimeIncrement*100;
|
||||
|
||||
if (tp^.tv_nsec<1) then
|
||||
begin
|
||||
tp^.tv_nsec:=1;
|
||||
end;
|
||||
|
||||
tp^.tv_nsec:=100;
|
||||
end;
|
||||
|
||||
CLOCK_MONOTONIC,
|
||||
CLOCK_MONOTONIC_PRECISE,
|
||||
CLOCK_MONOTONIC_FAST:
|
||||
begin
|
||||
|
||||
SwQueryPerformanceCounter(pc,pf);
|
||||
|
||||
tp^.tv_sec :=0;
|
||||
tp^.tv_nsec:=(POW10_9+(pf shr 1)) div pf;
|
||||
|
||||
if (tp^.tv_nsec<1) then
|
||||
begin
|
||||
tp^.tv_nsec:=1;
|
||||
end;
|
||||
|
||||
tp^.tv_nsec:=100;
|
||||
end;
|
||||
|
||||
else
|
||||
|
@ -242,6 +217,22 @@ begin
|
|||
|
||||
end;
|
||||
|
||||
function ps4_sceKernelClockGetres(clock_id:Integer;tp:Ptimespec):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=ps4_clock_getres(clock_id,tp);
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Result:=px2sce(PInteger(_error)^);
|
||||
end;
|
||||
end;
|
||||
|
||||
function mul_div_u64(m,d,v:QWORD):QWORD; sysv_abi_default; assembler; nostackframe;
|
||||
asm
|
||||
movq v,%rax
|
||||
mulq m
|
||||
divq d
|
||||
end;
|
||||
|
||||
function ps4_clock_gettime(clock_id:Integer;tp:Ptimespec):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
pc,pf:QWORD;
|
||||
|
@ -256,7 +247,6 @@ begin
|
|||
SwGetSystemTimeAsFileTime(TFILETIME(pc));
|
||||
pc:=pc-DELTA_EPOCH_IN_100NS;
|
||||
tp^.tv_sec :=pc div POW10_7;
|
||||
//tp^.tv_nsec:=(QWORD(pc) mod POW10_7)*100;
|
||||
tp^.tv_nsec:=0;
|
||||
end;
|
||||
|
||||
|
@ -279,40 +269,12 @@ begin
|
|||
CLOCK_MONOTONIC_PRECISE,
|
||||
CLOCK_MONOTONIC_FAST:
|
||||
begin
|
||||
|
||||
//this stabilize timers, why? idk
|
||||
//Int64(pc):=-100*100;
|
||||
//SwDelayExecution(False,@pc); //100ms
|
||||
|
||||
SwQueryPerformanceCounter(pc,pf);
|
||||
|
||||
tp^.tv_sec :=pc div pf;
|
||||
tp^.tv_nsec:=((pc mod pf)*POW10_9+(pf shr 1)) div pf;
|
||||
|
||||
if (tp^.tv_nsec>=POW10_9) then
|
||||
begin
|
||||
Inc(tp^.tv_sec);
|
||||
Dec(tp^.tv_nsec,POW10_9);
|
||||
end;
|
||||
|
||||
//tp^.tv_nsec:=(tp^.tv_nsec shr 8) shl 8;
|
||||
//tp^.tv_nsec:=tp^.tv_nsec shr 2;
|
||||
|
||||
{
|
||||
if (old_tp.tv_sec=tp^.tv_sec) then
|
||||
begin
|
||||
if (old_tp.tv_nsec>tp^.tv_nsec) then
|
||||
begin
|
||||
DebugBreak;
|
||||
end;
|
||||
end else
|
||||
if (old_tp.tv_sec>tp^.tv_sec) then
|
||||
begin
|
||||
DebugBreak;
|
||||
end;
|
||||
old_tp:=tp^;
|
||||
}
|
||||
pc:=mul_div_u64(POW10_7,pf,pc);
|
||||
|
||||
tp^.tv_sec :=(pc div POW10_7);
|
||||
tp^.tv_nsec:=(pc mod POW10_7)*100;
|
||||
end;
|
||||
|
||||
CLOCK_PROCTIME:
|
||||
|
@ -346,21 +308,17 @@ begin
|
|||
end;
|
||||
|
||||
function ps4_sceKernelGetTscFrequency():QWORD; SysV_ABI_CDecl;
|
||||
var
|
||||
pc:QWORD;
|
||||
begin
|
||||
SwQueryPerformanceCounter(pc,Result);
|
||||
Result:=POW10_7;
|
||||
end;
|
||||
|
||||
function ps4_sceKernelReadTsc():QWORD; SysV_ABI_CDecl;
|
||||
var
|
||||
pf:QWORD;
|
||||
pc,pf:QWORD;
|
||||
begin
|
||||
//this stabilize timers, why? idk
|
||||
//Int64(pf):=-100*100;
|
||||
//SwDelayExecution(False,@pf); //100ms
|
||||
SwQueryPerformanceCounter(pc,pf);
|
||||
|
||||
SwQueryPerformanceCounter(Result,pf);
|
||||
Result:=mul_div_u64(POW10_7,pf,pc);
|
||||
end;
|
||||
|
||||
function ps4_sceKernelClockGettime(clockId:Integer;tp:Ptimespec):Integer; SysV_ABI_CDecl;
|
||||
|
|
538
ps4_elf.pas
|
@ -127,16 +127,18 @@ type
|
|||
Size:QWORD;
|
||||
sceKernelExtendedPageTable :PQWORD;
|
||||
sceKernelFlexibleMemorySize :PQWORD;
|
||||
sceKernelExtendedMemory1 :PQWORD;
|
||||
sceKernelExtendedMemory1 :PByte;
|
||||
sceKernelExtendedGpuPageTable:PQWORD;
|
||||
sceKernelExtendedMemory2 :PQWORD;
|
||||
sceKernelExtendedMemory2 :PByte;
|
||||
sceKernelExtendedCpuPageTable:PQWORD;
|
||||
end;
|
||||
|
||||
PSceKernelFsParam=^TSceKernelFsParam;
|
||||
TSceKernelFsParam=packed record
|
||||
Size:QWORD;
|
||||
sceKernelFsDupDent:PQWORD;
|
||||
sceKernelFsDupDent :PDWORD;
|
||||
sceWorkspaceUpdateMode:Pointer;
|
||||
sceTraceAprNameMode :Pointer;
|
||||
end;
|
||||
|
||||
PSceProcParam=^TSceProcParam;
|
||||
|
@ -155,6 +157,7 @@ type
|
|||
_sceKernelMemParam :PSceKernelMemParam;
|
||||
_sceKernelFsParam :PSceKernelFsParam;
|
||||
sceProcessPreloadEnabled :PDWORD;
|
||||
Unknown1 :QWORD;
|
||||
end;
|
||||
|
||||
Telf_file=class;
|
||||
|
@ -272,8 +275,8 @@ type
|
|||
function RelocatePltRelaEnum(cbs:TOnRelaInfoCb;data:Pointer):Boolean;
|
||||
function ParseSymbolsEnum(cbs:TOnRelaInfoCb;data:Pointer):Boolean;
|
||||
function LoadSymbolExport:Boolean;
|
||||
procedure _PatchTls(Proc:Pointer;Addr:PByte;Size:QWORD);
|
||||
procedure PatchTls(Proc:Pointer);
|
||||
procedure _PatchTls(Addr:PByte;Size:QWORD);
|
||||
procedure PatchTls;
|
||||
procedure mapProt;
|
||||
procedure mapCodeInit;
|
||||
Procedure ClearElfFile;
|
||||
|
@ -315,48 +318,11 @@ function DecodeEncName(strEncName:PAnsiChar;var nModuleId,nLibraryId:WORD;var n
|
|||
|
||||
function _dynamic_tls_get_addr(ti:PTLS_index):Pointer; SysV_ABI_CDecl;
|
||||
|
||||
procedure SetTlsBase(p:Pointer); assembler;
|
||||
function GetTlsBase:Pointer; assembler;
|
||||
|
||||
implementation
|
||||
|
||||
type
|
||||
Ppatch_ld=^Tpatch_ld;
|
||||
Tpatch_ld=packed record
|
||||
//_movabs_rax:array[0..1] of Byte; // $48 $B8 //2
|
||||
_addr:Pointer; //8
|
||||
//_jmp_rax:array[0..1] of Byte; // $FF $E0 //2 = 14
|
||||
end;
|
||||
|
||||
Ppatch_fs=^Tpatch_fs;
|
||||
Tpatch_fs=packed record
|
||||
_call_rip:array[0..1] of Byte; //$ff $15
|
||||
//_push_rdx:Byte; // $52 //1
|
||||
//_push_rcx:Byte; // $51 //1
|
||||
//_call_32:Byte; // $E8 //1
|
||||
_ofs:Integer; //4
|
||||
//_pop_rcx:Byte; // $59 //1
|
||||
//_pop_rdx:Byte; // $5a //1 = 9
|
||||
_nop:array[0..2] of Byte; //$90 $90 $90
|
||||
end;
|
||||
|
||||
//ff 15 [d3 ff ff ff]
|
||||
|
||||
Const
|
||||
_patch_ld:Tpatch_ld=(
|
||||
//_movabs_rax:($48,$B8);
|
||||
_addr:nil;
|
||||
//_jmp_rax:($FF,$E0);
|
||||
);
|
||||
|
||||
_patch_fs:Tpatch_fs=(
|
||||
_call_rip:($ff,$15);
|
||||
//_push_rcx:$51;
|
||||
//_push_rdx:$52;
|
||||
//_call_32:$E8;
|
||||
_ofs:0;
|
||||
//_pop_rdx:$5a;
|
||||
//_pop_rcx:$59;
|
||||
_nop:($90,$90,$90);
|
||||
);
|
||||
|
||||
Procedure Telf_file.ClearElfFile;
|
||||
begin
|
||||
if (Self=nil) then Exit;
|
||||
|
@ -398,6 +364,16 @@ begin
|
|||
if (flags and SF_BFLG)<>0 then Result:=Result+' SF_BFLG';
|
||||
end;
|
||||
|
||||
function maxInt64(a,b:Int64):Int64; inline;
|
||||
begin
|
||||
if (a>b) then Result:=a else Result:=b;
|
||||
end;
|
||||
|
||||
function minInt64(a,b:Int64):Int64; inline;
|
||||
begin
|
||||
if (a<b) then Result:=a else Result:=b;
|
||||
end;
|
||||
|
||||
function LoadPs4ElfFromFile(Const name:RawByteString):TElf_node;
|
||||
Var
|
||||
elf:Telf_file;
|
||||
|
@ -407,8 +383,7 @@ Var
|
|||
self_header:Tself_header;
|
||||
Segments:Pself_segment;
|
||||
|
||||
SELF_MEM:Pointer;
|
||||
SELF_SIZE:Int64;
|
||||
SELF:TMemChunk;
|
||||
|
||||
elf_hdr:Pelf64_hdr;
|
||||
elf_phdr:Pelf64_phdr;
|
||||
|
@ -485,71 +460,79 @@ begin
|
|||
if (name='') then Exit;
|
||||
F:=FileOpen(name,fmOpenRead);
|
||||
if (F=feInvalidHandle) then Exit;
|
||||
|
||||
FileRead(F,self_header.Magic,SizeOf(DWORD));
|
||||
|
||||
case self_header.Magic of
|
||||
ELFMAG:
|
||||
begin
|
||||
SELF_SIZE:=FileSeek(F,0,fsFromEnd);
|
||||
if (SELF_SIZE<=0) then
|
||||
SELF.nSize:=FileSeek(F,0,fsFromEnd);
|
||||
|
||||
if (SELF.nSize<=0) then
|
||||
begin
|
||||
Writeln(StdErr,'Error read file:',name);
|
||||
FileClose(F);
|
||||
Exit;
|
||||
end;
|
||||
SELF_MEM:=GetMem(SELF_SIZE);
|
||||
|
||||
SELF.pAddr:=GetMem(SELF.nSize);
|
||||
|
||||
FileSeek(F,0,fsFromBeginning);
|
||||
s:=FileRead(F,SELF_MEM^,SELF_SIZE);
|
||||
s:=FileRead(F,SELF.pAddr^,SELF.nSize);
|
||||
FileClose(F);
|
||||
|
||||
if (s<>SELF_SIZE) then
|
||||
if (s<>SELF.nSize) then
|
||||
begin
|
||||
Writeln(StdErr,'Error read file:',name);
|
||||
FreeMem(SELF_MEM);
|
||||
FreeMem(SELF.pAddr);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if not _test_elf(SELF_MEM) then
|
||||
if not _test_elf(SELF.pAddr) then
|
||||
begin
|
||||
Writeln(StdErr,'Error test file:',name);
|
||||
FreeMem(SELF_MEM);
|
||||
FreeMem(SELF.pAddr);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
elf:=Telf_file.Create;
|
||||
elf.mElf.nSize:=SELF_SIZE;
|
||||
elf.mElf.pAddr:=SELF_MEM;
|
||||
elf.mElf:=SELF;
|
||||
elf._set_filename(name);
|
||||
Result:=elf;
|
||||
end;
|
||||
self_magic:
|
||||
begin
|
||||
SELF_SIZE:=FileSeek(F,0,fsFromEnd);
|
||||
if (SELF_SIZE<=0) then
|
||||
SELF.nSize:=FileSeek(F,0,fsFromEnd);
|
||||
|
||||
if (SELF.nSize<=0) then
|
||||
begin
|
||||
Writeln(StdErr,'Error read file:',name);
|
||||
FileClose(F);
|
||||
Exit;
|
||||
end;
|
||||
SELF_MEM:=GetMem(SELF_SIZE);
|
||||
|
||||
SELF.pAddr:=GetMem(SELF.nSize);
|
||||
|
||||
FileSeek(F,0,fsFromBeginning);
|
||||
s:=FileRead(F,SELF_MEM^,SELF_SIZE);
|
||||
s:=FileRead(F,SELF.pAddr^,SELF.nSize);
|
||||
FileClose(F);
|
||||
|
||||
if (s<>SELF_SIZE) then
|
||||
if (s<>SELF.nSize) then
|
||||
begin
|
||||
Writeln(StdErr,'Error read file:',name);
|
||||
FreeMem(SELF_MEM);
|
||||
FreeMem(SELF.pAddr);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if not _test_self(SELF_MEM) then
|
||||
if not _test_self(SELF.pAddr) then
|
||||
begin
|
||||
FreeMem(SELF_MEM);
|
||||
FreeMem(SELF.pAddr);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Num_Segments:=Pself_header(SELF_MEM)^.Num_Segments;
|
||||
Segments:=SELF_MEM+SizeOf(Tself_header);
|
||||
Num_Segments:=Pself_header(SELF.pAddr)^.Num_Segments;
|
||||
Segments:=SELF.pAddr+SizeOf(Tself_header);
|
||||
|
||||
For i:=0 to Num_Segments-1 do
|
||||
begin
|
||||
if (Segments[i].flags and (SF_ENCR or SF_DFLG))<>0 then
|
||||
|
@ -561,51 +544,63 @@ begin
|
|||
Writeln(StdErr,' Seg.c_size=',HexStr(Segments[i].encrypted_compressed_size,16));
|
||||
Writeln(StdErr,' Seg.d_size=',HexStr(Segments[i].decrypted_decompressed_size,16));
|
||||
Writeln(StdErr,'encrypted or deflated SELF not support!');
|
||||
FreeMem(SELF_MEM);
|
||||
FreeMem(SELF.pAddr);
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
elf_hdr:=Pointer(Segments)+(Num_Segments*SizeOf(Tself_segment));
|
||||
|
||||
if not _test_elf(elf_hdr) then
|
||||
begin
|
||||
Writeln(StdErr,'Error test file:',name);
|
||||
FreeMem(SELF_MEM);
|
||||
FreeMem(SELF.pAddr);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
elf_phdr:=Pointer(elf_hdr)+SizeOf(elf64_hdr);
|
||||
LowSeg:=High(Int64);
|
||||
|
||||
elf:=Telf_file.Create;
|
||||
elf.mElf.nSize:=0;
|
||||
|
||||
For i:=0 to elf_hdr^.e_phnum-1 do
|
||||
begin
|
||||
s:=elf_phdr[i].p_offset;
|
||||
if (s<>0) then
|
||||
if (s<LowSeg) then LowSeg:=s;
|
||||
|
||||
begin
|
||||
LowSeg:=MinInt64(s,LowSeg);
|
||||
end;
|
||||
s:=s+elf_phdr[i].p_filesz;
|
||||
if s>elf.mElf.nSize then elf.mElf.nSize:=s;
|
||||
elf.mElf.nSize:=MaxInt64(s,elf.mElf.nSize);
|
||||
end;
|
||||
|
||||
if (LowSeg=High(Int64)) then
|
||||
begin
|
||||
Writeln(StdErr,'Error LowSeg');
|
||||
FreeMem(SELF_MEM);
|
||||
elf.Free;
|
||||
Exit;
|
||||
LowSeg:=0;
|
||||
end;
|
||||
|
||||
s:=ptruint(elf_hdr)-ptruint(SELF.pAddr); //offset
|
||||
|
||||
s:=MaxInt64(SELF.nSize,s)-s; //size
|
||||
|
||||
LowSeg:=MinInt64(LowSeg,s); //trunc
|
||||
|
||||
elf.mElf.pAddr:=AllocMem(elf.mElf.nSize);
|
||||
Writeln('Elf with LowSeg:',LowSeg,' Size:',elf.mElf.nSize);
|
||||
|
||||
Move(elf_hdr^,elf.mElf.pAddr^,LowSeg);
|
||||
|
||||
For i:=0 to Num_Segments-1 do
|
||||
if ((Segments[i].flags and SF_BFLG)<>0) then
|
||||
begin
|
||||
s:=(Segments[i].flags shr 20) and $FFF;
|
||||
Move(Pointer(SELF_MEM+Segments[i].offset)^,
|
||||
Pointer(elf.mElf.pAddr+elf_phdr[s].p_offset)^,
|
||||
Move(Pointer(SELF.pAddr +Segments[i].offset)^, //src
|
||||
Pointer(elf.mElf.pAddr+elf_phdr[s].p_offset)^, //dst
|
||||
Segments[i].encrypted_compressed_size);
|
||||
end;
|
||||
FreeMem(SELF_MEM);
|
||||
|
||||
FreeMem(SELF.pAddr);
|
||||
elf._set_filename(name);
|
||||
Result:=elf;
|
||||
end;
|
||||
|
@ -1059,6 +1054,7 @@ begin
|
|||
DT_NEEDED:
|
||||
begin
|
||||
mu.value:=entry.d_un.d_val;
|
||||
_md:=Default(TMODULE);
|
||||
_md.strName:=PChar(@pStrTable[mu.name_offset]);
|
||||
_add_need(_md.strName);
|
||||
Writeln('DT_NEEDED :',_md.strName); //import filename
|
||||
|
@ -1066,6 +1062,7 @@ begin
|
|||
DT_SCE_MODULE_INFO:
|
||||
begin
|
||||
mu.value:=entry.d_un.d_val;
|
||||
_md:=Default(TMODULE);
|
||||
_md.strName:=PChar(@pStrTable[mu.name_offset]);
|
||||
_md.Import:=False;
|
||||
Writeln('DT_SCE_MODULE_INFO:',_md.strName,':',HexStr(mu.id,4)); //current module name
|
||||
|
@ -1075,6 +1072,7 @@ begin
|
|||
DT_SCE_NEEDED_MODULE:
|
||||
begin
|
||||
mu.value:=entry.d_un.d_val;
|
||||
_md:=Default(TMODULE);
|
||||
_md.strName:=PChar(@pStrTable[mu.name_offset]);
|
||||
_md.Import:=True;
|
||||
Writeln('DT_SCE_NEEDED_MODULE :',HexStr(mu.id,4),':',_md.strName); //import module name
|
||||
|
@ -1083,6 +1081,7 @@ begin
|
|||
DT_SCE_IMPORT_LIB:
|
||||
begin
|
||||
lu.value:=entry.d_un.d_val;
|
||||
lib:=Default(TLIBRARY);
|
||||
lib.strName:=PChar(@pStrTable[lu.name_offset]);
|
||||
lib.Import:=True;
|
||||
Writeln('DT_SCE_IMPORT_LIB :',HexStr(lu.id,4),':',lib.strName); //import lib name
|
||||
|
@ -1091,6 +1090,7 @@ begin
|
|||
DT_SCE_EXPORT_LIB:
|
||||
begin
|
||||
lu.value:=entry.d_un.d_val;
|
||||
lib:=Default(TLIBRARY);
|
||||
lib.strName:=PChar(@pStrTable[lu.name_offset]);
|
||||
lib.Import:=False;
|
||||
Writeln('DT_SCE_EXPORT_LIB :',HexStr(lu.id,4),':',lib.strName); //export libname
|
||||
|
@ -1148,8 +1148,6 @@ begin
|
|||
Result:=True;
|
||||
end;
|
||||
|
||||
function __static_get_tls_adr:Pointer; assembler; nostackframe; forward;
|
||||
|
||||
function Telf_file.Prepare:Boolean;
|
||||
begin
|
||||
Result:=False;
|
||||
|
@ -1162,7 +1160,7 @@ begin
|
|||
Result:=MapImageIntoMemory;
|
||||
if not Result then raise Exception.Create('Error MapImageIntoMemory');
|
||||
Result:=LoadSymbolExport;
|
||||
PatchTls(@__static_get_tls_adr);
|
||||
PatchTls;
|
||||
FPrepared:=True;
|
||||
end;
|
||||
|
||||
|
@ -1364,28 +1362,8 @@ begin
|
|||
end;
|
||||
|
||||
procedure Telf_file._find_tls_stub(elf_phdr:Pelf64_phdr;s:SizeInt);
|
||||
Const
|
||||
patch_ld_size=SizeOf(Tpatch_ld);
|
||||
var
|
||||
i:SizeInt;
|
||||
p:QWORD;
|
||||
begin
|
||||
//find stub for static tls
|
||||
if (s<>0) then
|
||||
For i:=0 to s-1 do
|
||||
begin
|
||||
if _isSegmentLoadable(@elf_phdr[i]) then
|
||||
if ((elf_phdr[i].p_flags and PF_X)<>0) then
|
||||
begin
|
||||
p:=get_end_pad(elf_phdr[i].p_memsz,PHYSICAL_PAGE_SIZE);
|
||||
if (p>=patch_ld_size) then
|
||||
begin
|
||||
pTls.stub.pAddr:=Pointer(elf_phdr[i].p_vaddr+elf_phdr[i].p_memsz);
|
||||
pTls.stub.nSize:=p;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
//
|
||||
end;
|
||||
|
||||
function Telf_file.MapImageIntoMemory:Boolean;
|
||||
|
@ -2439,229 +2417,217 @@ begin
|
|||
Result:=True;
|
||||
end;
|
||||
|
||||
//64488b042500000000 mov %fs:0x0,%rax
|
||||
// 0 1 2 3 4
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
//[64] [48] [8b] [04] 25 [00 00 00 00] :0x0
|
||||
{
|
||||
64 48 A1 [0000000000000000] mov rax,fs:[$0000000000000000] -> 65 48 A1 [0807000000000000] mov rax,gs:[$0000000000000708]
|
||||
64 48 8B 04 25 [00000000] mov rax,fs:[$00000000] -> 65 48 8B 04 25 [08070000] mov rax,gs:[$00000708]
|
||||
64 48 8B 0C 25 [00000000] mov rcx,fs:[$00000000] -> 65 48 8B 0C 25 [08070000] mov rcx,gs:[$00000708]
|
||||
64 48 8B 14 25 [00000000] mov rdx,fs:[$00000000] -> 65 48 8B 14 25 [08070000] mov rdx,gs:[$00000708]
|
||||
64 48 8B 1C 25 [00000000] mov rbx,fs:[$00000000] -> 65 48 8B 1C 25 [08070000] mov rbx,gs:[$00000708]
|
||||
64 48 8B 24 25 [00000000] mov rsp,fs:[$00000000] -> 65 48 8B 24 25 [08070000] mov rsp,gs:[$00000708]
|
||||
64 48 8B 2C 25 [00000000] mov rbp,fs:[$00000000] -> 65 48 8B 2C 25 [08070000] mov rbp,gs:[$00000708]
|
||||
64 48 8B 34 25 [00000000] mov rsi,fs:[$00000000] -> 65 48 8B 34 25 [08070000] mov rsi,gs:[$00000708]
|
||||
64 48 8B 3C 25 [00000000] mov rdi,fs:[$00000000] -> 65 48 8B 3C 25 [08070000] mov rdi,gs:[$00000708]
|
||||
64 4C 8B 04 25 [00000000] mov r8 ,fs:[$00000000] -> 65 4C 8B 04 25 [08070000] mov r8 ,gs:[$00000708]
|
||||
64 4C 8B 0C 25 [00000000] mov r9 ,fs:[$00000000] -> 65 4C 8B 0C 25 [08070000] mov r9 ,gs:[$00000708]
|
||||
64 4C 8B 14 25 [00000000] mov r10,fs:[$00000000] -> 65 4C 8B 14 25 [08070000] mov r10,gs:[$00000708]
|
||||
64 4C 8B 1C 25 [00000000] mov r11,fs:[$00000000] -> 65 4C 8B 1C 25 [08070000] mov r11,gs:[$00000708]
|
||||
64 4C 8B 24 25 [00000000] mov r12,fs:[$00000000] -> 65 4C 8B 24 25 [08070000] mov r12,gs:[$00000708]
|
||||
64 4C 8B 2C 25 [00000000] mov r13,fs:[$00000000] -> 65 4C 8B 2C 25 [08070000] mov r13,gs:[$00000708]
|
||||
64 4C 8B 34 25 [00000000] mov r14,fs:[$00000000] -> 65 4C 8B 34 25 [08070000] mov r14,gs:[$00000708]
|
||||
64 4C 8B 3C 25 [00000000] mov r15,fs:[$00000000] -> 65 4C 8B 3C 25 [08070000] mov r15,gs:[$00000708]
|
||||
}
|
||||
|
||||
type
|
||||
t_patch_inst=array[0..11] of Byte;
|
||||
|
||||
//MOV RAX,qword ptr FS:[0x0]
|
||||
const
|
||||
patch_table:array[0..16] of t_patch_inst=(
|
||||
( 9,$65,$48,$8B,$04,$25,$08,$07,$00,$00,$00,$00),
|
||||
( 9,$65,$48,$8B,$0C,$25,$08,$07,$00,$00,$00,$00),
|
||||
( 9,$65,$48,$8B,$14,$25,$08,$07,$00,$00,$00,$00),
|
||||
( 9,$65,$48,$8B,$1C,$25,$08,$07,$00,$00,$00,$00),
|
||||
( 9,$65,$48,$8B,$24,$25,$08,$07,$00,$00,$00,$00),
|
||||
( 9,$65,$48,$8B,$2C,$25,$08,$07,$00,$00,$00,$00),
|
||||
( 9,$65,$48,$8B,$34,$25,$08,$07,$00,$00,$00,$00),
|
||||
( 9,$65,$48,$8B,$3C,$25,$08,$07,$00,$00,$00,$00),
|
||||
( 9,$65,$4C,$8B,$04,$25,$08,$07,$00,$00,$00,$00),
|
||||
( 9,$65,$4C,$8B,$0C,$25,$08,$07,$00,$00,$00,$00),
|
||||
( 9,$65,$4C,$8B,$14,$25,$08,$07,$00,$00,$00,$00),
|
||||
( 9,$65,$4C,$8B,$1C,$25,$08,$07,$00,$00,$00,$00),
|
||||
( 9,$65,$4C,$8B,$24,$25,$08,$07,$00,$00,$00,$00),
|
||||
( 9,$65,$4C,$8B,$2C,$25,$08,$07,$00,$00,$00,$00),
|
||||
( 9,$65,$4C,$8B,$34,$25,$08,$07,$00,$00,$00,$00),
|
||||
( 9,$65,$4C,$8B,$3C,$25,$08,$07,$00,$00,$00,$00),
|
||||
(12,$65,$48,$A1,$08,$07,$00,$00,$00,$00,$00,$00)
|
||||
);
|
||||
|
||||
// 0 1 2
|
||||
//[66] [66] [66]
|
||||
procedure SetTlsBase(p:Pointer); assembler; nostackframe;
|
||||
asm
|
||||
mov %rcx,%gs:(0x708)
|
||||
end;
|
||||
|
||||
// 3 4 5 6 7 8 9 10 11
|
||||
//[64] [48] [8b] [04] 25 [00 00 00 00]
|
||||
function GetTlsBase:Pointer; assembler; nostackframe;
|
||||
asm
|
||||
mov %gs:(0x708),%rax
|
||||
end;
|
||||
|
||||
//[66] [66] [66]
|
||||
//64488b042500000000 //data16 data16 data16 mov %fs:0x0,%rax
|
||||
|
||||
|
||||
// v this adr - base adr
|
||||
//[e8] [9e be b3 00] relative
|
||||
//^ call
|
||||
// 0 1 2 3 4
|
||||
//90 = nop
|
||||
|
||||
//48030504853603 add 0x3368504(%rip),%rax # 0x81d44a8
|
||||
// v-add
|
||||
//[48] [03] [05] [04 85 36 03] - adr
|
||||
//^64 bits
|
||||
|
||||
//000000010000366B 51 push %rcx
|
||||
//000000010000366C 48b9d5728a0e00000000 movabs $0xe8a72d5,%rcx
|
||||
//0000000100003676 ff2500000000 jmpq *0x0(%rip) # 0x10000367c <main+76>
|
||||
//ff 25 eb ff ff ff
|
||||
// 0 1 2 3 4 5
|
||||
|
||||
// $51 push %rcx
|
||||
// $59 pop %rcx
|
||||
|
||||
|
||||
//const
|
||||
//DWNOP=$90909090;
|
||||
|
||||
function IndexUnalignDWord(Const buf;len:SizeInt;b:DWord):SizeInt;
|
||||
function IndexMovFs(var pbuf:Pointer;pend:Pointer):Integer;
|
||||
var
|
||||
psrc:PDWORD;
|
||||
pend:PBYTE;
|
||||
psrc:Pointer;
|
||||
W:DWORD;
|
||||
begin
|
||||
psrc:=@buf;
|
||||
pend:=PBYTE(psrc)+len;
|
||||
while (PBYTE(psrc)<pend) do
|
||||
Result:=-1;
|
||||
psrc:=pbuf;
|
||||
while (psrc<pend) do
|
||||
begin
|
||||
if (psrc^=b) then
|
||||
W:=PDWORD(psrc)^;
|
||||
|
||||
Case W of
|
||||
$048B4864:Result:= 0; //rax
|
||||
$0C8B4864:Result:= 1; //rcx
|
||||
$148B4864:Result:= 2; //rdx
|
||||
$1C8B4864:Result:= 3; //rbx
|
||||
$248B4864:Result:= 4; //rsp
|
||||
$2C8B4864:Result:= 5; //rbp
|
||||
$348B4864:Result:= 6; //rsi
|
||||
$3C8B4864:Result:= 7; //rdi
|
||||
$048B4C64:Result:= 8; //r8
|
||||
$0C8B4C64:Result:= 9; //r9
|
||||
$148B4C64:Result:=10; //r10
|
||||
$1C8B4C64:Result:=11; //r11
|
||||
$248B4C64:Result:=12; //r12
|
||||
$2C8B4C64:Result:=13; //r13
|
||||
$348B4C64:Result:=14; //r14
|
||||
$3C8B4C64:Result:=15; //r15
|
||||
$00A14864:Result:=16; //rax64
|
||||
|
||||
//shft 8
|
||||
$8B486400..$8B4864FF,
|
||||
$8B4C6400..$8B4C64FF,
|
||||
$A1486400..$A14864FF:
|
||||
begin
|
||||
Inc(psrc,1);
|
||||
Continue;
|
||||
end;
|
||||
|
||||
//shft 16
|
||||
$48640000..$4864FFFF,
|
||||
$4C640000..$4C64FFFF:
|
||||
begin
|
||||
Inc(psrc,2);
|
||||
Continue;
|
||||
end;
|
||||
|
||||
//shft 24
|
||||
$64000000..$64FFFFFF:
|
||||
begin
|
||||
Inc(psrc,3);
|
||||
Continue;
|
||||
end;
|
||||
|
||||
else
|
||||
begin
|
||||
Inc(psrc,4);
|
||||
Continue;
|
||||
end;
|
||||
end;
|
||||
|
||||
Case Result of
|
||||
0..15:
|
||||
begin
|
||||
if (PBYTE(psrc)[4]=$25) then
|
||||
begin
|
||||
if (PDWORD(@PBYTE(psrc)[5])^<>$00000000) then
|
||||
begin
|
||||
Inc(psrc,5);
|
||||
Continue;
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
Inc(psrc,4);
|
||||
Continue;
|
||||
end;
|
||||
end;
|
||||
16:
|
||||
begin
|
||||
if (PQWORD(@PBYTE(psrc)[3])^<>$0000000000000000) then
|
||||
begin
|
||||
Inc(psrc,4);
|
||||
Continue;
|
||||
end;
|
||||
end;
|
||||
else;
|
||||
end;
|
||||
|
||||
if (Result<>-1) then
|
||||
begin
|
||||
Result:=PBYTE(psrc)-PBYTE(@buf);
|
||||
pbuf:=psrc;
|
||||
exit;
|
||||
end;
|
||||
inc(PBYTE(psrc));
|
||||
|
||||
Inc(psrc);
|
||||
end;
|
||||
Result:=-1;
|
||||
end;
|
||||
|
||||
procedure Telf_file._PatchTls(Proc:Pointer;Addr:PByte;Size:QWORD);
|
||||
Const
|
||||
prefix1:DWORD=$048b4864;
|
||||
|
||||
prefix2:Byte =$25;
|
||||
prefix3:DWORD=$00000000;
|
||||
|
||||
//prefix3:DWORD=$05034800;
|
||||
|
||||
//prefix4:QWORD=$0503480000000025;
|
||||
|
||||
prefix5:DWORD=$666666;
|
||||
|
||||
prefixm:DWORD=$FFFFFF;
|
||||
|
||||
procedure Telf_file._PatchTls(Addr:PByte;Size:QWORD);
|
||||
var
|
||||
Stub:Pointer;
|
||||
c:SizeInt;
|
||||
_call:Tpatch_fs;
|
||||
count:SizeInt;
|
||||
|
||||
procedure do_patch_ld(p:PByte); inline;
|
||||
var
|
||||
_jmp:Tpatch_ld;
|
||||
procedure do_patch(p:PByte;i:Integer); inline;
|
||||
begin
|
||||
_jmp:=_patch_ld;
|
||||
_jmp._addr:=proc;
|
||||
Ppatch_ld(p)^:=_jmp;
|
||||
end;
|
||||
|
||||
procedure do_patch(p:PByte); inline;
|
||||
begin
|
||||
_call._ofs:=Integer(PtrInt(Stub)-PtrInt(P)-PtrInt(@Tpatch_fs(nil^).{_pop_rcx}_nop));
|
||||
Ppatch_fs(p)^:=_call;
|
||||
|
||||
p:=p-3;
|
||||
if ((PDWORD(p)^ and prefixm)=prefix5) then
|
||||
begin
|
||||
p[0]:=$90; //nop
|
||||
p[1]:=$90; //nop
|
||||
p[2]:=$90; //nop
|
||||
end;
|
||||
|
||||
Move(patch_table[i][1],p^,patch_table[i][0]);
|
||||
end;
|
||||
|
||||
procedure do_find(p:PByte;s:SizeInt);
|
||||
var
|
||||
i:SizeInt;
|
||||
A:PByte;
|
||||
pend:Pointer;
|
||||
i,len:Integer;
|
||||
begin
|
||||
pend:=p+s;
|
||||
repeat
|
||||
i:=IndexUnalignDWord(P^,s,prefix1);
|
||||
if (i=-1) then Break;
|
||||
A:=@P[i];
|
||||
i:=IndexMovFs(p,pend);
|
||||
|
||||
if (A[4]=prefix2) and (PDWORD(@A[5])^=prefix3) then
|
||||
//if (PQWORD(@A[4])^=prefix4) then
|
||||
if not _ro_seg_adr_in(A,12) then
|
||||
if (i=-1) then Exit;
|
||||
|
||||
len:=patch_table[i][0];
|
||||
|
||||
if not _ro_seg_adr_in(p,len) then
|
||||
begin
|
||||
Inc(c);
|
||||
do_patch(A);
|
||||
Inc(count);
|
||||
do_patch(p,i);
|
||||
Inc(p,len);
|
||||
end;
|
||||
|
||||
Inc(i,4);
|
||||
Inc(P,i);
|
||||
Dec(s,i);
|
||||
until (s<=0);
|
||||
until false;
|
||||
end;
|
||||
|
||||
begin
|
||||
if (Size=0) then Exit;
|
||||
if (Size>=12) then Size:=Size-12;
|
||||
c:=0;
|
||||
_call:=_patch_fs;
|
||||
count:=0;
|
||||
|
||||
Stub:=pTls.stub.pAddr;
|
||||
do_find(@Addr[0],Size);
|
||||
|
||||
do_find(@Addr[0],Size-0);
|
||||
|
||||
//Writeln('patch_tls_count=',c);
|
||||
//do_find(@Addr[1],Size-1);
|
||||
//Writeln('patch_tls_count=',c);
|
||||
//do_find(@Addr[2],Size-2);
|
||||
//Writeln('patch_tls_count=',c);
|
||||
//do_find(@Addr[3],Size-3);
|
||||
|
||||
Writeln('patch_tls_count=',c);
|
||||
if (c<>0) then
|
||||
begin
|
||||
do_patch_ld(Stub);
|
||||
end;
|
||||
Writeln('patch_tls_count=',count);
|
||||
end;
|
||||
|
||||
procedure Telf_file.PatchTls(Proc:Pointer);
|
||||
procedure Telf_file.PatchTls;
|
||||
var
|
||||
i,c:DWORD;
|
||||
begin
|
||||
if (Self=nil) or (Proc=nil) then Exit;
|
||||
if (Self=nil) then Exit;
|
||||
if (pTls.full_size=0) then Exit; //no tls?
|
||||
c:=ModuleInfo.segmentCount;
|
||||
if (c<>0) then
|
||||
For i:=0 to c-1 do
|
||||
if (ModuleInfo.segmentInfo[i].prot and PF_X<>0) then
|
||||
begin
|
||||
_PatchTls(Proc,
|
||||
ModuleInfo.segmentInfo[i].address,
|
||||
_PatchTls(ModuleInfo.segmentInfo[i].address,
|
||||
ModuleInfo.segmentInfo[i].Size);
|
||||
end;
|
||||
end;
|
||||
|
||||
{
|
||||
function _static_get_tls_adr:Pointer; MS_ABI_Default;
|
||||
var
|
||||
elf:Telf_file;
|
||||
begin
|
||||
Result:=nil;
|
||||
elf:=Telf_file(ps4_app.prog);
|
||||
if (elf=nil) then Exit;
|
||||
Result:=elf._get_tls;
|
||||
end;
|
||||
}
|
||||
|
||||
{
|
||||
[oob page] <- old Stack guard
|
||||
[tls link] <- new Stack guard
|
||||
[Stack]
|
||||
[Stack]
|
||||
[Stack]
|
||||
}
|
||||
|
||||
function __static_get_tls_adr:Pointer; assembler; nostackframe;
|
||||
asm
|
||||
//new idea, no stack save, only %rax used
|
||||
movq %gs:(8),%rax //-> StackTop
|
||||
movq (%rax) ,%rax //-> StackTop^
|
||||
|
||||
{
|
||||
push %rcx
|
||||
push %rdx
|
||||
push %r8
|
||||
push %r9
|
||||
push %R10
|
||||
push %R11
|
||||
|
||||
call _static_get_tls_adr
|
||||
|
||||
pop %R11
|
||||
pop %R10
|
||||
pop %r9
|
||||
pop %r8
|
||||
pop %rdx
|
||||
pop %rcx
|
||||
}
|
||||
end;
|
||||
|
||||
//-not need:
|
||||
//-RAX:result
|
||||
////-RCX,RDX:Tpatch_fs
|
||||
//-other:win call save
|
||||
|
||||
//The registers RAX, RCX, RDX, R8, R9, R10, R11 are considered volatile (вызывающий сохраняет)
|
||||
//The registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15 are considered nonvolatile (вызываемый сохраняет)
|
||||
|
||||
function _dynamic_tls_get_addr(ti:PTLS_index):Pointer; SysV_ABI_CDecl;
|
||||
var
|
||||
elf:Telf_file;
|
||||
|
@ -2684,7 +2650,7 @@ Var
|
|||
adr:Pointer;
|
||||
begin
|
||||
tcb_size:=pTls.full_size;
|
||||
tcb:=_init_tls_tcb(tcb_size,is_static,Handle);
|
||||
tcb:=_init_tls_tcb(tcb_size,pTls.align,is_static,Handle);
|
||||
base:=tcb^._dtv.value;
|
||||
Assert(IsAlign(base,pTls.align));
|
||||
if (pTls.tmpl_size<>0) then
|
||||
|
@ -2776,7 +2742,6 @@ begin
|
|||
|
||||
if (pTls.stub.pAddr<>nil) then
|
||||
begin
|
||||
Assert(pTls.stub.nSize>=SizeOf(Tpatch_ld));
|
||||
//extra tls stub
|
||||
if (pTls.stub.nSize=PHYSICAL_PAGE_SIZE) then
|
||||
begin
|
||||
|
@ -2997,17 +2962,20 @@ end;
|
|||
|
||||
procedure _Entry(P:TEntryPoint;pFileName:Pchar);
|
||||
var
|
||||
StartupParams:TPS4StartupParams;
|
||||
data:array[0..SizeOf(TPS4StartupParams)+38] of Byte;
|
||||
psp:PPS4StartupParams;
|
||||
begin
|
||||
StartupParams:=Default(TPS4StartupParams);
|
||||
StartupParams.argc:=1;
|
||||
StartupParams.argv[0]:=pFileName;
|
||||
psp:=Pointer(Align(@data,32)+8); //AVX align +8
|
||||
|
||||
psp^:=Default(TPS4StartupParams);
|
||||
psp^.argc:=1;
|
||||
psp^.argv[0]:=pFileName;
|
||||
|
||||
//OpenOrbis relies on the fact that besides %rdi and %rsp also link to StartupParams, a very strange thing
|
||||
asm
|
||||
xor %rsi,%rsi
|
||||
lea StartupParams,%rdi
|
||||
mov %rdi,%rsp
|
||||
xor %rsi,%rsi //2
|
||||
mov psp ,%rdi //1
|
||||
mov %rdi,%rsp //stack
|
||||
jmp P
|
||||
end;
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ uses
|
|||
RWLock,
|
||||
hamt,
|
||||
sys_types,
|
||||
sys_crt,
|
||||
sys_kernel,
|
||||
ps4_handles;
|
||||
|
||||
|
@ -415,14 +416,19 @@ end;
|
|||
|
||||
procedure TElf_node._set_lib(id:Word;lib:TLIBRARY);
|
||||
var
|
||||
i:SizeInt;
|
||||
p,i:SizeInt;
|
||||
plib:PLIBRARY;
|
||||
begin
|
||||
i:=Length(aLibs);
|
||||
if (i<=id) then
|
||||
begin
|
||||
i:=id+1;
|
||||
p:=Length(aLibs);
|
||||
SetLength(aLibs,i);
|
||||
for p:=p to i-1 do
|
||||
begin
|
||||
aLibs[p]:=nil;
|
||||
end;
|
||||
end;
|
||||
plib:=aLibs[id];
|
||||
if (plib=nil) then plib:=AllocMem(SizeOf(TLIBRARY));
|
||||
|
@ -433,14 +439,19 @@ end;
|
|||
|
||||
procedure TElf_node._set_lib_attr(u:TLibraryValue);
|
||||
var
|
||||
i:SizeInt;
|
||||
p,i:SizeInt;
|
||||
plib:PLIBRARY;
|
||||
begin
|
||||
i:=Length(aLibs);
|
||||
if (i<=u.id) then
|
||||
begin
|
||||
i:=u.id+1;
|
||||
p:=Length(aLibs);
|
||||
SetLength(aLibs,i);
|
||||
for p:=p to i-1 do
|
||||
begin
|
||||
aLibs[p]:=nil;
|
||||
end;
|
||||
end;
|
||||
plib:=aLibs[u.id];
|
||||
if (plib=nil) then plib:=AllocMem(SizeOf(TLIBRARY));
|
||||
|
@ -726,7 +737,7 @@ begin
|
|||
|
||||
if (PP^<>Pointer(node)) then
|
||||
begin
|
||||
Writeln(StdErr,'Warn, ',node.pFileName,' file is registred');
|
||||
Writeln(StdWrn,'[Warn]:',node.pFileName,' file is registred');
|
||||
Result:=False;
|
||||
end;
|
||||
|
||||
|
@ -788,7 +799,7 @@ begin
|
|||
nid:=ps4_nid_hash(strName);
|
||||
PP:=HAMT_insert64(@mods.hamt,nid,Pointer(node));
|
||||
Assert(PP<>nil);
|
||||
if (PP^<>Pointer(node)) then Writeln(StdErr,'Warn, ',strName,' module is registred');
|
||||
if (PP^<>Pointer(node)) then Writeln(StdWrn,'[Warn]:',strName,' module is registred');
|
||||
end;
|
||||
|
||||
Procedure Tps4_program.SetLib(lib:PLIBRARY);
|
||||
|
@ -802,7 +813,7 @@ begin
|
|||
nid:=ps4_nid_hash(lib^.strName);
|
||||
PP:=HAMT_insert64(@libs.hamt,nid,Pointer(lib));
|
||||
Assert(PP<>nil);
|
||||
if (PP^<>Pointer(lib)) then Writeln(StdErr,'Warn, ',lib^.strName,' lib is registred');
|
||||
if (PP^<>Pointer(lib)) then Writeln(StdWrn,'[Warn]:',lib^.strName,' lib is registred');
|
||||
end;
|
||||
|
||||
function Tps4_program.GetLib(const strName:RawByteString):PLIBRARY;
|
||||
|
@ -891,7 +902,7 @@ begin
|
|||
pre_load.LockWr;
|
||||
if not pre_load._set_proc(nid,Pointer(cb)) then
|
||||
begin
|
||||
Writeln(StdErr,'Warn, ',strName,' is registred')
|
||||
Writeln(StdWrn,'[Warn]:',strName,' is registred')
|
||||
end;
|
||||
pre_load.Unlock;
|
||||
end;
|
||||
|
@ -905,7 +916,7 @@ begin
|
|||
fin_load.LockWr;
|
||||
if not fin_load._set_proc(nid,Pointer(cb)) then
|
||||
begin
|
||||
Writeln(StdErr,'Warn, ',strName,' is registred')
|
||||
Writeln(StdWrn,'[Warn]:',strName,' is registred')
|
||||
end;
|
||||
fin_load.Unlock;
|
||||
end;
|
||||
|
@ -1079,7 +1090,7 @@ begin
|
|||
node:=Loader(S);
|
||||
if (node=nil) then
|
||||
begin
|
||||
Writeln(StdErr,'Warn, file ',S,' not loaded!');
|
||||
Writeln(StdWrn,'[Warn]:',' file ',S,' not loaded!');
|
||||
end else
|
||||
begin
|
||||
PopupFile(node);
|
||||
|
|
3237
ps4libdoc.pas
803
rtl/hamt.pas
10
rtl/mmap.pas
|
@ -78,8 +78,15 @@ const
|
|||
MAP_ALIGNMENT_MASK=$1f000000;
|
||||
MAP_ALIGNMENT_MUL =$01000000; //1 shl 24
|
||||
|
||||
MCL_CURRENT=$0001; // Lock only current memory
|
||||
MCL_FUTURE =$0002; // Lock all future memory as well
|
||||
|
||||
MAP_FAILED =Pointer(-1);
|
||||
|
||||
MS_SYNC =$0000; // msync synchronously
|
||||
MS_ASYNC =$0001; // return immediately
|
||||
MS_INVALIDATE=$0002; // invalidate all cached data
|
||||
|
||||
function _isgpu(prot:Integer):Boolean; inline;
|
||||
function _iswrite(prot:Integer):Boolean; inline;
|
||||
function __map_prot_page(prot:Integer):DWORD;
|
||||
|
@ -156,6 +163,7 @@ begin
|
|||
PAGE_EXECUTE_READWRITE);
|
||||
|
||||
Case prot of
|
||||
0,
|
||||
PAGE_NOACCESS :Result:=0;
|
||||
PAGE_READONLY :Result:=PROT_READ;
|
||||
PAGE_READWRITE :Result:=PROT_READ or PROT_WRITE;
|
||||
|
@ -188,7 +196,7 @@ function _VirtualReserve(Addr:Pointer;dwSize:PTRUINT;prot:Integer):Integer;
|
|||
begin
|
||||
Result:=0;
|
||||
if (Addr=nil) then Exit(-1);
|
||||
Addr:=VirtualAlloc(Addr,dwSize,MEM_RESERVE,__map_prot_page(prot));
|
||||
Addr:=VirtualAlloc(Addr,dwSize,MEM_RESERVE,PAGE_NOACCESS);
|
||||
if (Addr<>nil) then Exit;
|
||||
Result:=GetLastError;
|
||||
end;
|
||||
|
|
|
@ -19,18 +19,49 @@ const
|
|||
STATUS_PENDING =$00000103;
|
||||
STATUS_NO_YIELD_PERFORMED=$40000024;
|
||||
STATUS_ACCESS_VIOLATION =$C0000005;
|
||||
STATUS_INVALID_HANDLE =$C0000008;
|
||||
STATUS_INVALID_PARAMETER =$C000000D;
|
||||
STATUS_END_OF_FILE =$C0000011;
|
||||
STATUS_ACCESS_DENIED =$C0000022;
|
||||
STATUS_DISK_FULL =$C000007F;
|
||||
|
||||
NT_INFINITE=$8000000000000000;
|
||||
|
||||
FileStandardInformation = 5;
|
||||
FilePositionInformation =14;
|
||||
FileAllocationInformation=19;
|
||||
FileEndOfFileInformation =20;
|
||||
|
||||
type
|
||||
PIO_STATUS_BLOCK=^IO_STATUS_BLOCK;
|
||||
IO_STATUS_BLOCK=packed record
|
||||
Status:DWORD;
|
||||
_Align:DWORD;
|
||||
Information:PTRUINT;
|
||||
end;
|
||||
|
||||
PFILE_STANDARD_INFORMATION=^FILE_STANDARD_INFORMATION;
|
||||
FILE_STANDARD_INFORMATION=packed record
|
||||
AllocationSize:LARGE_INTEGER;
|
||||
EndOfFile :LARGE_INTEGER;
|
||||
NumberOfLinks :ULONG;
|
||||
DeletePending :WORD;
|
||||
Directory :WORD;
|
||||
end;
|
||||
|
||||
PIO_APC_ROUTINE=procedure(ApcContext:Pointer;
|
||||
IoStatusBlock:PIO_STATUS_BLOCK;
|
||||
Reserved:ULONG); stdcall;
|
||||
|
||||
function NtAlertThread(hThread:THandle):DWORD; stdcall; external 'ntdll';
|
||||
function NtTestAlert():DWORD; stdcall; external 'ntdll';
|
||||
|
||||
function NtQueueApcThread(
|
||||
hThread:THandle;
|
||||
ApcRoutine:Pointer;
|
||||
ApcRoutineContext:PTRUINT;
|
||||
ApcStatusBlock:Pointer;
|
||||
ApcReserved:ULONG
|
||||
hThread :THandle;
|
||||
ApcRoutine :Pointer;
|
||||
ApcContext :Pointer;
|
||||
IoStatusBlock:PIO_STATUS_BLOCK;
|
||||
ApcReserved :ULONG
|
||||
):DWORD; stdcall; external 'ntdll';
|
||||
|
||||
function NtYieldExecution():DWORD; stdcall; external 'ntdll';
|
||||
|
@ -93,6 +124,46 @@ function NtSetTimerResolution(
|
|||
CurrentResolution:PULONG
|
||||
):DWORD; stdcall; external 'ntdll';
|
||||
|
||||
function NtReadFile(
|
||||
FileHandle :THandle;
|
||||
Event :THandle;
|
||||
ApcRoutine :Pointer;
|
||||
ApcContext :Pointer;
|
||||
IoStatusBlock:PIO_STATUS_BLOCK;
|
||||
Buffer :Pointer;
|
||||
Length :ULONG;
|
||||
ByteOffset :PLARGE_INTEGER;
|
||||
Key :PULONG
|
||||
):DWORD; stdcall; external 'ntdll';
|
||||
|
||||
function NtWriteFile(
|
||||
FileHandle :THandle;
|
||||
Event :THandle;
|
||||
ApcRoutine :Pointer;
|
||||
ApcContext :Pointer;
|
||||
IoStatusBlock:PIO_STATUS_BLOCK;
|
||||
Buffer :Pointer;
|
||||
Length :ULONG;
|
||||
ByteOffset :PLARGE_INTEGER;
|
||||
Key :PULONG
|
||||
):DWORD; stdcall; external 'ntdll';
|
||||
|
||||
function NtSetInformationFile(
|
||||
FileHandle :THandle;
|
||||
IoStatusBlock :PIO_STATUS_BLOCK;
|
||||
FileInformation :Pointer;
|
||||
Length :ULONG;
|
||||
FileInformationClass:DWORD
|
||||
):DWORD; stdcall; external 'ntdll';
|
||||
|
||||
function NtQueryInformationFile(
|
||||
FileHandle :THandle;
|
||||
IoStatusBlock :PIO_STATUS_BLOCK;
|
||||
FileInformation :Pointer;
|
||||
Length :ULONG;
|
||||
FileInformationClass:DWORD
|
||||
):DWORD; stdcall; external 'ntdll';
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
|
|
|
@ -21,9 +21,10 @@ type
|
|||
seg_adr:Pointer;
|
||||
dtv:Pdtv;
|
||||
_dtv:Tdtv;
|
||||
base:Pointer;
|
||||
end;
|
||||
|
||||
function _init_tls_tcb(Size,is_static,gen:QWORD):Ptls_tcb;
|
||||
function _init_tls_tcb(Size,_align,is_static,gen:QWORD):Ptls_tcb;
|
||||
function _get_tls_tcb(gen:QWORD):Ptls_tcb;
|
||||
procedure _free_tls_tcb_all;
|
||||
|
||||
|
@ -32,21 +33,29 @@ implementation
|
|||
threadvar
|
||||
tls_local:THAMT;
|
||||
|
||||
function _init_tls_tcb(Size,is_static,gen:QWORD):Ptls_tcb;
|
||||
function _init_tls_tcb(Size,_align,is_static,gen:QWORD):Ptls_tcb;
|
||||
var
|
||||
full_size:QWORD;
|
||||
base:Pointer;
|
||||
tcb:Ptls_tcb;
|
||||
PP:PPointer;
|
||||
dtv :Pointer;
|
||||
tcb :Ptls_tcb;
|
||||
PP :PPointer;
|
||||
begin
|
||||
full_size:=Size+SizeOf(Ttls_tcb);
|
||||
if (_align=0) then _align:=1;
|
||||
|
||||
full_size:=Size+(_align-1)+SizeOf(Ttls_tcb);
|
||||
base:=AllocMem(full_size);
|
||||
tcb:=Pointer(base+Size);
|
||||
dtv :=Align(base,_align);
|
||||
|
||||
tcb:=Pointer(dtv+Size);
|
||||
tcb^.base:=base;
|
||||
|
||||
tcb^.seg_adr:=tcb;
|
||||
tcb^.dtv:=@tcb^._dtv;
|
||||
tcb^._dtv.value:=base;
|
||||
tcb^._dtv.value:=dtv;
|
||||
tcb^._dtv.is_static:=is_static;
|
||||
tcb^._dtv.gen:=gen;
|
||||
|
||||
if (tls_local=nil) then tls_local:=HAMT_create64;
|
||||
PP:=HAMT_insert64(tls_local,gen,tcb);
|
||||
Assert(PP<>nil);
|
||||
|
@ -70,7 +79,7 @@ Var
|
|||
begin
|
||||
tcb:=data;
|
||||
if (tcb=nil) then Exit;
|
||||
base:=tcb^._dtv.value;
|
||||
base:=tcb^.base;
|
||||
FreeMem(base);
|
||||
end;
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ begin
|
|||
Result:=False;
|
||||
if (Key<min_key) or (Key>max_key) then Exit;
|
||||
rwlock_wrlock(FLock);
|
||||
Pointer(data):=HAMT_delete32(FHAMT,Key);
|
||||
HAMT_delete32(FHAMT,Key,@data);
|
||||
if Assigned(data) then
|
||||
begin
|
||||
data.Release;
|
||||
|
|
|
@ -181,6 +181,35 @@ begin
|
|||
node:=HeaderList.AddSpirvOp(Op.OpExecutionMode);
|
||||
node^.AddParam(Main);
|
||||
node^.AddLiteral(ExecutionMode.OriginUpperLeft,ExecutionMode.GetStr(ExecutionMode.OriginUpperLeft));
|
||||
|
||||
if (foDepthReplacing in DecorateList.FfemOpSet) then
|
||||
begin
|
||||
node:=HeaderList.AddSpirvOp(Op.OpExecutionMode);
|
||||
node^.AddParam(Main);
|
||||
node^.AddLiteral(ExecutionMode.DepthReplacing,ExecutionMode.GetStr(ExecutionMode.DepthReplacing));
|
||||
end;
|
||||
|
||||
if (foDepthGreater in DecorateList.FfemOpSet) then
|
||||
begin
|
||||
node:=HeaderList.AddSpirvOp(Op.OpExecutionMode);
|
||||
node^.AddParam(Main);
|
||||
node^.AddLiteral(ExecutionMode.DepthGreater,ExecutionMode.GetStr(ExecutionMode.DepthGreater));
|
||||
end;
|
||||
|
||||
if (foDepthLess in DecorateList.FfemOpSet) then
|
||||
begin
|
||||
node:=HeaderList.AddSpirvOp(Op.OpExecutionMode);
|
||||
node^.AddParam(Main);
|
||||
node^.AddLiteral(ExecutionMode.DepthLess,ExecutionMode.GetStr(ExecutionMode.DepthLess));
|
||||
end;
|
||||
|
||||
if (foDepthUnchanged in DecorateList.FfemOpSet) then
|
||||
begin
|
||||
node:=HeaderList.AddSpirvOp(Op.OpExecutionMode);
|
||||
node^.AddParam(Main);
|
||||
node^.AddLiteral(ExecutionMode.DepthUnchanged,ExecutionMode.GetStr(ExecutionMode.DepthUnchanged));
|
||||
end;
|
||||
|
||||
end;
|
||||
ExecutionModel.GLCompute:
|
||||
begin
|
||||
|
|
|
@ -100,7 +100,7 @@ begin
|
|||
$4:src[0]:=fetch_vsrc8(FSPI.EXP.VSRC2,dtFloat32);
|
||||
$8:src[0]:=fetch_vsrc8(FSPI.EXP.VSRC3,dtFloat32);
|
||||
else
|
||||
Assert(false);
|
||||
Assert(false,'FSPI.EXP.COMPR='+HexStr(f,1));
|
||||
end;
|
||||
dout:=FetchOutput(TpsslExportType(FSPI.EXP.TGT),dtFloat32); //output in FSPI.EXP.TGT
|
||||
OpStore(line,dout,src[0]);
|
||||
|
@ -112,7 +112,7 @@ begin
|
|||
3:rtype:=dtVec3f;
|
||||
4:rtype:=dtVec4f;
|
||||
else
|
||||
Assert(false,IntToStr(p));
|
||||
Assert(false,'FSPI.EXP.COMPR='+HexStr(f,1));
|
||||
end;
|
||||
|
||||
i:=0;
|
||||
|
@ -158,13 +158,11 @@ begin
|
|||
fetch_vsrc8_vec2h(FSPI.EXP.VSRC3,src[2],src[3]);
|
||||
end;
|
||||
else
|
||||
Assert(false);
|
||||
Assert(false,'FSPI.EXP.COMPR='+HexStr(f,1));
|
||||
end;
|
||||
|
||||
if Config.UseOutput16 then
|
||||
begin
|
||||
dst:=OpMakeVec(line,dtVec4h,@src);
|
||||
|
||||
rtype:=dtVec4h;
|
||||
end else
|
||||
begin
|
||||
|
|
|
@ -317,6 +317,7 @@ begin
|
|||
src:=RegsStory.get_ssrc8(SOFFSET);
|
||||
Result:=MakeRead(src,rtype);
|
||||
end;
|
||||
Assert(Result<>nil,'fetch_ssrc8');
|
||||
end;
|
||||
|
||||
function TEmitFetch.fetch_ssrc9(SSRC:Word;rtype:TsrDataType):PsrRegNode;
|
||||
|
@ -333,6 +334,7 @@ begin
|
|||
src:=RegsStory.get_ssrc9(SSRC);
|
||||
Result:=MakeRead(src,rtype);
|
||||
end;
|
||||
Assert(Result<>nil,'fetch_ssrc9');
|
||||
end;
|
||||
|
||||
function TEmitFetch.fetch_ssrc9_pair(SSRC:Word;src:PPsrRegNode;rtype:TsrDataType):Boolean;
|
||||
|
@ -361,6 +363,7 @@ var
|
|||
begin
|
||||
src:=RegsStory.get_vsrc8(VSRC);
|
||||
Result:=MakeRead(src,rtype);
|
||||
Assert(Result<>nil,'fetch_vsrc8');
|
||||
end;
|
||||
|
||||
function TEmitFetch.fetch_vdst8(VDST:Word;rtype:TsrDataType):PsrRegNode;
|
||||
|
@ -369,6 +372,7 @@ var
|
|||
begin
|
||||
src:=RegsStory.get_vdst8(VDST);
|
||||
Result:=MakeRead(src,rtype);
|
||||
Assert(Result<>nil,'fetch_vdst8');
|
||||
end;
|
||||
|
||||
procedure TEmitFetch.fetch_vsrc8_vec2h(VSRC:Word;var dst0,dst1:PsrRegNode);
|
||||
|
@ -379,6 +383,7 @@ begin
|
|||
pSlot:=RegsStory.get_vsrc8(VSRC);
|
||||
|
||||
dst:=MakeRead(pSlot,dtVec2h);
|
||||
Assert(dst<>nil,'fetch_vsrc8_vec2h');
|
||||
|
||||
dst0:=NewReg(dtHalf16);
|
||||
dst1:=NewReg(dtHalf16);;
|
||||
|
|
|
@ -32,8 +32,8 @@ type
|
|||
procedure emit_MIMG;
|
||||
procedure DistribDmask(DMASK:Byte;dst:PsrRegNode;info:PsrImageInfo);
|
||||
function GatherDmask(telem:TsrDataType):PsrRegNode;
|
||||
Function GatherCoord_f(var offset:DWORD;dim_id:Byte):PsrRegNode;
|
||||
Function GatherCoord_u(var offset:DWORD;dim_id:Byte):PsrRegNode;
|
||||
Function GatherCoord_f(var offset:DWORD;info:PsrImageInfo):PsrRegNode;
|
||||
Function GatherCoord_u(var offset:DWORD;info:PsrImageInfo):PsrRegNode;
|
||||
Function Gather_value(var offset:DWORD;rtype:TsrDataType):PsrRegNode;
|
||||
Function Gather_packed_offset(var offset:DWORD;dim:Byte):PsrRegNode;
|
||||
procedure Gather_sample_param(var p:TImgSampleParam;info:PsrImageInfo);
|
||||
|
@ -42,6 +42,8 @@ type
|
|||
procedure emit_image_sample_gather(Tgrp:PsrNode;info:PsrImageInfo);
|
||||
procedure emit_image_load(Tgrp:PsrNode;info:PsrImageInfo);
|
||||
procedure emit_image_store(Tgrp:PsrNode;info:PsrImageInfo);
|
||||
procedure emit_image_get_resinfo(Tgrp:PsrNode;info:PsrImageInfo);
|
||||
procedure emit_image_get_lod(Tgrp:PsrNode;info:PsrImageInfo);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
@ -372,6 +374,7 @@ begin
|
|||
Dim.Dim2D:Result:=2;
|
||||
Dim.Dim3D:Result:=3;
|
||||
Dim.Cube :Result:=3;
|
||||
else;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -488,8 +491,12 @@ end;
|
|||
procedure TEmit_MIMG.DistribDmask(DMASK:Byte;dst:PsrRegNode;info:PsrImageInfo); //result
|
||||
var
|
||||
pSlot:PsrRegSlot;
|
||||
i,d:Byte;
|
||||
dtype:TsrDataType;
|
||||
i,d,max:Byte;
|
||||
begin
|
||||
dtype:=dst^.dtype.Child;
|
||||
max :=dst^.dtype.Count;
|
||||
|
||||
d:=0;
|
||||
For i:=0 to 3 do
|
||||
if DMASK.TestBit(i) then
|
||||
|
@ -505,11 +512,17 @@ begin
|
|||
MakeCopy(pSlot,dst);
|
||||
end else
|
||||
begin
|
||||
SetConst_i(pSlot,info^.dtype,0);
|
||||
SetConst_i(pSlot,dtype,0);
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
OpExtract(line,pSlot^.New(line,info^.dtype),dst,i);
|
||||
if (i<max) then
|
||||
begin
|
||||
OpExtract(line,pSlot^.New(line,dtype),dst,i);
|
||||
end else
|
||||
begin
|
||||
SetConst_i(pSlot,dtype,0);
|
||||
end;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
@ -541,17 +554,17 @@ begin
|
|||
Result:=OpMakeVec(line,telem.AsVector(m+1),@src);
|
||||
end;
|
||||
|
||||
Function TEmit_MIMG.GatherCoord_f(var offset:DWORD;dim_id:Byte):PsrRegNode; //src
|
||||
Function TEmit_MIMG.GatherCoord_f(var offset:DWORD;info:PsrImageInfo):PsrRegNode; //src
|
||||
var
|
||||
src:array[0..3] of PsrRegNode;
|
||||
i,count:Byte;
|
||||
begin
|
||||
Result:=nil;
|
||||
|
||||
count:=GetDimCount(dim_id);
|
||||
count:=GetDimCount(info^.tinfo.Dim);
|
||||
if (FSPI.MIMG.DA<>0) then Inc(count); //slice
|
||||
|
||||
if (dim_id=Dim.Cube) then
|
||||
if (info^.tinfo.Dim=Dim.Cube) then
|
||||
begin
|
||||
//x,y,slice,(face_id+slice*8)
|
||||
|
||||
|
@ -566,6 +579,12 @@ begin
|
|||
src[0]:=fetch_vsrc8(FSPI.MIMG.VADDR+offset+0,dtFloat32); //x
|
||||
src[1]:=fetch_vsrc8(FSPI.MIMG.VADDR+offset+1,dtFloat32); //y
|
||||
src[2]:=fetch_vsrc8(FSPI.MIMG.VADDR+offset+2,dtFloat32); //face
|
||||
|
||||
if (info^.tinfo.Arrayed<>0) then //is array
|
||||
begin
|
||||
Inc(count);
|
||||
src[3]:=NewReg_s(dtFloat32,0);
|
||||
end;
|
||||
end;
|
||||
|
||||
Result:=OpMakeCub(line,TsrDataType(dtFloat32).AsVector(count),@src);
|
||||
|
@ -578,6 +597,15 @@ begin
|
|||
src[i]:=fetch_vsrc8(FSPI.MIMG.VADDR+offset+i,dtFloat32);
|
||||
end;
|
||||
|
||||
if (info^.tinfo.Arrayed<>0) and //is array
|
||||
(FSPI.MIMG.DA=0) then //not slice
|
||||
begin
|
||||
i:=count;
|
||||
Inc(count);
|
||||
|
||||
src[i]:=NewReg_s(dtFloat32,0);
|
||||
end;
|
||||
|
||||
if (count=1) then
|
||||
begin
|
||||
Result:=src[0];
|
||||
|
@ -591,17 +619,17 @@ begin
|
|||
offset:=offset+count;
|
||||
end;
|
||||
|
||||
Function TEmit_MIMG.GatherCoord_u(var offset:DWORD;dim_id:Byte):PsrRegNode; //src
|
||||
Function TEmit_MIMG.GatherCoord_u(var offset:DWORD;info:PsrImageInfo):PsrRegNode; //src
|
||||
var
|
||||
src:array[0..3] of PsrRegNode;
|
||||
i,count:Byte;
|
||||
begin
|
||||
Result:=nil;
|
||||
|
||||
count:=GetDimCount(dim_id);
|
||||
count:=GetDimCount(info^.tinfo.Dim);
|
||||
if (FSPI.MIMG.DA<>0) then Inc(count); //slice
|
||||
|
||||
if (dim_id=Dim.Cube) then
|
||||
if (info^.tinfo.Dim=Dim.Cube) then
|
||||
begin
|
||||
//x,y,slice,(face_id+slice*8)
|
||||
|
||||
|
@ -616,6 +644,12 @@ begin
|
|||
src[0]:=fetch_vsrc8(FSPI.MIMG.VADDR+offset+0,dtInt32); //x
|
||||
src[1]:=fetch_vsrc8(FSPI.MIMG.VADDR+offset+1,dtInt32); //y
|
||||
src[2]:=fetch_vsrc8(FSPI.MIMG.VADDR+offset+2,dtInt32); //face
|
||||
|
||||
if (info^.tinfo.Arrayed<>0) then //is array
|
||||
begin
|
||||
Inc(count);
|
||||
src[3]:=NewReg_i(dtInt32,0);
|
||||
end;
|
||||
end;
|
||||
|
||||
Result:=OpMakeCub(line,TsrDataType(dtInt32).AsVector(count),@src);
|
||||
|
@ -628,6 +662,15 @@ begin
|
|||
src[i]:=fetch_vsrc8(FSPI.MIMG.VADDR+offset+i,dtInt32);
|
||||
end;
|
||||
|
||||
if (info^.tinfo.Arrayed<>0) and //is array
|
||||
(FSPI.MIMG.DA=0) then //not slice
|
||||
begin
|
||||
i:=count;
|
||||
Inc(count);
|
||||
|
||||
src[i]:=NewReg_i(dtInt32,0);
|
||||
end;
|
||||
|
||||
if (count=1) then
|
||||
begin
|
||||
Result:=src[0];
|
||||
|
@ -695,7 +738,7 @@ begin
|
|||
Assert(false,'TODO imGrad');
|
||||
end;
|
||||
|
||||
p.coord:=GatherCoord_f(p.roffset,info^.tinfo.Dim);
|
||||
p.coord:=GatherCoord_f(p.roffset,info);
|
||||
|
||||
if (imLod in p.mods) then
|
||||
begin
|
||||
|
@ -894,7 +937,7 @@ begin
|
|||
Case FSPI.MIMG.OP of
|
||||
IMAGE_LOAD:
|
||||
begin
|
||||
coord:=GatherCoord_u(roffset,info^.tinfo.Dim);
|
||||
coord:=GatherCoord_u(roffset,info);
|
||||
node:=OpImageFetch(line,Tgrp,dst,coord);
|
||||
|
||||
if (info^.tinfo.MS<>0) then //fragid T# 2D MSAA
|
||||
|
@ -907,7 +950,7 @@ begin
|
|||
end;
|
||||
IMAGE_LOAD_MIP: //All except MSAA
|
||||
begin
|
||||
coord:=GatherCoord_u(roffset,info^.tinfo.Dim);
|
||||
coord:=GatherCoord_u(roffset,info);
|
||||
node:=OpImageFetch(line,Tgrp,dst,coord);
|
||||
|
||||
lod:=Gather_value(roffset,dtUint32);
|
||||
|
@ -937,7 +980,7 @@ begin
|
|||
Case FSPI.MIMG.OP of
|
||||
IMAGE_STORE:
|
||||
begin
|
||||
coord:=GatherCoord_u(roffset,info^.tinfo.Dim);
|
||||
coord:=GatherCoord_u(roffset,info);
|
||||
node:=OpImageWrite(line,Tgrp,coord,dst);
|
||||
|
||||
if (info^.tinfo.MS<>0) then //fragid T# 2D MSAA
|
||||
|
@ -950,7 +993,7 @@ begin
|
|||
end;
|
||||
IMAGE_STORE_MIP: //All except MSAA
|
||||
begin
|
||||
coord:=GatherCoord_u(roffset,info^.tinfo.Dim);
|
||||
coord:=GatherCoord_u(roffset,info);
|
||||
node:=OpImageWrite(line,Tgrp,coord,dst);
|
||||
|
||||
lod:=Gather_value(roffset,dtUint32);
|
||||
|
@ -964,6 +1007,82 @@ begin
|
|||
|
||||
end;
|
||||
|
||||
procedure TEmit_MIMG.emit_image_get_resinfo(Tgrp:PsrNode;info:PsrImageInfo);
|
||||
var
|
||||
offset:DWORD;
|
||||
dst,lod:PsrRegNode;
|
||||
|
||||
dvec:TsrDataType;
|
||||
count:Byte;
|
||||
begin
|
||||
offset:=0;
|
||||
lod:=Gather_value(offset,dtUint32);
|
||||
|
||||
count:=1;
|
||||
Case info^.tinfo.Dim of
|
||||
Dim.Dim2D:count:=2;
|
||||
Dim.Cube :count:=2;
|
||||
Dim.Dim3D:count:=3;
|
||||
else;
|
||||
end;
|
||||
if (info^.tinfo.Arrayed<>0) then Inc(count);
|
||||
|
||||
dvec:=TsrDataType(dtUint32).AsVector(count);
|
||||
|
||||
dst:=NewReg(dvec);
|
||||
|
||||
_Op2(line,Op.OpImageQuerySizeLod,dst,PsrRegNode(Tgrp),lod);
|
||||
|
||||
DistribDmask(FSPI.MIMG.DMASK,dst,info);
|
||||
|
||||
AddCapability(Capability.ImageQuery);
|
||||
end;
|
||||
|
||||
procedure TEmit_MIMG.emit_image_get_lod(Tgrp:PsrNode;info:PsrImageInfo);
|
||||
var
|
||||
src:array[0..3] of PsrRegSlot;
|
||||
|
||||
pLayout:PsrDataLayout;
|
||||
Sgrp:PsrNode;
|
||||
|
||||
dst,cmb:PsrRegNode;
|
||||
|
||||
param:TImgSampleParam;
|
||||
|
||||
mask:Byte;
|
||||
begin
|
||||
if not get_srsrc(FSPI.MIMG.SSAMP,4,@src) then Assert(false);
|
||||
|
||||
pLayout:=GroupingSharp(src,rtSSharp4);
|
||||
Sgrp:=FetchSampler(pLayout);
|
||||
|
||||
cmb:=OpSampledImage(line,Tgrp,Sgrp,info^.dtype,info^.tinfo);
|
||||
|
||||
Assert(FSPI.MIMG.DMASK=1,'FSPI.MIMG.DMASK<>1');
|
||||
|
||||
//gather
|
||||
param:=Default(TImgSampleParam);
|
||||
param.coord:=GatherCoord_f(param.roffset,info);
|
||||
//gather
|
||||
|
||||
dst:=NewReg(param.coord^.dtype);
|
||||
|
||||
_Op2(line,Op.OpImageQueryLod,dst,PsrRegNode(cmb),param.coord);
|
||||
|
||||
case param.coord^.dtype.Count of
|
||||
1:mask:=1;
|
||||
2:mask:=3;
|
||||
3:mask:=7;
|
||||
4:mask:=15;
|
||||
else
|
||||
mask:=0;
|
||||
end;
|
||||
|
||||
DistribDmask(mask,dst,info);
|
||||
|
||||
AddCapability(Capability.ImageQuery);
|
||||
end;
|
||||
|
||||
procedure TEmit_MIMG.emit_MIMG;
|
||||
var
|
||||
src:array[0..7] of PsrRegSlot;
|
||||
|
@ -977,15 +1096,15 @@ begin
|
|||
pLayout:=nil;
|
||||
|
||||
Case FSPI.MIMG.R128 of
|
||||
0:
|
||||
0: //256=8 *4*8
|
||||
begin
|
||||
if not get_srsrc(FSPI.MIMG.SRSRC,8,@src) then Assert(false);
|
||||
pLayout:=GroupingSharp(src,rtTSharp4);
|
||||
pLayout:=GroupingSharp(src,rtTSharp8);
|
||||
end;
|
||||
1:
|
||||
1: //128=4 *4*8
|
||||
begin
|
||||
if not get_srsrc(FSPI.MIMG.SRSRC,4,@src) then Assert(false);
|
||||
pLayout:=GroupingSharp(src,rtTSharp8);
|
||||
pLayout:=GroupingSharp(src,rtTSharp4);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -1033,6 +1152,22 @@ begin
|
|||
emit_image_store(Tgrp,@info);
|
||||
end;
|
||||
|
||||
IMAGE_GET_RESINFO: //get info by mip
|
||||
begin
|
||||
info.tinfo.Sampled:=1;
|
||||
Tgrp:=FetchImage(pLayout,info.dtype,info.tinfo);
|
||||
|
||||
emit_image_get_resinfo(Tgrp,@info);
|
||||
end;
|
||||
|
||||
IMAGE_GET_LOD:
|
||||
begin
|
||||
info.tinfo.Sampled:=1;
|
||||
Tgrp:=FetchImage(pLayout,info.dtype,info.tinfo);
|
||||
|
||||
emit_image_get_lod(Tgrp,@info);
|
||||
end;
|
||||
|
||||
else
|
||||
Assert(false,'MIMG?'+IntToStr(FSPI.MIMG.OP));
|
||||
end;
|
||||
|
|
|
@ -52,8 +52,15 @@ end;
|
|||
|
||||
procedure TEmit_MUBUF.make_load_comp(dst:PsrRegSlot;dtype:TsrDataType;rsl:PsrRegNode;i:Byte);
|
||||
begin
|
||||
dst^.New(line,dtype);
|
||||
OpExtract(line,dst^.current,rsl,i);
|
||||
if rsl^.dtype.isVector then
|
||||
begin
|
||||
dst^.New(line,dtype);
|
||||
OpExtract(line,dst^.current,rsl,i);
|
||||
end else
|
||||
begin
|
||||
Assert(i=0);
|
||||
MakeCopy(dst,rsl);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TEmit_MUBUF.emit_BUFFER_LOAD_VA(src:PPsrRegSlot;count:Byte):Boolean;
|
||||
|
|
|
@ -74,13 +74,15 @@ type
|
|||
function OpAbsDiff(pLine:PspirvOp;dst,src0,src1:PsrRegNode):PSpirvOp;
|
||||
procedure OpWQM32(dst:PsrRegSlot;src:PsrRegNode);
|
||||
//
|
||||
procedure OpBFEU32(dst:PsrRegSlot;base,src0,src1:PsrRegNode);
|
||||
procedure OpBFE_32(dst:PsrRegSlot;base,src0,src1:PsrRegNode);
|
||||
procedure OpBFIB32(dst:PsrRegSlot;bitmsk,src0,src1:PsrRegNode);
|
||||
//
|
||||
function OpBFITo(src0,src1,src2,src3:PsrRegNode;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
//
|
||||
procedure OpPackAnc(dst:PsrRegSlot;prim,smid,rtid:PsrRegNode);
|
||||
//
|
||||
function OpSMinTo(src0,src1:PsrRegNode;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
function OpSMaxTo(src0,src1:PsrRegNode;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
function OpUMinTo(src0,src1:PsrRegNode;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
function OpUMaxTo(src0,src1:PsrRegNode;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
function OpFMinTo(src0,src1:PsrRegNode;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
|
@ -88,6 +90,8 @@ type
|
|||
function OpNMinTo(src0,src1:PsrRegNode;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
function OpNMaxTo(src0,src1:PsrRegNode;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
//
|
||||
procedure OpMED3I(dst:PsrRegSlot;src0,src1,src2:PsrRegNode);
|
||||
procedure OpMED3U(dst:PsrRegSlot;src0,src1,src2:PsrRegNode);
|
||||
procedure OpMED3F(dst:PsrRegSlot;src0,src1,src2:PsrRegNode);
|
||||
//
|
||||
function OpPackOfs(pLine:PspirvOp;rtype:TsrDataType;count:Byte;src:PsrRegNode):PsrRegNode;
|
||||
|
@ -123,6 +127,7 @@ type
|
|||
function OpFMulToS(src0:PsrRegNode;src1:Single;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
//
|
||||
function OpUToF(src:PsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
function OpFToU(src:PsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
function OpSToF(src:PsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
function OpUToU(src:PsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
function OpSToS(src:PsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
|
@ -419,6 +424,7 @@ function TEmitOp.OpExtract(pLine:PspirvOp;dst,src:PsrRegNode;id:DWORD):PSpirvOp;
|
|||
Var
|
||||
node:PSpirvOp;
|
||||
begin
|
||||
Assert(src^.dtype.isVector);
|
||||
node:=AddSpirvOp(pLine,Op.OpCompositeExtract);
|
||||
node^.pType:=TypeList.Fetch(dst^.dtype);
|
||||
node^.pDst:=dst;
|
||||
|
@ -633,9 +639,9 @@ begin
|
|||
Op1(srOpUtils.OpWQM32,dtUnknow,dst,src);
|
||||
end;
|
||||
|
||||
procedure TEmitOp.OpBFEU32(dst:PsrRegSlot;base,src0,src1:PsrRegNode);
|
||||
procedure TEmitOp.OpBFE_32(dst:PsrRegSlot;base,src0,src1:PsrRegNode);
|
||||
begin
|
||||
Op3(srOpUtils.OpBFEU32,dtUint32,dst,base,src0,src1);
|
||||
Op3(srOpUtils.OpBFE_32,base^.dtype,dst,base,src0,src1);
|
||||
end;
|
||||
|
||||
procedure TEmitOp.OpBFIB32(dst:PsrRegSlot;bitmsk,src0,src1:PsrRegNode);
|
||||
|
@ -658,6 +664,18 @@ end;
|
|||
|
||||
//
|
||||
|
||||
function TEmitOp.OpSMinTo(src0,src1:PsrRegNode;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
begin
|
||||
Result:=NewReg(src0^.dtype);
|
||||
_set_line(ppLine,_OpGlsl2(_get_line(ppLine),GlslOp.SMin,Result,src0,src1));
|
||||
end;
|
||||
|
||||
function TEmitOp.OpSMaxTo(src0,src1:PsrRegNode;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
begin
|
||||
Result:=NewReg(src0^.dtype);
|
||||
_set_line(ppLine,_OpGlsl2(_get_line(ppLine),GlslOp.SMax,Result,src0,src1));
|
||||
end;
|
||||
|
||||
function TEmitOp.OpUMinTo(src0,src1:PsrRegNode;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
begin
|
||||
Result:=NewReg(src0^.dtype);
|
||||
|
@ -694,6 +712,32 @@ begin
|
|||
_set_line(ppLine,_OpGlsl2(_get_line(ppLine),GlslOp.NMax,Result,src0,src1));
|
||||
end;
|
||||
|
||||
procedure TEmitOp.OpMED3I(dst:PsrRegSlot;src0,src1,src2:PsrRegNode);
|
||||
var
|
||||
min:PsrRegNode;
|
||||
max:PsrRegNode;
|
||||
mmx:PsrRegNode;
|
||||
begin
|
||||
min:=OpSMinTo(src0,src1); //min(s0,s1)
|
||||
max:=OpSMaxTo(src0,src1); //max(s0,s1)
|
||||
mmx:=OpSMinTo(max ,src2); //min(max(s0,s1),s2)
|
||||
|
||||
OpGlsl2(GlslOp.SMax,src0^.dtype,dst,min,mmx); //max(min(s0,s1),min(max(s0,s1),s2))
|
||||
end;
|
||||
|
||||
procedure TEmitOp.OpMED3U(dst:PsrRegSlot;src0,src1,src2:PsrRegNode);
|
||||
var
|
||||
min:PsrRegNode;
|
||||
max:PsrRegNode;
|
||||
mmx:PsrRegNode;
|
||||
begin
|
||||
min:=OpUMinTo(src0,src1); //min(s0,s1)
|
||||
max:=OpUMaxTo(src0,src1); //max(s0,s1)
|
||||
mmx:=OpUMinTo(max ,src2); //min(max(s0,s1),s2)
|
||||
|
||||
OpGlsl2(GlslOp.UMax,src0^.dtype,dst,min,mmx); //max(min(s0,s1),min(max(s0,s1),s2))
|
||||
end;
|
||||
|
||||
procedure TEmitOp.OpMED3F(dst:PsrRegSlot;src0,src1,src2:PsrRegNode);
|
||||
var
|
||||
min:PsrRegNode;
|
||||
|
@ -1167,6 +1211,14 @@ begin
|
|||
_Op1(_get_line(ppLine),Op.OpConvertUToF,Result,src);
|
||||
end;
|
||||
|
||||
function TEmitOp.OpFToU(src:PsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
begin
|
||||
if (src=nil) then Exit(src);
|
||||
|
||||
Result:=NewReg(rtype);
|
||||
_Op1(_get_line(ppLine),Op.OpConvertFToU,Result,src);
|
||||
end;
|
||||
|
||||
function TEmitOp.OpSToF(src:PsrRegNode;rtype:TsrDataType;ppLine:PPspirvOp=nil):PsrRegNode;
|
||||
begin
|
||||
if (src=nil) then Exit(src);
|
||||
|
|
|
@ -63,6 +63,7 @@ type
|
|||
end;
|
||||
|
||||
function EnumLineRegs(cb:TRegsCb;pLine:PSpirvOp):Integer;
|
||||
function EnumFirstReg(cb:TRegsCb;pLine:PSpirvOp):Integer;
|
||||
function EnumBlockOpForward(cb:TPostCb;pBlock:PsrOpBlock):Integer;
|
||||
function EnumBlockOpBackward(cb:TPostCb;pBlock:PsrOpBlock):Integer;
|
||||
|
||||
|
@ -101,6 +102,25 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function EnumFirstReg(cb:TRegsCb;pLine:PSpirvOp):Integer;
|
||||
var
|
||||
node:POpParamNode;
|
||||
pReg:PsrRegNode;
|
||||
begin
|
||||
Result:=0;
|
||||
if (cb=nil) or (pLine=nil) then Exit;
|
||||
node:=pLine^.ParamFirst;
|
||||
if (node<>nil) then
|
||||
begin
|
||||
if node^.Value^.IsType(ntReg) then
|
||||
begin
|
||||
pReg:=node^.AsReg;
|
||||
Result:=Result+cb(pLine,pReg);
|
||||
node^.Value:=pReg;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function EnumBlockOpForward(cb:TPostCb;pBlock:PsrOpBlock):Integer;
|
||||
var
|
||||
node,prev:PSpirvOp;
|
||||
|
@ -429,10 +449,13 @@ begin
|
|||
if not node^.pDst^.IsType(ntReg) then Exit; //is reg
|
||||
|
||||
Case node^.OpId of
|
||||
Op.OpBitFieldUExtract ,
|
||||
Op.OpBitFieldSExtract ,
|
||||
Op.OpBitFieldUExtract :Result:=EnumFirstReg(@RegSTStrict,node);
|
||||
Op.OpSelect :Result:=EnumLineRegs(@RegSTStrict,node);
|
||||
Op.OpIAddCarry ,
|
||||
Op.OpISubBorrow ,
|
||||
Op.OpUMulExtended ,
|
||||
Op.OpSMulExtended ,
|
||||
Op.OpCompositeConstruct:Result:=EnumLineRegs(@RegVTStrict,node);
|
||||
else;
|
||||
end;
|
||||
|
@ -698,7 +721,14 @@ begin
|
|||
end;
|
||||
F:=F.pField^.FetchValue(_offset,pChain^.size,dtype);
|
||||
|
||||
until (F.fValue<>frNotFit);
|
||||
case F.fValue of
|
||||
frNotFit,
|
||||
frIdent :Break;
|
||||
else;
|
||||
end;
|
||||
|
||||
until false;
|
||||
|
||||
if (F.fValue<>frNotFit) then Break;
|
||||
|
||||
buf:=BufferList.NextAlias(buf);
|
||||
|
@ -760,7 +790,14 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
until (F.fValue<>frNotFit);
|
||||
case F.fValue of
|
||||
frNotFit,
|
||||
frIdent :Break;
|
||||
else;
|
||||
end;
|
||||
|
||||
until false;
|
||||
|
||||
if (F.fValue<>frNotFit) then Break;
|
||||
|
||||
buf:=BufferList.NextAlias(buf);
|
||||
|
|
|
@ -38,7 +38,7 @@ type
|
|||
function OnWQM32__1(node:PSpirvOp):Integer;
|
||||
function OnPackOfs1(node:PSpirvOp):Integer;
|
||||
function _Fetch_PackAnc(node:PsrRegNode;index,count:Byte):PsrRegNode;
|
||||
function OnBFEU32_1(node:PSpirvOp):Integer;
|
||||
function OnBFE_32_1(node:PSpirvOp):Integer;
|
||||
function OnBFIB32_1(node:PSpirvOp):Integer;
|
||||
function OnMakeCub1(node:PSpirvOp):Integer;
|
||||
//
|
||||
|
@ -47,6 +47,7 @@ type
|
|||
function OnBitwiseOr1(node:PSpirvOp):Integer;
|
||||
function OnLogicalOr1(node:PSpirvOp):Integer;
|
||||
function OnNot1(node:PSpirvOp):Integer;
|
||||
function OnLogicalNot1(node:PSpirvOp):Integer;
|
||||
function OnBranchConditional1(node:PSpirvOp):Integer;
|
||||
//
|
||||
function OpBitCount1(node:PSpirvOp):Integer;
|
||||
|
@ -91,7 +92,7 @@ begin
|
|||
srOpUtils.OpAbsDiff :Result:=OnAbsDiff1(node);
|
||||
srOpUtils.OpWQM32 :Result:=OnWQM32__1(node);
|
||||
srOpUtils.OpPackOfs :Result:=OnPackOfs1(node);
|
||||
srOpUtils.OpBFEU32 :Result:=OnBFEU32_1(node);
|
||||
srOpUtils.OpBFE_32 :Result:=OnBFE_32_1(node);
|
||||
srOpUtils.OpBFIB32 :Result:=OnBFIB32_1(node);
|
||||
srOpUtils.OpMakeCub :Result:=OnMakeCub1(node);
|
||||
|
||||
|
@ -103,6 +104,7 @@ begin
|
|||
Op.OpLogicalOr :Result:=OnLogicalOr1(node);
|
||||
|
||||
Op.OpNot :Result:=OnNot1(node);
|
||||
Op.OpLogicalNot :Result:=OnLogicalNot1(node);
|
||||
|
||||
Op.OpBranchConditional:Result:=OnBranchConditional1(node);
|
||||
|
||||
|
@ -751,6 +753,54 @@ begin
|
|||
Result:=Result+PrepTypeParam(node^.ParamNode(0),dst^.dtype);
|
||||
end;
|
||||
|
||||
function TEmitPostOp.OnLogicalNot1(node:PSpirvOp):Integer;
|
||||
var
|
||||
dtype:TsrDataType;
|
||||
dst:PsrRegNode;
|
||||
src:PsrRegNode;
|
||||
|
||||
dst2:PsrRegNode;
|
||||
srp:array[0..1] of PsrRegNode;
|
||||
pop:PSpirvOp;
|
||||
cmp:DWORD;
|
||||
|
||||
procedure _SetReg(src:PsrRegNode);
|
||||
begin
|
||||
dst^.pWriter:=src;
|
||||
node^.mark_not_used;
|
||||
node^.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
||||
begin
|
||||
Result:=0;
|
||||
dst:=node^.pDst^.AsType(ntReg);
|
||||
src:=RegDown(node^.ParamNode(0)^.AsReg);
|
||||
|
||||
if (dst=nil) or (src=nil) then Exit;
|
||||
|
||||
if (src^.read_count>1) then Exit;
|
||||
|
||||
pop:=src^.pWriter^.AsType(ntOp);
|
||||
|
||||
if (pop=nil) then Exit;
|
||||
|
||||
cmp:=pop^.OpId;
|
||||
cmp:=get_inverse_not_cmp_op(cmp);
|
||||
|
||||
if (cmp=0) then Exit;
|
||||
|
||||
srp[0]:=pop^.ParamNode(0)^.AsReg;
|
||||
srp[1]:=pop^.ParamNode(1)^.AsReg;
|
||||
|
||||
if (srp[0]=nil) or (srp[1]=nil) then Exit;
|
||||
|
||||
dst2:=NewReg(dtBool);
|
||||
_Op2(pop,cmp,dst2,srp[0],srp[1]);
|
||||
|
||||
_SetReg(dst2);
|
||||
end;
|
||||
|
||||
function TEmitPostOp.OnBranchConditional1(node:PSpirvOp):Integer;
|
||||
var
|
||||
src,prv:PsrRegNode;
|
||||
|
@ -819,6 +869,7 @@ end;
|
|||
|
||||
Function ReverseBits(src:QWORD;count:Byte):QWORD;
|
||||
var
|
||||
v:QWORD;
|
||||
i:Byte;
|
||||
begin
|
||||
Result:=0;
|
||||
|
@ -826,7 +877,8 @@ begin
|
|||
dec(count);
|
||||
For i:=0 to count do
|
||||
begin
|
||||
Result.Bits[i]:=src.Bits[count-i];
|
||||
v:=((src shr i) and 1); //get
|
||||
Result:=Result or (v shl (count-i)); //set
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -1014,31 +1066,35 @@ end;
|
|||
function TEmitPostOp.OnCompositeExtract1(node:PSpirvOp):Integer;
|
||||
var
|
||||
pc:PsrConst;
|
||||
dst,src:PsrRegNode;
|
||||
dst,org,src:PsrRegNode;
|
||||
pos:PtrUint;
|
||||
begin
|
||||
Result:=0;
|
||||
dst:=node^.pDst^.AsType(ntReg);
|
||||
src:=RegDown(node^.ParamNode(0)^.AsReg);
|
||||
org:=node^.ParamNode(0)^.AsReg;
|
||||
src:=RegDown(org);
|
||||
|
||||
if (dst=nil) or (src=nil) then Exit;
|
||||
|
||||
pos:=0;
|
||||
if not node^.ParamNode(1)^.TryGetValue(pos) then Exit;
|
||||
|
||||
if src^.is_const then
|
||||
begin
|
||||
pc:=src^.AsConst;
|
||||
if (pos<pc^.ItemCount) then
|
||||
begin
|
||||
pc:=pc^.GetConst(pos);
|
||||
dst^.pWriter:=pc;
|
||||
if not src^.is_const then Exit;
|
||||
|
||||
node^.mark_not_used;
|
||||
node^.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
end;
|
||||
pc:=src^.AsConst;
|
||||
|
||||
pc:=ConstList.Bitcast(org^.dtype,pc);
|
||||
|
||||
if (pos>=pc^.ItemCount) then Exit;
|
||||
|
||||
pc:=pc^.GetConst(pos);
|
||||
if (pc=nil) then Exit;
|
||||
|
||||
dst^.pWriter:=pc;
|
||||
|
||||
node^.mark_not_used;
|
||||
node^.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
||||
{
|
||||
|
@ -1082,6 +1138,27 @@ var
|
|||
dtype:TsrDataType;
|
||||
dst:PsrRegNode;
|
||||
src:array[0..1] of PsrRegNode;
|
||||
|
||||
cst:array[0..1] of PsrConst;
|
||||
|
||||
pLine:PSpirvOp;
|
||||
|
||||
procedure _SetConst(dtype:TsrDataType;value:QWORD);
|
||||
begin
|
||||
dst^.pWriter:=ConstList.Fetch(dtype,value);
|
||||
node^.mark_not_used;
|
||||
node^.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
||||
procedure _SetReg(src:PsrRegNode);
|
||||
begin
|
||||
dst^.pWriter:=src;
|
||||
node^.mark_not_used;
|
||||
node^.pDst:=nil;
|
||||
Inc(Result);
|
||||
end;
|
||||
|
||||
begin
|
||||
Result:=0;
|
||||
dst:=node^.pDst^.AsType(ntReg);
|
||||
|
@ -1090,6 +1167,41 @@ begin
|
|||
|
||||
if (dst=nil) or (src[0]=nil) or (src[1]=nil) then Exit;
|
||||
|
||||
cst[0]:=RegDown(src[0])^.AsConst;
|
||||
cst[1]:=RegDown(src[1])^.AsConst;
|
||||
if (cst[0]<>nil) and (cst[1]<>nil) then
|
||||
begin
|
||||
|
||||
if (cst[0]^.GetData=cst[1]^.GetData) then
|
||||
begin
|
||||
_SetConst(dst^.dtype,cst[0]^.GetData);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if (dst^.dtype=dtBool) and
|
||||
(cst[0]^.dtype=dtBool) and
|
||||
(cst[1]^.dtype=dtBool) then
|
||||
begin
|
||||
if (cst[0]^.AsBool=True) and (cst[1]^.AsBool=False) then
|
||||
begin
|
||||
src[0]:=node^.ParamNode(0)^.AsReg;
|
||||
_SetReg(src[0]);
|
||||
Exit;
|
||||
end else
|
||||
if (cst[0]^.AsBool=False) and (cst[1]^.AsBool=True) then
|
||||
begin
|
||||
src[0]:=node^.ParamNode(0)^.AsReg;
|
||||
pLine:=src[0]^.pLine;
|
||||
src[1]:=OpNotTo(src[0],@pLine);
|
||||
src[1]^.PrepType(ord(dtBool));
|
||||
_SetReg(src[1]);
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
end;
|
||||
|
||||
dtype:=LazyType3(dst^.dtype,src[0]^.dtype,src[1]^.dtype);
|
||||
|
||||
if (node^.pType^.dtype<>dtype) then
|
||||
|
@ -1777,7 +1889,7 @@ begin
|
|||
|
||||
end;
|
||||
|
||||
function TEmitPostOp.OnBFEU32_1(node:PSpirvOp):Integer;
|
||||
function TEmitPostOp.OnBFE_32_1(node:PSpirvOp):Integer;
|
||||
var
|
||||
dst:PsrRegNode;
|
||||
rBase,rIndex,rCount:PsrRegNode;
|
||||
|
@ -1785,6 +1897,7 @@ var
|
|||
num_31:PsrRegNode;
|
||||
data:array[0..1] of QWORD;
|
||||
index,count:Byte;
|
||||
dtype:TsrDataType;
|
||||
begin
|
||||
Result:=0;
|
||||
dst:=node^.pDst^.AsType(ntReg);
|
||||
|
@ -1796,6 +1909,8 @@ begin
|
|||
|
||||
if (rBase=nil) or (rIndex=nil) or (rCount=nil) then Exit;
|
||||
|
||||
dtype:=rBase^.dtype;
|
||||
|
||||
//else
|
||||
node^.mark_not_used;
|
||||
node^.pDst:=nil;
|
||||
|
@ -1830,7 +1945,7 @@ begin
|
|||
num_31:=NewReg_q(dtUInt32,data[1],@Node);
|
||||
//
|
||||
rsl:=OpAndTo(rsl,num_31,@node);
|
||||
rsl^.PrepType(ord(dtUInt32));
|
||||
rsl^.PrepType(ord(dtype));
|
||||
end;
|
||||
|
||||
dst^.pWriter:=rsl;
|
||||
|
@ -1890,7 +2005,13 @@ begin
|
|||
rCount^.PrepType(ord(dtUInt32));
|
||||
end;
|
||||
|
||||
_Op3(node,Op.OpBitFieldUExtract,dst,rBase,rIndex,rCount);
|
||||
case dtype of
|
||||
dtUint32:_Op3(node,Op.OpBitFieldUExtract,dst,rBase,rIndex,rCount);
|
||||
dtInt32 :_Op3(node,Op.OpBitFieldSExtract,dst,rBase,rIndex,rCount);
|
||||
else
|
||||
Assert(False);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function TEmitPostOp.OnBFIB32_1(node:PSpirvOp):Integer;
|
||||
|
|
|
@ -16,17 +16,18 @@ uses
|
|||
type
|
||||
TEmit_SOP2=class(TEmitFetch)
|
||||
procedure emit_SOP2;
|
||||
procedure emit_S_ADD_U32;
|
||||
procedure emit_S_ADD_I32;
|
||||
procedure emit_S_ADD_B32(rtype:TsrDataType);
|
||||
procedure emit_S_SUB_B32(rtype:TsrDataType);
|
||||
procedure emit_S_ADDC_U32;
|
||||
procedure emit_S_MUL_I32;
|
||||
procedure OpISccNotZero(src:PsrRegNode);
|
||||
procedure emit_S_LSHL_B32;
|
||||
procedure emit_S_LSHR_B32;
|
||||
procedure emit_S_SH(OpId:DWORD;rtype:TsrDataType);
|
||||
procedure emit_S_AND_B32;
|
||||
procedure emit_S_AND_B64;
|
||||
procedure emit_S_ANDN2_B64;
|
||||
procedure emit_S_OR_B32;
|
||||
procedure emit_S_OR_B64;
|
||||
procedure emit_S_XOR_B32;
|
||||
procedure emit_S_XOR_B64;
|
||||
procedure emit_S_ORN2_B64;
|
||||
procedure emit_S_NAND_B64;
|
||||
|
@ -39,7 +40,7 @@ type
|
|||
|
||||
implementation
|
||||
|
||||
procedure TEmit_SOP2.emit_S_ADD_U32;
|
||||
procedure TEmit_SOP2.emit_S_ADD_B32(rtype:TsrDataType);
|
||||
Var
|
||||
dst,car:PsrRegSlot;
|
||||
src:array[0..1] of PsrRegNode;
|
||||
|
@ -47,24 +48,24 @@ begin
|
|||
dst:=get_sdst7(FSPI.SOP2.SDST);
|
||||
car:=get_scc;
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtUInt32);
|
||||
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUInt32);
|
||||
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,rtype);
|
||||
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,rtype);
|
||||
|
||||
OpIAddExt(dst,car,src[0],src[1]);
|
||||
end;
|
||||
|
||||
procedure TEmit_SOP2.emit_S_ADD_I32;
|
||||
procedure TEmit_SOP2.emit_S_SUB_B32(rtype:TsrDataType);
|
||||
Var
|
||||
dst,car:PsrRegSlot;
|
||||
dst,bor:PsrRegSlot;
|
||||
src:array[0..1] of PsrRegNode;
|
||||
begin
|
||||
dst:=get_sdst7(FSPI.SOP2.SDST);
|
||||
car:=get_scc;
|
||||
bor:=get_scc;
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtInt32);
|
||||
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtInt32);
|
||||
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,rtype);
|
||||
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,rtype);
|
||||
|
||||
OpIAddExt(dst,car,src[0],src[1]);
|
||||
OpISubExt(dst,bor,src[0],src[1]);
|
||||
end;
|
||||
|
||||
procedure TEmit_SOP2.emit_S_ADDC_U32;
|
||||
|
@ -110,38 +111,20 @@ begin
|
|||
get_scc^.current^.dtype:=dtBool; //implict cast (int != 0)
|
||||
end;
|
||||
|
||||
procedure TEmit_SOP2.emit_S_LSHL_B32;
|
||||
procedure TEmit_SOP2.emit_S_SH(OpId:DWORD;rtype:TsrDataType);
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..1] of PsrRegNode;
|
||||
begin
|
||||
dst:=get_sdst7(FSPI.SOP2.SDST);
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtUInt32);
|
||||
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,rtype);
|
||||
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUInt32);
|
||||
|
||||
src[1]:=OpAndTo(src[1],31);
|
||||
src[1]^.PrepType(ord(dtUInt32));
|
||||
|
||||
Op2(Op.OpShiftLeftLogical,src[0]^.dtype,dst,src[0],src[1]);
|
||||
|
||||
OpISccNotZero(dst^.current); //SCC = (sdst.u != 0)
|
||||
end;
|
||||
|
||||
procedure TEmit_SOP2.emit_S_LSHR_B32;
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..1] of PsrRegNode;
|
||||
begin
|
||||
dst:=get_sdst7(FSPI.SOP2.SDST);
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtUInt32);
|
||||
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUInt32);
|
||||
|
||||
src[1]:=OpAndTo(src[1],31);
|
||||
src[1]^.PrepType(ord(dtUInt32));
|
||||
|
||||
Op2(Op.OpShiftRightLogical,src[0]^.dtype,dst,src[0],src[1]);
|
||||
Op2(OpId,src[0]^.dtype,dst,src[0],src[1]);
|
||||
|
||||
OpISccNotZero(dst^.current); //SCC = (sdst.u != 0)
|
||||
end;
|
||||
|
@ -202,6 +185,21 @@ begin
|
|||
OpLogicalOr(get_scc,src2[0],src2[1]); //implict cast (int != 0)
|
||||
end;
|
||||
|
||||
procedure TEmit_SOP2.emit_S_OR_B32;
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..1] of PsrRegNode;
|
||||
begin
|
||||
dst:=get_sdst7(FSPI.SOP2.SDST);
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtUInt32);
|
||||
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUInt32);
|
||||
|
||||
OpBitwiseOr(dst,src[0],src[1]);
|
||||
|
||||
OpISccNotZero(dst^.current); //SCC = (sdst.u != 0)
|
||||
end;
|
||||
|
||||
procedure TEmit_SOP2.emit_S_OR_B64; //sdst[2] = (ssrc0[2] | ssrc1[2]); SCC = (sdst[2] != 0)
|
||||
Var
|
||||
dst:array[0..1] of PsrRegSlot;
|
||||
|
@ -221,6 +219,21 @@ begin
|
|||
OpLogicalOr(get_scc,src2[0],src2[1]); //implict cast (int != 0)
|
||||
end;
|
||||
|
||||
procedure TEmit_SOP2.emit_S_XOR_B32;
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..1] of PsrRegNode;
|
||||
begin
|
||||
dst:=get_sdst7(FSPI.SOP2.SDST);
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtUInt32);
|
||||
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUInt32);
|
||||
|
||||
OpBitwiseXor(dst,src[0],src[1]);
|
||||
|
||||
OpISccNotZero(dst^.current); //SCC = (sdst.u != 0)
|
||||
end;
|
||||
|
||||
procedure TEmit_SOP2.emit_S_XOR_B64; //sdst[2] = (ssrc0[2] ^ ssrc1[2]); SCC = (sdst[2] != 0)
|
||||
Var
|
||||
dst:array[0..1] of PsrRegSlot;
|
||||
|
@ -348,8 +361,8 @@ Var
|
|||
begin
|
||||
dst:=get_sdst7(FSPI.SOP2.SDST);
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtUint32);
|
||||
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUint32);
|
||||
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtUInt32);
|
||||
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUInt32);
|
||||
|
||||
offset:=OpAndTo(src[1],31);
|
||||
count :=OpShrTo(src[1],16);
|
||||
|
@ -367,8 +380,8 @@ Var
|
|||
begin
|
||||
dst:=get_sdst7(FSPI.SOP2.SDST);
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtUint32);
|
||||
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUint32);
|
||||
src[0]:=fetch_ssrc9(FSPI.SOP2.SSRC0,dtUInt32);
|
||||
src[1]:=fetch_ssrc9(FSPI.SOP2.SSRC1,dtUInt32);
|
||||
|
||||
src[0]:=OpAndTo(src[0],31);
|
||||
src[1]:=OpAndTo(src[1],31);
|
||||
|
@ -376,12 +389,12 @@ begin
|
|||
src[0]^.PrepType(ord(dtUInt32));
|
||||
src[1]^.PrepType(ord(dtUInt32));
|
||||
|
||||
one:=NewReg_q(dtUint32,1);
|
||||
one:=NewReg_q(dtUInt32,1);
|
||||
|
||||
src[0]:=OpShrTo(one,src[0]); //(1 << src0)
|
||||
src[0]:=OpISubTo(src[0],1); //-1
|
||||
|
||||
Op2(Op.OpShiftRightLogical,dtUint32,dst,src[0],src[1]);
|
||||
Op2(Op.OpShiftRightLogical,dtUInt32,dst,src[0],src[1]);
|
||||
end;
|
||||
|
||||
procedure TEmit_SOP2.emit_SOP2;
|
||||
|
@ -389,23 +402,29 @@ begin
|
|||
|
||||
Case FSPI.SOP2.OP of
|
||||
|
||||
S_ADD_U32: emit_S_ADD_U32;
|
||||
S_ADD_I32: emit_S_ADD_I32;
|
||||
S_ADD_U32: emit_S_ADD_B32(dtUInt32);
|
||||
S_ADD_I32: emit_S_ADD_B32(dtInt32);
|
||||
|
||||
S_SUB_U32: emit_S_SUB_B32(dtUInt32);
|
||||
S_SUB_I32: emit_S_SUB_B32(dtInt32);
|
||||
|
||||
S_ADDC_U32: emit_S_ADDC_U32;
|
||||
|
||||
S_MUL_I32: emit_S_MUL_I32;
|
||||
|
||||
S_LSHL_B32: emit_S_LSHL_B32;
|
||||
S_LSHR_B32: emit_S_LSHR_B32;
|
||||
S_LSHL_B32: emit_S_SH(Op.OpShiftLeftLogical ,dtUInt32);
|
||||
S_LSHR_B32: emit_S_SH(Op.OpShiftRightLogical ,dtUInt32);
|
||||
S_ASHR_I32: emit_S_SH(Op.OpShiftRightArithmetic,dtInt32);
|
||||
|
||||
S_AND_B32: emit_S_AND_B32;
|
||||
S_AND_B64: emit_S_AND_B64;
|
||||
|
||||
S_ANDN2_B64: emit_S_ANDN2_B64;
|
||||
|
||||
S_OR_B32: emit_S_OR_B32;
|
||||
S_OR_B64: emit_S_OR_B64;
|
||||
|
||||
S_XOR_B32: emit_S_XOR_B32;
|
||||
S_XOR_B64: emit_S_XOR_B64;
|
||||
|
||||
S_ORN2_B64: emit_S_ORN2_B64;
|
||||
|
|
|
@ -5,17 +5,20 @@ unit emit_SOPK;
|
|||
interface
|
||||
|
||||
uses
|
||||
sysutils,
|
||||
ps4_pssl,
|
||||
srType,
|
||||
srReg,
|
||||
emit_fetch;
|
||||
sysutils,
|
||||
spirv,
|
||||
ps4_pssl,
|
||||
srType,
|
||||
srReg,
|
||||
emit_fetch;
|
||||
|
||||
type
|
||||
TEmit_SOPK=class(TEmitFetch)
|
||||
procedure emit_SOPK;
|
||||
procedure emit_S_MOVK_I32;
|
||||
procedure emit_S_ADDK_I32;
|
||||
procedure emit_S_CMPK_I32(OpId:DWORD);
|
||||
procedure emit_S_CMPK_U32(OpId:DWORD);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
@ -51,11 +54,53 @@ begin
|
|||
OpIAddExt(dst,car,src,imm);
|
||||
end;
|
||||
|
||||
procedure TEmit_SOPK.emit_S_CMPK_I32(OpId:DWORD); //SCC = compareOp(sdst.s, signExtend(imm16.s))
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:PsrRegNode;
|
||||
imm:PsrRegNode;
|
||||
begin
|
||||
dst:=get_scc;
|
||||
|
||||
src:=fetch_ssrc8(FSPI.SOPK.SDST,dtInt32);
|
||||
imm:=NewReg_i(dtInt32,SignExtend16(FSPI.SOPK.SIMM));
|
||||
|
||||
OpCmpS(OpId,dst,src,imm);
|
||||
end;
|
||||
|
||||
procedure TEmit_SOPK.emit_S_CMPK_U32(OpId:DWORD); //SCC = compareOp(sdst.u, imm16.u)
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:PsrRegNode;
|
||||
imm:PsrRegNode;
|
||||
begin
|
||||
dst:=get_scc;
|
||||
|
||||
src:=fetch_ssrc8(FSPI.SOPK.SDST,dtUint32);
|
||||
imm:=NewReg_i(dtUint32,FSPI.SOPK.SIMM);
|
||||
|
||||
OpCmpS(OpId,dst,src,imm);
|
||||
end;
|
||||
|
||||
procedure TEmit_SOPK.emit_SOPK;
|
||||
begin
|
||||
|
||||
Case FSPI.SOPK.OP of
|
||||
|
||||
S_CMPK_EQ_I32:emit_S_CMPK_I32(Op.OpIEqual);
|
||||
S_CMPK_LG_I32:emit_S_CMPK_I32(Op.OpINotEqual);
|
||||
S_CMPK_GT_I32:emit_S_CMPK_I32(Op.OpSGreaterThan);
|
||||
S_CMPK_GE_I32:emit_S_CMPK_I32(Op.OpSGreaterThanEqual);
|
||||
S_CMPK_LT_I32:emit_S_CMPK_I32(Op.OpSLessThan);
|
||||
S_CMPK_LE_I32:emit_S_CMPK_I32(Op.OpSLessThanEqual);
|
||||
|
||||
S_CMPK_EQ_U32:emit_S_CMPK_U32(Op.OpIEqual);
|
||||
S_CMPK_LG_U32:emit_S_CMPK_U32(Op.OpINotEqual);
|
||||
S_CMPK_GT_U32:emit_S_CMPK_U32(Op.OpSGreaterThan);
|
||||
S_CMPK_GE_U32:emit_S_CMPK_U32(Op.OpSGreaterThanEqual);
|
||||
S_CMPK_LT_U32:emit_S_CMPK_U32(Op.OpSLessThan);
|
||||
S_CMPK_LE_U32:emit_S_CMPK_U32(Op.OpSLessThanEqual);
|
||||
|
||||
S_MOVK_I32: emit_S_MOVK_I32;
|
||||
|
||||
S_ADDK_I32: emit_S_ADDK_I32;
|
||||
|
|
|
@ -104,15 +104,46 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
if (lc.elem_resl<>lc.elem_orig) then
|
||||
begin
|
||||
case lc.elem_resl of
|
||||
dtFloat32: //isScalar
|
||||
begin
|
||||
|
||||
Case lc.info.NFMT of
|
||||
BUF_NUM_FORMAT_UNORM:
|
||||
begin
|
||||
For i:=0 to lc.elem_count-1 do
|
||||
begin
|
||||
lc.elm[i]:=OpFMulToS(lc.elm[i],255);
|
||||
lc.elm[i]:=OpFToU(lc.elm[i],lc.elem_orig);
|
||||
end;
|
||||
end;
|
||||
else
|
||||
Assert(false,'TODO CONVERT');
|
||||
end;
|
||||
|
||||
end;
|
||||
dtUint32,
|
||||
dtInt32 : //isInt
|
||||
begin
|
||||
Assert(false,'TODO CONVERT');
|
||||
end;
|
||||
else
|
||||
Assert(False);
|
||||
end;
|
||||
end;
|
||||
|
||||
Case lc.elem_count of
|
||||
1:rsl:=lc.elm[0];
|
||||
else
|
||||
begin
|
||||
rsl:=OpMakeVec(line,lc.elem_resl.AsVector(lc.elem_count),@lc.elm);
|
||||
rsl:=OpMakeVec(line,lc.elem_orig.AsVector(lc.elem_count),@lc.elm);
|
||||
//rsl:=OpMakeVec(line,lc.elem_resl.AsVector(lc.elem_count),@lc.elm);
|
||||
end;
|
||||
end;
|
||||
|
||||
Assert(lc.elem_resl=lc.elem_orig,'TODO CONVERT');
|
||||
//Assert(lc.elem_resl=lc.elem_orig,'TODO CONVERT');
|
||||
|
||||
csize:=Min(lc.info.GetElemSize*lc.elem_count,lc.info.GetSizeFormat);
|
||||
orig:=lc.v.data[0];
|
||||
|
|
|
@ -29,7 +29,7 @@ var
|
|||
|
||||
inp_SRC:PsrInput;
|
||||
|
||||
rsl:PsrRegNode;
|
||||
rsl,elm:PsrRegNode;
|
||||
|
||||
begin
|
||||
Assert(FExecutionModel=ExecutionModel.Fragment); //only pixel shader
|
||||
|
@ -38,8 +38,8 @@ begin
|
|||
|
||||
inp_M0:=GetInputRegNode(get_m0^.current);
|
||||
|
||||
Assert(inp_M0<>nil);
|
||||
Assert(inp_M0^.itype=itPsState);
|
||||
//Assert(inp_M0<>nil);
|
||||
//Assert(inp_M0^.itype=itPsState);
|
||||
|
||||
Case FSPI.VINTRP.OP of
|
||||
V_INTERP_P1_F32:
|
||||
|
@ -65,8 +65,9 @@ begin
|
|||
|
||||
rsl:=AddFragLayout(inp_SRC^.itype,dtVec4f,FSPI.VINTRP.ATTR);
|
||||
|
||||
dst^.New(line,dtFloat32);
|
||||
OpExtract(line,dst^.current,rsl,FSPI.VINTRP.ATTRCHAN);
|
||||
elm:=dst^.New(line,dtFloat32);
|
||||
|
||||
OpExtract(line,elm,rsl,FSPI.VINTRP.ATTRCHAN);
|
||||
end;
|
||||
|
||||
V_INTERP_P2_F32:
|
||||
|
@ -92,8 +93,9 @@ begin
|
|||
|
||||
rsl:=AddFragLayout(inp_SRC^.itype,dtVec4f,FSPI.VINTRP.ATTR);
|
||||
|
||||
dst^.New(line,dtFloat32);
|
||||
OpExtract(line,dst^.current,rsl,FSPI.VINTRP.ATTRCHAN);
|
||||
elm:=dst^.New(line,dtFloat32);
|
||||
|
||||
OpExtract(line,elm,rsl,FSPI.VINTRP.ATTRCHAN);
|
||||
end;
|
||||
|
||||
V_INTERP_MOV_F32:
|
||||
|
@ -105,8 +107,9 @@ begin
|
|||
|
||||
rsl:=AddFragLayout(inp_SRC^.itype,dtVec4f,FSPI.VINTRP.ATTR);
|
||||
|
||||
dst^.New(line,dtFloat32);
|
||||
OpExtract(line,dst^.current,rsl,FSPI.VINTRP.ATTRCHAN);
|
||||
elm:=dst^.New(line,dtFloat32);
|
||||
|
||||
OpExtract(line,elm,rsl,FSPI.VINTRP.ATTRCHAN);
|
||||
end;
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@ type
|
|||
procedure emit_V_CVT_FLR_I32_F32;
|
||||
procedure emit_V_CVT_RPI_I32_F32;
|
||||
procedure emit_V_CVT_F32_UBYTE0;
|
||||
procedure emit_V_CVT_F32_UBYTE1;
|
||||
procedure emit_V_CVT_F32_UBYTE2;
|
||||
procedure emit_V_CVT_F32_UBYTE3;
|
||||
procedure emit_V_EXT_F32(OpId:DWORD);
|
||||
procedure emit_V_RSQ_CLAMP_F32;
|
||||
procedure emit_V_SIN_COS(OpId:DWORD);
|
||||
|
@ -152,6 +155,51 @@ begin
|
|||
Op1(Op.OpConvertUToF,dtFloat32,dst,src);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP1.emit_V_CVT_F32_UBYTE1;
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:PsrRegNode;
|
||||
begin
|
||||
dst:=get_vdst8(FSPI.VOP1.VDST);
|
||||
src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtUInt32);
|
||||
|
||||
src:=OpShrTo(src,8);
|
||||
src:=OpAndTo(src,$FF);
|
||||
src^.PrepType(ord(dtUInt32));
|
||||
|
||||
Op1(Op.OpConvertUToF,dtFloat32,dst,src);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP1.emit_V_CVT_F32_UBYTE2;
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:PsrRegNode;
|
||||
begin
|
||||
dst:=get_vdst8(FSPI.VOP1.VDST);
|
||||
src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtUInt32);
|
||||
|
||||
src:=OpShrTo(src,16);
|
||||
src:=OpAndTo(src,$FF);
|
||||
src^.PrepType(ord(dtUInt32));
|
||||
|
||||
Op1(Op.OpConvertUToF,dtFloat32,dst,src);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP1.emit_V_CVT_F32_UBYTE3;
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:PsrRegNode;
|
||||
begin
|
||||
dst:=get_vdst8(FSPI.VOP1.VDST);
|
||||
src:=fetch_ssrc9(FSPI.VOP1.SRC0,dtUInt32);
|
||||
|
||||
src:=OpShrTo(src,24);
|
||||
src:=OpAndTo(src,$FF);
|
||||
src^.PrepType(ord(dtUInt32));
|
||||
|
||||
Op1(Op.OpConvertUToF,dtFloat32,dst,src);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP1.emit_V_EXT_F32(OpId:DWORD);
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
|
@ -254,7 +302,9 @@ begin
|
|||
V_CVT_RPI_I32_F32: emit_V_CVT_RPI_I32_F32;
|
||||
|
||||
V_CVT_F32_UBYTE0: emit_V_CVT_F32_UBYTE0;
|
||||
|
||||
V_CVT_F32_UBYTE1: emit_V_CVT_F32_UBYTE1;
|
||||
V_CVT_F32_UBYTE2: emit_V_CVT_F32_UBYTE2;
|
||||
V_CVT_F32_UBYTE3: emit_V_CVT_F32_UBYTE3;
|
||||
|
||||
V_FRACT_F32: emit_V_EXT_F32(GlslOp.Fract);
|
||||
V_TRUNC_F32: emit_V_EXT_F32(GlslOp.Trunc);
|
||||
|
@ -274,6 +324,7 @@ begin
|
|||
V_COS_F32 : emit_V_SIN_COS(GlslOp.Cos);
|
||||
|
||||
V_RCP_F32 : emit_V_RCP_F32;
|
||||
V_RCP_IFLAG_F32: emit_V_RCP_F32;
|
||||
|
||||
V_FFBL_B32 : emit_V_FFBL_B32;
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@ type
|
|||
procedure emit_V_AND_B32;
|
||||
procedure emit_V_OR_B32;
|
||||
procedure emit_V_XOR_B32;
|
||||
procedure emit_V_SH(OpId:DWORD;rtype:TsrDataType);
|
||||
procedure emit_V_SHREV(OpId:DWORD;rtype:TsrDataType);
|
||||
procedure emit_V_SH_NRM(OpId:DWORD;rtype:TsrDataType);
|
||||
procedure emit_V_SH_REV(OpId:DWORD;rtype:TsrDataType);
|
||||
procedure emit_V_ADD_I32;
|
||||
procedure emit_V_SUB_I32;
|
||||
procedure emit_V_SUBREV_I32;
|
||||
|
@ -39,6 +39,8 @@ type
|
|||
procedure emit_V_MMX(OpId:DWORD;rtype:TsrDataType);
|
||||
procedure emit_V_LDEXP_F32;
|
||||
procedure emit_V_ADDC_U32;
|
||||
procedure emit_V_MBCNT_LO_U32_B32;
|
||||
procedure emit_V_MBCNT_HI_U32_B32;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
@ -117,7 +119,7 @@ begin
|
|||
OpBitwiseXor(dst,src[0],src[1]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP2.emit_V_SH(OpId:DWORD;rtype:TsrDataType);
|
||||
procedure TEmit_VOP2.emit_V_SH_NRM(OpId:DWORD;rtype:TsrDataType);
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..1] of PsrRegNode;
|
||||
|
@ -125,7 +127,7 @@ begin
|
|||
dst:=get_vdst8(FSPI.VOP2.VDST);
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,rtype);
|
||||
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUint32);
|
||||
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUInt32);
|
||||
|
||||
src[1]:=OpAndTo(src[1],31);
|
||||
src[1]^.PrepType(ord(dtUInt32));
|
||||
|
@ -133,14 +135,14 @@ begin
|
|||
Op2(OpId,src[0]^.dtype,dst,src[0],src[1]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP2.emit_V_SHREV(OpId:DWORD;rtype:TsrDataType);
|
||||
procedure TEmit_VOP2.emit_V_SH_REV(OpId:DWORD;rtype:TsrDataType);
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..1] of PsrRegNode;
|
||||
begin
|
||||
dst:=get_vdst8(FSPI.VOP2.VDST);
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUint32);
|
||||
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUInt32);
|
||||
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,rtype);
|
||||
|
||||
src[0]:=OpAndTo(src[0],31);
|
||||
|
@ -158,7 +160,7 @@ begin
|
|||
dst:=get_vdst8(FSPI.VOP2.VDST);
|
||||
car:=get_vcc0;
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUint32);
|
||||
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUInt32);
|
||||
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUint32);
|
||||
|
||||
OpIAddExt(dst,car,src[0],src[1]);
|
||||
|
@ -457,6 +459,46 @@ begin
|
|||
OpBitwiseAnd(car,src[0],exc); //carry_out & EXEC
|
||||
end;
|
||||
|
||||
//V_MBCNT_LO_U32_B32 v1, -1, v1
|
||||
|
||||
procedure TEmit_VOP2.emit_V_MBCNT_LO_U32_B32;
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..2] of PsrRegNode;
|
||||
begin
|
||||
//V_MBCNT_LO_U32_B32 vdst, vsrc, vaccum
|
||||
//mask_lo_threads_before= (thread_id>32) ? 0xffffffff : (1<<thread_id)-1
|
||||
//vdst = vaccum.u + bit_count(vsrc & mask_lo_threads_before)
|
||||
|
||||
dst:=get_vdst8(FSPI.VOP2.VDST);
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUint32);
|
||||
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUint32);
|
||||
|
||||
src[0]:=OpAndTo(src[0],1); //mean mask_lo_threads_before=1
|
||||
src[0]:=OpBitCountTo(src[0]);
|
||||
|
||||
OpIAdd(dst,src[0],src[1]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP2.emit_V_MBCNT_HI_U32_B32;
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..2] of PsrRegNode;
|
||||
begin
|
||||
//V_MBCNT_HI_U32_B3 vdst, vsrc, vaccum
|
||||
//mask_hi_threads_before= (thread_id>32) ? (1<<(thread_id-32))-1 : 0
|
||||
//vdst = vaccum.u + bit_count(vsrc & mask_hi_threads_before)
|
||||
|
||||
dst:=get_vdst8(FSPI.VOP2.VDST);
|
||||
|
||||
//src[0]:=fetch_ssrc9(FSPI.VOP2.SRC0 ,dtUint32);
|
||||
src[1]:=fetch_vsrc8(FSPI.VOP2.VSRC1,dtUint32);
|
||||
|
||||
//only lower thread_id mean
|
||||
MakeCopy(dst,src[1]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP2.emit_VOP2;
|
||||
begin
|
||||
|
||||
|
@ -468,12 +510,12 @@ begin
|
|||
V_OR_B32 : emit_V_OR_B32;
|
||||
V_XOR_B32 : emit_V_XOR_B32;
|
||||
|
||||
V_LSHL_B32 : emit_V_SH(Op.OpShiftLeftLogical,dtUint32);
|
||||
V_LSHLREV_B32: emit_V_SHREV(Op.OpShiftLeftLogical,dtUint32);
|
||||
V_LSHR_B32 : emit_V_SH(Op.OpShiftRightLogical,dtUint32);
|
||||
V_LSHRREV_B32: emit_V_SHREV(Op.OpShiftRightLogical,dtUint32);
|
||||
V_ASHR_I32 : emit_V_SH(Op.OpShiftRightLogical,dtInt32);
|
||||
V_ASHRREV_I32: emit_V_SHREV(Op.OpShiftRightLogical,dtInt32);
|
||||
V_LSHL_B32 : emit_V_SH_NRM(Op.OpShiftLeftLogical ,dtUint32);
|
||||
V_LSHLREV_B32: emit_V_SH_REV(Op.OpShiftLeftLogical ,dtUint32);
|
||||
V_LSHR_B32 : emit_V_SH_NRM(Op.OpShiftRightLogical ,dtUint32);
|
||||
V_LSHRREV_B32: emit_V_SH_REV(Op.OpShiftRightLogical ,dtUint32);
|
||||
V_ASHR_I32 : emit_V_SH_NRM(Op.OpShiftRightArithmetic,dtInt32);
|
||||
V_ASHRREV_I32: emit_V_SH_REV(Op.OpShiftRightArithmetic,dtInt32);
|
||||
|
||||
V_ADD_I32 : emit_V_ADD_I32;
|
||||
V_SUB_I32 : emit_V_SUB_I32;
|
||||
|
@ -515,6 +557,9 @@ begin
|
|||
|
||||
V_ADDC_U32: emit_V_ADDC_U32;
|
||||
|
||||
V_MBCNT_LO_U32_B32: emit_V_MBCNT_LO_U32_B32;
|
||||
V_MBCNT_HI_U32_B32: emit_V_MBCNT_HI_U32_B32;
|
||||
|
||||
else
|
||||
Assert(false,'VOP2?'+IntToStr(FSPI.VOP2.OP));
|
||||
end;
|
||||
|
|
|
@ -29,20 +29,27 @@ type
|
|||
function get_legacy_cmp(src0,src1,zero:PsrRegNode):PsrRegNode;
|
||||
|
||||
procedure emit_V_ADDC_U32;
|
||||
procedure emit_V_SUBB_U32;
|
||||
|
||||
procedure emit_V_CNDMASK_B32;
|
||||
procedure emit_V_MUL_LEGACY_F32;
|
||||
procedure emit_V2_F32(OpId:DWORD);
|
||||
procedure emit_V_SUBREV_F32;
|
||||
procedure emit_V2_REV_F32(OpId:DWORD);
|
||||
procedure emit_V_CVT_PKRTZ_F16_F32;
|
||||
procedure emit_V_MMX_F32(OpId:DWORD);
|
||||
procedure emit_V_SH_NRM(OpId:DWORD;rtype:TsrDataType);
|
||||
procedure emit_V_SH_REV(OpId:DWORD;rtype:TsrDataType);
|
||||
procedure emit_V_MUL_LO(rtype:TsrDataType);
|
||||
procedure emit_V_MUL_I32_I24;
|
||||
procedure emit_V_MUL_U32_U24;
|
||||
procedure emit_V_MUL_HI(rtype:TsrDataType);
|
||||
procedure emit_V_MAC_F32;
|
||||
procedure emit_V_LDEXP_F32;
|
||||
procedure emit_V_MBCNT_LO_U32_B32;
|
||||
procedure emit_V_MBCNT_HI_U32_B32;
|
||||
|
||||
procedure emit_V_BFE_U32;
|
||||
procedure emit_V_BFE_I32;
|
||||
procedure emit_V_BFI_B32;
|
||||
procedure emit_V_MAD_F32;
|
||||
procedure emit_V_MAD_LEGACY_F32;
|
||||
|
@ -52,6 +59,8 @@ type
|
|||
procedure emit_V_MAX3_F32;
|
||||
procedure emit_V_MIN3_F32;
|
||||
procedure emit_V_MED3_F32;
|
||||
procedure emit_V_MED3_I32;
|
||||
procedure emit_V_MED3_U32;
|
||||
procedure emit_V_FMA_F32;
|
||||
procedure emit_V_CUBE(OpId:DWORD);
|
||||
procedure emit_V_MOV_B32;
|
||||
|
@ -228,6 +237,35 @@ begin
|
|||
OpSelect(dst,src[0],src[1],src[2]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_MUL_LEGACY_F32;
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..1] of PsrRegNode;
|
||||
zero:PsrRegNode;
|
||||
cmp:PsrRegNode;
|
||||
mul:PsrRegNode;
|
||||
begin
|
||||
dst:=get_vdst8(FSPI.VOP3a.VDST);
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtFloat32);
|
||||
src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtFloat32);
|
||||
|
||||
emit_src_abs_bit(@src,2);
|
||||
emit_src_neg_bit(@src,2);
|
||||
|
||||
zero:=NewReg_s(dtFloat32,0);
|
||||
cmp:=get_legacy_cmp(src[0],src[1],zero);
|
||||
|
||||
//
|
||||
mul:=NewReg(dtFloat32);
|
||||
_Op2(line,Op.OpFMul,mul,src[0],src[1]);
|
||||
|
||||
OpSelect(dst,mul,zero,cmp); //false,true,cond
|
||||
|
||||
emit_dst_omod_f(dst);
|
||||
emit_dst_clamp_f(dst);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V2_F32(OpId:DWORD);
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
|
@ -247,7 +285,7 @@ begin
|
|||
emit_dst_clamp_f(dst);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_SUBREV_F32;
|
||||
procedure TEmit_VOP3.emit_V2_REV_F32(OpId:DWORD);
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..1] of PsrRegNode;
|
||||
|
@ -260,7 +298,7 @@ begin
|
|||
emit_src_abs_bit(@src,2);
|
||||
emit_src_neg_bit(@src,2);
|
||||
|
||||
Op2(Op.OpFSub,dtFloat32,dst,src[1],src[0]);
|
||||
Op2(OpId,dtFloat32,dst,src[1],src[0]);
|
||||
|
||||
emit_dst_omod_f(dst);
|
||||
emit_dst_clamp_f(dst);
|
||||
|
@ -304,6 +342,48 @@ begin
|
|||
emit_dst_clamp_f(dst);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_SH_NRM(OpId:DWORD;rtype:TsrDataType);
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..1] of PsrRegNode;
|
||||
begin
|
||||
dst:=get_vdst8(FSPI.VOP3a.VDST);
|
||||
|
||||
Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD');
|
||||
Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS');
|
||||
Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP');
|
||||
Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG');
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,rtype);
|
||||
src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUInt32);
|
||||
|
||||
src[1]:=OpAndTo(src[1],31);
|
||||
src[1]^.PrepType(ord(dtUInt32));
|
||||
|
||||
Op2(OpId,src[0]^.dtype,dst,src[0],src[1]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_SH_REV(OpId:DWORD;rtype:TsrDataType);
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..1] of PsrRegNode;
|
||||
begin
|
||||
dst:=get_vdst8(FSPI.VOP3a.VDST);
|
||||
|
||||
Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD');
|
||||
Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS');
|
||||
Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP');
|
||||
Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG');
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtUInt32);
|
||||
src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,rtype);
|
||||
|
||||
src[0]:=OpAndTo(src[0],31);
|
||||
src[0]^.PrepType(ord(dtUInt32));
|
||||
|
||||
Op2(OpId,src[1]^.dtype,dst,src[1],src[0]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_MUL_LO(rtype:TsrDataType);
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
|
@ -456,6 +536,54 @@ begin
|
|||
emit_dst_clamp_f(dst);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_MBCNT_LO_U32_B32;
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..1] of PsrRegNode;
|
||||
begin
|
||||
//V_MBCNT_LO_U32_B32 vdst, vsrc, vaccum
|
||||
//mask_lo_threads_before= (thread_id>32) ? 0xffffffff : (1<<thread_id)-1
|
||||
//vdst = vaccum.u + bit_count(vsrc & mask_lo_threads_before)
|
||||
|
||||
dst:=get_vdst8(FSPI.VOP3a.VDST);
|
||||
|
||||
Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD');
|
||||
Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS');
|
||||
Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP');
|
||||
Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG');
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtUint32);
|
||||
src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUint32);
|
||||
|
||||
src[0]:=OpAndTo(src[0],1); //mean mask_lo_threads_before=1
|
||||
src[0]:=OpBitCountTo(src[0]);
|
||||
|
||||
OpIAdd(dst,src[0],src[1]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_MBCNT_HI_U32_B32;
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..1] of PsrRegNode;
|
||||
begin
|
||||
//V_MBCNT_HI_U32_B3 vdst, vsrc, vaccum
|
||||
//mask_hi_threads_before= (thread_id>32) ? (1<<(thread_id-32))-1 : 0
|
||||
//vdst = vaccum.u + bit_count(vsrc & mask_hi_threads_before)
|
||||
|
||||
dst:=get_vdst8(FSPI.VOP3a.VDST);
|
||||
|
||||
Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD');
|
||||
Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS');
|
||||
Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP');
|
||||
Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG');
|
||||
|
||||
//src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtUint32);
|
||||
src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUint32);
|
||||
|
||||
//only lower thread_id mean
|
||||
MakeCopy(dst,src[1]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_BFE_U32;
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
|
@ -472,7 +600,26 @@ begin
|
|||
src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUint32);
|
||||
src[2]:=fetch_ssrc9(FSPI.VOP3a.SRC2,dtUint32);
|
||||
|
||||
OpBFEU32(dst,src[0],src[1],src[2]);
|
||||
OpBFE_32(dst,src[0],src[1],src[2]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_BFE_I32;
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..2] of PsrRegNode;
|
||||
begin
|
||||
dst:=get_vdst8(FSPI.VOP3a.VDST);
|
||||
|
||||
Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD');
|
||||
Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS');
|
||||
Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP');
|
||||
Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG');
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtInt32);
|
||||
src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUint32);
|
||||
src[2]:=fetch_ssrc9(FSPI.VOP3a.SRC2,dtUint32);
|
||||
|
||||
OpBFE_32(dst,src[0],src[1],src[2]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_BFI_B32;
|
||||
|
@ -693,6 +840,44 @@ begin
|
|||
emit_dst_clamp_f(dst);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_MED3_I32;
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..2] of PsrRegNode;
|
||||
begin
|
||||
dst:=get_vdst8(FSPI.VOP3a.VDST);
|
||||
|
||||
Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD');
|
||||
Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS');
|
||||
Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP');
|
||||
Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG');
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtInt32);
|
||||
src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtInt32);
|
||||
src[2]:=fetch_ssrc9(FSPI.VOP3a.SRC2,dtInt32);
|
||||
|
||||
OpMED3I(dst,src[0],src[1],src[2]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_MED3_U32;
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
src:array[0..2] of PsrRegNode;
|
||||
begin
|
||||
dst:=get_vdst8(FSPI.VOP3a.VDST);
|
||||
|
||||
Assert(FSPI.VOP3a.OMOD =0,'FSPI.VOP3a.OMOD');
|
||||
Assert(FSPI.VOP3a.ABS =0,'FSPI.VOP3a.ABS');
|
||||
Assert(FSPI.VOP3a.CLAMP=0,'FSPI.VOP3a.CLAMP');
|
||||
Assert(FSPI.VOP3a.NEG =0,'FSPI.VOP3a.NEG');
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.VOP3a.SRC0,dtUint32);
|
||||
src[1]:=fetch_ssrc9(FSPI.VOP3a.SRC1,dtUint32);
|
||||
src[2]:=fetch_ssrc9(FSPI.VOP3a.SRC2,dtUint32);
|
||||
|
||||
OpMED3U(dst,src[0],src[1],src[2]);
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_FMA_F32;
|
||||
Var
|
||||
dst:PsrRegSlot;
|
||||
|
@ -1023,10 +1208,48 @@ begin
|
|||
OpBitwiseAnd(car,src[0],exc); //carry_out & EXEC
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_V_SUBB_U32;
|
||||
Var
|
||||
dst,bor:PsrRegSlot;
|
||||
src:array[0..2] of PsrRegNode;
|
||||
exc:PsrRegNode;
|
||||
begin
|
||||
dst:=get_vdst8(FSPI.VOP3b.VDST);
|
||||
bor:=get_sdst7(FSPI.VOP3b.SDST);
|
||||
|
||||
Assert(FSPI.VOP3b.OMOD=0,'FSPI.VOP3b.OMOD');
|
||||
Assert(FSPI.VOP3b.NEG =0,'FSPI.VOP3b.NEG');
|
||||
|
||||
src[0]:=fetch_ssrc9(FSPI.VOP3b.SRC0,dtUInt32);
|
||||
src[1]:=fetch_ssrc9(FSPI.VOP3b.SRC1,dtUInt32);
|
||||
src[2]:=fetch_ssrc9(FSPI.VOP3b.SRC2,dtUInt32);
|
||||
|
||||
src[2]:=OpAndTo(src[2],1);
|
||||
src[2]^.PrepType(ord(dtUInt32));
|
||||
|
||||
OpISubExt(dst,bor,src[0],src[1]); //src0-src1
|
||||
|
||||
src[0]:=MakeRead(dst,dtUInt32);
|
||||
src[1]:=MakeRead(bor,dtUInt32); //save car1
|
||||
|
||||
OpISubExt(dst,bor,src[0],src[2]); //(src0-src1)-src2
|
||||
|
||||
src[0]:=MakeRead(bor,dtUInt32);
|
||||
|
||||
//Or??? And???
|
||||
OpBitwiseOr(bor,src[1],src[0]); //car1 or car2
|
||||
|
||||
src[0]:=MakeRead(bor,dtUInt32);
|
||||
|
||||
exc:=MakeRead(get_exec0,dtUnknow);
|
||||
OpBitwiseAnd(bor,src[0],exc); //borrow_out & EXEC
|
||||
end;
|
||||
|
||||
procedure TEmit_VOP3.emit_VOP3b;
|
||||
begin
|
||||
Case FSPI.VOP3b.OP of
|
||||
256+V_ADDC_U32: emit_V_ADDC_U32;
|
||||
256+V_SUBB_U32: emit_V_SUBB_U32;
|
||||
|
||||
else
|
||||
Assert(false,'VOP3b?'+IntToStr(FSPI.VOP3b.OP));
|
||||
|
@ -1041,9 +1264,16 @@ begin
|
|||
|
||||
256+V_CNDMASK_B32: emit_V_CNDMASK_B32;
|
||||
|
||||
256+V_ADD_F32: emit_V2_F32(Op.OpFAdd);
|
||||
256+V_SUB_F32: emit_V2_F32(Op.OpFSub);
|
||||
256+V_SUBREV_F32: emit_V_SUBREV_F32;
|
||||
256+V_ADD_F32 : emit_V2_F32(Op.OpFAdd);
|
||||
256+V_SUB_F32 : emit_V2_F32(Op.OpFSub);
|
||||
256+V_SUBREV_F32 : emit_V2_REV_F32(Op.OpFSub);
|
||||
|
||||
256+V_LSHL_B32 : emit_V_SH_NRM(Op.OpShiftLeftLogical ,dtUint32);
|
||||
256+V_LSHLREV_B32: emit_V_SH_REV(Op.OpShiftLeftLogical ,dtUint32);
|
||||
256+V_LSHR_B32 : emit_V_SH_NRM(Op.OpShiftRightLogical ,dtUint32);
|
||||
256+V_LSHRREV_B32: emit_V_SH_REV(Op.OpShiftRightLogical ,dtUint32);
|
||||
256+V_ASHR_I32 : emit_V_SH_NRM(Op.OpShiftRightArithmetic,dtInt32);
|
||||
256+V_ASHRREV_I32: emit_V_SH_REV(Op.OpShiftRightArithmetic,dtInt32);
|
||||
|
||||
256+V_CVT_PKRTZ_F16_F32: emit_V_CVT_PKRTZ_F16_F32;
|
||||
|
||||
|
@ -1053,6 +1283,8 @@ begin
|
|||
256+V_MIN_F32:emit_V_MMX_F32(GlslOp.FMin);
|
||||
256+V_MAX_F32:emit_V_MMX_F32(GlslOp.FMax);
|
||||
|
||||
256+V_MUL_LEGACY_F32: emit_V_MUL_LEGACY_F32;
|
||||
|
||||
256+V_MUL_F32: emit_V2_F32(Op.OpFMul);
|
||||
|
||||
256+V_MUL_I32_I24: emit_V_MUL_I32_I24;
|
||||
|
@ -1062,6 +1294,9 @@ begin
|
|||
|
||||
256+V_LDEXP_F32: emit_V_LDEXP_F32;
|
||||
|
||||
256+V_MBCNT_LO_U32_B32: emit_V_MBCNT_LO_U32_B32;
|
||||
256+V_MBCNT_HI_U32_B32: emit_V_MBCNT_HI_U32_B32;
|
||||
|
||||
//VOP3 only
|
||||
|
||||
V_MUL_LO_U32: emit_V_MUL_LO(dtUint32);
|
||||
|
@ -1071,7 +1306,9 @@ begin
|
|||
V_MUL_HI_I32: emit_V_MUL_HI(dtInt32);
|
||||
|
||||
V_BFE_U32: emit_V_BFE_U32;
|
||||
V_BFE_I32: emit_V_BFE_I32;
|
||||
V_BFI_B32: emit_V_BFI_B32;
|
||||
|
||||
V_MAD_F32: emit_V_MAD_F32;
|
||||
V_MAD_LEGACY_F32: emit_V_MAD_LEGACY_F32;
|
||||
|
||||
|
@ -1082,6 +1319,8 @@ begin
|
|||
V_MAX3_F32: emit_V_MAX3_F32;
|
||||
V_MIN3_F32: emit_V_MIN3_F32;
|
||||
V_MED3_F32: emit_V_MED3_F32;
|
||||
V_MED3_I32: emit_V_MED3_I32;
|
||||
V_MED3_U32: emit_V_MED3_U32;
|
||||
V_FMA_F32 : emit_V_FMA_F32;
|
||||
|
||||
V_CUBEID_F32:emit_V_CUBE(OpCUBEID);
|
||||
|
@ -1117,6 +1356,7 @@ begin
|
|||
384+V_COS_F32 : emit_V_SIN_COS(GlslOp.Cos);
|
||||
|
||||
384+V_RCP_F32 : emit_V_RCP_F32;
|
||||
384+V_RCP_IFLAG_F32: emit_V_RCP_F32;
|
||||
|
||||
else
|
||||
Assert(false,'VOP3a?'+IntToStr(FSPI.VOP3a.OP));
|
||||
|
|
|
@ -40,9 +40,12 @@ type
|
|||
function Next(node:PNode):PNode;
|
||||
function Prev(node:PNode):PNode;
|
||||
function Find(node:PNode):PNode;
|
||||
function Find_b(node:PNode):PNode;
|
||||
function Find_be(node:PNode):PNode;
|
||||
function Find_l(node:PNode):PNode;
|
||||
function Find_le(node:PNode):PNode;
|
||||
procedure Insert(new:PNode);
|
||||
function Insert(node:PNode):Boolean;
|
||||
function Delete(node:PNode):Boolean;
|
||||
end;
|
||||
|
||||
function ComparePChar(buf1,buf2:PChar):Integer;
|
||||
|
@ -51,54 +54,93 @@ function ComparePtruint(buf1,buf2:PPtruint;count:PtrUint):Integer;
|
|||
implementation
|
||||
|
||||
function TNodeFetch._Splay(node:PNode):Integer;
|
||||
label
|
||||
_left,
|
||||
_right;
|
||||
var
|
||||
aux:TNode;
|
||||
t,l,r,y:PNode;
|
||||
llist,rlist:PNode;
|
||||
ltree,rtree:PNode;
|
||||
y :PNode;
|
||||
begin
|
||||
t:=pRoot;
|
||||
l:=@aux;
|
||||
r:=@aux;
|
||||
aux.pLeft:=nil;
|
||||
aux.pRight:=nil;
|
||||
while (true) do
|
||||
begin
|
||||
Result:=TNode.c(t,node);
|
||||
if (Result=0) then Break;
|
||||
if (pRoot=nil) then Exit(0);
|
||||
|
||||
llist:=nil;
|
||||
rlist:=nil;
|
||||
repeat
|
||||
Result:=TNode.c(node,pRoot);
|
||||
|
||||
if (Result<0) then
|
||||
begin
|
||||
y:=pRoot^.pLeft;
|
||||
if (y=nil) then break;
|
||||
if (y^.pLeft=nil) then
|
||||
begin
|
||||
_left:
|
||||
pRoot^.pLeft:=rlist;
|
||||
rlist:=pRoot;
|
||||
pRoot:=y;
|
||||
end else
|
||||
if (TNode.c(node,y)<0) then
|
||||
begin
|
||||
pRoot^.pLeft:=y^.pRight;
|
||||
y^.pRight:=pRoot;
|
||||
pRoot:=y^.pLeft;
|
||||
y^.pLeft:=rlist;
|
||||
rlist:=y;
|
||||
end else
|
||||
begin
|
||||
goto _left;
|
||||
end;
|
||||
end else
|
||||
if (Result>0) then
|
||||
begin
|
||||
if (t^.pLeft=nil) then break;
|
||||
if (TNode.c(node,t^.pLeft)<0) then
|
||||
y:=pRoot^.pRight;
|
||||
if (y=nil) then break;
|
||||
if (y^.pRight=nil) then
|
||||
begin
|
||||
y:=t^.pLeft; // rotate pRight
|
||||
t^.pLeft:=y^.pRight;
|
||||
y^.pRight:=t;
|
||||
t:=y;
|
||||
if (t^.pLeft=nil) then break;
|
||||
_right:
|
||||
pRoot^.pRight:=llist;
|
||||
llist:=pRoot;
|
||||
pRoot:=y;
|
||||
end else
|
||||
if (TNode.c(node,y)>0) then
|
||||
begin
|
||||
pRoot^.pRight:=y^.pLeft;
|
||||
y^.pLeft:=pRoot;
|
||||
pRoot:=y^.pRight;
|
||||
y^.pRight:=llist;
|
||||
llist:=y;
|
||||
end else
|
||||
begin
|
||||
goto _right;
|
||||
end;
|
||||
r^.pLeft:=t; // link pRight
|
||||
r:=t;
|
||||
t:=t^.pLeft;
|
||||
end else
|
||||
begin
|
||||
if (t^.pRight=nil) then break;
|
||||
if (TNode.c(node,t^.pRight)>0) then
|
||||
begin
|
||||
y:=t^.pRight; // rotate pLeft
|
||||
t^.pRight:=y^.pLeft;
|
||||
y^.pLeft:=t;
|
||||
t:=y;
|
||||
if (t^.pRight=nil) then break;
|
||||
end;
|
||||
l^.pRight:=t; // link pLeft
|
||||
l:=t;
|
||||
t:=t^.pRight;
|
||||
Break;
|
||||
end;
|
||||
until false;
|
||||
|
||||
ltree:=pRoot^.pLeft;
|
||||
while (llist<>nil) do
|
||||
begin
|
||||
y:=llist^.pRight;
|
||||
llist^.pRight:=ltree;
|
||||
ltree:=llist;
|
||||
llist:=y;
|
||||
end;
|
||||
l^.pRight:=t^.pLeft; // assemble
|
||||
r^.pLeft :=t^.pRight;
|
||||
t^.pLeft :=aux.pRight;
|
||||
t^.pRight:=aux.pLeft;
|
||||
pRoot:=t;
|
||||
|
||||
rtree:=pRoot^.pRight;
|
||||
while (rlist<>nil) do
|
||||
begin
|
||||
y:=rlist^.pLeft;
|
||||
rlist^.pLeft:=rtree;
|
||||
rtree:=rlist;
|
||||
rlist:=y;
|
||||
end;
|
||||
|
||||
pRoot^.pLeft :=ltree;
|
||||
pRoot^.pRight:=rtree;
|
||||
Result:=TNode.c(node,pRoot);
|
||||
end;
|
||||
|
||||
function TNodeFetch.Min:PNode;
|
||||
|
@ -128,29 +170,79 @@ begin
|
|||
end;
|
||||
|
||||
function TNodeFetch.Next(node:PNode):PNode;
|
||||
var
|
||||
y,r:PNode;
|
||||
c:Integer;
|
||||
begin
|
||||
Result:=nil;
|
||||
if (pRoot=nil) or (node=nil) then Exit;
|
||||
_Splay(node);
|
||||
node:=node^.pRight;
|
||||
While (node<>nil) do
|
||||
|
||||
r:=pRoot;
|
||||
y:=nil;
|
||||
|
||||
if (node^.pRight<>nil) then
|
||||
begin
|
||||
Result:=node;
|
||||
node:=node^.pLeft;
|
||||
y:=node^.pRight;
|
||||
while (y^.pLeft<>nil) do y:=y^.pLeft;
|
||||
Exit(y);
|
||||
end;
|
||||
|
||||
while (r<>nil) do
|
||||
begin
|
||||
c:=TNode.c(node,r);
|
||||
if (c=0) then
|
||||
begin
|
||||
Break;
|
||||
end else
|
||||
if (c<0) then
|
||||
begin
|
||||
y:=r;
|
||||
r:=r^.pLeft;
|
||||
end else
|
||||
begin
|
||||
r:=r^.pRight;
|
||||
end;
|
||||
end;
|
||||
|
||||
Exit(y);
|
||||
end;
|
||||
|
||||
function TNodeFetch.Prev(node:PNode):PNode;
|
||||
var
|
||||
y,r:PNode;
|
||||
c:Integer;
|
||||
begin
|
||||
Result:=nil;
|
||||
if (pRoot=nil) or (node=nil) then Exit;
|
||||
_Splay(node);
|
||||
node:=node^.pLeft;
|
||||
While (node<>nil) do
|
||||
|
||||
r:=pRoot;
|
||||
y:=nil;
|
||||
|
||||
if (node^.pLeft<>nil) then
|
||||
begin
|
||||
Result:=node;
|
||||
node:=node^.pRight;
|
||||
y:=node^.pLeft;
|
||||
while (y^.pRight<>nil) do y:=y^.pRight;
|
||||
Exit(y);
|
||||
end;
|
||||
|
||||
while (r<>nil) do
|
||||
begin
|
||||
c:=TNode.c(node,r);
|
||||
if (c=0) then
|
||||
begin
|
||||
break;
|
||||
end else
|
||||
if (c>0) then
|
||||
begin
|
||||
y:=r;
|
||||
r:=r^.pRight;
|
||||
end else
|
||||
begin
|
||||
r:=r^.pLeft;
|
||||
end;
|
||||
end;
|
||||
|
||||
Exit(y);
|
||||
end;
|
||||
|
||||
function TNodeFetch.Find(node:PNode):PNode;
|
||||
|
@ -160,59 +252,159 @@ begin
|
|||
if (_Splay(node)=0) then Result:=pRoot;
|
||||
end;
|
||||
|
||||
function TNodeFetch.Find_be(node:PNode):PNode;
|
||||
function TNodeFetch.Find_b(node:PNode):PNode;
|
||||
var
|
||||
c:Integer;
|
||||
begin
|
||||
Result:=nil;
|
||||
if (pRoot=nil) or (node=nil) then Exit;
|
||||
if (_Splay(node)<0) then
|
||||
c:=_Splay(node);
|
||||
if (c=0) then
|
||||
begin
|
||||
//=
|
||||
Result:=Next(pRoot);
|
||||
end else
|
||||
if (c<0) then
|
||||
begin
|
||||
//<
|
||||
Result:=pRoot;
|
||||
end else
|
||||
begin
|
||||
//>
|
||||
Result:=Next(pRoot);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TNodeFetch.Find_be(node:PNode):PNode;
|
||||
var
|
||||
c:Integer;
|
||||
begin
|
||||
Result:=nil;
|
||||
if (pRoot=nil) or (node=nil) then Exit;
|
||||
c:=_Splay(node);
|
||||
if (c=0) then
|
||||
begin
|
||||
//=
|
||||
Result:=pRoot;
|
||||
end else
|
||||
if (c<0) then
|
||||
begin
|
||||
//<
|
||||
Result:=pRoot;
|
||||
end else
|
||||
begin
|
||||
//>
|
||||
Result:=Next(pRoot);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TNodeFetch.Find_l(node:PNode):PNode;
|
||||
var
|
||||
c:Integer;
|
||||
begin
|
||||
Result:=nil;
|
||||
if (pRoot=nil) or (node=nil) then Exit;
|
||||
c:=_Splay(node);
|
||||
if (c=0) then
|
||||
begin
|
||||
//=
|
||||
Result:=Prev(pRoot);
|
||||
end else
|
||||
if (c<0) then
|
||||
begin
|
||||
//<
|
||||
Result:=Prev(pRoot);
|
||||
end else
|
||||
begin
|
||||
//>
|
||||
Result:=pRoot;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TNodeFetch.Find_le(node:PNode):PNode;
|
||||
var
|
||||
c:Integer;
|
||||
begin
|
||||
Result:=nil;
|
||||
if (pRoot=nil) or (node=nil) then Exit;
|
||||
if (_Splay(node)>0) then
|
||||
c:=_Splay(node);
|
||||
if (c=0) then
|
||||
begin
|
||||
//=
|
||||
Result:=pRoot;
|
||||
end else
|
||||
if (c<0) then
|
||||
begin
|
||||
//<
|
||||
Result:=Prev(pRoot);
|
||||
end else
|
||||
begin
|
||||
//>
|
||||
Result:=pRoot;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TNodeFetch.Insert(new:PNode);
|
||||
function TNodeFetch.Insert(node:PNode):Boolean;
|
||||
var
|
||||
c:Integer;
|
||||
begin
|
||||
if (new=nil) then Exit;
|
||||
Result:=False;
|
||||
if (node=nil) then Exit;
|
||||
if (pRoot=nil) then
|
||||
begin
|
||||
pRoot:=new;
|
||||
pRoot:=node;
|
||||
end else
|
||||
begin
|
||||
c:=TNode.c(pRoot,new);
|
||||
if (c<>0) then
|
||||
c:=_Splay(node);
|
||||
if (c=0) then Exit;
|
||||
if (c>0) then
|
||||
begin
|
||||
if (c<0) then
|
||||
begin
|
||||
new^.pRight:=pRoot^.pRight;
|
||||
new^.pLeft :=pRoot;
|
||||
pRoot^.pRight:=nil;
|
||||
end else
|
||||
begin
|
||||
new^.pLeft :=pRoot^.pLeft;
|
||||
new^.pRight:=pRoot;
|
||||
pRoot^.pLeft:=nil;
|
||||
end;
|
||||
pRoot:=new;
|
||||
node^.pRight:=pRoot^.pRight;
|
||||
node^.pLeft :=pRoot;
|
||||
pRoot^.pRight:=nil;
|
||||
end else
|
||||
begin
|
||||
node^.pLeft :=pRoot^.pLeft;
|
||||
node^.pRight:=pRoot;
|
||||
pRoot^.pLeft:=nil;
|
||||
end;
|
||||
pRoot:=node;
|
||||
end;
|
||||
Result:=True;
|
||||
end;
|
||||
|
||||
function TNodeFetch.Delete(node:PNode):Boolean;
|
||||
var
|
||||
pLeft :PNode;
|
||||
pRight:PNode;
|
||||
pMax :PNode;
|
||||
begin
|
||||
Result:=False;
|
||||
|
||||
if (pRoot=nil) or (node=nil) then Exit;
|
||||
if (_Splay(node)<>0) then Exit;
|
||||
|
||||
pLeft :=pRoot^.pLeft;
|
||||
pRight:=pRoot^.pRight;
|
||||
|
||||
if (pLeft<>nil) then
|
||||
begin
|
||||
pMax:=pLeft;
|
||||
while (pMax^.pRight<>nil) do
|
||||
begin
|
||||
pMax:=pMax^.pRight;
|
||||
end;
|
||||
|
||||
pRoot:=pLeft;
|
||||
_Splay(pMax);
|
||||
|
||||
pRoot^.pRight:=pRight;
|
||||
end else
|
||||
begin
|
||||
pRoot:=pRight;
|
||||
end;
|
||||
|
||||
Result:=True;
|
||||
end;
|
||||
|
||||
//--
|
||||
|
|
|
@ -32,7 +32,9 @@ type
|
|||
FNTree:TNodeFetch;
|
||||
rSlot:TsrRegSlot;
|
||||
procedure Init(Emit:TCustomEmit); inline;
|
||||
function Find(dtype:TsrDataType;src:PsrRegNode):PsrBitcast;
|
||||
function _Find(dtype:TsrDataType;src:PsrRegNode):PsrBitcast;
|
||||
function Find(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
|
||||
Procedure Save(dtype:TsrDataType;src,dst:PsrRegNode);
|
||||
function FetchRead(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
|
||||
function FetchDstr(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
|
||||
function FetchCast(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
|
||||
|
@ -54,7 +56,7 @@ begin
|
|||
rSlot.Init(Emit,'BCAST');
|
||||
end;
|
||||
|
||||
function TsrBitcastList.Find(dtype:TsrDataType;src:PsrRegNode):PsrBitcast;
|
||||
function TsrBitcastList._Find(dtype:TsrDataType;src:PsrRegNode):PsrBitcast;
|
||||
var
|
||||
node:TsrBitcast;
|
||||
begin
|
||||
|
@ -64,16 +66,64 @@ begin
|
|||
Result:=FNTree.Find(@node);
|
||||
end;
|
||||
|
||||
function TsrBitcastList.Find(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
|
||||
var
|
||||
node:PsrBitcast;
|
||||
begin
|
||||
Result:=nil;
|
||||
node:=_Find(dtype,src);
|
||||
if (node<>nil) then
|
||||
begin
|
||||
Result:=node^.dst;
|
||||
end;
|
||||
end;
|
||||
|
||||
Procedure TsrBitcastList.Save(dtype:TsrDataType;src,dst:PsrRegNode);
|
||||
var
|
||||
node:PsrBitcast;
|
||||
begin
|
||||
node:=rSlot.Emit.Alloc(SizeOf(TsrBitcast));
|
||||
node^:=Default(TsrBitcast);
|
||||
node^.key.dtype:=dtype;
|
||||
node^.key.src:=src;
|
||||
node^.dst:=dst;
|
||||
FNTree.Insert(node);
|
||||
end;
|
||||
|
||||
function TsrBitcastList.FetchRead(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
|
||||
var
|
||||
pConstList:PsrConstList;
|
||||
dst:PsrRegNode;
|
||||
pConst:PsrConst;
|
||||
|
||||
begin
|
||||
Result:=src;
|
||||
if (src=nil) then Exit;
|
||||
if (dtype=dtUnknow) or (dtype=src^.dtype) then Exit;
|
||||
|
||||
dst:=rSlot.New(src^.pLine,dtype);
|
||||
dst^.pWriter:=src;
|
||||
Assert(TryBitcastType(src^.dtype,dtype));
|
||||
|
||||
if src^.is_const then
|
||||
begin
|
||||
//only from consts, first
|
||||
dst:=Find(dtype,src);
|
||||
if (dst<>nil) then Exit(dst);
|
||||
|
||||
pConst:=src^.AsConst;
|
||||
|
||||
pConstList:=rSlot.Emit.GetConstList;
|
||||
pConst:=pConstList^.Bitcast(dtype,pConst);
|
||||
|
||||
dst:=rSlot.New(src^.pLine,dtype);
|
||||
dst^.pWriter:=pConst;
|
||||
|
||||
//
|
||||
Save(dtype,src,dst);
|
||||
end else
|
||||
begin
|
||||
dst:=rSlot.New(src^.pLine,dtype);
|
||||
dst^.pWriter:=src;
|
||||
end;
|
||||
|
||||
Result:=dst;
|
||||
end;
|
||||
|
@ -86,6 +136,8 @@ begin
|
|||
if (src=nil) then Exit;
|
||||
if (dtype=dtUnknow) or (dtype=src^.dtype) then Exit;
|
||||
|
||||
Assert(TryBitcastType(src^.dtype,dtype));
|
||||
|
||||
dst:=rSlot.New(src^.pLine,dtype);
|
||||
dst^.pWriter:=src^.pWriter;
|
||||
|
||||
|
@ -97,7 +149,6 @@ end;
|
|||
function TsrBitcastList.FetchCast(dtype:TsrDataType;src:PsrRegNode):PsrRegNode;
|
||||
var
|
||||
pConstList:PsrConstList;
|
||||
node:PsrBitcast;
|
||||
dst:PsrRegNode;
|
||||
pConst:PsrConst;
|
||||
|
||||
|
@ -108,12 +159,11 @@ begin
|
|||
|
||||
dst:=nil;
|
||||
|
||||
node:=Find(dtype,src);
|
||||
if (node<>nil) then
|
||||
begin
|
||||
Result:=node^.dst;
|
||||
Exit;
|
||||
end;
|
||||
Assert(TryBitcastType(src^.dtype,dtype));
|
||||
|
||||
//
|
||||
dst:=Find(dtype,src);
|
||||
if (dst<>nil) then Exit(dst);
|
||||
|
||||
if src^.is_const then
|
||||
begin
|
||||
|
@ -133,16 +183,13 @@ begin
|
|||
rSlot.Emit.OpCast(src^.pLine,dst,src)
|
||||
end else
|
||||
begin
|
||||
Writeln('bitcast:',src^.dtype,'<>',dtype);
|
||||
Assert(false,'bitcast');
|
||||
end;
|
||||
end;
|
||||
|
||||
node:=rSlot.Emit.Alloc(SizeOf(TsrBitcast));
|
||||
node^:=Default(TsrBitcast);
|
||||
node^.key.dtype:=dtype;
|
||||
node^.key.src:=src;
|
||||
node^.dst:=dst;
|
||||
FNTree.Insert(node);
|
||||
//
|
||||
Save(dtype,src,dst);
|
||||
|
||||
Result:=dst;
|
||||
end;
|
||||
|
|
|
@ -15,9 +15,10 @@ uses
|
|||
type
|
||||
PsrCacheOp=^TsrCacheOp;
|
||||
TsrCacheOp=object
|
||||
private
|
||||
public
|
||||
pLeft,pRight:PsrCacheOp;
|
||||
//----
|
||||
function c(n1,n2:PsrCacheOp):Integer; static;
|
||||
private
|
||||
key:packed record
|
||||
place:PsrOpBlock;
|
||||
OpId:DWORD;
|
||||
|
@ -25,7 +26,6 @@ type
|
|||
count:DWORD;
|
||||
end;
|
||||
pData:PPsrRegNode;
|
||||
function c(n1,n2:PsrCacheOp):Integer; static;
|
||||
public
|
||||
pDst:PsrNode;
|
||||
end;
|
||||
|
|
|
@ -32,15 +32,15 @@ type
|
|||
PPsrConst=^PsrConst;
|
||||
PsrConst=^TsrConst;
|
||||
TsrConst=packed object(TsrNode)
|
||||
private
|
||||
public
|
||||
pPrev,pNext,pLeft,pRight:PsrConst;
|
||||
//--
|
||||
function c(n1,n2:PsrConst):Integer; static;
|
||||
private
|
||||
ID:TsrRefId; //post id
|
||||
fOpId:WORD;
|
||||
fCount:WORD;
|
||||
FType:PsrType;
|
||||
pData:PPsrNode;
|
||||
function c(n1,n2:PsrConst):Integer; static;
|
||||
public
|
||||
property pType:PsrType read FType;
|
||||
property OpId:WORD read fOpId;
|
||||
|
|
|
@ -19,24 +19,34 @@ type
|
|||
|
||||
PsrDecorate=^TsrDecorate;
|
||||
TsrDecorate=object
|
||||
private
|
||||
public
|
||||
pLeft,pRight:PsrDecorate;
|
||||
//----
|
||||
function c(n1,n2:PsrDecorate):Integer; static;
|
||||
private
|
||||
key:packed record
|
||||
data:PsrNode;
|
||||
param:array[0..2] of DWORD;
|
||||
end;
|
||||
function c(n1,n2:PsrDecorate):Integer; static;
|
||||
public
|
||||
node:PSpirvOp;
|
||||
end;
|
||||
|
||||
TfemOp=(
|
||||
foDepthReplacing,
|
||||
foDepthGreater,
|
||||
foDepthLess,
|
||||
foDepthUnchanged
|
||||
);
|
||||
|
||||
TfemOpSet=Set of TfemOp;
|
||||
|
||||
PsrDecorateList=^TsrDecorateList;
|
||||
TsrDecorateList=object(TsrOpBlockCustom)
|
||||
type
|
||||
TNodeFetch=specialize TNodeFetch<PsrDecorate,TsrDecorate>;
|
||||
var
|
||||
FNTree:TNodeFetch;
|
||||
FfemOpSet:TfemOpSet;
|
||||
function Fetch(data:PsrNode;param1,param2,param3:DWORD):PsrDecorate;
|
||||
procedure OpDecorate(Data:PsrNode;dec_id,param:DWORD);
|
||||
procedure OpMember (Data:PsrNode;index,offset:DWORD);
|
||||
|
|
|
@ -33,11 +33,11 @@ type
|
|||
|
||||
PsrFragLayout=^TsrFragLayout;
|
||||
TsrFragLayout=object(TsrDescriptor)
|
||||
private
|
||||
public
|
||||
pLeft,pRight:PsrFragLayout;
|
||||
//----
|
||||
itype:TpsslInputType;
|
||||
function c(n1,n2:PsrFragLayout):Integer; static;
|
||||
private
|
||||
itype:TpsslInputType;
|
||||
public
|
||||
pReg:PsrRegNode;
|
||||
Procedure Init; inline;
|
||||
|
|
|
@ -69,14 +69,14 @@ type
|
|||
PsrInput=^TsrInput;
|
||||
|
||||
TsrInput=object(TsrDescriptor)
|
||||
private
|
||||
public
|
||||
pLeft,pRight:PsrInput;
|
||||
//----
|
||||
function c(n1,n2:PsrInput):Integer; static;
|
||||
private
|
||||
key:packed record
|
||||
itype:TpsslInputType;
|
||||
typeid:Byte;
|
||||
end;
|
||||
function c(n1,n2:PsrInput):Integer; static;
|
||||
public
|
||||
pReg:PsrRegNode;
|
||||
property itype:TpsslInputType read key.itype;
|
||||
|
|
|
@ -73,9 +73,10 @@ type
|
|||
pLine:PspirvOp;
|
||||
end;
|
||||
TNodeList=specialize TNodeList<PVNode>;
|
||||
private
|
||||
public
|
||||
pLeft,pRight:PsrChain;
|
||||
//--
|
||||
function c(n1,n2:PsrChain):Integer; static;
|
||||
private
|
||||
fwrite_count:DWORD;
|
||||
//--
|
||||
ID:TsrRefId; //post id
|
||||
|
@ -88,7 +89,6 @@ type
|
|||
FWriter:PsrNode;
|
||||
Fdtype:TsrDataType;
|
||||
FList:TNodeList;
|
||||
function c(n1,n2:PsrChain):Integer; static;
|
||||
Procedure SetWriter(t:PsrNode);
|
||||
Function GetWriter:PsrNode;
|
||||
Procedure SetBuffer(t:PsrNode);
|
||||
|
@ -701,6 +701,8 @@ var
|
|||
node:PVNode;
|
||||
pLine:PspirvOp;
|
||||
begin
|
||||
Assert(rtype.BitSize div 8=size);
|
||||
|
||||
Fdtype:=rtype;
|
||||
|
||||
pTypeList:=Emit.GetTypeList;
|
||||
|
|
|
@ -6,7 +6,7 @@ interface
|
|||
|
||||
uses
|
||||
sysutils,
|
||||
half16,
|
||||
Half16,
|
||||
srType,
|
||||
ginodes,
|
||||
srNode;
|
||||
|
@ -29,7 +29,7 @@ type
|
|||
|
||||
PsrLiteral=^TsrLiteral;
|
||||
TsrLiteral=object(TsrNode)
|
||||
private
|
||||
public
|
||||
pLeft,pRight:PsrLiteral;
|
||||
public
|
||||
dtype:TsrDataType;
|
||||
|
|
|
@ -50,8 +50,9 @@ type
|
|||
|
||||
POpParamNode=^TOpParamNode;
|
||||
TOpParamNode=packed object
|
||||
private
|
||||
public
|
||||
pNext:POpParamNode;
|
||||
private
|
||||
pParent:PspirvOp;
|
||||
pValue:PsrNode;
|
||||
procedure SetValue(v:PsrNode);
|
||||
|
@ -69,8 +70,9 @@ type
|
|||
|
||||
PsrOpCustom=^TsrOpCustom;
|
||||
TsrOpCustom=object(TsrNode)
|
||||
private
|
||||
public
|
||||
pPrev,pNext:PsrOpCustom;
|
||||
private
|
||||
pParent:PsrOpBlock;
|
||||
end;
|
||||
|
||||
|
@ -181,14 +183,14 @@ type
|
|||
|
||||
PSpirvFunc=^TSpirvFunc;
|
||||
TSpirvFunc=object(TsrNode)
|
||||
private
|
||||
public
|
||||
pPrev,pNext,pLeft,pRight:PSpirvFunc;
|
||||
//----
|
||||
function c(n1,n2:PSpirvFunc):Integer; static;
|
||||
private
|
||||
FName:RawByteString;
|
||||
FTop:TsrOpBlock;
|
||||
FBlock:PsrOpBlock;
|
||||
ID:TsrRefId; //post id
|
||||
function c(n1,n2:PSpirvFunc):Integer; static;
|
||||
public
|
||||
property Name:RawByteString read FName;
|
||||
property pBlock:PsrOpBlock read FBlock;
|
||||
|
|
|
@ -19,7 +19,7 @@ const
|
|||
OpAbsDiff=DWORD(-3);
|
||||
OpWQM32 =DWORD(-4);
|
||||
|
||||
OpBFEU32 =DWORD(-5);
|
||||
OpBFE_32 =DWORD(-5);
|
||||
OpBFIB32 =DWORD(-6);
|
||||
|
||||
OpPackAnc=DWORD(-7);
|
||||
|
@ -34,7 +34,8 @@ const
|
|||
OpCUBEMA =DWORD(-15);
|
||||
|
||||
function InsSpirvOp(pLine,pNew:PspirvOp):PspirvOp;
|
||||
Function get_inverse_cmp_op(OpId:DWORD):DWORD;
|
||||
Function get_inverse_left_cmp_op(OpId:DWORD):DWORD;
|
||||
Function get_inverse_not_cmp_op(OpId:DWORD):DWORD;
|
||||
Function is_term_op(OpId:DWORD):Boolean;
|
||||
Function is_merge_op(OpId:DWORD):Boolean;
|
||||
Function is_term_op(pLine:PspirvOp):Boolean;
|
||||
|
@ -295,7 +296,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
Function get_inverse_cmp_op(OpId:DWORD):DWORD;
|
||||
Function get_inverse_left_cmp_op(OpId:DWORD):DWORD;
|
||||
begin
|
||||
Result:=0;
|
||||
Case OpId of
|
||||
|
@ -314,19 +315,54 @@ begin
|
|||
Op.OpFUnordNotEqual :Result:=Op.OpFUnordNotEqual ;
|
||||
Op.OpFUnordGreaterThanEqual:Result:=Op.OpFUnordLessThanEqual ;
|
||||
|
||||
Op.OpSLessThan :Result:=Op.OpSGreaterThan ;
|
||||
Op.OpIEqual :Result:=Op.OpIEqual ;
|
||||
Op.OpINotEqual :Result:=Op.OpINotEqual ;
|
||||
|
||||
Op.OpSLessThan :Result:=Op.OpSGreaterThan ;
|
||||
Op.OpSLessThanEqual :Result:=Op.OpSGreaterThanEqual ;
|
||||
Op.OpSGreaterThan :Result:=Op.OpSLessThan ;
|
||||
Op.OpINotEqual :Result:=Op.OpINotEqual ;
|
||||
Op.OpSGreaterThanEqual :Result:=Op.OpSLessThanEqual ;
|
||||
|
||||
Op.OpULessThan :Result:=Op.OpUGreaterThan ;
|
||||
Op.OpULessThanEqual :Result:=Op.OpUGreaterThanEqual ;
|
||||
Op.OpUGreaterThan :Result:=Op.OpULessThan ;
|
||||
Op.OpUGreaterThanEqual :Result:=Op.OpULessThanEqual ;
|
||||
else
|
||||
Assert(false);
|
||||
else;
|
||||
end;
|
||||
end;
|
||||
|
||||
Function get_inverse_not_cmp_op(OpId:DWORD):DWORD;
|
||||
begin
|
||||
Result:=0;
|
||||
Case OpId of
|
||||
Op.OpFOrdLessThan :Result:=Op.OpFUnordGreaterThanEqual;
|
||||
Op.OpFOrdEqual :Result:=Op.OpFUnordNotEqual;
|
||||
Op.OpFOrdLessThanEqual :Result:=Op.OpFUnordGreaterThan;
|
||||
Op.OpFOrdGreaterThan :Result:=Op.OpFUnordLessThanEqual;
|
||||
Op.OpFOrdNotEqual :Result:=Op.OpFUnordEqual;
|
||||
Op.OpFOrdGreaterThanEqual :Result:=Op.OpFUnordLessThan;
|
||||
Op.OpOrdered :Result:=Op.OpUnordered;
|
||||
Op.OpUnordered :Result:=Op.OpOrdered;
|
||||
Op.OpFUnordLessThan :Result:=Op.OpFOrdGreaterThanEqual;
|
||||
Op.OpFUnordEqual :Result:=Op.OpFOrdNotEqual;
|
||||
Op.OpFUnordLessThanEqual :Result:=Op.OpFOrdGreaterThan;
|
||||
Op.OpFUnordGreaterThan :Result:=Op.OpFOrdLessThanEqual;
|
||||
Op.OpFUnordNotEqual :Result:=Op.OpFOrdEqual;
|
||||
Op.OpFUnordGreaterThanEqual:Result:=Op.OpFOrdLessThan;
|
||||
|
||||
Op.OpIEqual :Result:=Op.OpINotEqual;
|
||||
Op.OpINotEqual :Result:=Op.OpIEqual;
|
||||
|
||||
Op.OpSLessThan :Result:=Op.OpSGreaterThanEqual;
|
||||
Op.OpSLessThanEqual :Result:=Op.OpSGreaterThan;
|
||||
Op.OpSGreaterThan :Result:=Op.OpSLessThanEqual;
|
||||
Op.OpSGreaterThanEqual :Result:=Op.OpSLessThan;
|
||||
|
||||
Op.OpULessThan :Result:=Op.OpUGreaterThanEqual;
|
||||
Op.OpULessThanEqual :Result:=Op.OpUGreaterThan;
|
||||
Op.OpUGreaterThan :Result:=Op.OpULessThanEqual;
|
||||
Op.OpUGreaterThanEqual :Result:=Op.OpULessThan;
|
||||
else;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
|
@ -129,7 +129,11 @@ begin
|
|||
end;
|
||||
//Decoration.Index; ???
|
||||
end;
|
||||
//etMrtz,
|
||||
etMrtz:
|
||||
begin
|
||||
pDecorateList^.FfemOpSet:=pDecorateList^.FfemOpSet+[foDepthReplacing,foDepthGreater];
|
||||
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.FragDepth);
|
||||
end;
|
||||
etPos0:
|
||||
begin
|
||||
pDecorateList^.OpDecorate(pVar,Decoration.BuiltIn,BuiltIn.Position);
|
||||
|
|
|
@ -66,16 +66,16 @@ type
|
|||
end;
|
||||
TNodeList=specialize TNodeList<PVNode>;
|
||||
TVoltList=specialize TNodeList<PsrVolatile>;
|
||||
private
|
||||
public
|
||||
pLeft,pRight:PsrPrivate;
|
||||
//----
|
||||
function c(n1,n2:PsrPrivate):Integer; static;
|
||||
private
|
||||
fwrite_count:DWORD;
|
||||
//
|
||||
FSource:PsrRegSlot;
|
||||
//
|
||||
FLineList:TNodeList;
|
||||
FVoltList:TVoltList;
|
||||
function c(n1,n2:PsrPrivate):Integer; static;
|
||||
Procedure SetRegType(rtype:TsrDataType);
|
||||
function GetRegType:TsrDataType;
|
||||
public
|
||||
|
|
|
@ -46,9 +46,9 @@ type
|
|||
TRegDNodeList=specialize TNodeStack<PRegDNode>;
|
||||
|
||||
TsrRegNode=packed object(TsrNode)
|
||||
private
|
||||
public
|
||||
pPrev,pNext:PsrRegNode;
|
||||
//
|
||||
private
|
||||
ID:TsrRefId; //post id
|
||||
F:bitpacked record
|
||||
dtype:TsrDataType;
|
||||
|
|
|
@ -26,16 +26,16 @@ type
|
|||
PPsrType=^PsrType;
|
||||
PsrType=^TsrType;
|
||||
TsrType=packed object(TsrNode)
|
||||
private
|
||||
public
|
||||
pPrev,pNext,pLeft,pRight:PsrType;
|
||||
//
|
||||
function c(n1,n2:PsrType):Integer; static;
|
||||
private
|
||||
ID:TsrRefId; //post id
|
||||
fdtype:TsrDataType;
|
||||
fsize:DWORD;
|
||||
fOpId:WORD;
|
||||
fcount:WORD;
|
||||
pData:PPsrNode;
|
||||
function c(n1,n2:PsrType):Integer; static;
|
||||
public
|
||||
property size:DWORD read fsize;
|
||||
property OpId:WORD read fOpId;
|
||||
|
|
|
@ -52,15 +52,15 @@ type
|
|||
|
||||
PsrUniform=^TsrUniform;
|
||||
TsrUniform=object(TsrDescriptor)
|
||||
private
|
||||
public
|
||||
pLeft,pRight:PsrUniform;
|
||||
//----
|
||||
function c(n1,n2:PsrUniform):Integer; static;
|
||||
private
|
||||
pLayout:PsrDataLayout;
|
||||
//
|
||||
fwrite_count:DWORD;
|
||||
//
|
||||
FReg:TsrRegUniform;
|
||||
function c(n1,n2:PsrUniform):Integer; static;
|
||||
public
|
||||
Procedure Init; inline;
|
||||
function pReg:PsrRegUniform; inline;
|
||||
|
|
|
@ -30,9 +30,9 @@ type
|
|||
|
||||
PsrVariable=^TsrVariable;
|
||||
TsrVariable=packed object(TsrNode)
|
||||
private
|
||||
public
|
||||
pPrev,pNext:PsrVariable;
|
||||
//
|
||||
private
|
||||
fwrite_count:DWORD;
|
||||
ID:TsrRefId; //post id
|
||||
FType:PsrType;
|
||||
|
|
|
@ -23,11 +23,11 @@ type
|
|||
|
||||
PsrVertLayout=^TsrVertLayout;
|
||||
TsrVertLayout=object(TsrDescriptor)
|
||||
private
|
||||
public
|
||||
pLeft,pRight:PsrVertLayout;
|
||||
//----
|
||||
pLayout:PsrDataLayout;
|
||||
function c(n1,n2:PsrVertLayout):Integer; static;
|
||||
private
|
||||
pLayout:PsrDataLayout;
|
||||
public
|
||||
pReg:PsrRegNode;
|
||||
procedure Init(p:PsrDataLayout); inline;
|
||||
|
|
|
@ -305,6 +305,11 @@ begin
|
|||
if not FAjmMap.Delete(uiContext) then Result:=SCE_AJM_ERROR_INVALID_CONTEXT;
|
||||
end;
|
||||
|
||||
function ps4_sceAjmInstanceCodecType(uiCodec:SceAjmCodecType):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=uiCodec shr $E;
|
||||
end;
|
||||
|
||||
function ps4_sceAjmInstanceCreate(uiContext:SceAjmContextId;
|
||||
uiCodec:SceAjmCodecType;
|
||||
uiFlags:QWORD;
|
||||
|
@ -391,6 +396,19 @@ begin
|
|||
|
||||
end;
|
||||
|
||||
function ps4_sceAjmBatchJobInlineBuffer(
|
||||
const pBatchPosition :Pointer;
|
||||
const pDataInput :Pointer;
|
||||
const szDataInputSize:QWORD;
|
||||
const pBatchAddress :PPointer):Pointer; SysV_ABI_CDecl;
|
||||
begin
|
||||
PDWORD(pBatchPosition)^ :=PDWORD(pBatchPosition)^ and $ffffffe0 or 7;
|
||||
PDWORD(pBatchPosition + 4)^:=(szDataInputSize + 7) and $fffffff8;
|
||||
Move(pDataInput^, Pointer(pBatchPosition + 8)^, szDataInputSize);
|
||||
pBatchAddress^:=(pBatchPosition + 8);
|
||||
Result:=pBatchPosition + 8 + ((szDataInputSize + 7) and $fffffffffffffff8);
|
||||
end;
|
||||
|
||||
function ps4_sceAjmBatchJobRunBufferRa(
|
||||
pBatchPosition:Pointer;
|
||||
uiInstance:SceAjmInstanceId;
|
||||
|
@ -477,9 +495,11 @@ begin
|
|||
lib^.set_proc($43777216EC069FAE,@ps4_sceAjmModuleRegister);
|
||||
lib^.set_proc($5A2EC3B652D5F8A2,@ps4_sceAjmModuleUnregister);
|
||||
lib^.set_proc($307BABEAA0AC52EB,@ps4_sceAjmFinalize);
|
||||
lib^.set_proc($7625E340D88CBBFB,@ps4_sceAjmInstanceCodecType);
|
||||
lib^.set_proc($031A03AC8369E09F,@ps4_sceAjmInstanceCreate);
|
||||
lib^.set_proc($45B2DBB8ABFCCE1A,@ps4_sceAjmInstanceDestroy);
|
||||
lib^.set_proc($7660F26CDFFF167F,@ps4_sceAjmBatchJobControlBufferRa);
|
||||
lib^.set_proc($B2D96086789CDC97,@ps4_sceAjmBatchJobInlineBuffer);
|
||||
lib^.set_proc($125B25382A4E227B,@ps4_sceAjmBatchJobRunBufferRa);
|
||||
lib^.set_proc($EE37405CAFB67CCA,@ps4_sceAjmBatchJobRunSplitBufferRa);
|
||||
lib^.set_proc($7C5164934C5F196B,@ps4_sceAjmBatchStartBuffer);
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
unit ps4_libSceAudio3d;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
ps4_program;
|
||||
|
||||
const
|
||||
//SceAudio3dFormat
|
||||
SCE_AUDIO3D_FORMAT_S16 =0;
|
||||
SCE_AUDIO3D_FORMAT_FLOAT=1;
|
||||
|
||||
//SceAudio3dRate
|
||||
SCE_AUDIO3D_RATE_48000=0;
|
||||
|
||||
//SceAudio3dBufferMode
|
||||
SCE_AUDIO3D_BUFFER_NO_ADVANCE =0;
|
||||
SCE_AUDIO3D_BUFFER_ADVANCE_NO_PUSH =1;
|
||||
SCE_AUDIO3D_BUFFER_ADVANCE_AND_PUSH=2;
|
||||
|
||||
//SceAudio3dBlocking
|
||||
SCE_AUDIO3D_BLOCKING_ASYNC=0;
|
||||
SCE_AUDIO3D_BLOCKING_SYNC =1;
|
||||
|
||||
type
|
||||
pSceAudio3dFormat=^SceAudio3dFormat;
|
||||
SceAudio3dFormat=Integer;
|
||||
|
||||
pSceAudio3dAttributeId=^SceAudio3dAttributeId;
|
||||
SceAudio3dAttributeId=DWORD;
|
||||
|
||||
pSceAudio3dAttribute=^SceAudio3dAttribute;
|
||||
SceAudio3dAttribute=packed record
|
||||
uiAttributeId:SceAudio3dAttributeId;
|
||||
_align:Integer;
|
||||
pValue:Pointer;
|
||||
szValue:QWORD;
|
||||
end;
|
||||
|
||||
pSceAudio3dBlocking=^SceAudio3dBlocking;
|
||||
SceAudio3dBlocking=Integer;
|
||||
|
||||
pSceAudio3dBufferMode=^SceAudio3dBufferMode;
|
||||
SceAudio3dBufferMode=Integer;
|
||||
|
||||
pSceAudio3dObjectId=^SceAudio3dObjectId;
|
||||
SceAudio3dObjectId=DWORD;
|
||||
|
||||
pSceAudio3dPortId=^SceAudio3dPortId;
|
||||
SceAudio3dPortId=DWORD;
|
||||
|
||||
pSceAudio3dRate=^SceAudio3dRate;
|
||||
SceAudio3dRate=Integer;
|
||||
|
||||
pSceAudio3dOpenParameters=^SceAudio3dOpenParameters;
|
||||
SceAudio3dOpenParameters=packed record
|
||||
szSizeThis :QWORD;
|
||||
uiGranularity:DWORD;
|
||||
eRate :SceAudio3dRate;
|
||||
uiMaxObjects :DWORD;
|
||||
uiQueueDepth :DWORD;
|
||||
eBufferMode :SceAudio3dBufferMode;
|
||||
_align :Integer;
|
||||
uiNumBeds :DWORD;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
function ps4_sceAudio3dInitialize(iReserved:Int64):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
procedure ps4_sceAudio3dGetDefaultOpenParameters(const pParameters:pSceAudio3dOpenParameters); SysV_ABI_CDecl;
|
||||
begin
|
||||
if (pParameters<>nil) then
|
||||
begin
|
||||
pParameters^.szSizeThis :=$20;
|
||||
pParameters^.uiGranularity:=256;
|
||||
pParameters^.eRate :=SCE_AUDIO3D_RATE_48000;
|
||||
pParameters^.uiMaxObjects :=512;
|
||||
pParameters^.uiQueueDepth :=2;
|
||||
pParameters^.eBufferMode :=SCE_AUDIO3D_BUFFER_ADVANCE_AND_PUSH;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_sceAudio3dPortOpen(iUserId:Integer;
|
||||
const pParameters:pSceAudio3dOpenParameters;
|
||||
pId:pSceAudio3dPortId):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceAudio3dObjectReserve(uiPortId:SceAudio3dPortId;
|
||||
pId:pSceAudio3dObjectId):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceAudio3dObjectSetAttributes(uiPortId:SceAudio3dPortId;
|
||||
uiObjectId:SceAudio3dObjectId;
|
||||
szNumAttributes:QWORD;
|
||||
const pAttributesArray:pSceAudio3dAttribute):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceAudio3dPortSetAttribute(uiPortId:SceAudio3dPortId;
|
||||
uiAttributeId:SceAudio3dAttributeId;
|
||||
const pAttribute:Pointer;
|
||||
szAttribute:QWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceAudio3dPortFlush(uiPortId:SceAudio3dPortId):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceAudio3dPortAdvance(uiPortId:SceAudio3dPortId):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceAudio3dPortPush(uiPortId:SceAudio3dPortId;
|
||||
eBlocking:SceAudio3dBlocking):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceAudio3dAudioOutOpen(uiPortId:SceAudio3dPortId;
|
||||
userId,_type,index:Integer;
|
||||
len,freq,param:DWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceAudio3dPortGetQueueLevel(uiPortId:SceAudio3dPortId;
|
||||
pQueueLevel,pQueueAvailable:pWord):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceAudio3dBedWrite(uiPortId:SceAudio3dPortId;
|
||||
uiNumChannels:Integer;
|
||||
eFormat:SceAudio3dFormat;
|
||||
const pBuffer:Pointer;
|
||||
_uiNumChannels:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceAudio3dTerminate():Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function Load_libSceAudio3d(Const name:RawByteString):TElf_node;
|
||||
var
|
||||
lib:PLIBRARY;
|
||||
begin
|
||||
Result:=TElf_node.Create;
|
||||
Result.pFileName:=name;
|
||||
lib:=Result._add_lib('libSceAudio3d');
|
||||
lib^.set_proc($5260AF8D29AE648C,@ps4_sceAudio3dInitialize);
|
||||
lib^.set_proc($226FA33A86B95802,@ps4_sceAudio3dGetDefaultOpenParameters);
|
||||
lib^.set_proc($5DE0C32B4C495900,@ps4_sceAudio3dPortOpen);
|
||||
lib^.set_proc($8CEDAD79CE1D2763,@ps4_sceAudio3dObjectReserve);
|
||||
lib^.set_proc($E2EC8737DAB865E5,@ps4_sceAudio3dObjectSetAttributes);
|
||||
lib^.set_proc($62AF5B7D4434B898,@ps4_sceAudio3dPortSetAttribute);
|
||||
lib^.set_proc($64E1ABC562E04331,@ps4_sceAudio3dPortFlush);
|
||||
lib^.set_proc($970D2AADD4A366DF,@ps4_sceAudio3dPortAdvance);
|
||||
lib^.set_proc($54456167DA9DE196,@ps4_sceAudio3dPortPush);
|
||||
lib^.set_proc($B9C12C8BADACA13A,@ps4_sceAudio3dAudioOutOpen);
|
||||
lib^.set_proc($61A6836C3C0AA453,@ps4_sceAudio3dPortGetQueueLevel);
|
||||
lib^.set_proc($F6D130134195D2AA,@ps4_sceAudio3dBedWrite);
|
||||
lib^.set_proc($596D534B68B3E727,@ps4_sceAudio3dTerminate);
|
||||
end;
|
||||
|
||||
initialization
|
||||
//low priority
|
||||
ps4_app.RegistredFinLoad('libSceAudio3d.prx',@Load_libSceAudio3d);
|
||||
|
||||
end.
|
||||
|
|
@ -421,6 +421,23 @@ begin
|
|||
Result:=0;
|
||||
end;
|
||||
|
||||
type
|
||||
pSceAudioOutSystemState=^SceAudioOutSystemState;
|
||||
SceAudioOutSystemState=packed record
|
||||
loudness :single;
|
||||
reserved8 :array[0..3] of Byte;
|
||||
reserved64:array[0..2] of QWORD;
|
||||
end;
|
||||
|
||||
function ps4_sceAudioOutGetSystemState(state:pSceAudioOutSystemState):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (state=nil) then Exit(SCE_AUDIO_OUT_ERROR_INVALID_POINTER);
|
||||
if (HAudioOuts=nil) then Exit(SCE_AUDIO_OUT_ERROR_NOT_INIT);
|
||||
|
||||
state^.loudness:=1;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceAudioOutSetVolume(handle,flag:Integer;vol:PInteger):Integer; SysV_ABI_CDecl;
|
||||
Var
|
||||
H:TAudioOutHandle;
|
||||
|
@ -601,7 +618,6 @@ const
|
|||
fdiv2:Single=(1/Sqrt(2))*(1+(3/Sqrt(2)));
|
||||
var
|
||||
fvolume:array[0..7] of Single;
|
||||
fL,fR:Single;
|
||||
begin
|
||||
fvolume[_FL]:=(volume[_FL]/SCE_AUDIO_VOLUME_0DB)*fdiv1;
|
||||
fvolume[_FR]:=(volume[_FR]/SCE_AUDIO_VOLUME_0DB)*fdiv1;
|
||||
|
@ -613,6 +629,51 @@ begin
|
|||
__VecMulF32CH8ToS(Src,Dst,count,@fvolume);
|
||||
end;
|
||||
|
||||
procedure __VecMulS16CH8ToS(Src,Dst:Pointer;count:Integer;fvolume:PSingle);
|
||||
var
|
||||
fL,fR:Single;
|
||||
begin
|
||||
While (count>0) do
|
||||
begin
|
||||
|
||||
fL:=(PSmallInt(Src)[_FL]*fvolume[_FL])+
|
||||
(PSmallInt(Src)[_FC]*fvolume[_FC])+
|
||||
(PSmallInt(Src)[_SL]*fvolume[_SL])+
|
||||
(PSmallInt(Src)[_BL]*fvolume[_BL]);
|
||||
|
||||
fR:=(PSmallInt(Src)[_FR]*fvolume[_FR])+
|
||||
(PSmallInt(Src)[_FC]*fvolume[_FC])+
|
||||
(PSmallInt(Src)[_SR]*fvolume[_SR])+
|
||||
(PSmallInt(Src)[_BR]*fvolume[_BR]);
|
||||
|
||||
PSmallInt(Dst)^:=Trunc(fL);
|
||||
Inc(Dst,2);
|
||||
PSmallInt(Dst)^:=Trunc(fR);
|
||||
Inc(Dst,2);
|
||||
|
||||
Inc(Src,2*8);
|
||||
|
||||
Dec(count);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure _VecMulS32CH8ToS(Src,Dst:Pointer;count:Integer;volume:PInteger);
|
||||
const
|
||||
fdiv1:Single=1+(3/Sqrt(2));
|
||||
fdiv2:Single=(1/Sqrt(2))*(1+(3/Sqrt(2)));
|
||||
var
|
||||
fvolume:array[0..7] of Single;
|
||||
begin
|
||||
fvolume[_FL]:=(volume[_FL]/SCE_AUDIO_VOLUME_0DB)*fdiv1;
|
||||
fvolume[_FR]:=(volume[_FR]/SCE_AUDIO_VOLUME_0DB)*fdiv1;
|
||||
fvolume[_FC]:=(volume[_FC]/SCE_AUDIO_VOLUME_0DB)*fdiv2;
|
||||
fvolume[_SL]:=(volume[_SL]/SCE_AUDIO_VOLUME_0DB)*fdiv2;
|
||||
fvolume[_SR]:=(volume[_SR]/SCE_AUDIO_VOLUME_0DB)*fdiv2;
|
||||
fvolume[_BL]:=(volume[_BL]/SCE_AUDIO_VOLUME_0DB)*fdiv2;
|
||||
fvolume[_BR]:=(volume[_BR]/SCE_AUDIO_VOLUME_0DB)*fdiv2;
|
||||
__VecMulS16CH8ToS(Src,Dst,count,@fvolume);
|
||||
end;
|
||||
|
||||
procedure _VecMulF32CH8STDToS(Src,Dst:Pointer;count:Integer;volume:PInteger);
|
||||
const
|
||||
fdiv1:Single=1+(3/Sqrt(2));
|
||||
|
@ -668,7 +729,18 @@ begin
|
|||
end;
|
||||
SCE_AUDIO_OUT_PARAM_FORMAT_S16_8CH:
|
||||
begin
|
||||
Assert(false,'SCE_AUDIO_OUT_PARAM_FORMAT_S16_8CH');
|
||||
|
||||
if (H.pnumOutputChannels=2) then
|
||||
begin
|
||||
_VecMulS32CH8ToS(ptr,H.buf,count,@H.volume);
|
||||
_sig_lock;
|
||||
err:=Pa_WriteStream(H.pstream,H.buf,count);
|
||||
_sig_unlock;
|
||||
end else
|
||||
begin
|
||||
Assert(false,'SCE_AUDIO_OUT_PARAM_FORMAT_S16_8CH');
|
||||
end;
|
||||
|
||||
end;
|
||||
SCE_AUDIO_OUT_PARAM_FORMAT_FLOAT_MONO:
|
||||
begin
|
||||
|
@ -793,6 +865,7 @@ begin
|
|||
lib^.set_proc($40E42D6DE0EAB13E,@ps4_sceAudioOutOutput);
|
||||
lib^.set_proc($C373DD6924D2C061,@ps4_sceAudioOutOutputs);
|
||||
lib^.set_proc($3ED96DB37DBAA5DB,@ps4_sceAudioOutGetLastOutputTime);
|
||||
lib^.set_proc($47985E9A828A203F,@ps4_sceAudioOutGetSystemState);
|
||||
end;
|
||||
|
||||
const
|
||||
|
@ -803,6 +876,15 @@ begin
|
|||
Result:=Integer(SCE_AUDIO_IN_ERROR_NOT_OPENED);
|
||||
end;
|
||||
|
||||
const
|
||||
SCE_AUDIO_IN_SILENT_STATE_DEVICE_NONE=$00000001;
|
||||
|
||||
|
||||
function ps4_sceAudioInGetSilentState(handle:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=SCE_AUDIO_IN_SILENT_STATE_DEVICE_NONE;
|
||||
end;
|
||||
|
||||
function Load_libSceAudioIn(Const name:RawByteString):TElf_node;
|
||||
var
|
||||
lib:PLIBRARY;
|
||||
|
@ -811,6 +893,7 @@ begin
|
|||
Result.pFileName:=name;
|
||||
lib:=Result._add_lib('libSceAudioIn');
|
||||
lib^.set_proc($E4D13C4A373B542F,@ps4_sceAudioInOpen);
|
||||
lib^.set_proc($068844010EC39541,@ps4_sceAudioInGetSilentState);
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
|
|
@ -0,0 +1,286 @@
|
|||
unit ps4_libSceAudiodec;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
hamt,
|
||||
spinlock,
|
||||
ps4_program;
|
||||
|
||||
implementation
|
||||
|
||||
const
|
||||
SCE_AUDIODEC_TYPE_AT9 =1;
|
||||
SCE_AUDIODEC_TYPE_MP3 =2;
|
||||
SCE_AUDIODEC_TYPE_M4AAC=3;
|
||||
|
||||
SCE_AUDIODEC_ERROR_API_FAIL=$807F0000;
|
||||
SCE_AUDIODEC_ERROR_INVALID_TYPE=$807F0001;
|
||||
SCE_AUDIODEC_ERROR_ARG=$807F0002;
|
||||
SCE_AUDIODEC_ERROR_INVALID_SIZE=$807F0003;
|
||||
SCE_AUDIODEC_ERROR_INVALID_PARAM_SIZE=$807F0004;
|
||||
SCE_AUDIODEC_ERROR_INVALID_BSI_INFO_SIZE=$807F0005;
|
||||
SCE_AUDIODEC_ERROR_INVALID_AU_INFO_SIZE=$807F0006;
|
||||
SCE_AUDIODEC_ERROR_INVALID_PCM_ITEM_SIZE=$807F0007;
|
||||
SCE_AUDIODEC_ERROR_INVALID_CTRL_POINTER=$807F0008;
|
||||
SCE_AUDIODEC_ERROR_INVALID_PARAM_POINTER=$807F0009;
|
||||
SCE_AUDIODEC_ERROR_INVALID_BSI_INFO_POINTER=$807F000A;
|
||||
SCE_AUDIODEC_ERROR_INVALID_AU_INFO_POINTER=$807F000B;
|
||||
SCE_AUDIODEC_ERROR_INVALID_PCM_ITEM_POINTER=$807F000C;
|
||||
SCE_AUDIODEC_ERROR_INVALID_AU_POINTER=$807F000D;
|
||||
SCE_AUDIODEC_ERROR_INVALID_PCM_POINTER=$807F000E;
|
||||
SCE_AUDIODEC_ERROR_INVALID_HANDLE=$807F000F;
|
||||
SCE_AUDIODEC_ERROR_INVALID_WORD_LENGTH=$807F0010;
|
||||
SCE_AUDIODEC_ERROR_INVALID_AU_SIZE=$807F0011;
|
||||
SCE_AUDIODEC_ERROR_INVALID_PCM_SIZE=$807F0012;
|
||||
SCE_AUDIODEC_ERROR_M4AAC_INVALID_SAMPLING_FREQ=$807F0300;
|
||||
SCE_AUDIODEC_ERROR_M4AAC_INVALID_ENABLE_HEAAC=$807F0302;
|
||||
SCE_AUDIODEC_ERROR_M4AAC_INVALID_CONFIG_NUMBER=$807F0303;
|
||||
SCE_AUDIODEC_ERROR_M4AAC_INVALID_MAX_CHANNELS=$807F0304;
|
||||
SCE_AUDIODEC_ERROR_M4AAC_INVALID_ENABLE_NONDELAY_OUTPUT=$807F0305;
|
||||
SCE_AUDIODEC_ERROR_M4AAC_INVALID_SURROUND_CHANNEL_INTERLEAVE_ORDER=$807F0306;
|
||||
SCE_AUDIODEC_ERROR_AT9_INVALID_CONFIG_DATA=$807F1000;
|
||||
|
||||
type
|
||||
SceAudiodecAuInfo=packed record
|
||||
uiSize :DWord;
|
||||
_align1 :Dword;
|
||||
pAuAddr :Pointer;
|
||||
uiAuSize:DWord;
|
||||
_align2 :DWord;
|
||||
end;
|
||||
PSceAudiodecAuInfo=^SceAudiodecAuInfo;
|
||||
|
||||
SceAudiodecPcmItem=packed record
|
||||
uiSize :DWord;
|
||||
_align1 :Dword;
|
||||
pPcmAddr :Pointer;
|
||||
uiPcmSize:DWord;
|
||||
_align2 :DWord;
|
||||
end;
|
||||
PSceAudiodecPcmItem=^SceAudiodecPcmItem;
|
||||
|
||||
SceAudiodecParam=packed record
|
||||
uiSize:DWord;
|
||||
// TODO: union
|
||||
end;
|
||||
PSceAudiodecParam=^SceAudiodecParam;
|
||||
|
||||
SceAudiodecBsiInfo=packed record
|
||||
uiSize:DWord;
|
||||
// TODO: union
|
||||
end;
|
||||
PSceAudiodecBsiInfo=^SceAudiodecBsiInfo;
|
||||
|
||||
SceAudiodecCtrl=packed record
|
||||
pParam :PSceAudiodecParam;
|
||||
pBsiInfo:PSceAudiodecBsiInfo;
|
||||
pAuInfo :PSceAudiodecAuInfo;
|
||||
pPcmItem:PSceAudiodecPcmItem;
|
||||
end;
|
||||
PSceAudiodecCtrl=^SceAudiodecCtrl;
|
||||
|
||||
SceAudiodecHandle =DWord;
|
||||
PSceAudiodecHandle=^SceAudiodecHandle;
|
||||
|
||||
TAudioDecoderAT9=record
|
||||
channels :DWord;
|
||||
sampleRate :DWord;
|
||||
bitRate :DWord;
|
||||
configData :DWord;
|
||||
superFrameRate :DWord;
|
||||
framesInSuperFrame:DWord;
|
||||
end;
|
||||
|
||||
TAudioDecoderMP3=record
|
||||
channels:DWord;
|
||||
end;
|
||||
|
||||
TAudioDecoderM4AAC=record
|
||||
channels :DWord;
|
||||
sampleRate:DWord;
|
||||
isAdts :DWord;
|
||||
isSbr :DWord;
|
||||
end;
|
||||
|
||||
TAudioDecoderInfo=record
|
||||
param :SceAudiodecParam;
|
||||
bsiInfo :SceAudiodecBsiInfo;
|
||||
codecType:DWord;
|
||||
case Byte of
|
||||
SCE_AUDIODEC_TYPE_AT9 :(at9:TAudioDecoderAT9);
|
||||
SCE_AUDIODEC_TYPE_MP3 :(mp3:TAudioDecoderMP3);
|
||||
SCE_AUDIODEC_TYPE_M4AAC:(aac:TAudioDecoderM4AAC);
|
||||
end;
|
||||
|
||||
TAudioDecoder=class
|
||||
handle:SceAudiodecHandle;
|
||||
info :TAudioDecoderInfo;
|
||||
constructor Create(const pCtrl:PSceAudiodecCtrl;const codecType:DWord);
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
var
|
||||
hamt_lock :Pointer;
|
||||
handleCount :QWord=0;
|
||||
AudiodecHamt:TSTUB_HAMT32;
|
||||
|
||||
function _GetDecoder(const handle:SceAudiodecHandle):TAudioDecoder;
|
||||
var
|
||||
data:PPointer;
|
||||
begin
|
||||
Result:=nil;
|
||||
spin_lock(hamt_lock);
|
||||
data:=HAMT_search32(@AudiodecHamt,handle);
|
||||
if (data<>nil) then
|
||||
begin
|
||||
Result:=TAudioDecoder(data^);
|
||||
end;
|
||||
spin_unlock(hamt_lock);
|
||||
end;
|
||||
|
||||
function _AddDecoder(const decoder:TAudioDecoder):SceAudiodecHandle;
|
||||
var
|
||||
data:PPointer;
|
||||
begin
|
||||
spin_lock(hamt_lock);
|
||||
Inc(handleCount);
|
||||
data:=HAMT_insert32(@AudiodecHamt,handleCount,decoder);
|
||||
Assert(data<>nil,'unexpected err');
|
||||
data^:=decoder;
|
||||
decoder.handle:=handleCount;
|
||||
Result:=handleCount;
|
||||
spin_unlock(hamt_lock);
|
||||
end;
|
||||
|
||||
procedure _DeleteDecoder(const handle:SceAudiodecHandle);
|
||||
begin
|
||||
spin_lock(hamt_lock);
|
||||
HAMT_delete32(@AudiodecHamt,handle,nil);
|
||||
spin_unlock(hamt_lock);
|
||||
end;
|
||||
|
||||
constructor TAudioDecoder.Create(const pCtrl:PSceAudiodecCtrl;const codecType:DWord);
|
||||
begin
|
||||
inherited Create;
|
||||
_AddDecoder(Self);
|
||||
info.codecType:=codecType;
|
||||
Move(pCtrl^.pParam^ ,info.param ,pCtrl^.pParam^.uiSize);
|
||||
Move(pCtrl^.pBsiInfo^,info.bsiInfo,pCtrl^.pBsiInfo^.uiSize);
|
||||
case codecType of
|
||||
SCE_AUDIODEC_TYPE_AT9:
|
||||
begin
|
||||
// TODO:
|
||||
end;
|
||||
SCE_AUDIODEC_TYPE_MP3:
|
||||
begin
|
||||
// TODO:
|
||||
end;
|
||||
SCE_AUDIODEC_TYPE_M4AAC:
|
||||
begin
|
||||
// TODO:
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
destructor TAudioDecoder.Destroy;
|
||||
begin
|
||||
_DeleteDecoder(handle);
|
||||
inherited;
|
||||
end;
|
||||
|
||||
function ps4_sceAudiodecInitLibrary(codecType:DWord):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln('sceAudiodecInitLibrary,codecType=',codecType);
|
||||
if not (codecType in [SCE_AUDIODEC_TYPE_AT9..SCE_AUDIODEC_TYPE_M4AAC]) then
|
||||
Result:=SCE_AUDIODEC_ERROR_INVALID_TYPE
|
||||
else
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceAudiodecCreateDecoder(pCtrl:PSceAudiodecCtrl;uiCodecType:Dword):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
audioDecoder:TAudioDecoder;
|
||||
begin
|
||||
Writeln('sceAudiodecCreateDecoder,uiCodecType=',uiCodecType);
|
||||
if pCtrl=nil then
|
||||
Exit(SCE_AUDIODEC_ERROR_INVALID_CTRL_POINTER);
|
||||
if pCtrl^.pParam=nil then
|
||||
Exit(SCE_AUDIODEC_ERROR_INVALID_PARAM_POINTER);
|
||||
if pCtrl^.pBsiInfo=nil then
|
||||
Exit(SCE_AUDIODEC_ERROR_INVALID_BSI_INFO_POINTER);
|
||||
case uiCodecType of
|
||||
SCE_AUDIODEC_TYPE_AT9,
|
||||
SCE_AUDIODEC_TYPE_MP3,
|
||||
SCE_AUDIODEC_TYPE_M4AAC:
|
||||
begin
|
||||
audioDecoder:=TAudioDecoder.Create(pCtrl,uiCodecType);
|
||||
Result:=audioDecoder.handle;
|
||||
end;
|
||||
else
|
||||
begin
|
||||
Writeln(StdErr,'ERROR: Unsupported audio decoder');
|
||||
Result:=SCE_AUDIODEC_ERROR_INVALID_TYPE;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_sceAudiodecDecode(handle:Integer;pCtrl:PSceAudiodecCtrl):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if pCtrl=nil then
|
||||
Exit(-1);
|
||||
//Writeln('sceAudiodecDecode,handle=',handle,',uiAuSize=',pCtrl^.pAuInfo^.uiAuSize,',uiPcmSize=',pCtrl^.pPcmItem^.uiPcmSize);
|
||||
// TODO:
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceAudiodecDeleteDecoder(handle:Integer):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
audioDecoder:TAudioDecoder;
|
||||
begin
|
||||
Writeln('sceAudiodecDeleteDecoder,handle=',handle);
|
||||
audioDecoder:=_GetDecoder(handle);
|
||||
if audioDecoder<>nil then
|
||||
audioDecoder.Free;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceAudiodecClearContext(handle:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln('sceAudiodecClearContext,handle=',handle);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceAudiodecTermLibrary(uiCodecType:DWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln('sceAudiodecTermLibrary,uiCodecType=',uiCodecType);
|
||||
if not (uiCodecType in [SCE_AUDIODEC_TYPE_AT9..SCE_AUDIODEC_TYPE_M4AAC]) then
|
||||
Result:=SCE_AUDIODEC_ERROR_INVALID_TYPE
|
||||
else
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function Load_libSceAudiodec(Const name:RawByteString):TElf_node;
|
||||
var
|
||||
lib:PLIBRARY;
|
||||
begin
|
||||
Result:=TElf_node.Create;
|
||||
Result.pFileName:=name;
|
||||
|
||||
lib:=Result._add_lib('libSceAudiodec');
|
||||
lib^.set_proc($56386C9B1A5C7B32,@ps4_sceAudiodecInitLibrary);
|
||||
lib^.set_proc($3B77F5B0B31646FB,@ps4_sceAudiodecCreateDecoder);
|
||||
lib^.set_proc($2875C73032E420BC,@ps4_sceAudiodecDecode);
|
||||
lib^.set_proc($4E9F99132EBD98B9,@ps4_sceAudiodecDeleteDecoder);
|
||||
lib^.set_proc($E957FD5932C3A2CB,@ps4_sceAudiodecClearContext);
|
||||
lib^.set_proc($8798D20764080D5D,@ps4_sceAudiodecTermLibrary);
|
||||
end;
|
||||
|
||||
initialization
|
||||
FillChar(AudiodecHamt,SizeOf(AudiodecHamt),0);
|
||||
ps4_app.RegistredPreLoad('libSceAudiodec.prx' ,@Load_libSceAudiodec);
|
||||
|
||||
end.
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
unit ps4_libSceAudiodecCpu;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
ps4_program;
|
||||
|
||||
implementation
|
||||
|
||||
type
|
||||
PSceAudiodecCpuCtrl=Pointer;
|
||||
PSceAudiodecCpuResource=Pointer;
|
||||
|
||||
function ps4_sceAudiodecCpuQueryMemSize(pCtrl :PSceAudiodecCpuCtrl;
|
||||
pRes :PSceAudiodecCpuResource;
|
||||
uiCodecType:DWord):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln('sceAudiodecCpuQueryMemSize,uiCodecType=',uiCodecType);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceAudiodecCpuInitDecoder(pCtrl :PSceAudiodecCpuCtrl;
|
||||
pRes :PSceAudiodecCpuResource;
|
||||
uiCodecType:DWord):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln('sceAudiodecCpuInitDecoder,uiCodecType=',uiCodecType);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceAudiodecCpuDecode(pCtrl :PSceAudiodecCpuCtrl;
|
||||
pRes :PSceAudiodecCpuResource;
|
||||
uiCodecType:DWord):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
// Writeln('sceAudiodecCpuDecode,uiCodecType=',uiCodecType);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function Load_libSceAudiodecCpu(Const name:RawByteString):TElf_node;
|
||||
var
|
||||
lib:PLIBRARY;
|
||||
begin
|
||||
Result:=TElf_node.Create;
|
||||
Result.pFileName:=name;
|
||||
|
||||
lib:=Result._add_lib('libSceAudiodecCpu');
|
||||
|
||||
lib^.set_proc($92D0F6C370F81B65,@ps4_sceAudiodecCpuQueryMemSize);
|
||||
lib^.set_proc($85D16CC68DCC16EF,@ps4_sceAudiodecCpuInitDecoder);
|
||||
lib^.set_proc($952553896579C0B7,@ps4_sceAudiodecCpuDecode);
|
||||
end;
|
||||
|
||||
initialization
|
||||
ps4_app.RegistredPreLoad('libSceAudiodecCpu.prx',@Load_libSceAudiodecCpu);
|
||||
|
||||
end.
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
unit kbm_pad_interface;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Windows,
|
||||
sysutils,
|
||||
spinlock,
|
||||
sce_pad_types,
|
||||
sce_pad_interface;
|
||||
|
||||
type
|
||||
TKbmPadHandle=class(TScePadHandle)
|
||||
function ReadState(data:PScePadData):Integer; override;
|
||||
end;
|
||||
|
||||
TKbmPadInterface=class(TScePadInterface)
|
||||
class function Open(var handle:TScePadHandle):Integer; override;
|
||||
end;
|
||||
|
||||
TMouseAsTouchpad=class
|
||||
class var
|
||||
last_mouse_lock :Pointer;
|
||||
last_mouse_point:TPoint;
|
||||
last_mouse_init :Integer;
|
||||
class function ReadState(data:PScePadData):Integer;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
class function TKbmPadInterface.Open(var handle:TScePadHandle):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
handle:=TKbmPadHandle.Create;
|
||||
end;
|
||||
|
||||
function GetAsyncKeyState(vKey:longint):Boolean; inline;
|
||||
begin
|
||||
Result:=(Windows.GetKeyState(vKey) and $8000)<>0;
|
||||
end;
|
||||
|
||||
class function TMouseAsTouchpad.ReadState(data:PScePadData):Integer;
|
||||
var
|
||||
mPoint,delta:TPoint;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
//mouse as touch pad
|
||||
|
||||
spin_lock(last_mouse_lock);
|
||||
|
||||
GetCursorPos(mPoint);
|
||||
|
||||
if (last_mouse_init=0) then
|
||||
begin
|
||||
last_mouse_init :=1;
|
||||
last_mouse_point:=mPoint;
|
||||
end else
|
||||
if QWORD(mPoint)<>QWORD(last_mouse_point) then
|
||||
begin
|
||||
data^.touchData.touchNum:=1;
|
||||
data^.touchData.touch[0].id:=0;
|
||||
|
||||
delta:=mPoint;
|
||||
|
||||
if (delta.X<0) then delta.X:=0;
|
||||
if (delta.Y<0) then delta.Y:=0;
|
||||
|
||||
if (delta.X>1919) then delta.X:=1919;
|
||||
if (delta.Y>941) then delta.Y:=941;
|
||||
|
||||
data^.touchData.touch[0].x:=delta.X;
|
||||
data^.touchData.touch[0].y:=delta.Y;
|
||||
|
||||
last_mouse_point:=mPoint;
|
||||
end;
|
||||
|
||||
spin_unlock(last_mouse_lock);
|
||||
|
||||
if GetAsyncKeyState(VK_LBUTTON) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_TOUCH_PAD;
|
||||
end;
|
||||
|
||||
function TKbmPadHandle.ReadState(data:PScePadData):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
TMouseAsTouchpad.ReadState(data);
|
||||
|
||||
//keymapping
|
||||
|
||||
if GetAsyncKeyState(VK_W) then
|
||||
data^.leftStick.y:=0;
|
||||
|
||||
if GetAsyncKeyState(VK_S) then
|
||||
data^.leftStick.y:=$FF;
|
||||
|
||||
if GetAsyncKeyState(VK_A) then
|
||||
data^.leftStick.x:=0;
|
||||
|
||||
if GetAsyncKeyState(VK_D) then
|
||||
data^.leftStick.x:=$FF;
|
||||
|
||||
//
|
||||
|
||||
if GetAsyncKeyState(VK_I) then
|
||||
data^.rightStick.y:=0;
|
||||
|
||||
if GetAsyncKeyState(VK_K) then
|
||||
data^.rightStick.y:=$FF;
|
||||
|
||||
if GetAsyncKeyState(VK_J) then
|
||||
data^.rightStick.x:=0;
|
||||
|
||||
if GetAsyncKeyState(VK_L) then
|
||||
data^.rightStick.x:=$FF;
|
||||
|
||||
//
|
||||
|
||||
if GetAsyncKeyState(VK_RETURN) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_OPTIONS;
|
||||
|
||||
if GetAsyncKeyState(VK_UP) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_UP;
|
||||
|
||||
if GetAsyncKeyState(VK_RIGHT) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_RIGHT;
|
||||
|
||||
if GetAsyncKeyState(VK_DOWN) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_DOWN;
|
||||
|
||||
if GetAsyncKeyState(VK_LEFT) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_LEFT;
|
||||
|
||||
if GetAsyncKeyState(VK_NUMPAD8) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_TRIANGLE;
|
||||
|
||||
if GetAsyncKeyState(VK_NUMPAD6) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_CIRCLE;
|
||||
|
||||
if GetAsyncKeyState(VK_NUMPAD2) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_CROSS;
|
||||
|
||||
if GetAsyncKeyState(VK_NUMPAD4) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_SQUARE;
|
||||
|
||||
if GetAsyncKeyState(VK_Q) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_L1;
|
||||
|
||||
if GetAsyncKeyState(VK_1) then
|
||||
begin
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_L2;
|
||||
data^.analogButtons.l2:=255;
|
||||
end;
|
||||
|
||||
if GetAsyncKeyState(VK_Z) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_L3;
|
||||
|
||||
|
||||
if GetAsyncKeyState(VK_E) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_R1;
|
||||
|
||||
if GetAsyncKeyState(VK_4) then
|
||||
begin
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_R2;
|
||||
data^.analogButtons.r2:=255;
|
||||
end;
|
||||
|
||||
if GetAsyncKeyState(VK_C) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_R3;
|
||||
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
unit sce_pad_interface;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
sce_pad_types,
|
||||
ps4_handles,
|
||||
spinlock;
|
||||
|
||||
type
|
||||
TScePadHandle=class(TClassHandle)
|
||||
var
|
||||
userID:Integer;
|
||||
_type :Integer;
|
||||
index :Integer;
|
||||
handle:Integer;
|
||||
function ReadState(data:PScePadData):Integer; virtual;
|
||||
function SetLightBar(data:pScePadLightBarParam):Integer; virtual;
|
||||
function ResetLightBar():Integer; virtual;
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
TScePadInterface=class
|
||||
class function Load:Boolean; virtual;
|
||||
class procedure Unload; virtual;
|
||||
class function Init:Integer; virtual;
|
||||
class function Done:Integer; virtual;
|
||||
class function Open(var handle:TScePadHandle):Integer; virtual;
|
||||
end;
|
||||
|
||||
TAbstractScePadInterface=class of TScePadInterface;
|
||||
|
||||
var
|
||||
pad_handles:TIntegerHandles;
|
||||
pad_opened :array[0..15] of TScePadHandle;
|
||||
pad_lock :Pointer;
|
||||
|
||||
function FindPadByParam(userID,_type,index:Integer):TScePadHandle;
|
||||
Procedure SavePadHandle(handle:TScePadHandle);
|
||||
Procedure ClearPadHandle(handle:TScePadHandle);
|
||||
|
||||
implementation
|
||||
|
||||
function FindPadByParam(userID,_type,index:Integer):TScePadHandle;
|
||||
var
|
||||
i:Integer;
|
||||
begin
|
||||
Result:=nil;
|
||||
spin_lock(pad_lock);
|
||||
For i:=Low(pad_opened) to High(pad_opened) do
|
||||
if (pad_opened[i]<>nil) then
|
||||
if (pad_opened[i].userID=userID) and
|
||||
(pad_opened[i]._type =_type ) and
|
||||
(pad_opened[i].index =index ) then
|
||||
begin
|
||||
Result:=pad_opened[i];
|
||||
Result.Acqure;
|
||||
Break;
|
||||
end;
|
||||
spin_unlock(pad_lock);
|
||||
end;
|
||||
|
||||
Procedure SavePadHandle(handle:TScePadHandle);
|
||||
var
|
||||
i:Integer;
|
||||
begin
|
||||
spin_lock(pad_lock);
|
||||
For i:=Low(pad_opened) to High(pad_opened) do
|
||||
if (pad_opened[i]=nil) then
|
||||
begin
|
||||
pad_opened[i]:=handle;
|
||||
Break;
|
||||
end;
|
||||
spin_unlock(pad_lock);
|
||||
end;
|
||||
|
||||
Procedure ClearPadHandle(handle:TScePadHandle);
|
||||
var
|
||||
i:Integer;
|
||||
begin
|
||||
spin_lock(pad_lock);
|
||||
For i:=Low(pad_opened) to High(pad_opened) do
|
||||
if (pad_opened[i]=handle) then
|
||||
begin
|
||||
pad_opened[i]:=nil;
|
||||
Break;
|
||||
end;
|
||||
spin_unlock(pad_lock);
|
||||
end;
|
||||
|
||||
function TScePadHandle.ReadState(data:PScePadData):Integer;
|
||||
begin
|
||||
Result:=SCE_PAD_ERROR_INVALID_HANDLE;
|
||||
end;
|
||||
|
||||
function TScePadHandle.SetLightBar(data:pScePadLightBarParam):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function TScePadHandle.ResetLightBar():Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
destructor TScePadHandle.Destroy;
|
||||
begin
|
||||
ClearPadHandle(Self);
|
||||
//
|
||||
inherited;
|
||||
end;
|
||||
|
||||
class function TScePadInterface.Load:Boolean;
|
||||
begin
|
||||
Result:=True;
|
||||
end;
|
||||
|
||||
class procedure TScePadInterface.Unload;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
|
||||
class function TScePadInterface.Init:Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
class function TScePadInterface.Done:Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
class function TScePadInterface.Open(var handle:TScePadHandle):Integer;
|
||||
begin
|
||||
handle:=nil;
|
||||
Result:=SCE_PAD_ERROR_NOT_INITIALIZED;
|
||||
end;
|
||||
|
||||
initialization
|
||||
pad_handles:=TIntegerHandles.Create(1);
|
||||
pad_handles.max_key:=16;
|
||||
|
||||
end.
|
||||
|
||||
|
|
@ -0,0 +1,295 @@
|
|||
unit sce_pad_types;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
SCE_PAD_ERROR_INVALID_ARG =-2137915391; // 0x80920001
|
||||
SCE_PAD_ERROR_INVALID_PORT =-2137915390; // 0x80920002
|
||||
SCE_PAD_ERROR_INVALID_HANDLE =-2137915389; // 0x80920003
|
||||
SCE_PAD_ERROR_ALREADY_OPENED =-2137915388; // 0x80920004
|
||||
SCE_PAD_ERROR_NOT_INITIALIZED =-2137915387; // 0x80920005
|
||||
SCE_PAD_ERROR_INVALID_LIGHTBAR_SETTING=-2137915386; // 0x80920006
|
||||
SCE_PAD_ERROR_DEVICE_NOT_CONNECTED =-2137915385; // 0x80920007
|
||||
SCE_PAD_ERROR_NO_HANDLE =-2137915384; // 0x80920008
|
||||
SCE_PAD_ERROR_FATAL =-2137915137; // 0x809200FF
|
||||
|
||||
//ScePadButtonDataOffset
|
||||
SCE_PAD_BUTTON_L3 = $00000002;
|
||||
SCE_PAD_BUTTON_R3 = $00000004;
|
||||
SCE_PAD_BUTTON_OPTIONS = $00000008;
|
||||
SCE_PAD_BUTTON_UP = $00000010;
|
||||
SCE_PAD_BUTTON_RIGHT = $00000020;
|
||||
SCE_PAD_BUTTON_DOWN = $00000040;
|
||||
SCE_PAD_BUTTON_LEFT = $00000080;
|
||||
SCE_PAD_BUTTON_L2 = $00000100;
|
||||
SCE_PAD_BUTTON_R2 = $00000200;
|
||||
SCE_PAD_BUTTON_L1 = $00000400;
|
||||
SCE_PAD_BUTTON_R1 = $00000800;
|
||||
SCE_PAD_BUTTON_TRIANGLE = $00001000;
|
||||
SCE_PAD_BUTTON_CIRCLE = $00002000;
|
||||
SCE_PAD_BUTTON_CROSS = $00004000;
|
||||
SCE_PAD_BUTTON_SQUARE = $00008000;
|
||||
SCE_PAD_BUTTON_TOUCH_PAD = $00100000;
|
||||
SCE_PAD_BUTTON_INTERCEPTED = $80000000;
|
||||
|
||||
// This definietion is alias for support old style.
|
||||
SCE_PAD_BUTTON_START=SCE_PAD_BUTTON_OPTIONS;
|
||||
|
||||
//Maximum number of touch points.
|
||||
SCE_PAD_MAX_TOUCH_NUM=2;
|
||||
|
||||
//device unique data size
|
||||
SCE_PAD_MAX_DEVICE_UNIQUE_DATA_SIZE=12;
|
||||
|
||||
SCE_PAD_CONNECTION_TYPE_LOCAL =0;
|
||||
SCE_PAD_CONNECTION_TYPE_REMOTE =1;
|
||||
SCE_PAD_CONNECTION_TYPE_REMOTE_VITA =SCE_PAD_CONNECTION_TYPE_REMOTE;
|
||||
SCE_PAD_CONNECTION_TYPE_REMOTE_DUALSHOCK4=2;
|
||||
|
||||
//ScePadDeviceClass
|
||||
SCE_PAD_DEVICE_CLASS_INVALID = -1;
|
||||
SCE_PAD_DEVICE_CLASS_STANDARD = 0;
|
||||
SCE_PAD_DEVICE_CLASS_GUITAR = 1;
|
||||
SCE_PAD_DEVICE_CLASS_DRUM = 2;
|
||||
SCE_PAD_DEVICE_CLASS_DJ_TURNTABLE = 3;
|
||||
SCE_PAD_DEVICE_CLASS_DANCEMAT = 4;
|
||||
SCE_PAD_DEVICE_CLASS_NAVIGATION = 5;
|
||||
SCE_PAD_DEVICE_CLASS_STEERING_WHEEL = 6;
|
||||
SCE_PAD_DEVICE_CLASS_STICK = 7;
|
||||
SCE_PAD_DEVICE_CLASS_FLIGHT_STICK = 8;
|
||||
SCE_PAD_DEVICE_CLASS_GUN = 9;
|
||||
|
||||
// Personal user
|
||||
SCE_PAD_PORT_TYPE_STANDARD=0; // for standard controller
|
||||
SCE_PAD_PORT_TYPE_SPECIAL =2; // for special controller
|
||||
|
||||
//SYSTEM user(SCE_USER_SERVICE_USER_ID_SYSTEM)
|
||||
SCE_PAD_PORT_TYPE_REMOTE_CONTROL=16; // for remote control(CEC remote control)
|
||||
|
||||
type
|
||||
Tvec_float3=packed record
|
||||
x,y,z:Single;
|
||||
end;
|
||||
|
||||
Tvec_float4=packed record
|
||||
x,y,z,w:Single;
|
||||
end;
|
||||
|
||||
ScePadAnalogStick=packed record
|
||||
x,y:Byte;
|
||||
end;
|
||||
|
||||
ScePadAnalogButtons=packed record
|
||||
l2,r2:Byte;
|
||||
padding:Word;
|
||||
end;
|
||||
|
||||
ScePadTouch=packed record
|
||||
x:Word;
|
||||
y:Word;
|
||||
id:Byte;
|
||||
reserve:array[0..2] of Byte;
|
||||
end;
|
||||
|
||||
ScePadTouchData=packed record
|
||||
touchNum:Byte;
|
||||
reserve:array[0..2] of Byte;
|
||||
reserve1:DWORD;
|
||||
touch:array[0..SCE_PAD_MAX_TOUCH_NUM-1] of ScePadTouch;
|
||||
end;
|
||||
|
||||
ScePadExtensionUnitData=packed record
|
||||
extensionUnitId:DWORD;
|
||||
reserve:Byte;
|
||||
dataLength:Byte;
|
||||
data:array[0..9] of Byte;
|
||||
end;
|
||||
|
||||
PScePadData=^ScePadData;
|
||||
ScePadData=packed record
|
||||
buttons :DWORD;
|
||||
leftStick :ScePadAnalogStick;
|
||||
rightStick :ScePadAnalogStick;
|
||||
analogButtons :ScePadAnalogButtons;
|
||||
orientation :Tvec_float4;
|
||||
acceleration :Tvec_float3;
|
||||
angularVelocity :Tvec_float3;
|
||||
touchData :ScePadTouchData;
|
||||
connected :Boolean;
|
||||
_align:array[0..2] of Byte;
|
||||
timestamp :QWORD;
|
||||
extensionUnitData:ScePadExtensionUnitData;
|
||||
connectedCount :Byte;
|
||||
reserve:array[0..1] of Byte;
|
||||
deviceUniqueDataLen:Byte;
|
||||
deviceUniqueData:array[0..SCE_PAD_MAX_DEVICE_UNIQUE_DATA_SIZE-1] of Byte;
|
||||
end;
|
||||
|
||||
ScePadOpenParam=packed record
|
||||
reserve:array[0..7] of Byte;
|
||||
end;
|
||||
|
||||
TPadColor=packed record
|
||||
r,g,b,a:Byte;
|
||||
end;
|
||||
|
||||
PScePadVibrationParam=^ScePadVibrationParam;
|
||||
ScePadVibrationParam=packed record
|
||||
largeMotor:Byte;
|
||||
smallMotor:Byte;
|
||||
end;
|
||||
|
||||
ScePadColor=packed record
|
||||
r:Byte;
|
||||
g:Byte;
|
||||
b:Byte;
|
||||
reserve:Byte;
|
||||
end;
|
||||
|
||||
ScePadLightBarParam=ScePadColor;
|
||||
PScePadLightBarParam=^ScePadLightBarParam;
|
||||
|
||||
ScePadTouchPadInformation=packed record
|
||||
pixelDensity:Single;
|
||||
resolution:packed record
|
||||
x,y:Word;
|
||||
end;
|
||||
end;
|
||||
|
||||
ScePadStickInformation=packed record
|
||||
deadZoneLeft :Byte;
|
||||
deadZoneRight:Byte;
|
||||
end;
|
||||
|
||||
PScePadControllerInformation=^ScePadControllerInformation;
|
||||
ScePadControllerInformation=packed record
|
||||
touchPadInfo:ScePadTouchPadInformation;
|
||||
stickInfo:ScePadStickInformation;
|
||||
connectionType:Byte;
|
||||
connectedCount:Byte;
|
||||
connected:Boolean;
|
||||
_align:array[0..2] of Byte;
|
||||
deviceClass:DWORD; //ScePadDeviceClass
|
||||
reserve:array[0..7] of Byte;
|
||||
end;
|
||||
|
||||
pScePadExtControllerInformation=^ScePadExtControllerInformation;
|
||||
ScePadExtControllerInformation=packed record
|
||||
base:ScePadControllerInformation;
|
||||
pad_type1:Word;
|
||||
pad_type2:Word;
|
||||
capability:Byte;
|
||||
case byte of
|
||||
0:(quantityOfSelectorSwitch:Byte);
|
||||
1:(maxPhysicalWheelAngle:Integer);
|
||||
2:(data:array[0..7] of Byte);
|
||||
end;
|
||||
|
||||
pScePadDeviceClassExtendedInformation=^ScePadDeviceClassExtendedInformation;
|
||||
ScePadDeviceClassExtendedInformation=packed record
|
||||
deviceClass:DWORD; //ScePadDeviceClass
|
||||
reserved:DWORD;
|
||||
classData:packed record
|
||||
Case Byte of
|
||||
|
||||
0:(steeringWheel:packed record
|
||||
capability:Byte;
|
||||
reserved1:Byte;
|
||||
maxPhysicalWheelAngle:Word;
|
||||
reserved2:QWORD;
|
||||
end);
|
||||
|
||||
1:(guitar:packed record
|
||||
capability:Byte;
|
||||
quantityOfSelectorSwitch:Byte;
|
||||
reserved1:Word;
|
||||
reserved2:QWORD;
|
||||
end);
|
||||
|
||||
2:(drum:packed record
|
||||
capability:Byte;
|
||||
reserved1:Byte;
|
||||
reserved2:Word;
|
||||
reserved3:QWORD;
|
||||
end);
|
||||
|
||||
3:(flightStick:packed record
|
||||
capability:Byte;
|
||||
reserved1:Byte;
|
||||
reserved2:Word;
|
||||
reserved3:QWORD;
|
||||
end);
|
||||
|
||||
4:(data:array[0..11] of Byte);
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
pScePadDeviceClassData=^ScePadDeviceClassData;
|
||||
ScePadDeviceClassData=packed record
|
||||
deviceClass:DWORD; //ScePadDeviceClass
|
||||
bDataValid :Boolean;
|
||||
_align:array[0..2] of Byte;
|
||||
classData:packed record
|
||||
Case Byte of
|
||||
|
||||
0:(steeringWheel:packed record
|
||||
steeringWheelAngle:Single;
|
||||
steeringWheel :Word;
|
||||
acceleratorPedal :Word;
|
||||
brakePedal :Word;
|
||||
clutchPedal :Word;
|
||||
handBlake :Word;
|
||||
gear :Byte;
|
||||
reserved :Byte;
|
||||
end); //SCE_PAD_DEVICE_CLASS_STEERING_WHEEL
|
||||
|
||||
1:(guitar:packed record
|
||||
toneNumber:Byte;
|
||||
whammyBar :Byte;
|
||||
tilt :Byte;
|
||||
fret :Byte;
|
||||
fretSolo :Byte;
|
||||
reserved:array[0..10] of Byte;
|
||||
end); //SCE_PAD_DEVICE_CLASS_GUITAR
|
||||
|
||||
2:(drum:packed record
|
||||
snare :Byte;
|
||||
tom1 :Byte;
|
||||
tom2 :Byte;
|
||||
floorTom :Byte;
|
||||
hihatCymbal:Byte;
|
||||
rideCymbal :Byte;
|
||||
crashCymbal:Byte;
|
||||
reserved:array[0..8] of Byte;
|
||||
end); //SCE_PAD_DEVICE_CLASS_DRUM
|
||||
|
||||
3:(flightStick:packed record
|
||||
stickAxisX :Word;
|
||||
stickAxisY :Word;
|
||||
stickTwist :Byte;
|
||||
throttle :Byte;
|
||||
trigger :Byte;
|
||||
rudderPedal :Byte;
|
||||
brakePedalLeft :Byte;
|
||||
brakePedalRight:Byte;
|
||||
antennaKnob :Byte;
|
||||
rangeKnob :Byte;
|
||||
reserved:array[0..3] of Byte;
|
||||
end); //SCE_PAD_DEVICE_CLASS_FLIGHT_STICK
|
||||
|
||||
4:(others:packed record
|
||||
dataLen:Byte;
|
||||
reserved:array[0..2] of Byte;
|
||||
data:array[0..SCE_PAD_MAX_DEVICE_UNIQUE_DATA_SIZE-1] of Byte;
|
||||
end); //Not Supported device
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
|
|
@ -0,0 +1,391 @@
|
|||
unit sdl2_pad_interface;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
sysutils,
|
||||
spinlock,
|
||||
sdl2,
|
||||
sce_pad_types,
|
||||
sce_pad_interface,
|
||||
kbm_pad_interface;
|
||||
|
||||
type
|
||||
TSdl2PadHandle=class(TScePadHandle)
|
||||
var
|
||||
connectedCount:Integer;
|
||||
game_controller:PSDL_GameController;
|
||||
LED:ScePadLightBarParam;
|
||||
function SetLightBar(data:pScePadLightBarParam):Integer; override;
|
||||
function ResetLightBar():Integer; override;
|
||||
function ReadState(data:PScePadData):Integer; override;
|
||||
end;
|
||||
|
||||
TSdl2PadInterface=class(TScePadInterface)
|
||||
class var
|
||||
sdl2_init:Boolean;
|
||||
class function Load:Boolean; override;
|
||||
class procedure Unload; override;
|
||||
class function Init:Integer; override;
|
||||
class function Done:Integer; override;
|
||||
class function Open(var handle:TScePadHandle):Integer; override;
|
||||
class function FindOpened(device_index:Integer;prev:PSDL_GameController):Boolean;
|
||||
class function FindDevice(prev:PSDL_GameController):PSDL_GameController;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
class function TSdl2PadInterface.Load:Boolean;
|
||||
var
|
||||
i:Integer;
|
||||
begin
|
||||
if sdl2_init then Exit(True);
|
||||
|
||||
i:=SDL_InitSubSystem(SDL_INIT_JOYSTICK or SDL_INIT_GAMECONTROLLER);
|
||||
sdl2_init:=(i=0);
|
||||
|
||||
if sdl2_init then
|
||||
begin
|
||||
Writeln('SDL2 Game-Controller subsystem initialized!');
|
||||
end else
|
||||
begin
|
||||
Writeln('SDL2 Game-Controller not initialized!');
|
||||
end;
|
||||
|
||||
Result:=sdl2_init;
|
||||
end;
|
||||
|
||||
class procedure TSdl2PadInterface.Unload;
|
||||
begin
|
||||
if not sdl2_init then Exit;
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK or SDL_INIT_GAMECONTROLLER);
|
||||
sdl2_init:=False;
|
||||
Writeln('SDL2 Game-Controller subsystem quit!');
|
||||
end;
|
||||
|
||||
class function TSdl2PadInterface.Init:Integer;
|
||||
begin
|
||||
if (sdl2_init) then
|
||||
begin
|
||||
Result:=0;
|
||||
end else
|
||||
begin
|
||||
Result:=SCE_PAD_ERROR_NOT_INITIALIZED;
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TSdl2PadInterface.Done:Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function Compare(g1,g2:TSDL_JoystickGUID):Boolean; inline;
|
||||
begin
|
||||
Result:=CompareByte(g1,g2,SizeOf(TSDL_JoystickGUID))=0;
|
||||
end;
|
||||
|
||||
function Compare(g1,g2:PSDL_GameController):Boolean;
|
||||
begin
|
||||
Result:=Compare(SDL_JoystickGetGUID(SDL_GameControllerGetJoystick(g1)),
|
||||
SDL_JoystickGetGUID(SDL_GameControllerGetJoystick(g2))
|
||||
);
|
||||
end;
|
||||
|
||||
function Compare(device_index:Integer;g2:PSDL_GameController):Boolean;
|
||||
begin
|
||||
Result:=Compare(SDL_JoystickGetDeviceGUID(device_index),
|
||||
SDL_JoystickGetGUID(SDL_GameControllerGetJoystick(g2))
|
||||
);
|
||||
end;
|
||||
|
||||
class function TSdl2PadInterface.FindOpened(device_index:Integer;prev:PSDL_GameController):Boolean;
|
||||
var
|
||||
i:Integer;
|
||||
h:TSdl2PadHandle;
|
||||
begin
|
||||
Result:=False;
|
||||
spin_lock(pad_lock);
|
||||
For i:=0 to 15 do
|
||||
if (pad_opened[i]<>nil) then
|
||||
if (pad_opened[i].InheritsFrom(TSdl2PadHandle)) then
|
||||
begin
|
||||
h:=TSdl2PadHandle(pad_opened[i]);
|
||||
if (h.game_controller<>nil) then
|
||||
if (h.game_controller<>prev) then
|
||||
begin
|
||||
Result:=Compare(device_index,h.game_controller);
|
||||
if Result then Break;
|
||||
end;
|
||||
end;
|
||||
spin_unlock(pad_lock);
|
||||
end;
|
||||
|
||||
class function TSdl2PadInterface.FindDevice(prev:PSDL_GameController):PSDL_GameController;
|
||||
var
|
||||
i,c:Integer;
|
||||
first,compared:Integer;
|
||||
begin
|
||||
Result:=nil;
|
||||
first:=-1;
|
||||
compared:=-1;
|
||||
SDL_LockJoysticks;
|
||||
c:=SDL_NumJoysticks();
|
||||
if (c<>0) then
|
||||
For i:=0 to c-1 do
|
||||
if SDL_IsGameController(i) then
|
||||
if not FindOpened(i,prev) then
|
||||
begin
|
||||
if (first=-1) then first:=i;
|
||||
if (prev=nil) then
|
||||
begin
|
||||
compared:=i;
|
||||
Break;
|
||||
end else
|
||||
if Compare(i,prev) then
|
||||
begin
|
||||
compared:=i;
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
//
|
||||
if (compared=-1) then compared:=first;
|
||||
if (compared<>-1) then
|
||||
begin
|
||||
Result:=SDL_GameControllerOpen(compared);
|
||||
end;
|
||||
SDL_UnlockJoysticks;
|
||||
end;
|
||||
|
||||
class function TSdl2PadInterface.Open(var handle:TScePadHandle):Integer;
|
||||
var
|
||||
game_controller:PSDL_GameController;
|
||||
begin
|
||||
Result:=0;
|
||||
if not sdl2_init then Exit(SCE_PAD_ERROR_NOT_INITIALIZED);
|
||||
|
||||
game_controller:=FindDevice(nil);
|
||||
|
||||
handle:=TSdl2PadHandle.Create;
|
||||
TSdl2PadHandle(handle).game_controller:=game_controller;
|
||||
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('SDL2: Game Controller loaded!');
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('Controller Name: ', SDL_GameControllerName(game_controller));
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('USB Vendor ID: ', SDL_GameControllerGetVendor(game_controller));
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('USB Product ID: ', SDL_GameControllerGetProduct(game_controller));
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('Product Version: ', SDL_GameControllerGetProductVersion(game_controller));
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('Firmware Version: ', SDL_GameControllerGetFirmwareVersion(game_controller));
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('Serial Number: ', SDL_GameControllerGetSerial(game_controller));
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('Controller Path: ', SDL_GameControllerPath(game_controller));
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
|
||||
|
||||
Writeln('Controller GUID: ', GUIDToString(TGUID(SDL_JoystickGetGUID(SDL_GameControllerGetJoystick(game_controller)))));
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
|
||||
|
||||
Writeln('Modifiable LED: ', SDL_GameControllerHasLED(game_controller));
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('Modifiable Rumble: ', SDL_GameControllerHasRumble(game_controller));
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
Writeln('----------------------------------------------------------------------------------------');
|
||||
end;
|
||||
|
||||
function AxisToAnalog(i:Integer):Byte;
|
||||
begin
|
||||
if (i>0) then
|
||||
begin
|
||||
i:=(i*127) div 32767;
|
||||
end else
|
||||
begin
|
||||
i:=(i*128) div 32768;
|
||||
end;
|
||||
Result:=Byte(i+128);
|
||||
end;
|
||||
|
||||
function AxisToTrigger(i:Integer):Byte;
|
||||
begin
|
||||
Result:=Byte((abs(i)*255) div 32767);
|
||||
end;
|
||||
|
||||
function TSdl2PadHandle.SetLightBar(data:pScePadLightBarParam):Integer;
|
||||
begin
|
||||
LED:=data^;
|
||||
if (game_controller<>nil) then
|
||||
begin
|
||||
SDL_GameControllerSetLED(game_controller, LED.r, LED.g, LED.b);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSdl2PadHandle.ResetLightBar():Integer;
|
||||
begin
|
||||
LED:=Default(ScePadLightBarParam);
|
||||
if (game_controller<>nil) then
|
||||
begin
|
||||
SDL_GameControllerSetLED(game_controller, LED.r, LED.g, LED.b);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSdl2PadHandle.ReadState(data:PScePadData):Integer;
|
||||
var
|
||||
i,f,t,n:Integer;
|
||||
x,y,pressure:Single;
|
||||
state:Byte;
|
||||
new:PSDL_GameController;
|
||||
event:TSDL_Event;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
//loop events
|
||||
while (SDL_PollEvent(@event)<>0) do;
|
||||
|
||||
if not SDL_GameControllerGetAttached(game_controller) then
|
||||
begin
|
||||
new:=TSdl2PadInterface.FindDevice(game_controller);
|
||||
if (new=nil) then
|
||||
begin
|
||||
data^.connected:=False;
|
||||
data^.connectedCount:=Byte(connectedCount);
|
||||
Exit(0);
|
||||
end else
|
||||
begin
|
||||
Writeln('Reconnect:',index);
|
||||
SDL_GameControllerClose(game_controller);
|
||||
game_controller:=new;
|
||||
Inc(connectedCount);
|
||||
//
|
||||
SDL_GameControllerSetLED(game_controller, LED.r, LED.g, LED.b);
|
||||
end;
|
||||
end;
|
||||
|
||||
data^.connected:=True;
|
||||
data^.connectedCount:=Byte(connectedCount);
|
||||
|
||||
t:=SDL_GameControllerGetNumTouchpads(game_controller);
|
||||
|
||||
if (t=0) then
|
||||
begin
|
||||
//no touchpad? use mouse
|
||||
TMouseAsTouchpad.ReadState(data);
|
||||
end else
|
||||
begin
|
||||
//use ony first touchpad
|
||||
f:=SDL_GameControllerGetNumTouchpadFingers(game_controller,0);
|
||||
|
||||
n:=0;
|
||||
data^.touchData.touchNum:=0;
|
||||
|
||||
if (f<>0) then
|
||||
For i:=0 to f-1 do
|
||||
begin
|
||||
|
||||
if SDL_GameControllerGetTouchpadFinger(
|
||||
game_controller,
|
||||
0,i,
|
||||
@state,
|
||||
@x,@y,@pressure)=0 then
|
||||
begin
|
||||
|
||||
if (x>1919) then x:=1919;
|
||||
if (y>941) then y:=941;
|
||||
|
||||
data^.touchData.touch[n].id:=n;
|
||||
data^.touchData.touch[n].x :=Word(Trunc(x));
|
||||
data^.touchData.touch[n].y :=Word(Trunc(y));
|
||||
|
||||
Inc(n);
|
||||
data^.touchData.touchNum:=n;
|
||||
|
||||
if (n=SCE_PAD_MAX_TOUCH_NUM) then Break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
//Options and Touchpad
|
||||
if SDL_GameControllerGetButton(game_controller, SDL_CONTROLLER_BUTTON_START) = 1 then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_OPTIONS;
|
||||
|
||||
if SDL_GameControllerGetButton(game_controller, SDL_CONTROLLER_BUTTON_TOUCHPAD) = 1 then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_TOUCH_PAD;
|
||||
|
||||
//Hats(D-PAD)
|
||||
if SDL_GameControllerGetButton(game_controller, SDL_CONTROLLER_BUTTON_DPAD_UP) = 1 then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_UP;
|
||||
if SDL_GameControllerGetButton(game_controller, SDL_CONTROLLER_BUTTON_DPAD_DOWN) = 1 then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_DOWN;
|
||||
if SDL_GameControllerGetButton(game_controller, SDL_CONTROLLER_BUTTON_DPAD_LEFT) = 1 then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_LEFT;
|
||||
if SDL_GameControllerGetButton(game_controller, SDL_CONTROLLER_BUTTON_DPAD_RIGHT) = 1 then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_RIGHT;
|
||||
|
||||
//Cross, Circle, Square and Triangle
|
||||
if SDL_GameControllerGetButton(game_controller, SDL_CONTROLLER_BUTTON_A) = 1 then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_CROSS;
|
||||
if SDL_GameControllerGetButton(game_controller, SDL_CONTROLLER_BUTTON_B) = 1 then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_CIRCLE;
|
||||
if SDL_GameControllerGetButton(game_controller, SDL_CONTROLLER_BUTTON_X) = 1 then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_SQUARE;
|
||||
if SDL_GameControllerGetButton(game_controller, SDL_CONTROLLER_BUTTON_Y) = 1 then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_TRIANGLE;
|
||||
|
||||
//L1, R1 and L3, R3
|
||||
if SDL_GameControllerGetButton(game_controller, SDL_CONTROLLER_BUTTON_LEFTSHOULDER) = 1 then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_L1;
|
||||
if SDL_GameControllerGetButton(game_controller, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER) = 1 then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_R1;
|
||||
|
||||
if SDL_GameControllerGetButton(game_controller, SDL_CONTROLLER_BUTTON_LEFTSTICK) = 1 then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_L3;
|
||||
if SDL_GameControllerGetButton(game_controller, SDL_CONTROLLER_BUTTON_RIGHTSTICK) = 1 then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_R3;
|
||||
|
||||
//Left and Right Axes
|
||||
data^.leftStick.x:=AxisToAnalog(SDL_GameControllerGetAxis(game_controller, SDL_CONTROLLER_AXIS_LEFTX));
|
||||
data^.leftStick.y:=AxisToAnalog(SDL_GameControllerGetAxis(game_controller, SDL_CONTROLLER_AXIS_LEFTY));
|
||||
|
||||
data^.rightStick.x:=AxisToAnalog(SDL_GameControllerGetAxis(game_controller, SDL_CONTROLLER_AXIS_RIGHTX));
|
||||
data^.rightStick.y:=AxisToAnalog(SDL_GameControllerGetAxis(game_controller, SDL_CONTROLLER_AXIS_RIGHTY));
|
||||
|
||||
//Left and Right Triggers (L2 and R2)
|
||||
data^.analogButtons.l2:=AxisToTrigger(SDL_GameControllerGetAxis(game_controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT ));
|
||||
data^.analogButtons.r2:=AxisToTrigger(SDL_GameControllerGetAxis(game_controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT));
|
||||
|
||||
//Approx L2
|
||||
if (data^.analogButtons.l2>1) then
|
||||
begin
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_L2;
|
||||
end;
|
||||
|
||||
//Approx R2
|
||||
if (data^.analogButtons.r2>1) then
|
||||
begin
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_R2;
|
||||
end;
|
||||
end;
|
||||
|
||||
finalization
|
||||
TSdl2PadInterface.Unload;
|
||||
|
||||
end.
|
||||
|
|
@ -172,8 +172,8 @@ begin
|
|||
xiRJoyRight: Result := Max(s.Gamepad.sThumbRX, 0) * outOfDeadzoneR / 32767.0;
|
||||
xiRJoyLeft : Result := Min(s.Gamepad.sThumbRX, 0) * outOfDeadzoneR / 32767.0;
|
||||
|
||||
xiL2: Result := IfThen(s.Gamepad.bLeftTrigger > XInputDeadzoneTrigger, s.Gamepad.bLeftTrigger / 255.0, 0);
|
||||
xiR2: Result := IfThen(s.Gamepad.bRightTrigger > XInputDeadzoneTrigger, s.Gamepad.bLeftTrigger / 255.0, 0);
|
||||
xiL2: Result := IfThen(s.Gamepad.bLeftTrigger > XInputDeadzoneTrigger, s.Gamepad.bLeftTrigger / 255.0, 0);
|
||||
xiR2: Result := IfThen(s.Gamepad.bRightTrigger > XInputDeadzoneTrigger, s.Gamepad.bRightTrigger / 255.0, 0);
|
||||
else Result := 0;
|
||||
end;
|
||||
|
||||
|
@ -202,9 +202,9 @@ begin
|
|||
if not FileExists(filePath) then exit;
|
||||
|
||||
iniFile := TIniFile.Create(filePath);
|
||||
Self.XInputEnabled := iniFile.ReadBool('XInput', 'XInputEnabled', True);
|
||||
Self.XInputDeadzoneLeft := iniFile.ReadInteger('XInput', 'XInputDeadzoneLeft', XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
|
||||
Self.XInputDeadzoneRight := iniFile.ReadInteger('XInput', 'XInputDeadzoneRight', XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE);
|
||||
Self.XInputEnabled := iniFile.ReadBool ('XInput', 'XInputEnabled' , True);
|
||||
Self.XInputDeadzoneLeft := iniFile.ReadInteger('XInput', 'XInputDeadzoneLeft' , XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
|
||||
Self.XInputDeadzoneRight := iniFile.ReadInteger('XInput', 'XInputDeadzoneRight' , XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE);
|
||||
Self.XInputDeadzoneTrigger := iniFile.ReadInteger('XInput', 'XInputDeadzoneTrigger', XINPUT_GAMEPAD_TRIGGER_THRESHOLD);
|
||||
for i := 1 to NUM_PS4_BUTTONS do
|
||||
begin
|
||||
|
@ -225,9 +225,9 @@ begin
|
|||
Result := False;
|
||||
|
||||
iniFile := TIniFile.Create(filePath);
|
||||
iniFile.WriteBool('XInput', 'XInputEnabled', Self.XInputEnabled);
|
||||
iniFile.WriteInteger('XInput', 'XInputDeadzoneLeft', Self.XInputDeadzoneLeft);
|
||||
iniFile.WriteInteger('XInput', 'XInputDeadzoneRight', Self.XInputDeadzoneRight);
|
||||
iniFile.WriteBool ('XInput', 'XInputEnabled' , Self.XInputEnabled);
|
||||
iniFile.WriteInteger('XInput', 'XInputDeadzoneLeft' , Self.XInputDeadzoneLeft);
|
||||
iniFile.WriteInteger('XInput', 'XInputDeadzoneRight' , Self.XInputDeadzoneRight);
|
||||
iniFile.WriteInteger('XInput', 'XInputDeadzoneTrigger', Self.XInputDeadzoneTrigger);
|
||||
for i := 1 to NUM_PS4_BUTTONS do
|
||||
begin
|
||||
|
@ -242,14 +242,14 @@ end;
|
|||
function TMappableInputs.XInputIsTriggered(input: EnumXInputButtons; state: TXInputState): boolean;
|
||||
begin
|
||||
case (input) of
|
||||
xiLJoyUp: Result := state.Gamepad.sThumbLY > self.XInputDeadzoneLeft;
|
||||
xiLJoyDown: Result := state.Gamepad.sThumbLY < -self.XInputDeadzoneLeft;
|
||||
xiLJoyLeft: Result := state.Gamepad.sThumbLX < -self.XInputDeadzoneLeft;
|
||||
xiLJoyUp : Result := state.Gamepad.sThumbLY > self.XInputDeadzoneLeft;
|
||||
xiLJoyDown : Result := state.Gamepad.sThumbLY < -self.XInputDeadzoneLeft;
|
||||
xiLJoyLeft : Result := state.Gamepad.sThumbLX < -self.XInputDeadzoneLeft;
|
||||
xiLJoyRight: Result := state.Gamepad.sThumbLX > self.XInputDeadzoneLeft;
|
||||
|
||||
xiRJoyUp: Result := state.Gamepad.sThumbRY > self.XInputDeadzoneRight;
|
||||
xiRJoyDown: Result := state.Gamepad.sThumbRY < -self.XInputDeadzoneRight;
|
||||
xiRJoyLeft: Result := state.Gamepad.sThumbRX < -self.XInputDeadzoneRight;
|
||||
xiRJoyUp : Result := state.Gamepad.sThumbRY > self.XInputDeadzoneRight;
|
||||
xiRJoyDown : Result := state.Gamepad.sThumbRY < -self.XInputDeadzoneRight;
|
||||
xiRJoyLeft : Result := state.Gamepad.sThumbRX < -self.XInputDeadzoneRight;
|
||||
xiRJoyRight: Result := state.Gamepad.sThumbRX > self.XInputDeadzoneRight;
|
||||
|
||||
xiA: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_A) <> 0;
|
||||
|
@ -257,14 +257,14 @@ begin
|
|||
xiX: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_X) <> 0;
|
||||
xiY: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_Y) <> 0;
|
||||
|
||||
xiDPadUp: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_UP) <> 0;
|
||||
xiDPadDown: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_DOWN) <> 0;
|
||||
xiDPadLeft: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_LEFT) <> 0;
|
||||
xiDPadUp : Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_UP) <> 0;
|
||||
xiDPadDown : Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_DOWN) <> 0;
|
||||
xiDPadLeft : Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_LEFT) <> 0;
|
||||
xiDPadRight: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_RIGHT) <> 0;
|
||||
|
||||
xiSelect: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_BACK) <> 0;
|
||||
xiGuide: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_GUIDE) <> 0;
|
||||
xiStart: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_START) <> 0;
|
||||
xiGuide : Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_GUIDE) <> 0;
|
||||
xiStart : Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_START) <> 0;
|
||||
|
||||
xiL1: Result := (state.Gamepad.wButtons and XINPUT_GAMEPAD_LEFT_SHOULDER) <> 0;
|
||||
xiL2: Result := state.Gamepad.bLeftTrigger > self.XInputDeadzoneTrigger;
|
||||
|
@ -280,20 +280,20 @@ initialization
|
|||
|
||||
MappableInputs := TMappableInputs.Create;
|
||||
|
||||
MappableInputs.XInputButtonsNames[Ord(xiUnbound)] := 'Unbound';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiLJoyUp)] := 'LJOY_UP';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiLJoyDown)] := 'LJOY_DOWN';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiLJoyLeft)] := 'LJOY_LEFT';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiUnbound )] := 'Unbound';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiLJoyUp )] := 'LJOY_UP';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiLJoyDown )] := 'LJOY_DOWN';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiLJoyLeft )] := 'LJOY_LEFT';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiLJoyRight)] := 'LJOY_RIGHT';
|
||||
|
||||
MappableInputs.XInputButtonsNames[Ord(xiRJoyUp)] := 'RJOY_UP';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiRJoyDown)] := 'RJOY_DOWN';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiRJoyLeft)] := 'RJOY_LEFT';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiRJoyUp )] := 'RJOY_UP';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiRJoyDown )] := 'RJOY_DOWN';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiRJoyLeft )] := 'RJOY_LEFT';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiRJoyRight)] := 'RJOY_RIGHT';
|
||||
|
||||
MappableInputs.XInputButtonsNames[Ord(xiDPadUp)] := 'DPAD_UP';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiDPadDown)] := 'DPAD_DOWN';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiDPadLeft)] := 'DPAD_LEFT';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiDPadUp )] := 'DPAD_UP';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiDPadDown )] := 'DPAD_DOWN';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiDPadLeft )] := 'DPAD_LEFT';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiDPadRight)] := 'DPAD_RIGHT';
|
||||
|
||||
MappableInputs.XInputButtonsNames[Ord(xiA)] := 'A';
|
||||
|
@ -302,8 +302,8 @@ initialization
|
|||
MappableInputs.XInputButtonsNames[Ord(xiY)] := 'Y';
|
||||
|
||||
MappableInputs.XInputButtonsNames[Ord(xiSelect)] := 'SELECT';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiGuide)] := 'GUIDE';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiStart)] := 'START';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiGuide )] := 'GUIDE';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiStart )] := 'START';
|
||||
|
||||
MappableInputs.XInputButtonsNames[Ord(xiL1)] := 'L1';
|
||||
MappableInputs.XInputButtonsNames[Ord(xiL2)] := 'L2';
|
||||
|
@ -315,35 +315,37 @@ initialization
|
|||
|
||||
// Default mapping
|
||||
MappableInputs.XInputEnabled := True;
|
||||
MappableInputs.XInputDeadzoneLeft := XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE;
|
||||
MappableInputs.XInputDeadzoneRight := XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE;
|
||||
MappableInputs.XInputDeadzoneLeft := XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE;
|
||||
MappableInputs.XInputDeadzoneRight := XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE;
|
||||
MappableInputs.XInputDeadzoneTrigger := XINPUT_GAMEPAD_TRIGGER_THRESHOLD;
|
||||
MappableInputs.SetXInputMapping(miUnbound, xiUnbound);
|
||||
MappableInputs.SetXInputMapping(miLJoyUp, xiLJoyUp);
|
||||
MappableInputs.SetXInputMapping(miLJoyDown, xiLJoyDown);
|
||||
MappableInputs.SetXInputMapping(miLJoyLeft, xiLJoyLeft);
|
||||
MappableInputs.SetXInputMapping(miUnbound , xiUnbound);
|
||||
MappableInputs.SetXInputMapping(miLJoyUp , xiLJoyUp);
|
||||
MappableInputs.SetXInputMapping(miLJoyDown , xiLJoyDown);
|
||||
MappableInputs.SetXInputMapping(miLJoyLeft , xiLJoyLeft);
|
||||
MappableInputs.SetXInputMapping(miLJoyRight, xiLJoyRight);
|
||||
MappableInputs.SetXInputMapping(miRJoyUp, xiRJoyUp);
|
||||
MappableInputs.SetXInputMapping(miRJoyDown, xiRJoyDown);
|
||||
MappableInputs.SetXInputMapping(miRJoyLeft, xiRJoyLeft);
|
||||
MappableInputs.SetXInputMapping(miRJoyUp , xiRJoyUp);
|
||||
MappableInputs.SetXInputMapping(miRJoyDown , xiRJoyDown);
|
||||
MappableInputs.SetXInputMapping(miRJoyLeft , xiRJoyLeft);
|
||||
MappableInputs.SetXInputMapping(miRJoyRight, xiRJoyRight);
|
||||
MappableInputs.SetXInputMapping(miDPadUp, xiDPadUp);
|
||||
MappableInputs.SetXInputMapping(miDPadDown, xiDPadDown);
|
||||
MappableInputs.SetXInputMapping(miDPadLeft, xiDPadLeft);
|
||||
MappableInputs.SetXInputMapping(miDPadUp , xiDPadUp);
|
||||
MappableInputs.SetXInputMapping(miDPadDown , xiDPadDown);
|
||||
MappableInputs.SetXInputMapping(miDPadLeft , xiDPadLeft);
|
||||
MappableInputs.SetXInputMapping(miDPadRight, xiDPadRight);
|
||||
MappableInputs.SetXInputMapping(miCross, xiA);
|
||||
MappableInputs.SetXInputMapping(miCircle, xiB);
|
||||
MappableInputs.SetXInputMapping(miSquare, xiX);
|
||||
MappableInputs.SetXInputMapping(miTriangle, xiY);
|
||||
MappableInputs.SetXInputMapping(miShare, xiUnbound);
|
||||
MappableInputs.SetXInputMapping(miTouchPad, xiSelect);
|
||||
MappableInputs.SetXInputMapping(miOptions, xiStart);
|
||||
MappableInputs.SetXInputMapping(miL1, xiL1);
|
||||
MappableInputs.SetXInputMapping(miL2, xiL2);
|
||||
MappableInputs.SetXInputMapping(miL3, xiL3);
|
||||
MappableInputs.SetXInputMapping(miR1, xiR1);
|
||||
MappableInputs.SetXInputMapping(miR2, xiR2);
|
||||
MappableInputs.SetXInputMapping(miR3, xiR3);
|
||||
MappableInputs.SetXInputMapping(miCross , xiA);
|
||||
MappableInputs.SetXInputMapping(miCircle , xiB);
|
||||
MappableInputs.SetXInputMapping(miSquare , xiX);
|
||||
MappableInputs.SetXInputMapping(miTriangle , xiY);
|
||||
MappableInputs.SetXInputMapping(miShare , xiUnbound);
|
||||
MappableInputs.SetXInputMapping(miTouchPad , xiSelect);
|
||||
MappableInputs.SetXInputMapping(miOptions , xiStart);
|
||||
MappableInputs.SetXInputMapping(miL1 , xiL1);
|
||||
MappableInputs.SetXInputMapping(miL2 , xiL2);
|
||||
MappableInputs.SetXInputMapping(miL3 , xiL3);
|
||||
MappableInputs.SetXInputMapping(miR1 , xiR1);
|
||||
MappableInputs.SetXInputMapping(miR2 , xiR2);
|
||||
MappableInputs.SetXInputMapping(miR3 , xiR3);
|
||||
|
||||
MappableInputs.LoadFromFile(XINPUT_CONFIG_FILE);
|
||||
end.
|
||||
|
||||
|
||||
|
|
|
@ -2,11 +2,18 @@ unit XInput;
|
|||
|
||||
interface
|
||||
|
||||
uses
|
||||
dynlibs;
|
||||
|
||||
type
|
||||
BOOL = longbool;
|
||||
|
||||
const
|
||||
XINPUT_DLL = 'xinput1_3.dll';
|
||||
XINPUT_DLL:array[0..2] of PChar=(
|
||||
'XInput1_4.dll',
|
||||
'XInput1_3.dll',
|
||||
'XInput9_1_0.dll'
|
||||
);
|
||||
|
||||
// Device types available in XINPUT_CAPABILITIES
|
||||
XINPUT_DEVTYPE_GAMEPAD = $01;
|
||||
|
@ -162,44 +169,108 @@ type
|
|||
HidCode: Byte;
|
||||
end;
|
||||
|
||||
function XInputGetState(
|
||||
function XInput_Init: Integer; stdcall;
|
||||
procedure XInput_Quit; stdcall;
|
||||
|
||||
var
|
||||
XInputGetState:function(
|
||||
dwUserIndex: DWORD; // [in] Index of the gamer associated with the device
|
||||
out pState: TXInputState // [out] Receives the current state
|
||||
): DWORD; stdcall; external XINPUT_DLL;
|
||||
): DWORD; stdcall;
|
||||
|
||||
function XInputSetState(
|
||||
XInputSetState:function(
|
||||
dwUserIndex: DWORD; // [in] Index of the gamer associated with the device
|
||||
const pVibration: TXInputVibration // [in, out] The vibration information to send to the controller
|
||||
): DWORD; stdcall; external XINPUT_DLL;
|
||||
): DWORD; stdcall;
|
||||
|
||||
function XInputGetCapabilities(
|
||||
XInputGetCapabilities:function(
|
||||
dwUserIndex: DWORD; // [in] Index of the gamer associated with the device
|
||||
dwFlags: DWORD; // [in] Input flags that identify the device type
|
||||
out pCapabilities: TXInputCapabilities // [out] Receives the capabilities
|
||||
): DWORD; stdcall; external XINPUT_DLL;
|
||||
): DWORD; stdcall;
|
||||
|
||||
procedure XInputEnable(
|
||||
XInputEnable:procedure(
|
||||
enable: BOOL // [in] Indicates whether xinput is enabled or disabled.
|
||||
); stdcall; external XINPUT_DLL;
|
||||
); stdcall;
|
||||
|
||||
function XInputGetDSoundAudioDeviceGuids(
|
||||
XInputGetDSoundAudioDeviceGuids:function(
|
||||
dwUserIndex: DWORD; // [in] Index of the gamer associated with the device
|
||||
out pDSoundRenderGuid: TGUID; // [out] DSound device ID for render
|
||||
out pDSoundCaptureGuid: TGUID // [out] DSound device ID for capture
|
||||
): DWORD; stdcall; external XINPUT_DLL;
|
||||
): DWORD; stdcall;
|
||||
|
||||
function XInputGetBatteryInformation(
|
||||
XInputGetBatteryInformation:function(
|
||||
dwUserIndex: DWORD; // [in] Index of the gamer associated with the device
|
||||
devType: Byte; // [in] Which device on this user index
|
||||
out pBatteryInformation: TXInputBatteryInformation // [out] Contains the level and types of batteries
|
||||
): DWORD; stdcall; external XINPUT_DLL;
|
||||
): DWORD; stdcall;
|
||||
|
||||
function XInputGetKeystroke(
|
||||
XInputGetKeystroke:function(
|
||||
dwUserIndex: DWORD; // [in] Index of the gamer associated with the device
|
||||
dwReserved: DWORD; // [in] Reserved for future use
|
||||
var pKeystroke: TXInputKeystroke // [out] Pointer to an XINPUT_KEYSTROKE structure that receives an input event.
|
||||
): DWORD; stdcall; external XINPUT_DLL;
|
||||
): DWORD; stdcall;
|
||||
|
||||
implementation
|
||||
|
||||
var
|
||||
lib_handle:TLibHandle=NilHandle;
|
||||
|
||||
function XInput_Init:Integer; stdcall;
|
||||
var
|
||||
i:Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
if (lib_handle<>NilHandle) then Exit;
|
||||
|
||||
For i:=0 to High(XINPUT_DLL) do
|
||||
begin
|
||||
lib_handle:=SafeLoadLibrary(XINPUT_DLL[i]);
|
||||
if (lib_handle<>NilHandle) then Break;
|
||||
end;
|
||||
|
||||
if (lib_handle=NilHandle) then Exit(-1);
|
||||
|
||||
Pointer(XInputGetState):=GetProcedureAddress(lib_handle,100);
|
||||
|
||||
if (XInputGetState=nil) then
|
||||
begin
|
||||
Pointer(XInputGetState):=GetProcedureAddress(lib_handle,'XInputGetState');
|
||||
end;
|
||||
|
||||
if (XInputGetState=nil) then
|
||||
begin
|
||||
UnloadLibrary(lib_handle);
|
||||
lib_handle:=NilHandle;
|
||||
Exit(-1);
|
||||
end;
|
||||
|
||||
Pointer(XInputSetState ):=GetProcedureAddress(lib_handle,'XInputSetState');
|
||||
Pointer(XInputGetCapabilities ):=GetProcedureAddress(lib_handle,'XInputGetCapabilities');
|
||||
Pointer(XInputEnable ):=GetProcedureAddress(lib_handle,'XInputEnable');
|
||||
Pointer(XInputGetDSoundAudioDeviceGuids):=GetProcedureAddress(lib_handle,'XInputGetDSoundAudioDeviceGuids');
|
||||
Pointer(XInputGetBatteryInformation ):=GetProcedureAddress(lib_handle,'XInputGetBatteryInformation');
|
||||
Pointer(XInputGetKeystroke ):=GetProcedureAddress(lib_handle,'XInputGetKeystroke');
|
||||
end;
|
||||
|
||||
procedure XInput_Quit; stdcall;
|
||||
begin
|
||||
if (lib_handle=NilHandle) then Exit;
|
||||
|
||||
UnloadLibrary(lib_handle);
|
||||
lib_handle:=NilHandle;
|
||||
|
||||
Pointer(XInputGetState ):=nil;
|
||||
Pointer(XInputSetState ):=nil;
|
||||
Pointer(XInputGetCapabilities ):=nil;
|
||||
Pointer(XInputEnable ):=nil;
|
||||
Pointer(XInputGetDSoundAudioDeviceGuids):=nil;
|
||||
Pointer(XInputGetBatteryInformation ):=nil;
|
||||
Pointer(XInputGetKeystroke ):=nil;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,284 @@
|
|||
unit xinput_pad_interface;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
sysutils,
|
||||
spinlock,
|
||||
XInput,
|
||||
sce_pad_types,
|
||||
sce_pad_interface,
|
||||
kbm_pad_interface;
|
||||
|
||||
type
|
||||
TXInputPadHandle=class(TScePadHandle)
|
||||
var
|
||||
UserIndex :Integer;
|
||||
connected :Boolean;
|
||||
connectedCount:Byte;
|
||||
function ReadState(data:PScePadData):Integer; override;
|
||||
end;
|
||||
|
||||
TXInputPadInterface=class(TScePadInterface)
|
||||
class var
|
||||
xinput_init:Boolean;
|
||||
class function Load:Boolean; override;
|
||||
class procedure Unload; override;
|
||||
class function Init:Integer; override;
|
||||
class function Done:Integer; override;
|
||||
class function FindOpened(UserIndex,prev:Integer):Boolean;
|
||||
class function FindDevice(prev:Integer):Integer;
|
||||
class function Open(var handle:TScePadHandle):Integer; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
formController,
|
||||
uMappableInputs;
|
||||
|
||||
class function TXInputPadInterface.Load:Boolean;
|
||||
var
|
||||
i:Integer;
|
||||
begin
|
||||
if xinput_init then Exit(True);
|
||||
|
||||
i:=XInput.XInput_Init();
|
||||
xinput_init:=(i=0);
|
||||
|
||||
if xinput_init then
|
||||
begin
|
||||
Writeln('XInput initialized!');
|
||||
end else
|
||||
begin
|
||||
Writeln('XInput not initialized!');
|
||||
end;
|
||||
|
||||
Result:=xinput_init;
|
||||
end;
|
||||
|
||||
class procedure TXInputPadInterface.Unload;
|
||||
begin
|
||||
if not xinput_init then Exit;
|
||||
XInput_Quit;
|
||||
xinput_init:=False;
|
||||
Writeln('XInput quit!');
|
||||
end;
|
||||
|
||||
class function TXInputPadInterface.Init:Integer;
|
||||
begin
|
||||
if (xinput_init) then
|
||||
begin
|
||||
Result:=0;
|
||||
end else
|
||||
begin
|
||||
Result:=SCE_PAD_ERROR_NOT_INITIALIZED;
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TXInputPadInterface.Done:Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
class function TXInputPadInterface.FindOpened(UserIndex,prev:Integer):Boolean;
|
||||
var
|
||||
i:Integer;
|
||||
h:TXInputPadHandle;
|
||||
begin
|
||||
Result:=False;
|
||||
spin_lock(pad_lock);
|
||||
For i:=0 to 15 do
|
||||
if (pad_opened[i]<>nil) then
|
||||
if (pad_opened[i].InheritsFrom(TXInputPadHandle)) then
|
||||
begin
|
||||
h:=TXInputPadHandle(pad_opened[i]);
|
||||
if (h.UserIndex<>prev) then
|
||||
begin
|
||||
Result:=(UserIndex=h.UserIndex);
|
||||
if Result then Break;
|
||||
end;
|
||||
end;
|
||||
spin_unlock(pad_lock);
|
||||
end;
|
||||
|
||||
class function TXInputPadInterface.FindDevice(prev:Integer):Integer;
|
||||
var
|
||||
cs:TXInputState;
|
||||
i:Integer;
|
||||
first,compared:Integer;
|
||||
begin
|
||||
Result:=-1;
|
||||
first:=-1;
|
||||
compared:=-1;
|
||||
cs:=Default(TXInputState);
|
||||
For i:=0 to XUSER_MAX_COUNT-1 do
|
||||
begin
|
||||
if (XInputGetState(i, cs)=0) then
|
||||
if not FindOpened(i,prev) then
|
||||
begin
|
||||
if (first=-1) then first:=i;
|
||||
if (prev=-1) then
|
||||
begin
|
||||
compared:=i;
|
||||
Break;
|
||||
end else
|
||||
if (i=prev) then
|
||||
begin
|
||||
compared:=i;
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
//
|
||||
if (compared=-1) then compared:=first;
|
||||
if (compared<>-1) then
|
||||
begin
|
||||
Result:=compared;
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TXInputPadInterface.Open(var handle:TScePadHandle):Integer;
|
||||
var
|
||||
UserIndex:Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
UserIndex:=FindDevice(-1);
|
||||
|
||||
handle:=TXInputPadHandle.Create;
|
||||
TXInputPadHandle(handle).UserIndex:=UserIndex;
|
||||
end;
|
||||
|
||||
function TXInputPadHandle.ReadState(data:PScePadData):Integer;
|
||||
label
|
||||
_retry;
|
||||
var
|
||||
cs:TXInputState;
|
||||
new:Integer;
|
||||
stateResult:DWORD;
|
||||
|
||||
procedure DoConnect(new:DWORD); inline;
|
||||
begin
|
||||
UserIndex:=new;
|
||||
if not connected then
|
||||
begin
|
||||
connected:=True;
|
||||
Inc(connectedCount);
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
if (UserIndex=-1) then //not attached
|
||||
begin
|
||||
new:=TXInputPadInterface.FindDevice(UserIndex);
|
||||
if (new<>-1) then
|
||||
begin
|
||||
//connect
|
||||
DoConnect(new);
|
||||
end else
|
||||
begin
|
||||
//not connected
|
||||
data^.connected :=False;
|
||||
data^.connectedCount:=0;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
_retry:
|
||||
cs:=Default(TXInputState);
|
||||
stateResult:=XInputGetState(UserIndex, cs);
|
||||
|
||||
if (stateResult=ERROR_DEVICE_NOT_CONNECTED) then
|
||||
begin
|
||||
//disconnect
|
||||
connected:=False;
|
||||
//
|
||||
new:=TXInputPadInterface.FindDevice(UserIndex);
|
||||
if (new<>-1) then
|
||||
begin
|
||||
//connect
|
||||
DoConnect(new);
|
||||
goto _retry;
|
||||
end else
|
||||
begin
|
||||
//not connected
|
||||
data^.connected :=False;
|
||||
data^.connectedCount:=0;
|
||||
Exit;
|
||||
end;
|
||||
//
|
||||
data^.connected :=connected;
|
||||
data^.connectedCount:=connectedCount;
|
||||
Exit;
|
||||
end else
|
||||
begin
|
||||
//connect
|
||||
DoConnect(UserIndex);
|
||||
end;
|
||||
|
||||
data^.connected :=connected;
|
||||
data^.connectedCount:=connectedCount;
|
||||
|
||||
TMouseAsTouchpad.ReadState(data);
|
||||
|
||||
//if not MappableInputs.XInputEnabled then break; ?????
|
||||
|
||||
if MappableInputs.PS4IsPressed(miCross, cs) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_CROSS;
|
||||
if MappableInputs.PS4IsPressed(miCircle, cs) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_CIRCLE;
|
||||
if MappableInputs.PS4IsPressed(miSquare, cs) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_SQUARE;
|
||||
if MappableInputs.PS4IsPressed(miTriangle, cs) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_TRIANGLE;
|
||||
|
||||
if MappableInputs.PS4IsPressed(miOptions, cs) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_OPTIONS;
|
||||
if MappableInputs.PS4IsPressed(miTouchPad, cs) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_TOUCH_PAD;
|
||||
|
||||
if MappableInputs.PS4IsPressed(miL1, cs) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_L1;
|
||||
if MappableInputs.PS4IsPressed(miR1, cs) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_R1;
|
||||
if MappableInputs.PS4IsPressed(miL3, cs) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_L3;
|
||||
if MappableInputs.PS4IsPressed(miR3, cs) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_R3;
|
||||
|
||||
if MappableInputs.PS4IsPressed(miDPadUp, cs) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_UP;
|
||||
if MappableInputs.PS4IsPressed(miDPadDown, cs) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_DOWN;
|
||||
if MappableInputs.PS4IsPressed(miDPadLeft, cs) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_LEFT;
|
||||
if MappableInputs.PS4IsPressed(miDPadRight, cs) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_RIGHT;
|
||||
|
||||
data^.leftStick.x:=Trunc(128+(MappableInputs.GetAnalog(miLJoyRight, cs)-MappableInputs.GetAnalog(miLJoyLeft, cs))*127);
|
||||
data^.leftStick.y:=Trunc(128+(MappableInputs.GetAnalog(miLJoyDown , cs)-MappableInputs.GetAnalog(miLJoyUp , cs))*127);
|
||||
|
||||
data^.rightStick.x:=Trunc(128+(MappableInputs.GetAnalog(miRJoyRight, cs)-MappableInputs.GetAnalog(miRJoyLeft, cs))*127);
|
||||
data^.rightStick.y:=Trunc(128+(MappableInputs.GetAnalog(miRJoyDown , cs)-MappableInputs.GetAnalog(miRJoyUp , cs))*127);
|
||||
|
||||
data^.analogButtons.l2:=Trunc(MappableInputs.GetAnalog(miL2, cs)*255);
|
||||
data^.analogButtons.r2:=Trunc(MappableInputs.GetAnalog(miR2, cs)*255);
|
||||
|
||||
if MappableInputs.PS4IsPressed(miL2, cs) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_L2;
|
||||
if MappableInputs.PS4IsPressed(miR2, cs) then
|
||||
data^.buttons:=data^.buttons or SCE_PAD_BUTTON_R2;
|
||||
end;
|
||||
|
||||
finalization
|
||||
TXInputPadInterface.Unload;
|
||||
|
||||
end.
|
||||
|
||||
|
||||
|
|
@ -6,6 +6,7 @@ interface
|
|||
|
||||
uses
|
||||
ps4libdoc,
|
||||
sys_crt,
|
||||
ps4_map_mm,
|
||||
ps4_pthread,
|
||||
ps4_time,
|
||||
|
@ -20,6 +21,7 @@ uses
|
|||
ps4_atexit_internal,
|
||||
ps4_guard_internal,
|
||||
ps4_mtx_internal,
|
||||
ps4_libkernel,
|
||||
sys_kernel,
|
||||
sys_signal;
|
||||
|
||||
|
@ -66,6 +68,11 @@ begin
|
|||
Result:=strlcopy(dst,src,len);
|
||||
end;
|
||||
|
||||
function ps4_strlcpy(dst,src:PChar;len:sizeint):sizeint; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=strlcopy(dst,src,len)-dst;
|
||||
end;
|
||||
|
||||
function ps4_strcpy_s(dst:PChar;destSize:size_t;src:PChar):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
count:size_t;
|
||||
|
@ -89,6 +96,21 @@ begin
|
|||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_strcmp(a,b:PChar):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=StrComp(a,b);
|
||||
end;
|
||||
|
||||
function ps4_strncmp(a,b:PChar;n:ptrint):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=StrLComp(a,b,n);
|
||||
end;
|
||||
|
||||
function ps4_strstr(str,sub:PChar):PChar; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=StrPos(str,sub);
|
||||
end;
|
||||
|
||||
function ps4_memcpy(dst,src:Pointer;len:size_t):Pointer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Move(src^,dst^,len);
|
||||
|
@ -106,6 +128,53 @@ begin
|
|||
FillChar(s^,n,0);
|
||||
end;
|
||||
|
||||
function ps4_getenv(name:PChar):PChar; SysV_ABI_CDecl;
|
||||
label
|
||||
_err;
|
||||
var
|
||||
n:PChar;
|
||||
_environ:PPchar;
|
||||
nlen:ptrint;
|
||||
r:Integer;
|
||||
begin
|
||||
if (name=nil) then goto _err;
|
||||
|
||||
nlen:=0;
|
||||
n:=name;
|
||||
While (n^<>#0) do
|
||||
begin
|
||||
if (n^='=') then goto _err;
|
||||
Inc(n);
|
||||
Inc(nlen);
|
||||
end;
|
||||
|
||||
if (nlen=0) then goto _err;
|
||||
|
||||
if (environ=nil) then Exit(nil);
|
||||
|
||||
_environ:=environ;
|
||||
n:=_environ^;
|
||||
if (n=nil) then Exit(nil);
|
||||
|
||||
repeat
|
||||
r:=StrLComp(n,name,nlen);
|
||||
|
||||
if (r=0) and (n[nlen]='=') then Break;
|
||||
|
||||
Inc(_environ);
|
||||
n:=_environ^;
|
||||
|
||||
if (n=nil) then Exit(nil);
|
||||
|
||||
until false;
|
||||
|
||||
Exit(@n[nlen+1]);
|
||||
|
||||
_err:
|
||||
_set_errno(EINVAL);
|
||||
Result:=nil;
|
||||
end;
|
||||
|
||||
procedure ps4__init_env; SysV_ABI_CDecl;
|
||||
begin
|
||||
//
|
||||
|
@ -161,9 +230,18 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure ps4_perror(str:PChar); SysV_ABI_CDecl;
|
||||
begin
|
||||
if (str<>nil) and (str<>'') then
|
||||
begin
|
||||
Write(StdErr,str,': ');
|
||||
end;
|
||||
Writeln(StdErr,PInteger(_error)^);
|
||||
end;
|
||||
|
||||
Const
|
||||
Need_sceLibcInternal:QWORD=1;
|
||||
Need_sceLibc:QWORD=1;
|
||||
|
||||
_Stdin :QWORD=0;
|
||||
_Stdout:QWORD=1;
|
||||
|
@ -212,12 +290,12 @@ begin
|
|||
lib:=ps4_app.GetLib('libc');
|
||||
if (lib<>nil) then
|
||||
begin
|
||||
Writeln(StdErr,'Redirected:',HexStr(Nid,16),':',ps4libdoc.GetFunctName(Nid));
|
||||
Writeln(StdWrn,'Redirected:',HexStr(Nid,16),':',ps4libdoc.GetFunctName(Nid));
|
||||
Result:=lib^.get_proc(Nid);
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
Writeln(StdErr,'Operator:',HexStr(Nid,16),':',ps4libdoc.GetFunctName(Nid));
|
||||
Writeln(StdWrn,'Operator:',HexStr(Nid,16),':',ps4libdoc.GetFunctName(Nid));
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -240,6 +318,7 @@ begin
|
|||
lib^.Fget_proc_cb:=@_get_proc_libSceLibcInternal;
|
||||
|
||||
lib^.set_proc($653E0E0C3D93B3DA,@Need_sceLibcInternal);
|
||||
lib^.set_proc($3F7DF43F774517AF,@Need_sceLibc);
|
||||
|
||||
//lib^.set_proc($D530E8FC89AA9097,@_Stdin );
|
||||
//lib^.set_proc($DAC5B3858A851F81,@_Stdout);
|
||||
|
@ -250,11 +329,17 @@ begin
|
|||
lib^.set_proc($3452ECF9D44918D8,@ps4_memcpy_s);
|
||||
lib^.set_proc($8F856258D1C4830C,@ps4_strlen);
|
||||
lib^.set_proc($EAC256896491BAA9,@ps4_strncpy);
|
||||
lib^.set_proc($49F40865CAAFBE6B,@ps4_strlcpy);
|
||||
lib^.set_proc($E576B600234409DA,@ps4_strcpy_s);
|
||||
lib^.set_proc($3AF6F675224E02E1,@ps4_strcmp);
|
||||
lib^.set_proc($69EB328EB1D55B2E,@ps4_strncmp);
|
||||
lib^.set_proc($BE28B014C68D6A60,@ps4_strstr);
|
||||
lib^.set_proc($437541C425E1507B,@ps4_memcpy);
|
||||
lib^.set_proc($F8FE854461F82DF0,@ps4_memmove);
|
||||
lib^.set_proc($F68897D64C9E79D0,@ps4_bzero);
|
||||
|
||||
lib^.set_proc($B266D0BA47F16093,@ps4_getenv);
|
||||
|
||||
lib^.set_proc($6F3404C72D7CF592,@ps4__init_env);
|
||||
lib^.set_proc($E8D08EAABDDC0FBE,@ps4__init_tls);
|
||||
|
||||
|
@ -264,6 +349,8 @@ begin
|
|||
lib^.set_proc($5B48FABC2C61F4F7,@ps4__ZSt16_Throw_Cpp_errori);
|
||||
lib^.set_proc($6D1BA3221796941D,@ps4__ZSt14_Throw_C_errori);
|
||||
|
||||
lib^.set_proc($10CBADC1A437E09A,@ps4_perror);
|
||||
|
||||
//mspace
|
||||
|
||||
lib^.set_proc($DB4714934A97F73A,@ps4_malloc_init_lv2);
|
||||
|
|
|
@ -0,0 +1,639 @@
|
|||
unit np_error;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
SCE_NP_ERROR_ALREADY_INITIALIZED =-2141913087; //0x80550001
|
||||
SCE_NP_ERROR_NOT_INITIALIZED =-2141913086; //0x80550002
|
||||
SCE_NP_ERROR_INVALID_ARGUMENT =-2141913085; //0x80550003
|
||||
SCE_NP_ERROR_UNKNOWN_PLATFORM_TYPE =-2141913084; //0x80550004
|
||||
SCE_NP_ERROR_OUT_OF_MEMORY =-2141913083; //0x80550005
|
||||
SCE_NP_ERROR_SIGNED_OUT =-2141913082; //0x80550006
|
||||
SCE_NP_ERROR_USER_NOT_FOUND =-2141913081; //0x80550007
|
||||
SCE_NP_ERROR_CALLBACK_ALREADY_REGISTERED =-2141913080; //0x80550008
|
||||
SCE_NP_ERROR_CALLBACK_NOT_REGISTERED =-2141913079; //0x80550009
|
||||
SCE_NP_ERROR_NOT_SIGNED_UP =-2141913078; //0x8055000A
|
||||
SCE_NP_ERROR_AGE_RESTRICTION =-2141913077; //0x8055000B
|
||||
SCE_NP_ERROR_LOGOUT =-2141913076; //0x8055000C
|
||||
SCE_NP_ERROR_LATEST_SYSTEM_SOFTWARE_EXIST =-2141913075; //0x8055000D
|
||||
SCE_NP_ERROR_LATEST_SYSTEM_SOFTWARE_EXIST_FOR_TITLE =-2141913074; //0x8055000E
|
||||
SCE_NP_ERROR_LATEST_PATCH_PKG_EXIST =-2141913073; //0x8055000F
|
||||
SCE_NP_ERROR_LATEST_PATCH_PKG_DOWNLOADED =-2141913072; //0x80550010
|
||||
SCE_NP_ERROR_INVALID_SIZE =-2141913071; //0x80550011
|
||||
SCE_NP_ERROR_ABORTED =-2141913070; //0x80550012
|
||||
SCE_NP_ERROR_REQUEST_MAX =-2141913069; //0x80550013
|
||||
SCE_NP_ERROR_REQUEST_NOT_FOUND =-2141913068; //0x80550014
|
||||
SCE_NP_ERROR_INVALID_ID =-2141913067; //0x80550015
|
||||
SCE_NP_ERROR_NP_TITLE_DAT_NOT_FOUND =-2141913066; //0x80550016
|
||||
SCE_NP_ERROR_INCONSISTENT_NP_TITLE_ID =-2141913065; //0x80550017
|
||||
SCE_NP_ERROR_PATCH_NOT_CHECKED =-2141913064; //0x80550018
|
||||
SCE_NP_ERROR_TITLE_IS_BANNED =-2141913063; //0x80550019
|
||||
SCE_NP_ERROR_TIMEOUT =-2141913062; //0x8055001A
|
||||
SCE_NP_ERROR_TITLE_ID_IN_PARAM_SFO_NOT_MATCHED_TO_NP_TITLE_ID =-2141913061; //0x8055001B
|
||||
SCE_NP_ERROR_TITLE_ID_IN_PARAM_SFO_NOT_EXIST =-2141913060; //0x8055001C
|
||||
SCE_NP_ERROR_CALLBACK_MAX =-2141913059; //0x8055001D
|
||||
SCE_NP_ERROR_INVALID_NP_TITLE_ID =-2141913058; //0x8055001E
|
||||
SCE_NP_ERROR_ONLINE_ID_CHANGED =-2141913057; //0x8055001F
|
||||
SCE_NP_ERROR_TOO_LARGE_TICKET =-2141868013; //0x8055B013
|
||||
SCE_NP_AUTH_ERROR_INVALID_ARGUMENT =-2141912319; //0x80550301
|
||||
SCE_NP_AUTH_ERROR_INVALID_SIZE =-2141912318; //0x80550302
|
||||
SCE_NP_AUTH_ERROR_OUT_OF_MEMORY =-2141912317; //0x80550303
|
||||
SCE_NP_AUTH_ERROR_ABORTED =-2141912316; //0x80550304
|
||||
SCE_NP_AUTH_ERROR_REQUEST_MAX =-2141912315; //0x80550305
|
||||
SCE_NP_AUTH_ERROR_REQUEST_NOT_FOUND =-2141912314; //0x80550306
|
||||
SCE_NP_AUTH_ERROR_INVALID_ID =-2141912313; //0x80550307
|
||||
SCE_NP_AUTH_ERROR_NO_TOKEN_RECEIVED =-2141912312; //0x80550308
|
||||
SCE_NP_AUTH_ERROR_SERVICE_END =-2141912064; //0x80550400
|
||||
SCE_NP_AUTH_ERROR_SERVICE_DOWN =-2141912063; //0x80550401
|
||||
SCE_NP_AUTH_ERROR_SERVICE_BUSY =-2141912062; //0x80550402
|
||||
SCE_NP_AUTH_ERROR_SERVER_MAINTENANCE =-2141912061; //0x80550403
|
||||
SCE_NP_AUTH_ERROR_S_INVALID_DATA_LENGTH =-2141912048; //0x80550410
|
||||
SCE_NP_AUTH_ERROR_S_INVALID_USER_AGENT =-2141912047; //0x80550411
|
||||
SCE_NP_AUTH_ERROR_S_INVALID_VERSION =-2141912046; //0x80550412
|
||||
SCE_NP_AUTH_ERROR_S_INVALID_SERVICE_ID =-2141912032; //0x80550420
|
||||
SCE_NP_AUTH_ERROR_S_INVALID_CREDENTIAL =-2141912031; //0x80550421
|
||||
SCE_NP_AUTH_ERROR_S_INVALID_ENTITLEMENT_ID =-2141912030; //0x80550422
|
||||
SCE_NP_AUTH_ERROR_S_INVALID_CONSUMED_COUNT =-2141912029; //0x80550423
|
||||
SCE_NP_AUTH_ERROR_INVALID_CONSOLE_ID =-2141912028; //0x80550424
|
||||
SCE_NP_AUTH_ERROR_CONSOLE_ID_SUSPENDED =-2141912025; //0x80550427
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_CLOSED =-2141912016; //0x80550430
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_SUSPENDED =-2141912015; //0x80550431
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_RENEW_EULA =-2141912014; //0x80550432
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_RENEW_ACCOUNT1 =-2141912000; //0x80550440
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_RENEW_ACCOUNT2 =-2141911999; //0x80550441
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_RENEW_ACCOUNT3 =-2141911998; //0x80550442
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_RENEW_ACCOUNT4 =-2141911997; //0x80550443
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_RENEW_ACCOUNT5 =-2141911996; //0x80550444
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_RENEW_ACCOUNT6 =-2141911995; //0x80550445
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_RENEW_ACCOUNT7 =-2141911994; //0x80550446
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_RENEW_ACCOUNT8 =-2141911993; //0x80550447
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_RENEW_ACCOUNT9 =-2141911992; //0x80550448
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_RENEW_ACCOUNT10 =-2141911991; //0x80550449
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_RENEW_ACCOUNT11 =-2141911990; //0x8055044A
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_RENEW_ACCOUNT12 =-2141911989; //0x8055044B
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_RENEW_ACCOUNT13 =-2141911988; //0x8055044C
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_RENEW_ACCOUNT14 =-2141911987; //0x8055044D
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_RENEW_ACCOUNT15 =-2141911986; //0x8055044E
|
||||
SCE_NP_AUTH_ERROR_ACCOUNT_RENEW_ACCOUNT16 =-2141911985; //0x8055044F
|
||||
SCE_NP_AUTH_ERROR_SUB_ACCOUNT_RENEW_EULA =-2141911985; //0x8055044F
|
||||
SCE_NP_AUTH_ERROR_UNKNOWN =-2141911936; //0x80550480
|
||||
SCE_NP_UTIL_ERROR_INVALID_ARGUMENT =-2141911551; //0x80550601
|
||||
SCE_NP_UTIL_ERROR_INSUFFICIENT =-2141911550; //0x80550602
|
||||
SCE_NP_UTIL_ERROR_PARSER_FAILED =-2141911549; //0x80550603
|
||||
SCE_NP_UTIL_ERROR_INVALID_PROTOCOL_ID =-2141911548; //0x80550604
|
||||
SCE_NP_UTIL_ERROR_INVALID_NP_ID =-2141911547; //0x80550605
|
||||
SCE_NP_UTIL_ERROR_INVALID_NP_ENV =-2141911546; //0x80550606
|
||||
SCE_NP_UTIL_ERROR_INVALID_CHARACTER =-2141911544; //0x80550608
|
||||
SCE_NP_UTIL_ERROR_NOT_MATCH =-2141911543; //0x80550609
|
||||
SCE_NP_UTIL_ERROR_INVALID_TITLEID =-2141911542; //0x8055060A
|
||||
SCE_NP_UTIL_ERROR_UNKNOWN =-2141911538; //0x8055060E
|
||||
SCE_NP_COMMUNITY_ERROR_ALREADY_INITIALIZED =-2141911295; //0x80550701
|
||||
SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED =-2141911294; //0x80550702
|
||||
SCE_NP_COMMUNITY_ERROR_OUT_OF_MEMORY =-2141911293; //0x80550703
|
||||
SCE_NP_COMMUNITY_ERROR_INVALID_ARGUMENT =-2141911292; //0x80550704
|
||||
SCE_NP_COMMUNITY_ERROR_NO_LOGIN =-2141911291; //0x80550705
|
||||
SCE_NP_COMMUNITY_ERROR_TOO_MANY_OBJECTS =-2141911290; //0x80550706
|
||||
SCE_NP_COMMUNITY_ERROR_ABORTED =-2141911289; //0x80550707
|
||||
SCE_NP_COMMUNITY_ERROR_BAD_RESPONSE =-2141911288; //0x80550708
|
||||
SCE_NP_COMMUNITY_ERROR_BODY_TOO_LARGE =-2141911287; //0x80550709
|
||||
SCE_NP_COMMUNITY_ERROR_HTTP_SERVER =-2141911286; //0x8055070A
|
||||
SCE_NP_COMMUNITY_ERROR_INVALID_SIGNATURE =-2141911285; //0x8055070B
|
||||
SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT =-2141911284; //0x8055070C
|
||||
SCE_NP_COMMUNITY_ERROR_UNKNOWN_TYPE =-2141911283; //0x8055070D
|
||||
SCE_NP_COMMUNITY_ERROR_INVALID_ID =-2141911282; //0x8055070E
|
||||
SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID =-2141911281; //0x8055070F
|
||||
SCE_NP_COMMUNITY_ERROR_INVALID_TYPE =-2141911279; //0x80550711
|
||||
SCE_NP_COMMUNITY_ERROR_TRANSACTION_ALREADY_END =-2141911278; //0x80550712
|
||||
SCE_NP_COMMUNITY_ERROR_INVALID_PARTITION =-2141911277; //0x80550713
|
||||
SCE_NP_COMMUNITY_ERROR_INVALID_ALIGNMENT =-2141911276; //0x80550714
|
||||
SCE_NP_COMMUNITY_ERROR_CLIENT_HANDLE_ALREADY_EXISTS =-2141911275; //0x80550715
|
||||
SCE_NP_COMMUNITY_ERROR_NO_RESOURCE =-2141911274; //0x80550716
|
||||
SCE_NP_COMMUNITY_ERROR_REQUEST_BEFORE_END =-2141911273; //0x80550717
|
||||
SCE_NP_COMMUNITY_ERROR_TOO_MANY_SLOTID =-2141911272; //0x80550718
|
||||
SCE_NP_COMMUNITY_ERROR_TOO_MANY_NPID =-2141911271; //0x80550719
|
||||
SCE_NP_COMMUNITY_ERROR_SCORE_INVALID_SAVEDATA_OWNER =-2141911270; //0x8055071A
|
||||
SCE_NP_COMMUNITY_ERROR_TUS_INVALID_SAVEDATA_OWNER =-2141911269; //0x8055071B
|
||||
SCE_NP_COMMUNITY_ERROR_GHOST_SERVER_RETURN_INVALID_STATUS_CODE =-2141911268; //0x8055071C
|
||||
SCE_NP_COMMUNITY_ERROR_UBS_ONLINE_ID_IN_XML_CREATED_PAST_IS_DIFFERENT_FROM_CURRENT=-2141911267; //0x8055071D
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_BAD_REQUEST =-2141911039; //0x80550801
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_INVALID_TICKET =-2141911038; //0x80550802
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_INVALID_SIGNATURE =-2141911037; //0x80550803
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_INVALID_NPID =-2141911035; //0x80550805
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_FORBIDDEN =-2141911034; //0x80550806
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_INTERNAL_SERVER_ERROR =-2141911033; //0x80550807
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_VERSION_NOT_SUPPORTED =-2141911032; //0x80550808
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_SERVICE_UNAVAILABLE =-2141911031; //0x80550809
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_PLAYER_BANNED =-2141911030; //0x8055080A
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_CENSORED =-2141911029; //0x8055080B
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_RANKING_RECORD_FORBIDDEN =-2141911028; //0x8055080C
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_USER_PROFILE_NOT_FOUND =-2141911027; //0x8055080D
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_UPLOADER_DATA_NOT_FOUND =-2141911026; //0x8055080E
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_QUOTA_MASTER_NOT_FOUND =-2141911025; //0x8055080F
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_RANKING_TITLE_NOT_FOUND =-2141911024; //0x80550810
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_BLACKLISTED_USER_ID =-2141911023; //0x80550811
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_GAME_RANKING_NOT_FOUND =-2141911022; //0x80550812
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_RANKING_STORE_NOT_FOUND =-2141911020; //0x80550814
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_NOT_BEST_SCORE =-2141911019; //0x80550815
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_LATEST_UPDATE_NOT_FOUND =-2141911018; //0x80550816
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_RANKING_BOARD_MASTER_NOT_FOUND =-2141911017; //0x80550817
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_RANKING_GAME_DATA_MASTER_NOT_FOUND =-2141911016; //0x80550818
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_INVALID_ANTICHEAT_DATA =-2141911015; //0x80550819
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_TOO_LARGE_DATA =-2141911014; //0x8055081A
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_NO_SUCH_USER_NPID =-2141911013; //0x8055081B
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_INVALID_ENVIRONMENT =-2141911011; //0x8055081D
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_INVALID_ONLINE_NAME_CHARACTER =-2141911009; //0x8055081F
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_INVALID_ONLINE_NAME_LENGTH =-2141911008; //0x80550820
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_INVALID_ABOUT_ME_CHARACTER =-2141911007; //0x80550821
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_INVALID_ABOUT_ME_LENGTH =-2141911006; //0x80550822
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_INVALID_SCORE =-2141911005; //0x80550823
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_OVER_THE_RANKING_LIMIT =-2141911004; //0x80550824
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_FAIL_TO_CREATE_SIGNATURE =-2141911002; //0x80550826
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_RANKING_MASTER_INFO_NOT_FOUND =-2141911001; //0x80550827
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_OVER_THE_GAME_DATA_LIMIT =-2141911000; //0x80550828
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_SELF_DATA_NOT_FOUND =-2141910998; //0x8055082A
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_USER_NOT_ASSIGNED =-2141910997; //0x8055082B
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_GAME_DATA_ALREADY_EXISTS =-2141910996; //0x8055082C
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_TOO_MANY_RESULTS =-2141910995; //0x8055082D
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_NOT_RECORDABLE_VERSION =-2141910994; //0x8055082E
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_USER_STORAGE_TITLE_MASTER_NOT_FOUND =-2141910968; //0x80550848
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_INVALID_VIRTUAL_USER =-2141910967; //0x80550849
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_USER_STORAGE_DATA_NOT_FOUND =-2141910966; //0x8055084A
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_NON_PLUS_MEMBER =-2141910947; //0x8055085D
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_UNMATCH_SEQUENCE =-2141910946; //0x8055085E
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_SAVEDATA_NOT_FOUND =-2141910945; //0x8055085F
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_TOO_MANY_SAVEDATA_FILES =-2141910944; //0x80550860
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_TOO_MUCH_TOTAL_SAVEDATA_SIZE =-2141910943; //0x80550861
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_NOT_YET_DOWNLOADABLE =-2141910942; //0x80550862
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_BLACKLISTED_TITLE =-2141910936; //0x80550868
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_TOO_LARGE_ICONDATA =-2141910935; //0x80550869
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_TOO_LARGE_SAVEDATA =-2141910934; //0x8055086A
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_UNMATCH_SIGNATURE =-2141910933; //0x8055086B
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_UNMATCH_MD5SUM =-2141910932; //0x8055086C
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_TOO_MUCH_SAVEDATA_SIZE =-2141910931; //0x8055086D
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_RECORD_DATE_IS_NEWER_THAN_COMP_DATE =-2141910930; //0x8055086E
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_CONDITIONS_NOT_SATISFIED =-2141910925; //0x80550873
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_UNSUPPORTED_PLATFORM =-2141910920; //0x80550878
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_EXPIRED_SIGNATURE =-2141910903; //0x80550889
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_SAVEDATA_UPDATED =-2141910902; //0x8055088A
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_MATCHING_BEFORE_SERVICE =-2141910880; //0x805508A0
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_MATCHING_END_OF_SERVICE =-2141910879; //0x805508A1
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_MATCHING_MAINTENANCE =-2141910878; //0x805508A2
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_RANKING_BEFORE_SERVICE =-2141910877; //0x805508A3
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_RANKING_END_OF_SERVICE =-2141910876; //0x805508A4
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_RANKING_MAINTENANCE =-2141910875; //0x805508A5
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_NO_SUCH_TITLE =-2141910874; //0x805508A6
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_TITLE_USER_STORAGE_BEFORE_SERVICE =-2141910870; //0x805508AA
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_TITLE_USER_STORAGE_END_OF_SERVICE =-2141910869; //0x805508AB
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_TITLE_USER_STORAGE_MAINTENANCE =-2141910868; //0x805508AC
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_FSR_BEFORE_SERVICE =-2141910867; //0x805508AD
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_FSR_END_OF_SERVICE =-2141910866; //0x805508AE
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_FSR_MAINTENANCE =-2141910865; //0x805508AF
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_UBS_BEFORE_SERVICE =-2141910864; //0x805508B0
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_UBS_END_OF_SERVICE =-2141910863; //0x805508B1
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_UBS_MAINTENANCE =-2141910862; //0x805508B2
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_BASIC_BLACKLISTED_USER_ID =-2141910861; //0x805508B3
|
||||
SCE_NP_COMMUNITY_SERVER_ERROR_UNSPECIFIED =-2141910785; //0x805508FF
|
||||
SCE_NP_MATCHING2_ERROR_OUT_OF_MEMORY =-2141910015; //0x80550C01
|
||||
SCE_NP_MATCHING2_ERROR_ALREADY_INITIALIZED =-2141910014; //0x80550C02
|
||||
SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED =-2141910013; //0x80550C03
|
||||
SCE_NP_MATCHING2_ERROR_CONTEXT_MAX =-2141910012; //0x80550C04
|
||||
SCE_NP_MATCHING2_ERROR_CONTEXT_ALREADY_EXISTS =-2141910011; //0x80550C05
|
||||
SCE_NP_MATCHING2_ERROR_CONTEXT_NOT_FOUND =-2141910010; //0x80550C06
|
||||
SCE_NP_MATCHING2_ERROR_CONTEXT_ALREADY_STARTED =-2141910009; //0x80550C07
|
||||
SCE_NP_MATCHING2_ERROR_CONTEXT_NOT_STARTED =-2141910008; //0x80550C08
|
||||
SCE_NP_MATCHING2_ERROR_SERVER_NOT_FOUND =-2141910007; //0x80550C09
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT =-2141910006; //0x80550C0A
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_CONTEXT_ID =-2141910005; //0x80550C0B
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_SERVER_ID =-2141910004; //0x80550C0C
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_WORLD_ID =-2141910003; //0x80550C0D
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_LOBBY_ID =-2141910002; //0x80550C0E
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_ROOM_ID =-2141910001; //0x80550C0F
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_MEMBER_ID =-2141910000; //0x80550C10
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_ATTRIBUTE_ID =-2141909999; //0x80550C11
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_CASTTYPE =-2141909998; //0x80550C12
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_SORT_METHOD =-2141909997; //0x80550C13
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_MAX_SLOT =-2141909996; //0x80550C14
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_MATCHING_SPACE =-2141909994; //0x80550C16
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_BLOCK_KICK_FLAG =-2141909993; //0x80550C17
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_MESSAGE_TARGET =-2141909992; //0x80550C18
|
||||
SCE_NP_MATCHING2_ERROR_RANGE_FILTER_MAX =-2141909991; //0x80550C19
|
||||
SCE_NP_MATCHING2_ERROR_INSUFFICIENT_BUFFER =-2141909990; //0x80550C1A
|
||||
SCE_NP_MATCHING2_ERROR_DESTINATION_DISAPPEARED =-2141909989; //0x80550C1B
|
||||
SCE_NP_MATCHING2_ERROR_REQUEST_TIMEOUT =-2141909988; //0x80550C1C
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_ALIGNMENT =-2141909987; //0x80550C1D
|
||||
SCE_NP_MATCHING2_ERROR_CONNECTION_CLOSED_BY_SERVER =-2141909986; //0x80550C1E
|
||||
SCE_NP_MATCHING2_ERROR_SSL_VERIFY_FAILED =-2141909985; //0x80550C1F
|
||||
SCE_NP_MATCHING2_ERROR_SSL_HANDSHAKE =-2141909984; //0x80550C20
|
||||
SCE_NP_MATCHING2_ERROR_SSL_SEND =-2141909983; //0x80550C21
|
||||
SCE_NP_MATCHING2_ERROR_SSL_RECV =-2141909982; //0x80550C22
|
||||
SCE_NP_MATCHING2_ERROR_JOINED_SESSION_MAX =-2141909981; //0x80550C23
|
||||
SCE_NP_MATCHING2_ERROR_ALREADY_JOINED =-2141909980; //0x80550C24
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_SESSION_TYPE =-2141909979; //0x80550C25
|
||||
SCE_NP_MATCHING2_ERROR_NP_SIGNED_OUT =-2141909978; //0x80550C26
|
||||
SCE_NP_MATCHING2_ERROR_BUSY =-2141909977; //0x80550C27
|
||||
SCE_NP_MATCHING2_ERROR_SERVER_NOT_AVAILABLE =-2141909976; //0x80550C28
|
||||
SCE_NP_MATCHING2_ERROR_NOT_ALLOWED =-2141909975; //0x80550C29
|
||||
SCE_NP_MATCHING2_ERROR_ABORTED =-2141909974; //0x80550C2A
|
||||
SCE_NP_MATCHING2_ERROR_REQUEST_NOT_FOUND =-2141909973; //0x80550C2B
|
||||
SCE_NP_MATCHING2_ERROR_SESSION_DESTROYED =-2141909972; //0x80550C2C
|
||||
SCE_NP_MATCHING2_ERROR_CONTEXT_STOPPED =-2141909971; //0x80550C2D
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_REQUEST_PARAMETER =-2141909970; //0x80550C2E
|
||||
SCE_NP_MATCHING2_ERROR_NOT_NP_SIGN_IN =-2141909969; //0x80550C2F
|
||||
SCE_NP_MATCHING2_ERROR_ROOM_NOT_FOUND =-2141909968; //0x80550C30
|
||||
SCE_NP_MATCHING2_ERROR_ROOM_MEMBER_NOT_FOUND =-2141909967; //0x80550C31
|
||||
SCE_NP_MATCHING2_ERROR_LOBBY_NOT_FOUND =-2141909966; //0x80550C32
|
||||
SCE_NP_MATCHING2_ERROR_LOBBY_MEMBER_NOT_FOUND =-2141909965; //0x80550C33
|
||||
SCE_NP_MATCHING2_ERROR_KEEPALIVE_TIMEOUT =-2141909964; //0x80550C34
|
||||
SCE_NP_MATCHING2_ERROR_TIMEOUT_TOO_SHORT =-2141909963; //0x80550C35
|
||||
SCE_NP_MATCHING2_ERROR_TIMEDOUT =-2141909962; //0x80550C36
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_SLOTGROUP =-2141909961; //0x80550C37
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_ATTRIBUTE_SIZE =-2141909960; //0x80550C38
|
||||
SCE_NP_MATCHING2_ERROR_CANNOT_ABORT =-2141909959; //0x80550C39
|
||||
SCE_NP_MATCHING2_ERROR_SESSION_NOT_FOUND =-2141909958; //0x80550C3A
|
||||
SCE_NP_MATCHING2_ERROR_INVALID_CONTEXT =-2141909957; //0x80550C3B
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_BAD_REQUEST =-2141909759; //0x80550D01
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_SERVICE_UNAVAILABLE =-2141909758; //0x80550D02
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_BUSY =-2141909757; //0x80550D03
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_END_OF_SERVICE =-2141909756; //0x80550D04
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_INTERNAL_SERVER_ERROR =-2141909755; //0x80550D05
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_PLAYER_BANNED =-2141909754; //0x80550D06
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_FORBIDDEN =-2141909753; //0x80550D07
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_BLOCKED =-2141909752; //0x80550D08
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_UNSUPPORTED_NP_ENV =-2141909751; //0x80550D09
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_INVALID_TICKET =-2141909750; //0x80550D0A
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_INVALID_SIGNATURE =-2141909749; //0x80550D0B
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_EXPIRED_TICKET =-2141909748; //0x80550D0C
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_ENTITLEMENT_REQUIRED =-2141909747; //0x80550D0D
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_CONTEXT =-2141909746; //0x80550D0E
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_CLOSED =-2141909745; //0x80550D0F
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_TITLE =-2141909744; //0x80550D10
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_WORLD =-2141909743; //0x80550D11
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_LOBBY =-2141909742; //0x80550D12
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM =-2141909741; //0x80550D13
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_LOBBY_INSTANCE =-2141909740; //0x80550D14
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_ROOM_INSTANCE =-2141909739; //0x80550D15
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_PASSWORD_MISMATCH =-2141909737; //0x80550D17
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_LOBBY_FULL =-2141909736; //0x80550D18
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_ROOM_FULL =-2141909735; //0x80550D19
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_GROUP_FULL =-2141909733; //0x80550D1B
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_USER =-2141909732; //0x80550D1C
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_GROUP_PASSWORD_MISMATCH =-2141909731; //0x80550D1D
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_TITLE_PASSPHRASE_MISMATCH =-2141909730; //0x80550D1E
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_LOBBY_ALREADY_EXIST =-2141909723; //0x80550D25
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_ROOM_ALREADY_EXIST =-2141909722; //0x80550D26
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_CONSOLE_BANNED =-2141909720; //0x80550D28
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_NO_ROOMGROUP =-2141909719; //0x80550D29
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_NO_SUCH_GROUP =-2141909718; //0x80550D2A
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_NO_PASSWORD =-2141909717; //0x80550D2B
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_INVALID_GROUP_SLOT_NUM =-2141909716; //0x80550D2C
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_INVALID_PASSWORD_SLOT_MASK =-2141909715; //0x80550D2D
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_DUPLICATE_GROUP_LABEL =-2141909714; //0x80550D2E
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_REQUEST_OVERFLOW =-2141909713; //0x80550D2F
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_ALREADY_JOINED =-2141909712; //0x80550D30
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_NAT_TYPE_MISMATCH =-2141909711; //0x80550D31
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_ROOM_INCONSISTENCY =-2141909710; //0x80550D32
|
||||
SCE_NP_MATCHING2_SERVER_ERROR_BLOCKED_USER_IN_ROOM =-2141909709; //0x80550D33
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_NOT_INITIALIZED =-2141909503; //0x80550E01
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_ALREADY_INITIALIZED =-2141909502; //0x80550E02
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_OUT_OF_MEMORY =-2141909501; //0x80550E03
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_CTXID_NOT_AVAILABLE =-2141909500; //0x80550E04
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_CTX_NOT_FOUND =-2141909499; //0x80550E05
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_REQID_NOT_AVAILABLE =-2141909498; //0x80550E06
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_REQ_NOT_FOUND =-2141909497; //0x80550E07
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_PARSER_CREATE_FAILED =-2141909496; //0x80550E08
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_PARSER_FAILED =-2141909495; //0x80550E09
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_INVALID_NAMESPACE =-2141909494; //0x80550E0A
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_NETINFO_NOT_AVAILABLE =-2141909493; //0x80550E0B
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_PEER_NOT_RESPONDING =-2141909492; //0x80550E0C
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_CONNID_NOT_AVAILABLE =-2141909491; //0x80550E0D
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_CONN_NOT_FOUND =-2141909490; //0x80550E0E
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_PEER_UNREACHABLE =-2141909489; //0x80550E0F
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_TERMINATED_BY_PEER =-2141909488; //0x80550E10
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_TIMEOUT =-2141909487; //0x80550E11
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_CTX_MAX =-2141909486; //0x80550E12
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_RESULT_NOT_FOUND =-2141909485; //0x80550E13
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_CONN_IN_PROGRESS =-2141909484; //0x80550E14
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_INVALID_ARGUMENT =-2141909483; //0x80550E15
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_OWN_NP_ID =-2141909482; //0x80550E16
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_TOO_MANY_CONN =-2141909481; //0x80550E17
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_TERMINATED_BY_MYSELF =-2141909480; //0x80550E18
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_MATCHING2_PEER_NOT_FOUND =-2141909479; //0x80550E19
|
||||
SCE_NP_MATCHING2_SIGNALING_ERROR_OWN_PEER_ADDRESS =-2141909478; //0x80550E1A
|
||||
SCE_NP_BANDWIDTH_TEST_ERROR_NOT_INITIALIZED =-2141905150; //0x80551F02
|
||||
SCE_NP_BANDWIDTH_TEST_ERROR_BAD_RESPONSE =-2141905149; //0x80551F03
|
||||
SCE_NP_BANDWIDTH_TEST_ERROR_OUT_OF_MEMORY =-2141905148; //0x80551F04
|
||||
SCE_NP_BANDWIDTH_TEST_ERROR_INVALID_ARGUMENT =-2141905147; //0x80551F05
|
||||
SCE_NP_BANDWIDTH_TEST_ERROR_INVALID_SIZE =-2141905146; //0x80551F06
|
||||
SCE_NP_BANDWIDTH_TEST_ERROR_CONTEXT_NOT_AVAILABLE =-2141905145; //0x80551F07
|
||||
SCE_NP_BANDWIDTH_TEST_ERROR_ABORTED =-2141905144; //0x80551F08
|
||||
SCE_NP_BANDWIDTH_TEST_ERROR_TIMEOUT =-2141905143; //0x80551F09
|
||||
SCE_NP_PARTY_ERROR_UNKNOWN =-2141903615; //0x80552501
|
||||
SCE_NP_PARTY_ERROR_ALREADY_INITIALIZED =-2141903614; //0x80552502
|
||||
SCE_NP_PARTY_ERROR_NOT_INITIALIZED =-2141903613; //0x80552503
|
||||
SCE_NP_PARTY_ERROR_INVALID_ARGUMENT =-2141903612; //0x80552504
|
||||
SCE_NP_PARTY_ERROR_OUT_OF_MEMORY =-2141903611; //0x80552505
|
||||
SCE_NP_PARTY_ERROR_NOT_IN_PARTY =-2141903610; //0x80552506
|
||||
SCE_NP_PARTY_ERROR_VOICE_NOT_ENABLED =-2141903609; //0x80552507
|
||||
SCE_NP_PARTY_ERROR_MEMBER_NOT_FOUND =-2141903608; //0x80552508
|
||||
SCE_NP_PARTY_ERROR_SEND_BUSY =-2141903607; //0x80552509
|
||||
SCE_NP_PARTY_ERROR_SEND_OUT_OF_CONTEXT =-2141903600; //0x80552510
|
||||
SCE_NP_PARTY_ERROR_INVALID_STATE =-2141903599; //0x80552511
|
||||
SCE_NP_PARTY_ERROR_INVALID_LOCAL_PARTY_MEMBER =-2141903598; //0x80552512
|
||||
SCE_NP_PARTY_ERROR_INVALID_PROCESS_TYPE =-2141903597; //0x80552513
|
||||
SCE_NP_PARTY_ERROR_GAME_SESSION_NOT_ENABLED =-2141903596; //0x80552514
|
||||
SCE_NP_PARTY_ERROR_INVALID_PARTY_NO_FRIENDS =-2141903595; //0x80552515
|
||||
SCE_NP_PARTY_ERROR_INVALID_PARTY_IS_GAME_SESSION =-2141903594; //0x80552516
|
||||
SCE_NP_SIGNALING_ERROR_NOT_INITIALIZED =-2141903103; //0x80552701
|
||||
SCE_NP_SIGNALING_ERROR_ALREADY_INITIALIZED =-2141903102; //0x80552702
|
||||
SCE_NP_SIGNALING_ERROR_OUT_OF_MEMORY =-2141903101; //0x80552703
|
||||
SCE_NP_SIGNALING_ERROR_CTXID_NOT_AVAILABLE =-2141903100; //0x80552704
|
||||
SCE_NP_SIGNALING_ERROR_CTX_NOT_FOUND =-2141903099; //0x80552705
|
||||
SCE_NP_SIGNALING_ERROR_REQID_NOT_AVAILABLE =-2141903098; //0x80552706
|
||||
SCE_NP_SIGNALING_ERROR_REQ_NOT_FOUND =-2141903097; //0x80552707
|
||||
SCE_NP_SIGNALING_ERROR_PARSER_CREATE_FAILED =-2141903096; //0x80552708
|
||||
SCE_NP_SIGNALING_ERROR_PARSER_FAILED =-2141903095; //0x80552709
|
||||
SCE_NP_SIGNALING_ERROR_INVALID_NAMESPACE =-2141903094; //0x8055270A
|
||||
SCE_NP_SIGNALING_ERROR_NETINFO_NOT_AVAILABLE =-2141903093; //0x8055270B
|
||||
SCE_NP_SIGNALING_ERROR_PEER_NOT_RESPONDING =-2141903092; //0x8055270C
|
||||
SCE_NP_SIGNALING_ERROR_CONNID_NOT_AVAILABLE =-2141903091; //0x8055270D
|
||||
SCE_NP_SIGNALING_ERROR_CONN_NOT_FOUND =-2141903090; //0x8055270E
|
||||
SCE_NP_SIGNALING_ERROR_PEER_UNREACHABLE =-2141903089; //0x8055270F
|
||||
SCE_NP_SIGNALING_ERROR_TERMINATED_BY_PEER =-2141903088; //0x80552710
|
||||
SCE_NP_SIGNALING_ERROR_TIMEOUT =-2141903087; //0x80552711
|
||||
SCE_NP_SIGNALING_ERROR_CTX_MAX =-2141903086; //0x80552712
|
||||
SCE_NP_SIGNALING_ERROR_RESULT_NOT_FOUND =-2141903085; //0x80552713
|
||||
SCE_NP_SIGNALING_ERROR_CONN_IN_PROGRESS =-2141903084; //0x80552714
|
||||
SCE_NP_SIGNALING_ERROR_INVALID_ARGUMENT =-2141903083; //0x80552715
|
||||
SCE_NP_SIGNALING_ERROR_OWN_NP_ID =-2141903082; //0x80552716
|
||||
SCE_NP_SIGNALING_ERROR_TOO_MANY_CONN =-2141903081; //0x80552717
|
||||
SCE_NP_SIGNALING_ERROR_TERMINATED_BY_MYSELF =-2141903080; //0x80552718
|
||||
SCE_NP_SIGNALING_ERROR_PROHIBITED_TO_USE =-2141903079; //0x80552719
|
||||
SCE_NP_SIGNALING_ERROR_EXCEED_RATE_LIMIT =-2141903078; //0x8055271A
|
||||
SCE_NP_SIGNALING_ERROR_OWN_PEER_ADDRESS =-2141903077; //0x8055271B
|
||||
SCE_NP_WEBAPI_ERROR_OUT_OF_MEMORY =-2141902591; //0x80552901
|
||||
SCE_NP_WEBAPI_ERROR_INVALID_ARGUMENT =-2141902590; //0x80552902
|
||||
SCE_NP_WEBAPI_ERROR_INVALID_LIB_CONTEXT_ID =-2141902589; //0x80552903
|
||||
SCE_NP_WEBAPI_ERROR_LIB_CONTEXT_NOT_FOUND =-2141902588; //0x80552904
|
||||
SCE_NP_WEBAPI_ERROR_USER_CONTEXT_NOT_FOUND =-2141902587; //0x80552905
|
||||
SCE_NP_WEBAPI_ERROR_REQUEST_NOT_FOUND =-2141902586; //0x80552906
|
||||
SCE_NP_WEBAPI_ERROR_NOT_SIGNED_IN =-2141902585; //0x80552907
|
||||
SCE_NP_WEBAPI_ERROR_INVALID_CONTENT_PARAMETER =-2141902584; //0x80552908
|
||||
SCE_NP_WEBAPI_ERROR_ABORTED =-2141902583; //0x80552909
|
||||
SCE_NP_WEBAPI_ERROR_USER_CONTEXT_ALREADY_EXIST =-2141902582; //0x8055290A
|
||||
SCE_NP_WEBAPI_ERROR_PUSH_EVENT_FILTER_NOT_FOUND =-2141902581; //0x8055290B
|
||||
SCE_NP_WEBAPI_ERROR_PUSH_EVENT_CALLBACK_NOT_FOUND =-2141902580; //0x8055290C
|
||||
SCE_NP_WEBAPI_ERROR_HANDLE_NOT_FOUND =-2141902579; //0x8055290D
|
||||
SCE_NP_WEBAPI_ERROR_SERVICE_PUSH_EVENT_FILTER_NOT_FOUND =-2141902578; //0x8055290E
|
||||
SCE_NP_WEBAPI_ERROR_SERVICE_PUSH_EVENT_CALLBACK_NOT_FOUND =-2141902577; //0x8055290F
|
||||
SCE_NP_WEBAPI_ERROR_SIGNED_IN_USER_NOT_FOUND =-2141902576; //0x80552910
|
||||
SCE_NP_WEBAPI_ERROR_LIB_CONTEXT_BUSY =-2141902575; //0x80552911
|
||||
SCE_NP_WEBAPI_ERROR_USER_CONTEXT_BUSY =-2141902574; //0x80552912
|
||||
SCE_NP_WEBAPI_ERROR_REQUEST_BUSY =-2141902573; //0x80552913
|
||||
SCE_NP_WEBAPI_ERROR_INVALID_HTTP_STATUS_CODE =-2141902572; //0x80552914
|
||||
SCE_NP_WEBAPI_ERROR_PROHIBITED_HTTP_HEADER =-2141902571; //0x80552915
|
||||
SCE_NP_WEBAPI_ERROR_PROHIBITED_FUNCTION_CALL =-2141902570; //0x80552916
|
||||
SCE_NP_WEBAPI_ERROR_MULTIPART_PART_NOT_FOUND =-2141902569; //0x80552917
|
||||
SCE_NP_WEBAPI_ERROR_PARAMETER_TOO_LONG =-2141902568; //0x80552918
|
||||
SCE_NP_WEBAPI_ERROR_HANDLE_BUSY =-2141902567; //0x80552919
|
||||
SCE_NP_WEBAPI_ERROR_LIB_CONTEXT_MAX =-2141902566; //0x8055291A
|
||||
SCE_NP_WEBAPI_ERROR_USER_CONTEXT_MAX =-2141902565; //0x8055291B
|
||||
SCE_NP_WEBAPI_ERROR_EXTD_PUSH_EVENT_FILTER_NOT_FOUND =-2141902564; //0x8055291C
|
||||
SCE_NP_WEBAPI_ERROR_EXTD_PUSH_EVENT_CALLBACK_NOT_FOUND =-2141902563; //0x8055291D
|
||||
SCE_NP_WEBAPI_ERROR_AFTER_SEND =-2141902562; //0x8055291E
|
||||
SCE_NP_WEBAPI_ERROR_TIMEOUT =-2141902561; //0x8055291F
|
||||
SCE_NP_AUTH_SERVER_ERROR_UNKNOWN =-2141902336; //0x80552A00
|
||||
SCE_NP_AUTH_SERVER_ERROR_INVALID_REQUEST =-2141902335; //0x80552A01
|
||||
SCE_NP_AUTH_SERVER_ERROR_UNAUTHORIZED_CLIENT =-2141902334; //0x80552A02
|
||||
SCE_NP_AUTH_SERVER_ERROR_ACCESS_DENIED =-2141902333; //0x80552A03
|
||||
SCE_NP_AUTH_SERVER_ERROR_UNSUPPORTED_RESPONSE_TYPE =-2141902332; //0x80552A04
|
||||
SCE_NP_AUTH_SERVER_ERROR_SERVER_ERROR =-2141902330; //0x80552A06
|
||||
SCE_NP_AUTH_SERVER_ERROR_TEMPORARILY_UNAVAILABLE =-2141902329; //0x80552A07
|
||||
SCE_NP_AUTH_SERVER_ERROR_INVALID_GRANT =-2141902327; //0x80552A09
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_05 =-2141902331; //0x80552A05
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_08 =-2141902328; //0x80552A08
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_0A =-2141902326; //0x80552A0A
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_10 =-2141902320; //0x80552A10
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_11 =-2141902319; //0x80552A11
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_12 =-2141902318; //0x80552A12
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_13 =-2141902317; //0x80552A13
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_14 =-2141902316; //0x80552A14
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_15 =-2141902315; //0x80552A15
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_16 =-2141902314; //0x80552A16
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_17 =-2141902313; //0x80552A17
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_18 =-2141902312; //0x80552A18
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_19 =-2141902311; //0x80552A19
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_1A =-2141902310; //0x80552A1A
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_1B =-2141902309; //0x80552A1B
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_1C =-2141902308; //0x80552A1C
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_1D =-2141902307; //0x80552A1D
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_80 =-2141902208; //0x80552A80
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_81 =-2141902207; //0x80552A81
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_82 =-2141902206; //0x80552A82
|
||||
SCE_NP_AUTH_SERVER_ERROR_OBSOLETE_83 =-2141902205; //0x80552A83
|
||||
SCE_NP_IN_GAME_MESSAGE_ERROR_OUT_OF_MEMORY =-2141902079; //0x80552B01
|
||||
SCE_NP_IN_GAME_MESSAGE_ERROR_INVALID_ARGUMENT =-2141902078; //0x80552B02
|
||||
SCE_NP_IN_GAME_MESSAGE_ERROR_LIB_CONTEXT_NOT_FOUND =-2141902077; //0x80552B03
|
||||
SCE_NP_IN_GAME_MESSAGE_ERROR_NOT_SIGNED_IN =-2141902076; //0x80552B04
|
||||
SCE_NP_IN_GAME_MESSAGE_ERROR_HANDLE_NOT_FOUND =-2141902075; //0x80552B05
|
||||
SCE_NP_IN_GAME_MESSAGE_ERROR_ABORTED =-2141902074; //0x80552B06
|
||||
SCE_NP_IN_GAME_MESSAGE_ERROR_SIGNED_IN_USER_NOT_FOUND =-2141902073; //0x80552B07
|
||||
SCE_NP_IN_GAME_MESSAGE_ERROR_NOT_PREPARED =-2141902072; //0x80552B08
|
||||
SCE_NP_IN_GAME_MESSAGE_ERROR_EXCEED_RATE_LIMIT =-2141902071; //0x80552B09
|
||||
SCE_NP_TROPHY_ERROR_UNKNOWN =-2141907456; //0x80551600
|
||||
SCE_NP_TROPHY_ERROR_NOT_INITIALIZED =-2141907455; //0x80551601
|
||||
SCE_NP_TROPHY_ERROR_ALREADY_INITIALIZED =-2141907454; //0x80551602
|
||||
SCE_NP_TROPHY_ERROR_OUT_OF_MEMORY =-2141907453; //0x80551603
|
||||
SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT =-2141907452; //0x80551604
|
||||
SCE_NP_TROPHY_ERROR_INSUFFICIENT_BUFFER =-2141907451; //0x80551605
|
||||
SCE_NP_TROPHY_ERROR_EXCEEDS_MAX =-2141907450; //0x80551606
|
||||
SCE_NP_TROPHY_ERROR_ABORT =-2141907449; //0x80551607
|
||||
SCE_NP_TROPHY_ERROR_INVALID_HANDLE =-2141907448; //0x80551608
|
||||
SCE_NP_TROPHY_ERROR_INVALID_CONTEXT =-2141907447; //0x80551609
|
||||
SCE_NP_TROPHY_ERROR_INVALID_TROPHY_ID =-2141907446; //0x8055160A
|
||||
SCE_NP_TROPHY_ERROR_INVALID_GROUP_ID =-2141907445; //0x8055160B
|
||||
SCE_NP_TROPHY_ERROR_TROPHY_ALREADY_UNLOCKED =-2141907444; //0x8055160C
|
||||
SCE_NP_TROPHY_ERROR_PLATINUM_CANNOT_UNLOCK =-2141907443; //0x8055160D
|
||||
SCE_NP_TROPHY_ERROR_ACCOUNTID_NOT_MATCH =-2141907442; //0x8055160E
|
||||
SCE_NP_TROPHY_ERROR_NOT_REGISTERED =-2141907441; //0x8055160F
|
||||
SCE_NP_TROPHY_ERROR_ALREADY_REGISTERED =-2141907440; //0x80551610
|
||||
SCE_NP_TROPHY_ERROR_BROKEN_DATA =-2141907439; //0x80551611
|
||||
SCE_NP_TROPHY_ERROR_INSUFFICIENT_SPACE =-2141907438; //0x80551612
|
||||
SCE_NP_TROPHY_ERROR_CONTEXT_ALREADY_EXISTS =-2141907437; //0x80551613
|
||||
SCE_NP_TROPHY_ERROR_ICON_FILE_NOT_FOUND =-2141907436; //0x80551614
|
||||
SCE_NP_TROPHY_ERROR_INVALID_TRP_FILE_FORMAT =-2141907434; //0x80551616
|
||||
SCE_NP_TROPHY_ERROR_UNSUPPORTED_TRP_FILE =-2141907433; //0x80551617
|
||||
SCE_NP_TROPHY_ERROR_INVALID_TROPHY_CONF_FORMAT =-2141907432; //0x80551618
|
||||
SCE_NP_TROPHY_ERROR_UNSUPPORTED_TROPHY_CONF =-2141907431; //0x80551619
|
||||
SCE_NP_TROPHY_ERROR_TROPHY_NOT_UNLOCKED =-2141907430; //0x8055161A
|
||||
SCE_NP_TROPHY_ERROR_USER_NOT_FOUND =-2141907428; //0x8055161C
|
||||
SCE_NP_TROPHY_ERROR_USER_NOT_LOGGED_IN =-2141907427; //0x8055161D
|
||||
SCE_NP_TROPHY_ERROR_CONTEXT_USER_LOGOUT =-2141907426; //0x8055161E
|
||||
SCE_NP_TROPHY_ERROR_USE_TRP_FOR_DEVELOPMENT =-2141907425; //0x8055161F
|
||||
SCE_NP_TROPHY_ERROR_INVALID_NP_TITLE_ID =-2141907424; //0x80551620
|
||||
SCE_NP_TROPHY_ERROR_INVALID_NP_SERVICE_LABEL =-2141907423; //0x80551621
|
||||
SCE_NP_TROPHY_ERROR_NOT_SUPPORTED =-2141907422; //0x80551622
|
||||
SCE_NP_TROPHY_ERROR_CONTEXT_EXCEEDS_MAX =-2141907421; //0x80551623
|
||||
SCE_NP_TROPHY_ERROR_HANDLE_EXCEEDS_MAX =-2141907420; //0x80551624
|
||||
SCE_NP_TROPHY_ERROR_INVALID_USER_ID =-2141907419; //0x80551625
|
||||
SCE_NP_TROPHY_ERROR_TITLE_CONF_NOT_INSTALLED =-2141907418; //0x80551626
|
||||
SCE_NP_TROPHY_ERROR_BROKEN_TITLE_CONF =-2141907417; //0x80551627
|
||||
SCE_NP_TROPHY_ERROR_INCONSISTENT_TITLE_CONF =-2141907416; //0x80551628
|
||||
SCE_NP_TROPHY_ERROR_TITLE_BACKGROUND =-2141907415; //0x80551629
|
||||
SCE_NP_TROPHY_ERROR_UNSUPPORTED_TITLE =-2141907414; //0x8055162A
|
||||
SCE_NP_TROPHY_ERROR_SCREENSHOT_DISABLED =-2141907413; //0x8055162B
|
||||
SCE_NP_TROPHY_ERROR_SCREENSHOT_GOTO_PROCESS_SUSPEND =-2141907412; //0x8055162C
|
||||
SCE_NP_TROPHY_ERROR_SCREENSHOT_DISPLAY_BUFFER_NOT_IN_USE =-2141907411; //0x8055162D
|
||||
SCE_NP_TROPHY_ERROR_SCREENSHOT_DISPLAY_BUFFER_ON_MUTE =-2141907410; //0x8055162E
|
||||
SCE_NP_TROPHY_ERROR_SCREENSHOT_DISPLAY_BUFFER_TOO_BIG =-2141907409; //0x8055162F
|
||||
SCE_NP_TROPHY_ERROR_SCREENSHOT_DISPLAY_BUFFER_RETRY_COUNT_MAX =-2141907408; //0x80551630
|
||||
SCE_NP_TROPHY_ERROR_TITLE_NOT_FOUND =-2141907262; //0x805516C2
|
||||
SCE_NP_ID_MAPPER_ERROR_ABORTED =-2141900800; //0x80553000
|
||||
SCE_NP_ID_MAPPER_ERROR_ACCOUNT_ID_NOT_FOUND =-2141900799; //0x80553001
|
||||
SCE_NP_ID_MAPPER_ERROR_ONLINE_ID_NOT_FOUND =-2141900798; //0x80553002
|
||||
SCE_NP_ID_MAPPER_ERROR_NP_ID_NOT_FOUND =-2141900797; //0x80553003
|
||||
SCE_NP_ASM_CLIENT_ERROR_ABORTED =-2141871481; //0x8055A287
|
||||
SCE_NP_ASM_CLIENT_ERROR_NP_SERVICE_LAVEL_NOT_MATCH =-2141871479; //0x8055A289
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_UNKNOWN =-2141900288; //0x80553200
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_NOT_INITIALIZED =-2141900287; //0x80553201
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_ALREADY_INITIALIZED =-2141900286; //0x80553202
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_OUT_OF_MEMORY =-2141900285; //0x80553203
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_INVALID_SIZE =-2141900284; //0x80553204
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_INVALID_ARGUMENT =-2141900283; //0x80553205
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_INVALID_CONTEXT_ID =-2141900282; //0x80553206
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_INVALID_USER_ID =-2141900281; //0x80553207
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_INVALID_SERVICE_LABEL =-2141900280; //0x80553208
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_INVALID_EVENT_HANDLER =-2141900279; //0x80553209
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_INVALID_PEER_ADDRESS =-2141900278; //0x8055320A
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_INVALID_ACCOUNT_ID =-2141900277; //0x8055320B
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_INVALID_PLATFORM_TYPE =-2141900276; //0x8055320C
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_INVALID_SIGNALING_CONNECTION_ID =-2141900275; //0x8055320D
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_INVALID_PEER_CONNECTION_ID =-2141900274; //0x8055320E
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_INVALID_DATA_CHANNEL_ID =-2141900273; //0x8055320F
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_INVALID_DATA_CHANNEL_NUMBER =-2141900272; //0x80553210
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_INVALID_DATA_CHANNEL_OPTION =-2141900271; //0x80553211
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_INVALID_DATA_CHANNEL_OPTION_VALUE =-2141900270; //0x80553212
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_USER_NOT_LOGGED_IN =-2141900269; //0x80553213
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_USER_NOT_SIGNED_IN =-2141900268; //0x80553214
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_CONTEXT_EXCEEDS_MAX =-2141900267; //0x80553215
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_SIGNALING_EXCEEDS_MAX =-2141900266; //0x80553216
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_DATA_CHANNEL_EXCEEDS_MAX =-2141900265; //0x80553217
|
||||
SCE_NP_DATA_COMMUNICATION_ERROR_INSUFFICIENT_BUFFER =-2141900264; //0x80553218
|
||||
SCE_NP_SESSION_SIGNALING_ERROR_NOT_INITIALIZED =-2141900031; //0x80553301
|
||||
SCE_NP_SESSION_SIGNALING_ERROR_ALREADY_INITIALIZED =-2141900030; //0x80553302
|
||||
SCE_NP_SESSION_SIGNALING_ERROR_INVALID_ARGUMENT =-2141900029; //0x80553303
|
||||
SCE_NP_SESSION_SIGNALING_ERROR_OWN_PEER_ADDRESS =-2141900028; //0x80553304
|
||||
SCE_NP_SESSION_SIGNALING_ERROR_OUT_OF_MEMORY =-2141900027; //0x80553305
|
||||
SCE_NP_SESSION_SIGNALING_ERROR_TIMEOUT =-2141900026; //0x80553306
|
||||
SCE_NP_SESSION_SIGNALING_ERROR_CTXID_NOT_AVAILABLE =-2141900025; //0x80553307
|
||||
SCE_NP_SESSION_SIGNALING_ERROR_CTX_NOT_FOUND =-2141900024; //0x80553308
|
||||
SCE_NP_SESSION_SIGNALING_ERROR_GRPID_NOT_AVAILABLE =-2141900023; //0x80553309
|
||||
SCE_NP_SESSION_SIGNALING_ERROR_GRP_NOT_FOUND =-2141900022; //0x8055330A
|
||||
SCE_NP_SESSION_SIGNALING_ERROR_CONNID_NOT_AVAILABLE =-2141900021; //0x8055330B
|
||||
SCE_NP_SESSION_SIGNALING_ERROR_CONN_NOT_FOUND =-2141900020; //0x8055330C
|
||||
SCE_NP_SESSION_SIGNALING_ERROR_PEER_UNREACHABLE =-2141900019; //0x8055330D
|
||||
SCE_NP_SESSION_SIGNALING_ERROR_CONN_IN_PROGRESS =-2141900018; //0x8055330E
|
||||
SCE_NP_SESSION_SIGNALING_ERROR_TERMINATED_BY_PEER =-2141900017; //0x8055330F
|
||||
SCE_NP_SESSION_SIGNALING_ERROR_TERMINATED_BY_MYSELF =-2141900016; //0x80553310
|
||||
SCE_NP_SESSION_SIGNALING_ERROR_TOO_MANY_CONN =-2141900015; //0x80553311
|
||||
SCE_NP_SESSION_SIGNALING_ERROR_GROUP_SIGNALING_ALREADY_ACTIVATED =-2141900014; //0x80553312
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_ALREADY_INITIALIZED =-2141899264; //0x80553600
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_NOT_INITIALIZED =-2141899263; //0x80553601
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_OUT_OF_MEMORY =-2141899262; //0x80553602
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_ARGUMENT =-2141899261; //0x80553603
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_USER_ID =-2141899260; //0x80553604
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_ACCOUNT_ID =-2141899259; //0x80553605
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_PLATFORM_TYPE =-2141899258; //0x80553606
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_ONLINE_ID =-2141899257; //0x80553607
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_SESSION_ID =-2141899256; //0x80553608
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_BRIDGE_ID =-2141899255; //0x80553609
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_BRIDGE_TOKEN =-2141899254; //0x8055360A
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_ETAG =-2141899253; //0x8055360B
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_PEER_ADDRESS =-2141899252; //0x8055360C
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_CHANNEL =-2141899251; //0x8055360D
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_MESSAGE =-2141899250; //0x8055360E
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_PUSH_CONTEXT_ID =-2141899249; //0x8055360F
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_SESSION_CUSTOM_DATA =-2141899248; //0x80553610
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_MEMBER_CUSTOM_DATA =-2141899247; //0x80553611
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_FIELDS =-2141899246; //0x80553612
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_ABORTED =-2141899245; //0x80553613
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_UNKNOWN =-2141899244; //0x80553614
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INSUFFICIENT_BUFFER =-2141899243; //0x80553615
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_ITEM_NOT_FOUND =-2141899242; //0x80553616
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_DATA_MALFORMED =-2141899241; //0x80553617
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_TOPOLOGY =-2141899240; //0x80553618
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_SESSION_NAME =-2141899239; //0x80553619
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_DEVICE_ID =-2141899238; //0x8055361A
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_GROUP_ID =-2141899237; //0x8055361B
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_VIEW_NAME =-2141899236; //0x8055361C
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_EVENT =-2141899235; //0x8055361D
|
||||
SCE_NP_SESSION_MANAGEMENT_CLIENT_ERROR_INVALID_MEMBER_ID =-2141899234; //0x8055361E
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_ALREADY_INITIALIZED =-2141899008; //0x80553700
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_NOT_INITIALIZED =-2141899007; //0x80553701
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_OUT_OF_MEMORY =-2141899006; //0x80553702
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_ARGUMENT =-2141899005; //0x80553703
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_INITIALIZE_PARAMETER =-2141899004; //0x80553704
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_CONTEXT_PARAMETER =-2141899003; //0x80553705
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_HANDLER =-2141899002; //0x80553706
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_CONTEXT_ID =-2141899001; //0x80553707
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_SESSION_OPTION =-2141899000; //0x80553708
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_ACCOUNT_ID =-2141898999; //0x80553709
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_PLATFORM_TYPE =-2141898998; //0x8055370A
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_SESSION_ID =-2141898997; //0x8055370B
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_BRIDGE_INFO =-2141898996; //0x8055370C
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_BRIDGE_ID =-2141898995; //0x8055370D
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_BRIDGE_TOKEN =-2141898994; //0x8055370E
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_ETAG =-2141898993; //0x8055370F
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_CHANNEL =-2141898992; //0x80553710
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_MESSAGE =-2141898991; //0x80553711
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_REQUEST =-2141898990; //0x80553712
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_REQUEST_ID =-2141898989; //0x80553713
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_REQUEST_CALLBACK =-2141898988; //0x80553714
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_REQUEST_CALLBACK_ALREADY_REGISTERED =-2141898987; //0x80553715
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_SESSION_DATA_VALUE_TYPE =-2141898986; //0x80553716
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_MEMBER_DATA_VALUE_TYPE =-2141898985; //0x80553717
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_SESSION_DATA_VALUE =-2141898984; //0x80553718
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_MEMBER_DATA_VALUE =-2141898983; //0x80553719
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_MEMBER_ID =-2141898982; //0x8055371A
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_ABORTED =-2141898981; //0x8055371B
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_CONTEXT_NOT_STARTED =-2141898980; //0x8055371C
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_CONTEXT_ALREADY_STARTED =-2141898979; //0x8055371D
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_UNKNOWN =-2141898978; //0x8055371E
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INSUFFICIENT_BUFFER =-2141898977; //0x8055371F
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_REQUEST_NOT_FOUND =-2141898976; //0x80553720
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_SESSION_NOT_FOUND =-2141898975; //0x80553721
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_SESSION_ALREADY_EXISTS =-2141898974; //0x80553722
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_CONTEXT_SLOT_EXCEEDS_MAX =-2141898973; //0x80553723
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_UNEXPECTED_DEACTIVATED_ERRCODE =-2141898972; //0x80553724
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_CMD_HANDLER_STOPPED =-2141898971; //0x80553725
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_MEMBER_NOT_FOUND =-2141898970; //0x80553726
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_MEMBER_ALREADY_EXISTS =-2141898969; //0x80553727
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_SESSION_STATE =-2141898968; //0x80553728
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_SESSION_RELEASED =-2141898967; //0x80553729
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_MEMBER_FULL =-2141898966; //0x8055372A
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_CONTEXT_TYPE =-2141898965; //0x8055372B
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_REQUEST_NOT_FINISHED =-2141898964; //0x8055372C
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_QUEUE_EMPTY =-2141898963; //0x8055372D
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_PRESENCE_OFFLINE_DETECTED =-2141898962; //0x8055372E
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_PROPERTY =-2141898961; //0x8055372F
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_PROPERTY_NOT_FOUND =-2141898960; //0x80553730
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_UNSUPPORTED_OPERATION =-2141898959; //0x80553731
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_GROUP_ID =-2141898958; //0x80553732
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_VIEW_NAME =-2141898957; //0x80553733
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_BRIDGE_INFO_NOT_FOUND =-2141898956; //0x80553734
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_ITEM_NOT_FOUND =-2141898955; //0x80553735
|
||||
SCE_NP_SESSION_MANAGEMENT_MANAGER_ERROR_INVALID_SESSION_CUSTOM_DATA =-2141898954; //0x80553736
|
||||
SCE_NP_GAME_INTENT_ERROR_UNKNOWN =-2141898752; //0x80553800
|
||||
SCE_NP_GAME_INTENT_ERROR_ALREADY_INITIALIZED =-2141898751; //0x80553801
|
||||
SCE_NP_GAME_INTENT_ERROR_NOT_INITIALIZED =-2141898750; //0x80553802
|
||||
SCE_NP_GAME_INTENT_ERROR_OUT_OF_MEMORY =-2141898749; //0x80553803
|
||||
SCE_NP_GAME_INTENT_ERROR_INVALID_ARGUMENT =-2141898748; //0x80553804
|
||||
SCE_NP_GAME_INTENT_ERROR_INSUFFICIENT_BUFFER =-2141898747; //0x80553805
|
||||
SCE_NP_GAME_INTENT_ERROR_INTENT_NOT_FOUND =-2141898746; //0x80553806
|
||||
SCE_NP_GAME_INTENT_ERROR_VALUE_NOT_FOUND =-2141898745; //0x80553807
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
unit ps4_libSceNpAuth;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
ps4_program,
|
||||
np_error,
|
||||
ps4_libSceNpCommon,
|
||||
sys_kernel;
|
||||
|
||||
const
|
||||
SCE_NP_CLIENT_ID_MAX_LEN=128;
|
||||
SCE_NP_CLIENT_SECRET_MAX_LEN=256;
|
||||
SCE_NP_AUTHORIZATION_CODE_MAX_LEN=128;
|
||||
SCE_NP_ID_TOKEN_MAX_LEN=4096;
|
||||
|
||||
type
|
||||
pSceNpClientId=^SceNpClientId;
|
||||
SceNpClientId=packed record
|
||||
id:array[0..SCE_NP_CLIENT_ID_MAX_LEN] of char;
|
||||
padding:array[0..6] of Byte;
|
||||
end;
|
||||
|
||||
pSceNpClientSecret=^SceNpClientSecret;
|
||||
SceNpClientSecret=packed record
|
||||
secret:array[0..SCE_NP_CLIENT_SECRET_MAX_LEN] of char;
|
||||
padding:array[0..6] of Byte;
|
||||
end;
|
||||
|
||||
pSceNpAuthCreateAsyncRequestParameter=^SceNpAuthCreateAsyncRequestParameter;
|
||||
SceNpAuthCreateAsyncRequestParameter=packed record
|
||||
size:QWORD;
|
||||
cpuAffinityMask:QWORD;
|
||||
threadPriority:Integer;
|
||||
padding:array[0..3] of Byte;
|
||||
end;
|
||||
|
||||
pSceNpAuthGetAuthorizationCodeParameter=^SceNpAuthGetAuthorizationCodeParameter;
|
||||
SceNpAuthGetAuthorizationCodeParameter=packed record
|
||||
size:QWORD;
|
||||
pOnlineId:pSceNpOnlineId;
|
||||
pClientId:pSceNpClientId;
|
||||
scope:PChar;
|
||||
end;
|
||||
|
||||
pSceNpAuthorizationCode=^SceNpAuthorizationCode;
|
||||
SceNpAuthorizationCode=packed record
|
||||
code:array[0..SCE_NP_AUTHORIZATION_CODE_MAX_LEN] of char;
|
||||
padding:array[0..6] of Byte;
|
||||
end;
|
||||
|
||||
pSceNpAuthGetIdTokenParameterA=^SceNpAuthGetIdTokenParameterA;
|
||||
SceNpAuthGetIdTokenParameterA=packed record
|
||||
size:QWORD;
|
||||
userId:Integer;
|
||||
padding:array[0..3] of Byte;
|
||||
clientId:pSceNpClientId;
|
||||
clientSecret:pSceNpClientSecret;
|
||||
scope:PChar;
|
||||
end;
|
||||
|
||||
pSceNpIdToken=^SceNpIdToken;
|
||||
SceNpIdToken=packed record
|
||||
token:array[0..SCE_NP_ID_TOKEN_MAX_LEN] of char;
|
||||
padding:array[0..6] of Byte;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
function ps4_sceNpAuthCreateRequest():Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln(SysLogPrefix,'sceNpAuthCreateRequest');
|
||||
Result:=-1;
|
||||
end;
|
||||
|
||||
function ps4_sceNpAuthCreateAsyncRequest(const pParam:pSceNpAuthCreateAsyncRequestParameter):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceNpAuthGetAuthorizationCode(reqId:Integer;
|
||||
const param:pSceNpAuthGetAuthorizationCodeParameter;
|
||||
authCode:pSceNpAuthorizationCode;
|
||||
issuerId:PInteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceNpAuthPollAsync(reqId:Integer;pResult:PInteger):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceNpAuthDeleteRequest(reqId:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceNpAuthGetIdTokenA(reqId:Integer;
|
||||
const param:pSceNpAuthGetIdTokenParameterA;
|
||||
idToken:pSceNpIdToken):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln(SysLogPrefix,'sceNpAuthGetIdTokenA');
|
||||
FillChar(idToken^, SizeOf(SceNpIdToken), 0);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function Load_libSceNpAuth(Const name:RawByteString):TElf_node;
|
||||
var
|
||||
lib:PLIBRARY;
|
||||
begin
|
||||
Result:=TElf_node.Create;
|
||||
Result.pFileName:=name;
|
||||
|
||||
lib:=Result._add_lib('libSceNpAuth');
|
||||
lib^.set_proc($E9BC05928B184508,@ps4_sceNpAuthCreateRequest);
|
||||
lib^.set_proc($37E9ABEC68D3BEBF,@ps4_sceNpAuthCreateAsyncRequest);
|
||||
lib^.set_proc($2B11A43AB4094EA6,@ps4_sceNpAuthGetAuthorizationCode);
|
||||
lib^.set_proc($8234B27F34AC0DC1,@ps4_sceNpAuthPollAsync);
|
||||
lib^.set_proc($1FCC06F4193F9CF7,@ps4_sceNpAuthDeleteRequest);
|
||||
lib^.set_proc($0A871B1D520A3C4F,@ps4_sceNpAuthGetIdTokenA);
|
||||
end;
|
||||
|
||||
initialization
|
||||
ps4_app.RegistredPreLoad('libSceNpAuth.prx' ,@Load_libSceNpAuth);
|
||||
|
||||
end.
|
||||
|
|
@ -0,0 +1,328 @@
|
|||
unit ps4_libSceNpCommon;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
ps4_program,
|
||||
np_error;
|
||||
|
||||
const
|
||||
SCE_NP_DEFAULT_SERVICE_LABEL=$00000000;
|
||||
SCE_NP_INVALID_SERVICE_LABEL=$FFFFFFFF;
|
||||
|
||||
SCE_NP_ONLINEID_MIN_LENGTH=3;
|
||||
SCE_NP_ONLINEID_MAX_LENGTH=16;
|
||||
|
||||
SCE_NP_COMMUNICATION_PASSPHRASE_SIZE=128;
|
||||
|
||||
SCE_NP_ARCH_ERROR_UNKNOWN=-2141880310;
|
||||
|
||||
type
|
||||
SceNpServiceLabel=DWORD;
|
||||
|
||||
pSceNpAccountId=^SceNpAccountId;
|
||||
SceNpAccountId=QWORD;
|
||||
|
||||
SceNpPlatformType=Integer;
|
||||
|
||||
pSceNpOnlineId=^SceNpOnlineId;
|
||||
SceNpOnlineId=packed record
|
||||
data :array[0..SCE_NP_ONLINEID_MAX_LENGTH-1] of AnsiChar;
|
||||
term :AnsiChar;
|
||||
dummy:array[0..2] of AnsiChar;
|
||||
end;
|
||||
|
||||
PSceNpId=^SceNpId;
|
||||
SceNpId=packed record
|
||||
handle :SceNpOnlineId;
|
||||
opt :array[0..7] of Byte;
|
||||
reserved:array[0..7] of Byte;
|
||||
end;
|
||||
|
||||
pSceNpCommunicationId=^SceNpCommunicationId;
|
||||
SceNpCommunicationId=packed record
|
||||
data :array[0..8] of Char;
|
||||
term :Char;
|
||||
num :Byte;
|
||||
dummy:Char;
|
||||
end;
|
||||
|
||||
pSceNpCommunicationPassphrase=^SceNpCommunicationPassphrase;
|
||||
SceNpCommunicationPassphrase=packed record
|
||||
data:array[0..SCE_NP_COMMUNICATION_PASSPHRASE_SIZE-1] of Byte;
|
||||
end;
|
||||
|
||||
pSceNpHeap=^SceNpHeap;
|
||||
SceNpHeap=packed record
|
||||
mspace:Pointer;
|
||||
end;
|
||||
|
||||
type
|
||||
SceNpMallocFunc =function(size:size_t;userdata:Pointer):Pointer; SysV_ABI_CDecl;
|
||||
SceNpReallocFunc=function(ptr:Pointer;size:size_t;userdata:Pointer):Pointer; SysV_ABI_CDecl;
|
||||
SceNpFreeFunc =procedure(ptr,userdata:Pointer); SysV_ABI_CDecl;
|
||||
|
||||
pSceNpAllocator=^SceNpAllocator;
|
||||
SceNpAllocator=packed record
|
||||
mallocFunc :SceNpMallocFunc;
|
||||
reallocFunc:SceNpReallocFunc;
|
||||
freeFunc :SceNpFreeFunc;
|
||||
userdata :Pointer;
|
||||
end;
|
||||
|
||||
PSceNpObject=^SceNpObject;
|
||||
SceNpObject=packed record
|
||||
mem :pSceNpAllocator; // 8
|
||||
_unk1:QWord; // 16
|
||||
entry:Pointer; // 24
|
||||
end;
|
||||
|
||||
pSceNpHeapStat=^SceNpHeapStat;
|
||||
SceNpHeapStat=packed record
|
||||
maxSystemSize :QWORD;
|
||||
maxInuseSize :QWORD;
|
||||
currentInuseSize:QWORD;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
ps4_event_flag,
|
||||
ps4_mspace_internal,
|
||||
ps4_mutex,
|
||||
ps4_map_mm;
|
||||
|
||||
function ps4_sceNpCmpNpId(npid1,npid2:PSceNpId):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (npid1=nil) or (npid2=nil) then Exit(SCE_NP_ERROR_INVALID_ARGUMENT);
|
||||
|
||||
if (CompareChar0(npid1^.handle,npid2^.handle,SCE_NP_ONLINEID_MAX_LENGTH)=0) and
|
||||
(QWORD(npid1^.opt)=QWORD(npid2^.opt)) then
|
||||
begin
|
||||
Result:=0;
|
||||
end else
|
||||
begin
|
||||
Result:=SCE_NP_UTIL_ERROR_NOT_MATCH;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function ps4_sceNpCmpOnlineId(str1,str2:PChar):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (str1=nil) or (str2=nil) then
|
||||
Exit(SCE_NP_ERROR_INVALID_ARGUMENT);
|
||||
if CompareChar0(str1,str2,SCE_NP_ONLINEID_MAX_LENGTH)=0 then
|
||||
Result:=0
|
||||
else
|
||||
Result:=SCE_NP_UTIL_ERROR_NOT_MATCH;
|
||||
end;
|
||||
|
||||
type
|
||||
pnp_mem=^np_mem;
|
||||
np_mem=packed record
|
||||
len:qword;
|
||||
unknow:qword;
|
||||
ptr:Pointer;
|
||||
end;
|
||||
|
||||
function ps4_sceNpAllocateKernelMemoryWithAlignment(
|
||||
len:qword;
|
||||
name:Pchar;
|
||||
ptr_out:PPointer;
|
||||
mem_out:pnp_mem):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
pad_len:qword;
|
||||
begin
|
||||
if (mem_out=nil) then
|
||||
begin
|
||||
Exit(-$7faa7ffb); //NP-32268-1
|
||||
end;
|
||||
|
||||
mem_out^.unknow:=0;
|
||||
pad_len:=0;
|
||||
if (len and $3fff)<>0 then
|
||||
begin
|
||||
pad_len:=$4000-(len and $3fff);
|
||||
end;
|
||||
mem_out^.len:=pad_len+len;
|
||||
|
||||
Result:=ps4_sceKernelMapNamedFlexibleMemory(@mem_out^.ptr,mem_out^.len,3,0,name);
|
||||
|
||||
if (ptr_out<>nil) and (Result>-1) then
|
||||
begin
|
||||
ptr_out^:=mem_out^.ptr;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_sceNpAllocateKernelMemoryNoAlignment(
|
||||
len:qword;
|
||||
name:Pchar;
|
||||
ptr_out:PPointer;
|
||||
mem_out:pnp_mem):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
if (mem_out=nil) then
|
||||
begin
|
||||
Exit(-$7faa7ffb); //NP-32268-1
|
||||
end;
|
||||
|
||||
mem_out^.unknow:=0;
|
||||
mem_out^.len:=len;
|
||||
|
||||
Result:=ps4_sceKernelMapNamedFlexibleMemory(@mem_out^.ptr,mem_out^.len,3,0,name);
|
||||
|
||||
if (ptr_out<>nil) and (Result>-1) then
|
||||
begin
|
||||
ptr_out^:=mem_out^.ptr;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_sceNpMutexInit(mutex:PScePthreadMutex;name:PChar;isRecursive:Boolean):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
attr:pthread_mutex_attr;
|
||||
begin
|
||||
Result:=ps4_scePthreadMutexattrInit(@attr);
|
||||
if Result=0 then
|
||||
begin
|
||||
if isRecursive then
|
||||
Result:=ps4_scePthreadMutexattrSettype(@attr,SCE_PTHREAD_MUTEX_RECURSIVE);
|
||||
if Result=0 then
|
||||
Result:=ps4_scePthreadMutexInit(mutex,@attr,name);
|
||||
ps4_scePthreadMutexattrDestroy(@attr);
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_sceNpMutexLock(mutex:PScePthreadMutex):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=ps4_scePthreadMutexLock(mutex);
|
||||
end;
|
||||
|
||||
function ps4_sceNpMutexUnlock(mutex:PScePthreadMutex):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=ps4_scePthreadMutexUnlock(mutex);
|
||||
end;
|
||||
|
||||
function ps4_sceNpMutexTryLock(mutex:PScePthreadMutex):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=ps4_scePthreadMutexTryLock(mutex);
|
||||
end;
|
||||
|
||||
function ps4_sceNpMutexDestroy(mutex:PScePthreadMutex):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=ps4_scePthreadMutexDestroy(mutex);
|
||||
end;
|
||||
|
||||
function ps4_sceNpHeapInit(heap:pSceNpHeap;base:Pointer;capacity:size_t;name:PChar):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
m:Pointer;
|
||||
begin
|
||||
Result:=SCE_NP_ARCH_ERROR_UNKNOWN;
|
||||
if heap<>nil then
|
||||
begin
|
||||
m:=ps4_sceLibcMspaceCreate(name,base,capacity,0);
|
||||
if (m<>nil) then
|
||||
begin
|
||||
heap^.mspace:=m;
|
||||
Result:=0;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4__sceNpHeapMalloc(heap:pSceNpHeap;size:size_t):Pointer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=nil;
|
||||
if (heap^.mspace<>nil) then
|
||||
begin
|
||||
Result:=ps4_sceLibcMspaceMalloc(heap^.mspace,size);
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_sceNpHeapGetStat(heap:pSceNpHeap;stat:pSceNpHeapStat):Integer; SysV_ABI_CDecl;
|
||||
var
|
||||
data:SceLibcMallocManagedSize;
|
||||
begin
|
||||
data:=Default(SceLibcMallocManagedSize);
|
||||
data.size :=40;
|
||||
data.version:=1;
|
||||
|
||||
Result:=ps4_sceLibcMspaceMallocStats(heap^.mspace,@data);
|
||||
|
||||
if (Result=0) then
|
||||
begin
|
||||
stat^.maxSystemSize :=data.maxSystemSize;
|
||||
stat^.maxInuseSize :=data.maxInuseSize;
|
||||
stat^.currentInuseSize:=data.currentInuseSize;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure ps4_sceNpHeapDestroy(heap:pSceNpHeap); SysV_ABI_CDecl;
|
||||
begin
|
||||
if (heap^.mspace<>nil) then
|
||||
begin
|
||||
ps4_sceLibcMspaceDestroy(heap^.mspace);
|
||||
heap^.mspace:=nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_sceNpCreateEventFlag(ef:pSceKernelEventFlag;
|
||||
pName:PChar;
|
||||
attr:DWORD;
|
||||
initPattern:QWORD
|
||||
):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=ps4_sceKernelCreateEventFlag(ef,pName,attr,initPattern,nil);
|
||||
Result:=(Result shr $1F) and Result; // Looks like bool, but True when Result<0
|
||||
end;
|
||||
|
||||
//void * sce::np::Object::operator_new(size_t size,SceNpAllocator *mem)
|
||||
function ps4__ZN3sce2np6ObjectnwEmR14SceNpAllocator(size:size_t;mem:pSceNpAllocator):Pointer; SysV_ABI_CDecl;
|
||||
var
|
||||
npObj:PSceNpObject;
|
||||
begin
|
||||
npObj:=mem^.mallocFunc(size+$10,mem^.userdata);
|
||||
if npObj<>nil then
|
||||
begin
|
||||
npObj^.mem:=mem;
|
||||
Result:=@npObj^.entry;
|
||||
end else
|
||||
Result:=nil;
|
||||
end;
|
||||
|
||||
function Load_libSceNpCommon(Const name:RawByteString):TElf_node;
|
||||
var
|
||||
lib:PLIBRARY;
|
||||
begin
|
||||
Result:=TElf_node.Create;
|
||||
Result.pFileName:=name;
|
||||
|
||||
lib:=Result._add_lib('libSceNpCommon');
|
||||
lib^.set_proc($8BC5265D34AAECDE,@ps4_sceNpCmpNpId);
|
||||
lib^.set_proc($763F8EE5A0F66B44,@ps4_sceNpCmpOnlineId);
|
||||
lib^.set_proc($80C958E9E7B0AFF7,@ps4_sceNpAllocateKernelMemoryWithAlignment);
|
||||
lib^.set_proc($3163CE92ACD8B2CD,@ps4_sceNpAllocateKernelMemoryNoAlignment);
|
||||
lib^.set_proc($B84C1A83FD1864F7,@ps4_sceNpMutexInit);
|
||||
lib^.set_proc($AFD05EB7EB3A7CA7,@ps4_sceNpMutexLock);
|
||||
lib^.set_proc($A19C9BF64B6E0A90,@ps4_sceNpMutexUnlock);
|
||||
lib^.set_proc($0EEB259A8A90FA79,@ps4_sceNpMutexTryLock);
|
||||
lib^.set_proc($950D7506930CE0B5,@ps4_sceNpMutexDestroy);
|
||||
// These sceNpLwMutexXxx have the same interface & functionally as sceNpMutexXxx
|
||||
lib^.set_proc($D4289723F33210AB,@ps4_sceNpMutexInit); // sceNpLwMutexInit
|
||||
lib^.set_proc($D7C8FEAA4E9D4709,@ps4_sceNpMutexLock); // sceNpLwMutexLock
|
||||
lib^.set_proc($0901B6A32C75FE73,@ps4_sceNpMutexUnlock); // sceNpLwMutexUnlock
|
||||
lib^.set_proc($869D24560BB9171C,@ps4_sceNpMutexTryLock); // sceNpLwMutexTryLock
|
||||
lib^.set_proc($E33C5EBE082D62B4,@ps4_sceNpMutexDestroy); // sceNpLwMutexDestroy
|
||||
//
|
||||
lib^.set_proc($07EC86217D7E0532,@ps4_sceNpHeapInit);
|
||||
lib^.set_proc($9305B9A9D75FF8BA,@ps4__sceNpHeapMalloc);
|
||||
lib^.set_proc($DA3747A0FA52F96D,@ps4_sceNpHeapGetStat);
|
||||
lib^.set_proc($C15767EFC1CA737D,@ps4_sceNpHeapDestroy);
|
||||
lib^.set_proc($EA3156A407EA01C7,@ps4_sceNpCreateEventFlag);
|
||||
lib^.set_proc($D2CC8D921240355C,@ps4__ZN3sce2np6ObjectnwEmR14SceNpAllocator);
|
||||
end;
|
||||
|
||||
initialization
|
||||
ps4_app.RegistredPreLoad('libSceNpCommon.prx' ,@Load_libSceNpCommon);
|
||||
|
||||
end.
|
||||
|