1.20
24
.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
|
||||
o/**
|
||||
.gradle/
|
||||
.idea/
|
||||
local.properties
|
||||
|
||||
app/build.gradle
|
||||
|
||||
aps3e.keystore
|
||||
aps3e.jks
|
||||
app/release/
|
||||
app/.cxx/
|
||||
app/src/main/java/aenu/aps3e/R.java
|
||||
|
||||
app/src/main/cpp/ab/
|
||||
app/src/main/cpp/ffmpeg_android/
|
||||
app/src/main/cpp/iconv_out/
|
||||
app/src/main/cpp/iso_t/
|
||||
app/src/main/cpp/llvm_out/
|
||||
app/src/main/cpp/ffmpeg_out/
|
||||
app/src/main/cpp/glslang_out/
|
||||
|
||||
app/src/main/lib/
|
||||
1
app/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
81
app/build.gradle.bak
Normal file
@@ -0,0 +1,81 @@
|
||||
plugins {
|
||||
alias(libs.plugins.android.application)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'aenu.aps3e'
|
||||
compileSdk 35
|
||||
|
||||
defaultConfig {
|
||||
applicationId "aenu.aps3e"
|
||||
//applicationId "aenu.aps3e.premium"
|
||||
|
||||
minSdk 28
|
||||
targetSdk 34
|
||||
versionCode 19
|
||||
versionName "1.19a"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
abiFilters 'arm64-v8a'
|
||||
cppFlags ''
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets{
|
||||
main {
|
||||
//jniLibs.srcDirs = ['src/main/lib']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
}
|
||||
debug {
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
debug {
|
||||
minifyEnabled false
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
}
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path file('src/main/cpp/CMakeLists.txt')
|
||||
version '3.22.1'
|
||||
}
|
||||
}
|
||||
|
||||
packaging{
|
||||
jniLibs.useLegacyPackaging = true
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation libs.appcompat
|
||||
implementation libs.material
|
||||
implementation libs.activity
|
||||
implementation libs.constraintlayout
|
||||
implementation libs.preference
|
||||
testImplementation libs.junit
|
||||
androidTestImplementation libs.ext.junit
|
||||
androidTestImplementation libs.espresso.core
|
||||
}
|
||||
23
app/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
-keep class **.R$* { *; }
|
||||
-keep class **.R { *; }
|
||||
@@ -0,0 +1,26 @@
|
||||
package aenu.aps3e;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
assertEquals("aenu.aps3e", appContext.getPackageName());
|
||||
}
|
||||
}
|
||||
83
app/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!--安卓高版本创建socket需要-->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="32" />
|
||||
|
||||
<application android:label="@string/app_name"
|
||||
|
||||
android:name="aenu.aps3e.Application"
|
||||
android:allowNativeHeapPointerTagging="false"
|
||||
android:icon="@drawable/app_icon"
|
||||
android:isGame="true">
|
||||
<activity android:name="aenu.aps3e.MainActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="aenu.proptest.HelloJni"
|
||||
android:exported="false"
|
||||
android:label="@string/about">
|
||||
</activity>
|
||||
<activity android:name="aenu.aps3e.TextActivity"
|
||||
android:exported="false">
|
||||
</activity>
|
||||
<activity android:name="aenu.aps3e.KeyMapActivity"
|
||||
android:exported="false"
|
||||
android:label="@string/key_mappers"/>
|
||||
<activity android:name="aenu.aps3e.UserDataActivity"
|
||||
android:theme="@style/Theme.AppCompat"
|
||||
android:exported="false"/>
|
||||
<activity android:name="aenu.aps3e.VirtualPadEdit"
|
||||
android:screenOrientation="sensorLandscape"
|
||||
android:configChanges="layoutDirection|locale|orientation|uiMode|screenLayout|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
|
||||
android:exported="false"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||
android:launchMode="singleTask"/>
|
||||
<activity android:name="aenu.aps3e.EmulatorActivity"
|
||||
|
||||
android:screenOrientation="sensorLandscape"
|
||||
android:launchMode="singleTask"
|
||||
android:configChanges="layoutDirection|locale|orientation|uiMode|screenLayout|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
|
||||
android:exported="false"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||
android:process=":emu"
|
||||
>
|
||||
<intent-filter>
|
||||
<action android:name="aenu.intent.action.APS3E" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="aenu.aps3e.EmulatorSettings"
|
||||
android:theme="@style/Theme.AppCompat"
|
||||
android:exported="false"
|
||||
android:label="@string/settings"/>
|
||||
<provider
|
||||
android:name="aenu.aps3e.DocumentsProvider"
|
||||
android:authorities="${applicationId}.provider"
|
||||
android:exported="true"
|
||||
android:grantUriPermissions="true"
|
||||
android:permission="android.permission.MANAGE_DOCUMENTS">
|
||||
<intent-filter>
|
||||
<action android:name="android.content.action.DOCUMENTS_PROVIDER" />
|
||||
</intent-filter>
|
||||
</provider>
|
||||
<provider
|
||||
android:name="aenu.aps3e.InnerDocumentsProvider"
|
||||
android:authorities="${applicationId}.inner.provider"
|
||||
android:exported="true"
|
||||
android:grantUriPermissions="true"
|
||||
android:permission="android.permission.MANAGE_DOCUMENTS">
|
||||
<intent-filter>
|
||||
<action android:name="android.content.action.DOCUMENTS_PROVIDER" />
|
||||
</intent-filter>
|
||||
</provider>
|
||||
</application>
|
||||
</manifest>
|
||||
BIN
app/src/main/assets/Icons/ui/L1.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/assets/Icons/ui/L2.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
app/src/main/assets/Icons/ui/R1.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
app/src/main/assets/Icons/ui/R2.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/main/assets/Icons/ui/circle.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
app/src/main/assets/Icons/ui/cross.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
app/src/main/assets/Icons/ui/dpad.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
app/src/main/assets/Icons/ui/dpad_down.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
app/src/main/assets/Icons/ui/dpad_left.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
app/src/main/assets/Icons/ui/dpad_right.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
app/src/main/assets/Icons/ui/dpad_up.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
app/src/main/assets/Icons/ui/fade_bottom.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
app/src/main/assets/Icons/ui/fade_top.png
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
app/src/main/assets/Icons/ui/left_stick.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/assets/Icons/ui/new.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
app/src/main/assets/Icons/ui/right_stick.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
app/src/main/assets/Icons/ui/save.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
app/src/main/assets/Icons/ui/select.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
app/src/main/assets/Icons/ui/spinner-24.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
app/src/main/assets/Icons/ui/square.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
app/src/main/assets/Icons/ui/start.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/main/assets/Icons/ui/triangle.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
245
app/src/main/assets/config/config.yml
Normal file
@@ -0,0 +1,245 @@
|
||||
Core:
|
||||
PPU Decoder: Recompiler (LLVM)
|
||||
PPU Threads: 2
|
||||
PPU Debug: false
|
||||
PPU Calling History: false
|
||||
Save LLVM logs: false
|
||||
Use LLVM CPU: ""
|
||||
Max LLVM Compile Threads: 4
|
||||
LLVM Precompilation: true
|
||||
Thread Scheduler Mode: Operating System
|
||||
Set DAZ and FTZ: false
|
||||
SPU Decoder: Recompiler (LLVM)
|
||||
SPU Reservation Busy Waiting Percentage: 0
|
||||
SPU GETLLAR Busy Waiting Percentage: 100
|
||||
Disable SPU GETLLAR Spin Optimization: false
|
||||
SPU Debug: false
|
||||
MFC Debug: false
|
||||
Preferred SPU Threads: 0
|
||||
SPU delay penalty: 3
|
||||
SPU loop detection: false
|
||||
Max SPURS Threads: 6
|
||||
SPU Block Size: Safe
|
||||
Accurate SPU DMA: false
|
||||
Accurate SPU Reservations: true
|
||||
Accurate Cache Line Stores: false
|
||||
Accurate RSX reservation access: false
|
||||
RSX FIFO Accuracy: Fast
|
||||
SPU Verification: true
|
||||
SPU Cache: true
|
||||
SPU Profiler: false
|
||||
MFC Commands Shuffling Limit: 0
|
||||
MFC Commands Timeout: 0
|
||||
MFC Commands Shuffling In Steps: false
|
||||
Enable TSX: Disabled
|
||||
XFloat Accuracy: Approximate
|
||||
Accurate PPU 128-byte Reservation Op Max Length: 0
|
||||
Stub PPU Traps: 0
|
||||
Precise SPU Verification: false
|
||||
PPU LLVM Java Mode Handling: true
|
||||
Use Accurate DFMA: true
|
||||
PPU Set Saturation Bit: false
|
||||
PPU Accurate Non-Java Mode: false
|
||||
PPU Fixup Vector NaN Values: false
|
||||
PPU Accurate Vector NaN Values: false
|
||||
PPU Set FPCC Bits: false
|
||||
Debug Console Mode: false
|
||||
Hook static functions: false
|
||||
Libraries Control: []
|
||||
HLE lwmutex: false
|
||||
SPU LLVM Lower Bound: 0
|
||||
SPU LLVM Upper Bound: 18446744073709551615
|
||||
TSX Transaction First Limit: 800
|
||||
TSX Transaction Second Limit: 2000
|
||||
Clocks scale: 100
|
||||
SPU Wake-Up Delay: 0
|
||||
SPU Wake-Up Delay Thread Mask: 63
|
||||
Max CPU Preempt Count: 0
|
||||
Allow RSX CPU Preemptions: true
|
||||
Sleep Timers Accuracy: As Host
|
||||
Usleep Time Addend: 0
|
||||
Performance Report Threshold: 500
|
||||
Enable Performance Report: false
|
||||
Assume External Debugger: false
|
||||
VFS:
|
||||
Enable /host_root/: false
|
||||
Initialize Directories: true
|
||||
Limit disk cache size: false
|
||||
Disk cache maximum size (MB): 5120
|
||||
Empty /dev_hdd0/tmp/: true
|
||||
Video:
|
||||
Renderer: Vulkan
|
||||
Resolution: 1280x720
|
||||
Aspect ratio: 16:9
|
||||
Frame limit: Auto
|
||||
Second Frame Limit: 0
|
||||
MSAA: Auto
|
||||
Shader Mode: Async Shader Recompiler
|
||||
Shader Precision: High
|
||||
Write Color Buffers: false
|
||||
Write Depth Buffer: false
|
||||
Read Color Buffers: false
|
||||
Read Depth Buffer: false
|
||||
Handle RSX Memory Tiling: false
|
||||
Log shader programs: false
|
||||
VSync: false
|
||||
Debug output: false
|
||||
Debug overlay: false
|
||||
Renderdoc Compatibility Mode: false
|
||||
Use GPU texture scaling: false
|
||||
Stretch To Display Area: false
|
||||
Force High Precision Z buffer: false
|
||||
Strict Rendering Mode: false
|
||||
Disable ZCull Occlusion Queries: false
|
||||
Disable Video Output: false
|
||||
Disable Vertex Cache: false
|
||||
Disable FIFO Reordering: false
|
||||
Enable Frame Skip: false
|
||||
Force CPU Blit: false
|
||||
Disable On-Disk Shader Cache: false
|
||||
Disable Vulkan Memory Allocator: false
|
||||
Use full RGB output range: true
|
||||
Strict Texture Flushing: false
|
||||
Multithreaded RSX: false
|
||||
Relaxed ZCULL Sync: false
|
||||
Force Hardware MSAA Resolve: false
|
||||
3D Display Mode: Disabled
|
||||
Debug Program Analyser: false
|
||||
Accurate ZCULL stats: true
|
||||
Consecutive Frames To Draw: 1
|
||||
Consecutive Frames To Skip: 1
|
||||
Resolution Scale: 100
|
||||
Anisotropic Filter Override: 0
|
||||
Texture LOD Bias Addend: 0
|
||||
Minimum Scalable Dimension: 16
|
||||
Shader Compiler Threads: 0
|
||||
Driver Recovery Timeout: 1000000
|
||||
Driver Wake-Up Delay: 1
|
||||
Vblank Rate: 60
|
||||
Vblank NTSC Fixup: false
|
||||
DECR memory layout: false
|
||||
Allow Host GPU Labels: false
|
||||
Disable Asynchronous Memory Manager: false
|
||||
Output Scaling Mode: Bilinear
|
||||
Vertex Buffer Upload Mode: Auto
|
||||
Vulkan:
|
||||
Adapter: ""
|
||||
Force FIFO present mode: true
|
||||
Exclusive Fullscreen Mode: Automatic
|
||||
Asynchronous Texture Streaming 2: false
|
||||
FidelityFX CAS Sharpening Intensity: 50
|
||||
Asynchronous Queue Scheduler: Safe
|
||||
VRAM allocation limit (MB): 16384
|
||||
Use Custom Driver: false
|
||||
Custom Driver Library Path: ""
|
||||
Custom Driver Force Max Clocks: false
|
||||
Performance Overlay:
|
||||
Enabled: false
|
||||
Enable Framerate Graph: false
|
||||
Enable Frametime Graph: false
|
||||
Framerate datapoints: 50
|
||||
Frametime datapoints: 170
|
||||
Detail level: Medium
|
||||
Framerate graph detail level: All
|
||||
Frametime graph detail level: All
|
||||
Metrics update interval (ms): 350
|
||||
Font size (px): 10
|
||||
Position: Top Left
|
||||
Font: n023055ms.ttf
|
||||
Horizontal Margin (px): 50
|
||||
Vertical Margin (px): 50
|
||||
Center Horizontally: false
|
||||
Center Vertically: false
|
||||
Opacity (%): 70
|
||||
Body Color (hex): "#FFE138FF"
|
||||
Body Background (hex): "#002339FF"
|
||||
Title Color (hex): "#F26C24FF"
|
||||
Title Background (hex): "#00000000"
|
||||
Shader Loading Dialog:
|
||||
Allow custom background: true
|
||||
Darkening effect strength: 30
|
||||
Blur effect strength: 0
|
||||
Audio:
|
||||
Renderer: Cubeb
|
||||
Audio Provider: CellAudio
|
||||
RSXAudio Avport: HDMI 0
|
||||
Dump to file: false
|
||||
Convert to 16 bit: false
|
||||
Audio Format: Stereo
|
||||
Audio Formats: 0
|
||||
Audio Channel Layout: Automatic
|
||||
Audio Device: "@@@default@@@"
|
||||
Master Volume: 100
|
||||
Enable Buffering: true
|
||||
Desired Audio Buffer Duration: 100
|
||||
Enable Time Stretching: false
|
||||
Disable Sampling Skip: false
|
||||
Time Stretching Threshold: 75
|
||||
Microphone Type: "Null"
|
||||
Microphone Devices: "@@@@@@@@@@@@"
|
||||
Music Handler: Qt
|
||||
Input/Output:
|
||||
Keyboard: "Null"
|
||||
Mouse: Basic
|
||||
Camera: "Null"
|
||||
Camera type: Unknown
|
||||
Camera flip: None
|
||||
Camera ID: Default
|
||||
Move: "Null"
|
||||
Buzz emulated controller: "Null"
|
||||
Turntable emulated controller: "Null"
|
||||
GHLtar emulated controller: "Null"
|
||||
Pad handler mode: Single-threaded
|
||||
Keep pads connected: false
|
||||
Pad handler sleep (microseconds): 1000
|
||||
Background input enabled: true
|
||||
Show move cursor: false
|
||||
Lock overlay input to player one: false
|
||||
Emulated Midi devices: ßßß@@@ßßß@@@ßßß@@@
|
||||
Load SDL GameController Mappings: true
|
||||
IO Debug overlay: false
|
||||
System:
|
||||
License Area: SCEA
|
||||
Language: English (US)
|
||||
Keyboard Type: English keyboard (US standard)
|
||||
Enter button assignment: Enter with cross
|
||||
System Name: RPCS3-255
|
||||
PSID high: 0
|
||||
PSID low: 0
|
||||
HDD Model Name: ""
|
||||
HDD Serial Number: ""
|
||||
Net:
|
||||
Internet enabled: Disconnected
|
||||
IP address: 0.0.0.0
|
||||
Bind address: 0.0.0.0
|
||||
DNS address: 8.8.8.8
|
||||
IP swap list: ""
|
||||
UPNP Enabled: false
|
||||
PSN status: Disconnected
|
||||
PSN Country: us
|
||||
Savestate:
|
||||
Start Paused: false
|
||||
Suspend Emulation Savestate Mode: false
|
||||
Compatible Savestate Mode: false
|
||||
Inspection Mode Savestates: false
|
||||
Save Disc Game Data: false
|
||||
Miscellaneous:
|
||||
Automatically start games after boot: true
|
||||
Exit RPCS3 when process finishes: false
|
||||
Pause emulation on RPCS3 focus loss: false
|
||||
Start games in fullscreen mode: false
|
||||
Show trophy popups: true
|
||||
Show RPCN popups: true
|
||||
Show shader compilation hint: true
|
||||
Show PPU compilation hint: true
|
||||
Show pressure intensity toggle hint: true
|
||||
Show analog limiter toggle hint: true
|
||||
Show autosave/autoload hint: false
|
||||
Use native user interface: true
|
||||
GDB Server: 127.0.0.1:2345
|
||||
Silence All Logs: false
|
||||
Window Title Format: "FPS: %F | %R | %V | %T [%t]"
|
||||
Pause Emulation During Home Menu: false
|
||||
Font File Selection: From Firmware
|
||||
Custom Font File Path: ""
|
||||
Log: {}
|
||||
55
app/src/main/cpp/CMakeLists.txt
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
# For more information about using CMake with Android Studio, read the
|
||||
# documentation: https://d.android.com/studio/projects/add-native-code.html.
|
||||
# For more examples on how to use CMake, see https://github.com/android/ndk-samples.
|
||||
|
||||
# Sets the minimum CMake version required for this project.
|
||||
cmake_minimum_required(VERSION 3.22.1)
|
||||
# Declares the project name. The project name can be accessed via ${ PROJECT_NAME},
|
||||
# Since this is the top level CMakeLists.txt, the project name is also accessible
|
||||
# with ${CMAKE_PROJECT_NAME} (both CMake variables are in-sync within the top level
|
||||
# build script scope).
|
||||
project("aps3e")
|
||||
|
||||
add_compile_options(-march=armv8-a)
|
||||
add_compile_options(-stdlib=libc++)
|
||||
#add_compile_options(-flto=thin)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
add_link_options(-Wl,-z,max-page-size=16384)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
project(aps3e LANGUAGES C CXX)
|
||||
|
||||
add_library(lang_System SHARED lang_System.cpp)
|
||||
|
||||
add_subdirectory(rpcs3 EXCLUDE_FROM_ALL)
|
||||
|
||||
add_library(emu SHARED)
|
||||
set_target_properties(emu PROPERTIES OUTPUT_NAME "e")
|
||||
|
||||
target_link_options(emu PRIVATE -Wl,--exclude-libs,ALL)
|
||||
|
||||
#target_compile_options(emu PRIVATE -flto)
|
||||
#target_link_options(emu PRIVATE -flto)
|
||||
|
||||
target_sources(emu
|
||||
PRIVATE
|
||||
rpcs3/rpcs3/Input/raw_mouse_config.cpp
|
||||
rpcs3/rpcs3/Input/raw_mouse_handler.cpp
|
||||
rpcs3/rpcs3/Input/product_info.cpp
|
||||
rpcs3/rpcs3/rpcs3_version.cpp
|
||||
rpcs3/rpcs3/stb_image.cpp
|
||||
rpcs3/rpcs3/stdafx.cpp
|
||||
aps3e.cpp
|
||||
iso.cpp
|
||||
vkapi.cpp
|
||||
vkutil.cpp
|
||||
cpuinfo.cpp
|
||||
glsl2spv.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(emu PRIVATE rpcs3_emu)
|
||||
target_link_libraries(emu PRIVATE 3rdparty::yaml-cpp 3rdparty::hidapi 3rdparty::libusb 3rdparty::wolfssl 3rdparty::libcurl)
|
||||
target_link_libraries(emu PRIVATE android)
|
||||
1965
app/src/main/cpp/aps3e.cpp
Normal file
408
app/src/main/cpp/aps3e_config.cpp
Normal file
@@ -0,0 +1,408 @@
|
||||
//
|
||||
// Created by aenu on 2025/6/2.
|
||||
// SPDX-License-Identifier: WTFPL
|
||||
//
|
||||
|
||||
static_assert(sizeof(YAML::Node*)==8,"");
|
||||
|
||||
static YAML::Node* open_config_file(JNIEnv* env,jobject self,jstring config_path){
|
||||
jboolean is_copy=false;
|
||||
const char* path=env->GetStringUTFChars(config_path,&is_copy);
|
||||
|
||||
YAML::Node* config_node = new YAML::Node(YAML::LoadFile(path));
|
||||
env->ReleaseStringUTFChars(config_path,path);
|
||||
return config_node;
|
||||
}
|
||||
|
||||
static jstring load_config_entry(JNIEnv* env,jobject self,YAML::Node* config_node,jstring tag){
|
||||
jboolean is_copy=false;
|
||||
const char* tag_cstr=env->GetStringUTFChars(tag,&is_copy);
|
||||
std::string tag_str(tag_cstr);
|
||||
env->ReleaseStringUTFChars(tag,tag_cstr);
|
||||
size_t pos=tag_str.find('|');
|
||||
std::string parent=tag_str.substr(0,pos);
|
||||
std::string child=tag_str.substr(pos+1);
|
||||
|
||||
switch(std::count(child.begin(),child.end(),'|')){
|
||||
case 0: {
|
||||
YAML::Node node=(*config_node)[parent][child];
|
||||
if(node.IsDefined())
|
||||
return env->NewStringUTF(node.as<std::string>().c_str());
|
||||
}
|
||||
break;
|
||||
case 1:{
|
||||
pos=child.find('|');
|
||||
std::string child2=child.substr(pos+1);
|
||||
child=child.substr(0,pos);
|
||||
|
||||
YAML::Node node=(*config_node)[parent][child][child2];
|
||||
if(node.IsDefined())
|
||||
return env->NewStringUTF(node.as<std::string>().c_str());
|
||||
}
|
||||
break;
|
||||
#if 0
|
||||
case 2:{
|
||||
|
||||
pos=child.find('|');
|
||||
std::string child2=child.substr(pos+1);
|
||||
child=child.substr(0,pos);
|
||||
pos=child2.find('|');
|
||||
std::string child3=child2.substr(pos+1);
|
||||
child2=child2.substr(0,pos);
|
||||
|
||||
YAML::Node node=(*config_node)[parent][child][child2][child3];
|
||||
if(node.IsDefined())
|
||||
return env->NewStringUTF(node.as<std::string>().c_str());
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
aps3e_log.error("load_config_entry fail %s",tag_str.c_str());
|
||||
LOGE("load_config_entry fail %s",tag_str.c_str());
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void save_config_entry(JNIEnv* env,jobject self,YAML::Node* config_node,jstring tag,jstring val){
|
||||
|
||||
jboolean is_copy=false;
|
||||
const char* tag_cstr=env->GetStringUTFChars(tag,&is_copy);
|
||||
std::string tag_str(tag_cstr);
|
||||
env->ReleaseStringUTFChars(tag,tag_cstr);
|
||||
size_t pos=tag_str.find('|');
|
||||
std::string parent=tag_str.substr(0,pos);
|
||||
std::string child=tag_str.substr(pos+1);
|
||||
const char* val_cstr=env->GetStringUTFChars(val,&is_copy);
|
||||
|
||||
switch(std::count(child.begin(),child.end(),'|')){
|
||||
case 0: {
|
||||
(*config_node)[parent][child] = std::string(val_cstr);
|
||||
}
|
||||
break;
|
||||
case 1:{
|
||||
pos=child.find('|');
|
||||
std::string child2=child.substr(pos+1);
|
||||
child=child.substr(0,pos);
|
||||
(*config_node)[parent][child][child2]=std::string(val_cstr);
|
||||
}
|
||||
break;
|
||||
#if 0
|
||||
case 2:{
|
||||
|
||||
pos=child.find('|');
|
||||
std::string child2=child.substr(pos+1);
|
||||
child=child.substr(0,pos);
|
||||
pos=child2.find('|');
|
||||
std::string child3=child2.substr(pos+1);
|
||||
child2=child2.substr(0,pos);
|
||||
(*config_node)[parent][child][child2][child3]=std::string(val_cstr);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
aps3e_log.error("save_config_entry fail %s",tag_str.c_str());
|
||||
LOGE("save_config_entry fail %s",tag_str.c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
env->ReleaseStringUTFChars(val,val_cstr);
|
||||
}
|
||||
|
||||
static void close_config_file(JNIEnv* env,jobject self,YAML::Node* config_node,jstring config_path){
|
||||
YAML::Emitter out;
|
||||
out << *config_node;
|
||||
jboolean is_copy=false;
|
||||
const char* path=env->GetStringUTFChars(config_path,&is_copy);
|
||||
std::ofstream fout(path);
|
||||
fout << out.c_str();
|
||||
fout.close();
|
||||
env->ReleaseStringUTFChars(config_path,path);
|
||||
delete config_node;
|
||||
}
|
||||
|
||||
auto gen_key=[](const std::string& name)->std::string{
|
||||
std::string k=name;
|
||||
if(size_t p=k.find("(");p!=std::string::npos){
|
||||
k=k.substr(0,p);
|
||||
}
|
||||
|
||||
//replace(' ','_');
|
||||
//replace('/','_')
|
||||
for(auto& c:k){
|
||||
if(c==' '){
|
||||
c='_';
|
||||
}
|
||||
else if(c=='/'){
|
||||
c='_';
|
||||
}
|
||||
else if(c=='|'){
|
||||
c='_';
|
||||
}
|
||||
}
|
||||
|
||||
//replace("-","");
|
||||
size_t p=k.find("-");
|
||||
while(p!=std::string::npos){
|
||||
k.erase(p,1);
|
||||
p=k.find("-");
|
||||
}
|
||||
|
||||
//移除尾部的_
|
||||
while (k.at(k.size()-1)=='_'){
|
||||
k.erase(k.size()-1,1);
|
||||
}
|
||||
|
||||
std::transform(k.begin(),k.end(),k.begin(),[](char c){
|
||||
return std::tolower(c);
|
||||
});
|
||||
|
||||
return k;
|
||||
};
|
||||
|
||||
static jstring generate_config_xml(JNIEnv* env,jobject self){
|
||||
|
||||
auto gen_one_preference=[&](const std::string parent_name,cfg::_base* node)->std::string{
|
||||
std::stringstream out;
|
||||
|
||||
std::string parent_name_l=gen_key(parent_name);
|
||||
|
||||
const std::string& name=node->get_name();
|
||||
const std::string key=gen_key(name);
|
||||
|
||||
switch (node->get_type()) {
|
||||
case cfg::type::_bool:
|
||||
out<<"<CheckBoxPreference app:title=\"@string/emulator_settings_"<<parent_name_l<<"_"<<key<<"\" \n";
|
||||
out<<"app:key=\""<<parent_name<<"|"<<name<<"\" />\n";
|
||||
break;
|
||||
case cfg::type::_int:
|
||||
case cfg::type::uint:
|
||||
out<<"<SeekBarPreference app:title=\"@string/emulator_settings_"<<parent_name_l<<"_"<<key<<"\" \n";
|
||||
out<<"app:min=\""<<node->get_min()<<"\"\n";
|
||||
if(node->get_max()!=-1)
|
||||
out<<"android:max=\""<<node->get_max()<<"\"\n";
|
||||
else
|
||||
out<<"android:max=\"0x7fffffff\"\n";
|
||||
out<<"app:showSeekBarValue=\"true\"\n";
|
||||
out<<"app:key=\""<<parent_name<<"|"<<name<<"\" />\n";
|
||||
break;
|
||||
|
||||
case cfg::type::_enum:
|
||||
out<<"<ListPreference app:title=\"@string/emulator_settings_"<<parent_name_l<<"_"<<key<<"\" \n";
|
||||
out<<"app:entries=\""<<"@array/"<<parent_name_l<<"_"<<key<<"_entries\"\n";
|
||||
out<<"app:entryValues=\""<<"@array/"<<parent_name_l<<"_"<<key<<"_values\"\n";
|
||||
out<<"app:key=\""<<parent_name<<"|"<<name<<"\" />\n";
|
||||
break;
|
||||
default:
|
||||
|
||||
out<<"<PreferenceScreen app:title=\"@string/emulator_settings_"<<parent_name_l<<"_"<<key<<"\"\n";
|
||||
out<<"app:key=\""<<parent_name<<"|"<<name<<"\" />\n";
|
||||
break;
|
||||
}
|
||||
return out.str();
|
||||
};
|
||||
|
||||
std::ostringstream out;
|
||||
out<<R"(
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
)";
|
||||
|
||||
for(auto n:g_cfg.get_nodes()){
|
||||
const std::string& name=n->get_name();
|
||||
if(name=="Core"||name=="Video"||name=="Audio"||name=="Input/Output"||name=="System"
|
||||
||name=="Net"||name=="Savestate"||name=="Miscellaneous"){
|
||||
out<<" <PreferenceScreen app:title=\"@string/emulator_settings_"<<gen_key(name)<<"\" \n";
|
||||
out<<"app:key=\""<<name<<"\" >\n";
|
||||
for(auto n2:reinterpret_cast<cfg::node*>(n)->get_nodes()){
|
||||
|
||||
//Video下的3个子项
|
||||
if(n2->get_type()==cfg::type::node){
|
||||
out<<"<PreferenceScreen app:title=\"@string/emulator_settings_"<<gen_key(name)<<"_"<<gen_key(n2->get_name())<<"\" \n";
|
||||
out<<"app:key=\""<<name+"|"+n2->get_name()<<"\" >\n";
|
||||
for(auto n3:reinterpret_cast<cfg::node*>(n2)->get_nodes()) {
|
||||
out << "\n" << gen_one_preference(name+"|"+n2->get_name(), n3) << "\n";
|
||||
}
|
||||
out<<"</PreferenceScreen>\n";
|
||||
}
|
||||
else{
|
||||
out<<"\n"<< gen_one_preference(name,n2)<<"\n";
|
||||
}
|
||||
}
|
||||
out<<"</PreferenceScreen>\n";
|
||||
}
|
||||
}
|
||||
|
||||
out<<"</PreferenceScreen>\n";
|
||||
|
||||
return env->NewStringUTF(out.str().c_str());
|
||||
}
|
||||
|
||||
//public native String generate_strings_xml();
|
||||
static jstring generate_strings_xml(JNIEnv* env,jobject self){
|
||||
|
||||
auto gen_one_string=[&](const std::string parent_name,cfg::_base* node)->std::string{
|
||||
std::stringstream out;
|
||||
|
||||
std::string parent_name_l=gen_key(parent_name);
|
||||
|
||||
const std::string& name=node->get_name();
|
||||
const std::string key=gen_key(name);
|
||||
|
||||
out<<"<string name=\"emulator_settings_"<<parent_name_l<<"_"<<key<<"\">"<<name<<"</string>\n";
|
||||
if(node->get_type()==cfg::type::_enum){
|
||||
out<<"<string-array name=\""<<parent_name_l<<"_"<<key<<"_entries\">\n";
|
||||
std::vector<std::string> list=node->to_list();
|
||||
for(const auto& e:list){
|
||||
out<<"<item>"<<e<<"</item>\n";
|
||||
}
|
||||
out<<"</string-array>\n";
|
||||
}
|
||||
|
||||
return out.str();
|
||||
};
|
||||
|
||||
std::ostringstream out;
|
||||
|
||||
for(auto n:g_cfg.get_nodes()){
|
||||
const std::string& name=n->get_name();
|
||||
if(name=="Core"||name=="Video"||name=="Audio"||name=="Input/Output"||name=="System"
|
||||
||name=="Net"||name=="Savestate"||name=="Miscellaneous"){
|
||||
|
||||
out<<"<string name=\"emulator_settings_"<<gen_key(name)<<"\">"<<name<<"</string>\n";
|
||||
|
||||
for(auto n2:reinterpret_cast<cfg::node*>(n)->get_nodes()){
|
||||
|
||||
//Video下的3个子项
|
||||
if(n2->get_type()==cfg::type::node){
|
||||
|
||||
out<<"<string name=\"emulator_settings_"<<gen_key(name+"|"+n2->get_name())<<"\">"<<n2->get_name()<<"</string>\n";
|
||||
for(auto n3:reinterpret_cast<cfg::node*>(n2)->get_nodes()) {
|
||||
out << gen_one_string(name+"|"+n2->get_name(), n3);
|
||||
}
|
||||
}
|
||||
else{
|
||||
out<< gen_one_string(name,n2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//array
|
||||
for(auto n:g_cfg.get_nodes()){
|
||||
const std::string& name=n->get_name();
|
||||
if(name=="Core"||name=="Video"||name=="Audio"||name=="Input/Output"||name=="System"
|
||||
||name=="Net"||name=="Savestate"||name=="Miscellaneous"){
|
||||
|
||||
for(auto n2:reinterpret_cast<cfg::node*>(n)->get_nodes()){
|
||||
|
||||
switch (n2->get_type()) {
|
||||
case cfg::type::_enum: {
|
||||
|
||||
out << "<string-array name=\"" << gen_key(name + "|" + n2->get_name())
|
||||
<< "_values\">\n";
|
||||
std::vector<std::string> list = n2->to_list();
|
||||
for (const auto &e: list) {
|
||||
out << "<item>" << e << "</item>\n";
|
||||
}
|
||||
out << "</string-array>\n";
|
||||
break;
|
||||
}
|
||||
//Video下的3个子项
|
||||
case cfg::type::node:{
|
||||
for(auto n3:reinterpret_cast<cfg::node*>(n2)->get_nodes()) {
|
||||
out << "<string-array name=\""<<gen_key(name+"|"+n2->get_name()+"|"+n3->get_name())<<"_values\">\n";
|
||||
std::vector<std::string> list=n3->to_list();
|
||||
for(const auto& e:list){
|
||||
out<<"<item>"<<e<<"</item>\n";
|
||||
}
|
||||
out<<"</string-array>\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return env->NewStringUTF(out.str().c_str());
|
||||
}
|
||||
|
||||
static jstring generate_java_string_arr(JNIEnv* env,jobject self){
|
||||
|
||||
auto gen_one_key_string=[&](const std::string parent_name,cfg::_base* node,cfg::type test_ty)->std::string{
|
||||
std::string r="";
|
||||
if(node->get_type()==test_ty){
|
||||
return r+"\""+parent_name+"|"+node->get_name()+"\",\n";
|
||||
}
|
||||
return r;
|
||||
};
|
||||
|
||||
auto gen_one_key_array=[&](const std::string prefix,cfg::type test_ty)->std::string{
|
||||
|
||||
std::ostringstream out;
|
||||
out<<prefix<<"\n";
|
||||
for(auto n:g_cfg.get_nodes()){
|
||||
const std::string& name=n->get_name();
|
||||
if(name=="Core"||name=="Video"||name=="Audio"||name=="Input/Output"||name=="System"
|
||||
||name=="Net"||name=="Savestate"||name=="Miscellaneous"){
|
||||
|
||||
for(auto n2:reinterpret_cast<cfg::node*>(n)->get_nodes()){
|
||||
|
||||
//Video下的3个子项
|
||||
if(n2->get_type()==cfg::type::node){
|
||||
for(auto n3:reinterpret_cast<cfg::node*>(n2)->get_nodes()) {
|
||||
out << gen_one_key_string(name+"|"+n2->get_name(), n3,test_ty);
|
||||
}
|
||||
}
|
||||
else{
|
||||
out<< gen_one_key_string(name,n2,test_ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
out<<"};\n";
|
||||
return out.str();
|
||||
};
|
||||
|
||||
auto gen_node_key_array=[&]()->std::string{
|
||||
|
||||
std::ostringstream out;
|
||||
out<<"final String[] NODE_KEYS={\n";
|
||||
for(auto n:g_cfg.get_nodes()){
|
||||
const std::string& name=n->get_name();
|
||||
if(name=="Core"||name=="Video"||name=="Audio"||name=="Input/Output"||name=="System"
|
||||
||name=="Net"||name=="Savestate"||name=="Miscellaneous"){
|
||||
|
||||
out<<"\""<<name<<"\",\n";
|
||||
|
||||
for(auto n2:reinterpret_cast<cfg::node*>(n)->get_nodes()){
|
||||
|
||||
//Video下的3个子项
|
||||
if(n2->get_type()==cfg::type::node){
|
||||
out<<"\""<<name+"|"+n2->get_name()<<"\",\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
out<<"};\n";
|
||||
return out.str();
|
||||
};
|
||||
|
||||
std::ostringstream out;
|
||||
|
||||
out<<gen_one_key_array("final String[] BOOL_KEYS={",cfg::type::_bool);
|
||||
out<<gen_one_key_array("final String[] INT_KEYS={",cfg::type::_int);
|
||||
out<<gen_one_key_array("final String[] INT_KEYS={",cfg::type::uint);
|
||||
out<<gen_one_key_array("final String[] STRING_ARR_KEYS={",cfg::type::_enum);
|
||||
|
||||
//
|
||||
out<<gen_node_key_array();
|
||||
|
||||
return env->NewStringUTF(out.str().c_str());
|
||||
}
|
||||
1443
app/src/main/cpp/aps3e_key_handler.cpp
Normal file
669
app/src/main/cpp/aps3e_pad_thread.cpp
Normal file
@@ -0,0 +1,669 @@
|
||||
|
||||
extern void pad_state_notify_state_change(usz index, u32 state);
|
||||
extern bool is_input_allowed();
|
||||
extern std::string g_input_config_override;
|
||||
|
||||
namespace pad
|
||||
{
|
||||
atomic_t<pad_thread*> g_current = nullptr;
|
||||
shared_mutex g_pad_mutex;
|
||||
std::string g_title_id;
|
||||
atomic_t<bool> g_started{false};
|
||||
atomic_t<bool> g_reset{false};
|
||||
atomic_t<bool> g_enabled{true};
|
||||
atomic_t<bool> g_home_menu_requested{false};
|
||||
}
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
void set_native_ui_flip();
|
||||
}
|
||||
|
||||
struct pad_setting
|
||||
{
|
||||
u32 port_status = 0;
|
||||
u32 device_capability = 0;
|
||||
u32 device_type = 0;
|
||||
bool is_ldd_pad = false;
|
||||
};
|
||||
|
||||
pad_thread::pad_thread(void* curthread, void* curwindow, std::string_view title_id) : m_curthread(curthread), m_curwindow(curwindow)
|
||||
{
|
||||
pad::g_title_id = title_id;
|
||||
pad::g_current = this;
|
||||
pad::g_started = false;
|
||||
}
|
||||
|
||||
pad_thread::~pad_thread()
|
||||
{
|
||||
pad::g_current = nullptr;
|
||||
}
|
||||
|
||||
void pad_thread::Init()
|
||||
{
|
||||
std::lock_guard lock(pad::g_pad_mutex);
|
||||
|
||||
// Cache old settings if possible
|
||||
std::array<pad_setting, CELL_PAD_MAX_PORT_NUM> pad_settings;
|
||||
for (u32 i = 0; i < CELL_PAD_MAX_PORT_NUM; i++) // max 7 pads
|
||||
{
|
||||
if (m_pads[i])
|
||||
{
|
||||
pad_settings[i] =
|
||||
{
|
||||
m_pads[i]->m_port_status,
|
||||
m_pads[i]->m_device_capability,
|
||||
m_pads[i]->m_device_type,
|
||||
m_pads[i]->ldd
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
pad_settings[i] =
|
||||
{
|
||||
CELL_PAD_STATUS_DISCONNECTED,
|
||||
CELL_PAD_CAPABILITY_PS3_CONFORMITY | CELL_PAD_CAPABILITY_PRESS_MODE | CELL_PAD_CAPABILITY_ACTUATOR,
|
||||
CELL_PAD_DEV_TYPE_STANDARD,
|
||||
false
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
num_ldd_pad = 0;
|
||||
|
||||
m_info.now_connect = 0;
|
||||
|
||||
m_handlers.clear();
|
||||
|
||||
g_cfg_input_configs.load();
|
||||
|
||||
std::string active_config = g_cfg_input_configs.active_configs.get_value(pad::g_title_id);
|
||||
|
||||
if (active_config.empty())
|
||||
{
|
||||
active_config = g_cfg_input_configs.active_configs.get_value(g_cfg_input_configs.global_key);
|
||||
}
|
||||
|
||||
input_log.notice("Using input configuration: '%s' (override='%s')", active_config, g_input_config_override);
|
||||
|
||||
// Load in order to get the pad handlers
|
||||
if (!g_cfg_input.load(pad::g_title_id, active_config))
|
||||
{
|
||||
input_log.notice("Loaded empty pad config");
|
||||
}
|
||||
|
||||
// Adjust to the different pad handlers
|
||||
for (usz i = 0; i < g_cfg_input.player.size(); i++)
|
||||
{
|
||||
std::shared_ptr<PadHandlerBase> handler;
|
||||
pad_thread::InitPadConfig(g_cfg_input.player[i]->config, g_cfg_input.player[i]->handler, handler);
|
||||
}
|
||||
|
||||
// Reload with proper defaults
|
||||
if (!g_cfg_input.load(pad::g_title_id, active_config))
|
||||
{
|
||||
input_log.notice("Reloaded empty pad config");
|
||||
}
|
||||
|
||||
input_log.trace("Using pad config:\n%s", g_cfg_input);
|
||||
|
||||
std::shared_ptr<AndroidVirtualPadHandler> keyptr;
|
||||
|
||||
// Always have a Null Pad Handler
|
||||
std::shared_ptr<NullPadHandler> nullpad = std::make_shared<NullPadHandler>();
|
||||
m_handlers.emplace(pad_handler::null, nullpad);
|
||||
|
||||
for (u32 i = 0; i < CELL_PAD_MAX_PORT_NUM; i++) // max 7 pads
|
||||
{
|
||||
cfg_player* cfg = g_cfg_input.player[i];
|
||||
std::shared_ptr<PadHandlerBase> cur_pad_handler;
|
||||
|
||||
const pad_handler handler_type = pad_settings[i].is_ldd_pad ? pad_handler::null : cfg->handler.get();
|
||||
|
||||
if (m_handlers.contains(handler_type))
|
||||
{
|
||||
cur_pad_handler = m_handlers[handler_type];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (handler_type == pad_handler::keyboard)
|
||||
{
|
||||
keyptr = std::make_shared<AndroidVirtualPadHandler>();
|
||||
//keyptr->moveToThread(static_cast<QThread*>(m_curthread));
|
||||
//keyptr->SetTargetWindow(static_cast<QWindow*>(m_curwindow));
|
||||
cur_pad_handler = keyptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_pad_handler = GetHandler(handler_type);
|
||||
}
|
||||
|
||||
m_handlers.emplace(handler_type, cur_pad_handler);
|
||||
}
|
||||
cur_pad_handler->Init();
|
||||
|
||||
std::shared_ptr<Pad> pad = std::make_shared<Pad>(handler_type, i, CELL_PAD_STATUS_DISCONNECTED, pad_settings[i].device_capability, pad_settings[i].device_type);
|
||||
m_pads[i] = pad;
|
||||
|
||||
if (pad_settings[i].is_ldd_pad)
|
||||
{
|
||||
InitLddPad(i, &pad_settings[i].port_status);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!cur_pad_handler->bindPadToDevice(pad))
|
||||
{
|
||||
// Failed to bind the device to cur_pad_handler so binds to NullPadHandler
|
||||
input_log.error("Failed to bind device '%s' to handler %s. Falling back to NullPadHandler.", cfg->device.to_string(), handler_type);
|
||||
nullpad->bindPadToDevice(pad);
|
||||
}
|
||||
|
||||
input_log.notice("Pad %d: device='%s', handler=%s, VID=0x%x, PID=0x%x, class_type=0x%x, class_profile=0x%x",
|
||||
i, cfg->device.to_string(), pad->m_pad_handler, pad->m_vendor_id, pad->m_product_id, pad->m_class_type, pad->m_class_profile);
|
||||
|
||||
if (pad->m_pad_handler != pad_handler::null)
|
||||
{
|
||||
input_log.notice("Pad %d: config=\n%s", i, cfg->to_string());
|
||||
}
|
||||
}
|
||||
|
||||
pad->is_fake_pad = (g_cfg.io.move == move_handler::fake && i >= (static_cast<u32>(CELL_PAD_MAX_PORT_NUM) - static_cast<u32>(CELL_GEM_MAX_NUM)))
|
||||
|| (pad->m_class_type >= CELL_PAD_FAKE_TYPE_FIRST && pad->m_class_type < CELL_PAD_FAKE_TYPE_LAST);
|
||||
connect_usb_controller(i, input::get_product_by_vid_pid(pad->m_vendor_id, pad->m_product_id));
|
||||
}
|
||||
|
||||
// Initialize active mouse and keyboard. Activate pad handler if one exists.
|
||||
input::set_mouse_and_keyboard(m_handlers.contains(pad_handler::keyboard) ? input::active_mouse_and_keyboard::pad : input::active_mouse_and_keyboard::emulated);
|
||||
}
|
||||
|
||||
void pad_thread::SetRumble(const u32 pad, u8 large_motor, bool small_motor)
|
||||
{
|
||||
if (pad >= m_pads.size())
|
||||
return;
|
||||
|
||||
m_pads[pad]->m_vibrateMotors[0].m_value = large_motor;
|
||||
m_pads[pad]->m_vibrateMotors[1].m_value = small_motor ? 255 : 0;
|
||||
}
|
||||
|
||||
void pad_thread::SetIntercepted(bool intercepted)
|
||||
{
|
||||
if (intercepted)
|
||||
{
|
||||
m_info.system_info |= CELL_PAD_INFO_INTERCEPTED;
|
||||
m_info.ignore_input = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_info.system_info &= ~CELL_PAD_INFO_INTERCEPTED;
|
||||
}
|
||||
}
|
||||
|
||||
void pad_thread::update_pad_states()
|
||||
{
|
||||
|
||||
for (usz i = 0; i < m_pads.size(); i++)
|
||||
{
|
||||
const auto& pad = m_pads[i];
|
||||
const bool connected = pad && !pad->is_fake_pad && !!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED);
|
||||
|
||||
if (m_pads_connected[i] == connected)
|
||||
continue;
|
||||
|
||||
pad_state_notify_state_change(i, connected ? CELL_PAD_STATUS_CONNECTED : CELL_PAD_STATUS_DISCONNECTED);
|
||||
|
||||
m_pads_connected[i] = connected;
|
||||
}
|
||||
}
|
||||
|
||||
namespace aps3e_emu{
|
||||
extern pthread_mutex_t key_event_mutex;
|
||||
}
|
||||
|
||||
void pad_thread::operator()()
|
||||
{
|
||||
Init();
|
||||
|
||||
const bool is_vsh = Emu.IsVsh();
|
||||
|
||||
pad::g_reset = false;
|
||||
pad::g_started = true;
|
||||
|
||||
bool mode_changed = true;
|
||||
|
||||
atomic_t<pad_handler_mode> pad_mode{g_cfg.io.pad_mode.get()};
|
||||
std::vector<std::unique_ptr<named_thread<std::function<void()>>>> threads;
|
||||
|
||||
const auto stop_threads = [&threads]()
|
||||
{
|
||||
input_log.notice("Stopping pad threads...");
|
||||
|
||||
for (auto& thread : threads)
|
||||
{
|
||||
if (thread)
|
||||
{
|
||||
auto& enumeration_thread = *thread;
|
||||
enumeration_thread = thread_state::aborting;
|
||||
enumeration_thread();
|
||||
}
|
||||
}
|
||||
threads.clear();
|
||||
|
||||
input_log.notice("Pad threads stopped");
|
||||
};
|
||||
|
||||
const auto start_threads = [this, &threads, &pad_mode]()
|
||||
{
|
||||
if (pad_mode == pad_handler_mode::single_threaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
input_log.notice("Starting pad threads...");
|
||||
|
||||
for (const auto& handler : m_handlers)
|
||||
{
|
||||
if (handler.first == pad_handler::null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
threads.push_back(std::make_unique<named_thread<std::function<void()>>>(fmt::format("%s Thread", handler.second->m_type), [&handler = handler.second, &pad_mode]()
|
||||
{
|
||||
while (thread_ctrl::state() != thread_state::aborting)
|
||||
{
|
||||
if (!pad::g_enabled || !is_input_allowed())
|
||||
{
|
||||
thread_ctrl::wait_for(30'000);
|
||||
continue;
|
||||
}
|
||||
|
||||
handler->process();
|
||||
|
||||
u64 pad_sleep = g_cfg.io.pad_sleep;
|
||||
|
||||
if (Emu.IsPaused())
|
||||
{
|
||||
pad_sleep = std::max<u64>(pad_sleep, 30'000);
|
||||
}
|
||||
|
||||
thread_ctrl::wait_for(pad_sleep);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
input_log.notice("Pad threads started");
|
||||
};
|
||||
|
||||
while (thread_ctrl::state() != thread_state::aborting)
|
||||
{
|
||||
if (!pad::g_enabled || !is_input_allowed())
|
||||
{
|
||||
m_resume_emulation_flag = false;
|
||||
m_mask_start_press_to_resume = 0;
|
||||
thread_ctrl::wait_for(30'000);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Update variables
|
||||
const bool needs_reset = pad::g_reset && pad::g_reset.exchange(false);
|
||||
const pad_handler_mode new_pad_mode = g_cfg.io.pad_mode.get();
|
||||
mode_changed |= new_pad_mode != pad_mode.exchange(new_pad_mode);
|
||||
|
||||
// Reset pad handlers if necessary
|
||||
if (needs_reset || mode_changed)
|
||||
{
|
||||
mode_changed = false;
|
||||
|
||||
stop_threads();
|
||||
|
||||
if (needs_reset)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
else
|
||||
{
|
||||
input_log.success("The pad mode was changed to %s", pad_mode.load());
|
||||
}
|
||||
|
||||
start_threads();
|
||||
}
|
||||
|
||||
u32 connected_devices = 0;
|
||||
|
||||
if (pad_mode == pad_handler_mode::single_threaded)
|
||||
{
|
||||
pthread_mutex_lock(&aps3e_emu::key_event_mutex);
|
||||
for (auto& handler : m_handlers)
|
||||
{
|
||||
handler.second->process();
|
||||
connected_devices += handler.second->connected_devices;
|
||||
}
|
||||
pthread_mutex_unlock(&aps3e_emu::key_event_mutex);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto& handler : m_handlers)
|
||||
{
|
||||
connected_devices += handler.second->connected_devices;
|
||||
}
|
||||
}
|
||||
|
||||
if (Emu.IsRunning())
|
||||
{
|
||||
update_pad_states();
|
||||
}
|
||||
|
||||
m_info.now_connect = connected_devices + num_ldd_pad;
|
||||
|
||||
// The ignore_input section is only reached when a dialog was closed and the pads are still intercepted.
|
||||
// As long as any of the listed buttons is pressed, cellPadGetData will ignore all input (needed for Hotline Miami).
|
||||
// ignore_input was added because if we keep the pads intercepted, then some games will enter the menu due to unexpected system interception (tested with Ninja Gaiden Sigma).
|
||||
if (m_info.ignore_input && !(m_info.system_info & CELL_PAD_INFO_INTERCEPTED))
|
||||
{
|
||||
bool any_button_pressed = false;
|
||||
|
||||
for (usz i = 0; i < m_pads.size() && !any_button_pressed; i++)
|
||||
{
|
||||
const auto& pad = m_pads[i];
|
||||
|
||||
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
|
||||
continue;
|
||||
|
||||
for (const auto& button : pad->m_buttons)
|
||||
{
|
||||
if (button.m_pressed && (
|
||||
button.m_outKeyCode == CELL_PAD_CTRL_CROSS ||
|
||||
button.m_outKeyCode == CELL_PAD_CTRL_CIRCLE ||
|
||||
button.m_outKeyCode == CELL_PAD_CTRL_TRIANGLE ||
|
||||
button.m_outKeyCode == CELL_PAD_CTRL_SQUARE ||
|
||||
button.m_outKeyCode == CELL_PAD_CTRL_START ||
|
||||
button.m_outKeyCode == CELL_PAD_CTRL_SELECT))
|
||||
{
|
||||
any_button_pressed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!any_button_pressed)
|
||||
{
|
||||
m_info.ignore_input = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle home menu if requested
|
||||
if (!is_vsh && !m_home_menu_open && Emu.IsRunning())
|
||||
{
|
||||
bool ps_button_pressed = false;
|
||||
|
||||
for (usz i = 0; i < m_pads.size() && !ps_button_pressed; i++)
|
||||
{
|
||||
if (i > 0 && g_cfg.io.lock_overlay_input_to_player_one)
|
||||
break;
|
||||
|
||||
const auto& pad = m_pads[i];
|
||||
|
||||
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
|
||||
continue;
|
||||
|
||||
// Check if an LDD pad pressed the PS button (bit 0 of the first button)
|
||||
// NOTE: Rock Band 3 doesn't seem to care about the len. It's always 0.
|
||||
if (pad->ldd /*&& pad->ldd_data.len >= 1 */&& !!(pad->ldd_data.button[0] & CELL_PAD_CTRL_LDD_PS))
|
||||
{
|
||||
ps_button_pressed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
for (const auto& button : pad->m_buttons)
|
||||
{
|
||||
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1 && button.m_outKeyCode == CELL_PAD_CTRL_PS && button.m_pressed)
|
||||
{
|
||||
ps_button_pressed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we call this function only once per button press
|
||||
if ((ps_button_pressed && !m_ps_button_pressed) || pad::g_home_menu_requested.exchange(false))
|
||||
{
|
||||
open_home_menu();
|
||||
}
|
||||
|
||||
m_ps_button_pressed = ps_button_pressed;
|
||||
}
|
||||
|
||||
// Handle paused emulation (if triggered by home menu).
|
||||
if (m_home_menu_open && g_cfg.misc.pause_during_home_menu)
|
||||
{
|
||||
// Reset resume control if the home menu is open
|
||||
m_resume_emulation_flag = false;
|
||||
m_mask_start_press_to_resume = 0;
|
||||
m_track_start_press_begin_timestamp = 0;
|
||||
|
||||
// Update UI
|
||||
rsx::set_native_ui_flip();
|
||||
thread_ctrl::wait_for(33'000);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_resume_emulation_flag)
|
||||
{
|
||||
m_resume_emulation_flag = false;
|
||||
|
||||
Emu.BlockingCallFromMainThread([]()
|
||||
{
|
||||
Emu.Resume();
|
||||
});
|
||||
}
|
||||
|
||||
u64 pad_sleep = g_cfg.io.pad_sleep;
|
||||
|
||||
if (Emu.GetStatus(false) == system_state::paused)
|
||||
{
|
||||
pad_sleep = std::max<u64>(pad_sleep, 30'000);
|
||||
|
||||
u64 timestamp = get_system_time();
|
||||
u32 pressed_mask = 0;
|
||||
|
||||
for (usz i = 0; i < m_pads.size(); i++)
|
||||
{
|
||||
const auto& pad = m_pads[i];
|
||||
|
||||
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
|
||||
continue;
|
||||
for (const auto& button : pad->m_buttons)
|
||||
{
|
||||
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1 && button.m_outKeyCode == CELL_PAD_CTRL_START && button.m_pressed)
|
||||
{
|
||||
pressed_mask |= 1u << i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_mask_start_press_to_resume &= pressed_mask;
|
||||
|
||||
if (!pressed_mask || timestamp - m_track_start_press_begin_timestamp >= 700'000)
|
||||
{
|
||||
m_track_start_press_begin_timestamp = timestamp;
|
||||
|
||||
if (std::exchange(m_mask_start_press_to_resume, u32{umax}))
|
||||
{
|
||||
m_mask_start_press_to_resume = 0;
|
||||
m_track_start_press_begin_timestamp = 0;
|
||||
|
||||
//sys_log.success("Resuming emulation using the START button in a few seconds...");
|
||||
|
||||
auto msg_ref = std::make_shared<atomic_t<u32>>(1);
|
||||
rsx::overlays::queue_message(localized_string_id::EMULATION_RESUMING, 2'000'000, msg_ref);
|
||||
|
||||
m_resume_emulation_flag = true;
|
||||
|
||||
for (u32 i = 0; i < 40; i++)
|
||||
{
|
||||
if (Emu.GetStatus(false) != system_state::paused)
|
||||
{
|
||||
// Abort if emulation has been resumed by other means
|
||||
m_resume_emulation_flag = false;
|
||||
msg_ref->release(0);
|
||||
break;
|
||||
}
|
||||
|
||||
thread_ctrl::wait_for(50'000);
|
||||
rsx::set_native_ui_flip();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset resume control if caught a state of unpaused emulation
|
||||
m_mask_start_press_to_resume = 0;
|
||||
m_track_start_press_begin_timestamp = 0;
|
||||
}
|
||||
|
||||
thread_ctrl::wait_for(pad_sleep);
|
||||
}
|
||||
|
||||
stop_threads();
|
||||
}
|
||||
|
||||
void pad_thread::InitLddPad(u32 handle, const u32* port_status)
|
||||
{
|
||||
if (handle >= m_pads.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static const input::product_info product = input::get_product_info(input::product_type::playstation_3_controller);
|
||||
|
||||
m_pads[handle]->ldd = true;
|
||||
m_pads[handle]->Init
|
||||
(
|
||||
port_status ? *port_status : CELL_PAD_STATUS_CONNECTED | CELL_PAD_STATUS_ASSIGN_CHANGES | CELL_PAD_STATUS_CUSTOM_CONTROLLER,
|
||||
CELL_PAD_CAPABILITY_PS3_CONFORMITY,
|
||||
CELL_PAD_DEV_TYPE_LDD,
|
||||
CELL_PAD_PCLASS_TYPE_STANDARD,
|
||||
product.pclass_profile,
|
||||
product.vendor_id,
|
||||
product.product_id,
|
||||
50
|
||||
);
|
||||
|
||||
input_log.notice("Pad %d: LDD, VID=0x%x, PID=0x%x, class_type=0x%x, class_profile=0x%x",
|
||||
handle, m_pads[handle]->m_vendor_id, m_pads[handle]->m_product_id, m_pads[handle]->m_class_type, m_pads[handle]->m_class_profile);
|
||||
|
||||
num_ldd_pad++;
|
||||
}
|
||||
|
||||
s32 pad_thread::AddLddPad()
|
||||
{
|
||||
// Look for first null pad
|
||||
for (u32 i = 0; i < CELL_PAD_MAX_PORT_NUM; i++)
|
||||
{
|
||||
if (g_cfg_input.player[i]->handler == pad_handler::null && !m_pads[i]->ldd)
|
||||
{
|
||||
InitLddPad(i, nullptr);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void pad_thread::UnregisterLddPad(u32 handle)
|
||||
{
|
||||
ensure(handle < m_pads.size());
|
||||
|
||||
m_pads[handle]->ldd = false;
|
||||
|
||||
num_ldd_pad--;
|
||||
}
|
||||
|
||||
std::shared_ptr<PadHandlerBase> pad_thread::GetHandler(pad_handler type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case pad_handler::null:
|
||||
return std::make_shared<NullPadHandler>();
|
||||
case pad_handler::keyboard:
|
||||
return std::make_shared<AndroidVirtualPadHandler>();
|
||||
/*case pad_handler::ds3:
|
||||
return std::make_shared<ds3_pad_handler>();
|
||||
case pad_handler::ds4:
|
||||
return std::make_shared<ds4_pad_handler>();
|
||||
case pad_handler::dualsense:
|
||||
return std::make_shared<dualsense_pad_handler>();
|
||||
case pad_handler::skateboard:
|
||||
return std::make_shared<skateboard_pad_handler>();
|
||||
#ifdef _WIN32
|
||||
case pad_handler::xinput:
|
||||
return std::make_shared<xinput_pad_handler>();
|
||||
case pad_handler::mm:
|
||||
return std::make_shared<mm_joystick_handler>();
|
||||
#endif
|
||||
#ifdef HAVE_SDL2
|
||||
case pad_handler::sdl:
|
||||
return std::make_shared<sdl_pad_handler>();
|
||||
/*#endif
|
||||
#ifdef HAVE_LIBEVDEV
|
||||
case pad_handler::evdev:
|
||||
return std::make_shared<evdev_joystick_handler>();
|
||||
#endif*/
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void pad_thread::InitPadConfig(cfg_pad& cfg, pad_handler type, std::shared_ptr<PadHandlerBase>& handler)
|
||||
{
|
||||
if (!handler)
|
||||
{
|
||||
handler = GetHandler(type);
|
||||
}
|
||||
|
||||
ensure(!!handler);
|
||||
handler->init_config(&cfg);
|
||||
}
|
||||
|
||||
extern bool send_open_home_menu_cmds();
|
||||
extern void send_close_home_menu_cmds();
|
||||
extern bool close_osk_from_ps_button();
|
||||
|
||||
void pad_thread::open_home_menu()
|
||||
{
|
||||
// Check if the OSK is open and can be closed
|
||||
if (!close_osk_from_ps_button())
|
||||
{
|
||||
rsx::overlays::queue_message(get_localized_string(localized_string_id::CELL_OSK_DIALOG_BUSY));
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto manager = g_fxo->try_get<rsx::overlays::display_manager>())
|
||||
{
|
||||
if (m_home_menu_open.exchange(true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!send_open_home_menu_cmds())
|
||||
{
|
||||
m_home_menu_open = false;
|
||||
return;
|
||||
}
|
||||
|
||||
input_log.notice("opening home menu...");
|
||||
|
||||
const error_code result = manager->create<rsx::overlays::home_menu_dialog>()->show([this](s32 status)
|
||||
{
|
||||
input_log.notice("closing home menu with status %d", status);
|
||||
|
||||
m_home_menu_open = false;
|
||||
|
||||
send_close_home_menu_cmds();
|
||||
});
|
||||
|
||||
(result ? input_log.error : input_log.notice)("opened home menu with result %d", s32{result});
|
||||
}
|
||||
}
|
||||
153
app/src/main/cpp/cpuinfo.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
//
|
||||
// Created by aenu on 2025/5/31.
|
||||
//
|
||||
#include "cpuinfo.h"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
std::vector<core_info_t> cpu_get_core_info(){
|
||||
std::ifstream cpuinfo("/proc/cpuinfo");
|
||||
if (!cpuinfo.is_open()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<core_info_t> cores;
|
||||
core_info_t core;
|
||||
|
||||
std::string line;
|
||||
while (std::getline(cpuinfo, line)) {
|
||||
|
||||
if (line.find("processor") != std::string::npos) {
|
||||
core.processor = std::stoi(line.substr(line.find(":") + 2));
|
||||
}
|
||||
else if (line.find("CPU implementer") != std::string::npos) {
|
||||
core.implementer = std::stoi(line.substr(line.find(":") + 2), nullptr, 16);
|
||||
}
|
||||
else if (line.find("CPU variant") != std::string::npos) {
|
||||
core.variant = std::stoi(line.substr(line.find(":") + 2), nullptr, 16);
|
||||
}
|
||||
else if (line.find("CPU part") != std::string::npos) {
|
||||
core.part = std::stoi(line.substr(line.find(":") + 2), nullptr, 16);
|
||||
cores.push_back(core);
|
||||
}
|
||||
else if (line.find("Features") != std::string::npos) {
|
||||
//FIXME 转换其为编译feature
|
||||
std::string features = line.substr(line.find(":") + 2);
|
||||
std::istringstream iss(features);
|
||||
std::string feature;
|
||||
while (iss >> feature) {
|
||||
core.features.push_back(feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::sort(cores.begin(), cores.end(), [](const core_info_t& a, const core_info_t& b) {
|
||||
return a.processor < b.processor;
|
||||
});
|
||||
return cores;
|
||||
}
|
||||
|
||||
//map.find
|
||||
bool operator<(const core_info_t& lhs,const core_info_t& rhs){
|
||||
if(lhs.implementer!= rhs.implementer) return lhs.implementer < rhs.implementer;
|
||||
if(lhs.part!= rhs.part) return lhs.part < rhs.part;
|
||||
return lhs.variant < rhs.variant;
|
||||
}
|
||||
|
||||
std::string cpu_get_simple_info(const std::vector<core_info_t>& core_info_list){
|
||||
std::map<core_info_t, int> core_counts;
|
||||
for (const auto& core : core_info_list) {
|
||||
if(core_counts.find(core) == core_counts.end())
|
||||
core_counts[core] = 1;
|
||||
else
|
||||
core_counts[core]++;
|
||||
}
|
||||
std::stringstream ss;
|
||||
for (auto it=core_counts.rbegin(); it!=core_counts.rend();it++) {
|
||||
ss<<cpu_get_processor_name(it->first)<<"*"<<it->second<<"+";
|
||||
}
|
||||
std::string r = ss.str();
|
||||
return r.substr(0,r.size()-1);
|
||||
}
|
||||
|
||||
|
||||
std::set<core_info_t> get_processor_info_set(){
|
||||
std::vector<core_info_t> core_info_list = cpu_get_core_info();
|
||||
return std::set<core_info_t>(core_info_list.begin(), core_info_list.end());
|
||||
}
|
||||
|
||||
std::set<std::string> get_processor_name_set(){
|
||||
std::vector<core_info_t> core_info_list = cpu_get_core_info();
|
||||
std::set<std::string> processor_name_set;
|
||||
std::for_each(core_info_list.begin(), core_info_list.end(), [&processor_name_set](const core_info_t& core_info) {
|
||||
processor_name_set.insert(cpu_get_processor_name(core_info));
|
||||
});
|
||||
return processor_name_set;
|
||||
}
|
||||
|
||||
|
||||
std::string cpu_get_processor_name(const core_info_t& core_info){
|
||||
static const std::map<std::tuple<int,int>,std::string> processor_map{
|
||||
|
||||
//ARM
|
||||
{{ 0x41, 0xd04}, "cortex-a35" },
|
||||
{{ 0x41, 0xd03}, "cortex-a53" },
|
||||
{{ 0x41, 0xd07}, "cortex-a57" },
|
||||
{{ 0x41, 0xd08}, "cortex-a72" },
|
||||
{{ 0x41, 0xd09}, "cortex-a73" },
|
||||
|
||||
{{ 0x41, 0xd05}, "cortex-a55" },
|
||||
{{ 0x41, 0xd0a}, "cortex-a75" },
|
||||
{{ 0x41, 0xd0b}, "cortex-a76" },
|
||||
{{ 0x41, 0xd0d}, "cortex-a77" },
|
||||
{{ 0x41, 0xd41}, "cortex-a78" },
|
||||
{{ 0x41, 0xd44}, "cortex-x1" },
|
||||
|
||||
{{ 0x41, 0xd46}, "cortex-a510" },
|
||||
{{ 0x41, 0xd47}, "cortex-a710" },
|
||||
{{ 0x41, 0xd48}, "cortex-x2" },
|
||||
{{ 0x41, 0xd4d}, "cortex-a715" },
|
||||
{{ 0x41, 0xd4e}, "cortex-x3" },
|
||||
|
||||
{{ 0x41, 0xd80}, "cortex-a520" },
|
||||
{{ 0x41, 0xd81}, "cortex-a720" },
|
||||
{{ 0x41, 0xd87}, "cortex-a725" },
|
||||
{{ 0x41, 0xd82}, "cortex-x4" },
|
||||
{{ 0x41, 0xd85}, "cortex-x925" },
|
||||
|
||||
{{ 0x41, 0xd88}, "cortex-a520ae" },
|
||||
{{ 0x41, 0xd06}, "cortex-a65" },
|
||||
{{ 0x41, 0xd43}, "cortex-a65ae" },
|
||||
{{ 0x41, 0xd0e}, "cortex-a76ae" },
|
||||
{{ 0x41, 0xd0d}, "cortex-a77" },
|
||||
{{ 0x41, 0xd42}, "cortex-a78ae" },
|
||||
{{ 0x41, 0xd4b}, "cortex-a78c" },
|
||||
|
||||
//高通
|
||||
{{ 0x51, 0x801}, "cortex-a73" },// Kryo 2xx Silver
|
||||
{{ 0x51, 0x802}, "cortex-a75" },// Kryo 3xx Gold
|
||||
{{ 0x51, 0x803}, "cortex-a75" },// Kryo 3xx Silver
|
||||
{{ 0x51, 0x804}, "cortex-a76" },// Kryo 4xx Gold
|
||||
{{ 0x51, 0x805}, "cortex-a76" },// Kryo 4xx/5xx Silver
|
||||
//{{ 0x51, 0xc00}, "falkor" },
|
||||
//{{ 0x51, 0xc01}, "saphira" },
|
||||
{{ 0x51, 0x001}, "oryon-1" },
|
||||
|
||||
//海思
|
||||
//{{ 0x48, 0xd01}, "tsv110" },
|
||||
|
||||
//三星
|
||||
{{ 0x53, 0x002}, "exynos-m3" },
|
||||
{{ 0x53, 0x003}, "exynos-m4" },
|
||||
};
|
||||
|
||||
int implementer=core_info.implementer;
|
||||
int variant=core_info.variant;
|
||||
int part=core_info.part;
|
||||
|
||||
if (auto core = processor_map.find(std::make_tuple(implementer, part)); core != processor_map.end()) {
|
||||
return core->second;
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
24
app/src/main/cpp/cpuinfo.h
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by aenu on 2025/5/31.
|
||||
//
|
||||
|
||||
#ifndef APS3E_CPUINFO_H
|
||||
#define APS3E_CPUINFO_H
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
struct core_info_t {
|
||||
int processor;
|
||||
int implementer;
|
||||
int variant;
|
||||
int part;
|
||||
std::vector<std::string> features;
|
||||
};
|
||||
|
||||
std::vector<core_info_t> cpu_get_core_info();
|
||||
std::string cpu_get_simple_info(const std::vector<core_info_t>& core_info_list);
|
||||
std::set<core_info_t> get_processor_info_set();
|
||||
std::set<std::string> get_processor_name_set();
|
||||
std::string cpu_get_processor_name(const core_info_t& core_info);
|
||||
|
||||
#endif //APS3E_CPUINFO_H
|
||||
175
app/src/main/cpp/decode_bcn.cpp
Normal file
@@ -0,0 +1,175 @@
|
||||
|
||||
|
||||
// =========================== COMPRESSION ============================
|
||||
// Some texture has block compression, when uncompressed will have swizzled layout. Since on some backend, no
|
||||
// option is provided to make the GPU driver not try to translate the layout to linear, we have to do uncompress
|
||||
// and unswizzled on the CPU.
|
||||
|
||||
// This BC decompression code is based on code from AMD GPUOpen's Compressonator
|
||||
|
||||
/**
|
||||
* \brief Decompresses one block of a BC1 texture and stores the resulting pixels at the appropriate offset in 'image'.
|
||||
*
|
||||
* \param block_storage pointer to the block to decompress.
|
||||
* \param image pointer to image where the decompressed pixel data should be stored.
|
||||
**/
|
||||
void decompress_block_bc1(const uint8_t *block_storage, uint32_t *image) {
|
||||
std::uint16_t n0 = static_cast<std::uint16_t>((block_storage[1] << 8) | block_storage[0]);
|
||||
std::uint16_t n1 = static_cast<std::uint16_t>((block_storage[3] << 8) | block_storage[2]);
|
||||
|
||||
block_storage += 4;
|
||||
|
||||
std::uint8_t r0 = (n0 & 0xF800) >> 8;
|
||||
std::uint8_t g0 = (n0 & 0x07E0) >> 3;
|
||||
std::uint8_t b0 = (n0 & 0x001F) << 3;
|
||||
|
||||
std::uint8_t r1 = (n1 & 0xF800) >> 8;
|
||||
std::uint8_t g1 = (n1 & 0x07E0) >> 3;
|
||||
std::uint8_t b1 = (n1 & 0x001F) << 3;
|
||||
|
||||
r0 |= r0 >> 5;
|
||||
r1 |= r1 >> 5;
|
||||
g0 |= g0 >> 6;
|
||||
g1 |= g1 >> 6;
|
||||
b0 |= b0 >> 5;
|
||||
b1 |= b1 >> 5;
|
||||
|
||||
std::uint32_t c0 = 0xFF000000 | (b0 << 16) | (g0 << 8) | r0;
|
||||
std::uint32_t c1 = 0xFF000000 | (b1 << 16) | (g1 << 8) | r1;
|
||||
|
||||
if (n0 > n1) {
|
||||
std::uint8_t r2 = static_cast<uint8_t>((2 * r0 + r1 + 1) / 3);
|
||||
std::uint8_t r3 = static_cast<uint8_t>((2 * r1 + r0 + 1) / 3);
|
||||
std::uint8_t g2 = static_cast<uint8_t>((2 * g0 + g1 + 1) / 3);
|
||||
std::uint8_t g3 = static_cast<uint8_t>((2 * g1 + g0 + 1) / 3);
|
||||
std::uint8_t b2 = static_cast<uint8_t>((2 * b0 + b1 + 1) / 3);
|
||||
std::uint8_t b3 = static_cast<uint8_t>((2 * b1 + b0 + 1) / 3);
|
||||
|
||||
std::uint32_t c2 = 0xFF000000 | (b2 << 16) | (g2 << 8) | r2;
|
||||
std::uint32_t c3 = 0xFF000000 | (b3 << 16) | (g3 << 8) | r3;
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
int index = (block_storage[i / 4] >> (i % 4 * 2)) & 0x03;
|
||||
switch (index) {
|
||||
case 0:
|
||||
image[i] = c0;
|
||||
break;
|
||||
case 1:
|
||||
image[i] = c1;
|
||||
break;
|
||||
case 2:
|
||||
image[i] = c2;
|
||||
break;
|
||||
case 3:
|
||||
image[i] = c3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Transparent decode
|
||||
std::uint8_t r2 = static_cast<uint8_t>((r0 + r1) / 2);
|
||||
std::uint8_t g2 = static_cast<uint8_t>((g0 + g1) / 2);
|
||||
std::uint8_t b2 = static_cast<uint8_t>((b0 + b1) / 2);
|
||||
|
||||
std::uint32_t c2 = 0xFF000000 | (b2 << 16) | (g2 << 8) | r2;
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
int index = (block_storage[i / 4] >> (i % 4 * 2)) & 0x03;
|
||||
switch (index) {
|
||||
case 0:
|
||||
image[i] = c0;
|
||||
break;
|
||||
case 1:
|
||||
image[i] = c1;
|
||||
break;
|
||||
case 2:
|
||||
image[i] = c2;
|
||||
break;
|
||||
case 3:
|
||||
image[i] = 0x00000000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Decompresses one block of a alpha texture and stores the resulting pixels at the appropriate offset in 'image'.
|
||||
*
|
||||
* \param block_storage pointer to the block to decompress.
|
||||
* \param image pointer to image where the decompressed pixel data should be stored.
|
||||
* \param offset offset to where data should be written.
|
||||
* \param stride stride between bytes to where data should be written.
|
||||
**/
|
||||
void decompress_block_alpha(const uint8_t *block_storage, uint8_t *image, const uint32_t offset, const uint32_t stride) {
|
||||
uint8_t alpha[8];
|
||||
|
||||
alpha[0] = block_storage[0];
|
||||
alpha[1] = block_storage[1];
|
||||
|
||||
if (alpha[0] > alpha[1]) {
|
||||
// 8-alpha block: derive the other six alphas.
|
||||
// Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated.
|
||||
alpha[2] = static_cast<uint8_t>((6 * alpha[0] + 1 * alpha[1] + 3) / 7); // bit code 010
|
||||
alpha[3] = static_cast<uint8_t>((5 * alpha[0] + 2 * alpha[1] + 3) / 7); // bit code 011
|
||||
alpha[4] = static_cast<uint8_t>((4 * alpha[0] + 3 * alpha[1] + 3) / 7); // bit code 100
|
||||
alpha[5] = static_cast<uint8_t>((3 * alpha[0] + 4 * alpha[1] + 3) / 7); // bit code 101
|
||||
alpha[6] = static_cast<uint8_t>((2 * alpha[0] + 5 * alpha[1] + 3) / 7); // bit code 110
|
||||
alpha[7] = static_cast<uint8_t>((1 * alpha[0] + 6 * alpha[1] + 3) / 7); // bit code 111
|
||||
} else {
|
||||
// 6-alpha block.
|
||||
// Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated.
|
||||
alpha[2] = static_cast<uint8_t>((4 * alpha[0] + 1 * alpha[1] + 2) / 5); // Bit code 010
|
||||
alpha[3] = static_cast<uint8_t>((3 * alpha[0] + 2 * alpha[1] + 2) / 5); // Bit code 011
|
||||
alpha[4] = static_cast<uint8_t>((2 * alpha[0] + 3 * alpha[1] + 2) / 5); // Bit code 100
|
||||
alpha[5] = static_cast<uint8_t>((1 * alpha[0] + 4 * alpha[1] + 2) / 5); // Bit code 101
|
||||
alpha[6] = 0; // Bit code 110
|
||||
alpha[7] = 255; // Bit code 111
|
||||
}
|
||||
|
||||
image += offset;
|
||||
|
||||
image[stride * 0] = alpha[block_storage[2] & 0x07];
|
||||
image[stride * 1] = alpha[(block_storage[2] >> 3) & 0x07];
|
||||
image[stride * 2] = alpha[((block_storage[3] << 2) & 0x04) | ((block_storage[2] >> 6) & 0x03)];
|
||||
image[stride * 3] = alpha[(block_storage[3] >> 1) & 0x07];
|
||||
image[stride * 4] = alpha[(block_storage[3] >> 4) & 0x07];
|
||||
image[stride * 5] = alpha[((block_storage[4] << 1) & 0x06) | ((block_storage[3] >> 7) & 0x01)];
|
||||
image[stride * 6] = alpha[(block_storage[4] >> 2) & 0x07];
|
||||
image[stride * 7] = alpha[(block_storage[4] >> 5) & 0x07];
|
||||
image[stride * 8] = alpha[block_storage[5] & 0x07];
|
||||
image[stride * 9] = alpha[(block_storage[5] >> 3) & 0x07];
|
||||
image[stride * 10] = alpha[((block_storage[6] << 2) & 0x04) | ((block_storage[5] >> 6) & 0x03)];
|
||||
image[stride * 11] = alpha[(block_storage[6] >> 1) & 0x07];
|
||||
image[stride * 12] = alpha[(block_storage[6] >> 4) & 0x07];
|
||||
image[stride * 13] = alpha[((block_storage[7] << 1) & 0x06) | ((block_storage[6] >> 7) & 0x01)];
|
||||
image[stride * 14] = alpha[(block_storage[7] >> 2) & 0x07];
|
||||
image[stride * 15] = alpha[(block_storage[7] >> 5) & 0x07];
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Decompresses one block of a BC2 texture and stores the resulting pixels at the appropriate offset in 'image'.
|
||||
*
|
||||
* \param block_storage pointer to the block to decompress.
|
||||
* \param image pointer to image where the decompressed pixel data should be stored.
|
||||
**/
|
||||
void decompress_block_bc2(const uint8_t *block_storage, uint32_t *image) {
|
||||
decompress_block_bc1(block_storage + 8, image);
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
image[2 * i] = (((block_storage[i] & 0x0F) | ((block_storage[i] & 0x0F) << 4)) << 24) | (image[2 * i] & 0x00FFFFFF);
|
||||
image[2 * i + 1] = (((block_storage[i] & 0xF0) | ((block_storage[i] & 0xF0) >> 4)) << 24) | (image[2 * i + 1] & 0x00FFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Decompresses one block of a BC3 texture and stores the resulting pixels at the appropriate offset in 'image'.
|
||||
*
|
||||
* \param block_storage pointer to the block to decompress.
|
||||
* \param image pointer to image where the decompressed pixel data should be stored.
|
||||
**/
|
||||
void decompress_block_bc3(const uint8_t *block_storage, uint32_t *image) {
|
||||
decompress_block_bc1(block_storage + 8, image);
|
||||
decompress_block_alpha(block_storage, reinterpret_cast<std::uint8_t *>(image), 3, 4);
|
||||
}
|
||||
|
||||
174
app/src/main/cpp/glsl2spv.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
//
|
||||
// Created by aenu on 2025/6/1.
|
||||
// SPDX-License-Identifier: WTFPL
|
||||
//
|
||||
#include "glsl2spv.h"
|
||||
|
||||
namespace{
|
||||
TBuiltInResource resource;
|
||||
}
|
||||
void glsl2spv_init(const VkPhysicalDeviceLimits& limits){
|
||||
|
||||
resource.maxLights = 32;
|
||||
resource.maxClipPlanes = 6;
|
||||
resource.maxTextureUnits = 32;
|
||||
resource.maxTextureCoords = 32;
|
||||
resource.maxVertexAttribs = 64;
|
||||
|
||||
resource.maxVertexUniformComponents = 4096;
|
||||
resource.maxVaryingFloats = 64;
|
||||
resource.maxVertexTextureImageUnits = 32;
|
||||
resource.maxCombinedTextureImageUnits = 80;
|
||||
resource.maxTextureImageUnits = 32;
|
||||
|
||||
resource.maxFragmentUniformComponents = 4096;
|
||||
resource.maxDrawBuffers = 32;
|
||||
resource.maxVertexUniformVectors = 128;
|
||||
resource.maxVaryingVectors = 8;
|
||||
resource.maxFragmentUniformVectors = 16;
|
||||
|
||||
resource.maxVertexOutputVectors = limits.maxVertexOutputComponents;
|
||||
resource.maxFragmentInputVectors = limits.maxFragmentInputComponents;
|
||||
resource.minProgramTexelOffset = limits.minTexelOffset;
|
||||
resource.maxProgramTexelOffset = limits.maxTexelOffset;
|
||||
resource.maxClipDistances = limits.maxClipDistances;
|
||||
|
||||
resource.maxComputeWorkGroupCountX = limits.maxComputeWorkGroupCount[0];
|
||||
resource.maxComputeWorkGroupCountY = limits.maxComputeWorkGroupCount[1];
|
||||
resource.maxComputeWorkGroupCountZ = limits.maxComputeWorkGroupCount[2];
|
||||
resource.maxComputeWorkGroupSizeX = limits.maxComputeWorkGroupSize[0];
|
||||
resource.maxComputeWorkGroupSizeY = limits.maxComputeWorkGroupSize[1];
|
||||
resource.maxComputeWorkGroupSizeZ = limits.maxComputeWorkGroupSize[2];
|
||||
|
||||
resource.maxComputeUniformComponents = 1024;
|
||||
resource.maxComputeTextureImageUnits = 16;
|
||||
resource.maxComputeImageUniforms = 8;
|
||||
resource.maxComputeAtomicCounters = 8;
|
||||
resource.maxComputeAtomicCounterBuffers = 1;
|
||||
resource.maxVaryingComponents = 60;
|
||||
|
||||
resource.maxVertexOutputComponents = limits.maxVertexOutputComponents;
|
||||
resource.maxGeometryInputComponents = limits.maxGeometryInputComponents;
|
||||
resource.maxGeometryOutputComponents = limits.maxGeometryOutputComponents;
|
||||
resource.maxFragmentInputComponents = limits.maxFragmentInputComponents;
|
||||
|
||||
resource.maxImageUnits = 8;
|
||||
resource.maxCombinedImageUnitsAndFragmentOutputs = 8;
|
||||
resource.maxCombinedShaderOutputResources = 8;
|
||||
resource.maxImageSamples = 0;
|
||||
|
||||
resource.maxVertexImageUniforms = 0;
|
||||
resource.maxTessControlImageUniforms = 0;
|
||||
resource.maxTessEvaluationImageUniforms = 0;
|
||||
|
||||
resource.maxGeometryImageUniforms = 0;
|
||||
resource.maxFragmentImageUniforms = 0;
|
||||
resource.maxCombinedImageUniforms = 0;
|
||||
|
||||
resource.maxGeometryTextureImageUnits = 16;
|
||||
resource.maxGeometryOutputVertices = limits.maxGeometryOutputVertices;
|
||||
resource.maxGeometryTotalOutputComponents = limits.maxGeometryTotalOutputComponents;
|
||||
resource.maxGeometryUniformComponents = 1024;
|
||||
resource.maxGeometryVaryingComponents = 64;
|
||||
|
||||
resource.maxTessControlInputComponents = 128;
|
||||
resource.maxTessControlOutputComponents = 128;
|
||||
resource.maxTessControlTextureImageUnits = 16;
|
||||
resource.maxTessControlUniformComponents = 1024;
|
||||
resource.maxTessControlTotalOutputComponents = 4096;
|
||||
resource.maxTessEvaluationInputComponents = 128;
|
||||
resource.maxTessEvaluationOutputComponents = 128;
|
||||
resource.maxTessEvaluationTextureImageUnits = 16;
|
||||
resource.maxTessEvaluationUniformComponents = 1024;
|
||||
resource.maxTessPatchComponents = 120;
|
||||
|
||||
resource.maxPatchVertices = 32;
|
||||
resource.maxTessGenLevel = limits.maxTessellationGenerationLevel;
|
||||
resource.maxViewports = limits.maxViewports;
|
||||
|
||||
resource.maxVertexAtomicCounters = 0;
|
||||
resource.maxTessControlAtomicCounters = 0;
|
||||
resource.maxTessEvaluationAtomicCounters = 0;
|
||||
resource.maxGeometryAtomicCounters = 0;
|
||||
resource.maxFragmentAtomicCounters = 0;
|
||||
resource.maxCombinedAtomicCounters = 0;
|
||||
resource.maxAtomicCounterBindings = 0;
|
||||
resource.maxVertexAtomicCounterBuffers = 0;
|
||||
resource.maxTessControlAtomicCounterBuffers = 0;
|
||||
resource.maxTessEvaluationAtomicCounterBuffers = 0;
|
||||
resource.maxGeometryAtomicCounterBuffers = 0;
|
||||
resource.maxFragmentAtomicCounterBuffers = 0;
|
||||
resource.maxCombinedAtomicCounterBuffers = 0;
|
||||
resource.maxAtomicCounterBufferSize = 16384;
|
||||
|
||||
resource.maxTransformFeedbackBuffers = 4;
|
||||
resource.maxTransformFeedbackInterleavedComponents = 64;
|
||||
resource.maxCullDistances = 8;
|
||||
resource.maxCombinedClipAndCullDistances = 8;
|
||||
resource.maxSamples = 4;
|
||||
|
||||
/*
|
||||
int maxMeshOutputVerticesNV;
|
||||
int maxMeshOutputPrimitivesNV;
|
||||
int maxMeshWorkGroupSizeX_NV;
|
||||
int maxMeshWorkGroupSizeY_NV;
|
||||
int maxMeshWorkGroupSizeZ_NV;
|
||||
int maxTaskWorkGroupSizeX_NV;
|
||||
int maxTaskWorkGroupSizeY_NV;
|
||||
int maxTaskWorkGroupSizeZ_NV;
|
||||
int maxMeshViewCountNV;
|
||||
int maxMeshOutputVerticesEXT;
|
||||
int maxMeshOutputPrimitivesEXT;
|
||||
int maxMeshWorkGroupSizeX_EXT;
|
||||
int maxMeshWorkGroupSizeY_EXT;
|
||||
int maxMeshWorkGroupSizeZ_EXT;
|
||||
int maxTaskWorkGroupSizeX_EXT;
|
||||
int maxTaskWorkGroupSizeY_EXT;
|
||||
int maxTaskWorkGroupSizeZ_EXT;
|
||||
int maxMeshViewCountEXT;
|
||||
int maxDualSourceDrawBuffersEXT;
|
||||
*/
|
||||
|
||||
resource.limits= {
|
||||
.nonInductiveForLoops = true,
|
||||
.whileLoops = true,
|
||||
.doWhileLoops = true,
|
||||
.generalUniformIndexing = true,
|
||||
.generalAttributeMatrixVectorIndexing = true,
|
||||
.generalVaryingIndexing = true,
|
||||
.generalSamplerIndexing = true,
|
||||
.generalVariableIndexing = true,
|
||||
.generalConstantMatrixVectorIndexing = true,
|
||||
};
|
||||
|
||||
glslang::InitializeProcess();
|
||||
}
|
||||
std::optional<std::vector<uint32_t >> glsl2spv_compile(const std::string& source,EShLanguage lang){
|
||||
glslang::TShader shader(lang);
|
||||
|
||||
shader.setEnvInput(glslang::EShSourceGlsl,lang,glslang::EShClientVulkan,450);
|
||||
shader.setEnvClient(glslang::EShClientVulkan,glslang::EShTargetVulkan_1_0);
|
||||
shader.setEnvTarget(glslang::EshTargetSpv,glslang::EShTargetSpv_1_0);
|
||||
|
||||
const char* shader_source = source.c_str();
|
||||
shader.setStrings(&shader_source,1);
|
||||
|
||||
EShMessages messages = static_cast<EShMessages>(EShMsgSpvRules | EShMsgVulkanRules);
|
||||
if(!shader.parse(&resource,450,false,messages)){
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
glslang::TProgram program;
|
||||
program.addShader(&shader);
|
||||
if(!program.link(messages)){
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::vector<uint32_t> spv;
|
||||
glslang::GlslangToSpv(*program.getIntermediate(lang),spv);
|
||||
return spv;
|
||||
}
|
||||
|
||||
void glsl2spv_finalize(){
|
||||
glslang::FinalizeProcess();
|
||||
}
|
||||
21
app/src/main/cpp/glsl2spv.h
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// Created by aenu on 2025/6/1.
|
||||
// SPDX-License-Identifier: WTFPL
|
||||
//
|
||||
|
||||
#ifndef APS3E_GLSL2SPV_H
|
||||
#define APS3E_GLSL2SPV_H
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include "vkapi.h"
|
||||
#include "glslang/Public/ShaderLang.h"
|
||||
#include "glslang/SPIRV/GlslangToSpv.h"
|
||||
#include "glslang/Include/glslang_c_interface.h"
|
||||
|
||||
void glsl2spv_init(const VkPhysicalDeviceLimits& limits);
|
||||
std::optional<std::vector<uint32_t >> glsl2spv_compile(const std::string& source,EShLanguage lang);
|
||||
void glsl2spv_finalize();
|
||||
|
||||
#endif //APS3E_GLSL2SPV_H
|
||||
249
app/src/main/cpp/iso.cpp
Normal file
@@ -0,0 +1,249 @@
|
||||
//
|
||||
// Created by aenu on 2025/5/11.
|
||||
//
|
||||
#include "iso.h"
|
||||
|
||||
std::unique_ptr<iso_fs> iso_fs::from_fd(int fd) {
|
||||
std::unique_ptr<iso_fs> _iso_fs=std::make_unique<iso_fs>();
|
||||
_iso_fs->fd = fd;
|
||||
return _iso_fs;
|
||||
}
|
||||
|
||||
bool iso_fs::load(){
|
||||
|
||||
off_t pos=0x8000;
|
||||
|
||||
std::optional<VolumeDescriptor> primary_vd;
|
||||
std::optional<VolumeDescriptor> supplementary_vd;
|
||||
|
||||
for(;;){
|
||||
lseek(fd, pos, SEEK_SET);
|
||||
|
||||
VolumeDescriptor vd;
|
||||
if(::read(fd, &vd, sizeof(vd))!=sizeof(vd)){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(memcmp(vd.identifier, "CD001", 5)!=0)
|
||||
return false;
|
||||
|
||||
if(vd.version>2)
|
||||
return false;
|
||||
|
||||
if(vd.type_code==255)
|
||||
break;
|
||||
|
||||
pos+=0x800;
|
||||
|
||||
if(vd.type_code==0){
|
||||
//Boot Record
|
||||
continue;
|
||||
}
|
||||
|
||||
if(vd.type_code==1){
|
||||
primary_vd=vd;
|
||||
continue;
|
||||
}
|
||||
if(vd.type_code==2){
|
||||
supplementary_vd=vd;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(supplementary_vd){
|
||||
parse<2>(*supplementary_vd);
|
||||
return true;
|
||||
}
|
||||
else if(primary_vd){
|
||||
parse<1>(*primary_vd);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool iso_fs::exists(const std::string& path){
|
||||
if(path==":")
|
||||
return true;
|
||||
return files.find(path)!=files.end();
|
||||
}
|
||||
|
||||
std::vector<uint8_t> iso_fs::get_data_tiny(const std::string& path){
|
||||
auto it = files.find(path);
|
||||
if (it != files.end()) {
|
||||
const entry_t& entry = it->second;
|
||||
#if 0
|
||||
if(entry.blocks.size()!=1){
|
||||
//FIXME 应该抛出异常,get_data_tiny应该只用于获取轻量级文件
|
||||
return {};
|
||||
}
|
||||
lseek(fd, entry.blocks[0].offset, SEEK_SET);
|
||||
std::vector<uint8_t> buffer(entry.blocks[0].size);
|
||||
#else
|
||||
lseek(fd, entry.offset, SEEK_SET);
|
||||
std::vector<uint8_t> buffer(entry.size);
|
||||
#endif
|
||||
::read(fd, buffer.data(), buffer.size());
|
||||
return buffer;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<iso_fs::entry_t>& iso_fs::list_dir(const std::string& path){
|
||||
return tree[path];
|
||||
}
|
||||
|
||||
iso_fs::~iso_fs()
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
|
||||
template<const int VOLUME_TYPE>
|
||||
void iso_fs::parse(VolumeDescriptor& vd){
|
||||
read_dir<VOLUME_TYPE>(vd.root_directory_record, ":");//std::nullopt);
|
||||
}
|
||||
|
||||
template<const int VOLUME_TYPE>
|
||||
void iso_fs::read_dir(RootDirectoryRecord& dir_record, std::optional<std::string> path) {
|
||||
if(dir_record.extended_attribute_length!=0){
|
||||
//return;
|
||||
}
|
||||
std::vector<uint8_t> buffer(dir_record.data_length.ne());
|
||||
lseek(fd, dir_record.extent_location.ne()*2048, SEEK_SET);
|
||||
if(::read(fd, buffer.data(), buffer.size())!=buffer.size())
|
||||
return;
|
||||
|
||||
for(size_t offset=0;;){
|
||||
if(offset>=buffer.size())
|
||||
break;
|
||||
size_t length=buffer[offset];
|
||||
if(length==0) {
|
||||
offset&=~2047;
|
||||
offset+=2048;
|
||||
continue;
|
||||
}
|
||||
RootDirectoryRecord record;
|
||||
memcpy(&record, buffer.data()+offset, sizeof(record));
|
||||
if((record.file_identifier_length&1)==1){
|
||||
offset+=length;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto read_file_identifier_ascii=[&]()->std::string {
|
||||
return std::string(reinterpret_cast<char*>(buffer.data() + offset + sizeof(RootDirectoryRecord)), record.file_identifier_length);
|
||||
};
|
||||
//2 bytes
|
||||
auto read_file_identifier_unicode = [&]()->std::string {
|
||||
std::string result;
|
||||
char* file_identifier_base_ptr = reinterpret_cast<char*>(buffer.data() + offset + sizeof(RootDirectoryRecord));
|
||||
for (size_t i = 0; i + 1 < record.file_identifier_length; i += 2) {
|
||||
uint16_t code_unit = (static_cast<uint8_t>(file_identifier_base_ptr[i+0]) << 8) |
|
||||
static_cast<uint8_t>(file_identifier_base_ptr[i + 1]);
|
||||
|
||||
if (code_unit <= 0x7F) {
|
||||
result += static_cast<char>(code_unit);
|
||||
} else if (code_unit <= 0x7FF) {
|
||||
result += static_cast<char>(0xC0 | ((code_unit >> 6) & 0x1F));
|
||||
result += static_cast<char>(0x80 | (code_unit & 0x3F));
|
||||
} else {
|
||||
result += static_cast<char>(0xE0 | ((code_unit >> 12) & 0x0F));
|
||||
result += static_cast<char>(0x80 | ((code_unit >> 6) & 0x3F));
|
||||
result += static_cast<char>(0x80 | (code_unit & 0x3F));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
std::string file_identifier;
|
||||
if constexpr (VOLUME_TYPE==1){
|
||||
file_identifier=read_file_identifier_ascii();
|
||||
}
|
||||
else if constexpr (VOLUME_TYPE==2){
|
||||
file_identifier=read_file_identifier_unicode();
|
||||
}
|
||||
|
||||
//LOGE("%s", file_identifier.c_str());
|
||||
|
||||
//if(path)
|
||||
// file_identifier=path.value()+"/"+file_identifier;
|
||||
|
||||
|
||||
if(path.value()==":")
|
||||
file_identifier = path.value() + file_identifier;
|
||||
else
|
||||
file_identifier = path.value() + "/" + file_identifier;
|
||||
|
||||
if(!(record.file_flags&0x2))
|
||||
file_identifier=file_identifier.substr(0,file_identifier.size()-2); //;1
|
||||
|
||||
#if 0
|
||||
if(auto it=files.find(file_identifier);it!=files.end()){
|
||||
it->second.blocks.push_back({
|
||||
.offset=record.extent_location.ne()*2048,
|
||||
.size=record.data_length.ne(),
|
||||
.entry_offset=it->second.blocks.back().entry_offset+it->second.blocks.back().size,
|
||||
});
|
||||
|
||||
}
|
||||
else{
|
||||
files[file_identifier]=entry_t{
|
||||
.path=file_identifier,
|
||||
.blocks={{
|
||||
.offset=record.extent_location.ne()*2048ull,
|
||||
.size=record.data_length.ne(),
|
||||
.entry_offset=0,
|
||||
}},
|
||||
.is_dir=!!(record.file_flags&0x2)
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
if(auto it=tree.find(path.value());it==tree.end()){
|
||||
tree[path.value()]=std::vector<entry_t>();
|
||||
}
|
||||
|
||||
auto& dir_entries = tree[path.value()];
|
||||
|
||||
if(auto it = std::find_if(dir_entries.begin(), dir_entries.end(), [&](const entry_t& entry) {
|
||||
return entry.path == file_identifier;});it != dir_entries.end())
|
||||
{
|
||||
*it = files[file_identifier];
|
||||
}
|
||||
else {
|
||||
dir_entries.push_back(files[file_identifier]);
|
||||
}
|
||||
#else
|
||||
|
||||
if(auto it=files.find(file_identifier);it!=files.end()){
|
||||
it->second.size+=record.data_length.ne();
|
||||
}
|
||||
else{
|
||||
files[file_identifier]=entry_t{
|
||||
.path=file_identifier,
|
||||
.offset=record.extent_location.ne()*2048ull,
|
||||
.size=record.data_length.ne(),
|
||||
.is_dir=!!(record.file_flags&0x2)
|
||||
};
|
||||
}
|
||||
if(auto it=tree.find(path.value());it==tree.end()){
|
||||
tree[path.value()]=std::vector<entry_t>();
|
||||
}
|
||||
auto& dir_entries = tree[path.value()];
|
||||
if(auto it = std::find_if(dir_entries.begin(), dir_entries.end(), [&](const entry_t& entry) {
|
||||
return entry.path == file_identifier;
|
||||
});it != dir_entries.end()){
|
||||
*it = files[file_identifier];
|
||||
}
|
||||
else {
|
||||
dir_entries.push_back(files[file_identifier]);
|
||||
}
|
||||
|
||||
#endif
|
||||
if(record.file_flags&0x2){
|
||||
read_dir<VOLUME_TYPE>(record, file_identifier);
|
||||
}
|
||||
offset+=length;
|
||||
}
|
||||
}
|
||||
186
app/src/main/cpp/iso.h
Normal file
@@ -0,0 +1,186 @@
|
||||
//
|
||||
// Created by aenu on 2025/5/17.
|
||||
//
|
||||
|
||||
#ifndef APS3E_ISO_H
|
||||
#define APS3E_ISO_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <endian.h>
|
||||
#include <bit>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <numeric>
|
||||
|
||||
#include "util/logs.hpp"
|
||||
|
||||
LOG_CHANNEL(iso_fs_log);
|
||||
|
||||
template<typename T>
|
||||
struct le_be_t {
|
||||
T le;
|
||||
T be;
|
||||
T ne() {
|
||||
#if __BYTE_ORDER==__LITTLE_ENDIAN
|
||||
return le;
|
||||
#elif __BYTE_ORDER==__BIG_ENDIAN
|
||||
return be;
|
||||
#else
|
||||
#error "unknown byte order"
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
struct path_table_t{
|
||||
uint32_t path_table;
|
||||
uint32_t ext_path_table;
|
||||
};
|
||||
|
||||
static_assert(sizeof(path_table_t)==8, "sizeof(path_table_t) != 8");
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct RootDirectoryRecord {
|
||||
uint8_t length;
|
||||
uint8_t extended_attribute_length;
|
||||
le_be_t<uint32_t> extent_location;
|
||||
le_be_t<uint32_t> data_length;
|
||||
uint8_t recording_date[7];
|
||||
uint8_t file_flags;
|
||||
uint8_t file_unit_size;
|
||||
uint8_t interleave_gap_size;
|
||||
le_be_t<uint16_t> volume_sequence_number;
|
||||
uint8_t file_identifier_length;
|
||||
};
|
||||
|
||||
static_assert(sizeof(RootDirectoryRecord)==33, "sizeof(RootDirectoryRecord) != 33");
|
||||
|
||||
struct VolumeDescriptor {
|
||||
uint8_t type_code;
|
||||
char identifier[5];
|
||||
uint8_t version;
|
||||
uint8_t unused[1];
|
||||
char system_identifier[32];
|
||||
char volume_identifier[32];
|
||||
uint8_t unused2[8];
|
||||
le_be_t<uint32_t> volume_space_size;
|
||||
uint8_t unused3[32];
|
||||
le_be_t<uint16_t> volume_set_size;
|
||||
le_be_t<uint16_t> volume_sequence_number;
|
||||
le_be_t<uint16_t> logical_block_size;
|
||||
le_be_t<uint32_t> path_table_size;
|
||||
le_be_t<path_table_t> path_table_data;
|
||||
RootDirectoryRecord root_directory_record;
|
||||
uint8_t unused4[1];
|
||||
char volume_set_identifier[128];
|
||||
char publisher_identifier[128];
|
||||
char data_preparer_identifier[128];
|
||||
char application_identifier[128];
|
||||
char copyright_file_identifier[37];
|
||||
char abstract_file_identifier[37];
|
||||
char bibliographic_file_identifier[37];
|
||||
char volume_creation_date[17];
|
||||
char volume_modification_date[17];
|
||||
char volume_expiration_date[17];
|
||||
char volume_effective_date[17];
|
||||
uint8_t file_structure_version;
|
||||
uint8_t unused5[1];
|
||||
uint8_t application_data[512];
|
||||
uint8_t reserved[653];
|
||||
};
|
||||
|
||||
static_assert(sizeof(VolumeDescriptor)==2048, "sizeof(VolumeDescriptor) != 2048");
|
||||
|
||||
struct iso_fs{
|
||||
static std::unique_ptr<iso_fs> from_fd(int fd);
|
||||
|
||||
iso_fs()=default;
|
||||
~iso_fs();
|
||||
|
||||
iso_fs(const iso_fs&) = delete;
|
||||
iso_fs(iso_fs&&) = delete;
|
||||
|
||||
bool load();
|
||||
|
||||
bool exists(const std::string& path);
|
||||
|
||||
std::vector<uint8_t> get_data_tiny(const std::string& path);
|
||||
|
||||
#if 0
|
||||
struct block_t {
|
||||
uint64_t offset;
|
||||
uint64_t size;
|
||||
|
||||
uint64_t entry_offset;
|
||||
};
|
||||
|
||||
struct entry_t {
|
||||
std::string path;
|
||||
std::vector<block_t> blocks;
|
||||
bool is_dir;
|
||||
|
||||
uint64_t size(){return std::accumulate(blocks.begin(),blocks.end(),0ull,[](uint64_t sum,const block_t& b){return sum+b.size;});}
|
||||
};
|
||||
#else
|
||||
|
||||
struct entry_t {
|
||||
std::string path;
|
||||
uint64_t offset;
|
||||
uint64_t size;
|
||||
bool is_dir;
|
||||
};
|
||||
#endif
|
||||
entry_t get_entry(const std::string& path){
|
||||
if(files.find(path)==files.end()) {
|
||||
iso_fs_log.warning("iso_fs::get_entry(%s) not found",path);
|
||||
return {};
|
||||
}else {
|
||||
iso_fs_log.warning("iso_fs::get_entry(%s) found",path);
|
||||
return files[path];
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<entry_t>& list_dir(const std::string& path);
|
||||
|
||||
off_t seek(uint64_t offset) const {return lseek(fd, offset, SEEK_SET);}
|
||||
ssize_t read(uint8_t* buffer, uint64_t size){return ::read(fd, buffer, size);}
|
||||
|
||||
#if 0
|
||||
void save(int fp,const std::string& path){
|
||||
auto entry=get_entry(path);
|
||||
uint8_t buffer[1024*1024];
|
||||
for(auto& block:entry.blocks){
|
||||
uint64_t offset=block.offset;
|
||||
uint64_t remaining=block.size;
|
||||
uint64_t buffer_size=std::min(remaining,sizeof(buffer));
|
||||
while(remaining>0){
|
||||
seek(offset);
|
||||
read(buffer,buffer_size);
|
||||
write(fp,buffer,buffer_size);
|
||||
remaining-=buffer_size;
|
||||
offset+=buffer_size;
|
||||
buffer_size=std::min(remaining,sizeof(buffer));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
private:
|
||||
|
||||
template<const int VOLUME_TYPE>
|
||||
void parse(VolumeDescriptor& vd);
|
||||
|
||||
template<const int VOLUME_TYPE>
|
||||
void read_dir(RootDirectoryRecord& dir_record,std::optional<std::string> path);
|
||||
|
||||
int fd;
|
||||
std::unordered_map <std::string, entry_t> files;
|
||||
std::unordered_map <std::string, std::vector<entry_t>> tree;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif //APS3E_ISO_H
|
||||
13
app/src/main/cpp/lang_System.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// Created by aenu on 2025/4/10.
|
||||
//
|
||||
#include <stdlib.h>
|
||||
#include <jni.h>
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_aenu_lang_System_setenv(JNIEnv* env,jclass cls,jstring jname,jstring jvalue,jboolean overwrite){
|
||||
const char* name = env->GetStringUTFChars(jname,NULL);
|
||||
const char* value = env->GetStringUTFChars(jvalue,NULL);
|
||||
setenv(name,value,overwrite);
|
||||
env->ReleaseStringUTFChars(jname,name);
|
||||
env->ReleaseStringUTFChars(jvalue,value);
|
||||
}
|
||||
585
app/src/main/cpp/pt.cpp
Normal file
@@ -0,0 +1,585 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <jni.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <csignal>
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <atomic>
|
||||
#include "vkapi.h"
|
||||
#include "vkutil.h"
|
||||
#include "cpuinfo.h"
|
||||
|
||||
#if 0
|
||||
std::string get_gpu_info() {
|
||||
VkApplicationInfo appinfo = {};
|
||||
appinfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
appinfo.pNext = nullptr;
|
||||
appinfo.pApplicationName = "aps3e-test";
|
||||
appinfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
|
||||
appinfo.pEngineName = "nul";
|
||||
appinfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
|
||||
appinfo.apiVersion = VK_API_VERSION_1_0;
|
||||
|
||||
VkInstanceCreateInfo inst_create_info = {};
|
||||
inst_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
inst_create_info.pApplicationInfo = &appinfo;
|
||||
|
||||
VkInstance inst;
|
||||
if (_vkCreateInstance(&inst_create_info, nullptr, &inst)!= VK_SUCCESS) {
|
||||
return "获取gpu信息失败";;
|
||||
}
|
||||
|
||||
// 获取物理设备数量
|
||||
uint32_t physicalDeviceCount = 0;
|
||||
_vkEnumeratePhysicalDevices(inst, &physicalDeviceCount, nullptr);
|
||||
std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
|
||||
_vkEnumeratePhysicalDevices(inst, &physicalDeviceCount, physicalDevices.data());
|
||||
|
||||
if (physicalDeviceCount != 1) {
|
||||
if (physicalDeviceCount == 0) {
|
||||
_vkDestroyInstance(inst, nullptr);
|
||||
return "没有有效的gpu!";
|
||||
}
|
||||
|
||||
std::string result = "多个gpu! [";
|
||||
for (int i = 0; i < physicalDeviceCount; ++i) {
|
||||
|
||||
VkPhysicalDeviceProperties deviceProperties;
|
||||
_vkGetPhysicalDeviceProperties(physicalDevices[i], &deviceProperties);
|
||||
result += deviceProperties.deviceName;
|
||||
if (i != physicalDeviceCount - 1)
|
||||
result += ", ";
|
||||
}
|
||||
_vkDestroyInstance(inst, nullptr);
|
||||
return result+"]";
|
||||
}
|
||||
|
||||
VkPhysicalDevice physicalDevice = physicalDevices[0];
|
||||
|
||||
// 获取物理设备属性以获取设备名称
|
||||
VkPhysicalDeviceProperties deviceProperties;
|
||||
_vkGetPhysicalDeviceProperties(physicalDevice, &deviceProperties);
|
||||
|
||||
uint32_t deviceExtensionCount = 0;
|
||||
_vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &deviceExtensionCount, nullptr);
|
||||
std::vector<VkExtensionProperties> deviceExtensions(deviceExtensionCount);
|
||||
_vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &deviceExtensionCount, deviceExtensions.data());
|
||||
|
||||
std::ostringstream result;
|
||||
|
||||
auto gen_vk_version = [](uint32_t v) {
|
||||
std::ostringstream oss;
|
||||
oss << (v >> 22) << "." << ((v >> 12) & 0x3ff) << "." << (v & 0xfff);
|
||||
return oss.str();
|
||||
};
|
||||
|
||||
result << "GPU ["<<deviceProperties.deviceName<<"(Vulkan "<<gen_vk_version(deviceProperties.apiVersion)<<")]:\n\n";
|
||||
|
||||
auto pr_u64 = [](uint64_t v) {
|
||||
std::ostringstream oss;
|
||||
oss << std::fixed << std::setprecision(2);
|
||||
|
||||
const double GB = 1024.0 * 1024.0 * 1024.0;
|
||||
const double MB = 1024.0 * 1024.0;
|
||||
const double KB = 1024.0;
|
||||
|
||||
if (v >= GB) {
|
||||
double value = v / GB;
|
||||
oss << (value == floor(value) ? std::setprecision(0) : std::setprecision(2))
|
||||
<< value << "GB(" << v << ")";
|
||||
} else if (v >= MB) {
|
||||
double value = v / MB;
|
||||
oss << (value == floor(value) ? std::setprecision(0) : std::setprecision(2))
|
||||
<< value << "MB(" << v << ")";
|
||||
} else if (v >= KB) {
|
||||
double value = v / KB;
|
||||
oss << (value == floor(value) ? std::setprecision(0) : std::setprecision(2))
|
||||
<< value << "KB(" << v << ")";
|
||||
} else {
|
||||
oss << v ;
|
||||
}
|
||||
|
||||
std::string result = oss.str();
|
||||
return result;
|
||||
};
|
||||
|
||||
auto pr_u32 = [&](uint32_t v) {
|
||||
return pr_u64(v);
|
||||
};
|
||||
|
||||
auto pr_f32 = [](float v) {
|
||||
std::ostringstream oss;
|
||||
oss << std::fixed << std::setprecision(4)<<v;
|
||||
return oss.str();
|
||||
};
|
||||
// 宏定义
|
||||
#define w_u32(field) result << " " #field ": " << pr_u32(deviceProperties.limits.field) << "\n"
|
||||
#define w_u64(field) result << " " #field ": " << pr_u64(deviceProperties.limits.field) << "\n"
|
||||
#define w_f32(field) result << " " #field ": " << pr_f32(deviceProperties.limits.field) << "\n"
|
||||
|
||||
result << "limits:\n";
|
||||
|
||||
// 字段映射列表
|
||||
w_u32(maxImageDimension1D);
|
||||
w_u32(maxImageDimension2D);
|
||||
w_u32(maxImageDimension3D);
|
||||
w_u32(maxImageDimensionCube);
|
||||
w_u32(maxImageArrayLayers);
|
||||
w_u32(maxTexelBufferElements);
|
||||
w_u32(maxUniformBufferRange);
|
||||
w_u32(maxStorageBufferRange);
|
||||
w_u32(maxPushConstantsSize);
|
||||
w_u32(maxMemoryAllocationCount);
|
||||
w_u32(maxSamplerAllocationCount);
|
||||
w_u64(bufferImageGranularity);
|
||||
w_u64(sparseAddressSpaceSize);
|
||||
w_u32(maxBoundDescriptorSets);
|
||||
w_u32(maxPerStageDescriptorSamplers);
|
||||
w_u32(maxPerStageDescriptorUniformBuffers);
|
||||
w_u32(maxPerStageDescriptorStorageBuffers);
|
||||
w_u32(maxPerStageDescriptorSampledImages);
|
||||
w_u32(maxPerStageDescriptorStorageImages);
|
||||
w_u32(maxPerStageDescriptorInputAttachments);
|
||||
w_u32(maxPerStageResources);
|
||||
w_u32(maxDescriptorSetSamplers);
|
||||
w_u32(maxDescriptorSetUniformBuffers);
|
||||
w_u32(maxDescriptorSetUniformBuffersDynamic);
|
||||
w_u32(maxDescriptorSetStorageBuffers);
|
||||
w_u32(maxDescriptorSetStorageBuffersDynamic);
|
||||
w_u32(maxDescriptorSetSampledImages);
|
||||
w_u32(maxDescriptorSetStorageImages);
|
||||
w_u32(maxDescriptorSetInputAttachments);
|
||||
w_u32(maxVertexInputAttributes);
|
||||
w_u32(maxVertexInputBindings);
|
||||
w_u32(maxVertexInputAttributeOffset);
|
||||
w_u32(maxVertexInputBindingStride);
|
||||
w_u32(maxVertexOutputComponents);
|
||||
w_u32(maxTessellationGenerationLevel);
|
||||
w_u32(maxTessellationPatchSize);
|
||||
w_u32(maxTessellationControlPerVertexInputComponents);
|
||||
w_u32(maxTessellationControlPerVertexOutputComponents);
|
||||
w_u32(maxTessellationControlPerPatchOutputComponents);
|
||||
w_u32(maxTessellationControlTotalOutputComponents);
|
||||
w_u32(maxTessellationEvaluationInputComponents);
|
||||
w_u32(maxTessellationEvaluationOutputComponents);
|
||||
w_u32(maxGeometryShaderInvocations);
|
||||
w_u32(maxGeometryInputComponents);
|
||||
w_u32(maxGeometryOutputComponents);
|
||||
w_u32(maxGeometryOutputVertices);
|
||||
w_u32(maxGeometryTotalOutputComponents);
|
||||
w_u32(maxFragmentInputComponents);
|
||||
w_u32(maxFragmentOutputAttachments);
|
||||
w_u32(maxFragmentDualSrcAttachments);
|
||||
w_u32(maxFragmentCombinedOutputResources);
|
||||
w_u32(maxComputeSharedMemorySize);
|
||||
result << " maxComputeWorkGroupCount: [x="
|
||||
<< pr_u32(deviceProperties.limits.maxComputeWorkGroupCount[0]) << ", y="
|
||||
<< pr_u32(deviceProperties.limits.maxComputeWorkGroupCount[1]) << ", z="
|
||||
<< pr_u32(deviceProperties.limits.maxComputeWorkGroupCount[2]) << "]\n";
|
||||
w_u32(maxComputeWorkGroupInvocations);
|
||||
result << " maxComputeWorkGroupSize: [x="
|
||||
<< pr_u32(deviceProperties.limits.maxComputeWorkGroupSize[0]) << ", y="
|
||||
<< pr_u32(deviceProperties.limits.maxComputeWorkGroupSize[1]) << ", z="
|
||||
<< pr_u32(deviceProperties.limits.maxComputeWorkGroupSize[2]) << "]\n";
|
||||
w_u32(subPixelPrecisionBits);
|
||||
w_u32(subTexelPrecisionBits);
|
||||
w_u32(mipmapPrecisionBits);
|
||||
w_u32(maxDrawIndexedIndexValue);
|
||||
w_u32(maxDrawIndirectCount);
|
||||
w_f32(maxSamplerLodBias);
|
||||
w_f32(maxSamplerAnisotropy);
|
||||
w_u32(maxViewports);
|
||||
// 二维数组处理:
|
||||
result << " maxViewportDimensions: ["
|
||||
<< pr_u32(deviceProperties.limits.maxViewportDimensions[0]) << " | "
|
||||
<< pr_u32(deviceProperties.limits.maxViewportDimensions[1]) << "]\n";
|
||||
result << " viewportBoundsRange: ["
|
||||
<< pr_f32(deviceProperties.limits.viewportBoundsRange[0]) << " | "
|
||||
<< pr_f32(deviceProperties.limits.viewportBoundsRange[1]) << "]\n";
|
||||
w_u32(viewportSubPixelBits);
|
||||
w_u64(minMemoryMapAlignment);
|
||||
w_u64(minTexelBufferOffsetAlignment);
|
||||
w_u64(minUniformBufferOffsetAlignment);
|
||||
w_u64(minStorageBufferOffsetAlignment);
|
||||
w_u32(minTexelOffset);
|
||||
w_u32(maxTexelOffset);
|
||||
w_u32(minTexelGatherOffset);
|
||||
w_u32(maxTexelGatherOffset);
|
||||
w_f32(minInterpolationOffset);
|
||||
w_f32(maxInterpolationOffset);
|
||||
w_u32(subPixelInterpolationOffsetBits);
|
||||
w_u32(maxFramebufferWidth);
|
||||
w_u32(maxFramebufferHeight);
|
||||
w_u32(maxFramebufferLayers);
|
||||
w_u32(framebufferColorSampleCounts);
|
||||
w_u32(framebufferDepthSampleCounts);
|
||||
w_u32(framebufferStencilSampleCounts);
|
||||
w_u32(framebufferNoAttachmentsSampleCounts);
|
||||
w_u32(maxColorAttachments);
|
||||
w_u32(sampledImageColorSampleCounts);
|
||||
w_u32(sampledImageIntegerSampleCounts);
|
||||
w_u32(sampledImageDepthSampleCounts);
|
||||
w_u32(sampledImageStencilSampleCounts);
|
||||
w_u32(storageImageSampleCounts);
|
||||
w_u32(maxSampleMaskWords);
|
||||
w_u32(timestampComputeAndGraphics);
|
||||
w_f32(timestampPeriod);
|
||||
w_u32(maxClipDistances);
|
||||
w_u32(maxCullDistances);
|
||||
w_u32(maxCombinedClipAndCullDistances);
|
||||
w_u32(discreteQueuePriorities);
|
||||
// 浮点数组处理:
|
||||
result << " pointSizeRange: ["
|
||||
<< pr_f32(deviceProperties.limits.pointSizeRange[0]) << " | "
|
||||
<< pr_f32(deviceProperties.limits.pointSizeRange[1]) << "]\n";
|
||||
result << " lineWidthRange: ["
|
||||
<< pr_f32(deviceProperties.limits.lineWidthRange[0]) << " | "
|
||||
<< pr_f32(deviceProperties.limits.lineWidthRange[1]) << "]\n";
|
||||
w_f32(pointSizeGranularity);
|
||||
w_f32(lineWidthGranularity);
|
||||
w_u32(strictLines);
|
||||
w_u32(standardSampleLocations);
|
||||
w_u64(optimalBufferCopyOffsetAlignment);
|
||||
w_u64(optimalBufferCopyRowPitchAlignment);
|
||||
w_u64(nonCoherentAtomSize);
|
||||
|
||||
#undef w_f32
|
||||
#undef w_u32
|
||||
#undef w_u64
|
||||
|
||||
result << "\n";
|
||||
|
||||
result << "extensions:\n";
|
||||
for (const auto& deviceExt : deviceExtensions) {
|
||||
result << " * " << deviceExt.extensionName<< "\n";
|
||||
}
|
||||
|
||||
vkDestroyInstance(inst, nullptr);
|
||||
return result.str();
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#if 0
|
||||
std::string get_cpu_info() {
|
||||
std::ifstream cpuinfo("/proc/cpuinfo");
|
||||
if (!cpuinfo.is_open()) {
|
||||
return "获取cpuinfo失败";
|
||||
}
|
||||
|
||||
struct CoreInfo {
|
||||
int implementer;
|
||||
int variant;
|
||||
int part;
|
||||
std::vector<std::string> features;
|
||||
};
|
||||
|
||||
std::vector<CoreInfo> cores;
|
||||
std::map<std::tuple<int,int,int>,int> core_n;
|
||||
|
||||
std::string line;
|
||||
|
||||
CoreInfo core;
|
||||
|
||||
while (std::getline(cpuinfo, line)) {
|
||||
|
||||
if (line.find("CPU implementer") != std::string::npos) {
|
||||
core.implementer = std::stoi(line.substr(line.find(":") + 2), nullptr, 16);
|
||||
}
|
||||
else if (line.find("CPU variant") != std::string::npos) {
|
||||
core.variant = std::stoi(line.substr(line.find(":") + 2), nullptr, 16);
|
||||
}
|
||||
else if (line.find("CPU part") != std::string::npos) {
|
||||
core.part = std::stoi(line.substr(line.find(":") + 2), nullptr, 16);
|
||||
cores.push_back(core);
|
||||
if (core_n.find({core.implementer, core.variant, core.part}) == core_n.end()) {
|
||||
core_n[{core.implementer, core.variant, core.part}] = 1;
|
||||
}
|
||||
else {
|
||||
core_n[{core.implementer, core.variant, core.part}]++;
|
||||
}
|
||||
}
|
||||
else if (line.find("Features") != std::string::npos) {
|
||||
std::string features = line.substr(line.find(":") + 2);
|
||||
std::istringstream iss(features);
|
||||
std::string feature;
|
||||
while (iss >> feature) {
|
||||
core.features.push_back(feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto cpu_core_info = [&]() {
|
||||
|
||||
static const std::map<std::tuple<int,int>,std::string> core_map{
|
||||
|
||||
{{ 0x41, 0xd01}, "Cortex-A32" },
|
||||
{{ 0x41, 0xd04}, "Cortex-A35" },
|
||||
{{ 0x41, 0xd03}, "Cortex-A53" },
|
||||
{{ 0x41, 0xd07}, "Cortex-A57" },
|
||||
{{ 0x41, 0xd08}, "Cortex-A72" },
|
||||
{{ 0x41, 0xd09}, "Cortex-A73" },
|
||||
|
||||
{{ 0x41, 0xd05}, "Cortex-A55" },
|
||||
{{ 0x41, 0xd0a}, "Cortex-A75" },
|
||||
{{ 0x41, 0xd0b}, "Cortex-A76" },
|
||||
{{ 0x41, 0xd0d}, "Cortex-A77" },
|
||||
{{ 0x41, 0xd41}, "Cortex-A78" },
|
||||
{{ 0x41, 0xd44}, "Cortex-X1" },
|
||||
|
||||
{{ 0x41, 0xd46}, "Cortex-A510" },
|
||||
{{ 0x41, 0xd47}, "Cortex-A710" },
|
||||
{{ 0x41, 0xd48}, "Cortex-X2" },
|
||||
{{ 0x41, 0xd4d}, "Cortex-A715" },
|
||||
{{ 0x41, 0xd4e}, "Cortex-X3" },
|
||||
|
||||
{{ 0x41, 0xd80}, "Cortex-A520" },
|
||||
{{ 0x41, 0xd81}, "Cortex-A720" },
|
||||
{{ 0x41, 0xd87}, "Cortex-A725" },
|
||||
{{ 0x41, 0xd82}, "Cortex-X4" },
|
||||
{{ 0x41, 0xd85}, "Cortex-X925" },
|
||||
|
||||
{{ 0x51, 0x001}, "X-Elite" },
|
||||
};
|
||||
|
||||
std::ostringstream ss;
|
||||
for(const auto& [k,v] : core_n){
|
||||
auto &[implementer, variant, part] = k;
|
||||
if (auto core = core_map.find(std::make_tuple(implementer, part)); core != core_map.end()) {
|
||||
ss <<core->second << "*"<< v << "+";
|
||||
}
|
||||
else{
|
||||
ss <<"[" <<implementer<<" | "<<part<< "]*"<< v << "+";
|
||||
}
|
||||
}
|
||||
std::string r=ss.str();
|
||||
if(r.size()<1) return "获取cpu信息失败"s;
|
||||
return r.substr(0,r.size()-1);
|
||||
}();
|
||||
|
||||
std::stringstream result;
|
||||
|
||||
result << "CPU [" << cpu_core_info << "]:\n";
|
||||
|
||||
if (cores.size() > 0) {
|
||||
//TODO 理论上来讲,所有核心的feature应该都是相同的
|
||||
for (const auto& frature : cores[0].features) {
|
||||
result << " * " << frature << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
return result.str();
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
int main() {
|
||||
std::cout<< get_supported_extensions() << std::endl;
|
||||
}*/
|
||||
|
||||
std::string get_auther_info(){
|
||||
return "b站 路人aenu \n" \
|
||||
"个人主页https://aenu.cc \n";
|
||||
}
|
||||
|
||||
std::pair<std::string,bool> vk_lib_info(){
|
||||
const std::pair<std::string,bool> dedault_info={"libvulkan.so",false};
|
||||
const char* cfg_path=getenv("APS3E_CONFIG_YAML_PATH");
|
||||
if(!cfg_path)
|
||||
return dedault_info;
|
||||
if(!std::filesystem::exists(cfg_path))
|
||||
return dedault_info;
|
||||
|
||||
YAML::Node config_node = YAML::LoadFile(cfg_path);
|
||||
if(!config_node.IsDefined())
|
||||
return dedault_info;
|
||||
YAML::Node use_custom_driver=config_node["Video"]["Vulkan"]["Use Custom Driver"];
|
||||
if(!use_custom_driver.IsDefined())
|
||||
return dedault_info;
|
||||
if(!use_custom_driver.as<bool>())
|
||||
return dedault_info;
|
||||
|
||||
YAML::Node custom_lib_path=config_node["Video"]["Vulkan"]["Custom Driver Library Path"];
|
||||
if(!custom_lib_path.IsDefined())
|
||||
return dedault_info;
|
||||
std::string custom_lib_path_str=custom_lib_path.as<std::string>();
|
||||
if(custom_lib_path_str.empty()||!std::filesystem::exists(custom_lib_path_str))
|
||||
return dedault_info;
|
||||
return {custom_lib_path_str,true};
|
||||
}
|
||||
|
||||
|
||||
std::string test_compute_pipeline_source(){
|
||||
return R"(
|
||||
#version 430
|
||||
layout(local_size_x=32, local_size_y=1, local_size_z=1) in;
|
||||
layout(set = 0, binding=0, std430) buffer ssbo{ uint data[]; };
|
||||
|
||||
|
||||
#define KERNEL_SIZE 1
|
||||
|
||||
// Generic swap routines
|
||||
#define bswap_u16(bits) (bits & 0xFF) << 8 | (bits & 0xFF00) >> 8 | (bits & 0xFF0000) << 8 | (bits & 0xFF000000) >> 8
|
||||
#define bswap_u32(bits) (bits & 0xFF) << 24 | (bits & 0xFF00) << 8 | (bits & 0xFF0000) >> 8 | (bits & 0xFF000000) >> 24
|
||||
#define bswap_u16_u32(bits) (bits & 0xFFFF) << 16 | (bits & 0xFFFF0000) >> 16
|
||||
|
||||
// Depth format conversions
|
||||
#define d24_to_f32(bits) floatBitsToUint(float(bits) / 16777215.f)
|
||||
#define f32_to_d24(bits) uint(uintBitsToFloat(bits) * 16777215.f)
|
||||
#define d24f_to_f32(bits) (bits << 7)
|
||||
#define f32_to_d24f(bits) (bits >> 7)
|
||||
#define d24x8_to_f32(bits) d24_to_f32(bits >> 8)
|
||||
#define d24x8_to_d24x8_swapped(bits) (bits & 0xFF00) | (bits & 0xFF0000) >> 16 | (bits & 0xFF) << 16
|
||||
#define f32_to_d24x8_swapped(bits) d24x8_to_d24x8_swapped(f32_to_d24(bits))
|
||||
|
||||
uint linear_invocation_id()
|
||||
{
|
||||
uint size_in_x = (gl_NumWorkGroups.x * gl_WorkGroupSize.x);
|
||||
return (gl_GlobalInvocationID.y * size_in_x) + gl_GlobalInvocationID.x;
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
uint invocation_id = linear_invocation_id();
|
||||
uint index = invocation_id * KERNEL_SIZE;
|
||||
uint value;
|
||||
|
||||
|
||||
{
|
||||
value = data[index];
|
||||
data[index] = bswap_u32(value);
|
||||
}
|
||||
}
|
||||
)";
|
||||
}
|
||||
|
||||
std::string get_gpu_info(){
|
||||
std::pair<std::string,bool> lib_info=vk_lib_info();
|
||||
vk_load(lib_info.first.c_str(),lib_info.second);
|
||||
|
||||
struct clean_t{
|
||||
std::vector<std::function<void()>> funcs;
|
||||
~clean_t(){
|
||||
for(auto it=funcs.rbegin();it!=funcs.rend();it++){
|
||||
(*it)();
|
||||
}
|
||||
}
|
||||
}clean;
|
||||
|
||||
clean.funcs.push_back([](){
|
||||
vk_unload();
|
||||
});
|
||||
|
||||
std::optional<VkInstance> inst=vk_create_instance("aps3e-gpu_info");
|
||||
if(!inst) {
|
||||
return "获取gpu信息失败";
|
||||
}
|
||||
|
||||
clean.funcs.push_back([&](){
|
||||
vk_destroy_instance(*inst);
|
||||
});
|
||||
|
||||
if(int count=vk_get_physical_device_count(*inst);count!=1) {
|
||||
|
||||
if(count<1){
|
||||
return "获取gpu信息失败";
|
||||
}
|
||||
if(count>1){
|
||||
return "多个gpu!";
|
||||
}
|
||||
}
|
||||
if(auto pdev=vk_get_physical_device(*inst);pdev) {
|
||||
std::string gpu_name=vk_get_physical_device_properties(*pdev).deviceName;
|
||||
std::string gpu_vk_ver=[](uint32_t v) {
|
||||
std::ostringstream oss;
|
||||
oss << (v >> 22) << "." << ((v >> 12) & 0x3ff) << "." << (v & 0xfff);
|
||||
return oss.str();
|
||||
}(vk_get_physical_device_properties(*pdev).apiVersion);
|
||||
|
||||
std::string gpu_ext=[&]() {
|
||||
std::ostringstream oss;
|
||||
for (auto ext : vk_get_physical_device_extension_properties(*pdev)) {
|
||||
oss <<" * " << ext.extensionName << "\n";
|
||||
}
|
||||
return oss.str();
|
||||
}();
|
||||
#if 0
|
||||
VkQueueFamilyProperties queue_family_props=vk_get_queue_family_properties(*pdev,0);
|
||||
if(auto dev=vk_create_device(*pdev,0,queue_family_props);dev){
|
||||
clean.funcs.push_back([&](){
|
||||
vk_destroy_device(*dev);
|
||||
});
|
||||
std::vector<VkDescriptorSetLayoutBinding> binds;
|
||||
binds.push_back(
|
||||
VkDescriptorSetLayoutBinding{0,VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,1,VK_SHADER_STAGE_COMPUTE_BIT,nullptr});
|
||||
auto descriptor_set_layout=vk_create_descriptor_set_layout(*dev,binds);
|
||||
clean.funcs.push_back([&](){
|
||||
vk_destroy_descriptor_set_layout(*dev,*descriptor_set_layout);
|
||||
});
|
||||
auto pipeline_layout=vk_create_pipeline_layout(*dev,*descriptor_set_layout);
|
||||
clean.funcs.push_back([&](){
|
||||
vk_destroy_pipeline_layout(*dev,*pipeline_layout);
|
||||
});
|
||||
std::optional<std::vector<uint32_t>> spv=vk_compile_glsl_to_spv(*dev,test_compute_pipeline_source(),vk_get_physical_device_limits(*pdev));
|
||||
auto module=vk_create_shader_module(*dev,*spv);
|
||||
|
||||
clean.funcs.push_back([&](){
|
||||
vk_destroy_shader_module(*dev,*module);
|
||||
});
|
||||
|
||||
auto pipeline=vk_create_compute_pipeline(*dev,*pipeline_layout,*module);
|
||||
if(pipeline){
|
||||
gpu_name+=":ok";
|
||||
clean.funcs.push_back([&](){
|
||||
vk_destroy_pipeline(*dev,*pipeline);
|
||||
});
|
||||
return "GPU [" + gpu_name +"(VK: "+gpu_vk_ver+ ")]:\n" + gpu_ext;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
return "GPU [" + gpu_name +"(VK: "+gpu_vk_ver+ ")]:\n" + gpu_ext;
|
||||
|
||||
}
|
||||
return "获取gpu信息失败";
|
||||
|
||||
}
|
||||
|
||||
std::string get_cpu_info() {
|
||||
|
||||
std::vector<core_info_t> core_info=cpu_get_core_info();
|
||||
std::string cpu_name=cpu_get_simple_info(core_info);
|
||||
std::string cpu_features=[&](){
|
||||
std::ostringstream oss;
|
||||
for(const auto& feature : core_info[0].features){
|
||||
oss <<" * " << feature << "\n";
|
||||
}
|
||||
return oss.str();
|
||||
}();
|
||||
return "CPU [" + cpu_name + "]:\n" + cpu_features;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
JNIEXPORT jstring JNICALL Java_aenu_proptest_HelloJni_stringFromJNI(JNIEnv* env, jobject thiz)
|
||||
{
|
||||
|
||||
std::string vv;//=get_auther_info();
|
||||
|
||||
vv+=get_cpu_info();
|
||||
vv+="\n"+get_gpu_info();
|
||||
|
||||
return env->NewStringUTF(vv.c_str());
|
||||
}
|
||||
}
|
||||
37
app/src/main/cpp/rpcs3/.ci/build-freebsd.sh
Normal file
@@ -0,0 +1,37 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
# Pull all the submodules except llvm
|
||||
# Note: Tried to use git submodule status, but it takes over 20 seconds
|
||||
# shellcheck disable=SC2046
|
||||
git submodule -q update --init --depth 1 $(awk '/path/ && !/llvm/ { print $3 }' .gitmodules)
|
||||
|
||||
# Prefer newer Clang than in base system (see also .ci/install-freebsd.sh)
|
||||
# libc++ isn't in llvm* packages, so download manually
|
||||
fetch https://github.com/llvm/llvm-project/releases/download/llvmorg-16.0.1/llvm-project-16.0.1.src.tar.xz
|
||||
tar xf llvm*.tar.xz
|
||||
export CC=clang16 CXX=clang++16
|
||||
cmake -B libcxx_build -G Ninja -S llvm*/libcxx \
|
||||
-DLLVM_CCACHE_BUILD=ON \
|
||||
-DLIBCXX_INCLUDE_BENCHMARKS=OFF \
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=libcxx_prefix
|
||||
cmake --build libcxx_build
|
||||
cmake --install libcxx_build
|
||||
export CXXFLAGS="$CXXFLAGS -nostdinc++ -isystem$PWD/libcxx_prefix/include/c++/v1"
|
||||
export LDFLAGS="$LDFLAGS -nostdlib++ -L$PWD/libcxx_prefix/lib -l:libc++.a -lcxxrt"
|
||||
|
||||
CONFIGURE_ARGS="
|
||||
-DWITH_LLVM=ON
|
||||
-DUSE_SDL=OFF
|
||||
-DUSE_PRECOMPILED_HEADERS=OFF
|
||||
-DUSE_NATIVE_INSTRUCTIONS=OFF
|
||||
-DUSE_SYSTEM_FFMPEG=ON
|
||||
-DUSE_SYSTEM_CURL=ON
|
||||
-DUSE_SYSTEM_LIBPNG=ON
|
||||
"
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
cmake -B build -G Ninja $CONFIGURE_ARGS
|
||||
cmake --build build
|
||||
|
||||
ccache --show-stats
|
||||
ccache --zero-stats
|
||||
47
app/src/main/cpp/rpcs3/.ci/build-linux-aarch64.sh
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
if [ -z "$CIRRUS_CI" ]; then
|
||||
cd rpcs3 || exit 1
|
||||
fi
|
||||
|
||||
git config --global --add safe.directory '*'
|
||||
|
||||
# Pull all the submodules except llvm
|
||||
# shellcheck disable=SC2046
|
||||
git submodule -q update --init $(awk '/path/ && !/llvm/ { print $3 }' .gitmodules)
|
||||
|
||||
mkdir build && cd build || exit 1
|
||||
|
||||
export CC="${CLANG_BINARY}"
|
||||
export CXX="${CLANGXX_BINARY}"
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DUSE_NATIVE_INSTRUCTIONS=OFF \
|
||||
-DUSE_PRECOMPILED_HEADERS=OFF \
|
||||
-DCMAKE_C_FLAGS="$CFLAGS" \
|
||||
-DCMAKE_CXX_FLAGS="$CFLAGS" \
|
||||
-DUSE_SYSTEM_CURL=ON \
|
||||
-DUSE_SDL=ON \
|
||||
-DUSE_SYSTEM_SDL=ON \
|
||||
-DUSE_SYSTEM_FFMPEG=OFF \
|
||||
-DUSE_DISCORD_RPC=ON \
|
||||
-DOpenGL_GL_PREFERENCE=LEGACY \
|
||||
-DLLVM_DIR=/opt/llvm/lib/cmake/llvm \
|
||||
-DSTATIC_LINK_LLVM=ON \
|
||||
-G Ninja
|
||||
|
||||
ninja; build_status=$?;
|
||||
|
||||
cd ..
|
||||
|
||||
shellcheck .ci/*.sh
|
||||
|
||||
# If it compiled succesfully let's deploy.
|
||||
# Azure and Cirrus publish PRs as artifacts only.
|
||||
{ [ "$CI_HAS_ARTIFACTS" = "true" ];
|
||||
} && SHOULD_DEPLOY="true" || SHOULD_DEPLOY="false"
|
||||
|
||||
if [ "$build_status" -eq 0 ] && [ "$SHOULD_DEPLOY" = "true" ]; then
|
||||
.ci/deploy-linux.sh "aarch64"
|
||||
fi
|
||||
66
app/src/main/cpp/rpcs3/.ci/build-linux.sh
Normal file
@@ -0,0 +1,66 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
if [ -z "$CIRRUS_CI" ]; then
|
||||
cd rpcs3 || exit 1
|
||||
fi
|
||||
|
||||
git config --global --add safe.directory '*'
|
||||
|
||||
# Pull all the submodules except llvm
|
||||
# Note: Tried to use git submodule status, but it takes over 20 seconds
|
||||
# shellcheck disable=SC2046
|
||||
git submodule -q update --init $(awk '/path/ && !/llvm/ { print $3 }' .gitmodules)
|
||||
|
||||
mkdir build && cd build || exit 1
|
||||
|
||||
if [ "$COMPILER" = "gcc" ]; then
|
||||
# These are set in the dockerfile
|
||||
export CC="${GCC_BINARY}"
|
||||
export CXX="${GXX_BINARY}"
|
||||
export LINKER=gold
|
||||
# We need to set the following variables for LTO to link properly
|
||||
export AR=/usr/bin/gcc-ar-"$GCCVER"
|
||||
export RANLIB=/usr/bin/gcc-ranlib-"$GCCVER"
|
||||
export CFLAGS="-fuse-linker-plugin"
|
||||
else
|
||||
export CC="${CLANG_BINARY}"
|
||||
export CXX="${CLANGXX_BINARY}"
|
||||
export LINKER=lld
|
||||
export AR=/usr/bin/llvm-ar-"$LLVMVER"
|
||||
export RANLIB=/usr/bin/llvm-ranlib-"$LLVMVER"
|
||||
fi
|
||||
|
||||
export CFLAGS="$CFLAGS -fuse-ld=${LINKER}"
|
||||
|
||||
cmake .. \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DUSE_NATIVE_INSTRUCTIONS=OFF \
|
||||
-DUSE_PRECOMPILED_HEADERS=OFF \
|
||||
-DCMAKE_C_FLAGS="$CFLAGS" \
|
||||
-DCMAKE_CXX_FLAGS="$CFLAGS" \
|
||||
-DCMAKE_AR="$AR" \
|
||||
-DCMAKE_RANLIB="$RANLIB" \
|
||||
-DUSE_SYSTEM_CURL=ON \
|
||||
-DUSE_SDL=ON \
|
||||
-DUSE_SYSTEM_SDL=ON \
|
||||
-DUSE_SYSTEM_FFMPEG=OFF \
|
||||
-DUSE_DISCORD_RPC=ON \
|
||||
-DOpenGL_GL_PREFERENCE=LEGACY \
|
||||
-DLLVM_DIR=/opt/llvm/lib/cmake/llvm \
|
||||
-DSTATIC_LINK_LLVM=ON \
|
||||
-G Ninja
|
||||
|
||||
ninja; build_status=$?;
|
||||
|
||||
cd ..
|
||||
|
||||
shellcheck .ci/*.sh
|
||||
|
||||
# If it compiled succesfully let's deploy.
|
||||
# Azure and Cirrus publish PRs as artifacts only.
|
||||
{ [ "$CI_HAS_ARTIFACTS" = "true" ];
|
||||
} && SHOULD_DEPLOY="true" || SHOULD_DEPLOY="false"
|
||||
|
||||
if [ "$build_status" -eq 0 ] && [ "$SHOULD_DEPLOY" = "true" ]; then
|
||||
.ci/deploy-linux.sh "x86_64"
|
||||
fi
|
||||
153
app/src/main/cpp/rpcs3/.ci/build-mac-arm64.sh
Normal file
@@ -0,0 +1,153 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
brew_arm64_install_packages() {
|
||||
for pkg in "$@"; do
|
||||
echo "Fetching bottle for $pkg (arm64)..."
|
||||
bottle_path="$("$BREW_ARM64_PATH/bin/brew" --cache --bottle-tag=arm64_ventura "$pkg")"
|
||||
if [ ! -f "$bottle_path" ]; then
|
||||
if ! "$BREW_ARM64_PATH/bin/brew" fetch --force --verbose --debug --bottle-tag=arm64_ventura "$pkg"; then
|
||||
echo "Failed to fetch bottle for $pkg"
|
||||
return 1
|
||||
fi
|
||||
bottle_path="$("$BREW_ARM64_PATH/bin/brew" --cache --bottle-tag=arm64_ventura "$pkg")"
|
||||
fi
|
||||
|
||||
echo "Installing $pkg (arm64)..."
|
||||
"$BREW_ARM64_PATH/bin/brew" install --force --force-bottle --ignore-dependencies "$bottle_path" || true
|
||||
done
|
||||
}
|
||||
|
||||
export HOMEBREW_NO_AUTO_UPDATE=1
|
||||
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
|
||||
export HOMEBREW_NO_INSTALL_CLEANUP=1
|
||||
|
||||
/usr/local/bin/brew update
|
||||
sudo rm -rf /usr/local/Cellar/curl /usr/local/opt/curl
|
||||
/usr/local/bin/brew install -f --overwrite curl
|
||||
/usr/local/bin/brew uninstall -f --ignore-dependencies ffmpeg
|
||||
/usr/local/bin/brew install -f --build-from-source ffmpeg@5 || true
|
||||
/usr/local/bin/brew install -f --overwrite python || true
|
||||
/usr/local/bin/brew link --overwrite python || true
|
||||
/usr/local/bin/brew install -f --overwrite nasm ninja p7zip ccache pipenv #create-dmg
|
||||
/usr/local/bin/brew link -f curl || true
|
||||
/usr/local/bin/brew install llvm@$LLVM_COMPILER_VER glew cmake sdl2 vulkan-headers coreutils
|
||||
/usr/local/bin/brew link -f llvm@$LLVM_COMPILER_VER ffmpeg@5 || true
|
||||
|
||||
export BREW_ARM64_PATH="/opt/homebrew1"
|
||||
sudo mkdir -p "$BREW_ARM64_PATH"
|
||||
sudo chmod 777 "$BREW_ARM64_PATH"
|
||||
curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C "$BREW_ARM64_PATH"
|
||||
|
||||
#"$BREW_ARM64_PATH/bin/brew" update
|
||||
# libvorbis requires Homebrew-installed curl, but we can't run it on x64, and we also need the aarch64 libs, so we swap the binary
|
||||
brew_arm64_install_packages curl
|
||||
mv /opt/homebrew1/opt/curl/bin/curl /opt/homebrew1/opt/curl/bin/curl.bak
|
||||
ln -s /usr/local/opt/curl/bin/curl /opt/homebrew1/opt/curl/bin/curl
|
||||
|
||||
brew_arm64_install_packages 0mq aom aribb24 ca-certificates cjson dav1d ffmpeg@5 fontconfig freetype freetype2 gettext glew gmp gnutls lame libbluray libidn2 libnettle libogg libpng librist libsodium libsoxr libtasn libtasn1 libunistring libvmaf libvorbis libvpx libx11 libxau libxcb libxdmcp llvm@$LLVM_COMPILER_VER mbedtls molten-vk nettle opencore-amr openjpeg openssl opus p11-kit pkg-config pkgconfig pzstd rav1e sdl2 snappy speex srt svt-av1 theora vulkan-headers webp x264 x265 xz z3 zeromq zmq zstd
|
||||
"$BREW_ARM64_PATH/bin/brew" link -f ffmpeg@5
|
||||
|
||||
# moltenvk based on commit for 1.2.11 release
|
||||
wget https://raw.githubusercontent.com/Homebrew/homebrew-core/6bfc8950c696d1f952425e8af2a6248603dc0df9/Formula/m/molten-vk.rb
|
||||
/usr/local/bin/brew install -f --overwrite ./molten-vk.rb
|
||||
export CXX=clang++
|
||||
export CC=clang
|
||||
|
||||
export BREW_PATH;
|
||||
BREW_PATH="$(brew --prefix)"
|
||||
export BREW_X64_PATH;
|
||||
BREW_X64_PATH="$("/usr/local/bin/brew" --prefix)"
|
||||
export BREW_BIN="/usr/local/bin"
|
||||
export BREW_SBIN="/usr/local/sbin"
|
||||
export CMAKE_EXTRA_OPTS='-DLLVM_TARGETS_TO_BUILD=arm64'
|
||||
|
||||
export WORKDIR;
|
||||
WORKDIR="$(pwd)"
|
||||
|
||||
# Get Qt
|
||||
if [ ! -d "/tmp/Qt/$QT_VER" ]; then
|
||||
mkdir -p "/tmp/Qt"
|
||||
git clone https://github.com/engnr/qt-downloader.git
|
||||
cd qt-downloader
|
||||
git checkout f52efee0f18668c6d6de2dec0234b8c4bc54c597
|
||||
cd "/tmp/Qt"
|
||||
"$BREW_X64_PATH/bin/pipenv" run pip3 install py7zr requests semantic_version lxml
|
||||
mkdir -p "$QT_VER/macos" ; ln -s "macos" "$QT_VER/clang_64"
|
||||
"$BREW_X64_PATH/bin/pipenv" run "$WORKDIR/qt-downloader/qt-downloader" macos desktop "$QT_VER" clang_64 --opensource --addons qtmultimedia qtimageformats
|
||||
fi
|
||||
|
||||
cd "$WORKDIR"
|
||||
ditto "/tmp/Qt/$QT_VER" "qt-downloader/$QT_VER"
|
||||
|
||||
export Qt6_DIR="$WORKDIR/qt-downloader/$QT_VER/clang_64/lib/cmake/Qt$QT_VER_MAIN"
|
||||
export SDL2_DIR="$BREW_ARM64_PATH/opt/sdl2/lib/cmake/SDL2"
|
||||
|
||||
export PATH="$BREW_X64_PATH/opt/llvm@$LLVM_COMPILER_VER/bin:$WORKDIR/qt-downloader/$QT_VER/clang_64/bin:$BREW_BIN:$BREW_SBIN:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Library/Apple/usr/bin:$PATH"
|
||||
export LDFLAGS="-L$BREW_ARM64_PATH/lib $BREW_ARM64_PATH/opt/ffmpeg@5/lib/libavcodec.dylib $BREW_ARM64_PATH/opt/ffmpeg@5/lib/libavformat.dylib $BREW_ARM64_PATH/opt/ffmpeg@5/lib/libavutil.dylib $BREW_ARM64_PATH/opt/ffmpeg@5/lib/libswscale.dylib $BREW_ARM64_PATH/opt/ffmpeg@5/lib/libswresample.dylib $BREW_ARM64_PATH/opt/llvm@$LLVM_COMPILER_VER/lib/c++/libc++.1.dylib $BREW_ARM64_PATH/lib/libSDL2.dylib $BREW_ARM64_PATH/lib/libGLEW.dylib $BREW_ARM64_PATH/opt/llvm@$LLVM_COMPILER_VER/lib/libunwind.1.dylib -Wl,-rpath,$BREW_ARM64_PATH/lib"
|
||||
export CPPFLAGS="-I$BREW_ARM64_PATH/include -I$BREW_X64_PATH/include -no-pie -D__MAC_OS_X_VERSION_MIN_REQUIRED=130000"
|
||||
export CFLAGS="-D__MAC_OS_X_VERSION_MIN_REQUIRED=130000"
|
||||
export LIBRARY_PATH="$BREW_ARM64_PATH/lib"
|
||||
export LD_LIBRARY_PATH="$BREW_ARM64_PATH/lib"
|
||||
|
||||
export VULKAN_SDK
|
||||
VULKAN_SDK="$BREW_ARM64_PATH/opt/molten-vk"
|
||||
ln -s "$VULKAN_SDK/lib/libMoltenVK.dylib" "$VULKAN_SDK/lib/libvulkan.dylib" || true
|
||||
export VK_ICD_FILENAMES="$VULKAN_SDK/share/vulkan/icd.d/MoltenVK_icd.json"
|
||||
|
||||
export LLVM_DIR
|
||||
LLVM_DIR="$BREW_ARM64_PATH/opt/llvm@$LLVM_COMPILER_VER"
|
||||
# exclude ffmpeg, LLVM, and sdl from submodule update
|
||||
# shellcheck disable=SC2046
|
||||
git submodule -q update --init --depth=1 --jobs=8 $(awk '/path/ && !/ffmpeg/ && !/llvm/ && !/SDL/ { print $3 }' .gitmodules)
|
||||
|
||||
# 3rdparty fixes
|
||||
sed -i '' "s/extern const double NSAppKitVersionNumber;/const double NSAppKitVersionNumber = 1343;/g" 3rdparty/hidapi/hidapi/mac/hid.c
|
||||
|
||||
rm -rf build
|
||||
mkdir build && cd build || exit 1
|
||||
|
||||
export MACOSX_DEPLOYMENT_TARGET=13.0
|
||||
|
||||
"$BREW_X64_PATH/bin/cmake" .. \
|
||||
-DUSE_SDL=ON \
|
||||
-DUSE_DISCORD_RPC=OFF \
|
||||
-DUSE_VULKAN=ON \
|
||||
-DUSE_ALSA=OFF \
|
||||
-DUSE_PULSE=OFF \
|
||||
-DUSE_AUDIOUNIT=ON \
|
||||
-DUSE_SYSTEM_FFMPEG=ON \
|
||||
-DLLVM_CCACHE_BUILD=OFF \
|
||||
-DLLVM_BUILD_RUNTIME=OFF \
|
||||
-DLLVM_BUILD_TOOLS=OFF \
|
||||
-DLLVM_INCLUDE_DOCS=OFF \
|
||||
-DLLVM_INCLUDE_EXAMPLES=OFF \
|
||||
-DLLVM_INCLUDE_TESTS=OFF \
|
||||
-DLLVM_INCLUDE_TOOLS=OFF \
|
||||
-DLLVM_INCLUDE_UTILS=OFF \
|
||||
-DLLVM_USE_PERF=OFF \
|
||||
-DLLVM_ENABLE_Z3_SOLVER=OFF \
|
||||
-DUSE_NATIVE_INSTRUCTIONS=OFF \
|
||||
-DUSE_SYSTEM_MVK=ON \
|
||||
-DUSE_SYSTEM_FAUDIO=OFF \
|
||||
-DUSE_SYSTEM_SDL=ON \
|
||||
$CMAKE_EXTRA_OPTS \
|
||||
-DLLVM_TARGET_ARCH=arm64 \
|
||||
-DCMAKE_OSX_ARCHITECTURES=arm64 \
|
||||
-DCMAKE_IGNORE_PATH="$BREW_X64_PATH/lib" \
|
||||
-DCMAKE_IGNORE_PREFIX_PATH=/usr/local/opt \
|
||||
-DCMAKE_SYSTEM_PROCESSOR=arm64 \
|
||||
-DCMAKE_TOOLCHAIN_FILE=buildfiles/cmake/TCDarwinARM64.cmake \
|
||||
-DCMAKE_CXX_FLAGS="-D__MAC_OS_X_VERSION_MIN_REQUIRED=130000" \
|
||||
-G Ninja
|
||||
|
||||
"$BREW_PATH/bin/ninja"; build_status=$?;
|
||||
|
||||
cd ..
|
||||
|
||||
{ [ "$CI_HAS_ARTIFACTS" = "true" ];
|
||||
} && SHOULD_DEPLOY="true" || SHOULD_DEPLOY="false"
|
||||
|
||||
if [ "$build_status" -eq 0 ] && [ "$SHOULD_DEPLOY" = "true" ]; then
|
||||
.ci/deploy-mac-arm64.sh
|
||||
fi
|
||||
117
app/src/main/cpp/rpcs3/.ci/build-mac.sh
Normal file
@@ -0,0 +1,117 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
export HOMEBREW_NO_AUTO_UPDATE=1
|
||||
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
|
||||
brew unlink certifi
|
||||
brew install -f --overwrite nasm ninja p7zip ccache pipenv #create-dmg
|
||||
|
||||
#/usr/sbin/softwareupdate --install-rosetta --agree-to-license
|
||||
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
arch -x86_64 /usr/local/bin/brew update
|
||||
arch -x86_64 /usr/local/bin/brew install -f --overwrite python || arch -x86_64 /usr/local/bin/brew link --overwrite python
|
||||
arch -x86_64 /usr/local/bin/brew uninstall -f --ignore-dependencies ffmpeg
|
||||
arch -x86_64 /usr/local/bin/brew install -f --build-from-source ffmpeg@5
|
||||
arch -x86_64 /usr/local/bin/brew reinstall -f --build-from-source gnutls freetype
|
||||
arch -x86_64 /usr/local/bin/brew install llvm@$LLVM_COMPILER_VER glew cmake sdl2 vulkan-headers coreutils
|
||||
arch -x86_64 /usr/local/bin/brew link -f llvm@$LLVM_COMPILER_VER ffmpeg@5
|
||||
|
||||
# moltenvk based on commit for 1.2.11 release
|
||||
wget https://raw.githubusercontent.com/Homebrew/homebrew-core/6bfc8950c696d1f952425e8af2a6248603dc0df9/Formula/m/molten-vk.rb
|
||||
arch -x86_64 /usr/local/bin/brew install -f --overwrite ./molten-vk.rb
|
||||
export CXX=clang++
|
||||
export CC=clang
|
||||
|
||||
export BREW_PATH;
|
||||
BREW_PATH="$(brew --prefix)"
|
||||
export BREW_X64_PATH;
|
||||
BREW_X64_PATH="$("/usr/local/bin/brew" --prefix)"
|
||||
export BREW_BIN="/usr/local/bin"
|
||||
export BREW_SBIN="/usr/local/sbin"
|
||||
export CMAKE_EXTRA_OPTS='-DLLVM_TARGETS_TO_BUILD=X86'
|
||||
|
||||
export WORKDIR;
|
||||
WORKDIR="$(pwd)"
|
||||
|
||||
# Get Qt
|
||||
if [ ! -d "/tmp/Qt/$QT_VER" ]; then
|
||||
mkdir -p "/tmp/Qt"
|
||||
git clone https://github.com/engnr/qt-downloader.git
|
||||
cd qt-downloader
|
||||
git checkout f52efee0f18668c6d6de2dec0234b8c4bc54c597
|
||||
cd "/tmp/Qt"
|
||||
"$BREW_X64_PATH/bin/pipenv" run pip3 install py7zr requests semantic_version lxml
|
||||
mkdir -p "$QT_VER/macos" ; ln -s "macos" "$QT_VER/clang_64"
|
||||
"$BREW_X64_PATH/bin/pipenv" run "$WORKDIR/qt-downloader/qt-downloader" macos desktop "$QT_VER" clang_64 --opensource --addons qtmultimedia qtimageformats
|
||||
fi
|
||||
|
||||
cd "$WORKDIR"
|
||||
ditto "/tmp/Qt/$QT_VER" "qt-downloader/$QT_VER"
|
||||
|
||||
export Qt6_DIR="$WORKDIR/qt-downloader/$QT_VER/clang_64/lib/cmake/Qt$QT_VER_MAIN"
|
||||
export SDL2_DIR="$BREW_X64_PATH/opt/sdl2/lib/cmake/SDL2"
|
||||
|
||||
export PATH="$BREW_X64_PATH/opt/llvm@$LLVM_COMPILER_VER/bin:$WORKDIR/qt-downloader/$QT_VER/clang_64/bin:$BREW_BIN:$BREW_SBIN:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Library/Apple/usr/bin:$PATH"
|
||||
export LDFLAGS="-L$BREW_X64_PATH/lib -Wl,-rpath,$BREW_X64_PATH/lib"
|
||||
export CPPFLAGS="-I$BREW_X64_PATH/include -msse -msse2 -mcx16 -no-pie -D__MAC_OS_X_VERSION_MIN_REQUIRED=130000"
|
||||
export CFLAGS="-D__MAC_OS_X_VERSION_MIN_REQUIRED=130000"
|
||||
export LIBRARY_PATH="$BREW_X64_PATH/lib"
|
||||
export LD_LIBRARY_PATH="$BREW_X64_PATH/lib"
|
||||
|
||||
export VULKAN_SDK
|
||||
VULKAN_SDK="$BREW_X64_PATH/opt/molten-vk"
|
||||
ln -s "$VULKAN_SDK/lib/libMoltenVK.dylib" "$VULKAN_SDK/lib/libvulkan.dylib"
|
||||
export VK_ICD_FILENAMES="$VULKAN_SDK/share/vulkan/icd.d/MoltenVK_icd.json"
|
||||
|
||||
export LLVM_DIR
|
||||
LLVM_DIR="BREW_X64_PATH/opt/llvm@$LLVM_COMPILER_VER"
|
||||
# exclude ffmpeg, LLVM, and sdl from submodule update
|
||||
# shellcheck disable=SC2046
|
||||
git submodule -q update --init --depth=1 --jobs=8 $(awk '/path/ && !/ffmpeg/ && !/llvm/ && !/SDL/ { print $3 }' .gitmodules)
|
||||
|
||||
# 3rdparty fixes
|
||||
sed -i '' "s/extern const double NSAppKitVersionNumber;/const double NSAppKitVersionNumber = 1343;/g" 3rdparty/hidapi/hidapi/mac/hid.c
|
||||
|
||||
mkdir build && cd build || exit 1
|
||||
|
||||
export MACOSX_DEPLOYMENT_TARGET=13.0
|
||||
|
||||
"$BREW_X64_PATH/bin/cmake" .. \
|
||||
-DUSE_SDL=ON \
|
||||
-DUSE_DISCORD_RPC=ON \
|
||||
-DUSE_VULKAN=ON \
|
||||
-DUSE_ALSA=OFF \
|
||||
-DUSE_PULSE=OFF \
|
||||
-DUSE_AUDIOUNIT=ON \
|
||||
-DUSE_SYSTEM_FFMPEG=ON \
|
||||
-DLLVM_CCACHE_BUILD=OFF \
|
||||
-DLLVM_BUILD_RUNTIME=OFF \
|
||||
-DLLVM_BUILD_TOOLS=OFF \
|
||||
-DLLVM_INCLUDE_DOCS=OFF \
|
||||
-DLLVM_INCLUDE_EXAMPLES=OFF \
|
||||
-DLLVM_INCLUDE_TESTS=OFF \
|
||||
-DLLVM_INCLUDE_TOOLS=OFF \
|
||||
-DLLVM_INCLUDE_UTILS=OFF \
|
||||
-DLLVM_USE_PERF=OFF \
|
||||
-DLLVM_ENABLE_Z3_SOLVER=OFF \
|
||||
-DUSE_NATIVE_INSTRUCTIONS=OFF \
|
||||
-DUSE_SYSTEM_MVK=ON \
|
||||
-DUSE_SYSTEM_FAUDIO=OFF \
|
||||
-DUSE_SYSTEM_SDL=ON \
|
||||
$CMAKE_EXTRA_OPTS \
|
||||
-DLLVM_TARGET_ARCH=X86_64 \
|
||||
-DCMAKE_OSX_ARCHITECTURES=x86_64 \
|
||||
-DCMAKE_IGNORE_PATH="$BREW_PATH/lib" \
|
||||
-DCMAKE_CXX_FLAGS="-D__MAC_OS_X_VERSION_MIN_REQUIRED=130000" \
|
||||
-G Ninja
|
||||
|
||||
"$BREW_PATH/bin/ninja"; build_status=$?;
|
||||
|
||||
cd ..
|
||||
|
||||
{ [ "$CI_HAS_ARTIFACTS" = "true" ];
|
||||
} && SHOULD_DEPLOY="true" || SHOULD_DEPLOY="false"
|
||||
|
||||
if [ "$build_status" -eq 0 ] && [ "$SHOULD_DEPLOY" = "true" ]; then
|
||||
.ci/deploy-mac.sh
|
||||
fi
|
||||
55
app/src/main/cpp/rpcs3/.ci/deploy-linux.sh
Normal file
@@ -0,0 +1,55 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
cd build || exit 1
|
||||
|
||||
CPU_ARCH="${1:-x86_64}"
|
||||
|
||||
if [ "$DEPLOY_APPIMAGE" = "true" ]; then
|
||||
DESTDIR=AppDir ninja install
|
||||
|
||||
curl -fsSLo /usr/bin/linuxdeploy "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-$CPU_ARCH.AppImage"
|
||||
chmod +x /usr/bin/linuxdeploy
|
||||
curl -fsSLo /usr/bin/linuxdeploy-plugin-qt "https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-$CPU_ARCH.AppImage"
|
||||
chmod +x /usr/bin/linuxdeploy-plugin-qt
|
||||
curl -fsSLo linuxdeploy-plugin-checkrt.sh https://github.com/darealshinji/linuxdeploy-plugin-checkrt/releases/download/continuous/linuxdeploy-plugin-checkrt.sh
|
||||
chmod +x ./linuxdeploy-plugin-checkrt.sh
|
||||
|
||||
export EXTRA_PLATFORM_PLUGINS="libqwayland-egl.so;libqwayland-generic.so"
|
||||
export EXTRA_QT_PLUGINS="svg;wayland-decoration-client;wayland-graphics-integration-client;wayland-shell-integration;waylandcompositor"
|
||||
|
||||
APPIMAGE_EXTRACT_AND_RUN=1 linuxdeploy --appdir AppDir --plugin qt --plugin checkrt
|
||||
|
||||
# Remove libwayland-client because it has platform-dependent exports and breaks other OSes
|
||||
rm -f ./AppDir/usr/lib/libwayland-client.so*
|
||||
|
||||
# Remove libvulkan because it causes issues with gamescope
|
||||
rm -f ./AppDir/usr/lib/libvulkan.so*
|
||||
|
||||
# Remove git directory containing local commit history file
|
||||
rm -rf ./AppDir/usr/share/rpcs3/git
|
||||
|
||||
linuxdeploy --appimage-extract
|
||||
./squashfs-root/plugins/linuxdeploy-plugin-appimage/usr/bin/appimagetool AppDir -g
|
||||
|
||||
APPIMAGE_SUFFIX="linux_${CPU_ARCH}"
|
||||
if [ "$CPU_ARCH" = "x86_64" ]; then
|
||||
# Preserve back compat. Previous versions never included the full arch.
|
||||
APPIMAGE_SUFFIX="linux64"
|
||||
fi
|
||||
|
||||
COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ../rpcs3/rpcs3_version.cpp)
|
||||
COMM_COUNT="$(git rev-list --count HEAD)"
|
||||
COMM_HASH="$(git rev-parse --short=8 HEAD)"
|
||||
RPCS3_APPIMAGE="rpcs3-v${COMM_TAG}-${COMM_COUNT}-${COMM_HASH}_${APPIMAGE_SUFFIX}.AppImage"
|
||||
|
||||
mv ./RPCS3*.AppImage "$RPCS3_APPIMAGE"
|
||||
|
||||
# If we're building using a CI, let's copy over the AppImage artifact
|
||||
if [ -n "$BUILD_ARTIFACTSTAGINGDIRECTORY" ]; then
|
||||
cp "$RPCS3_APPIMAGE" "$ARTDIR"
|
||||
fi
|
||||
|
||||
FILESIZE=$(stat -c %s ./rpcs3*.AppImage)
|
||||
SHA256SUM=$(sha256sum ./rpcs3*.AppImage | awk '{ print $1 }')
|
||||
echo "${SHA256SUM};${FILESIZE}B" > "$RELEASE_MESSAGE"
|
||||
fi
|
||||
76
app/src/main/cpp/rpcs3/.ci/deploy-mac-arm64.sh
Normal file
@@ -0,0 +1,76 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
cd build || exit 1
|
||||
|
||||
# Gather explicit version number and number of commits
|
||||
COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ../rpcs3/rpcs3_version.cpp)
|
||||
COMM_COUNT=$(git rev-list --count HEAD)
|
||||
COMM_HASH=$(git rev-parse --short=8 HEAD)
|
||||
|
||||
AVVER="${COMM_TAG}-${COMM_COUNT}"
|
||||
|
||||
# AVVER is used for GitHub releases, it is the version number.
|
||||
echo "AVVER=$AVVER" >> ../.ci/ci-vars.env
|
||||
|
||||
cd bin
|
||||
mkdir "rpcs3.app/Contents/lib/" || true
|
||||
|
||||
cp "$(realpath /opt/homebrew1/opt/llvm@$LLVM_COMPILER_VER/lib/c++/libc++abi.1.0.dylib)" "rpcs3.app/Contents/Frameworks/libc++abi.1.dylib"
|
||||
cp "$(realpath /opt/homebrew1/lib/libsharpyuv.0.dylib)" "rpcs3.app/Contents/lib/libsharpyuv.0.dylib"
|
||||
cp "$(realpath /opt/homebrew1/lib/libintl.8.dylib)" "rpcs3.app/Contents/lib/libintl.8.dylib"
|
||||
|
||||
rm -rf "rpcs3.app/Contents/Frameworks/QtPdf.framework" \
|
||||
"rpcs3.app/Contents/Frameworks/QtQml.framework" \
|
||||
"rpcs3.app/Contents/Frameworks/QtQmlModels.framework" \
|
||||
"rpcs3.app/Contents/Frameworks/QtQuick.framework" \
|
||||
"rpcs3.app/Contents/Frameworks/QtVirtualKeyboard.framework" \
|
||||
"rpcs3.app/Contents/Plugins/platforminputcontexts" \
|
||||
"rpcs3.app/Contents/Plugins/virtualkeyboard" \
|
||||
"rpcs3.app/Contents/Resources/git"
|
||||
|
||||
../../.ci/optimize-mac.sh rpcs3.app
|
||||
|
||||
# Hack
|
||||
install_name_tool \
|
||||
-delete_rpath /opt/homebrew1/lib \
|
||||
-delete_rpath /opt/homebrew/lib \
|
||||
-delete_rpath /opt/homebrew1/opt/llvm@$LLVM_COMPILER_VER/lib \
|
||||
-delete_rpath /usr/local/lib RPCS3.app/Contents/MacOS/rpcs3
|
||||
#-delete_rpath /opt/homebrew1/Cellar/sdl2/2.30.7/lib
|
||||
|
||||
# Need to do this rename hack due to case insensitive filesystem
|
||||
mv rpcs3.app RPCS3_.app
|
||||
mv RPCS3_.app RPCS3.app
|
||||
|
||||
# NOTE: "--deep" is deprecated
|
||||
codesign --deep -fs - RPCS3.app
|
||||
|
||||
echo "[InternetShortcut]" > Quickstart.url
|
||||
echo "URL=https://rpcs3.net/quickstart" >> Quickstart.url
|
||||
echo "IconIndex=0" >> Quickstart.url
|
||||
|
||||
#DMG_FILEPATH="$BUILD_ARTIFACTSTAGINGDIRECTORY/rpcs3-v${COMM_TAG}-${COMM_COUNT}-${COMM_HASH}_macos_arm64.dmg"
|
||||
#"$BREW_X64_PATH/bin/create-dmg" --volname RPCS3 \
|
||||
#--window-size 800 400 \
|
||||
#--icon-size 100 \
|
||||
#--icon rpcs3.app 200 190 \
|
||||
#--add-file Quickstart.url Quickstart.url 400 20 \
|
||||
#--hide-extension rpcs3.app \
|
||||
#--hide-extension Quickstart.url \
|
||||
#--app-drop-link 600 185 \
|
||||
#--skip-jenkins \
|
||||
#--format ULMO \
|
||||
#"$DMG_FILEPATH" \
|
||||
#RPCS3.app
|
||||
#FILESIZE=$(stat -f %z "$DMG_FILEPATH")
|
||||
#SHA256SUM=$(shasum -a 256 "$DMG_FILEPATH" | awk '{ print $1 }')
|
||||
|
||||
ARCHIVE_FILEPATH="$BUILD_ARTIFACTSTAGINGDIRECTORY/rpcs3-v${COMM_TAG}-${COMM_COUNT}-${COMM_HASH}_macos_arm64.7z"
|
||||
"$BREW_X64_PATH/bin/7z" a -mx9 "$ARCHIVE_FILEPATH" RPCS3.app Quickstart.url
|
||||
FILESIZE=$(stat -f %z "$ARCHIVE_FILEPATH")
|
||||
SHA256SUM=$(shasum -a 256 "$ARCHIVE_FILEPATH" | awk '{ print $1 }')
|
||||
|
||||
cd ..
|
||||
echo "${SHA256SUM};${FILESIZE}B" > "$RELEASE_MESSAGE"
|
||||
cd bin
|
||||
74
app/src/main/cpp/rpcs3/.ci/deploy-mac.sh
Normal file
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
cd build || exit 1
|
||||
|
||||
# Gather explicit version number and number of commits
|
||||
COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ../rpcs3/rpcs3_version.cpp)
|
||||
COMM_COUNT=$(git rev-list --count HEAD)
|
||||
COMM_HASH=$(git rev-parse --short=8 HEAD)
|
||||
|
||||
AVVER="${COMM_TAG}-${COMM_COUNT}"
|
||||
|
||||
# AVVER is used for GitHub releases, it is the version number.
|
||||
echo "AVVER=$AVVER" >> ../.ci/ci-vars.env
|
||||
|
||||
cd bin
|
||||
mkdir "rpcs3.app/Contents/lib/"
|
||||
|
||||
cp "/usr/local/opt/llvm@$LLVM_COMPILER_VER/lib/c++/libc++abi.1.0.dylib" "rpcs3.app/Contents/lib/libc++abi.1.dylib"
|
||||
cp "$(realpath /usr/local/lib/libsharpyuv.0.dylib)" "rpcs3.app/Contents/lib/libsharpyuv.0.dylib"
|
||||
cp "$(realpath /usr/local/lib/libintl.8.dylib)" "rpcs3.app/Contents/lib/libintl.8.dylib"
|
||||
|
||||
rm -rf "rpcs3.app/Contents/Frameworks/QtPdf.framework" \
|
||||
"rpcs3.app/Contents/Frameworks/QtQml.framework" \
|
||||
"rpcs3.app/Contents/Frameworks/QtQmlModels.framework" \
|
||||
"rpcs3.app/Contents/Frameworks/QtQuick.framework" \
|
||||
"rpcs3.app/Contents/Frameworks/QtVirtualKeyboard.framework" \
|
||||
"rpcs3.app/Contents/Plugins/platforminputcontexts" \
|
||||
"rpcs3.app/Contents/Plugins/virtualkeyboard" \
|
||||
"rpcs3.app/Contents/Resources/git"
|
||||
|
||||
../../.ci/optimize-mac.sh rpcs3.app
|
||||
|
||||
# Need to do this rename hack due to case insensitive filesystem
|
||||
mv rpcs3.app RPCS3_.app
|
||||
mv RPCS3_.app RPCS3.app
|
||||
|
||||
# Hack
|
||||
install_name_tool \
|
||||
-delete_rpath /usr/local/lib \
|
||||
-delete_rpath /usr/local/opt/llvm@$LLVM_COMPILER_VER/lib RPCS3.app/Contents/MacOS/rpcs3
|
||||
#-delete_rpath /usr/local/Cellar/sdl2/2.30.3/lib
|
||||
|
||||
# NOTE: "--deep" is deprecated
|
||||
codesign --deep -fs - RPCS3.app
|
||||
|
||||
echo "[InternetShortcut]" > Quickstart.url
|
||||
echo "URL=https://rpcs3.net/quickstart" >> Quickstart.url
|
||||
echo "IconIndex=0" >> Quickstart.url
|
||||
|
||||
#DMG_FILEPATH="$BUILD_ARTIFACTSTAGINGDIRECTORY/rpcs3-v${COMM_TAG}-${COMM_COUNT}-${COMM_HASH}_macos.dmg"
|
||||
#"$BREW_X64_PATH/bin/create-dmg" --volname RPCS3 \
|
||||
#--window-size 800 400 \
|
||||
#--icon-size 100 \
|
||||
#--icon rpcs3.app 200 190 \
|
||||
#--add-file Quickstart.url Quickstart.url 400 20 \
|
||||
#--hide-extension rpcs3.app \
|
||||
#--hide-extension Quickstart.url \
|
||||
#--app-drop-link 600 185 \
|
||||
#--skip-jenkins \
|
||||
#--format ULMO \
|
||||
#"$DMG_FILEPATH" \
|
||||
#RPCS3.app
|
||||
#FILESIZE=$(stat -f %z "$DMG_FILEPATH")
|
||||
#SHA256SUM=$(shasum -a 256 "$DMG_FILEPATH" | awk '{ print $1 }')
|
||||
|
||||
ARCHIVE_FILEPATH="$BUILD_ARTIFACTSTAGINGDIRECTORY/rpcs3-v${COMM_TAG}-${COMM_COUNT}-${COMM_HASH}_macos.7z"
|
||||
"$BREW_X64_PATH/bin/7z" a -mx9 "$ARCHIVE_FILEPATH" RPCS3.app Quickstart.url
|
||||
FILESIZE=$(stat -f %z "$ARCHIVE_FILEPATH")
|
||||
SHA256SUM=$(shasum -a 256 "$ARCHIVE_FILEPATH" | awk '{ print $1 }')
|
||||
|
||||
cd ..
|
||||
echo "${SHA256SUM};${FILESIZE}B" > "$RELEASE_MESSAGE"
|
||||
cd bin
|
||||
29
app/src/main/cpp/rpcs3/.ci/deploy-windows.sh
Normal file
@@ -0,0 +1,29 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
# BUILD_blablabla is Azure specific, so we wrap it for portability
|
||||
ARTIFACT_DIR="$BUILD_ARTIFACTSTAGINGDIRECTORY"
|
||||
|
||||
# Remove unecessary files
|
||||
rm -f ./bin/rpcs3.exp ./bin/rpcs3.lib ./bin/rpcs3.pdb ./bin/vc_redist.x64.exe
|
||||
rm -rf ./bin/git
|
||||
|
||||
# Prepare compatibility and SDL database for packaging
|
||||
mkdir ./bin/config
|
||||
mkdir ./bin/config/input_configs
|
||||
curl -fsSL 'https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt' 1> ./bin/config/input_configs/gamecontrollerdb.txt
|
||||
curl -fsSL 'https://rpcs3.net/compatibility?api=v1&export' | iconv -t UTF-8 1> ./bin/GuiConfigs/compat_database.dat
|
||||
|
||||
# Download SSL certificate (not needed with CURLSSLOPT_NATIVE_CA)
|
||||
#curl -fsSL 'https://curl.haxx.se/ca/cacert.pem' 1> ./bin/cacert.pem
|
||||
|
||||
# Package artifacts
|
||||
7z a -m0=LZMA2 -mx9 "$BUILD" ./bin/*
|
||||
|
||||
# Generate sha256 hashes
|
||||
# Write to file for GitHub releases
|
||||
sha256sum "$BUILD" | awk '{ print $1 }' | tee "$BUILD.sha256"
|
||||
echo "$(cat "$BUILD.sha256");$(stat -c %s "$BUILD")B" > GitHubReleaseMessage.txt
|
||||
|
||||
# Move files to publishing directory
|
||||
cp -- "$BUILD" "$ARTIFACT_DIR"
|
||||
cp -- "$BUILD.sha256" "$ARTIFACT_DIR"
|
||||
15
app/src/main/cpp/rpcs3/.ci/docker.env
Normal file
@@ -0,0 +1,15 @@
|
||||
# Variables set by Azure Pipelines
|
||||
CI_HAS_ARTIFACTS
|
||||
BUILD_REASON
|
||||
BUILD_SOURCEVERSION
|
||||
BUILD_ARTIFACTSTAGINGDIRECTORY
|
||||
BUILD_REPOSITORY_NAME
|
||||
BUILD_SOURCEBRANCHNAME
|
||||
APPDIR
|
||||
ARTDIR
|
||||
RELEASE_MESSAGE
|
||||
# Variables for build matrix
|
||||
COMPILER
|
||||
DEPLOY_APPIMAGE
|
||||
# Private variables
|
||||
GITHUB_TOKEN
|
||||
13
app/src/main/cpp/rpcs3/.ci/export-azure-vars.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
# Export variables for later stages of the Azure pipeline
|
||||
# Values done in this manner will appear as environment variables
|
||||
# in later stages.
|
||||
|
||||
# From pure-sh-bible
|
||||
# Setting 'IFS' tells 'read' where to split the string.
|
||||
while IFS='=' read -r key val; do
|
||||
# Skip over lines containing comments.
|
||||
[ "${key##\#*}" ] || continue
|
||||
echo "##vso[task.setvariable variable=$key]$val"
|
||||
done < ".ci/ci-vars.env"
|
||||
13
app/src/main/cpp/rpcs3/.ci/export-cirrus-vars.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
# Export variables for later stages of the Cirrus pipeline
|
||||
# Values done in this manner will appear as environment variables
|
||||
# in later stages.
|
||||
|
||||
# From pure-sh-bible
|
||||
# Setting 'IFS' tells 'read' where to split the string.
|
||||
while IFS='=' read -r key val; do
|
||||
# Skip over lines containing comments.
|
||||
[ "${key##\#*}" ] || continue
|
||||
export "$key"="$val"
|
||||
done < ".ci/ci-vars.env"
|
||||
4
app/src/main/cpp/rpcs3/.ci/get_keys-windows.sh
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
curl -fLo "./llvm.lock" "https://github.com/RPCS3/llvm-mirror/releases/download/custom-build-win-16.0.1/llvmlibs_mt.7z.sha256"
|
||||
curl -fLo "./glslang.lock" "https://github.com/RPCS3/glslang/releases/download/custom-build-win/glslanglibs_mt.7z.sha256"
|
||||
42
app/src/main/cpp/rpcs3/.ci/github-upload.sh
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
ARTIFACT_DIR="$BUILD_ARTIFACTSTAGINGDIRECTORY"
|
||||
generate_post_data()
|
||||
{
|
||||
body=$(cat GitHubReleaseMessage.txt)
|
||||
cat <<EOF
|
||||
{
|
||||
"tag_name": "build-${BUILD_SOURCEVERSION}",
|
||||
"target_commitish": "${UPLOAD_COMMIT_HASH}",
|
||||
"name": "${AVVER}",
|
||||
"body": "$body",
|
||||
"draft": false,
|
||||
"prerelease": false
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
curl -fsS \
|
||||
-H "Authorization: token ${RPCS3_TOKEN}" \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
--data "$(generate_post_data)" "https://api.github.com/repos/$UPLOAD_REPO_FULL_NAME/releases" >> release.json
|
||||
|
||||
cat release.json
|
||||
id=$(grep '"id"' release.json | cut -d ':' -f2 | head -n1 | awk '{$1=$1;print}')
|
||||
id=${id%?}
|
||||
echo "${id:?}"
|
||||
|
||||
upload_file()
|
||||
{
|
||||
curl -fsS \
|
||||
-H "Authorization: token ${RPCS3_TOKEN}" \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
-H "Content-Type: application/octet-stream" \
|
||||
--data-binary @"$2"/"$3" \
|
||||
"https://uploads.github.com/repos/$UPLOAD_REPO_FULL_NAME/releases/$1/assets?name=$3"
|
||||
}
|
||||
|
||||
for file in "$ARTIFACT_DIR"/*; do
|
||||
name=$(basename "$file")
|
||||
upload_file "$id" "$ARTIFACT_DIR" "$name"
|
||||
done
|
||||
18
app/src/main/cpp/rpcs3/.ci/install-freebsd.sh
Normal file
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env -S su -m root -ex
|
||||
# NOTE: this script is run under root permissions
|
||||
# shellcheck shell=sh disable=SC2096
|
||||
|
||||
# RPCS3 often needs recent Qt and Vulkan-Headers
|
||||
sed -i '' 's/quarterly/latest/' /etc/pkg/FreeBSD.conf
|
||||
|
||||
export ASSUME_ALWAYS_YES=true
|
||||
pkg info # debug
|
||||
|
||||
# Prefer newer Clang than in base system (see also .ci/build-freebsd.sh)
|
||||
pkg install llvm16
|
||||
|
||||
# Mandatory dependencies (qt6-base is pulled via qt6-multimedia)
|
||||
pkg install git ccache cmake ninja qt6-multimedia qt6-svg glew openal-soft ffmpeg
|
||||
|
||||
# Optional dependencies (libevdev is pulled by qt6-base)
|
||||
pkg install pkgconf alsa-lib pulseaudio sdl2 evdev-proto vulkan-headers vulkan-loader
|
||||
21
app/src/main/cpp/rpcs3/.ci/optimize-mac.sh
Normal file
@@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
|
||||
file_path=$(find "$1/Contents/MacOS" -type f -print0 | head -n 1)
|
||||
|
||||
if [ -z "$file_path" ]; then
|
||||
echo "No executable file found in $1/Contents/MacOS" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
target_architecture="$(lipo "$file_path" -archs)"
|
||||
|
||||
if [ -z "$target_architecture" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC3045
|
||||
find "$1" -type f -print0 | while IFS= read -r -d '' file; do
|
||||
echo Thinning "$file" -> "$target_architecture"
|
||||
lipo "$file" -thin "$target_architecture" -output "$file" || true
|
||||
done
|
||||
118
app/src/main/cpp/rpcs3/.ci/setup-windows.sh
Normal file
@@ -0,0 +1,118 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
# These are Azure specific, so we wrap them for portability
|
||||
REPO_NAME="$BUILD_REPOSITORY_NAME"
|
||||
REPO_BRANCH="$SYSTEM_PULLREQUEST_SOURCEBRANCH"
|
||||
PR_NUMBER="$SYSTEM_PULLREQUEST_PULLREQUESTID"
|
||||
|
||||
# Resource/dependency URLs
|
||||
# Qt mirrors can be volatile and slow, so we list 2
|
||||
#QT_HOST="http://mirrors.ocf.berkeley.edu/qt/"
|
||||
QT_HOST="http://qt.mirror.constant.com/"
|
||||
QT_URL_VER=$(echo "$QT_VER" | sed "s/\.//g")
|
||||
QT_VER_MSVC_UP=$(echo "${QT_VER_MSVC}" | tr '[:lower:]' '[:upper:]')
|
||||
QT_PREFIX="online/qtsdkrepository/windows_x86/desktop/qt${QT_VER_MAIN}_${QT_URL_VER}/qt.qt${QT_VER_MAIN}.${QT_URL_VER}."
|
||||
QT_PREFIX_2="win64_${QT_VER_MSVC}_64/${QT_VER}-0-${QT_DATE}"
|
||||
QT_SUFFIX="-Windows-Windows_10_22H2-${QT_VER_MSVC_UP}-Windows-Windows_10_22H2-X86_64.7z"
|
||||
QT_BASE_URL="${QT_HOST}${QT_PREFIX}${QT_PREFIX_2}qtbase${QT_SUFFIX}"
|
||||
QT_DECL_URL="${QT_HOST}${QT_PREFIX}${QT_PREFIX_2}qtdeclarative${QT_SUFFIX}"
|
||||
QT_TOOL_URL="${QT_HOST}${QT_PREFIX}${QT_PREFIX_2}qttools${QT_SUFFIX}"
|
||||
QT_MM_URL="${QT_HOST}${QT_PREFIX}addons.qtmultimedia.${QT_PREFIX_2}qtmultimedia${QT_SUFFIX}"
|
||||
QT_SVG_URL="${QT_HOST}${QT_PREFIX}${QT_PREFIX_2}qtsvg${QT_SUFFIX}"
|
||||
LLVMLIBS_URL='https://github.com/RPCS3/llvm-mirror/releases/download/custom-build-win-16.0.1/llvmlibs_mt.7z'
|
||||
GLSLANG_URL='https://github.com/RPCS3/glslang/releases/latest/download/glslanglibs_mt.7z'
|
||||
VULKAN_SDK_URL="https://www.dropbox.com/scl/fi/sjjh0fc4ld281pjbl2xzu/VulkanSDK-1.3.268.0-Installer.exe?rlkey=f6wzc0lvms5vwkt2z3qabfv9d&dl=1"
|
||||
|
||||
DEP_URLS=" \
|
||||
$QT_BASE_URL \
|
||||
$QT_DECL_URL \
|
||||
$QT_TOOL_URL \
|
||||
$QT_MM_URL \
|
||||
$QT_SVG_URL \
|
||||
$LLVMLIBS_URL \
|
||||
$GLSLANG_URL \
|
||||
$VULKAN_SDK_URL"
|
||||
|
||||
# Azure pipelines doesn't make a cache dir if it doesn't exist, so we do it manually
|
||||
[ -d "$CACHE_DIR" ] || mkdir "$CACHE_DIR"
|
||||
|
||||
# Pull all the submodules except llvm, since it is built separately and we just download that build
|
||||
# Note: Tried to use git submodule status, but it takes over 20 seconds
|
||||
# shellcheck disable=SC2046
|
||||
git submodule -q update --init --depth=1 --jobs=8 $(awk '/path/ && !/FAudio/ && !/llvm/ { print $3 }' .gitmodules)
|
||||
|
||||
# Git bash doesn't have rev, so here it is
|
||||
rev()
|
||||
{
|
||||
echo "$1" | awk '{ for(i = length($0); i != 0; --i) { a = a substr($0, i, 1); } } END { print a }'
|
||||
}
|
||||
|
||||
# Usage: download_and_verify url checksum algo file
|
||||
# Check to see if a file is already cached, and the checksum matches. If not, download it.
|
||||
# Tries up to 3 times
|
||||
download_and_verify()
|
||||
{
|
||||
url="$1"
|
||||
correctChecksum="$2"
|
||||
algo="$3"
|
||||
fileName="$4"
|
||||
|
||||
for _ in 1 2 3; do
|
||||
[ -e "$CACHE_DIR/$fileName" ] || curl -fLo "$CACHE_DIR/$fileName" "$url"
|
||||
fileChecksum=$("${algo}sum" "$CACHE_DIR/$fileName" | awk '{ print $1 }')
|
||||
[ "$fileChecksum" = "$correctChecksum" ] && return 0
|
||||
rm "$CACHE_DIR/$fileName"
|
||||
done
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Some dependencies install here
|
||||
[ -d "./lib" ] || mkdir "./lib"
|
||||
|
||||
for url in $DEP_URLS; do
|
||||
# Get the filename from the URL and remove query strings (?arg=something).
|
||||
fileName="$(rev "$(rev "$url" | cut -d'/' -f1)" | cut -d'?' -f1)"
|
||||
[ -z "$fileName" ] && echo "Unable to parse url: $url" && exit 1
|
||||
|
||||
# shellcheck disable=SC1003
|
||||
case "$url" in
|
||||
*qt*) checksum=$(curl -fL "${url}.sha1"); algo="sha1"; outDir='C:\Qt\' ;;
|
||||
*llvm*) checksum=$(curl -fL "${url}.sha256"); algo="sha256"; outDir="./3rdparty/llvm" ;;
|
||||
*glslang*) checksum=$(curl -fL "${url}.sha256"); algo="sha256"; outDir="./lib/Release-x64" ;;
|
||||
*Vulkan*)
|
||||
# Vulkan setup needs to be run in batch environment
|
||||
# Need to subshell this or else it doesn't wait
|
||||
download_and_verify "$url" "$VULKAN_SDK_SHA" "sha256" "$fileName"
|
||||
cp "$CACHE_DIR/$fileName" .
|
||||
_=$(echo "$fileName --accept-licenses --default-answer --confirm-command install" | cmd)
|
||||
continue
|
||||
;;
|
||||
*) echo "Unknown url resource: $url"; exit 1 ;;
|
||||
esac
|
||||
|
||||
download_and_verify "$url" "$checksum" "$algo" "$fileName"
|
||||
7z x -y "$CACHE_DIR/$fileName" -aos -o"$outDir"
|
||||
done
|
||||
|
||||
# Gather explicit version number and number of commits
|
||||
COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ./rpcs3/rpcs3_version.cpp)
|
||||
COMM_COUNT=$(git rev-list --count HEAD)
|
||||
COMM_HASH=$(git rev-parse --short=8 HEAD)
|
||||
|
||||
# Format the above into filenames
|
||||
if [ -n "$PR_NUMBER" ]; then
|
||||
AVVER="${COMM_TAG}-${COMM_HASH}"
|
||||
BUILD="rpcs3-v${AVVER}_win64.7z"
|
||||
else
|
||||
AVVER="${COMM_TAG}-${COMM_COUNT}"
|
||||
BUILD="rpcs3-v${AVVER}-${COMM_HASH}_win64.7z"
|
||||
fi
|
||||
|
||||
# BRANCH is used for experimental build warnings for pr builds, used in main_window.cpp.
|
||||
# BUILD is the name of the release artifact
|
||||
# AVVER is used for GitHub releases, it is the version number.
|
||||
BRANCH="${REPO_NAME}/${REPO_BRANCH}"
|
||||
echo "BRANCH=$BRANCH" > .ci/ci-vars.env
|
||||
echo "BUILD=$BUILD" >> .ci/ci-vars.env
|
||||
echo "AVVER=$AVVER" >> .ci/ci-vars.env
|
||||
151
app/src/main/cpp/rpcs3/.cirrus.yml
Normal file
@@ -0,0 +1,151 @@
|
||||
env:
|
||||
CIRRUS_CLONE_DEPTH: 0 # Unshallow clone to obtain proper GIT_VERSION
|
||||
BUILD_REPOSITORY_NAME: $CIRRUS_REPO_FULL_NAME
|
||||
SYSTEM_PULLREQUEST_SOURCEBRANCH: $CIRRUS_BRANCH
|
||||
SYSTEM_PULLREQUEST_PULLREQUESTID: $CIRRUS_PR
|
||||
BUILD_SOURCEVERSION: $CIRRUS_CHANGE_IN_REPO
|
||||
BUILD_SOURCEBRANCHNAME: $CIRRUS_BRANCH
|
||||
RPCS3_TOKEN: ENCRYPTED[100ebb8e3552bf2021d0ef55dccda3e58d27be5b6cab0b0b92843ef490195d3c4edaefa087e4a3b425caa6392300b9b1]
|
||||
QT_VER_MAIN: '6'
|
||||
QT_VER: '6.7.3'
|
||||
|
||||
# windows_task:
|
||||
# matrix:
|
||||
# - name: Cirrus Windows
|
||||
# windows_container:
|
||||
# image: cirrusci/windowsservercore:visualstudio2019
|
||||
# cpu: 8
|
||||
# memory: 16G
|
||||
# env:
|
||||
# CIRRUS_SHELL: "bash"
|
||||
# COMPILER: msvc
|
||||
# BUILD_ARTIFACTSTAGINGDIRECTORY: ${CIRRUS_WORKING_DIR}\artifacts\
|
||||
# QT_VER_MSVC: 'msvc2019'
|
||||
# QT_DATE: '202409200836'
|
||||
# QTDIR: C:\Qt\${QT_VER}\${QT_VER_MSVC}_64
|
||||
# VULKAN_VER: '1.3.268.0'
|
||||
# VULKAN_SDK_SHA: '8459ef49bd06b697115ddd3d97c9aec729e849cd775f5be70897718a9b3b9db5'
|
||||
# VULKAN_SDK: C:\VulkanSDK\${VULKAN_VER}
|
||||
# CACHE_DIR: "./cache"
|
||||
# UPLOAD_COMMIT_HASH: 7d09e3be30805911226241afbb14f8cdc2eb054e
|
||||
# UPLOAD_REPO_FULL_NAME: "rpcs3/rpcs3-binaries-win"
|
||||
# deps_cache:
|
||||
# folder: "./cache"
|
||||
# #obj_cache:
|
||||
# # folder: "./tmp"
|
||||
# #obj2_cache:
|
||||
# # folder: "./rpcs3/x64"
|
||||
# setup_script:
|
||||
# - './.ci/get_keys-windows.sh'
|
||||
# - './.ci/setup-windows.sh'
|
||||
# rpcs3_script:
|
||||
# - export PATH=${PATH}:"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin"
|
||||
# - msbuild.exe rpcs3.sln //p:Configuration=Release //m
|
||||
# deploy_script:
|
||||
# - mkdir artifacts
|
||||
# - source './.ci/export-cirrus-vars.sh'
|
||||
# - './.ci/deploy-windows.sh'
|
||||
# artifacts:
|
||||
# name: Artifact
|
||||
# path: "*.7z*"
|
||||
# push_script: |
|
||||
# if [ "$CIRRUS_REPO_OWNER" = "RPCS3" ] && [ -z "$CIRRUS_PR" ] && [ "$CIRRUS_BRANCH" = "master" ]; then
|
||||
# source './.ci/export-cirrus-vars.sh'
|
||||
# './.ci/github-upload.sh'
|
||||
# fi;
|
||||
|
||||
# linux_task:
|
||||
# container:
|
||||
# image: rpcs3/rpcs3-ci-focal:1.7
|
||||
# cpu: 4
|
||||
# memory: 16G
|
||||
# env:
|
||||
# BUILD_ARTIFACTSTAGINGDIRECTORY: ${CIRRUS_WORKING_DIR}/artifacts
|
||||
# ARTDIR: ${CIRRUS_WORKING_DIR}/artifacts/
|
||||
# CCACHE_DIR: "/tmp/ccache_dir"
|
||||
# CCACHE_MAXSIZE: 300M
|
||||
# CI_HAS_ARTIFACTS: true
|
||||
# UPLOAD_COMMIT_HASH: d812f1254a1157c80fd402f94446310560f54e5f
|
||||
# UPLOAD_REPO_FULL_NAME: "rpcs3/rpcs3-binaries-linux"
|
||||
# DEPLOY_APPIMAGE: true
|
||||
# APPDIR: "./appdir"
|
||||
# RELEASE_MESSAGE: "../GitHubReleaseMessage.txt"
|
||||
# ccache_cache:
|
||||
# folder: "/tmp/ccache_dir"
|
||||
# matrix:
|
||||
# - name: Cirrus Linux GCC
|
||||
# env:
|
||||
# COMPILER: gcc
|
||||
# gcc_script:
|
||||
# - mkdir artifacts
|
||||
# - ".ci/build-linux.sh"
|
||||
# - name: Cirrus Linux Clang
|
||||
# env:
|
||||
# COMPILER: clang
|
||||
# clang_script:
|
||||
# - mkdir artifacts
|
||||
# - ".ci/build-linux.sh"
|
||||
# artifacts:
|
||||
# name: Artifact
|
||||
# path: "artifacts/*"
|
||||
# push_script: |
|
||||
# if [ "$CIRRUS_REPO_OWNER" = "RPCS3" ] && [ -z "$CIRRUS_PR" ] && [ "$CIRRUS_BRANCH" = "master" ] && [ "$COMPILER" = "gcc" ]; then
|
||||
# COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ./rpcs3/rpcs3_version.cpp)
|
||||
# COMM_COUNT=$(git rev-list --count HEAD)
|
||||
# COMM_HASH=$(git rev-parse --short=8 HEAD)
|
||||
|
||||
# export AVVER="${COMM_TAG}-${COMM_COUNT}"
|
||||
|
||||
# .ci/github-upload.sh
|
||||
# fi;
|
||||
|
||||
freebsd_task:
|
||||
matrix:
|
||||
- name: Cirrus FreeBSD
|
||||
freebsd_instance:
|
||||
image_family: freebsd-13-3
|
||||
cpu: 8
|
||||
memory: 8G
|
||||
env:
|
||||
CCACHE_MAXSIZE: 300M # 3x clean build, rounded
|
||||
CCACHE_DIR: /tmp/ccache_dir
|
||||
ccache_cache:
|
||||
folder: /tmp/ccache_dir
|
||||
install_script: "sh -ex ./.ci/install-freebsd.sh"
|
||||
script: "./.ci/build-freebsd.sh"
|
||||
|
||||
linux_aarch64_task:
|
||||
env:
|
||||
BUILD_ARTIFACTSTAGINGDIRECTORY: ${CIRRUS_WORKING_DIR}/artifacts
|
||||
ARTDIR: ${CIRRUS_WORKING_DIR}/artifacts/
|
||||
CCACHE_DIR: "/tmp/ccache_dir"
|
||||
CCACHE_MAXSIZE: 300M
|
||||
CI_HAS_ARTIFACTS: true
|
||||
UPLOAD_COMMIT_HASH: a1d35836e8d45bfc6f63c26f0a3e5d46ef622fe1
|
||||
UPLOAD_REPO_FULL_NAME: "rpcs3/rpcs3-binaries-linux-arm64"
|
||||
DEPLOY_APPIMAGE: true
|
||||
APPDIR: "./appdir"
|
||||
RELEASE_MESSAGE: "../GitHubReleaseMessage.txt"
|
||||
COMPILER: clang
|
||||
ccache_cache:
|
||||
folder: "/tmp/ccache_dir"
|
||||
matrix:
|
||||
- name: Cirrus Linux AArch64 Clang
|
||||
arm_container:
|
||||
image: 'docker.io/rpcs3/rpcs3-ci-focal-aarch64:1.0'
|
||||
cpu: 8
|
||||
memory: 8G
|
||||
clang_script:
|
||||
- mkdir artifacts
|
||||
- "sh -ex ./.ci/build-linux-aarch64.sh"
|
||||
artifacts:
|
||||
name: Artifact
|
||||
path: "artifacts/*"
|
||||
push_script: |
|
||||
if [ "$CIRRUS_REPO_OWNER" = "RPCS3" ] && [ -z "$CIRRUS_PR" ] && [ "$CIRRUS_BRANCH" = "master" ]; then
|
||||
COMM_TAG=$(awk '/version{.*}/ { printf("%d.%d.%d", $5, $6, $7) }' ./rpcs3/rpcs3_version.cpp)
|
||||
COMM_COUNT=$(git rev-list --count HEAD)
|
||||
COMM_HASH=$(git rev-parse --short=8 HEAD)
|
||||
export AVVER="${COMM_TAG}-${COMM_COUNT}"
|
||||
.ci/github-upload.sh
|
||||
fi;
|
||||
32
app/src/main/cpp/rpcs3/.clang-format
Normal file
@@ -0,0 +1,32 @@
|
||||
Standard: c++20
|
||||
UseTab: AlignWithSpaces
|
||||
TabWidth: 4
|
||||
IndentWidth: 4
|
||||
AccessModifierOffset: -4
|
||||
PointerAlignment: Left
|
||||
NamespaceIndentation: All
|
||||
ColumnLimit: 0
|
||||
BreakBeforeBraces: Allman
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeTernaryOperators: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: true
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortLambdasOnASingleLine: Empty
|
||||
Cpp11BracedListStyle: true
|
||||
IndentCaseLabels: false
|
||||
SortIncludes: false
|
||||
ReflowComments: true
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignTrailingComments: true
|
||||
AlignAfterOpenBracket: DontAlign
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
AlwaysBreakAfterReturnType: None
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
IndentWrappedFunctionNames: false
|
||||
7
app/src/main/cpp/rpcs3/.editorconfig
Normal file
@@ -0,0 +1,7 @@
|
||||
root = true
|
||||
|
||||
[*.{h,cpp,hpp}]
|
||||
charset = utf-8
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
2
app/src/main/cpp/rpcs3/.gdbinit
Normal file
@@ -0,0 +1,2 @@
|
||||
handle SIGSEGV nostop noprint
|
||||
handle SIGPIPE nostop noprint
|
||||
19
app/src/main/cpp/rpcs3/.github/CONTRIBUTING.md
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# Getting Started
|
||||
|
||||
Before getting started using the emulator, read the [Quickstart Guide](https://rpcs3.net/quickstart). After reading it, if you need support, check out [How to ask for Support](https://github.com/RPCS3/rpcs3/wiki/How-to-ask-for-Support).
|
||||
|
||||
# Issue Reporting
|
||||
|
||||
**The GitHub Issue Tracker is not the place to ask for support or to submit [Game Compatibility](https://rpcs3.net/compatibility) reports.** Requests for support or incorrect reports will be closed. If you are not sure whether the issue you want to report is an actual issue that is not yet known, please use the forums to submit such report.
|
||||
|
||||
**Before reporting an issue:**
|
||||
- Check if your system matches all the minimum requirements listed in the [Quickstart Guide](https://rpcs3.net/quickstart);
|
||||
- Search older issues/forum threads to see if your issue was already submitted;
|
||||
- Use understandable English. It doesn't need to be perfect, but clear enough to understand your message;
|
||||
- While reporting issues, please follow the template for the type of issue you've selected (Regression Report, Bug Report or Feature Request), which is prefilled on the issue's textbox.
|
||||
|
||||
Submitting your test results for Commercial Games must be done on our forums. Please read the [Game Compatibility](https://github.com/RPCS3/rpcs3/wiki/Game-Compatibility) wiki page before doing so.
|
||||
|
||||
# Contributing
|
||||
|
||||
Check the [Coding Style Guidelines](https://github.com/RPCS3/rpcs3/wiki/Coding-Style) and [Developer Information](https://github.com/RPCS3/rpcs3/wiki/Developer-Information). If you have any questions, hit us up on our [Discord Server](https://discord.me/RPCS3) in the **#development** channel.
|
||||
1
app/src/main/cpp/rpcs3/.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
patreon: Nekotekina
|
||||
93
app/src/main/cpp/rpcs3/.github/ISSUE_TEMPLATE/1-regression-report.yml
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
name: Regression report
|
||||
description: If something used to work before, but now it doesn't
|
||||
title: "[Regression] Enter a title here"
|
||||
labels: []
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
# Summary
|
||||
Please do not ask for help or report compatibility regressions here, use [RPCS3 Discord server](https://discord.me/RPCS3) or [forums](https://forums.rpcs3.net/) instead.
|
||||
- type: textarea
|
||||
id: quick-summary
|
||||
attributes:
|
||||
label: Quick summary
|
||||
description: Please briefly describe what has stopped working correctly.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: details
|
||||
attributes:
|
||||
label: Details
|
||||
description: Please describe the regression as accurately as possible. Include screenshots if neccessary.
|
||||
validations:
|
||||
required: false
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
# Identify the regressed build
|
||||
Please provide the _exact_ build (or commit) information that introduced the regression you're reporting.
|
||||
* Please see [How to find the build that caused a regression](https://wiki.rpcs3.net/index.php?title=Help:Using_different_versions_of_RPCS3#How_to_find_the_build_that_caused_a_regression.3F) in our wiki.
|
||||
* You can find [History of RPCS3 builds](https://rpcs3.net/compatibility?b) here.
|
||||
|
||||
Make sure you're running with settings as close to default as possible
|
||||
* **Do NOT enable any emulator game patches when reporting issues**
|
||||
* Only change settings that are required for the game to work
|
||||
- type: input
|
||||
id: regressed-build
|
||||
attributes:
|
||||
label: Build with regression
|
||||
description: Provide _exact_ build (or commit) information that introduced the regression you're reporting.
|
||||
placeholder: v0.0.23-13948-31df99f7
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
# Log files
|
||||
Obtaining the log file:
|
||||
* Run the game until you find the regression.
|
||||
* Completely close RPCS3 and locate the log file.
|
||||
|
||||
RPCS3's Log file will be ```RPCS3.log.gz``` (sometimes shows as RPCS3.log with zip icon) or ```RPCS3.log``` (sometimes shows as RPCS3 wtih notepad icon).
|
||||
* On Windows it will be in the RPCS3 directory near the executable
|
||||
* On Linux it will be in ```~/.cache/rpcs3/```
|
||||
* On MacOS it will be in ```~/Library/Caches/rpcs3```. If you're unable to locate it copy paste the path in Spotlight and hit enter.
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Attach two log files
|
||||
description: |
|
||||
Attach one file for the build with regression and another for a build that works.
|
||||
Drag & drop the files into this input field, or upload them to another service (f.ex. Dropbox, Mega) and provide a link.
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
# Other details
|
||||
If you describe a graphical regression, please provide an RSX capture and/or a RenderDoc capture that demonstrate it.
|
||||
* To create an RSX capture, use _Create_ _RSX_ _Capture_ under _Utilities_.
|
||||
* Captures will be stored in RPCS3 folder → captures.
|
||||
* To create a RenderDoc capture, please refer to [RenderDoc's documentation](https://renderdoc.org/docs/how/how_capture_frame.html).
|
||||
- type: textarea
|
||||
id: captures
|
||||
attributes:
|
||||
label: Attach capture files for visual issues
|
||||
description: Compress your capture with 7z, Rar etc. and attach it here, or upload it to the cloud (Dropbox, Mega etc) and add a link to it.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: system-info
|
||||
attributes:
|
||||
label: System configuration
|
||||
description: Provide information about your system, such as operating system, CPU and GPU model, GPU driver version and other information that describes your system configuration.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: other-details
|
||||
attributes:
|
||||
label: Other details
|
||||
description: Include anything else you deem to be important.
|
||||
validations:
|
||||
required: false
|
||||
78
app/src/main/cpp/rpcs3/.github/ISSUE_TEMPLATE/2-bug-report.yml
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
name: Bug report
|
||||
description: If something doesn't work correctly in RPCS3
|
||||
title: "Enter a title here"
|
||||
labels: []
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
# Summary
|
||||
Please do not ask for help or report compatibility regressions here, use [RPCS3 Discord server](https://discord.me/RPCS3) or [forums](https://forums.rpcs3.net/) instead.
|
||||
- type: textarea
|
||||
id: quick-summary
|
||||
attributes:
|
||||
label: Quick summary
|
||||
description: Please briefly describe what is not working correctly.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: details
|
||||
attributes:
|
||||
label: Details
|
||||
description: |
|
||||
Please describe the problem as accurately as possible.
|
||||
Provide a comparison with a real PS3, if possible.
|
||||
validations:
|
||||
required: false
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
# Log files
|
||||
|
||||
Provide a log file that includes the bug you're reporting.
|
||||
|
||||
Obtaining the log file:
|
||||
* Run the game until you find the regression.
|
||||
* Completely close RPCS3 and locate the log file.
|
||||
|
||||
RPCS3's Log file will be ```RPCS3.log.gz``` (sometimes shows as RPCS3.log with zip icon) or ```RPCS3.log``` (sometimes shows as RPCS3 wtih notepad icon).
|
||||
* On Windows it will be in the RPCS3 directory near the executable
|
||||
* On Linux it will be in ```~/.cache/rpcs3/```
|
||||
* On MacOS it will be in ```~/Library/Caches/rpcs3```. If you're unable to locate it copy paste the path in Spotlight and hit enter.
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Attach a log file
|
||||
description: |
|
||||
Drag & drop the files into this input field, or upload them to another service (f.ex. Dropbox, Mega) and provide a link.
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
# Other details
|
||||
If you describe a graphical issue, please provide an RSX capture and/or a RenderDoc capture that demonstrate it.
|
||||
* To create an RSX capture, use _Create_ _RSX_ _Capture_ under _Utilities_.
|
||||
* Captures will be stored in RPCS3 folder → captures.
|
||||
* To create a RenderDoc capture, please refer to [RenderDoc's documentation](https://renderdoc.org/docs/how/how_capture_frame.html).
|
||||
- type: textarea
|
||||
id: captures
|
||||
attributes:
|
||||
label: Attach capture files for visual issues
|
||||
description: Compress your capture with 7z, Rar etc. and attach it here, or upload it to the cloud (Dropbox, Mega etc) and add a link to it.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: system-info
|
||||
attributes:
|
||||
label: System configuration
|
||||
description: Provide information about your system, such as operating system, CPU and GPU model, GPU driver version and other information that describes your system configuration.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: other-details
|
||||
attributes:
|
||||
label: Other details
|
||||
description: Include anything else you deem to be important.
|
||||
validations:
|
||||
required: false
|
||||
36
app/src/main/cpp/rpcs3/.github/ISSUE_TEMPLATE/3-feature-request.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
name: Feature request
|
||||
description: If RPCS3 lacks a feature you would like to see
|
||||
title: "[Feature request] Enter a title here"
|
||||
labels: []
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please do not ask for help or report compatibility regressions here, use [RPCS3 Discord server](https://discord.me/RPCS3) or [forums](https://forums.rpcs3.net/) instead.
|
||||
- type: textarea
|
||||
id: quick-summary
|
||||
attributes:
|
||||
label: Quick summary
|
||||
description: Please briefly describe what feature you would like RPCS3 to have.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: details
|
||||
attributes:
|
||||
label: Details
|
||||
description: Please describe the feature as accurately as possible.
|
||||
validations:
|
||||
required: false
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please include the following information:
|
||||
* What part of RPCS3 would be affected by your feature? (Gameplay, Debugging, UI, Patches, Installation, CI etc.)
|
||||
* Why your feature is important to RPCS3.
|
||||
* If the feature is implemented in other projects, attach screenshots.
|
||||
* If this feature is something that a game is trying to use, upload a log file for it.
|
||||
|
||||
RPCS3's Log file will be ```RPCS3.log.gz``` (sometimes shows as RPCS3.log with zip icon) or ```RPCS3.log``` (sometimes shows as RPCS3 wtih notepad icon).
|
||||
* On Windows it will be in the RPCS3 directory near the executable
|
||||
* On Linux it will be in ```~/.cache/rpcs3/```
|
||||
* On MacOS it will be in ```~/Library/Caches/rpcs3```. If you're unable to locate it copy paste the path in Spotlight and hit enter.
|
||||
14
app/src/main/cpp/rpcs3/.github/ISSUE_TEMPLATE/4-advanced.md
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
name: Advanced
|
||||
about: For developers and experienced users only
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Please do not ask for help or report compatibility regressions here, use [RPCS3 Discord server](https://discord.me/RPCS3) or [forums](https://forums.rpcs3.net/) instead.
|
||||
|
||||
You're using the advanced template. You're expected to know what to write in order to fill in all the required information for proper report.
|
||||
|
||||
If you're unsure on what to do, please return back to the issue type selection and choose different category.
|
||||
11
app/src/main/cpp/rpcs3/.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Quickstart guide
|
||||
url: https://rpcs3.net/quickstart
|
||||
about: Everything you need to know to install and configure emulator, and add games
|
||||
- name: Ask for help
|
||||
url: https://discord.me/RPCS3
|
||||
about: If you have some questions or need help, please use our Discord server instead of GitHub
|
||||
- name: Report game compatibility
|
||||
url: https://forums.rpcs3.net/thread-196671.html
|
||||
about: Please use RPCS3 forums to submit or update game compatibility status
|
||||
18
app/src/main/cpp/rpcs3/.github/PR-BUILD.md
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
## How to test a PR build
|
||||
|
||||
Please take into account, that RPCS3 build usually takes some time (about 15 mins), so you can't access a build if a PR was just submitted.
|
||||
|
||||
- Open a PR you want to test
|
||||
- Scroll to the very bottom and locate the **Checks** section
|
||||
- Click on **Show all checks**
|
||||
You are supposed to see something like this
|
||||

|
||||
- Click on __Details__ on either **Cirrus Linux GCC** or **Cirrus Windows**
|
||||
- Click **View more details on Cirrus CI** at the very bottom
|
||||

|
||||
- Click on the download button for **Artifact** on the **Artifacts** block
|
||||

|
||||
|
||||
- Congratulations! You are now downloading an RPCS3 build for that specific PR.
|
||||
|
||||
__Please note that PR builds are not supposed to be stable because they contain new changesets.__
|
||||
3
app/src/main/cpp/rpcs3/.github/PULL_REQUEST_TEMPLATE/1-default.md
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<!-- Please include a summary of the change and which issue is fixed. -->
|
||||
|
||||
[How to test this PR](.github/PR-BUILD.md)
|
||||
111
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip.filters
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClInclude Include="7zip\C\7z.h" />
|
||||
<ClInclude Include="7zip\C\7zAlloc.h" />
|
||||
<ClInclude Include="7zip\C\7zBuf.h" />
|
||||
<ClInclude Include="7zip\C\7zCrc.h" />
|
||||
<ClInclude Include="7zip\C\7zFile.h" />
|
||||
<ClInclude Include="7zip\C\7zTypes.h" />
|
||||
<ClInclude Include="7zip\C\7zVersion.h" />
|
||||
<ClInclude Include="7zip\C\7zWindows.h" />
|
||||
<ClInclude Include="7zip\C\Aes.h" />
|
||||
<ClInclude Include="7zip\C\Alloc.h" />
|
||||
<ClInclude Include="7zip\C\Bcj2.h" />
|
||||
<ClInclude Include="7zip\C\Blake2.h" />
|
||||
<ClInclude Include="7zip\C\Bra.h" />
|
||||
<ClInclude Include="7zip\C\BwtSort.h" />
|
||||
<ClInclude Include="7zip\C\Compiler.h" />
|
||||
<ClInclude Include="7zip\C\CpuArch.h" />
|
||||
<ClInclude Include="7zip\C\Delta.h" />
|
||||
<ClInclude Include="7zip\C\DllSecur.h" />
|
||||
<ClInclude Include="7zip\C\HuffEnc.h" />
|
||||
<ClInclude Include="7zip\C\LzFind.h" />
|
||||
<ClInclude Include="7zip\C\LzFindMt.h" />
|
||||
<ClInclude Include="7zip\C\LzHash.h" />
|
||||
<ClInclude Include="7zip\C\Lzma2Dec.h" />
|
||||
<ClInclude Include="7zip\C\Lzma2DecMt.h" />
|
||||
<ClInclude Include="7zip\C\Lzma2Enc.h" />
|
||||
<ClInclude Include="7zip\C\Lzma86.h" />
|
||||
<ClInclude Include="7zip\C\LzmaDec.h" />
|
||||
<ClInclude Include="7zip\C\LzmaEnc.h" />
|
||||
<ClInclude Include="7zip\C\LzmaLib.h" />
|
||||
<ClInclude Include="7zip\C\MtCoder.h" />
|
||||
<ClInclude Include="7zip\C\MtDec.h" />
|
||||
<ClInclude Include="7zip\C\Ppmd.h" />
|
||||
<ClInclude Include="7zip\C\Ppmd7.h" />
|
||||
<ClInclude Include="7zip\C\Ppmd8.h" />
|
||||
<ClInclude Include="7zip\C\Precomp.h" />
|
||||
<ClInclude Include="7zip\C\RotateDefs.h" />
|
||||
<ClInclude Include="7zip\C\Sha1.h" />
|
||||
<ClInclude Include="7zip\C\Sha256.h" />
|
||||
<ClInclude Include="7zip\C\Sort.h" />
|
||||
<ClInclude Include="7zip\C\SwapBytes.h" />
|
||||
<ClInclude Include="7zip\C\Threads.h" />
|
||||
<ClInclude Include="7zip\C\Xz.h" />
|
||||
<ClInclude Include="7zip\C\XzCrc64.h" />
|
||||
<ClInclude Include="7zip\C\XzEnc.h" />
|
||||
<ClInclude Include="7zip\C\Xxh64.h" />
|
||||
<ClInclude Include="7zip\C\ZstdDec.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="7zip\C\7zAlloc.c" />
|
||||
<ClCompile Include="7zip\C\7zArcIn.c" />
|
||||
<ClCompile Include="7zip\C\7zBuf.c" />
|
||||
<ClCompile Include="7zip\C\7zBuf2.c" />
|
||||
<ClCompile Include="7zip\C\7zCrc.c" />
|
||||
<ClCompile Include="7zip\C\7zCrcOpt.c" />
|
||||
<ClCompile Include="7zip\C\7zDec.c" />
|
||||
<ClCompile Include="7zip\C\7zFile.c" />
|
||||
<ClCompile Include="7zip\C\7zStream.c" />
|
||||
<ClCompile Include="7zip\C\Aes.c" />
|
||||
<ClCompile Include="7zip\C\AesOpt.c" />
|
||||
<ClCompile Include="7zip\C\Alloc.c" />
|
||||
<ClCompile Include="7zip\C\Bcj2.c" />
|
||||
<ClCompile Include="7zip\C\Bcj2Enc.c" />
|
||||
<ClCompile Include="7zip\C\Blake2s.c" />
|
||||
<ClCompile Include="7zip\C\Bra.c" />
|
||||
<ClCompile Include="7zip\C\Bra86.c" />
|
||||
<ClCompile Include="7zip\C\BraIA64.c" />
|
||||
<ClCompile Include="7zip\C\BwtSort.c" />
|
||||
<ClCompile Include="7zip\C\CpuArch.c" />
|
||||
<ClCompile Include="7zip\C\Delta.c" />
|
||||
<ClCompile Include="7zip\C\DllSecur.c" />
|
||||
<ClCompile Include="7zip\C\HuffEnc.c" />
|
||||
<ClCompile Include="7zip\C\LzFind.c" />
|
||||
<ClCompile Include="7zip\C\LzFindMt.c" />
|
||||
<ClCompile Include="7zip\C\LzFindOpt.c" />
|
||||
<ClCompile Include="7zip\C\Lzma2Dec.c" />
|
||||
<ClCompile Include="7zip\C\Lzma2DecMt.c" />
|
||||
<ClCompile Include="7zip\C\Lzma2Enc.c" />
|
||||
<ClCompile Include="7zip\C\Lzma86Dec.c" />
|
||||
<ClCompile Include="7zip\C\Lzma86Enc.c" />
|
||||
<ClCompile Include="7zip\C\LzmaDec.c" />
|
||||
<ClCompile Include="7zip\C\LzmaEnc.c" />
|
||||
<ClCompile Include="7zip\C\LzmaLib.c" />
|
||||
<ClCompile Include="7zip\C\MtCoder.c" />
|
||||
<ClCompile Include="7zip\C\MtDec.c" />
|
||||
<ClCompile Include="7zip\C\Ppmd7.c" />
|
||||
<ClCompile Include="7zip\C\Ppmd7aDec.c" />
|
||||
<ClCompile Include="7zip\C\Ppmd7Dec.c" />
|
||||
<ClCompile Include="7zip\C\Ppmd7Enc.c" />
|
||||
<ClCompile Include="7zip\C\Ppmd8.c" />
|
||||
<ClCompile Include="7zip\C\Ppmd8Dec.c" />
|
||||
<ClCompile Include="7zip\C\Ppmd8Enc.c" />
|
||||
<ClCompile Include="7zip\C\Sha1.c" />
|
||||
<ClCompile Include="7zip\C\Sha1Opt.c" />
|
||||
<ClCompile Include="7zip\C\Sha256.c" />
|
||||
<ClCompile Include="7zip\C\Sha256Opt.c" />
|
||||
<ClCompile Include="7zip\C\Sort.c" />
|
||||
<ClCompile Include="7zip\C\SwapBytes.c" />
|
||||
<ClCompile Include="7zip\C\Threads.c" />
|
||||
<ClCompile Include="7zip\C\Xz.c" />
|
||||
<ClCompile Include="7zip\C\XzCrc64.c" />
|
||||
<ClCompile Include="7zip\C\XzCrc64Opt.c" />
|
||||
<ClCompile Include="7zip\C\XzDec.c" />
|
||||
<ClCompile Include="7zip\C\XzEnc.c" />
|
||||
<ClCompile Include="7zip\C\XzIn.c" />
|
||||
<ClCompile Include="7zip\C\Xxh64.c" />
|
||||
<ClCompile Include="7zip\C\ZstdDec.c" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
267
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip.vcxproj
vendored
Normal file
@@ -0,0 +1,267 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="7zip\C\7z.h" />
|
||||
<ClInclude Include="7zip\C\7zAlloc.h" />
|
||||
<ClInclude Include="7zip\C\7zBuf.h" />
|
||||
<ClInclude Include="7zip\C\7zCrc.h" />
|
||||
<ClInclude Include="7zip\C\7zFile.h" />
|
||||
<ClInclude Include="7zip\C\7zTypes.h" />
|
||||
<ClInclude Include="7zip\C\7zVersion.h" />
|
||||
<ClInclude Include="7zip\C\7zWindows.h" />
|
||||
<ClInclude Include="7zip\C\Aes.h" />
|
||||
<ClInclude Include="7zip\C\Alloc.h" />
|
||||
<ClInclude Include="7zip\C\Bcj2.h" />
|
||||
<ClInclude Include="7zip\C\Blake2.h" />
|
||||
<ClInclude Include="7zip\C\Bra.h" />
|
||||
<ClInclude Include="7zip\C\BwtSort.h" />
|
||||
<ClInclude Include="7zip\C\Compiler.h" />
|
||||
<ClInclude Include="7zip\C\CpuArch.h" />
|
||||
<ClInclude Include="7zip\C\Delta.h" />
|
||||
<ClInclude Include="7zip\C\DllSecur.h" />
|
||||
<ClInclude Include="7zip\C\HuffEnc.h" />
|
||||
<ClInclude Include="7zip\C\LzFind.h" />
|
||||
<ClInclude Include="7zip\C\LzFindMt.h" />
|
||||
<ClInclude Include="7zip\C\LzHash.h" />
|
||||
<ClInclude Include="7zip\C\Lzma2Dec.h" />
|
||||
<ClInclude Include="7zip\C\Lzma2DecMt.h" />
|
||||
<ClInclude Include="7zip\C\Lzma2Enc.h" />
|
||||
<ClInclude Include="7zip\C\Lzma86.h" />
|
||||
<ClInclude Include="7zip\C\LzmaDec.h" />
|
||||
<ClInclude Include="7zip\C\LzmaEnc.h" />
|
||||
<ClInclude Include="7zip\C\LzmaLib.h" />
|
||||
<ClInclude Include="7zip\C\MtCoder.h" />
|
||||
<ClInclude Include="7zip\C\MtDec.h" />
|
||||
<ClInclude Include="7zip\C\Ppmd.h" />
|
||||
<ClInclude Include="7zip\C\Ppmd7.h" />
|
||||
<ClInclude Include="7zip\C\Ppmd8.h" />
|
||||
<ClInclude Include="7zip\C\Precomp.h" />
|
||||
<ClInclude Include="7zip\C\RotateDefs.h" />
|
||||
<ClInclude Include="7zip\C\Sha1.h" />
|
||||
<ClInclude Include="7zip\C\Sha256.h" />
|
||||
<ClInclude Include="7zip\C\Sort.h" />
|
||||
<ClInclude Include="7zip\C\SwapBytes.h" />
|
||||
<ClInclude Include="7zip\C\Threads.h" />
|
||||
<ClInclude Include="7zip\C\Xxh64.h" />
|
||||
<ClInclude Include="7zip\C\Xz.h" />
|
||||
<ClInclude Include="7zip\C\XzCrc64.h" />
|
||||
<ClInclude Include="7zip\C\XzEnc.h" />
|
||||
<ClInclude Include="7zip\C\ZstdDec.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="7zip\C\7zAlloc.c" />
|
||||
<ClCompile Include="7zip\C\7zArcIn.c" />
|
||||
<ClCompile Include="7zip\C\7zBuf.c" />
|
||||
<ClCompile Include="7zip\C\7zBuf2.c" />
|
||||
<ClCompile Include="7zip\C\7zCrc.c" />
|
||||
<ClCompile Include="7zip\C\7zCrcOpt.c" />
|
||||
<ClCompile Include="7zip\C\7zDec.c" />
|
||||
<ClCompile Include="7zip\C\7zFile.c" />
|
||||
<ClCompile Include="7zip\C\7zStream.c" />
|
||||
<ClCompile Include="7zip\C\Aes.c" />
|
||||
<ClCompile Include="7zip\C\AesOpt.c" />
|
||||
<ClCompile Include="7zip\C\Alloc.c" />
|
||||
<ClCompile Include="7zip\C\Bcj2.c" />
|
||||
<ClCompile Include="7zip\C\Bcj2Enc.c" />
|
||||
<ClCompile Include="7zip\C\Blake2s.c" />
|
||||
<ClCompile Include="7zip\C\Bra.c" />
|
||||
<ClCompile Include="7zip\C\Bra86.c" />
|
||||
<ClCompile Include="7zip\C\BraIA64.c" />
|
||||
<ClCompile Include="7zip\C\BwtSort.c" />
|
||||
<ClCompile Include="7zip\C\CpuArch.c" />
|
||||
<ClCompile Include="7zip\C\Delta.c" />
|
||||
<ClCompile Include="7zip\C\DllSecur.c" />
|
||||
<ClCompile Include="7zip\C\HuffEnc.c" />
|
||||
<ClCompile Include="7zip\C\LzFind.c" />
|
||||
<ClCompile Include="7zip\C\LzFindMt.c" />
|
||||
<ClCompile Include="7zip\C\LzFindOpt.c" />
|
||||
<ClCompile Include="7zip\C\Lzma2Dec.c" />
|
||||
<ClCompile Include="7zip\C\Lzma2DecMt.c" />
|
||||
<ClCompile Include="7zip\C\Lzma2Enc.c" />
|
||||
<ClCompile Include="7zip\C\Lzma86Dec.c" />
|
||||
<ClCompile Include="7zip\C\Lzma86Enc.c" />
|
||||
<ClCompile Include="7zip\C\LzmaDec.c" />
|
||||
<ClCompile Include="7zip\C\LzmaEnc.c" />
|
||||
<ClCompile Include="7zip\C\LzmaLib.c" />
|
||||
<ClCompile Include="7zip\C\MtCoder.c" />
|
||||
<ClCompile Include="7zip\C\MtDec.c" />
|
||||
<ClCompile Include="7zip\C\Ppmd7.c" />
|
||||
<ClCompile Include="7zip\C\Ppmd7aDec.c" />
|
||||
<ClCompile Include="7zip\C\Ppmd7Dec.c" />
|
||||
<ClCompile Include="7zip\C\Ppmd7Enc.c" />
|
||||
<ClCompile Include="7zip\C\Ppmd8.c" />
|
||||
<ClCompile Include="7zip\C\Ppmd8Dec.c" />
|
||||
<ClCompile Include="7zip\C\Ppmd8Enc.c" />
|
||||
<ClCompile Include="7zip\C\Sha1.c" />
|
||||
<ClCompile Include="7zip\C\Sha1Opt.c" />
|
||||
<ClCompile Include="7zip\C\Sha256.c" />
|
||||
<ClCompile Include="7zip\C\Sha256Opt.c" />
|
||||
<ClCompile Include="7zip\C\Sort.c" />
|
||||
<ClCompile Include="7zip\C\SwapBytes.c" />
|
||||
<ClCompile Include="7zip\C\Threads.c" />
|
||||
<ClCompile Include="7zip\C\Xxh64.c" />
|
||||
<ClCompile Include="7zip\C\Xz.c" />
|
||||
<ClCompile Include="7zip\C\XzCrc64.c" />
|
||||
<ClCompile Include="7zip\C\XzCrc64Opt.c" />
|
||||
<ClCompile Include="7zip\C\XzDec.c" />
|
||||
<ClCompile Include="7zip\C\XzEnc.c" />
|
||||
<ClCompile Include="7zip\C\XzIn.c" />
|
||||
<ClCompile Include="7zip\C\ZstdDec.c" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{5B146DEA-9ACE-4D32-A7FD-3F42464DD69C}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>My7zlib</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)\buildfiles\msvc\common_default_macros.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<OutDir>$(SolutionDir)lib/$(Configuration)-$(Platform)/</OutDir>
|
||||
<IntDir>$(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)/</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
100
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/Asm/arm/7zCrcOpt.asm
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
CODE32
|
||||
|
||||
EXPORT |CrcUpdateT4@16|
|
||||
|
||||
AREA |.text|, CODE, ARM
|
||||
|
||||
MACRO
|
||||
CRC32_STEP_1
|
||||
|
||||
ldrb r4, [r1], #1
|
||||
subs r2, r2, #1
|
||||
eor r4, r4, r0
|
||||
and r4, r4, #0xFF
|
||||
ldr r4, [r3, +r4, lsl #2]
|
||||
eor r0, r4, r0, lsr #8
|
||||
|
||||
MEND
|
||||
|
||||
|
||||
MACRO
|
||||
CRC32_STEP_4 $STREAM_WORD
|
||||
|
||||
eor r7, r7, r8
|
||||
eor r7, r7, r9
|
||||
eor r0, r0, r7
|
||||
eor r0, r0, $STREAM_WORD
|
||||
ldr $STREAM_WORD, [r1], #4
|
||||
|
||||
and r7, r0, #0xFF
|
||||
and r8, r0, #0xFF00
|
||||
and r9, r0, #0xFF0000
|
||||
and r0, r0, #0xFF000000
|
||||
|
||||
ldr r7, [r6, +r7, lsl #2]
|
||||
ldr r8, [r5, +r8, lsr #6]
|
||||
ldr r9, [r4, +r9, lsr #14]
|
||||
ldr r0, [r3, +r0, lsr #22]
|
||||
|
||||
MEND
|
||||
|
||||
|
||||
|CrcUpdateT4@16| PROC
|
||||
|
||||
stmdb sp!, {r4-r11, lr}
|
||||
cmp r2, #0
|
||||
beq |$fin|
|
||||
|
||||
|$v1|
|
||||
tst r1, #7
|
||||
beq |$v2|
|
||||
CRC32_STEP_1
|
||||
bne |$v1|
|
||||
|
||||
|$v2|
|
||||
cmp r2, #16
|
||||
blo |$v3|
|
||||
|
||||
ldr r10, [r1], #4
|
||||
ldr r11, [r1], #4
|
||||
|
||||
add r4, r3, #0x400
|
||||
add r5, r3, #0x800
|
||||
add r6, r3, #0xC00
|
||||
|
||||
mov r7, #0
|
||||
mov r8, #0
|
||||
mov r9, #0
|
||||
|
||||
sub r2, r2, #16
|
||||
|
||||
|$loop|
|
||||
; pld [r1, #0x40]
|
||||
|
||||
CRC32_STEP_4 r10
|
||||
CRC32_STEP_4 r11
|
||||
|
||||
subs r2, r2, #8
|
||||
bhs |$loop|
|
||||
|
||||
sub r1, r1, #8
|
||||
add r2, r2, #16
|
||||
|
||||
eor r7, r7, r8
|
||||
eor r7, r7, r9
|
||||
eor r0, r0, r7
|
||||
|
||||
|$v3|
|
||||
cmp r2, #0
|
||||
beq |$fin|
|
||||
|
||||
|$v4|
|
||||
CRC32_STEP_1
|
||||
bne |$v4|
|
||||
|
||||
|$fin|
|
||||
ldmia sp!, {r4-r11, pc}
|
||||
|
||||
|CrcUpdateT4@16| ENDP
|
||||
|
||||
END
|
||||
181
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/Asm/arm64/7zAsm.S
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
// 7zAsm.S -- ASM macros for arm64
|
||||
// 2021-04-25 : Igor Pavlov : Public domain
|
||||
|
||||
#define r0 x0
|
||||
#define r1 x1
|
||||
#define r2 x2
|
||||
#define r3 x3
|
||||
#define r4 x4
|
||||
#define r5 x5
|
||||
#define r6 x6
|
||||
#define r7 x7
|
||||
#define r8 x8
|
||||
#define r9 x9
|
||||
#define r10 x10
|
||||
#define r11 x11
|
||||
#define r12 x12
|
||||
#define r13 x13
|
||||
#define r14 x14
|
||||
#define r15 x15
|
||||
#define r16 x16
|
||||
#define r17 x17
|
||||
#define r18 x18
|
||||
#define r19 x19
|
||||
#define r20 x20
|
||||
#define r21 x21
|
||||
#define r22 x22
|
||||
#define r23 x23
|
||||
#define r24 x24
|
||||
#define r25 x25
|
||||
#define r26 x26
|
||||
#define r27 x27
|
||||
#define r28 x28
|
||||
#define r29 x29
|
||||
#define r30 x30
|
||||
|
||||
#define REG_ABI_PARAM_0 r0
|
||||
#define REG_ABI_PARAM_1 r1
|
||||
#define REG_ABI_PARAM_2 r2
|
||||
|
||||
|
||||
.macro p2_add reg:req, param:req
|
||||
add \reg, \reg, \param
|
||||
.endm
|
||||
|
||||
.macro p2_sub reg:req, param:req
|
||||
sub \reg, \reg, \param
|
||||
.endm
|
||||
|
||||
.macro p2_sub_s reg:req, param:req
|
||||
subs \reg, \reg, \param
|
||||
.endm
|
||||
|
||||
.macro p2_and reg:req, param:req
|
||||
and \reg, \reg, \param
|
||||
.endm
|
||||
|
||||
.macro xor reg:req, param:req
|
||||
eor \reg, \reg, \param
|
||||
.endm
|
||||
|
||||
.macro or reg:req, param:req
|
||||
orr \reg, \reg, \param
|
||||
.endm
|
||||
|
||||
.macro shl reg:req, param:req
|
||||
lsl \reg, \reg, \param
|
||||
.endm
|
||||
|
||||
.macro shr reg:req, param:req
|
||||
lsr \reg, \reg, \param
|
||||
.endm
|
||||
|
||||
.macro sar reg:req, param:req
|
||||
asr \reg, \reg, \param
|
||||
.endm
|
||||
|
||||
.macro p1_neg reg:req
|
||||
neg \reg, \reg
|
||||
.endm
|
||||
|
||||
.macro dec reg:req
|
||||
sub \reg, \reg, 1
|
||||
.endm
|
||||
|
||||
.macro dec_s reg:req
|
||||
subs \reg, \reg, 1
|
||||
.endm
|
||||
|
||||
.macro inc reg:req
|
||||
add \reg, \reg, 1
|
||||
.endm
|
||||
|
||||
.macro inc_s reg:req
|
||||
adds \reg, \reg, 1
|
||||
.endm
|
||||
|
||||
|
||||
.macro imul reg:req, param:req
|
||||
mul \reg, \reg, \param
|
||||
.endm
|
||||
|
||||
/*
|
||||
arm64 and arm use reverted c flag after subs/cmp instructions:
|
||||
arm64-arm : x86
|
||||
b.lo / b.cc : jb / jc
|
||||
b.hs / b.cs : jae / jnc
|
||||
*/
|
||||
|
||||
.macro jmp lab:req
|
||||
b \lab
|
||||
.endm
|
||||
|
||||
.macro je lab:req
|
||||
b.eq \lab
|
||||
.endm
|
||||
|
||||
.macro jz lab:req
|
||||
b.eq \lab
|
||||
.endm
|
||||
|
||||
.macro jnz lab:req
|
||||
b.ne \lab
|
||||
.endm
|
||||
|
||||
.macro jne lab:req
|
||||
b.ne \lab
|
||||
.endm
|
||||
|
||||
.macro jb lab:req
|
||||
b.lo \lab
|
||||
.endm
|
||||
|
||||
.macro jbe lab:req
|
||||
b.ls \lab
|
||||
.endm
|
||||
|
||||
.macro ja lab:req
|
||||
b.hi \lab
|
||||
.endm
|
||||
|
||||
.macro jae lab:req
|
||||
b.hs \lab
|
||||
.endm
|
||||
|
||||
|
||||
.macro cmove dest:req, srcTrue:req
|
||||
csel \dest, \srcTrue, \dest, eq
|
||||
.endm
|
||||
|
||||
.macro cmovne dest:req, srcTrue:req
|
||||
csel \dest, \srcTrue, \dest, ne
|
||||
.endm
|
||||
|
||||
.macro cmovs dest:req, srcTrue:req
|
||||
csel \dest, \srcTrue, \dest, mi
|
||||
.endm
|
||||
|
||||
.macro cmovns dest:req, srcTrue:req
|
||||
csel \dest, \srcTrue, \dest, pl
|
||||
.endm
|
||||
|
||||
.macro cmovb dest:req, srcTrue:req
|
||||
csel \dest, \srcTrue, \dest, lo
|
||||
.endm
|
||||
|
||||
.macro cmovae dest:req, srcTrue:req
|
||||
csel \dest, \srcTrue, \dest, hs
|
||||
.endm
|
||||
|
||||
|
||||
.macro MY_ALIGN_16 macro
|
||||
.p2align 4,, (1 << 4) - 1
|
||||
.endm
|
||||
|
||||
.macro MY_ALIGN_32 macro
|
||||
.p2align 5,, (1 << 5) - 1
|
||||
.endm
|
||||
|
||||
.macro MY_ALIGN_64 macro
|
||||
.p2align 6,, (1 << 6) - 1
|
||||
.endm
|
||||
1487
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/Asm/arm64/LzmaDecOpt.S
vendored
Normal file
341
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/Asm/x86/7zAsm.asm
vendored
Normal file
@@ -0,0 +1,341 @@
|
||||
; 7zAsm.asm -- ASM macros
|
||||
; 2023-12-08 : Igor Pavlov : Public domain
|
||||
|
||||
|
||||
; UASM can require these changes
|
||||
; OPTION FRAMEPRESERVEFLAGS:ON
|
||||
; OPTION PROLOGUE:NONE
|
||||
; OPTION EPILOGUE:NONE
|
||||
|
||||
ifdef @wordsize
|
||||
; @wordsize is defined only in JWASM and ASMC and is not defined in MASM
|
||||
; @wordsize eq 8 for 64-bit x64
|
||||
; @wordsize eq 2 for 32-bit x86
|
||||
if @wordsize eq 8
|
||||
x64 equ 1
|
||||
endif
|
||||
else
|
||||
ifdef RAX
|
||||
x64 equ 1
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
ifdef x64
|
||||
IS_X64 equ 1
|
||||
else
|
||||
IS_X64 equ 0
|
||||
endif
|
||||
|
||||
ifdef ABI_LINUX
|
||||
IS_LINUX equ 1
|
||||
else
|
||||
IS_LINUX equ 0
|
||||
endif
|
||||
|
||||
ifndef x64
|
||||
; Use ABI_CDECL for x86 (32-bit) only
|
||||
; if ABI_CDECL is not defined, we use fastcall abi
|
||||
ifdef ABI_CDECL
|
||||
IS_CDECL equ 1
|
||||
else
|
||||
IS_CDECL equ 0
|
||||
endif
|
||||
endif
|
||||
|
||||
OPTION PROLOGUE:NONE
|
||||
OPTION EPILOGUE:NONE
|
||||
|
||||
MY_ASM_START macro
|
||||
ifdef x64
|
||||
.code
|
||||
else
|
||||
.386
|
||||
.model flat
|
||||
_TEXT$00 SEGMENT PARA PUBLIC 'CODE'
|
||||
endif
|
||||
endm
|
||||
|
||||
MY_PROC macro name:req, numParams:req
|
||||
align 16
|
||||
proc_numParams = numParams
|
||||
if (IS_X64 gt 0)
|
||||
proc_name equ name
|
||||
elseif (IS_LINUX gt 0)
|
||||
proc_name equ name
|
||||
elseif (IS_CDECL gt 0)
|
||||
proc_name equ @CatStr(_,name)
|
||||
else
|
||||
proc_name equ @CatStr(@,name,@, %numParams * 4)
|
||||
endif
|
||||
proc_name PROC
|
||||
endm
|
||||
|
||||
MY_ENDP macro
|
||||
if (IS_X64 gt 0)
|
||||
ret
|
||||
elseif (IS_CDECL gt 0)
|
||||
ret
|
||||
elseif (proc_numParams LT 3)
|
||||
ret
|
||||
else
|
||||
ret (proc_numParams - 2) * 4
|
||||
endif
|
||||
proc_name ENDP
|
||||
endm
|
||||
|
||||
|
||||
ifdef x64
|
||||
REG_SIZE equ 8
|
||||
REG_LOGAR_SIZE equ 3
|
||||
else
|
||||
REG_SIZE equ 4
|
||||
REG_LOGAR_SIZE equ 2
|
||||
endif
|
||||
|
||||
x0 equ EAX
|
||||
x1 equ ECX
|
||||
x2 equ EDX
|
||||
x3 equ EBX
|
||||
x4 equ ESP
|
||||
x5 equ EBP
|
||||
x6 equ ESI
|
||||
x7 equ EDI
|
||||
|
||||
x0_W equ AX
|
||||
x1_W equ CX
|
||||
x2_W equ DX
|
||||
x3_W equ BX
|
||||
|
||||
x5_W equ BP
|
||||
x6_W equ SI
|
||||
x7_W equ DI
|
||||
|
||||
x0_L equ AL
|
||||
x1_L equ CL
|
||||
x2_L equ DL
|
||||
x3_L equ BL
|
||||
|
||||
x0_H equ AH
|
||||
x1_H equ CH
|
||||
x2_H equ DH
|
||||
x3_H equ BH
|
||||
|
||||
; r0_L equ AL
|
||||
; r1_L equ CL
|
||||
; r2_L equ DL
|
||||
; r3_L equ BL
|
||||
|
||||
; r0_H equ AH
|
||||
; r1_H equ CH
|
||||
; r2_H equ DH
|
||||
; r3_H equ BH
|
||||
|
||||
|
||||
ifdef x64
|
||||
x5_L equ BPL
|
||||
x6_L equ SIL
|
||||
x7_L equ DIL
|
||||
x8_L equ r8b
|
||||
x9_L equ r9b
|
||||
x10_L equ r10b
|
||||
x11_L equ r11b
|
||||
x12_L equ r12b
|
||||
x13_L equ r13b
|
||||
x14_L equ r14b
|
||||
x15_L equ r15b
|
||||
|
||||
r0 equ RAX
|
||||
r1 equ RCX
|
||||
r2 equ RDX
|
||||
r3 equ RBX
|
||||
r4 equ RSP
|
||||
r5 equ RBP
|
||||
r6 equ RSI
|
||||
r7 equ RDI
|
||||
x8 equ r8d
|
||||
x9 equ r9d
|
||||
x10 equ r10d
|
||||
x11 equ r11d
|
||||
x12 equ r12d
|
||||
x13 equ r13d
|
||||
x14 equ r14d
|
||||
x15 equ r15d
|
||||
else
|
||||
r0 equ x0
|
||||
r1 equ x1
|
||||
r2 equ x2
|
||||
r3 equ x3
|
||||
r4 equ x4
|
||||
r5 equ x5
|
||||
r6 equ x6
|
||||
r7 equ x7
|
||||
endif
|
||||
|
||||
x0_R equ r0
|
||||
x1_R equ r1
|
||||
x2_R equ r2
|
||||
x3_R equ r3
|
||||
x4_R equ r4
|
||||
x5_R equ r5
|
||||
x6_R equ r6
|
||||
x7_R equ r7
|
||||
x8_R equ r8
|
||||
x9_R equ r9
|
||||
x10_R equ r10
|
||||
x11_R equ r11
|
||||
x12_R equ r12
|
||||
x13_R equ r13
|
||||
x14_R equ r14
|
||||
x15_R equ r15
|
||||
|
||||
ifdef x64
|
||||
ifdef ABI_LINUX
|
||||
|
||||
MY_PUSH_2_REGS macro
|
||||
push r3
|
||||
push r5
|
||||
endm
|
||||
|
||||
MY_POP_2_REGS macro
|
||||
pop r5
|
||||
pop r3
|
||||
endm
|
||||
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
MY_PUSH_4_REGS macro
|
||||
push r3
|
||||
push r5
|
||||
push r6
|
||||
push r7
|
||||
endm
|
||||
|
||||
MY_POP_4_REGS macro
|
||||
pop r7
|
||||
pop r6
|
||||
pop r5
|
||||
pop r3
|
||||
endm
|
||||
|
||||
|
||||
; for fastcall and for WIN-x64
|
||||
REG_PARAM_0_x equ x1
|
||||
REG_PARAM_0 equ r1
|
||||
REG_PARAM_1_x equ x2
|
||||
REG_PARAM_1 equ r2
|
||||
|
||||
ifndef x64
|
||||
; for x86-fastcall
|
||||
|
||||
REG_ABI_PARAM_0_x equ REG_PARAM_0_x
|
||||
REG_ABI_PARAM_0 equ REG_PARAM_0
|
||||
REG_ABI_PARAM_1_x equ REG_PARAM_1_x
|
||||
REG_ABI_PARAM_1 equ REG_PARAM_1
|
||||
|
||||
MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 macro
|
||||
MY_PUSH_4_REGS
|
||||
endm
|
||||
|
||||
MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 macro
|
||||
MY_POP_4_REGS
|
||||
endm
|
||||
|
||||
else
|
||||
; x64
|
||||
|
||||
if (IS_LINUX eq 0)
|
||||
|
||||
; for WIN-x64:
|
||||
REG_PARAM_2_x equ x8
|
||||
REG_PARAM_2 equ r8
|
||||
REG_PARAM_3 equ r9
|
||||
|
||||
REG_ABI_PARAM_0_x equ REG_PARAM_0_x
|
||||
REG_ABI_PARAM_0 equ REG_PARAM_0
|
||||
REG_ABI_PARAM_1_x equ REG_PARAM_1_x
|
||||
REG_ABI_PARAM_1 equ REG_PARAM_1
|
||||
REG_ABI_PARAM_2_x equ REG_PARAM_2_x
|
||||
REG_ABI_PARAM_2 equ REG_PARAM_2
|
||||
REG_ABI_PARAM_3 equ REG_PARAM_3
|
||||
|
||||
else
|
||||
; for LINUX-x64:
|
||||
REG_LINUX_PARAM_0_x equ x7
|
||||
REG_LINUX_PARAM_0 equ r7
|
||||
REG_LINUX_PARAM_1_x equ x6
|
||||
REG_LINUX_PARAM_1 equ r6
|
||||
REG_LINUX_PARAM_2 equ r2
|
||||
REG_LINUX_PARAM_3 equ r1
|
||||
REG_LINUX_PARAM_4_x equ x8
|
||||
REG_LINUX_PARAM_4 equ r8
|
||||
REG_LINUX_PARAM_5 equ r9
|
||||
|
||||
REG_ABI_PARAM_0_x equ REG_LINUX_PARAM_0_x
|
||||
REG_ABI_PARAM_0 equ REG_LINUX_PARAM_0
|
||||
REG_ABI_PARAM_1_x equ REG_LINUX_PARAM_1_x
|
||||
REG_ABI_PARAM_1 equ REG_LINUX_PARAM_1
|
||||
REG_ABI_PARAM_2 equ REG_LINUX_PARAM_2
|
||||
REG_ABI_PARAM_3 equ REG_LINUX_PARAM_3
|
||||
REG_ABI_PARAM_4_x equ REG_LINUX_PARAM_4_x
|
||||
REG_ABI_PARAM_4 equ REG_LINUX_PARAM_4
|
||||
REG_ABI_PARAM_5 equ REG_LINUX_PARAM_5
|
||||
|
||||
MY_ABI_LINUX_TO_WIN_2 macro
|
||||
mov r2, r6
|
||||
mov r1, r7
|
||||
endm
|
||||
|
||||
MY_ABI_LINUX_TO_WIN_3 macro
|
||||
mov r8, r2
|
||||
mov r2, r6
|
||||
mov r1, r7
|
||||
endm
|
||||
|
||||
MY_ABI_LINUX_TO_WIN_4 macro
|
||||
mov r9, r1
|
||||
mov r8, r2
|
||||
mov r2, r6
|
||||
mov r1, r7
|
||||
endm
|
||||
|
||||
endif ; IS_LINUX
|
||||
|
||||
|
||||
MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 macro
|
||||
if (IS_LINUX gt 0)
|
||||
MY_PUSH_2_REGS
|
||||
else
|
||||
MY_PUSH_4_REGS
|
||||
endif
|
||||
endm
|
||||
|
||||
MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11 macro
|
||||
if (IS_LINUX gt 0)
|
||||
MY_POP_2_REGS
|
||||
else
|
||||
MY_POP_4_REGS
|
||||
endif
|
||||
endm
|
||||
|
||||
|
||||
MY_PUSH_PRESERVED_ABI_REGS macro
|
||||
MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
endm
|
||||
|
||||
|
||||
MY_POP_PRESERVED_ABI_REGS macro
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11
|
||||
endm
|
||||
|
||||
endif ; x64
|
||||
258
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/Asm/x86/7zCrcOpt.asm
vendored
Normal file
@@ -0,0 +1,258 @@
|
||||
; 7zCrcOpt.asm -- CRC32 calculation : optimized version
|
||||
; 2023-12-08 : Igor Pavlov : Public domain
|
||||
|
||||
include 7zAsm.asm
|
||||
|
||||
MY_ASM_START
|
||||
|
||||
NUM_WORDS equ 3
|
||||
UNROLL_CNT equ 2
|
||||
|
||||
if (NUM_WORDS lt 1) or (NUM_WORDS gt 64)
|
||||
.err <NUM_WORDS_IS_INCORRECT>
|
||||
endif
|
||||
if (UNROLL_CNT lt 1)
|
||||
.err <UNROLL_CNT_IS_INCORRECT>
|
||||
endif
|
||||
|
||||
rD equ r2
|
||||
rD_x equ x2
|
||||
rN equ r7
|
||||
rT equ r5
|
||||
|
||||
ifndef x64
|
||||
if (IS_CDECL gt 0)
|
||||
crc_OFFS equ (REG_SIZE * 5)
|
||||
data_OFFS equ (REG_SIZE + crc_OFFS)
|
||||
size_OFFS equ (REG_SIZE + data_OFFS)
|
||||
else
|
||||
size_OFFS equ (REG_SIZE * 5)
|
||||
endif
|
||||
table_OFFS equ (REG_SIZE + size_OFFS)
|
||||
endif
|
||||
|
||||
; rN + rD is same speed as rD, but we reduce one instruction in loop
|
||||
SRCDAT_1 equ rN + rD * 1 + 1 *
|
||||
SRCDAT_4 equ rN + rD * 1 + 4 *
|
||||
|
||||
CRC macro op:req, dest:req, src:req, t:req
|
||||
op dest, dword ptr [rT + @CatStr(src, _R) * 4 + 0400h * (t)]
|
||||
endm
|
||||
|
||||
CRC_XOR macro dest:req, src:req, t:req
|
||||
CRC xor, dest, src, t
|
||||
endm
|
||||
|
||||
CRC_MOV macro dest:req, src:req, t:req
|
||||
CRC mov, dest, src, t
|
||||
endm
|
||||
|
||||
MOVZXLO macro dest:req, src:req
|
||||
movzx dest, @CatStr(src, _L)
|
||||
endm
|
||||
|
||||
MOVZXHI macro dest:req, src:req
|
||||
movzx dest, @CatStr(src, _H)
|
||||
endm
|
||||
|
||||
; movzx x0, x0_L - is slow in some cpus (ivb), if same register for src and dest
|
||||
; movzx x3, x0_L sometimes is 0 cycles latency (not always)
|
||||
; movzx x3, x0_L sometimes is 0.5 cycles latency
|
||||
; movzx x3, x0_H is 2 cycles latency in some cpus
|
||||
|
||||
CRC1b macro
|
||||
movzx x6, byte ptr [rD]
|
||||
MOVZXLO x3, x0
|
||||
inc rD
|
||||
shr x0, 8
|
||||
xor x6, x3
|
||||
CRC_XOR x0, x6, 0
|
||||
dec rN
|
||||
endm
|
||||
|
||||
LOAD_1 macro dest:req, t:req, iter:req, index:req
|
||||
movzx dest, byte ptr [SRCDAT_1 (4 * (NUM_WORDS - 1 - t + iter * NUM_WORDS) + index)]
|
||||
endm
|
||||
|
||||
LOAD_2 macro dest:req, t:req, iter:req, index:req
|
||||
movzx dest, word ptr [SRCDAT_1 (4 * (NUM_WORDS - 1 - t + iter * NUM_WORDS) + index)]
|
||||
endm
|
||||
|
||||
CRC_QUAD macro nn, t:req, iter:req
|
||||
ifdef x64
|
||||
; paired memory loads give 1-3% speed gain, but it uses more registers
|
||||
LOAD_2 x3, t, iter, 0
|
||||
LOAD_2 x9, t, iter, 2
|
||||
MOVZXLO x6, x3
|
||||
shr x3, 8
|
||||
CRC_XOR nn, x6, t * 4 + 3
|
||||
MOVZXLO x6, x9
|
||||
shr x9, 8
|
||||
CRC_XOR nn, x3, t * 4 + 2
|
||||
CRC_XOR nn, x6, t * 4 + 1
|
||||
CRC_XOR nn, x9, t * 4 + 0
|
||||
elseif 0
|
||||
LOAD_2 x3, t, iter, 0
|
||||
MOVZXLO x6, x3
|
||||
shr x3, 8
|
||||
CRC_XOR nn, x6, t * 4 + 3
|
||||
CRC_XOR nn, x3, t * 4 + 2
|
||||
LOAD_2 x3, t, iter, 2
|
||||
MOVZXLO x6, x3
|
||||
shr x3, 8
|
||||
CRC_XOR nn, x6, t * 4 + 1
|
||||
CRC_XOR nn, x3, t * 4 + 0
|
||||
elseif 0
|
||||
LOAD_1 x3, t, iter, 0
|
||||
LOAD_1 x6, t, iter, 1
|
||||
CRC_XOR nn, x3, t * 4 + 3
|
||||
CRC_XOR nn, x6, t * 4 + 2
|
||||
LOAD_1 x3, t, iter, 2
|
||||
LOAD_1 x6, t, iter, 3
|
||||
CRC_XOR nn, x3, t * 4 + 1
|
||||
CRC_XOR nn, x6, t * 4 + 0
|
||||
else
|
||||
; 32-bit load is better if there is only one read port (core2)
|
||||
; but that code can be slower if there are 2 read ports (snb)
|
||||
mov x3, dword ptr [SRCDAT_1 (4 * (NUM_WORDS - 1 - t + iter * NUM_WORDS) + 0)]
|
||||
MOVZXLO x6, x3
|
||||
CRC_XOR nn, x6, t * 4 + 3
|
||||
MOVZXHI x6, x3
|
||||
shr x3, 16
|
||||
CRC_XOR nn, x6, t * 4 + 2
|
||||
MOVZXLO x6, x3
|
||||
shr x3, 8
|
||||
CRC_XOR nn, x6, t * 4 + 1
|
||||
CRC_XOR nn, x3, t * 4 + 0
|
||||
endif
|
||||
endm
|
||||
|
||||
|
||||
LAST equ (4 * (NUM_WORDS - 1))
|
||||
|
||||
CRC_ITER macro qq, nn, iter
|
||||
mov nn, [SRCDAT_4 (NUM_WORDS * (1 + iter))]
|
||||
|
||||
i = 0
|
||||
rept NUM_WORDS - 1
|
||||
CRC_QUAD nn, i, iter
|
||||
i = i + 1
|
||||
endm
|
||||
|
||||
MOVZXLO x6, qq
|
||||
mov x3, qq
|
||||
shr x3, 24
|
||||
CRC_XOR nn, x6, LAST + 3
|
||||
CRC_XOR nn, x3, LAST + 0
|
||||
ror qq, 16
|
||||
MOVZXLO x6, qq
|
||||
shr qq, 24
|
||||
CRC_XOR nn, x6, LAST + 1
|
||||
if ((UNROLL_CNT and 1) eq 1) and (iter eq (UNROLL_CNT - 1))
|
||||
CRC_MOV qq, qq, LAST + 2
|
||||
xor qq, nn
|
||||
else
|
||||
CRC_XOR nn, qq, LAST + 2
|
||||
endif
|
||||
endm
|
||||
|
||||
|
||||
; + 4 for prefetching next 4-bytes after current iteration
|
||||
NUM_BYTES_LIMIT equ (NUM_WORDS * 4 * UNROLL_CNT + 4)
|
||||
ALIGN_MASK equ 3
|
||||
|
||||
|
||||
; MY_PROC @CatStr(CrcUpdateT, 12), 4
|
||||
MY_PROC @CatStr(CrcUpdateT, %(NUM_WORDS * 4)), 4
|
||||
MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11
|
||||
ifdef x64
|
||||
mov x0, REG_ABI_PARAM_0_x ; x0 = x1(win) / x7(linux)
|
||||
mov rT, REG_ABI_PARAM_3 ; r5 = r9(win) / x1(linux)
|
||||
mov rN, REG_ABI_PARAM_2 ; r7 = r8(win) / r2(linux)
|
||||
; mov rD, REG_ABI_PARAM_1 ; r2 = r2(win)
|
||||
if (IS_LINUX gt 0)
|
||||
mov rD, REG_ABI_PARAM_1 ; r2 = r6
|
||||
endif
|
||||
else
|
||||
if (IS_CDECL gt 0)
|
||||
mov x0, [r4 + crc_OFFS]
|
||||
mov rD, [r4 + data_OFFS]
|
||||
else
|
||||
mov x0, REG_ABI_PARAM_0_x
|
||||
endif
|
||||
mov rN, [r4 + size_OFFS]
|
||||
mov rT, [r4 + table_OFFS]
|
||||
endif
|
||||
|
||||
cmp rN, NUM_BYTES_LIMIT + ALIGN_MASK
|
||||
jb crc_end
|
||||
@@:
|
||||
test rD_x, ALIGN_MASK ; test rD, ALIGN_MASK
|
||||
jz @F
|
||||
CRC1b
|
||||
jmp @B
|
||||
@@:
|
||||
xor x0, dword ptr [rD]
|
||||
lea rN, [rD + rN * 1 - (NUM_BYTES_LIMIT - 1)]
|
||||
sub rD, rN
|
||||
|
||||
align 16
|
||||
@@:
|
||||
unr_index = 0
|
||||
while unr_index lt UNROLL_CNT
|
||||
if (unr_index and 1) eq 0
|
||||
CRC_ITER x0, x1, unr_index
|
||||
else
|
||||
CRC_ITER x1, x0, unr_index
|
||||
endif
|
||||
unr_index = unr_index + 1
|
||||
endm
|
||||
|
||||
add rD, NUM_WORDS * 4 * UNROLL_CNT
|
||||
jnc @B
|
||||
|
||||
if 0
|
||||
; byte verson
|
||||
add rD, rN
|
||||
xor x0, dword ptr [rD]
|
||||
add rN, NUM_BYTES_LIMIT - 1
|
||||
else
|
||||
; 4-byte version
|
||||
add rN, 4 * NUM_WORDS * UNROLL_CNT
|
||||
sub rD, 4 * NUM_WORDS * UNROLL_CNT
|
||||
@@:
|
||||
MOVZXLO x3, x0
|
||||
MOVZXHI x1, x0
|
||||
shr x0, 16
|
||||
MOVZXLO x6, x0
|
||||
shr x0, 8
|
||||
CRC_MOV x0, x0, 0
|
||||
CRC_XOR x0, x3, 3
|
||||
CRC_XOR x0, x1, 2
|
||||
CRC_XOR x0, x6, 1
|
||||
|
||||
add rD, 4
|
||||
if (NUM_WORDS * UNROLL_CNT) ne 1
|
||||
jc @F
|
||||
xor x0, [SRCDAT_4 0]
|
||||
jmp @B
|
||||
@@:
|
||||
endif
|
||||
add rD, rN
|
||||
add rN, 4 - 1
|
||||
|
||||
endif
|
||||
|
||||
sub rN, rD
|
||||
crc_end:
|
||||
test rN, rN
|
||||
jz func_end
|
||||
@@:
|
||||
CRC1b
|
||||
jnz @B
|
||||
|
||||
func_end:
|
||||
MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11
|
||||
MY_ENDP
|
||||
|
||||
end
|
||||
742
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/Asm/x86/AesOpt.asm
vendored
Normal file
@@ -0,0 +1,742 @@
|
||||
; AesOpt.asm -- AES optimized code for x86 AES hardware instructions
|
||||
; 2021-12-25 : Igor Pavlov : Public domain
|
||||
|
||||
include 7zAsm.asm
|
||||
|
||||
ifdef __ASMC__
|
||||
use_vaes_256 equ 1
|
||||
else
|
||||
ifdef ymm0
|
||||
use_vaes_256 equ 1
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
ifdef use_vaes_256
|
||||
ECHO "++ VAES 256"
|
||||
else
|
||||
ECHO "-- NO VAES 256"
|
||||
endif
|
||||
|
||||
ifdef x64
|
||||
ECHO "x86-64"
|
||||
else
|
||||
ECHO "x86"
|
||||
if (IS_CDECL gt 0)
|
||||
ECHO "ABI : CDECL"
|
||||
else
|
||||
ECHO "ABI : no CDECL : FASTCALL"
|
||||
endif
|
||||
endif
|
||||
|
||||
if (IS_LINUX gt 0)
|
||||
ECHO "ABI : LINUX"
|
||||
else
|
||||
ECHO "ABI : WINDOWS"
|
||||
endif
|
||||
|
||||
MY_ASM_START
|
||||
|
||||
ifndef x64
|
||||
.686
|
||||
.xmm
|
||||
endif
|
||||
|
||||
|
||||
; MY_ALIGN EQU ALIGN(64)
|
||||
MY_ALIGN EQU
|
||||
|
||||
SEG_ALIGN EQU MY_ALIGN
|
||||
|
||||
MY_SEG_PROC macro name:req, numParams:req
|
||||
; seg_name equ @CatStr(_TEXT$, name)
|
||||
; seg_name SEGMENT SEG_ALIGN 'CODE'
|
||||
MY_PROC name, numParams
|
||||
endm
|
||||
|
||||
MY_SEG_ENDP macro
|
||||
; seg_name ENDS
|
||||
endm
|
||||
|
||||
|
||||
NUM_AES_KEYS_MAX equ 15
|
||||
|
||||
; the number of push operators in function PROLOG
|
||||
if (IS_LINUX eq 0) or (IS_X64 eq 0)
|
||||
num_regs_push equ 2
|
||||
stack_param_offset equ (REG_SIZE * (1 + num_regs_push))
|
||||
endif
|
||||
|
||||
ifdef x64
|
||||
num_param equ REG_ABI_PARAM_2
|
||||
else
|
||||
if (IS_CDECL gt 0)
|
||||
; size_t size
|
||||
; void * data
|
||||
; UInt32 * aes
|
||||
; ret-ip <- (r4)
|
||||
aes_OFFS equ (stack_param_offset)
|
||||
data_OFFS equ (REG_SIZE + aes_OFFS)
|
||||
size_OFFS equ (REG_SIZE + data_OFFS)
|
||||
num_param equ [r4 + size_OFFS]
|
||||
else
|
||||
num_param equ [r4 + stack_param_offset]
|
||||
endif
|
||||
endif
|
||||
|
||||
keys equ REG_PARAM_0 ; r1
|
||||
rD equ REG_PARAM_1 ; r2
|
||||
rN equ r0
|
||||
|
||||
koffs_x equ x7
|
||||
koffs_r equ r7
|
||||
|
||||
ksize_x equ x6
|
||||
ksize_r equ r6
|
||||
|
||||
keys2 equ r3
|
||||
|
||||
state equ xmm0
|
||||
key equ xmm0
|
||||
key_ymm equ ymm0
|
||||
key_ymm_n equ 0
|
||||
|
||||
ifdef x64
|
||||
ways = 11
|
||||
else
|
||||
ways = 4
|
||||
endif
|
||||
|
||||
ways_start_reg equ 1
|
||||
|
||||
iv equ @CatStr(xmm, %(ways_start_reg + ways))
|
||||
iv_ymm equ @CatStr(ymm, %(ways_start_reg + ways))
|
||||
|
||||
|
||||
WOP macro op, op2
|
||||
i = 0
|
||||
rept ways
|
||||
op @CatStr(xmm, %(ways_start_reg + i)), op2
|
||||
i = i + 1
|
||||
endm
|
||||
endm
|
||||
|
||||
|
||||
ifndef ABI_LINUX
|
||||
ifdef x64
|
||||
|
||||
; we use 32 bytes of home space in stack in WIN64-x64
|
||||
NUM_HOME_MM_REGS equ (32 / 16)
|
||||
; we preserve xmm registers starting from xmm6 in WIN64-x64
|
||||
MM_START_SAVE_REG equ 6
|
||||
|
||||
SAVE_XMM macro num_used_mm_regs:req
|
||||
num_save_mm_regs = num_used_mm_regs - MM_START_SAVE_REG
|
||||
if num_save_mm_regs GT 0
|
||||
num_save_mm_regs2 = num_save_mm_regs - NUM_HOME_MM_REGS
|
||||
; RSP is (16*x + 8) after entering the function in WIN64-x64
|
||||
stack_offset = 16 * num_save_mm_regs2 + (stack_param_offset mod 16)
|
||||
|
||||
i = 0
|
||||
rept num_save_mm_regs
|
||||
|
||||
if i eq NUM_HOME_MM_REGS
|
||||
sub r4, stack_offset
|
||||
endif
|
||||
|
||||
if i lt NUM_HOME_MM_REGS
|
||||
movdqa [r4 + stack_param_offset + i * 16], @CatStr(xmm, %(MM_START_SAVE_REG + i))
|
||||
else
|
||||
movdqa [r4 + (i - NUM_HOME_MM_REGS) * 16], @CatStr(xmm, %(MM_START_SAVE_REG + i))
|
||||
endif
|
||||
|
||||
i = i + 1
|
||||
endm
|
||||
endif
|
||||
endm
|
||||
|
||||
RESTORE_XMM macro num_used_mm_regs:req
|
||||
if num_save_mm_regs GT 0
|
||||
i = 0
|
||||
if num_save_mm_regs2 GT 0
|
||||
rept num_save_mm_regs2
|
||||
movdqa @CatStr(xmm, %(MM_START_SAVE_REG + NUM_HOME_MM_REGS + i)), [r4 + i * 16]
|
||||
i = i + 1
|
||||
endm
|
||||
add r4, stack_offset
|
||||
endif
|
||||
|
||||
num_low_regs = num_save_mm_regs - i
|
||||
i = 0
|
||||
rept num_low_regs
|
||||
movdqa @CatStr(xmm, %(MM_START_SAVE_REG + i)), [r4 + stack_param_offset + i * 16]
|
||||
i = i + 1
|
||||
endm
|
||||
endif
|
||||
endm
|
||||
|
||||
endif ; x64
|
||||
endif ; ABI_LINUX
|
||||
|
||||
|
||||
MY_PROLOG macro num_used_mm_regs:req
|
||||
; num_regs_push: must be equal to the number of push operators
|
||||
; push r3
|
||||
; push r5
|
||||
if (IS_LINUX eq 0) or (IS_X64 eq 0)
|
||||
push r6
|
||||
push r7
|
||||
endif
|
||||
|
||||
mov rN, num_param ; don't move it; num_param can use stack pointer (r4)
|
||||
|
||||
if (IS_X64 eq 0)
|
||||
if (IS_CDECL gt 0)
|
||||
mov rD, [r4 + data_OFFS]
|
||||
mov keys, [r4 + aes_OFFS]
|
||||
endif
|
||||
elseif (IS_LINUX gt 0)
|
||||
MY_ABI_LINUX_TO_WIN_2
|
||||
endif
|
||||
|
||||
|
||||
ifndef ABI_LINUX
|
||||
ifdef x64
|
||||
SAVE_XMM num_used_mm_regs
|
||||
endif
|
||||
endif
|
||||
|
||||
mov ksize_x, [keys + 16]
|
||||
shl ksize_x, 5
|
||||
endm
|
||||
|
||||
|
||||
MY_EPILOG macro
|
||||
ifndef ABI_LINUX
|
||||
ifdef x64
|
||||
RESTORE_XMM num_save_mm_regs
|
||||
endif
|
||||
endif
|
||||
|
||||
if (IS_LINUX eq 0) or (IS_X64 eq 0)
|
||||
pop r7
|
||||
pop r6
|
||||
endif
|
||||
; pop r5
|
||||
; pop r3
|
||||
MY_ENDP
|
||||
endm
|
||||
|
||||
|
||||
OP_KEY macro op:req, offs:req
|
||||
op state, [keys + offs]
|
||||
endm
|
||||
|
||||
|
||||
WOP_KEY macro op:req, offs:req
|
||||
movdqa key, [keys + offs]
|
||||
WOP op, key
|
||||
endm
|
||||
|
||||
|
||||
; ---------- AES-CBC Decode ----------
|
||||
|
||||
|
||||
XOR_WITH_DATA macro reg, _ppp_
|
||||
pxor reg, [rD + i * 16]
|
||||
endm
|
||||
|
||||
WRITE_TO_DATA macro reg, _ppp_
|
||||
movdqa [rD + i * 16], reg
|
||||
endm
|
||||
|
||||
|
||||
; state0 equ @CatStr(xmm, %(ways_start_reg))
|
||||
|
||||
key0 equ @CatStr(xmm, %(ways_start_reg + ways + 1))
|
||||
key0_ymm equ @CatStr(ymm, %(ways_start_reg + ways + 1))
|
||||
|
||||
key_last equ @CatStr(xmm, %(ways_start_reg + ways + 2))
|
||||
key_last_ymm equ @CatStr(ymm, %(ways_start_reg + ways + 2))
|
||||
key_last_ymm_n equ (ways_start_reg + ways + 2)
|
||||
|
||||
NUM_CBC_REGS equ (ways_start_reg + ways + 3)
|
||||
|
||||
|
||||
MY_SEG_PROC AesCbc_Decode_HW, 3
|
||||
|
||||
AesCbc_Decode_HW_start::
|
||||
MY_PROLOG NUM_CBC_REGS
|
||||
|
||||
AesCbc_Decode_HW_start_2::
|
||||
movdqa iv, [keys]
|
||||
add keys, 32
|
||||
|
||||
movdqa key0, [keys + 1 * ksize_r]
|
||||
movdqa key_last, [keys]
|
||||
sub ksize_x, 16
|
||||
|
||||
jmp check2
|
||||
align 16
|
||||
nextBlocks2:
|
||||
WOP movdqa, [rD + i * 16]
|
||||
mov koffs_x, ksize_x
|
||||
; WOP_KEY pxor, ksize_r + 16
|
||||
WOP pxor, key0
|
||||
; align 16
|
||||
@@:
|
||||
WOP_KEY aesdec, 1 * koffs_r
|
||||
sub koffs_r, 16
|
||||
jnz @B
|
||||
; WOP_KEY aesdeclast, 0
|
||||
WOP aesdeclast, key_last
|
||||
|
||||
pxor @CatStr(xmm, %(ways_start_reg)), iv
|
||||
i = 1
|
||||
rept ways - 1
|
||||
pxor @CatStr(xmm, %(ways_start_reg + i)), [rD + i * 16 - 16]
|
||||
i = i + 1
|
||||
endm
|
||||
movdqa iv, [rD + ways * 16 - 16]
|
||||
WOP WRITE_TO_DATA
|
||||
|
||||
add rD, ways * 16
|
||||
AesCbc_Decode_HW_start_3::
|
||||
check2:
|
||||
sub rN, ways
|
||||
jnc nextBlocks2
|
||||
add rN, ways
|
||||
|
||||
sub ksize_x, 16
|
||||
|
||||
jmp check
|
||||
nextBlock:
|
||||
movdqa state, [rD]
|
||||
mov koffs_x, ksize_x
|
||||
; OP_KEY pxor, 1 * ksize_r + 32
|
||||
pxor state, key0
|
||||
; movdqa state0, [rD]
|
||||
; movdqa state, key0
|
||||
; pxor state, state0
|
||||
@@:
|
||||
OP_KEY aesdec, 1 * koffs_r + 16
|
||||
OP_KEY aesdec, 1 * koffs_r
|
||||
sub koffs_r, 32
|
||||
jnz @B
|
||||
OP_KEY aesdec, 16
|
||||
; OP_KEY aesdeclast, 0
|
||||
aesdeclast state, key_last
|
||||
|
||||
pxor state, iv
|
||||
movdqa iv, [rD]
|
||||
; movdqa iv, state0
|
||||
movdqa [rD], state
|
||||
|
||||
add rD, 16
|
||||
check:
|
||||
sub rN, 1
|
||||
jnc nextBlock
|
||||
|
||||
movdqa [keys - 32], iv
|
||||
MY_EPILOG
|
||||
|
||||
|
||||
|
||||
|
||||
; ---------- AVX ----------
|
||||
|
||||
|
||||
AVX__WOP_n macro op
|
||||
i = 0
|
||||
rept ways
|
||||
op (ways_start_reg + i)
|
||||
i = i + 1
|
||||
endm
|
||||
endm
|
||||
|
||||
AVX__WOP macro op
|
||||
i = 0
|
||||
rept ways
|
||||
op @CatStr(ymm, %(ways_start_reg + i))
|
||||
i = i + 1
|
||||
endm
|
||||
endm
|
||||
|
||||
|
||||
AVX__WOP_KEY macro op:req, offs:req
|
||||
vmovdqa key_ymm, ymmword ptr [keys2 + offs]
|
||||
AVX__WOP_n op
|
||||
endm
|
||||
|
||||
|
||||
AVX__CBC_START macro reg
|
||||
; vpxor reg, key_ymm, ymmword ptr [rD + 32 * i]
|
||||
vpxor reg, key0_ymm, ymmword ptr [rD + 32 * i]
|
||||
endm
|
||||
|
||||
AVX__CBC_END macro reg
|
||||
if i eq 0
|
||||
vpxor reg, reg, iv_ymm
|
||||
else
|
||||
vpxor reg, reg, ymmword ptr [rD + i * 32 - 16]
|
||||
endif
|
||||
endm
|
||||
|
||||
|
||||
AVX__WRITE_TO_DATA macro reg
|
||||
vmovdqu ymmword ptr [rD + 32 * i], reg
|
||||
endm
|
||||
|
||||
AVX__XOR_WITH_DATA macro reg
|
||||
vpxor reg, reg, ymmword ptr [rD + 32 * i]
|
||||
endm
|
||||
|
||||
AVX__CTR_START macro reg
|
||||
vpaddq iv_ymm, iv_ymm, one_ymm
|
||||
; vpxor reg, iv_ymm, key_ymm
|
||||
vpxor reg, iv_ymm, key0_ymm
|
||||
endm
|
||||
|
||||
|
||||
MY_VAES_INSTR_2 macro cmd, dest, a1, a2
|
||||
db 0c4H
|
||||
db 2 + 040H + 020h * (1 - (a2) / 8) + 080h * (1 - (dest) / 8)
|
||||
db 5 + 8 * ((not (a1)) and 15)
|
||||
db cmd
|
||||
db 0c0H + 8 * ((dest) and 7) + ((a2) and 7)
|
||||
endm
|
||||
|
||||
MY_VAES_INSTR macro cmd, dest, a
|
||||
MY_VAES_INSTR_2 cmd, dest, dest, a
|
||||
endm
|
||||
|
||||
MY_vaesenc macro dest, a
|
||||
MY_VAES_INSTR 0dcH, dest, a
|
||||
endm
|
||||
MY_vaesenclast macro dest, a
|
||||
MY_VAES_INSTR 0ddH, dest, a
|
||||
endm
|
||||
MY_vaesdec macro dest, a
|
||||
MY_VAES_INSTR 0deH, dest, a
|
||||
endm
|
||||
MY_vaesdeclast macro dest, a
|
||||
MY_VAES_INSTR 0dfH, dest, a
|
||||
endm
|
||||
|
||||
|
||||
AVX__VAES_DEC macro reg
|
||||
MY_vaesdec reg, key_ymm_n
|
||||
endm
|
||||
|
||||
AVX__VAES_DEC_LAST_key_last macro reg
|
||||
; MY_vaesdeclast reg, key_ymm_n
|
||||
MY_vaesdeclast reg, key_last_ymm_n
|
||||
endm
|
||||
|
||||
AVX__VAES_ENC macro reg
|
||||
MY_vaesenc reg, key_ymm_n
|
||||
endm
|
||||
|
||||
AVX__VAES_ENC_LAST macro reg
|
||||
MY_vaesenclast reg, key_ymm_n
|
||||
endm
|
||||
|
||||
AVX__vinserti128_TO_HIGH macro dest, src
|
||||
vinserti128 dest, dest, src, 1
|
||||
endm
|
||||
|
||||
|
||||
MY_PROC AesCbc_Decode_HW_256, 3
|
||||
ifdef use_vaes_256
|
||||
MY_PROLOG NUM_CBC_REGS
|
||||
|
||||
cmp rN, ways * 2
|
||||
jb AesCbc_Decode_HW_start_2
|
||||
|
||||
vmovdqa iv, xmmword ptr [keys]
|
||||
add keys, 32
|
||||
|
||||
vbroadcasti128 key0_ymm, xmmword ptr [keys + 1 * ksize_r]
|
||||
vbroadcasti128 key_last_ymm, xmmword ptr [keys]
|
||||
sub ksize_x, 16
|
||||
mov koffs_x, ksize_x
|
||||
add ksize_x, ksize_x
|
||||
|
||||
AVX_STACK_SUB = ((NUM_AES_KEYS_MAX + 1 - 2) * 32)
|
||||
push keys2
|
||||
sub r4, AVX_STACK_SUB
|
||||
; sub r4, 32
|
||||
; sub r4, ksize_r
|
||||
; lea keys2, [r4 + 32]
|
||||
mov keys2, r4
|
||||
and keys2, -32
|
||||
broad:
|
||||
vbroadcasti128 key_ymm, xmmword ptr [keys + 1 * koffs_r]
|
||||
vmovdqa ymmword ptr [keys2 + koffs_r * 2], key_ymm
|
||||
sub koffs_r, 16
|
||||
; jnc broad
|
||||
jnz broad
|
||||
|
||||
sub rN, ways * 2
|
||||
|
||||
align 16
|
||||
avx_cbcdec_nextBlock2:
|
||||
mov koffs_x, ksize_x
|
||||
; AVX__WOP_KEY AVX__CBC_START, 1 * koffs_r + 32
|
||||
AVX__WOP AVX__CBC_START
|
||||
@@:
|
||||
AVX__WOP_KEY AVX__VAES_DEC, 1 * koffs_r
|
||||
sub koffs_r, 32
|
||||
jnz @B
|
||||
; AVX__WOP_KEY AVX__VAES_DEC_LAST, 0
|
||||
AVX__WOP_n AVX__VAES_DEC_LAST_key_last
|
||||
|
||||
AVX__vinserti128_TO_HIGH iv_ymm, xmmword ptr [rD]
|
||||
AVX__WOP AVX__CBC_END
|
||||
|
||||
vmovdqa iv, xmmword ptr [rD + ways * 32 - 16]
|
||||
AVX__WOP AVX__WRITE_TO_DATA
|
||||
|
||||
add rD, ways * 32
|
||||
sub rN, ways * 2
|
||||
jnc avx_cbcdec_nextBlock2
|
||||
add rN, ways * 2
|
||||
|
||||
shr ksize_x, 1
|
||||
|
||||
; lea r4, [r4 + 1 * ksize_r + 32]
|
||||
add r4, AVX_STACK_SUB
|
||||
pop keys2
|
||||
|
||||
vzeroupper
|
||||
jmp AesCbc_Decode_HW_start_3
|
||||
else
|
||||
jmp AesCbc_Decode_HW_start
|
||||
endif
|
||||
MY_ENDP
|
||||
MY_SEG_ENDP
|
||||
|
||||
|
||||
|
||||
|
||||
; ---------- AES-CBC Encode ----------
|
||||
|
||||
e0 equ xmm1
|
||||
|
||||
CENC_START_KEY equ 2
|
||||
CENC_NUM_REG_KEYS equ (3 * 2)
|
||||
; last_key equ @CatStr(xmm, %(CENC_START_KEY + CENC_NUM_REG_KEYS))
|
||||
|
||||
MY_SEG_PROC AesCbc_Encode_HW, 3
|
||||
MY_PROLOG (CENC_START_KEY + CENC_NUM_REG_KEYS + 0)
|
||||
|
||||
movdqa state, [keys]
|
||||
add keys, 32
|
||||
|
||||
i = 0
|
||||
rept CENC_NUM_REG_KEYS
|
||||
movdqa @CatStr(xmm, %(CENC_START_KEY + i)), [keys + i * 16]
|
||||
i = i + 1
|
||||
endm
|
||||
|
||||
add keys, ksize_r
|
||||
neg ksize_r
|
||||
add ksize_r, (16 * CENC_NUM_REG_KEYS)
|
||||
; movdqa last_key, [keys]
|
||||
jmp check_e
|
||||
|
||||
align 16
|
||||
nextBlock_e:
|
||||
movdqa e0, [rD]
|
||||
mov koffs_r, ksize_r
|
||||
pxor e0, @CatStr(xmm, %(CENC_START_KEY))
|
||||
pxor state, e0
|
||||
|
||||
i = 1
|
||||
rept (CENC_NUM_REG_KEYS - 1)
|
||||
aesenc state, @CatStr(xmm, %(CENC_START_KEY + i))
|
||||
i = i + 1
|
||||
endm
|
||||
|
||||
@@:
|
||||
OP_KEY aesenc, 1 * koffs_r
|
||||
OP_KEY aesenc, 1 * koffs_r + 16
|
||||
add koffs_r, 32
|
||||
jnz @B
|
||||
OP_KEY aesenclast, 0
|
||||
; aesenclast state, last_key
|
||||
|
||||
movdqa [rD], state
|
||||
add rD, 16
|
||||
check_e:
|
||||
sub rN, 1
|
||||
jnc nextBlock_e
|
||||
|
||||
; movdqa [keys - 32], state
|
||||
movdqa [keys + 1 * ksize_r - (16 * CENC_NUM_REG_KEYS) - 32], state
|
||||
MY_EPILOG
|
||||
MY_SEG_ENDP
|
||||
|
||||
|
||||
|
||||
; ---------- AES-CTR ----------
|
||||
|
||||
ifdef x64
|
||||
; ways = 11
|
||||
endif
|
||||
|
||||
|
||||
one equ @CatStr(xmm, %(ways_start_reg + ways + 1))
|
||||
one_ymm equ @CatStr(ymm, %(ways_start_reg + ways + 1))
|
||||
key0 equ @CatStr(xmm, %(ways_start_reg + ways + 2))
|
||||
key0_ymm equ @CatStr(ymm, %(ways_start_reg + ways + 2))
|
||||
NUM_CTR_REGS equ (ways_start_reg + ways + 3)
|
||||
|
||||
INIT_CTR macro reg, _ppp_
|
||||
paddq iv, one
|
||||
movdqa reg, iv
|
||||
endm
|
||||
|
||||
|
||||
MY_SEG_PROC AesCtr_Code_HW, 3
|
||||
Ctr_start::
|
||||
MY_PROLOG NUM_CTR_REGS
|
||||
|
||||
Ctr_start_2::
|
||||
movdqa iv, [keys]
|
||||
add keys, 32
|
||||
movdqa key0, [keys]
|
||||
|
||||
add keys, ksize_r
|
||||
neg ksize_r
|
||||
add ksize_r, 16
|
||||
|
||||
Ctr_start_3::
|
||||
mov koffs_x, 1
|
||||
movd one, koffs_x
|
||||
jmp check2_c
|
||||
|
||||
align 16
|
||||
nextBlocks2_c:
|
||||
WOP INIT_CTR, 0
|
||||
mov koffs_r, ksize_r
|
||||
; WOP_KEY pxor, 1 * koffs_r -16
|
||||
WOP pxor, key0
|
||||
@@:
|
||||
WOP_KEY aesenc, 1 * koffs_r
|
||||
add koffs_r, 16
|
||||
jnz @B
|
||||
WOP_KEY aesenclast, 0
|
||||
|
||||
WOP XOR_WITH_DATA
|
||||
WOP WRITE_TO_DATA
|
||||
add rD, ways * 16
|
||||
check2_c:
|
||||
sub rN, ways
|
||||
jnc nextBlocks2_c
|
||||
add rN, ways
|
||||
|
||||
sub keys, 16
|
||||
add ksize_r, 16
|
||||
|
||||
jmp check_c
|
||||
|
||||
; align 16
|
||||
nextBlock_c:
|
||||
paddq iv, one
|
||||
; movdqa state, [keys + 1 * koffs_r - 16]
|
||||
movdqa state, key0
|
||||
mov koffs_r, ksize_r
|
||||
pxor state, iv
|
||||
|
||||
@@:
|
||||
OP_KEY aesenc, 1 * koffs_r
|
||||
OP_KEY aesenc, 1 * koffs_r + 16
|
||||
add koffs_r, 32
|
||||
jnz @B
|
||||
OP_KEY aesenc, 0
|
||||
OP_KEY aesenclast, 16
|
||||
|
||||
pxor state, [rD]
|
||||
movdqa [rD], state
|
||||
add rD, 16
|
||||
check_c:
|
||||
sub rN, 1
|
||||
jnc nextBlock_c
|
||||
|
||||
; movdqa [keys - 32], iv
|
||||
movdqa [keys + 1 * ksize_r - 16 - 32], iv
|
||||
MY_EPILOG
|
||||
|
||||
|
||||
MY_PROC AesCtr_Code_HW_256, 3
|
||||
ifdef use_vaes_256
|
||||
MY_PROLOG NUM_CTR_REGS
|
||||
|
||||
cmp rN, ways * 2
|
||||
jb Ctr_start_2
|
||||
|
||||
vbroadcasti128 iv_ymm, xmmword ptr [keys]
|
||||
add keys, 32
|
||||
vbroadcasti128 key0_ymm, xmmword ptr [keys]
|
||||
mov koffs_x, 1
|
||||
vmovd one, koffs_x
|
||||
vpsubq iv_ymm, iv_ymm, one_ymm
|
||||
vpaddq one, one, one
|
||||
AVX__vinserti128_TO_HIGH one_ymm, one
|
||||
|
||||
add keys, ksize_r
|
||||
sub ksize_x, 16
|
||||
neg ksize_r
|
||||
mov koffs_r, ksize_r
|
||||
add ksize_r, ksize_r
|
||||
|
||||
AVX_STACK_SUB = ((NUM_AES_KEYS_MAX + 1 - 1) * 32)
|
||||
push keys2
|
||||
lea keys2, [r4 - 32]
|
||||
sub r4, AVX_STACK_SUB
|
||||
and keys2, -32
|
||||
vbroadcasti128 key_ymm, xmmword ptr [keys]
|
||||
vmovdqa ymmword ptr [keys2], key_ymm
|
||||
@@:
|
||||
vbroadcasti128 key_ymm, xmmword ptr [keys + 1 * koffs_r]
|
||||
vmovdqa ymmword ptr [keys2 + koffs_r * 2], key_ymm
|
||||
add koffs_r, 16
|
||||
jnz @B
|
||||
|
||||
sub rN, ways * 2
|
||||
|
||||
align 16
|
||||
avx_ctr_nextBlock2:
|
||||
mov koffs_r, ksize_r
|
||||
AVX__WOP AVX__CTR_START
|
||||
; AVX__WOP_KEY AVX__CTR_START, 1 * koffs_r - 32
|
||||
@@:
|
||||
AVX__WOP_KEY AVX__VAES_ENC, 1 * koffs_r
|
||||
add koffs_r, 32
|
||||
jnz @B
|
||||
AVX__WOP_KEY AVX__VAES_ENC_LAST, 0
|
||||
|
||||
AVX__WOP AVX__XOR_WITH_DATA
|
||||
AVX__WOP AVX__WRITE_TO_DATA
|
||||
|
||||
add rD, ways * 32
|
||||
sub rN, ways * 2
|
||||
jnc avx_ctr_nextBlock2
|
||||
add rN, ways * 2
|
||||
|
||||
vextracti128 iv, iv_ymm, 1
|
||||
sar ksize_r, 1
|
||||
|
||||
add r4, AVX_STACK_SUB
|
||||
pop keys2
|
||||
|
||||
vzeroupper
|
||||
jmp Ctr_start_3
|
||||
else
|
||||
jmp Ctr_start
|
||||
endif
|
||||
MY_ENDP
|
||||
MY_SEG_ENDP
|
||||
|
||||
end
|
||||
540
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/Asm/x86/LzFindOpt.asm
vendored
Normal file
@@ -0,0 +1,540 @@
|
||||
; LzFindOpt.asm -- ASM version of GetMatchesSpecN_2() function
|
||||
; 2024-06-18: Igor Pavlov : Public domain
|
||||
;
|
||||
|
||||
ifndef x64
|
||||
; x64=1
|
||||
; .err <x64_IS_REQUIRED>
|
||||
endif
|
||||
|
||||
include 7zAsm.asm
|
||||
|
||||
MY_ASM_START
|
||||
|
||||
ifndef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT
|
||||
if (IS_LINUX gt 0)
|
||||
Z7_LZ_FIND_OPT_ASM_USE_SEGMENT equ 1
|
||||
else
|
||||
Z7_LZ_FIND_OPT_ASM_USE_SEGMENT equ 1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT
|
||||
_TEXT$LZFINDOPT SEGMENT ALIGN(64) 'CODE'
|
||||
MY_ALIGN macro num:req
|
||||
align num
|
||||
; align 16
|
||||
endm
|
||||
else
|
||||
MY_ALIGN macro num:req
|
||||
; We expect that ".text" is aligned for 16-bytes.
|
||||
; So we don't need large alignment inside our function.
|
||||
align 16
|
||||
endm
|
||||
endif
|
||||
|
||||
|
||||
MY_ALIGN_16 macro
|
||||
MY_ALIGN 16
|
||||
endm
|
||||
|
||||
MY_ALIGN_32 macro
|
||||
MY_ALIGN 32
|
||||
endm
|
||||
|
||||
MY_ALIGN_64 macro
|
||||
MY_ALIGN 64
|
||||
endm
|
||||
|
||||
|
||||
t0_L equ x0_L
|
||||
t0_x equ x0
|
||||
t0 equ r0
|
||||
t1_x equ x3
|
||||
t1 equ r3
|
||||
|
||||
cp_x equ t1_x
|
||||
cp_r equ t1
|
||||
m equ x5
|
||||
m_r equ r5
|
||||
len_x equ x6
|
||||
len equ r6
|
||||
diff_x equ x7
|
||||
diff equ r7
|
||||
len0 equ r10
|
||||
len1_x equ x11
|
||||
len1 equ r11
|
||||
maxLen_x equ x12
|
||||
maxLen equ r12
|
||||
d equ r13
|
||||
ptr0 equ r14
|
||||
ptr1 equ r15
|
||||
|
||||
d_lim equ m_r
|
||||
cycSize equ len_x
|
||||
hash_lim equ len0
|
||||
delta1_x equ len1_x
|
||||
delta1_r equ len1
|
||||
delta_x equ maxLen_x
|
||||
delta_r equ maxLen
|
||||
hash equ ptr0
|
||||
src equ ptr1
|
||||
|
||||
|
||||
|
||||
if (IS_LINUX gt 0)
|
||||
|
||||
; r1 r2 r8 r9 : win32
|
||||
; r7 r6 r2 r1 r8 r9 : linux
|
||||
|
||||
lenLimit equ r8
|
||||
lenLimit_x equ x8
|
||||
; pos_r equ r2
|
||||
pos equ x2
|
||||
cur equ r1
|
||||
son equ r9
|
||||
|
||||
else
|
||||
|
||||
lenLimit equ REG_ABI_PARAM_2
|
||||
lenLimit_x equ REG_ABI_PARAM_2_x
|
||||
pos equ REG_ABI_PARAM_1_x
|
||||
cur equ REG_ABI_PARAM_0
|
||||
son equ REG_ABI_PARAM_3
|
||||
|
||||
endif
|
||||
|
||||
|
||||
if (IS_LINUX gt 0)
|
||||
maxLen_OFFS equ (REG_SIZE * (6 + 1))
|
||||
else
|
||||
cutValue_OFFS equ (REG_SIZE * (8 + 1 + 4))
|
||||
d_OFFS equ (REG_SIZE + cutValue_OFFS)
|
||||
maxLen_OFFS equ (REG_SIZE + d_OFFS)
|
||||
endif
|
||||
hash_OFFS equ (REG_SIZE + maxLen_OFFS)
|
||||
limit_OFFS equ (REG_SIZE + hash_OFFS)
|
||||
size_OFFS equ (REG_SIZE + limit_OFFS)
|
||||
cycPos_OFFS equ (REG_SIZE + size_OFFS)
|
||||
cycSize_OFFS equ (REG_SIZE + cycPos_OFFS)
|
||||
posRes_OFFS equ (REG_SIZE + cycSize_OFFS)
|
||||
|
||||
if (IS_LINUX gt 0)
|
||||
else
|
||||
cutValue_PAR equ [r0 + cutValue_OFFS]
|
||||
d_PAR equ [r0 + d_OFFS]
|
||||
endif
|
||||
maxLen_PAR equ [r0 + maxLen_OFFS]
|
||||
hash_PAR equ [r0 + hash_OFFS]
|
||||
limit_PAR equ [r0 + limit_OFFS]
|
||||
size_PAR equ [r0 + size_OFFS]
|
||||
cycPos_PAR equ [r0 + cycPos_OFFS]
|
||||
cycSize_PAR equ [r0 + cycSize_OFFS]
|
||||
posRes_PAR equ [r0 + posRes_OFFS]
|
||||
|
||||
|
||||
cutValue_VAR equ DWORD PTR [r4 + 8 * 0]
|
||||
cutValueCur_VAR equ DWORD PTR [r4 + 8 * 0 + 4]
|
||||
cycPos_VAR equ DWORD PTR [r4 + 8 * 1 + 0]
|
||||
cycSize_VAR equ DWORD PTR [r4 + 8 * 1 + 4]
|
||||
hash_VAR equ QWORD PTR [r4 + 8 * 2]
|
||||
limit_VAR equ QWORD PTR [r4 + 8 * 3]
|
||||
size_VAR equ QWORD PTR [r4 + 8 * 4]
|
||||
distances equ QWORD PTR [r4 + 8 * 5]
|
||||
maxLen_VAR equ QWORD PTR [r4 + 8 * 6]
|
||||
|
||||
Old_RSP equ QWORD PTR [r4 + 8 * 7]
|
||||
LOCAL_SIZE equ 8 * 8
|
||||
|
||||
COPY_VAR_32 macro dest_var, src_var
|
||||
mov x3, src_var
|
||||
mov dest_var, x3
|
||||
endm
|
||||
|
||||
COPY_VAR_64 macro dest_var, src_var
|
||||
mov r3, src_var
|
||||
mov dest_var, r3
|
||||
endm
|
||||
|
||||
|
||||
ifdef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT
|
||||
; MY_ALIGN_64
|
||||
else
|
||||
MY_ALIGN_16
|
||||
endif
|
||||
MY_PROC GetMatchesSpecN_2, 13
|
||||
MY_PUSH_PRESERVED_ABI_REGS
|
||||
mov r0, RSP
|
||||
lea r3, [r0 - LOCAL_SIZE]
|
||||
and r3, -64
|
||||
mov RSP, r3
|
||||
mov Old_RSP, r0
|
||||
|
||||
if (IS_LINUX gt 0)
|
||||
mov d, REG_ABI_PARAM_5 ; r13 = r9
|
||||
mov cutValue_VAR, REG_ABI_PARAM_4_x ; = r8
|
||||
mov son, REG_ABI_PARAM_3 ; r9 = r1
|
||||
mov r8, REG_ABI_PARAM_2 ; r8 = r2
|
||||
mov pos, REG_ABI_PARAM_1_x ; r2 = x6
|
||||
mov r1, REG_ABI_PARAM_0 ; r1 = r7
|
||||
else
|
||||
COPY_VAR_32 cutValue_VAR, cutValue_PAR
|
||||
mov d, d_PAR
|
||||
endif
|
||||
|
||||
COPY_VAR_64 limit_VAR, limit_PAR
|
||||
|
||||
mov hash_lim, size_PAR
|
||||
mov size_VAR, hash_lim
|
||||
|
||||
mov cp_x, cycPos_PAR
|
||||
mov hash, hash_PAR
|
||||
|
||||
mov cycSize, cycSize_PAR
|
||||
mov cycSize_VAR, cycSize
|
||||
|
||||
; we want cur in (rcx). So we change the cur and lenLimit variables
|
||||
sub lenLimit, cur
|
||||
neg lenLimit_x
|
||||
inc lenLimit_x
|
||||
|
||||
mov t0_x, maxLen_PAR
|
||||
sub t0, lenLimit
|
||||
mov maxLen_VAR, t0
|
||||
|
||||
jmp main_loop
|
||||
|
||||
MY_ALIGN_64
|
||||
fill_empty:
|
||||
; ptr0 = *ptr1 = kEmptyHashValue;
|
||||
mov QWORD PTR [ptr1], 0
|
||||
inc pos
|
||||
inc cp_x
|
||||
mov DWORD PTR [d - 4], 0
|
||||
cmp d, limit_VAR
|
||||
jae fin
|
||||
cmp hash, hash_lim
|
||||
je fin
|
||||
|
||||
; MY_ALIGN_64
|
||||
main_loop:
|
||||
; UInt32 delta = *hash++;
|
||||
mov diff_x, [hash] ; delta
|
||||
add hash, 4
|
||||
; mov cycPos_VAR, cp_x
|
||||
|
||||
inc cur
|
||||
add d, 4
|
||||
mov m, pos
|
||||
sub m, diff_x; ; matchPos
|
||||
|
||||
; CLzRef *ptr1 = son + ((size_t)(pos) << 1) - CYC_TO_POS_OFFSET * 2;
|
||||
lea ptr1, [son + 8 * cp_r]
|
||||
; mov cycSize, cycSize_VAR
|
||||
cmp pos, cycSize
|
||||
jb directMode ; if (pos < cycSize_VAR)
|
||||
|
||||
; CYC MODE
|
||||
|
||||
cmp diff_x, cycSize
|
||||
jae fill_empty ; if (delta >= cycSize_VAR)
|
||||
|
||||
xor t0_x, t0_x
|
||||
mov cycPos_VAR, cp_x
|
||||
sub cp_x, diff_x
|
||||
; jae prepare_for_tree_loop
|
||||
; add cp_x, cycSize
|
||||
cmovb t0_x, cycSize
|
||||
add cp_x, t0_x ; cp_x += (cycPos < delta ? cycSize : 0)
|
||||
jmp prepare_for_tree_loop
|
||||
|
||||
|
||||
directMode:
|
||||
cmp diff_x, pos
|
||||
je fill_empty ; if (delta == pos)
|
||||
jae fin_error ; if (delta >= pos)
|
||||
|
||||
mov cycPos_VAR, cp_x
|
||||
mov cp_x, m
|
||||
|
||||
prepare_for_tree_loop:
|
||||
mov len0, lenLimit
|
||||
mov hash_VAR, hash
|
||||
; CLzRef *ptr0 = son + ((size_t)(pos) << 1) - CYC_TO_POS_OFFSET * 2 + 1;
|
||||
lea ptr0, [ptr1 + 4]
|
||||
; UInt32 *_distances = ++d;
|
||||
mov distances, d
|
||||
|
||||
neg len0
|
||||
mov len1, len0
|
||||
|
||||
mov t0_x, cutValue_VAR
|
||||
mov maxLen, maxLen_VAR
|
||||
mov cutValueCur_VAR, t0_x
|
||||
|
||||
MY_ALIGN_32
|
||||
tree_loop:
|
||||
neg diff
|
||||
mov len, len0
|
||||
cmp len1, len0
|
||||
cmovb len, len1 ; len = (len1 < len0 ? len1 : len0);
|
||||
add diff, cur
|
||||
|
||||
mov t0_x, [son + cp_r * 8] ; prefetch
|
||||
movzx t0_x, BYTE PTR [diff + 1 * len]
|
||||
lea cp_r, [son + cp_r * 8]
|
||||
cmp [cur + 1 * len], t0_L
|
||||
je matched_1
|
||||
|
||||
jb left_0
|
||||
|
||||
mov [ptr1], m
|
||||
mov m, [cp_r + 4]
|
||||
lea ptr1, [cp_r + 4]
|
||||
sub diff, cur ; FIX32
|
||||
jmp next_node
|
||||
|
||||
MY_ALIGN_32
|
||||
left_0:
|
||||
mov [ptr0], m
|
||||
mov m, [cp_r]
|
||||
mov ptr0, cp_r
|
||||
sub diff, cur ; FIX32
|
||||
; jmp next_node
|
||||
|
||||
; ------------ NEXT NODE ------------
|
||||
; MY_ALIGN_32
|
||||
next_node:
|
||||
mov cycSize, cycSize_VAR
|
||||
dec cutValueCur_VAR
|
||||
je finish_tree
|
||||
|
||||
add diff_x, pos ; prev_match = pos + diff
|
||||
cmp m, diff_x
|
||||
jae fin_error ; if (new_match >= prev_match)
|
||||
|
||||
mov diff_x, pos
|
||||
sub diff_x, m ; delta = pos - new_match
|
||||
cmp pos, cycSize
|
||||
jae cyc_mode_2 ; if (pos >= cycSize)
|
||||
|
||||
mov cp_x, m
|
||||
test m, m
|
||||
jne tree_loop ; if (m != 0)
|
||||
|
||||
finish_tree:
|
||||
; ptr0 = *ptr1 = kEmptyHashValue;
|
||||
mov DWORD PTR [ptr0], 0
|
||||
mov DWORD PTR [ptr1], 0
|
||||
|
||||
inc pos
|
||||
|
||||
; _distances[-1] = (UInt32)(d - _distances);
|
||||
mov t0, distances
|
||||
mov t1, d
|
||||
sub t1, t0
|
||||
shr t1_x, 2
|
||||
mov [t0 - 4], t1_x
|
||||
|
||||
cmp d, limit_VAR
|
||||
jae fin ; if (d >= limit)
|
||||
|
||||
mov cp_x, cycPos_VAR
|
||||
mov hash, hash_VAR
|
||||
mov hash_lim, size_VAR
|
||||
inc cp_x
|
||||
cmp hash, hash_lim
|
||||
jne main_loop ; if (hash != size)
|
||||
jmp fin
|
||||
|
||||
|
||||
MY_ALIGN_32
|
||||
cyc_mode_2:
|
||||
cmp diff_x, cycSize
|
||||
jae finish_tree ; if (delta >= cycSize)
|
||||
|
||||
mov cp_x, cycPos_VAR
|
||||
xor t0_x, t0_x
|
||||
sub cp_x, diff_x ; cp_x = cycPos - delta
|
||||
cmovb t0_x, cycSize
|
||||
add cp_x, t0_x ; cp_x += (cycPos < delta ? cycSize : 0)
|
||||
jmp tree_loop
|
||||
|
||||
|
||||
MY_ALIGN_32
|
||||
matched_1:
|
||||
|
||||
inc len
|
||||
; cmp len_x, lenLimit_x
|
||||
je short lenLimit_reach
|
||||
movzx t0_x, BYTE PTR [diff + 1 * len]
|
||||
cmp [cur + 1 * len], t0_L
|
||||
jne mismatch
|
||||
|
||||
|
||||
MY_ALIGN_32
|
||||
match_loop:
|
||||
; while (++len != lenLimit) (len[diff] != len[0]) ;
|
||||
|
||||
inc len
|
||||
; cmp len_x, lenLimit_x
|
||||
je short lenLimit_reach
|
||||
movzx t0_x, BYTE PTR [diff + 1 * len]
|
||||
cmp BYTE PTR [cur + 1 * len], t0_L
|
||||
je match_loop
|
||||
|
||||
mismatch:
|
||||
jb left_2
|
||||
|
||||
mov [ptr1], m
|
||||
mov m, [cp_r + 4]
|
||||
lea ptr1, [cp_r + 4]
|
||||
mov len1, len
|
||||
|
||||
jmp max_update
|
||||
|
||||
MY_ALIGN_32
|
||||
left_2:
|
||||
mov [ptr0], m
|
||||
mov m, [cp_r]
|
||||
mov ptr0, cp_r
|
||||
mov len0, len
|
||||
|
||||
max_update:
|
||||
sub diff, cur ; restore diff
|
||||
|
||||
cmp maxLen, len
|
||||
jae next_node
|
||||
|
||||
mov maxLen, len
|
||||
add len, lenLimit
|
||||
mov [d], len_x
|
||||
mov t0_x, diff_x
|
||||
not t0_x
|
||||
mov [d + 4], t0_x
|
||||
add d, 8
|
||||
|
||||
jmp next_node
|
||||
|
||||
|
||||
|
||||
MY_ALIGN_32
|
||||
lenLimit_reach:
|
||||
|
||||
mov delta_r, cur
|
||||
sub delta_r, diff
|
||||
lea delta1_r, [delta_r - 1]
|
||||
|
||||
mov t0_x, [cp_r]
|
||||
mov [ptr1], t0_x
|
||||
mov t0_x, [cp_r + 4]
|
||||
mov [ptr0], t0_x
|
||||
|
||||
mov [d], lenLimit_x
|
||||
mov [d + 4], delta1_x
|
||||
add d, 8
|
||||
|
||||
; _distances[-1] = (UInt32)(d - _distances);
|
||||
mov t0, distances
|
||||
mov t1, d
|
||||
sub t1, t0
|
||||
shr t1_x, 2
|
||||
mov [t0 - 4], t1_x
|
||||
|
||||
mov hash, hash_VAR
|
||||
mov hash_lim, size_VAR
|
||||
|
||||
inc pos
|
||||
mov cp_x, cycPos_VAR
|
||||
inc cp_x
|
||||
|
||||
mov d_lim, limit_VAR
|
||||
mov cycSize, cycSize_VAR
|
||||
; if (hash == size || *hash != delta || lenLimit[diff] != lenLimit[0] || d >= limit)
|
||||
; break;
|
||||
cmp hash, hash_lim
|
||||
je fin
|
||||
cmp d, d_lim
|
||||
jae fin
|
||||
cmp delta_x, [hash]
|
||||
jne main_loop
|
||||
movzx t0_x, BYTE PTR [diff]
|
||||
cmp [cur], t0_L
|
||||
jne main_loop
|
||||
|
||||
; jmp main_loop ; bypass for debug
|
||||
|
||||
mov cycPos_VAR, cp_x
|
||||
shl len, 3 ; cycSize * 8
|
||||
sub diff, cur ; restore diff
|
||||
xor t0_x, t0_x
|
||||
cmp cp_x, delta_x ; cmp (cycPos_VAR, delta)
|
||||
lea cp_r, [son + 8 * cp_r] ; dest
|
||||
lea src, [cp_r + 8 * diff]
|
||||
cmovb t0, len ; t0 = (cycPos_VAR < delta ? cycSize * 8 : 0)
|
||||
add src, t0
|
||||
add len, son ; len = son + cycSize * 8
|
||||
|
||||
|
||||
MY_ALIGN_32
|
||||
long_loop:
|
||||
add hash, 4
|
||||
|
||||
; *(UInt64 *)(void *)ptr = ((const UInt64 *)(const void *)ptr)[diff];
|
||||
|
||||
mov t0, [src]
|
||||
add src, 8
|
||||
mov [cp_r], t0
|
||||
add cp_r, 8
|
||||
cmp src, len
|
||||
cmove src, son ; if end of (son) buffer is reached, we wrap to begin
|
||||
|
||||
mov DWORD PTR [d], 2
|
||||
mov [d + 4], lenLimit_x
|
||||
mov [d + 8], delta1_x
|
||||
add d, 12
|
||||
|
||||
inc cur
|
||||
|
||||
cmp hash, hash_lim
|
||||
je long_footer
|
||||
cmp delta_x, [hash]
|
||||
jne long_footer
|
||||
movzx t0_x, BYTE PTR [diff + 1 * cur]
|
||||
cmp [cur], t0_L
|
||||
jne long_footer
|
||||
cmp d, d_lim
|
||||
jb long_loop
|
||||
|
||||
long_footer:
|
||||
sub cp_r, son
|
||||
shr cp_r, 3
|
||||
add pos, cp_x
|
||||
sub pos, cycPos_VAR
|
||||
mov cycSize, cycSize_VAR
|
||||
|
||||
cmp d, d_lim
|
||||
jae fin
|
||||
cmp hash, hash_lim
|
||||
jne main_loop
|
||||
jmp fin
|
||||
|
||||
|
||||
|
||||
fin_error:
|
||||
xor d, d
|
||||
|
||||
fin:
|
||||
mov RSP, Old_RSP
|
||||
mov t0, [r4 + posRes_OFFS]
|
||||
mov [t0], pos
|
||||
mov r0, d
|
||||
|
||||
MY_POP_PRESERVED_ABI_REGS
|
||||
MY_ENDP
|
||||
|
||||
ifdef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT
|
||||
_TEXT$LZFINDOPT ENDS
|
||||
endif
|
||||
|
||||
end
|
||||
1339
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/Asm/x86/LzmaDecOpt.asm
vendored
Normal file
263
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/Asm/x86/Sha1Opt.asm
vendored
Normal file
@@ -0,0 +1,263 @@
|
||||
; Sha1Opt.asm -- SHA-1 optimized code for SHA-1 x86 hardware instructions
|
||||
; 2024-06-16 : Igor Pavlov : Public domain
|
||||
|
||||
include 7zAsm.asm
|
||||
|
||||
MY_ASM_START
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
CONST SEGMENT READONLY
|
||||
|
||||
align 16
|
||||
Reverse_Endian_Mask db 15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
CONST ENDS
|
||||
|
||||
; _TEXT$SHA1OPT SEGMENT 'CODE'
|
||||
|
||||
ifndef x64
|
||||
.686
|
||||
.xmm
|
||||
endif
|
||||
|
||||
ifdef x64
|
||||
rNum equ REG_ABI_PARAM_2
|
||||
if (IS_LINUX eq 0)
|
||||
LOCAL_SIZE equ (16 * 2)
|
||||
endif
|
||||
else
|
||||
rNum equ r0
|
||||
LOCAL_SIZE equ (16 * 1)
|
||||
endif
|
||||
|
||||
rState equ REG_ABI_PARAM_0
|
||||
rData equ REG_ABI_PARAM_1
|
||||
|
||||
|
||||
MY_sha1rnds4 macro a1, a2, imm
|
||||
db 0fH, 03aH, 0ccH, (0c0H + a1 * 8 + a2), imm
|
||||
endm
|
||||
|
||||
MY_SHA_INSTR macro cmd, a1, a2
|
||||
db 0fH, 038H, cmd, (0c0H + a1 * 8 + a2)
|
||||
endm
|
||||
|
||||
cmd_sha1nexte equ 0c8H
|
||||
cmd_sha1msg1 equ 0c9H
|
||||
cmd_sha1msg2 equ 0caH
|
||||
|
||||
MY_sha1nexte macro a1, a2
|
||||
MY_SHA_INSTR cmd_sha1nexte, a1, a2
|
||||
endm
|
||||
|
||||
MY_sha1msg1 macro a1, a2
|
||||
MY_SHA_INSTR cmd_sha1msg1, a1, a2
|
||||
endm
|
||||
|
||||
MY_sha1msg2 macro a1, a2
|
||||
MY_SHA_INSTR cmd_sha1msg2, a1, a2
|
||||
endm
|
||||
|
||||
MY_PROLOG macro
|
||||
ifdef x64
|
||||
if (IS_LINUX eq 0)
|
||||
movdqa [r4 + 8], xmm6
|
||||
movdqa [r4 + 8 + 16], xmm7
|
||||
sub r4, LOCAL_SIZE + 8
|
||||
movdqa [r4 ], xmm8
|
||||
movdqa [r4 + 16], xmm9
|
||||
endif
|
||||
else ; x86
|
||||
if (IS_CDECL gt 0)
|
||||
mov rState, [r4 + REG_SIZE * 1]
|
||||
mov rData, [r4 + REG_SIZE * 2]
|
||||
mov rNum, [r4 + REG_SIZE * 3]
|
||||
else ; fastcall
|
||||
mov rNum, [r4 + REG_SIZE * 1]
|
||||
endif
|
||||
push r5
|
||||
mov r5, r4
|
||||
and r4, -16
|
||||
sub r4, LOCAL_SIZE
|
||||
endif
|
||||
endm
|
||||
|
||||
MY_EPILOG macro
|
||||
ifdef x64
|
||||
if (IS_LINUX eq 0)
|
||||
movdqa xmm8, [r4]
|
||||
movdqa xmm9, [r4 + 16]
|
||||
add r4, LOCAL_SIZE + 8
|
||||
movdqa xmm6, [r4 + 8]
|
||||
movdqa xmm7, [r4 + 8 + 16]
|
||||
endif
|
||||
else ; x86
|
||||
mov r4, r5
|
||||
pop r5
|
||||
endif
|
||||
MY_ENDP
|
||||
endm
|
||||
|
||||
|
||||
e0_N equ 0
|
||||
e1_N equ 1
|
||||
abcd_N equ 2
|
||||
e0_save_N equ 3
|
||||
w_regs equ 4
|
||||
|
||||
e0 equ @CatStr(xmm, %e0_N)
|
||||
e1 equ @CatStr(xmm, %e1_N)
|
||||
abcd equ @CatStr(xmm, %abcd_N)
|
||||
e0_save equ @CatStr(xmm, %e0_save_N)
|
||||
|
||||
|
||||
ifdef x64
|
||||
abcd_save equ xmm8
|
||||
mask2 equ xmm9
|
||||
else
|
||||
abcd_save equ [r4]
|
||||
mask2 equ e1
|
||||
endif
|
||||
|
||||
LOAD_MASK macro
|
||||
movdqa mask2, XMMWORD PTR Reverse_Endian_Mask
|
||||
endm
|
||||
|
||||
LOAD_W macro k:req
|
||||
movdqu @CatStr(xmm, %(w_regs + k)), [rData + (16 * (k))]
|
||||
pshufb @CatStr(xmm, %(w_regs + k)), mask2
|
||||
endm
|
||||
|
||||
|
||||
; pre2 can be 2 or 3 (recommended)
|
||||
pre2 equ 3
|
||||
pre1 equ (pre2 + 1)
|
||||
|
||||
NUM_ROUNDS4 equ 20
|
||||
|
||||
RND4 macro k
|
||||
movdqa @CatStr(xmm, %(e0_N + ((k + 1) mod 2))), abcd
|
||||
MY_sha1rnds4 abcd_N, (e0_N + (k mod 2)), k / 5
|
||||
|
||||
nextM = (w_regs + ((k + 1) mod 4))
|
||||
|
||||
if (k EQ NUM_ROUNDS4 - 1)
|
||||
nextM = e0_save_N
|
||||
endif
|
||||
|
||||
MY_sha1nexte (e0_N + ((k + 1) mod 2)), nextM
|
||||
|
||||
if (k GE (4 - pre2)) AND (k LT (NUM_ROUNDS4 - pre2))
|
||||
pxor @CatStr(xmm, %(w_regs + ((k + pre2) mod 4))), @CatStr(xmm, %(w_regs + ((k + pre2 - 2) mod 4)))
|
||||
endif
|
||||
|
||||
if (k GE (4 - pre1)) AND (k LT (NUM_ROUNDS4 - pre1))
|
||||
MY_sha1msg1 (w_regs + ((k + pre1) mod 4)), (w_regs + ((k + pre1 - 3) mod 4))
|
||||
endif
|
||||
|
||||
if (k GE (4 - pre2)) AND (k LT (NUM_ROUNDS4 - pre2))
|
||||
MY_sha1msg2 (w_regs + ((k + pre2) mod 4)), (w_regs + ((k + pre2 - 1) mod 4))
|
||||
endif
|
||||
endm
|
||||
|
||||
|
||||
REVERSE_STATE macro
|
||||
; abcd ; dcba
|
||||
; e0 ; 000e
|
||||
pshufd abcd, abcd, 01bH ; abcd
|
||||
pshufd e0, e0, 01bH ; e000
|
||||
endm
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
MY_PROC Sha1_UpdateBlocks_HW, 3
|
||||
MY_PROLOG
|
||||
|
||||
cmp rNum, 0
|
||||
je end_c
|
||||
|
||||
movdqu abcd, [rState] ; dcba
|
||||
movd e0, dword ptr [rState + 16] ; 000e
|
||||
|
||||
REVERSE_STATE
|
||||
|
||||
ifdef x64
|
||||
LOAD_MASK
|
||||
endif
|
||||
|
||||
align 16
|
||||
nextBlock:
|
||||
movdqa abcd_save, abcd
|
||||
movdqa e0_save, e0
|
||||
|
||||
ifndef x64
|
||||
LOAD_MASK
|
||||
endif
|
||||
|
||||
LOAD_W 0
|
||||
LOAD_W 1
|
||||
LOAD_W 2
|
||||
LOAD_W 3
|
||||
|
||||
paddd e0, @CatStr(xmm, %(w_regs))
|
||||
k = 0
|
||||
rept NUM_ROUNDS4
|
||||
RND4 k
|
||||
k = k + 1
|
||||
endm
|
||||
|
||||
paddd abcd, abcd_save
|
||||
|
||||
|
||||
add rData, 64
|
||||
sub rNum, 1
|
||||
jnz nextBlock
|
||||
|
||||
REVERSE_STATE
|
||||
|
||||
movdqu [rState], abcd
|
||||
movd dword ptr [rState + 16], e0
|
||||
|
||||
end_c:
|
||||
MY_EPILOG
|
||||
|
||||
; _TEXT$SHA1OPT ENDS
|
||||
|
||||
end
|
||||
275
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/Asm/x86/Sha256Opt.asm
vendored
Normal file
@@ -0,0 +1,275 @@
|
||||
; Sha256Opt.asm -- SHA-256 optimized code for SHA-256 x86 hardware instructions
|
||||
; 2024-06-16 : Igor Pavlov : Public domain
|
||||
|
||||
include 7zAsm.asm
|
||||
|
||||
MY_ASM_START
|
||||
|
||||
; .data
|
||||
; public K
|
||||
|
||||
; we can use external SHA256_K_ARRAY defined in Sha256.c
|
||||
; but we must guarantee that SHA256_K_ARRAY is aligned for 16-bytes
|
||||
|
||||
COMMENT @
|
||||
ifdef x64
|
||||
K_CONST equ SHA256_K_ARRAY
|
||||
else
|
||||
K_CONST equ _SHA256_K_ARRAY
|
||||
endif
|
||||
EXTRN K_CONST:xmmword
|
||||
@
|
||||
|
||||
CONST SEGMENT READONLY
|
||||
|
||||
align 16
|
||||
Reverse_Endian_Mask db 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12
|
||||
|
||||
; COMMENT @
|
||||
align 16
|
||||
K_CONST \
|
||||
DD 0428a2f98H, 071374491H, 0b5c0fbcfH, 0e9b5dba5H
|
||||
DD 03956c25bH, 059f111f1H, 0923f82a4H, 0ab1c5ed5H
|
||||
DD 0d807aa98H, 012835b01H, 0243185beH, 0550c7dc3H
|
||||
DD 072be5d74H, 080deb1feH, 09bdc06a7H, 0c19bf174H
|
||||
DD 0e49b69c1H, 0efbe4786H, 00fc19dc6H, 0240ca1ccH
|
||||
DD 02de92c6fH, 04a7484aaH, 05cb0a9dcH, 076f988daH
|
||||
DD 0983e5152H, 0a831c66dH, 0b00327c8H, 0bf597fc7H
|
||||
DD 0c6e00bf3H, 0d5a79147H, 006ca6351H, 014292967H
|
||||
DD 027b70a85H, 02e1b2138H, 04d2c6dfcH, 053380d13H
|
||||
DD 0650a7354H, 0766a0abbH, 081c2c92eH, 092722c85H
|
||||
DD 0a2bfe8a1H, 0a81a664bH, 0c24b8b70H, 0c76c51a3H
|
||||
DD 0d192e819H, 0d6990624H, 0f40e3585H, 0106aa070H
|
||||
DD 019a4c116H, 01e376c08H, 02748774cH, 034b0bcb5H
|
||||
DD 0391c0cb3H, 04ed8aa4aH, 05b9cca4fH, 0682e6ff3H
|
||||
DD 0748f82eeH, 078a5636fH, 084c87814H, 08cc70208H
|
||||
DD 090befffaH, 0a4506cebH, 0bef9a3f7H, 0c67178f2H
|
||||
; @
|
||||
|
||||
CONST ENDS
|
||||
|
||||
; _TEXT$SHA256OPT SEGMENT 'CODE'
|
||||
|
||||
ifndef x64
|
||||
.686
|
||||
.xmm
|
||||
endif
|
||||
|
||||
; jwasm-based assemblers for linux and linker from new versions of binutils
|
||||
; can generate incorrect code for load [ARRAY + offset] instructions.
|
||||
; 22.00: we load K_CONST offset to (rTable) register to avoid jwasm+binutils problem
|
||||
rTable equ r0
|
||||
; rTable equ K_CONST
|
||||
|
||||
ifdef x64
|
||||
rNum equ REG_ABI_PARAM_2
|
||||
if (IS_LINUX eq 0)
|
||||
LOCAL_SIZE equ (16 * 2)
|
||||
endif
|
||||
else
|
||||
rNum equ r3
|
||||
LOCAL_SIZE equ (16 * 1)
|
||||
endif
|
||||
|
||||
rState equ REG_ABI_PARAM_0
|
||||
rData equ REG_ABI_PARAM_1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
MY_SHA_INSTR macro cmd, a1, a2
|
||||
db 0fH, 038H, cmd, (0c0H + a1 * 8 + a2)
|
||||
endm
|
||||
|
||||
cmd_sha256rnds2 equ 0cbH
|
||||
cmd_sha256msg1 equ 0ccH
|
||||
cmd_sha256msg2 equ 0cdH
|
||||
|
||||
MY_sha256rnds2 macro a1, a2
|
||||
MY_SHA_INSTR cmd_sha256rnds2, a1, a2
|
||||
endm
|
||||
|
||||
MY_sha256msg1 macro a1, a2
|
||||
MY_SHA_INSTR cmd_sha256msg1, a1, a2
|
||||
endm
|
||||
|
||||
MY_sha256msg2 macro a1, a2
|
||||
MY_SHA_INSTR cmd_sha256msg2, a1, a2
|
||||
endm
|
||||
|
||||
MY_PROLOG macro
|
||||
ifdef x64
|
||||
if (IS_LINUX eq 0)
|
||||
movdqa [r4 + 8], xmm6
|
||||
movdqa [r4 + 8 + 16], xmm7
|
||||
sub r4, LOCAL_SIZE + 8
|
||||
movdqa [r4 ], xmm8
|
||||
movdqa [r4 + 16], xmm9
|
||||
endif
|
||||
else ; x86
|
||||
push r3
|
||||
push r5
|
||||
mov r5, r4
|
||||
NUM_PUSH_REGS equ 2
|
||||
PARAM_OFFSET equ (REG_SIZE * (1 + NUM_PUSH_REGS))
|
||||
if (IS_CDECL gt 0)
|
||||
mov rState, [r4 + PARAM_OFFSET]
|
||||
mov rData, [r4 + PARAM_OFFSET + REG_SIZE * 1]
|
||||
mov rNum, [r4 + PARAM_OFFSET + REG_SIZE * 2]
|
||||
else ; fastcall
|
||||
mov rNum, [r4 + PARAM_OFFSET]
|
||||
endif
|
||||
and r4, -16
|
||||
sub r4, LOCAL_SIZE
|
||||
endif
|
||||
endm
|
||||
|
||||
MY_EPILOG macro
|
||||
ifdef x64
|
||||
if (IS_LINUX eq 0)
|
||||
movdqa xmm8, [r4]
|
||||
movdqa xmm9, [r4 + 16]
|
||||
add r4, LOCAL_SIZE + 8
|
||||
movdqa xmm6, [r4 + 8]
|
||||
movdqa xmm7, [r4 + 8 + 16]
|
||||
endif
|
||||
else ; x86
|
||||
mov r4, r5
|
||||
pop r5
|
||||
pop r3
|
||||
endif
|
||||
MY_ENDP
|
||||
endm
|
||||
|
||||
|
||||
msg equ xmm0
|
||||
tmp equ xmm0
|
||||
state0_N equ 2
|
||||
state1_N equ 3
|
||||
w_regs equ 4
|
||||
|
||||
|
||||
state1_save equ xmm1
|
||||
state0 equ @CatStr(xmm, %state0_N)
|
||||
state1 equ @CatStr(xmm, %state1_N)
|
||||
|
||||
|
||||
ifdef x64
|
||||
state0_save equ xmm8
|
||||
mask2 equ xmm9
|
||||
else
|
||||
state0_save equ [r4]
|
||||
mask2 equ xmm0
|
||||
endif
|
||||
|
||||
LOAD_MASK macro
|
||||
movdqa mask2, XMMWORD PTR Reverse_Endian_Mask
|
||||
endm
|
||||
|
||||
LOAD_W macro k:req
|
||||
movdqu @CatStr(xmm, %(w_regs + k)), [rData + (16 * (k))]
|
||||
pshufb @CatStr(xmm, %(w_regs + k)), mask2
|
||||
endm
|
||||
|
||||
|
||||
; pre1 <= 4 && pre2 >= 1 && pre1 > pre2 && (pre1 - pre2) <= 1
|
||||
pre1 equ 3
|
||||
pre2 equ 2
|
||||
|
||||
|
||||
|
||||
RND4 macro k
|
||||
movdqa msg, xmmword ptr [rTable + (k) * 16]
|
||||
paddd msg, @CatStr(xmm, %(w_regs + ((k + 0) mod 4)))
|
||||
MY_sha256rnds2 state0_N, state1_N
|
||||
pshufd msg, msg, 0eH
|
||||
|
||||
if (k GE (4 - pre1)) AND (k LT (16 - pre1))
|
||||
; w4[0] = msg1(w4[-4], w4[-3])
|
||||
MY_sha256msg1 (w_regs + ((k + pre1) mod 4)), (w_regs + ((k + pre1 - 3) mod 4))
|
||||
endif
|
||||
|
||||
MY_sha256rnds2 state1_N, state0_N
|
||||
|
||||
if (k GE (4 - pre2)) AND (k LT (16 - pre2))
|
||||
movdqa tmp, @CatStr(xmm, %(w_regs + ((k + pre2 - 1) mod 4)))
|
||||
palignr tmp, @CatStr(xmm, %(w_regs + ((k + pre2 - 2) mod 4))), 4
|
||||
paddd @CatStr(xmm, %(w_regs + ((k + pre2) mod 4))), tmp
|
||||
; w4[0] = msg2(w4[0], w4[-1])
|
||||
MY_sha256msg2 %(w_regs + ((k + pre2) mod 4)), %(w_regs + ((k + pre2 - 1) mod 4))
|
||||
endif
|
||||
endm
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
REVERSE_STATE macro
|
||||
; state0 ; dcba
|
||||
; state1 ; hgfe
|
||||
pshufd tmp, state0, 01bH ; abcd
|
||||
pshufd state0, state1, 01bH ; efgh
|
||||
movdqa state1, state0 ; efgh
|
||||
punpcklqdq state0, tmp ; cdgh
|
||||
punpckhqdq state1, tmp ; abef
|
||||
endm
|
||||
|
||||
|
||||
MY_PROC Sha256_UpdateBlocks_HW, 3
|
||||
MY_PROLOG
|
||||
|
||||
lea rTable, [K_CONST]
|
||||
|
||||
cmp rNum, 0
|
||||
je end_c
|
||||
|
||||
movdqu state0, [rState] ; dcba
|
||||
movdqu state1, [rState + 16] ; hgfe
|
||||
|
||||
REVERSE_STATE
|
||||
|
||||
ifdef x64
|
||||
LOAD_MASK
|
||||
endif
|
||||
|
||||
align 16
|
||||
nextBlock:
|
||||
movdqa state0_save, state0
|
||||
movdqa state1_save, state1
|
||||
|
||||
ifndef x64
|
||||
LOAD_MASK
|
||||
endif
|
||||
|
||||
LOAD_W 0
|
||||
LOAD_W 1
|
||||
LOAD_W 2
|
||||
LOAD_W 3
|
||||
|
||||
|
||||
k = 0
|
||||
rept 16
|
||||
RND4 k
|
||||
k = k + 1
|
||||
endm
|
||||
|
||||
paddd state0, state0_save
|
||||
paddd state1, state1_save
|
||||
|
||||
add rData, 64
|
||||
sub rNum, 1
|
||||
jnz nextBlock
|
||||
|
||||
REVERSE_STATE
|
||||
|
||||
movdqu [rState], state0
|
||||
movdqu [rState + 16], state1
|
||||
|
||||
end_c:
|
||||
MY_EPILOG
|
||||
|
||||
; _TEXT$SHA256OPT ENDS
|
||||
|
||||
end
|
||||
523
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/Asm/x86/XzCrc64Opt.asm
vendored
Normal file
@@ -0,0 +1,523 @@
|
||||
; XzCrc64Opt.asm -- CRC64 calculation : optimized version
|
||||
; 2023-12-08 : Igor Pavlov : Public domain
|
||||
|
||||
include 7zAsm.asm
|
||||
|
||||
MY_ASM_START
|
||||
|
||||
NUM_WORDS equ 3
|
||||
|
||||
if (NUM_WORDS lt 1) or (NUM_WORDS gt 64)
|
||||
.err <num_words_IS_INCORRECT>
|
||||
endif
|
||||
|
||||
NUM_SKIP_BYTES equ ((NUM_WORDS - 2) * 4)
|
||||
|
||||
|
||||
MOVZXLO macro dest:req, src:req
|
||||
movzx dest, @CatStr(src, _L)
|
||||
endm
|
||||
|
||||
MOVZXHI macro dest:req, src:req
|
||||
movzx dest, @CatStr(src, _H)
|
||||
endm
|
||||
|
||||
|
||||
ifdef x64
|
||||
|
||||
rD equ r11
|
||||
rN equ r10
|
||||
rT equ r9
|
||||
|
||||
CRC_OP macro op:req, dest:req, src:req, t:req
|
||||
op dest, QWORD PTR [rT + @CatStr(src, _R) * 8 + 0800h * (t)]
|
||||
endm
|
||||
|
||||
CRC_XOR macro dest:req, src:req, t:req
|
||||
CRC_OP xor, dest, src, t
|
||||
endm
|
||||
|
||||
CRC_MOV macro dest:req, src:req, t:req
|
||||
CRC_OP mov, dest, src, t
|
||||
endm
|
||||
|
||||
CRC1b macro
|
||||
movzx x6, BYTE PTR [rD]
|
||||
inc rD
|
||||
MOVZXLO x3, x0
|
||||
xor x6, x3
|
||||
shr r0, 8
|
||||
CRC_XOR r0, x6, 0
|
||||
dec rN
|
||||
endm
|
||||
|
||||
|
||||
; ALIGN_MASK is 3 or 7 bytes alignment:
|
||||
ALIGN_MASK equ (7 - (NUM_WORDS and 1) * 4)
|
||||
|
||||
if NUM_WORDS eq 1
|
||||
|
||||
src_rN_offset equ 4
|
||||
; + 4 for prefetching next 4-bytes after current iteration
|
||||
NUM_BYTES_LIMIT equ (NUM_WORDS * 4 + 4)
|
||||
SRCDAT4 equ DWORD PTR [rN + rD * 1]
|
||||
|
||||
XOR_NEXT macro
|
||||
mov x1, [rD]
|
||||
xor r0, r1
|
||||
endm
|
||||
|
||||
else ; NUM_WORDS > 1
|
||||
|
||||
src_rN_offset equ 8
|
||||
; + 8 for prefetching next 8-bytes after current iteration
|
||||
NUM_BYTES_LIMIT equ (NUM_WORDS * 4 + 8)
|
||||
|
||||
XOR_NEXT macro
|
||||
xor r0, QWORD PTR [rD] ; 64-bit read, can be unaligned
|
||||
endm
|
||||
|
||||
; 32-bit or 64-bit
|
||||
LOAD_SRC_MULT4 macro dest:req, word_index:req
|
||||
mov dest, [rN + rD * 1 + 4 * (word_index) - src_rN_offset];
|
||||
endm
|
||||
|
||||
endif
|
||||
|
||||
|
||||
|
||||
MY_PROC @CatStr(XzCrc64UpdateT, %(NUM_WORDS * 4)), 4
|
||||
MY_PUSH_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11
|
||||
|
||||
mov r0, REG_ABI_PARAM_0 ; r0 <- r1 / r7
|
||||
mov rD, REG_ABI_PARAM_1 ; r11 <- r2 / r6
|
||||
mov rN, REG_ABI_PARAM_2 ; r10 <- r8 / r2
|
||||
if (IS_LINUX gt 0)
|
||||
mov rT, REG_ABI_PARAM_3 ; r9 <- r9 / r1
|
||||
endif
|
||||
|
||||
cmp rN, NUM_BYTES_LIMIT + ALIGN_MASK
|
||||
jb crc_end
|
||||
@@:
|
||||
test rD, ALIGN_MASK
|
||||
jz @F
|
||||
CRC1b
|
||||
jmp @B
|
||||
@@:
|
||||
XOR_NEXT
|
||||
lea rN, [rD + rN * 1 - (NUM_BYTES_LIMIT - 1)]
|
||||
sub rD, rN
|
||||
add rN, src_rN_offset
|
||||
|
||||
align 16
|
||||
@@:
|
||||
|
||||
if NUM_WORDS eq 1
|
||||
|
||||
mov x1, x0
|
||||
shr x1, 8
|
||||
MOVZXLO x3, x1
|
||||
MOVZXLO x2, x0
|
||||
shr x1, 8
|
||||
shr r0, 32
|
||||
xor x0, SRCDAT4
|
||||
CRC_XOR r0, x2, 3
|
||||
CRC_XOR r0, x3, 2
|
||||
MOVZXLO x2, x1
|
||||
shr x1, 8
|
||||
CRC_XOR r0, x2, 1
|
||||
CRC_XOR r0, x1, 0
|
||||
|
||||
else ; NUM_WORDS > 1
|
||||
|
||||
if NUM_WORDS ne 2
|
||||
k = 2
|
||||
while k lt NUM_WORDS
|
||||
|
||||
LOAD_SRC_MULT4 x1, k
|
||||
crc_op1 textequ <xor>
|
||||
|
||||
if k eq 2
|
||||
if (NUM_WORDS and 1)
|
||||
LOAD_SRC_MULT4 x7, NUM_WORDS ; aligned 32-bit
|
||||
LOAD_SRC_MULT4 x6, NUM_WORDS + 1 ; aligned 32-bit
|
||||
shl r6, 32
|
||||
else
|
||||
LOAD_SRC_MULT4 r6, NUM_WORDS ; aligned 64-bit
|
||||
crc_op1 textequ <mov>
|
||||
endif
|
||||
endif
|
||||
table = 4 * (NUM_WORDS - 1 - k)
|
||||
MOVZXLO x3, x1
|
||||
CRC_OP crc_op1, r7, x3, 3 + table
|
||||
MOVZXHI x3, x1
|
||||
shr x1, 16
|
||||
CRC_XOR r6, x3, 2 + table
|
||||
MOVZXLO x3, x1
|
||||
shr x1, 8
|
||||
CRC_XOR r7, x3, 1 + table
|
||||
CRC_XOR r6, x1, 0 + table
|
||||
k = k + 1
|
||||
endm
|
||||
crc_op2 textequ <xor>
|
||||
|
||||
else ; NUM_WORDS == 2
|
||||
LOAD_SRC_MULT4 r6, NUM_WORDS ; aligned 64-bit
|
||||
crc_op2 textequ <mov>
|
||||
endif ; NUM_WORDS == 2
|
||||
|
||||
MOVZXHI x3, x0
|
||||
MOVZXLO x2, x0
|
||||
mov r1, r0
|
||||
shr r1, 32
|
||||
shr x0, 16
|
||||
CRC_XOR r6, x2, NUM_SKIP_BYTES + 7
|
||||
CRC_OP crc_op2, r7, x3, NUM_SKIP_BYTES + 6
|
||||
MOVZXLO x2, x0
|
||||
MOVZXHI x5, x1
|
||||
MOVZXLO x3, x1
|
||||
shr x0, 8
|
||||
shr x1, 16
|
||||
CRC_XOR r7, x2, NUM_SKIP_BYTES + 5
|
||||
CRC_XOR r6, x3, NUM_SKIP_BYTES + 3
|
||||
CRC_XOR r7, x0, NUM_SKIP_BYTES + 4
|
||||
CRC_XOR r6, x5, NUM_SKIP_BYTES + 2
|
||||
MOVZXLO x2, x1
|
||||
shr x1, 8
|
||||
CRC_XOR r7, x2, NUM_SKIP_BYTES + 1
|
||||
CRC_MOV r0, x1, NUM_SKIP_BYTES + 0
|
||||
xor r0, r6
|
||||
xor r0, r7
|
||||
|
||||
endif ; NUM_WORDS > 1
|
||||
add rD, NUM_WORDS * 4
|
||||
jnc @B
|
||||
|
||||
sub rN, src_rN_offset
|
||||
add rD, rN
|
||||
XOR_NEXT
|
||||
add rN, NUM_BYTES_LIMIT - 1
|
||||
sub rN, rD
|
||||
|
||||
crc_end:
|
||||
test rN, rN
|
||||
jz func_end
|
||||
@@:
|
||||
CRC1b
|
||||
jnz @B
|
||||
func_end:
|
||||
MY_POP_PRESERVED_ABI_REGS_UP_TO_INCLUDING_R11
|
||||
MY_ENDP
|
||||
|
||||
|
||||
|
||||
else
|
||||
; ==================================================================
|
||||
; x86 (32-bit)
|
||||
|
||||
rD equ r7
|
||||
rN equ r1
|
||||
rT equ r5
|
||||
|
||||
xA equ x6
|
||||
xA_R equ r6
|
||||
|
||||
ifdef x64
|
||||
num_VAR equ r8
|
||||
else
|
||||
|
||||
crc_OFFS equ (REG_SIZE * 5)
|
||||
|
||||
if (IS_CDECL gt 0) or (IS_LINUX gt 0)
|
||||
; cdecl or (GNU fastcall) stack:
|
||||
; (UInt32 *) table
|
||||
; size_t size
|
||||
; void * data
|
||||
; (UInt64) crc
|
||||
; ret-ip <-(r4)
|
||||
data_OFFS equ (8 + crc_OFFS)
|
||||
size_OFFS equ (REG_SIZE + data_OFFS)
|
||||
table_OFFS equ (REG_SIZE + size_OFFS)
|
||||
num_VAR equ [r4 + size_OFFS]
|
||||
table_VAR equ [r4 + table_OFFS]
|
||||
else
|
||||
; Windows fastcall:
|
||||
; r1 = data, r2 = size
|
||||
; stack:
|
||||
; (UInt32 *) table
|
||||
; (UInt64) crc
|
||||
; ret-ip <-(r4)
|
||||
table_OFFS equ (8 + crc_OFFS)
|
||||
table_VAR equ [r4 + table_OFFS]
|
||||
num_VAR equ table_VAR
|
||||
endif
|
||||
endif ; x64
|
||||
|
||||
SRCDAT4 equ DWORD PTR [rN + rD * 1]
|
||||
|
||||
CRC_1 macro op:req, dest:req, src:req, t:req, word_index:req
|
||||
op dest, DWORD PTR [rT + @CatStr(src, _R) * 8 + 0800h * (t) + (word_index) * 4]
|
||||
endm
|
||||
|
||||
CRC macro op0:req, op1:req, dest0:req, dest1:req, src:req, t:req
|
||||
CRC_1 op0, dest0, src, t, 0
|
||||
CRC_1 op1, dest1, src, t, 1
|
||||
endm
|
||||
|
||||
CRC_XOR macro dest0:req, dest1:req, src:req, t:req
|
||||
CRC xor, xor, dest0, dest1, src, t
|
||||
endm
|
||||
|
||||
|
||||
CRC1b macro
|
||||
movzx xA, BYTE PTR [rD]
|
||||
inc rD
|
||||
MOVZXLO x3, x0
|
||||
xor xA, x3
|
||||
shrd x0, x2, 8
|
||||
shr x2, 8
|
||||
CRC_XOR x0, x2, xA, 0
|
||||
dec rN
|
||||
endm
|
||||
|
||||
|
||||
MY_PROLOG_BASE macro
|
||||
MY_PUSH_4_REGS
|
||||
ifdef x64
|
||||
mov r0, REG_ABI_PARAM_0 ; r0 <- r1 / r7
|
||||
mov rT, REG_ABI_PARAM_3 ; r5 <- r9 / r1
|
||||
mov rN, REG_ABI_PARAM_2 ; r1 <- r8 / r2
|
||||
mov rD, REG_ABI_PARAM_1 ; r7 <- r2 / r6
|
||||
mov r2, r0
|
||||
shr r2, 32
|
||||
mov x0, x0
|
||||
else
|
||||
if (IS_CDECL gt 0) or (IS_LINUX gt 0)
|
||||
proc_numParams = proc_numParams + 2 ; for ABI_LINUX
|
||||
mov rN, [r4 + size_OFFS]
|
||||
mov rD, [r4 + data_OFFS]
|
||||
else
|
||||
mov rD, REG_ABI_PARAM_0 ; r7 <- r1 : (data)
|
||||
mov rN, REG_ABI_PARAM_1 ; r1 <- r2 : (size)
|
||||
endif
|
||||
mov x0, [r4 + crc_OFFS]
|
||||
mov x2, [r4 + crc_OFFS + 4]
|
||||
mov rT, table_VAR
|
||||
endif
|
||||
endm
|
||||
|
||||
|
||||
MY_EPILOG_BASE macro crc_end:req, func_end:req
|
||||
crc_end:
|
||||
test rN, rN
|
||||
jz func_end
|
||||
@@:
|
||||
CRC1b
|
||||
jnz @B
|
||||
func_end:
|
||||
ifdef x64
|
||||
shl r2, 32
|
||||
xor r0, r2
|
||||
endif
|
||||
MY_POP_4_REGS
|
||||
endm
|
||||
|
||||
|
||||
; ALIGN_MASK is 3 or 7 bytes alignment:
|
||||
ALIGN_MASK equ (7 - (NUM_WORDS and 1) * 4)
|
||||
|
||||
if (NUM_WORDS eq 1)
|
||||
|
||||
NUM_BYTES_LIMIT_T4 equ (NUM_WORDS * 4 + 4)
|
||||
|
||||
MY_PROC @CatStr(XzCrc64UpdateT, %(NUM_WORDS * 4)), 5
|
||||
MY_PROLOG_BASE
|
||||
|
||||
cmp rN, NUM_BYTES_LIMIT_T4 + ALIGN_MASK
|
||||
jb crc_end_4
|
||||
@@:
|
||||
test rD, ALIGN_MASK
|
||||
jz @F
|
||||
CRC1b
|
||||
jmp @B
|
||||
@@:
|
||||
xor x0, [rD]
|
||||
lea rN, [rD + rN * 1 - (NUM_BYTES_LIMIT_T4 - 1)]
|
||||
sub rD, rN
|
||||
add rN, 4
|
||||
|
||||
MOVZXLO xA, x0
|
||||
align 16
|
||||
@@:
|
||||
mov x3, SRCDAT4
|
||||
xor x3, x2
|
||||
shr x0, 8
|
||||
CRC xor, mov, x3, x2, xA, 3
|
||||
MOVZXLO xA, x0
|
||||
shr x0, 8
|
||||
; MOVZXHI xA, x0
|
||||
; shr x0, 16
|
||||
CRC_XOR x3, x2, xA, 2
|
||||
|
||||
MOVZXLO xA, x0
|
||||
shr x0, 8
|
||||
CRC_XOR x3, x2, xA, 1
|
||||
CRC_XOR x3, x2, x0, 0
|
||||
MOVZXLO xA, x3
|
||||
mov x0, x3
|
||||
|
||||
add rD, 4
|
||||
jnc @B
|
||||
|
||||
sub rN, 4
|
||||
add rD, rN
|
||||
xor x0, [rD]
|
||||
add rN, NUM_BYTES_LIMIT_T4 - 1
|
||||
sub rN, rD
|
||||
MY_EPILOG_BASE crc_end_4, func_end_4
|
||||
MY_ENDP
|
||||
|
||||
else ; NUM_WORDS > 1
|
||||
|
||||
SHR_X macro x, imm
|
||||
shr x, imm
|
||||
endm
|
||||
|
||||
|
||||
ITER_1 macro v0, v1, a, off
|
||||
MOVZXLO xA, a
|
||||
SHR_X a, 8
|
||||
CRC_XOR v0, v1, xA, off
|
||||
endm
|
||||
|
||||
|
||||
ITER_4 macro v0, v1, a, off
|
||||
if 0 eq 0
|
||||
ITER_1 v0, v1, a, off + 3
|
||||
ITER_1 v0, v1, a, off + 2
|
||||
ITER_1 v0, v1, a, off + 1
|
||||
CRC_XOR v0, v1, a, off
|
||||
elseif 0 eq 0
|
||||
MOVZXLO xA, a
|
||||
CRC_XOR v0, v1, xA, off + 3
|
||||
mov xA, a
|
||||
ror a, 16 ; 32-bit ror
|
||||
shr xA, 24
|
||||
CRC_XOR v0, v1, xA, off
|
||||
MOVZXLO xA, a
|
||||
SHR_X a, 24
|
||||
CRC_XOR v0, v1, xA, off + 1
|
||||
CRC_XOR v0, v1, a, off + 2
|
||||
else
|
||||
; MOVZXHI provides smaller code, but MOVZX_HI_BYTE is not fast instruction
|
||||
MOVZXLO xA, a
|
||||
CRC_XOR v0, v1, xA, off + 3
|
||||
MOVZXHI xA, a
|
||||
SHR_X a, 16
|
||||
CRC_XOR v0, v1, xA, off + 2
|
||||
MOVZXLO xA, a
|
||||
SHR_X a, 8
|
||||
CRC_XOR v0, v1, xA, off + 1
|
||||
CRC_XOR v0, v1, a, off
|
||||
endif
|
||||
endm
|
||||
|
||||
|
||||
|
||||
ITER_1_PAIR macro v0, v1, a0, a1, off
|
||||
ITER_1 v0, v1, a0, off + 4
|
||||
ITER_1 v0, v1, a1, off
|
||||
endm
|
||||
|
||||
src_rD_offset equ 8
|
||||
STEP_SIZE equ (NUM_WORDS * 4)
|
||||
|
||||
ITER_12_NEXT macro op, index, v0, v1
|
||||
op v0, DWORD PTR [rD + (index + 1) * STEP_SIZE - src_rD_offset]
|
||||
op v1, DWORD PTR [rD + (index + 1) * STEP_SIZE + 4 - src_rD_offset]
|
||||
endm
|
||||
|
||||
ITER_12 macro index, a0, a1, v0, v1
|
||||
|
||||
if NUM_SKIP_BYTES eq 0
|
||||
ITER_12_NEXT mov, index, v0, v1
|
||||
else
|
||||
k = 0
|
||||
while k lt NUM_SKIP_BYTES
|
||||
movzx xA, BYTE PTR [rD + (index) * STEP_SIZE + k + 8 - src_rD_offset]
|
||||
if k eq 0
|
||||
CRC mov, mov, v0, v1, xA, NUM_SKIP_BYTES - 1 - k
|
||||
else
|
||||
CRC_XOR v0, v1, xA, NUM_SKIP_BYTES - 1 - k
|
||||
endif
|
||||
k = k + 1
|
||||
endm
|
||||
ITER_12_NEXT xor, index, v0, v1
|
||||
endif
|
||||
|
||||
if 0 eq 0
|
||||
ITER_4 v0, v1, a0, NUM_SKIP_BYTES + 4
|
||||
ITER_4 v0, v1, a1, NUM_SKIP_BYTES
|
||||
else ; interleave version is faster/slower for different processors
|
||||
ITER_1_PAIR v0, v1, a0, a1, NUM_SKIP_BYTES + 3
|
||||
ITER_1_PAIR v0, v1, a0, a1, NUM_SKIP_BYTES + 2
|
||||
ITER_1_PAIR v0, v1, a0, a1, NUM_SKIP_BYTES + 1
|
||||
CRC_XOR v0, v1, a0, NUM_SKIP_BYTES + 4
|
||||
CRC_XOR v0, v1, a1, NUM_SKIP_BYTES
|
||||
endif
|
||||
endm
|
||||
|
||||
; we use (UNROLL_CNT > 1) to reduce read ports pressure (num_VAR reads)
|
||||
UNROLL_CNT equ (2 * 1)
|
||||
NUM_BYTES_LIMIT equ (STEP_SIZE * UNROLL_CNT + 8)
|
||||
|
||||
MY_PROC @CatStr(XzCrc64UpdateT, %(NUM_WORDS * 4)), 5
|
||||
MY_PROLOG_BASE
|
||||
|
||||
cmp rN, NUM_BYTES_LIMIT + ALIGN_MASK
|
||||
jb crc_end_12
|
||||
@@:
|
||||
test rD, ALIGN_MASK
|
||||
jz @F
|
||||
CRC1b
|
||||
jmp @B
|
||||
@@:
|
||||
xor x0, [rD]
|
||||
xor x2, [rD + 4]
|
||||
add rD, src_rD_offset
|
||||
lea rN, [rD + rN * 1 - (NUM_BYTES_LIMIT - 1)]
|
||||
mov num_VAR, rN
|
||||
|
||||
align 16
|
||||
@@:
|
||||
i = 0
|
||||
rept UNROLL_CNT
|
||||
if (i and 1) eq 0
|
||||
ITER_12 i, x0, x2, x1, x3
|
||||
else
|
||||
ITER_12 i, x1, x3, x0, x2
|
||||
endif
|
||||
i = i + 1
|
||||
endm
|
||||
|
||||
if (UNROLL_CNT and 1)
|
||||
mov x0, x1
|
||||
mov x2, x3
|
||||
endif
|
||||
add rD, STEP_SIZE * UNROLL_CNT
|
||||
cmp rD, num_VAR
|
||||
jb @B
|
||||
|
||||
mov rN, num_VAR
|
||||
add rN, NUM_BYTES_LIMIT - 1
|
||||
sub rN, rD
|
||||
sub rD, src_rD_offset
|
||||
xor x0, [rD]
|
||||
xor x2, [rD + 4]
|
||||
|
||||
MY_EPILOG_BASE crc_end_12, func_end_12
|
||||
MY_ENDP
|
||||
|
||||
endif ; (NUM_WORDS > 1)
|
||||
endif ; ! x64
|
||||
end
|
||||
204
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/C/7z.h
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
/* 7z.h -- 7z interface
|
||||
2023-04-02 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef ZIP7_INC_7Z_H
|
||||
#define ZIP7_INC_7Z_H
|
||||
|
||||
#include "7zTypes.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
#define k7zStartHeaderSize 0x20
|
||||
#define k7zSignatureSize 6
|
||||
|
||||
extern const Byte k7zSignature[k7zSignatureSize];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const Byte *Data;
|
||||
size_t Size;
|
||||
} CSzData;
|
||||
|
||||
/* CSzCoderInfo & CSzFolder support only default methods */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t PropsOffset;
|
||||
UInt32 MethodID;
|
||||
Byte NumStreams;
|
||||
Byte PropsSize;
|
||||
} CSzCoderInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 InIndex;
|
||||
UInt32 OutIndex;
|
||||
} CSzBond;
|
||||
|
||||
#define SZ_NUM_CODERS_IN_FOLDER_MAX 4
|
||||
#define SZ_NUM_BONDS_IN_FOLDER_MAX 3
|
||||
#define SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX 4
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 NumCoders;
|
||||
UInt32 NumBonds;
|
||||
UInt32 NumPackStreams;
|
||||
UInt32 UnpackStream;
|
||||
UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX];
|
||||
CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX];
|
||||
CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX];
|
||||
} CSzFolder;
|
||||
|
||||
|
||||
SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 Low;
|
||||
UInt32 High;
|
||||
} CNtfsFileTime;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Byte *Defs; /* MSB 0 bit numbering */
|
||||
UInt32 *Vals;
|
||||
} CSzBitUi32s;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Byte *Defs; /* MSB 0 bit numbering */
|
||||
// UInt64 *Vals;
|
||||
CNtfsFileTime *Vals;
|
||||
} CSzBitUi64s;
|
||||
|
||||
#define SzBitArray_Check(p, i) (((p)[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)
|
||||
|
||||
#define SzBitWithVals_Check(p, i) ((p)->Defs && ((p)->Defs[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 NumPackStreams;
|
||||
UInt32 NumFolders;
|
||||
|
||||
UInt64 *PackPositions; // NumPackStreams + 1
|
||||
CSzBitUi32s FolderCRCs; // NumFolders
|
||||
|
||||
size_t *FoCodersOffsets; // NumFolders + 1
|
||||
UInt32 *FoStartPackStreamIndex; // NumFolders + 1
|
||||
UInt32 *FoToCoderUnpackSizes; // NumFolders + 1
|
||||
Byte *FoToMainUnpackSizeIndex; // NumFolders
|
||||
UInt64 *CoderUnpackSizes; // for all coders in all folders
|
||||
|
||||
Byte *CodersData;
|
||||
|
||||
UInt64 RangeLimit;
|
||||
} CSzAr;
|
||||
|
||||
UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex);
|
||||
|
||||
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
|
||||
ILookInStreamPtr stream, UInt64 startPos,
|
||||
Byte *outBuffer, size_t outSize,
|
||||
ISzAllocPtr allocMain);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CSzAr db;
|
||||
|
||||
UInt64 startPosAfterHeader;
|
||||
UInt64 dataPos;
|
||||
|
||||
UInt32 NumFiles;
|
||||
|
||||
UInt64 *UnpackPositions; // NumFiles + 1
|
||||
// Byte *IsEmptyFiles;
|
||||
Byte *IsDirs;
|
||||
CSzBitUi32s CRCs;
|
||||
|
||||
CSzBitUi32s Attribs;
|
||||
// CSzBitUi32s Parents;
|
||||
CSzBitUi64s MTime;
|
||||
CSzBitUi64s CTime;
|
||||
|
||||
UInt32 *FolderToFile; // NumFolders + 1
|
||||
UInt32 *FileToFolder; // NumFiles
|
||||
|
||||
size_t *FileNameOffsets; /* in 2-byte steps */
|
||||
Byte *FileNames; /* UTF-16-LE */
|
||||
} CSzArEx;
|
||||
|
||||
#define SzArEx_IsDir(p, i) (SzBitArray_Check((p)->IsDirs, i))
|
||||
|
||||
#define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i])
|
||||
|
||||
void SzArEx_Init(CSzArEx *p);
|
||||
void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc);
|
||||
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
|
||||
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
|
||||
|
||||
/*
|
||||
if dest == NULL, the return value specifies the required size of the buffer,
|
||||
in 16-bit characters, including the null-terminating character.
|
||||
if dest != NULL, the return value specifies the number of 16-bit characters that
|
||||
are written to the dest, including the null-terminating character. */
|
||||
|
||||
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
|
||||
|
||||
/*
|
||||
size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex);
|
||||
UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
SzArEx_Extract extracts file from archive
|
||||
|
||||
*outBuffer must be 0 before first call for each new archive.
|
||||
|
||||
Extracting cache:
|
||||
If you need to decompress more than one file, you can send
|
||||
these values from previous call:
|
||||
*blockIndex,
|
||||
*outBuffer,
|
||||
*outBufferSize
|
||||
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
||||
it will increase decompression speed.
|
||||
|
||||
If you use external function, you can declare these 3 cache variables
|
||||
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
||||
|
||||
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
||||
*/
|
||||
|
||||
SRes SzArEx_Extract(
|
||||
const CSzArEx *db,
|
||||
ILookInStreamPtr inStream,
|
||||
UInt32 fileIndex, /* index of file */
|
||||
UInt32 *blockIndex, /* index of solid block */
|
||||
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
||||
size_t *outBufferSize, /* buffer size for output buffer */
|
||||
size_t *offset, /* offset of stream for required file in *outBuffer */
|
||||
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
||||
ISzAllocPtr allocMain,
|
||||
ISzAllocPtr allocTemp);
|
||||
|
||||
|
||||
/*
|
||||
SzArEx_Open Errors:
|
||||
SZ_ERROR_NO_ARCHIVE
|
||||
SZ_ERROR_ARCHIVE
|
||||
SZ_ERROR_UNSUPPORTED
|
||||
SZ_ERROR_MEM
|
||||
SZ_ERROR_CRC
|
||||
SZ_ERROR_INPUT_EOF
|
||||
SZ_ERROR_FAIL
|
||||
*/
|
||||
|
||||
SRes SzArEx_Open(CSzArEx *p, ILookInStreamPtr inStream,
|
||||
ISzAllocPtr allocMain, ISzAllocPtr allocTemp);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
89
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/C/7zAlloc.c
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
/* 7zAlloc.c -- Allocation functions for 7z processing
|
||||
2023-03-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "7zAlloc.h"
|
||||
|
||||
/* #define SZ_ALLOC_DEBUG */
|
||||
/* use SZ_ALLOC_DEBUG to debug alloc/free operations */
|
||||
|
||||
#ifdef SZ_ALLOC_DEBUG
|
||||
|
||||
/*
|
||||
#ifdef _WIN32
|
||||
#include "7zWindows.h"
|
||||
#endif
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
static int g_allocCount = 0;
|
||||
static int g_allocCountTemp = 0;
|
||||
|
||||
static void Print_Alloc(const char *s, size_t size, int *counter)
|
||||
{
|
||||
const unsigned size2 = (unsigned)size;
|
||||
fprintf(stderr, "\n%s count = %10d : %10u bytes; ", s, *counter, size2);
|
||||
(*counter)++;
|
||||
}
|
||||
static void Print_Free(const char *s, int *counter)
|
||||
{
|
||||
(*counter)--;
|
||||
fprintf(stderr, "\n%s count = %10d", s, *counter);
|
||||
}
|
||||
#endif
|
||||
|
||||
void *SzAlloc(ISzAllocPtr p, size_t size)
|
||||
{
|
||||
UNUSED_VAR(p)
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef SZ_ALLOC_DEBUG
|
||||
Print_Alloc("Alloc", size, &g_allocCount);
|
||||
#endif
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void SzFree(ISzAllocPtr p, void *address)
|
||||
{
|
||||
UNUSED_VAR(p)
|
||||
#ifdef SZ_ALLOC_DEBUG
|
||||
if (address)
|
||||
Print_Free("Free ", &g_allocCount);
|
||||
#endif
|
||||
free(address);
|
||||
}
|
||||
|
||||
void *SzAllocTemp(ISzAllocPtr p, size_t size)
|
||||
{
|
||||
UNUSED_VAR(p)
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef SZ_ALLOC_DEBUG
|
||||
Print_Alloc("Alloc_temp", size, &g_allocCountTemp);
|
||||
/*
|
||||
#ifdef _WIN32
|
||||
return HeapAlloc(GetProcessHeap(), 0, size);
|
||||
#endif
|
||||
*/
|
||||
#endif
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void SzFreeTemp(ISzAllocPtr p, void *address)
|
||||
{
|
||||
UNUSED_VAR(p)
|
||||
#ifdef SZ_ALLOC_DEBUG
|
||||
if (address)
|
||||
Print_Free("Free_temp ", &g_allocCountTemp);
|
||||
/*
|
||||
#ifdef _WIN32
|
||||
HeapFree(GetProcessHeap(), 0, address);
|
||||
return;
|
||||
#endif
|
||||
*/
|
||||
#endif
|
||||
free(address);
|
||||
}
|
||||
19
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/C/7zAlloc.h
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
/* 7zAlloc.h -- Allocation functions
|
||||
2023-03-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef ZIP7_INC_7Z_ALLOC_H
|
||||
#define ZIP7_INC_7Z_ALLOC_H
|
||||
|
||||
#include "7zTypes.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
void *SzAlloc(ISzAllocPtr p, size_t size);
|
||||
void SzFree(ISzAllocPtr p, void *address);
|
||||
|
||||
void *SzAllocTemp(ISzAllocPtr p, size_t size);
|
||||
void SzFreeTemp(ISzAllocPtr p, void *address);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
1786
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/C/7zArcIn.c
vendored
Normal file
36
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/C/7zBuf.c
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/* 7zBuf.c -- Byte Buffer
|
||||
2017-04-03 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include "7zBuf.h"
|
||||
|
||||
void Buf_Init(CBuf *p)
|
||||
{
|
||||
p->data = 0;
|
||||
p->size = 0;
|
||||
}
|
||||
|
||||
int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc)
|
||||
{
|
||||
p->size = 0;
|
||||
if (size == 0)
|
||||
{
|
||||
p->data = 0;
|
||||
return 1;
|
||||
}
|
||||
p->data = (Byte *)ISzAlloc_Alloc(alloc, size);
|
||||
if (p->data)
|
||||
{
|
||||
p->size = size;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Buf_Free(CBuf *p, ISzAllocPtr alloc)
|
||||
{
|
||||
ISzAlloc_Free(alloc, p->data);
|
||||
p->data = 0;
|
||||
p->size = 0;
|
||||
}
|
||||
35
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/C/7zBuf.h
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/* 7zBuf.h -- Byte Buffer
|
||||
2023-03-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef ZIP7_INC_7Z_BUF_H
|
||||
#define ZIP7_INC_7Z_BUF_H
|
||||
|
||||
#include "7zTypes.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Byte *data;
|
||||
size_t size;
|
||||
} CBuf;
|
||||
|
||||
void Buf_Init(CBuf *p);
|
||||
int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc);
|
||||
void Buf_Free(CBuf *p, ISzAllocPtr alloc);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Byte *data;
|
||||
size_t size;
|
||||
size_t pos;
|
||||
} CDynBuf;
|
||||
|
||||
void DynBuf_Construct(CDynBuf *p);
|
||||
void DynBuf_SeekToBeg(CDynBuf *p);
|
||||
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc);
|
||||
void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
52
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/C/7zBuf2.c
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/* 7zBuf2.c -- Byte Buffer
|
||||
2017-04-03 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "7zBuf.h"
|
||||
|
||||
void DynBuf_Construct(CDynBuf *p)
|
||||
{
|
||||
p->data = 0;
|
||||
p->size = 0;
|
||||
p->pos = 0;
|
||||
}
|
||||
|
||||
void DynBuf_SeekToBeg(CDynBuf *p)
|
||||
{
|
||||
p->pos = 0;
|
||||
}
|
||||
|
||||
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc)
|
||||
{
|
||||
if (size > p->size - p->pos)
|
||||
{
|
||||
size_t newSize = p->pos + size;
|
||||
Byte *data;
|
||||
newSize += newSize / 4;
|
||||
data = (Byte *)ISzAlloc_Alloc(alloc, newSize);
|
||||
if (!data)
|
||||
return 0;
|
||||
p->size = newSize;
|
||||
if (p->pos != 0)
|
||||
memcpy(data, p->data, p->pos);
|
||||
ISzAlloc_Free(alloc, p->data);
|
||||
p->data = data;
|
||||
}
|
||||
if (size != 0)
|
||||
{
|
||||
memcpy(p->data + p->pos, buf, size);
|
||||
p->pos += size;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc)
|
||||
{
|
||||
ISzAlloc_Free(alloc, p->data);
|
||||
p->data = 0;
|
||||
p->size = 0;
|
||||
p->pos = 0;
|
||||
}
|
||||
420
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/C/7zCrc.c
vendored
Normal file
@@ -0,0 +1,420 @@
|
||||
/* 7zCrc.c -- CRC32 calculation and init
|
||||
2024-03-01 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include "7zCrc.h"
|
||||
#include "CpuArch.h"
|
||||
|
||||
// for debug:
|
||||
// #define __ARM_FEATURE_CRC32 1
|
||||
|
||||
#ifdef __ARM_FEATURE_CRC32
|
||||
// #pragma message("__ARM_FEATURE_CRC32")
|
||||
#define Z7_CRC_HW_FORCE
|
||||
#endif
|
||||
|
||||
// #define Z7_CRC_DEBUG_BE
|
||||
#ifdef Z7_CRC_DEBUG_BE
|
||||
#undef MY_CPU_LE
|
||||
#define MY_CPU_BE
|
||||
#endif
|
||||
|
||||
#ifdef Z7_CRC_HW_FORCE
|
||||
#define Z7_CRC_NUM_TABLES_USE 1
|
||||
#else
|
||||
#ifdef Z7_CRC_NUM_TABLES
|
||||
#define Z7_CRC_NUM_TABLES_USE Z7_CRC_NUM_TABLES
|
||||
#else
|
||||
#define Z7_CRC_NUM_TABLES_USE 12
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if Z7_CRC_NUM_TABLES_USE < 1
|
||||
#error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_LE) || (Z7_CRC_NUM_TABLES_USE == 1)
|
||||
#define Z7_CRC_NUM_TABLES_TOTAL Z7_CRC_NUM_TABLES_USE
|
||||
#else
|
||||
#define Z7_CRC_NUM_TABLES_TOTAL (Z7_CRC_NUM_TABLES_USE + 1)
|
||||
#endif
|
||||
|
||||
#ifndef Z7_CRC_HW_FORCE
|
||||
|
||||
#if Z7_CRC_NUM_TABLES_USE == 1 \
|
||||
|| (!defined(MY_CPU_LE) && !defined(MY_CPU_BE))
|
||||
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||
#define Z7_CRC_UPDATE_T1_FUNC_NAME CrcUpdateGT1
|
||||
static UInt32 Z7_FASTCALL Z7_CRC_UPDATE_T1_FUNC_NAME(UInt32 v, const void *data, size_t size)
|
||||
{
|
||||
const UInt32 *table = g_CrcTable;
|
||||
const Byte *p = (const Byte *)data;
|
||||
const Byte *lim = p + size;
|
||||
for (; p != lim; p++)
|
||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||
return v;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if Z7_CRC_NUM_TABLES_USE != 1
|
||||
#ifndef MY_CPU_BE
|
||||
#define FUNC_NAME_LE_2(s) CrcUpdateT ## s
|
||||
#define FUNC_NAME_LE_1(s) FUNC_NAME_LE_2(s)
|
||||
#define FUNC_NAME_LE FUNC_NAME_LE_1(Z7_CRC_NUM_TABLES_USE)
|
||||
UInt32 Z7_FASTCALL FUNC_NAME_LE (UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||
#endif
|
||||
#ifndef MY_CPU_LE
|
||||
#define FUNC_NAME_BE_2(s) CrcUpdateT1_BeT ## s
|
||||
#define FUNC_NAME_BE_1(s) FUNC_NAME_BE_2(s)
|
||||
#define FUNC_NAME_BE FUNC_NAME_BE_1(Z7_CRC_NUM_TABLES_USE)
|
||||
UInt32 Z7_FASTCALL FUNC_NAME_BE (UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // Z7_CRC_HW_FORCE
|
||||
|
||||
/* ---------- hardware CRC ---------- */
|
||||
|
||||
#ifdef MY_CPU_LE
|
||||
|
||||
#if defined(MY_CPU_ARM_OR_ARM64)
|
||||
// #pragma message("ARM*")
|
||||
|
||||
#if (defined(__clang__) && (__clang_major__ >= 3)) \
|
||||
|| defined(__GNUC__) && (__GNUC__ >= 6) && defined(MY_CPU_ARM64) \
|
||||
|| defined(__GNUC__) && (__GNUC__ >= 8)
|
||||
#if !defined(__ARM_FEATURE_CRC32)
|
||||
// #pragma message("!defined(__ARM_FEATURE_CRC32)")
|
||||
Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
|
||||
#define __ARM_FEATURE_CRC32 1
|
||||
Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
|
||||
#define Z7_ARM_FEATURE_CRC32_WAS_SET
|
||||
#if defined(__clang__)
|
||||
#if defined(MY_CPU_ARM64)
|
||||
#define ATTRIB_CRC __attribute__((__target__("crc")))
|
||||
#else
|
||||
#define ATTRIB_CRC __attribute__((__target__("armv8-a,crc")))
|
||||
#endif
|
||||
#else
|
||||
#if defined(MY_CPU_ARM64)
|
||||
#if !defined(Z7_GCC_VERSION) || (Z7_GCC_VERSION >= 60000)
|
||||
#define ATTRIB_CRC __attribute__((__target__("+crc")))
|
||||
#endif
|
||||
#else
|
||||
#if !defined(Z7_GCC_VERSION) || (__GNUC__ >= 8)
|
||||
#if defined(__ARM_FP) && __GNUC__ >= 8
|
||||
// for -mfloat-abi=hard: similar to <arm_acle.h>
|
||||
#define ATTRIB_CRC __attribute__((__target__("arch=armv8-a+crc+simd")))
|
||||
#else
|
||||
#define ATTRIB_CRC __attribute__((__target__("arch=armv8-a+crc")))
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__ARM_FEATURE_CRC32)
|
||||
// #pragma message("<arm_acle.h>")
|
||||
/*
|
||||
arm_acle.h (GGC):
|
||||
before Nov 17, 2017:
|
||||
#ifdef __ARM_FEATURE_CRC32
|
||||
|
||||
Nov 17, 2017: gcc10.0 (gcc 9.2.0) checked"
|
||||
#if __ARM_ARCH >= 8
|
||||
#pragma GCC target ("arch=armv8-a+crc")
|
||||
|
||||
Aug 22, 2019: GCC 8.4?, 9.2.1, 10.1:
|
||||
#ifdef __ARM_FEATURE_CRC32
|
||||
#ifdef __ARM_FP
|
||||
#pragma GCC target ("arch=armv8-a+crc+simd")
|
||||
#else
|
||||
#pragma GCC target ("arch=armv8-a+crc")
|
||||
#endif
|
||||
*/
|
||||
#if defined(__ARM_ARCH) && __ARM_ARCH < 8
|
||||
#if defined(Z7_GCC_VERSION) && (__GNUC__ == 8) && (Z7_GCC_VERSION < 80400) \
|
||||
|| defined(Z7_GCC_VERSION) && (__GNUC__ == 9) && (Z7_GCC_VERSION < 90201) \
|
||||
|| defined(Z7_GCC_VERSION) && (__GNUC__ == 10) && (Z7_GCC_VERSION < 100100)
|
||||
Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
|
||||
// #pragma message("#define __ARM_ARCH 8")
|
||||
#undef __ARM_ARCH
|
||||
#define __ARM_ARCH 8
|
||||
Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
|
||||
#endif
|
||||
#endif
|
||||
#define Z7_CRC_HW_USE
|
||||
#include <arm_acle.h>
|
||||
#endif
|
||||
#elif defined(_MSC_VER)
|
||||
#if defined(MY_CPU_ARM64)
|
||||
#if (_MSC_VER >= 1910)
|
||||
#ifdef __clang__
|
||||
// #define Z7_CRC_HW_USE
|
||||
// #include <arm_acle.h>
|
||||
#else
|
||||
#define Z7_CRC_HW_USE
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else // non-ARM*
|
||||
|
||||
// #define Z7_CRC_HW_USE // for debug : we can test HW-branch of code
|
||||
#ifdef Z7_CRC_HW_USE
|
||||
#include "7zCrcEmu.h"
|
||||
#endif
|
||||
|
||||
#endif // non-ARM*
|
||||
|
||||
|
||||
|
||||
#if defined(Z7_CRC_HW_USE)
|
||||
|
||||
// #pragma message("USE ARM HW CRC")
|
||||
|
||||
#ifdef MY_CPU_64BIT
|
||||
#define CRC_HW_WORD_TYPE UInt64
|
||||
#define CRC_HW_WORD_FUNC __crc32d
|
||||
#else
|
||||
#define CRC_HW_WORD_TYPE UInt32
|
||||
#define CRC_HW_WORD_FUNC __crc32w
|
||||
#endif
|
||||
|
||||
#define CRC_HW_UNROLL_BYTES (sizeof(CRC_HW_WORD_TYPE) * 4)
|
||||
|
||||
#ifdef ATTRIB_CRC
|
||||
ATTRIB_CRC
|
||||
#endif
|
||||
Z7_NO_INLINE
|
||||
#ifdef Z7_CRC_HW_FORCE
|
||||
UInt32 Z7_FASTCALL CrcUpdate
|
||||
#else
|
||||
static UInt32 Z7_FASTCALL CrcUpdate_HW
|
||||
#endif
|
||||
(UInt32 v, const void *data, size_t size)
|
||||
{
|
||||
const Byte *p = (const Byte *)data;
|
||||
for (; size != 0 && ((unsigned)(ptrdiff_t)p & (CRC_HW_UNROLL_BYTES - 1)) != 0; size--)
|
||||
v = __crc32b(v, *p++);
|
||||
if (size >= CRC_HW_UNROLL_BYTES)
|
||||
{
|
||||
const Byte *lim = p + size;
|
||||
size &= CRC_HW_UNROLL_BYTES - 1;
|
||||
lim -= size;
|
||||
do
|
||||
{
|
||||
v = CRC_HW_WORD_FUNC(v, *(const CRC_HW_WORD_TYPE *)(const void *)(p));
|
||||
v = CRC_HW_WORD_FUNC(v, *(const CRC_HW_WORD_TYPE *)(const void *)(p + sizeof(CRC_HW_WORD_TYPE)));
|
||||
p += 2 * sizeof(CRC_HW_WORD_TYPE);
|
||||
v = CRC_HW_WORD_FUNC(v, *(const CRC_HW_WORD_TYPE *)(const void *)(p));
|
||||
v = CRC_HW_WORD_FUNC(v, *(const CRC_HW_WORD_TYPE *)(const void *)(p + sizeof(CRC_HW_WORD_TYPE)));
|
||||
p += 2 * sizeof(CRC_HW_WORD_TYPE);
|
||||
}
|
||||
while (p != lim);
|
||||
}
|
||||
|
||||
for (; size != 0; size--)
|
||||
v = __crc32b(v, *p++);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
#ifdef Z7_ARM_FEATURE_CRC32_WAS_SET
|
||||
Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
|
||||
#undef __ARM_FEATURE_CRC32
|
||||
Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
|
||||
#undef Z7_ARM_FEATURE_CRC32_WAS_SET
|
||||
#endif
|
||||
|
||||
#endif // defined(Z7_CRC_HW_USE)
|
||||
#endif // MY_CPU_LE
|
||||
|
||||
|
||||
|
||||
#ifndef Z7_CRC_HW_FORCE
|
||||
|
||||
#if defined(Z7_CRC_HW_USE) || defined(Z7_CRC_UPDATE_T1_FUNC_NAME)
|
||||
/*
|
||||
typedef UInt32 (Z7_FASTCALL *Z7_CRC_UPDATE_WITH_TABLE_FUNC)
|
||||
(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||
Z7_CRC_UPDATE_WITH_TABLE_FUNC g_CrcUpdate;
|
||||
*/
|
||||
static unsigned g_Crc_Algo;
|
||||
#if (!defined(MY_CPU_LE) && !defined(MY_CPU_BE))
|
||||
static unsigned g_Crc_Be;
|
||||
#endif
|
||||
#endif // defined(Z7_CRC_HW_USE) || defined(Z7_CRC_UPDATE_T1_FUNC_NAME)
|
||||
|
||||
|
||||
|
||||
Z7_NO_INLINE
|
||||
#ifdef Z7_CRC_HW_USE
|
||||
static UInt32 Z7_FASTCALL CrcUpdate_Base
|
||||
#else
|
||||
UInt32 Z7_FASTCALL CrcUpdate
|
||||
#endif
|
||||
(UInt32 crc, const void *data, size_t size)
|
||||
{
|
||||
#if Z7_CRC_NUM_TABLES_USE == 1
|
||||
return Z7_CRC_UPDATE_T1_FUNC_NAME(crc, data, size);
|
||||
#else // Z7_CRC_NUM_TABLES_USE != 1
|
||||
#ifdef Z7_CRC_UPDATE_T1_FUNC_NAME
|
||||
if (g_Crc_Algo == 1)
|
||||
return Z7_CRC_UPDATE_T1_FUNC_NAME(crc, data, size);
|
||||
#endif
|
||||
|
||||
#ifdef MY_CPU_LE
|
||||
return FUNC_NAME_LE(crc, data, size, g_CrcTable);
|
||||
#elif defined(MY_CPU_BE)
|
||||
return FUNC_NAME_BE(crc, data, size, g_CrcTable);
|
||||
#else
|
||||
if (g_Crc_Be)
|
||||
return FUNC_NAME_BE(crc, data, size, g_CrcTable);
|
||||
else
|
||||
return FUNC_NAME_LE(crc, data, size, g_CrcTable);
|
||||
#endif
|
||||
#endif // Z7_CRC_NUM_TABLES_USE != 1
|
||||
}
|
||||
|
||||
|
||||
#ifdef Z7_CRC_HW_USE
|
||||
Z7_NO_INLINE
|
||||
UInt32 Z7_FASTCALL CrcUpdate(UInt32 crc, const void *data, size_t size)
|
||||
{
|
||||
if (g_Crc_Algo == 0)
|
||||
return CrcUpdate_HW(crc, data, size);
|
||||
return CrcUpdate_Base(crc, data, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !defined(Z7_CRC_HW_FORCE)
|
||||
|
||||
|
||||
|
||||
UInt32 Z7_FASTCALL CrcCalc(const void *data, size_t size)
|
||||
{
|
||||
return CrcUpdate(CRC_INIT_VAL, data, size) ^ CRC_INIT_VAL;
|
||||
}
|
||||
|
||||
|
||||
MY_ALIGN(64)
|
||||
UInt32 g_CrcTable[256 * Z7_CRC_NUM_TABLES_TOTAL];
|
||||
|
||||
|
||||
void Z7_FASTCALL CrcGenerateTable(void)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
#if defined(Z7_CRC_HW_FORCE)
|
||||
g_CrcTable[i] = __crc32b(i, 0);
|
||||
#else
|
||||
#define kCrcPoly 0xEDB88320
|
||||
UInt32 r = i;
|
||||
unsigned j;
|
||||
for (j = 0; j < 8; j++)
|
||||
r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
|
||||
g_CrcTable[i] = r;
|
||||
#endif
|
||||
}
|
||||
for (i = 256; i < 256 * Z7_CRC_NUM_TABLES_USE; i++)
|
||||
{
|
||||
const UInt32 r = g_CrcTable[(size_t)i - 256];
|
||||
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
|
||||
}
|
||||
|
||||
#if !defined(Z7_CRC_HW_FORCE) && \
|
||||
(defined(Z7_CRC_HW_USE) || defined(Z7_CRC_UPDATE_T1_FUNC_NAME) || defined(MY_CPU_BE))
|
||||
|
||||
#if Z7_CRC_NUM_TABLES_USE <= 1
|
||||
g_Crc_Algo = 1;
|
||||
#else // Z7_CRC_NUM_TABLES_USE <= 1
|
||||
|
||||
#if defined(MY_CPU_LE)
|
||||
g_Crc_Algo = Z7_CRC_NUM_TABLES_USE;
|
||||
#else // !defined(MY_CPU_LE)
|
||||
{
|
||||
#ifndef MY_CPU_BE
|
||||
UInt32 k = 0x01020304;
|
||||
const Byte *p = (const Byte *)&k;
|
||||
if (p[0] == 4 && p[1] == 3)
|
||||
g_Crc_Algo = Z7_CRC_NUM_TABLES_USE;
|
||||
else if (p[0] != 1 || p[1] != 2)
|
||||
g_Crc_Algo = 1;
|
||||
else
|
||||
#endif // MY_CPU_BE
|
||||
{
|
||||
for (i = 256 * Z7_CRC_NUM_TABLES_TOTAL - 1; i >= 256; i--)
|
||||
{
|
||||
const UInt32 x = g_CrcTable[(size_t)i - 256];
|
||||
g_CrcTable[i] = Z7_BSWAP32(x);
|
||||
}
|
||||
#if defined(Z7_CRC_UPDATE_T1_FUNC_NAME)
|
||||
g_Crc_Algo = Z7_CRC_NUM_TABLES_USE;
|
||||
#endif
|
||||
#if (!defined(MY_CPU_LE) && !defined(MY_CPU_BE))
|
||||
g_Crc_Be = 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif // !defined(MY_CPU_LE)
|
||||
|
||||
#ifdef MY_CPU_LE
|
||||
#ifdef Z7_CRC_HW_USE
|
||||
if (CPU_IsSupported_CRC32())
|
||||
g_Crc_Algo = 0;
|
||||
#endif // Z7_CRC_HW_USE
|
||||
#endif // MY_CPU_LE
|
||||
|
||||
#endif // Z7_CRC_NUM_TABLES_USE <= 1
|
||||
#endif // g_Crc_Algo was declared
|
||||
}
|
||||
|
||||
Z7_CRC_UPDATE_FUNC z7_GetFunc_CrcUpdate(unsigned algo)
|
||||
{
|
||||
if (algo == 0)
|
||||
return &CrcUpdate;
|
||||
|
||||
#if defined(Z7_CRC_HW_USE)
|
||||
if (algo == sizeof(CRC_HW_WORD_TYPE) * 8)
|
||||
{
|
||||
#ifdef Z7_CRC_HW_FORCE
|
||||
return &CrcUpdate;
|
||||
#else
|
||||
if (g_Crc_Algo == 0)
|
||||
return &CrcUpdate_HW;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef Z7_CRC_HW_FORCE
|
||||
if (algo == Z7_CRC_NUM_TABLES_USE)
|
||||
return
|
||||
#ifdef Z7_CRC_HW_USE
|
||||
&CrcUpdate_Base;
|
||||
#else
|
||||
&CrcUpdate;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#undef kCrcPoly
|
||||
#undef Z7_CRC_NUM_TABLES_USE
|
||||
#undef Z7_CRC_NUM_TABLES_TOTAL
|
||||
#undef CRC_UPDATE_BYTE_2
|
||||
#undef FUNC_NAME_LE_2
|
||||
#undef FUNC_NAME_LE_1
|
||||
#undef FUNC_NAME_LE
|
||||
#undef FUNC_NAME_BE_2
|
||||
#undef FUNC_NAME_BE_1
|
||||
#undef FUNC_NAME_BE
|
||||
|
||||
#undef CRC_HW_UNROLL_BYTES
|
||||
#undef CRC_HW_WORD_FUNC
|
||||
#undef CRC_HW_WORD_TYPE
|
||||
28
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/C/7zCrc.h
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
/* 7zCrc.h -- CRC32 calculation
|
||||
2024-01-22 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef ZIP7_INC_7Z_CRC_H
|
||||
#define ZIP7_INC_7Z_CRC_H
|
||||
|
||||
#include "7zTypes.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
extern UInt32 g_CrcTable[];
|
||||
|
||||
/* Call CrcGenerateTable one time before other CRC functions */
|
||||
void Z7_FASTCALL CrcGenerateTable(void);
|
||||
|
||||
#define CRC_INIT_VAL 0xFFFFFFFF
|
||||
#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL)
|
||||
#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||
|
||||
UInt32 Z7_FASTCALL CrcUpdate(UInt32 crc, const void *data, size_t size);
|
||||
UInt32 Z7_FASTCALL CrcCalc(const void *data, size_t size);
|
||||
|
||||
typedef UInt32 (Z7_FASTCALL *Z7_CRC_UPDATE_FUNC)(UInt32 v, const void *data, size_t size);
|
||||
Z7_CRC_UPDATE_FUNC z7_GetFunc_CrcUpdate(unsigned algo);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
199
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/C/7zCrcOpt.c
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
/* 7zCrcOpt.c -- CRC32 calculation (optimized functions)
|
||||
2023-12-07 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include "CpuArch.h"
|
||||
|
||||
#if !defined(Z7_CRC_NUM_TABLES) || Z7_CRC_NUM_TABLES > 1
|
||||
|
||||
// for debug only : define Z7_CRC_DEBUG_BE to test big-endian code in little-endian cpu
|
||||
// #define Z7_CRC_DEBUG_BE
|
||||
#ifdef Z7_CRC_DEBUG_BE
|
||||
#undef MY_CPU_LE
|
||||
#define MY_CPU_BE
|
||||
#endif
|
||||
|
||||
// the value Z7_CRC_NUM_TABLES_USE must be defined to same value as in 7zCrc.c
|
||||
#ifdef Z7_CRC_NUM_TABLES
|
||||
#define Z7_CRC_NUM_TABLES_USE Z7_CRC_NUM_TABLES
|
||||
#else
|
||||
#define Z7_CRC_NUM_TABLES_USE 12
|
||||
#endif
|
||||
|
||||
#if Z7_CRC_NUM_TABLES_USE % 4 || \
|
||||
Z7_CRC_NUM_TABLES_USE < 4 * 1 || \
|
||||
Z7_CRC_NUM_TABLES_USE > 4 * 6
|
||||
#error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef MY_CPU_BE
|
||||
|
||||
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||
|
||||
#define Q(n, d) \
|
||||
( (table + ((n) * 4 + 3) * 0x100)[(Byte)(d)] \
|
||||
^ (table + ((n) * 4 + 2) * 0x100)[((d) >> 1 * 8) & 0xFF] \
|
||||
^ (table + ((n) * 4 + 1) * 0x100)[((d) >> 2 * 8) & 0xFF] \
|
||||
^ (table + ((n) * 4 + 0) * 0x100)[((d) >> 3 * 8)] )
|
||||
|
||||
#define R(a) *((const UInt32 *)(const void *)p + (a))
|
||||
|
||||
#define CRC_FUNC_PRE_LE2(step) \
|
||||
UInt32 Z7_FASTCALL CrcUpdateT ## step (UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||
|
||||
#define CRC_FUNC_PRE_LE(step) \
|
||||
CRC_FUNC_PRE_LE2(step); \
|
||||
CRC_FUNC_PRE_LE2(step)
|
||||
|
||||
CRC_FUNC_PRE_LE(Z7_CRC_NUM_TABLES_USE)
|
||||
{
|
||||
const Byte *p = (const Byte *)data;
|
||||
const Byte *lim;
|
||||
for (; size && ((unsigned)(ptrdiff_t)p & (7 - (Z7_CRC_NUM_TABLES_USE & 4))) != 0; size--, p++)
|
||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||
lim = p + size;
|
||||
if (size >= Z7_CRC_NUM_TABLES_USE)
|
||||
{
|
||||
lim -= Z7_CRC_NUM_TABLES_USE;
|
||||
do
|
||||
{
|
||||
v ^= R(0);
|
||||
{
|
||||
#if Z7_CRC_NUM_TABLES_USE == 1 * 4
|
||||
v = Q(0, v);
|
||||
#else
|
||||
#define U2(r, op) \
|
||||
{ d = R(r); x op Q(Z7_CRC_NUM_TABLES_USE / 4 - 1 - (r), d); }
|
||||
UInt32 d, x;
|
||||
U2(1, =)
|
||||
#if Z7_CRC_NUM_TABLES_USE >= 3 * 4
|
||||
#define U(r) U2(r, ^=)
|
||||
U(2)
|
||||
#if Z7_CRC_NUM_TABLES_USE >= 4 * 4
|
||||
U(3)
|
||||
#if Z7_CRC_NUM_TABLES_USE >= 5 * 4
|
||||
U(4)
|
||||
#if Z7_CRC_NUM_TABLES_USE >= 6 * 4
|
||||
U(5)
|
||||
#if Z7_CRC_NUM_TABLES_USE >= 7 * 4
|
||||
#error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#undef U
|
||||
#undef U2
|
||||
v = x ^ Q(Z7_CRC_NUM_TABLES_USE / 4 - 1, v);
|
||||
#endif
|
||||
}
|
||||
p += Z7_CRC_NUM_TABLES_USE;
|
||||
}
|
||||
while (p <= lim);
|
||||
lim += Z7_CRC_NUM_TABLES_USE;
|
||||
}
|
||||
for (; p < lim; p++)
|
||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||
return v;
|
||||
}
|
||||
|
||||
#undef CRC_UPDATE_BYTE_2
|
||||
#undef R
|
||||
#undef Q
|
||||
#undef CRC_FUNC_PRE_LE
|
||||
#undef CRC_FUNC_PRE_LE2
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef MY_CPU_LE
|
||||
|
||||
#define CRC_UPDATE_BYTE_2_BE(crc, b) (table[((crc) >> 24) ^ (b)] ^ ((crc) << 8))
|
||||
|
||||
#define Q(n, d) \
|
||||
( (table + ((n) * 4 + 0) * 0x100)[((d)) & 0xFF] \
|
||||
^ (table + ((n) * 4 + 1) * 0x100)[((d) >> 1 * 8) & 0xFF] \
|
||||
^ (table + ((n) * 4 + 2) * 0x100)[((d) >> 2 * 8) & 0xFF] \
|
||||
^ (table + ((n) * 4 + 3) * 0x100)[((d) >> 3 * 8)] )
|
||||
|
||||
#ifdef Z7_CRC_DEBUG_BE
|
||||
#define R(a) GetBe32a((const UInt32 *)(const void *)p + (a))
|
||||
#else
|
||||
#define R(a) *((const UInt32 *)(const void *)p + (a))
|
||||
#endif
|
||||
|
||||
|
||||
#define CRC_FUNC_PRE_BE2(step) \
|
||||
UInt32 Z7_FASTCALL CrcUpdateT1_BeT ## step (UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||
|
||||
#define CRC_FUNC_PRE_BE(step) \
|
||||
CRC_FUNC_PRE_BE2(step); \
|
||||
CRC_FUNC_PRE_BE2(step)
|
||||
|
||||
CRC_FUNC_PRE_BE(Z7_CRC_NUM_TABLES_USE)
|
||||
{
|
||||
const Byte *p = (const Byte *)data;
|
||||
const Byte *lim;
|
||||
table += 0x100;
|
||||
v = Z7_BSWAP32(v);
|
||||
for (; size && ((unsigned)(ptrdiff_t)p & (7 - (Z7_CRC_NUM_TABLES_USE & 4))) != 0; size--, p++)
|
||||
v = CRC_UPDATE_BYTE_2_BE(v, *p);
|
||||
lim = p + size;
|
||||
if (size >= Z7_CRC_NUM_TABLES_USE)
|
||||
{
|
||||
lim -= Z7_CRC_NUM_TABLES_USE;
|
||||
do
|
||||
{
|
||||
v ^= R(0);
|
||||
{
|
||||
#if Z7_CRC_NUM_TABLES_USE == 1 * 4
|
||||
v = Q(0, v);
|
||||
#else
|
||||
#define U2(r, op) \
|
||||
{ d = R(r); x op Q(Z7_CRC_NUM_TABLES_USE / 4 - 1 - (r), d); }
|
||||
UInt32 d, x;
|
||||
U2(1, =)
|
||||
#if Z7_CRC_NUM_TABLES_USE >= 3 * 4
|
||||
#define U(r) U2(r, ^=)
|
||||
U(2)
|
||||
#if Z7_CRC_NUM_TABLES_USE >= 4 * 4
|
||||
U(3)
|
||||
#if Z7_CRC_NUM_TABLES_USE >= 5 * 4
|
||||
U(4)
|
||||
#if Z7_CRC_NUM_TABLES_USE >= 6 * 4
|
||||
U(5)
|
||||
#if Z7_CRC_NUM_TABLES_USE >= 7 * 4
|
||||
#error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#undef U
|
||||
#undef U2
|
||||
v = x ^ Q(Z7_CRC_NUM_TABLES_USE / 4 - 1, v);
|
||||
#endif
|
||||
}
|
||||
p += Z7_CRC_NUM_TABLES_USE;
|
||||
}
|
||||
while (p <= lim);
|
||||
lim += Z7_CRC_NUM_TABLES_USE;
|
||||
}
|
||||
for (; p < lim; p++)
|
||||
v = CRC_UPDATE_BYTE_2_BE(v, *p);
|
||||
return Z7_BSWAP32(v);
|
||||
}
|
||||
|
||||
#undef CRC_UPDATE_BYTE_2_BE
|
||||
#undef R
|
||||
#undef Q
|
||||
#undef CRC_FUNC_PRE_BE
|
||||
#undef CRC_FUNC_PRE_BE2
|
||||
|
||||
#endif
|
||||
#undef Z7_CRC_NUM_TABLES_USE
|
||||
#endif
|
||||
672
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/C/7zDec.c
vendored
Normal file
@@ -0,0 +1,672 @@
|
||||
/* 7zDec.c -- Decoding from 7z folder
|
||||
2024-03-01 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* #define Z7_PPMD_SUPPORT */
|
||||
|
||||
#include "7z.h"
|
||||
#include "7zCrc.h"
|
||||
|
||||
#include "Bcj2.h"
|
||||
#include "Bra.h"
|
||||
#include "CpuArch.h"
|
||||
#include "Delta.h"
|
||||
#include "LzmaDec.h"
|
||||
#include "Lzma2Dec.h"
|
||||
#ifdef Z7_PPMD_SUPPORT
|
||||
#include "Ppmd7.h"
|
||||
#endif
|
||||
|
||||
#define k_Copy 0
|
||||
#ifndef Z7_NO_METHOD_LZMA2
|
||||
#define k_LZMA2 0x21
|
||||
#endif
|
||||
#define k_LZMA 0x30101
|
||||
#define k_BCJ2 0x303011B
|
||||
|
||||
#if !defined(Z7_NO_METHODS_FILTERS)
|
||||
#define Z7_USE_BRANCH_FILTER
|
||||
#endif
|
||||
|
||||
#if !defined(Z7_NO_METHODS_FILTERS) || \
|
||||
defined(Z7_USE_NATIVE_BRANCH_FILTER) && defined(MY_CPU_ARM64)
|
||||
#define Z7_USE_FILTER_ARM64
|
||||
#ifndef Z7_USE_BRANCH_FILTER
|
||||
#define Z7_USE_BRANCH_FILTER
|
||||
#endif
|
||||
#define k_ARM64 0xa
|
||||
#endif
|
||||
|
||||
#if !defined(Z7_NO_METHODS_FILTERS) || \
|
||||
defined(Z7_USE_NATIVE_BRANCH_FILTER) && defined(MY_CPU_ARMT)
|
||||
#define Z7_USE_FILTER_ARMT
|
||||
#ifndef Z7_USE_BRANCH_FILTER
|
||||
#define Z7_USE_BRANCH_FILTER
|
||||
#endif
|
||||
#define k_ARMT 0x3030701
|
||||
#endif
|
||||
|
||||
#ifndef Z7_NO_METHODS_FILTERS
|
||||
#define k_Delta 3
|
||||
#define k_RISCV 0xb
|
||||
#define k_BCJ 0x3030103
|
||||
#define k_PPC 0x3030205
|
||||
#define k_IA64 0x3030401
|
||||
#define k_ARM 0x3030501
|
||||
#define k_SPARC 0x3030805
|
||||
#endif
|
||||
|
||||
#ifdef Z7_PPMD_SUPPORT
|
||||
|
||||
#define k_PPMD 0x30401
|
||||
|
||||
typedef struct
|
||||
{
|
||||
IByteIn vt;
|
||||
const Byte *cur;
|
||||
const Byte *end;
|
||||
const Byte *begin;
|
||||
UInt64 processed;
|
||||
BoolInt extra;
|
||||
SRes res;
|
||||
ILookInStreamPtr inStream;
|
||||
} CByteInToLook;
|
||||
|
||||
static Byte ReadByte(IByteInPtr pp)
|
||||
{
|
||||
Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CByteInToLook)
|
||||
if (p->cur != p->end)
|
||||
return *p->cur++;
|
||||
if (p->res == SZ_OK)
|
||||
{
|
||||
size_t size = (size_t)(p->cur - p->begin);
|
||||
p->processed += size;
|
||||
p->res = ILookInStream_Skip(p->inStream, size);
|
||||
size = (1 << 25);
|
||||
p->res = ILookInStream_Look(p->inStream, (const void **)&p->begin, &size);
|
||||
p->cur = p->begin;
|
||||
p->end = p->begin + size;
|
||||
if (size != 0)
|
||||
return *p->cur++;
|
||||
}
|
||||
p->extra = True;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream,
|
||||
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
|
||||
{
|
||||
CPpmd7 ppmd;
|
||||
CByteInToLook s;
|
||||
SRes res = SZ_OK;
|
||||
|
||||
s.vt.Read = ReadByte;
|
||||
s.inStream = inStream;
|
||||
s.begin = s.end = s.cur = NULL;
|
||||
s.extra = False;
|
||||
s.res = SZ_OK;
|
||||
s.processed = 0;
|
||||
|
||||
if (propsSize != 5)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
|
||||
{
|
||||
unsigned order = props[0];
|
||||
UInt32 memSize = GetUi32(props + 1);
|
||||
if (order < PPMD7_MIN_ORDER ||
|
||||
order > PPMD7_MAX_ORDER ||
|
||||
memSize < PPMD7_MIN_MEM_SIZE ||
|
||||
memSize > PPMD7_MAX_MEM_SIZE)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
Ppmd7_Construct(&ppmd);
|
||||
if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
|
||||
return SZ_ERROR_MEM;
|
||||
Ppmd7_Init(&ppmd, order);
|
||||
}
|
||||
{
|
||||
ppmd.rc.dec.Stream = &s.vt;
|
||||
if (!Ppmd7z_RangeDec_Init(&ppmd.rc.dec))
|
||||
res = SZ_ERROR_DATA;
|
||||
else if (!s.extra)
|
||||
{
|
||||
Byte *buf = outBuffer;
|
||||
const Byte *lim = buf + outSize;
|
||||
for (; buf != lim; buf++)
|
||||
{
|
||||
int sym = Ppmd7z_DecodeSymbol(&ppmd);
|
||||
if (s.extra || sym < 0)
|
||||
break;
|
||||
*buf = (Byte)sym;
|
||||
}
|
||||
if (buf != lim)
|
||||
res = SZ_ERROR_DATA;
|
||||
else if (!Ppmd7z_RangeDec_IsFinishedOK(&ppmd.rc.dec))
|
||||
{
|
||||
/* if (Ppmd7z_DecodeSymbol(&ppmd) != PPMD7_SYM_END || !Ppmd7z_RangeDec_IsFinishedOK(&ppmd.rc.dec)) */
|
||||
res = SZ_ERROR_DATA;
|
||||
}
|
||||
}
|
||||
if (s.extra)
|
||||
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
|
||||
else if (s.processed + (size_t)(s.cur - s.begin) != inSize)
|
||||
res = SZ_ERROR_DATA;
|
||||
}
|
||||
Ppmd7_Free(&ppmd, allocMain);
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream,
|
||||
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
|
||||
{
|
||||
CLzmaDec state;
|
||||
SRes res = SZ_OK;
|
||||
|
||||
LzmaDec_CONSTRUCT(&state)
|
||||
RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain))
|
||||
state.dic = outBuffer;
|
||||
state.dicBufSize = outSize;
|
||||
LzmaDec_Init(&state);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const void *inBuf = NULL;
|
||||
size_t lookahead = (1 << 18);
|
||||
if (lookahead > inSize)
|
||||
lookahead = (size_t)inSize;
|
||||
res = ILookInStream_Look(inStream, &inBuf, &lookahead);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
|
||||
{
|
||||
SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
|
||||
ELzmaStatus status;
|
||||
res = LzmaDec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status);
|
||||
lookahead -= inProcessed;
|
||||
inSize -= inProcessed;
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
|
||||
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
|
||||
{
|
||||
if (outSize != state.dicPos || inSize != 0)
|
||||
res = SZ_ERROR_DATA;
|
||||
break;
|
||||
}
|
||||
|
||||
if (outSize == state.dicPos && inSize == 0 && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
|
||||
break;
|
||||
|
||||
if (inProcessed == 0 && dicPos == state.dicPos)
|
||||
{
|
||||
res = SZ_ERROR_DATA;
|
||||
break;
|
||||
}
|
||||
|
||||
res = ILookInStream_Skip(inStream, inProcessed);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LzmaDec_FreeProbs(&state, allocMain);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
#ifndef Z7_NO_METHOD_LZMA2
|
||||
|
||||
static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream,
|
||||
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
|
||||
{
|
||||
CLzma2Dec state;
|
||||
SRes res = SZ_OK;
|
||||
|
||||
Lzma2Dec_CONSTRUCT(&state)
|
||||
if (propsSize != 1)
|
||||
return SZ_ERROR_DATA;
|
||||
RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain))
|
||||
state.decoder.dic = outBuffer;
|
||||
state.decoder.dicBufSize = outSize;
|
||||
Lzma2Dec_Init(&state);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const void *inBuf = NULL;
|
||||
size_t lookahead = (1 << 18);
|
||||
if (lookahead > inSize)
|
||||
lookahead = (size_t)inSize;
|
||||
res = ILookInStream_Look(inStream, &inBuf, &lookahead);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
|
||||
{
|
||||
SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
|
||||
ELzmaStatus status;
|
||||
res = Lzma2Dec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status);
|
||||
lookahead -= inProcessed;
|
||||
inSize -= inProcessed;
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
|
||||
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
|
||||
{
|
||||
if (outSize != state.decoder.dicPos || inSize != 0)
|
||||
res = SZ_ERROR_DATA;
|
||||
break;
|
||||
}
|
||||
|
||||
if (inProcessed == 0 && dicPos == state.decoder.dicPos)
|
||||
{
|
||||
res = SZ_ERROR_DATA;
|
||||
break;
|
||||
}
|
||||
|
||||
res = ILookInStream_Skip(inStream, inProcessed);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Lzma2Dec_FreeProbs(&state, allocMain);
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static SRes SzDecodeCopy(UInt64 inSize, ILookInStreamPtr inStream, Byte *outBuffer)
|
||||
{
|
||||
while (inSize > 0)
|
||||
{
|
||||
const void *inBuf;
|
||||
size_t curSize = (1 << 18);
|
||||
if (curSize > inSize)
|
||||
curSize = (size_t)inSize;
|
||||
RINOK(ILookInStream_Look(inStream, &inBuf, &curSize))
|
||||
if (curSize == 0)
|
||||
return SZ_ERROR_INPUT_EOF;
|
||||
memcpy(outBuffer, inBuf, curSize);
|
||||
outBuffer += curSize;
|
||||
inSize -= curSize;
|
||||
RINOK(ILookInStream_Skip(inStream, curSize))
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static BoolInt IS_MAIN_METHOD(UInt32 m)
|
||||
{
|
||||
switch (m)
|
||||
{
|
||||
case k_Copy:
|
||||
case k_LZMA:
|
||||
#ifndef Z7_NO_METHOD_LZMA2
|
||||
case k_LZMA2:
|
||||
#endif
|
||||
#ifdef Z7_PPMD_SUPPORT
|
||||
case k_PPMD:
|
||||
#endif
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
static BoolInt IS_SUPPORTED_CODER(const CSzCoderInfo *c)
|
||||
{
|
||||
return
|
||||
c->NumStreams == 1
|
||||
/* && c->MethodID <= (UInt32)0xFFFFFFFF */
|
||||
&& IS_MAIN_METHOD((UInt32)c->MethodID);
|
||||
}
|
||||
|
||||
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumStreams == 4)
|
||||
|
||||
static SRes CheckSupportedFolder(const CSzFolder *f)
|
||||
{
|
||||
if (f->NumCoders < 1 || f->NumCoders > 4)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (!IS_SUPPORTED_CODER(&f->Coders[0]))
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (f->NumCoders == 1)
|
||||
{
|
||||
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBonds != 0)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
|
||||
#if defined(Z7_USE_BRANCH_FILTER)
|
||||
|
||||
if (f->NumCoders == 2)
|
||||
{
|
||||
const CSzCoderInfo *c = &f->Coders[1];
|
||||
if (
|
||||
/* c->MethodID > (UInt32)0xFFFFFFFF || */
|
||||
c->NumStreams != 1
|
||||
|| f->NumPackStreams != 1
|
||||
|| f->PackStreams[0] != 0
|
||||
|| f->NumBonds != 1
|
||||
|| f->Bonds[0].InIndex != 1
|
||||
|| f->Bonds[0].OutIndex != 0)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
switch ((UInt32)c->MethodID)
|
||||
{
|
||||
#if !defined(Z7_NO_METHODS_FILTERS)
|
||||
case k_Delta:
|
||||
case k_BCJ:
|
||||
case k_PPC:
|
||||
case k_IA64:
|
||||
case k_SPARC:
|
||||
case k_ARM:
|
||||
case k_RISCV:
|
||||
#endif
|
||||
#ifdef Z7_USE_FILTER_ARM64
|
||||
case k_ARM64:
|
||||
#endif
|
||||
#ifdef Z7_USE_FILTER_ARMT
|
||||
case k_ARMT:
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
if (f->NumCoders == 4)
|
||||
{
|
||||
if (!IS_SUPPORTED_CODER(&f->Coders[1])
|
||||
|| !IS_SUPPORTED_CODER(&f->Coders[2])
|
||||
|| !IS_BCJ2(&f->Coders[3]))
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (f->NumPackStreams != 4
|
||||
|| f->PackStreams[0] != 2
|
||||
|| f->PackStreams[1] != 6
|
||||
|| f->PackStreams[2] != 1
|
||||
|| f->PackStreams[3] != 0
|
||||
|| f->NumBonds != 3
|
||||
|| f->Bonds[0].InIndex != 5 || f->Bonds[0].OutIndex != 0
|
||||
|| f->Bonds[1].InIndex != 4 || f->Bonds[1].OutIndex != 1
|
||||
|| f->Bonds[2].InIndex != 3 || f->Bonds[2].OutIndex != 2)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static SRes SzFolder_Decode2(const CSzFolder *folder,
|
||||
const Byte *propsData,
|
||||
const UInt64 *unpackSizes,
|
||||
const UInt64 *packPositions,
|
||||
ILookInStreamPtr inStream, UInt64 startPos,
|
||||
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain,
|
||||
Byte *tempBuf[])
|
||||
{
|
||||
UInt32 ci;
|
||||
SizeT tempSizes[3] = { 0, 0, 0};
|
||||
SizeT tempSize3 = 0;
|
||||
Byte *tempBuf3 = 0;
|
||||
|
||||
RINOK(CheckSupportedFolder(folder))
|
||||
|
||||
for (ci = 0; ci < folder->NumCoders; ci++)
|
||||
{
|
||||
const CSzCoderInfo *coder = &folder->Coders[ci];
|
||||
|
||||
if (IS_MAIN_METHOD((UInt32)coder->MethodID))
|
||||
{
|
||||
UInt32 si = 0;
|
||||
UInt64 offset;
|
||||
UInt64 inSize;
|
||||
Byte *outBufCur = outBuffer;
|
||||
SizeT outSizeCur = outSize;
|
||||
if (folder->NumCoders == 4)
|
||||
{
|
||||
const UInt32 indices[] = { 3, 2, 0 };
|
||||
const UInt64 unpackSize = unpackSizes[ci];
|
||||
si = indices[ci];
|
||||
if (ci < 2)
|
||||
{
|
||||
Byte *temp;
|
||||
outSizeCur = (SizeT)unpackSize;
|
||||
if (outSizeCur != unpackSize)
|
||||
return SZ_ERROR_MEM;
|
||||
temp = (Byte *)ISzAlloc_Alloc(allocMain, outSizeCur);
|
||||
if (!temp && outSizeCur != 0)
|
||||
return SZ_ERROR_MEM;
|
||||
outBufCur = tempBuf[1 - ci] = temp;
|
||||
tempSizes[1 - ci] = outSizeCur;
|
||||
}
|
||||
else if (ci == 2)
|
||||
{
|
||||
if (unpackSize > outSize) /* check it */
|
||||
return SZ_ERROR_PARAM;
|
||||
tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
|
||||
tempSize3 = outSizeCur = (SizeT)unpackSize;
|
||||
}
|
||||
else
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
offset = packPositions[si];
|
||||
inSize = packPositions[(size_t)si + 1] - offset;
|
||||
RINOK(LookInStream_SeekTo(inStream, startPos + offset))
|
||||
|
||||
if (coder->MethodID == k_Copy)
|
||||
{
|
||||
if (inSize != outSizeCur) /* check it */
|
||||
return SZ_ERROR_DATA;
|
||||
RINOK(SzDecodeCopy(inSize, inStream, outBufCur))
|
||||
}
|
||||
else if (coder->MethodID == k_LZMA)
|
||||
{
|
||||
RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain))
|
||||
}
|
||||
#ifndef Z7_NO_METHOD_LZMA2
|
||||
else if (coder->MethodID == k_LZMA2)
|
||||
{
|
||||
RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain))
|
||||
}
|
||||
#endif
|
||||
#ifdef Z7_PPMD_SUPPORT
|
||||
else if (coder->MethodID == k_PPMD)
|
||||
{
|
||||
RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain))
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
else if (coder->MethodID == k_BCJ2)
|
||||
{
|
||||
const UInt64 offset = packPositions[1];
|
||||
const UInt64 s3Size = packPositions[2] - offset;
|
||||
|
||||
if (ci != 3)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
|
||||
tempSizes[2] = (SizeT)s3Size;
|
||||
if (tempSizes[2] != s3Size)
|
||||
return SZ_ERROR_MEM;
|
||||
tempBuf[2] = (Byte *)ISzAlloc_Alloc(allocMain, tempSizes[2]);
|
||||
if (!tempBuf[2] && tempSizes[2] != 0)
|
||||
return SZ_ERROR_MEM;
|
||||
|
||||
RINOK(LookInStream_SeekTo(inStream, startPos + offset))
|
||||
RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2]))
|
||||
|
||||
if ((tempSizes[0] & 3) != 0 ||
|
||||
(tempSizes[1] & 3) != 0 ||
|
||||
tempSize3 + tempSizes[0] + tempSizes[1] != outSize)
|
||||
return SZ_ERROR_DATA;
|
||||
|
||||
{
|
||||
CBcj2Dec p;
|
||||
|
||||
p.bufs[0] = tempBuf3; p.lims[0] = tempBuf3 + tempSize3;
|
||||
p.bufs[1] = tempBuf[0]; p.lims[1] = tempBuf[0] + tempSizes[0];
|
||||
p.bufs[2] = tempBuf[1]; p.lims[2] = tempBuf[1] + tempSizes[1];
|
||||
p.bufs[3] = tempBuf[2]; p.lims[3] = tempBuf[2] + tempSizes[2];
|
||||
|
||||
p.dest = outBuffer;
|
||||
p.destLim = outBuffer + outSize;
|
||||
|
||||
Bcj2Dec_Init(&p);
|
||||
RINOK(Bcj2Dec_Decode(&p))
|
||||
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < 4; i++)
|
||||
if (p.bufs[i] != p.lims[i])
|
||||
return SZ_ERROR_DATA;
|
||||
if (p.dest != p.destLim || !Bcj2Dec_IsMaybeFinished(&p))
|
||||
return SZ_ERROR_DATA;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined(Z7_USE_BRANCH_FILTER)
|
||||
else if (ci == 1)
|
||||
{
|
||||
#if !defined(Z7_NO_METHODS_FILTERS)
|
||||
if (coder->MethodID == k_Delta)
|
||||
{
|
||||
if (coder->PropsSize != 1)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
{
|
||||
Byte state[DELTA_STATE_SIZE];
|
||||
Delta_Init(state);
|
||||
Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef Z7_USE_FILTER_ARM64
|
||||
if (coder->MethodID == k_ARM64)
|
||||
{
|
||||
UInt32 pc = 0;
|
||||
if (coder->PropsSize == 4)
|
||||
{
|
||||
pc = GetUi32(propsData + coder->PropsOffset);
|
||||
if (pc & 3)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
else if (coder->PropsSize != 0)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
z7_BranchConv_ARM64_Dec(outBuffer, outSize, pc);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(Z7_NO_METHODS_FILTERS)
|
||||
if (coder->MethodID == k_RISCV)
|
||||
{
|
||||
UInt32 pc = 0;
|
||||
if (coder->PropsSize == 4)
|
||||
{
|
||||
pc = GetUi32(propsData + coder->PropsOffset);
|
||||
if (pc & 1)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
else if (coder->PropsSize != 0)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
z7_BranchConv_RISCV_Dec(outBuffer, outSize, pc);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(Z7_NO_METHODS_FILTERS) || defined(Z7_USE_FILTER_ARMT)
|
||||
{
|
||||
if (coder->PropsSize != 0)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
#define CASE_BRA_CONV(isa) case k_ ## isa: Z7_BRANCH_CONV_DEC(isa)(outBuffer, outSize, 0); break; // pc = 0;
|
||||
switch (coder->MethodID)
|
||||
{
|
||||
#if !defined(Z7_NO_METHODS_FILTERS)
|
||||
case k_BCJ:
|
||||
{
|
||||
UInt32 state = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL;
|
||||
z7_BranchConvSt_X86_Dec(outBuffer, outSize, 0, &state); // pc = 0
|
||||
break;
|
||||
}
|
||||
case k_PPC: Z7_BRANCH_CONV_DEC_2(BranchConv_PPC)(outBuffer, outSize, 0); break; // pc = 0;
|
||||
// CASE_BRA_CONV(PPC)
|
||||
CASE_BRA_CONV(IA64)
|
||||
CASE_BRA_CONV(SPARC)
|
||||
CASE_BRA_CONV(ARM)
|
||||
#endif
|
||||
#if !defined(Z7_NO_METHODS_FILTERS) || defined(Z7_USE_FILTER_ARMT)
|
||||
CASE_BRA_CONV(ARMT)
|
||||
#endif
|
||||
default:
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
} // (c == 1)
|
||||
#endif // Z7_USE_BRANCH_FILTER
|
||||
else
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
|
||||
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
|
||||
ILookInStreamPtr inStream, UInt64 startPos,
|
||||
Byte *outBuffer, size_t outSize,
|
||||
ISzAllocPtr allocMain)
|
||||
{
|
||||
SRes res;
|
||||
CSzFolder folder;
|
||||
CSzData sd;
|
||||
|
||||
const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
|
||||
sd.Data = data;
|
||||
sd.Size = p->FoCodersOffsets[(size_t)folderIndex + 1] - p->FoCodersOffsets[folderIndex];
|
||||
|
||||
res = SzGetNextFolderItem(&folder, &sd);
|
||||
|
||||
if (res != SZ_OK)
|
||||
return res;
|
||||
|
||||
if (sd.Size != 0
|
||||
|| folder.UnpackStream != p->FoToMainUnpackSizeIndex[folderIndex]
|
||||
|| outSize != SzAr_GetFolderUnpackSize(p, folderIndex))
|
||||
return SZ_ERROR_FAIL;
|
||||
{
|
||||
unsigned i;
|
||||
Byte *tempBuf[3] = { 0, 0, 0};
|
||||
|
||||
res = SzFolder_Decode2(&folder, data,
|
||||
&p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex]],
|
||||
p->PackPositions + p->FoStartPackStreamIndex[folderIndex],
|
||||
inStream, startPos,
|
||||
outBuffer, (SizeT)outSize, allocMain, tempBuf);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
ISzAlloc_Free(allocMain, tempBuf[i]);
|
||||
|
||||
if (res == SZ_OK)
|
||||
if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))
|
||||
if (CrcCalc(outBuffer, outSize) != p->FolderCRCs.Vals[folderIndex])
|
||||
res = SZ_ERROR_CRC;
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
443
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/C/7zFile.c
vendored
Normal file
@@ -0,0 +1,443 @@
|
||||
/* 7zFile.c -- File IO
|
||||
2023-04-02 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include "7zFile.h"
|
||||
|
||||
#ifndef USE_WINDOWS_FILE
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef USE_FOPEN
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
typedef int ssize_t;
|
||||
typedef int off_t;
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
ReadFile and WriteFile functions in Windows have BUG:
|
||||
If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
|
||||
from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
|
||||
(Insufficient system resources exist to complete the requested service).
|
||||
Probably in some version of Windows there are problems with other sizes:
|
||||
for 32 MB (maybe also for 16 MB).
|
||||
And message can be "Network connection was lost"
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
#define kChunkSizeMax (1 << 22)
|
||||
|
||||
void File_Construct(CSzFile *p)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
p->handle = INVALID_HANDLE_VALUE;
|
||||
#elif defined(USE_FOPEN)
|
||||
p->file = NULL;
|
||||
#else
|
||||
p->fd = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
|
||||
|
||||
static WRes File_Open(CSzFile *p, const char *name, int writeMode)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
|
||||
p->handle = CreateFileA(name,
|
||||
writeMode ? GENERIC_WRITE : GENERIC_READ,
|
||||
FILE_SHARE_READ, NULL,
|
||||
writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
|
||||
|
||||
#elif defined(USE_FOPEN)
|
||||
|
||||
p->file = fopen(name, writeMode ? "wb+" : "rb");
|
||||
return (p->file != 0) ? 0 :
|
||||
#ifdef UNDER_CE
|
||||
2; /* ENOENT */
|
||||
#else
|
||||
errno;
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
int flags = (writeMode ? (O_CREAT | O_EXCL | O_WRONLY) : O_RDONLY);
|
||||
#ifdef O_BINARY
|
||||
flags |= O_BINARY;
|
||||
#endif
|
||||
p->fd = open(name, flags, 0666);
|
||||
return (p->fd != -1) ? 0 : errno;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
|
||||
|
||||
WRes OutFile_Open(CSzFile *p, const char *name)
|
||||
{
|
||||
#if defined(USE_WINDOWS_FILE) || defined(USE_FOPEN)
|
||||
return File_Open(p, name, 1);
|
||||
#else
|
||||
p->fd = creat(name, 0666);
|
||||
return (p->fd != -1) ? 0 : errno;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode)
|
||||
{
|
||||
p->handle = CreateFileW(name,
|
||||
writeMode ? GENERIC_WRITE : GENERIC_READ,
|
||||
FILE_SHARE_READ, NULL,
|
||||
writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
|
||||
}
|
||||
WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); }
|
||||
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); }
|
||||
#endif
|
||||
|
||||
WRes File_Close(CSzFile *p)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
|
||||
if (p->handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (!CloseHandle(p->handle))
|
||||
return GetLastError();
|
||||
p->handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
#elif defined(USE_FOPEN)
|
||||
|
||||
if (p->file != NULL)
|
||||
{
|
||||
int res = fclose(p->file);
|
||||
if (res != 0)
|
||||
{
|
||||
if (res == EOF)
|
||||
return errno;
|
||||
return res;
|
||||
}
|
||||
p->file = NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if (p->fd != -1)
|
||||
{
|
||||
if (close(p->fd) != 0)
|
||||
return errno;
|
||||
p->fd = -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
WRes File_Read(CSzFile *p, void *data, size_t *size)
|
||||
{
|
||||
size_t originalSize = *size;
|
||||
*size = 0;
|
||||
if (originalSize == 0)
|
||||
return 0;
|
||||
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
|
||||
do
|
||||
{
|
||||
const DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
|
||||
DWORD processed = 0;
|
||||
const BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);
|
||||
data = (void *)((Byte *)data + processed);
|
||||
originalSize -= processed;
|
||||
*size += processed;
|
||||
if (!res)
|
||||
return GetLastError();
|
||||
// debug : we can break here for partial reading mode
|
||||
if (processed == 0)
|
||||
break;
|
||||
}
|
||||
while (originalSize > 0);
|
||||
|
||||
#elif defined(USE_FOPEN)
|
||||
|
||||
do
|
||||
{
|
||||
const size_t curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : originalSize;
|
||||
const size_t processed = fread(data, 1, curSize, p->file);
|
||||
data = (void *)((Byte *)data + (size_t)processed);
|
||||
originalSize -= processed;
|
||||
*size += processed;
|
||||
if (processed != curSize)
|
||||
return ferror(p->file);
|
||||
// debug : we can break here for partial reading mode
|
||||
if (processed == 0)
|
||||
break;
|
||||
}
|
||||
while (originalSize > 0);
|
||||
|
||||
#else
|
||||
|
||||
do
|
||||
{
|
||||
const size_t curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : originalSize;
|
||||
const ssize_t processed = read(p->fd, data, curSize);
|
||||
if (processed == -1)
|
||||
return errno;
|
||||
if (processed == 0)
|
||||
break;
|
||||
data = (void *)((Byte *)data + (size_t)processed);
|
||||
originalSize -= (size_t)processed;
|
||||
*size += (size_t)processed;
|
||||
// debug : we can break here for partial reading mode
|
||||
// break;
|
||||
}
|
||||
while (originalSize > 0);
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
WRes File_Write(CSzFile *p, const void *data, size_t *size)
|
||||
{
|
||||
size_t originalSize = *size;
|
||||
*size = 0;
|
||||
if (originalSize == 0)
|
||||
return 0;
|
||||
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
|
||||
do
|
||||
{
|
||||
const DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
|
||||
DWORD processed = 0;
|
||||
const BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL);
|
||||
data = (const void *)((const Byte *)data + processed);
|
||||
originalSize -= processed;
|
||||
*size += processed;
|
||||
if (!res)
|
||||
return GetLastError();
|
||||
if (processed == 0)
|
||||
break;
|
||||
}
|
||||
while (originalSize > 0);
|
||||
|
||||
#elif defined(USE_FOPEN)
|
||||
|
||||
do
|
||||
{
|
||||
const size_t curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : originalSize;
|
||||
const size_t processed = fwrite(data, 1, curSize, p->file);
|
||||
data = (void *)((Byte *)data + (size_t)processed);
|
||||
originalSize -= processed;
|
||||
*size += processed;
|
||||
if (processed != curSize)
|
||||
return ferror(p->file);
|
||||
if (processed == 0)
|
||||
break;
|
||||
}
|
||||
while (originalSize > 0);
|
||||
|
||||
#else
|
||||
|
||||
do
|
||||
{
|
||||
const size_t curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : originalSize;
|
||||
const ssize_t processed = write(p->fd, data, curSize);
|
||||
if (processed == -1)
|
||||
return errno;
|
||||
if (processed == 0)
|
||||
break;
|
||||
data = (const void *)((const Byte *)data + (size_t)processed);
|
||||
originalSize -= (size_t)processed;
|
||||
*size += (size_t)processed;
|
||||
}
|
||||
while (originalSize > 0);
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
|
||||
DWORD moveMethod;
|
||||
UInt32 low = (UInt32)*pos;
|
||||
LONG high = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */
|
||||
// (int) to eliminate clang warning
|
||||
switch ((int)origin)
|
||||
{
|
||||
case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;
|
||||
case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;
|
||||
case SZ_SEEK_END: moveMethod = FILE_END; break;
|
||||
default: return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
low = SetFilePointer(p->handle, (LONG)low, &high, moveMethod);
|
||||
if (low == (UInt32)0xFFFFFFFF)
|
||||
{
|
||||
WRes res = GetLastError();
|
||||
if (res != NO_ERROR)
|
||||
return res;
|
||||
}
|
||||
*pos = ((Int64)high << 32) | low;
|
||||
return 0;
|
||||
|
||||
#else
|
||||
|
||||
int moveMethod; // = origin;
|
||||
|
||||
switch ((int)origin)
|
||||
{
|
||||
case SZ_SEEK_SET: moveMethod = SEEK_SET; break;
|
||||
case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;
|
||||
case SZ_SEEK_END: moveMethod = SEEK_END; break;
|
||||
default: return EINVAL;
|
||||
}
|
||||
|
||||
#if defined(USE_FOPEN)
|
||||
{
|
||||
int res = fseek(p->file, (long)*pos, moveMethod);
|
||||
if (res == -1)
|
||||
return errno;
|
||||
*pos = ftell(p->file);
|
||||
if (*pos == -1)
|
||||
return errno;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
{
|
||||
off_t res = lseek(p->fd, (off_t)*pos, moveMethod);
|
||||
if (res == -1)
|
||||
return errno;
|
||||
*pos = res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // USE_FOPEN
|
||||
#endif // USE_WINDOWS_FILE
|
||||
}
|
||||
|
||||
|
||||
WRes File_GetLength(CSzFile *p, UInt64 *length)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
|
||||
DWORD sizeHigh;
|
||||
DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);
|
||||
if (sizeLow == 0xFFFFFFFF)
|
||||
{
|
||||
DWORD res = GetLastError();
|
||||
if (res != NO_ERROR)
|
||||
return res;
|
||||
}
|
||||
*length = (((UInt64)sizeHigh) << 32) + sizeLow;
|
||||
return 0;
|
||||
|
||||
#elif defined(USE_FOPEN)
|
||||
|
||||
long pos = ftell(p->file);
|
||||
int res = fseek(p->file, 0, SEEK_END);
|
||||
*length = ftell(p->file);
|
||||
fseek(p->file, pos, SEEK_SET);
|
||||
return res;
|
||||
|
||||
#else
|
||||
|
||||
off_t pos;
|
||||
*length = 0;
|
||||
pos = lseek(p->fd, 0, SEEK_CUR);
|
||||
if (pos != -1)
|
||||
{
|
||||
const off_t len2 = lseek(p->fd, 0, SEEK_END);
|
||||
const off_t res2 = lseek(p->fd, pos, SEEK_SET);
|
||||
if (len2 != -1)
|
||||
{
|
||||
*length = (UInt64)len2;
|
||||
if (res2 != -1)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return errno;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* ---------- FileSeqInStream ---------- */
|
||||
|
||||
static SRes FileSeqInStream_Read(ISeqInStreamPtr pp, void *buf, size_t *size)
|
||||
{
|
||||
Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CFileSeqInStream)
|
||||
const WRes wres = File_Read(&p->file, buf, size);
|
||||
p->wres = wres;
|
||||
return (wres == 0) ? SZ_OK : SZ_ERROR_READ;
|
||||
}
|
||||
|
||||
void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
|
||||
{
|
||||
p->vt.Read = FileSeqInStream_Read;
|
||||
}
|
||||
|
||||
|
||||
/* ---------- FileInStream ---------- */
|
||||
|
||||
static SRes FileInStream_Read(ISeekInStreamPtr pp, void *buf, size_t *size)
|
||||
{
|
||||
Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CFileInStream)
|
||||
const WRes wres = File_Read(&p->file, buf, size);
|
||||
p->wres = wres;
|
||||
return (wres == 0) ? SZ_OK : SZ_ERROR_READ;
|
||||
}
|
||||
|
||||
static SRes FileInStream_Seek(ISeekInStreamPtr pp, Int64 *pos, ESzSeek origin)
|
||||
{
|
||||
Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CFileInStream)
|
||||
const WRes wres = File_Seek(&p->file, pos, origin);
|
||||
p->wres = wres;
|
||||
return (wres == 0) ? SZ_OK : SZ_ERROR_READ;
|
||||
}
|
||||
|
||||
void FileInStream_CreateVTable(CFileInStream *p)
|
||||
{
|
||||
p->vt.Read = FileInStream_Read;
|
||||
p->vt.Seek = FileInStream_Seek;
|
||||
}
|
||||
|
||||
|
||||
/* ---------- FileOutStream ---------- */
|
||||
|
||||
static size_t FileOutStream_Write(ISeqOutStreamPtr pp, const void *data, size_t size)
|
||||
{
|
||||
Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CFileOutStream)
|
||||
const WRes wres = File_Write(&p->file, data, &size);
|
||||
p->wres = wres;
|
||||
return size;
|
||||
}
|
||||
|
||||
void FileOutStream_CreateVTable(CFileOutStream *p)
|
||||
{
|
||||
p->vt.Write = FileOutStream_Write;
|
||||
}
|
||||
92
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/C/7zFile.h
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
/* 7zFile.h -- File IO
|
||||
2023-03-05 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef ZIP7_INC_FILE_H
|
||||
#define ZIP7_INC_FILE_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#define USE_WINDOWS_FILE
|
||||
// #include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
#include "7zWindows.h"
|
||||
|
||||
#else
|
||||
// note: USE_FOPEN mode is limited to 32-bit file size
|
||||
// #define USE_FOPEN
|
||||
// #include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "7zTypes.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
/* ---------- File ---------- */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
HANDLE handle;
|
||||
#elif defined(USE_FOPEN)
|
||||
FILE *file;
|
||||
#else
|
||||
int fd;
|
||||
#endif
|
||||
} CSzFile;
|
||||
|
||||
void File_Construct(CSzFile *p);
|
||||
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
|
||||
WRes InFile_Open(CSzFile *p, const char *name);
|
||||
WRes OutFile_Open(CSzFile *p, const char *name);
|
||||
#endif
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
WRes InFile_OpenW(CSzFile *p, const WCHAR *name);
|
||||
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name);
|
||||
#endif
|
||||
WRes File_Close(CSzFile *p);
|
||||
|
||||
/* reads max(*size, remain file's size) bytes */
|
||||
WRes File_Read(CSzFile *p, void *data, size_t *size);
|
||||
|
||||
/* writes *size bytes */
|
||||
WRes File_Write(CSzFile *p, const void *data, size_t *size);
|
||||
|
||||
WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin);
|
||||
WRes File_GetLength(CSzFile *p, UInt64 *length);
|
||||
|
||||
|
||||
/* ---------- FileInStream ---------- */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqInStream vt;
|
||||
CSzFile file;
|
||||
WRes wres;
|
||||
} CFileSeqInStream;
|
||||
|
||||
void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeekInStream vt;
|
||||
CSzFile file;
|
||||
WRes wres;
|
||||
} CFileInStream;
|
||||
|
||||
void FileInStream_CreateVTable(CFileInStream *p);
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqOutStream vt;
|
||||
CSzFile file;
|
||||
WRes wres;
|
||||
} CFileOutStream;
|
||||
|
||||
void FileOutStream_CreateVTable(CFileOutStream *p);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
199
app/src/main/cpp/rpcs3/3rdparty/7zip/7zip/C/7zStream.c
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
/* 7zStream.c -- 7z Stream functions
|
||||
2023-04-02 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "7zTypes.h"
|
||||
|
||||
|
||||
SRes SeqInStream_ReadMax(ISeqInStreamPtr stream, void *buf, size_t *processedSize)
|
||||
{
|
||||
size_t size = *processedSize;
|
||||
*processedSize = 0;
|
||||
while (size != 0)
|
||||
{
|
||||
size_t cur = size;
|
||||
const SRes res = ISeqInStream_Read(stream, buf, &cur);
|
||||
*processedSize += cur;
|
||||
buf = (void *)((Byte *)buf + cur);
|
||||
size -= cur;
|
||||
if (res != SZ_OK)
|
||||
return res;
|
||||
if (cur == 0)
|
||||
return SZ_OK;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
SRes SeqInStream_Read2(ISeqInStreamPtr stream, void *buf, size_t size, SRes errorType)
|
||||
{
|
||||
while (size != 0)
|
||||
{
|
||||
size_t processed = size;
|
||||
RINOK(ISeqInStream_Read(stream, buf, &processed))
|
||||
if (processed == 0)
|
||||
return errorType;
|
||||
buf = (void *)((Byte *)buf + processed);
|
||||
size -= processed;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes SeqInStream_Read(ISeqInStreamPtr stream, void *buf, size_t size)
|
||||
{
|
||||
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
SRes SeqInStream_ReadByte(ISeqInStreamPtr stream, Byte *buf)
|
||||
{
|
||||
size_t processed = 1;
|
||||
RINOK(ISeqInStream_Read(stream, buf, &processed))
|
||||
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SRes LookInStream_SeekTo(ILookInStreamPtr stream, UInt64 offset)
|
||||
{
|
||||
Int64 t = (Int64)offset;
|
||||
return ILookInStream_Seek(stream, &t, SZ_SEEK_SET);
|
||||
}
|
||||
|
||||
SRes LookInStream_LookRead(ILookInStreamPtr stream, void *buf, size_t *size)
|
||||
{
|
||||
const void *lookBuf;
|
||||
if (*size == 0)
|
||||
return SZ_OK;
|
||||
RINOK(ILookInStream_Look(stream, &lookBuf, size))
|
||||
memcpy(buf, lookBuf, *size);
|
||||
return ILookInStream_Skip(stream, *size);
|
||||
}
|
||||
|
||||
SRes LookInStream_Read2(ILookInStreamPtr stream, void *buf, size_t size, SRes errorType)
|
||||
{
|
||||
while (size != 0)
|
||||
{
|
||||
size_t processed = size;
|
||||
RINOK(ILookInStream_Read(stream, buf, &processed))
|
||||
if (processed == 0)
|
||||
return errorType;
|
||||
buf = (void *)((Byte *)buf + processed);
|
||||
size -= processed;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes LookInStream_Read(ILookInStreamPtr stream, void *buf, size_t size)
|
||||
{
|
||||
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define GET_LookToRead2 Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CLookToRead2)
|
||||
|
||||
static SRes LookToRead2_Look_Lookahead(ILookInStreamPtr pp, const void **buf, size_t *size)
|
||||
{
|
||||
SRes res = SZ_OK;
|
||||
GET_LookToRead2
|
||||
size_t size2 = p->size - p->pos;
|
||||
if (size2 == 0 && *size != 0)
|
||||
{
|
||||
p->pos = 0;
|
||||
p->size = 0;
|
||||
size2 = p->bufSize;
|
||||
res = ISeekInStream_Read(p->realStream, p->buf, &size2);
|
||||
p->size = size2;
|
||||
}
|
||||
if (*size > size2)
|
||||
*size = size2;
|
||||
*buf = p->buf + p->pos;
|
||||
return res;
|
||||
}
|
||||
|
||||
static SRes LookToRead2_Look_Exact(ILookInStreamPtr pp, const void **buf, size_t *size)
|
||||
{
|
||||
SRes res = SZ_OK;
|
||||
GET_LookToRead2
|
||||
size_t size2 = p->size - p->pos;
|
||||
if (size2 == 0 && *size != 0)
|
||||
{
|
||||
p->pos = 0;
|
||||
p->size = 0;
|
||||
if (*size > p->bufSize)
|
||||
*size = p->bufSize;
|
||||
res = ISeekInStream_Read(p->realStream, p->buf, size);
|
||||
size2 = p->size = *size;
|
||||
}
|
||||
if (*size > size2)
|
||||
*size = size2;
|
||||
*buf = p->buf + p->pos;
|
||||
return res;
|
||||
}
|
||||
|
||||
static SRes LookToRead2_Skip(ILookInStreamPtr pp, size_t offset)
|
||||
{
|
||||
GET_LookToRead2
|
||||
p->pos += offset;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static SRes LookToRead2_Read(ILookInStreamPtr pp, void *buf, size_t *size)
|
||||
{
|
||||
GET_LookToRead2
|
||||
size_t rem = p->size - p->pos;
|
||||
if (rem == 0)
|
||||
return ISeekInStream_Read(p->realStream, buf, size);
|
||||
if (rem > *size)
|
||||
rem = *size;
|
||||
memcpy(buf, p->buf + p->pos, rem);
|
||||
p->pos += rem;
|
||||
*size = rem;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static SRes LookToRead2_Seek(ILookInStreamPtr pp, Int64 *pos, ESzSeek origin)
|
||||
{
|
||||
GET_LookToRead2
|
||||
p->pos = p->size = 0;
|
||||
return ISeekInStream_Seek(p->realStream, pos, origin);
|
||||
}
|
||||
|
||||
void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead)
|
||||
{
|
||||
p->vt.Look = lookahead ?
|
||||
LookToRead2_Look_Lookahead :
|
||||
LookToRead2_Look_Exact;
|
||||
p->vt.Skip = LookToRead2_Skip;
|
||||
p->vt.Read = LookToRead2_Read;
|
||||
p->vt.Seek = LookToRead2_Seek;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static SRes SecToLook_Read(ISeqInStreamPtr pp, void *buf, size_t *size)
|
||||
{
|
||||
Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSecToLook)
|
||||
return LookInStream_LookRead(p->realStream, buf, size);
|
||||
}
|
||||
|
||||
void SecToLook_CreateVTable(CSecToLook *p)
|
||||
{
|
||||
p->vt.Read = SecToLook_Read;
|
||||
}
|
||||
|
||||
static SRes SecToRead_Read(ISeqInStreamPtr pp, void *buf, size_t *size)
|
||||
{
|
||||
Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSecToRead)
|
||||
return ILookInStream_Read(p->realStream, buf, size);
|
||||
}
|
||||
|
||||
void SecToRead_CreateVTable(CSecToRead *p)
|
||||
{
|
||||
p->vt.Read = SecToRead_Read;
|
||||
}
|
||||