mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-11 14:24:20 +00:00
Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e52e920b14 | |||
| d58ab98794 | |||
| b84e63f06b | |||
| 2db4c35c54 | |||
| d3d26797c1 | |||
| 99a65383f1 | |||
| 5f47a7f064 | |||
| 9c0d41b55f | |||
| 2cc7a94053 | |||
| b30e68a599 | |||
| 4e1f277432 | |||
| 9b0008008a | |||
| e47aee1215 | |||
| 61fd747cbd | |||
| bfcdcdc145 | |||
| 7a80ce616b | |||
| ed8d2d9ded | |||
| 4e5f0cd4e1 | |||
| f8685e0c92 | |||
| 2b952b79d7 | |||
| c040f73794 | |||
| 08c284fcb8 | |||
| 16b103aa6c | |||
| 36bd1c262a | |||
| 39ee32a311 | |||
| 51224713b7 | |||
| 08e5861af9 | |||
| a3ecd2b6cb | |||
| 70b4070709 | |||
| 72bc40c50b | |||
| 76b1180d02 | |||
| 23e11d2a58 | |||
| ff4ae20a88 | |||
| 37d4c6e636 | |||
| a06a5377ad | |||
| 684188d375 | |||
| 6e69740ab7 | |||
| f6d6e3c195 | |||
| 695a40872a | |||
| 897f9d5029 | |||
| e79ece6518 | |||
| 3d6974607e | |||
| d85d576b0d | |||
| e4c55e1aff | |||
| 8c3404960a | |||
| 0325b44d8e | |||
| a86e24731d | |||
| aafbcd6ce1 | |||
| 2c57681ca1 |
@@ -19,6 +19,7 @@ log.txt
|
|||||||
# Generated source files
|
# Generated source files
|
||||||
src/common/scm_rev.cpp
|
src/common/scm_rev.cpp
|
||||||
dist/english_plurals/generated_en.ts
|
dist/english_plurals/generated_en.ts
|
||||||
|
*-toolchain.cmake
|
||||||
|
|
||||||
# Project/editor files
|
# Project/editor files
|
||||||
*.swp
|
*.swp
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
--- a/source/effect_lexer.cpp
|
|
||||||
+++ b/source/effect_lexer.cpp
|
|
||||||
@@ -1181,7 +1181,7 @@
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
-#if 0
|
|
||||||
+#if !defined(__cpp_lib_to_chars)
|
|
||||||
exponent += decimal_location - mantissa_size;
|
|
||||||
|
|
||||||
const bool exponent_negative = exponent < 0;
|
|
||||||
@@ -85,8 +85,6 @@ option(ENABLE_WERROR "Enable -Werror diagnostics" ON)
|
|||||||
# Lossless Scaling frame generation. Only Android.
|
# Lossless Scaling frame generation. Only Android.
|
||||||
cmake_dependent_option(ENABLE_LSFG "Enable Lossless Scaling frame generation" ON "ANDROID" OFF)
|
cmake_dependent_option(ENABLE_LSFG "Enable Lossless Scaling frame generation" ON "ANDROID" OFF)
|
||||||
|
|
||||||
option(ENABLE_RESHADE "Enable ReShade FX post-processing effects" ON)
|
|
||||||
|
|
||||||
# non-linux bundled qt are static
|
# non-linux bundled qt are static
|
||||||
if (YUZU_USE_BUNDLED_QT AND (APPLE OR NOT UNIX))
|
if (YUZU_USE_BUNDLED_QT AND (APPLE OR NOT UNIX))
|
||||||
set(YUZU_STATIC_BUILD ON)
|
set(YUZU_STATIC_BUILD ON)
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
set(CROSS_TARGET "powerpc64le" CACHE STRING "Cross-compilation target (aarch64, powerpc64le, riscv64, etc)")
|
||||||
|
|
||||||
|
set(CMAKE_SYSROOT /usr/${CROSS_TARGET}-unknown-linux-gnu)
|
||||||
|
|
||||||
|
set(CMAKE_C_COMPILER ${CROSS_TARGET}-unknown-linux-gnu-gcc)
|
||||||
|
set(CMAKE_CXX_COMPILER ${CROSS_TARGET}-unknown-linux-gnu-g++)
|
||||||
|
|
||||||
|
# search programs in the host environment
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
|
||||||
|
# search headers and libraries in the target environment
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||||
|
|
||||||
|
set(CMAKE_FIND_ROOT_PATH /usr/${CROSS_TARGET}-unknown-linux-gnu)
|
||||||
@@ -238,14 +238,6 @@
|
|||||||
"repo": "stachenov/quazip",
|
"repo": "stachenov/quazip",
|
||||||
"version": "2e95c9001b"
|
"version": "2e95c9001b"
|
||||||
},
|
},
|
||||||
"reshade": {
|
|
||||||
"hash": "6fc9b39821ca6e2d91160f05846b3a42159fec759f5d6fba91d1a57801a1bdaf6047740578c136f0b1a60a9c29ad160d87dbfe0dbfbcdf6ea879a8a078377b8c",
|
|
||||||
"patches": [
|
|
||||||
"0001-from-chars-fallback.patch"
|
|
||||||
],
|
|
||||||
"repo": "crosire/reshade",
|
|
||||||
"version": "v6.8.0"
|
|
||||||
},
|
|
||||||
"sdl3": {
|
"sdl3": {
|
||||||
"hash": "df5a323af7ac366661a3c0e887969c72584d232f3cc211419d59b0487b620b6b2859d4549c9e8df002ee489290062e466fcfddf7edc0872a37b1f2845e81c0f3",
|
"hash": "df5a323af7ac366661a3c0e887969c72584d232f3cc211419d59b0487b620b6b2859d4549c9e8df002ee489290062e466fcfddf7edc0872a37b1f2845e81c0f3",
|
||||||
"min_version": "3.2.10",
|
"min_version": "3.2.10",
|
||||||
|
|||||||
Vendored
-3
@@ -1,3 +0,0 @@
|
|||||||
name=Anime
|
|
||||||
description=Cel shaded look: the picture is cleaned first, then the lighting is collapsed into flat bands with inked edges, finished with a small glow.
|
|
||||||
chain=Denoise.fx|Denoise|Strength=0.18,Radius=1.2;CelShading.fx|CelShading|Bands=5,BandContrast=0.35,BandEdge=0.2,Detail=0.7,OutlineStrength=0.7,OutlineThreshold=0.2,Saturation=1.3;Bloom.fx|Bloom|Radius=1.2,Amount=0.25
|
|
||||||
Vendored
-3
@@ -1,3 +0,0 @@
|
|||||||
name=Cinematic
|
|
||||||
description=Film look: soft glow on the highlights, a filmic contrast curve, cool shadows against warm highlights, fine grain and a gentle vignette.
|
|
||||||
chain=Bloom.fx|Bloom|Radius=1.6,Amount=0.35;FilmicCurve.fx|FilmicCurve|Toe=1.35,Shoulder=1.3,Amount=0.85;SplitToning.fx|SplitToning|ShadowHue=210,ShadowStrength=0.25,HighlightHue=38,HighlightStrength=0.3;FilmGrain.fx|FilmGrain|Intensity=0.022;Vignette.fx|Vignette|Strength=0.5
|
|
||||||
Vendored
-3
@@ -1,3 +0,0 @@
|
|||||||
name=Clean
|
|
||||||
description=Cleans up a low internal resolution: removes dithering and compression noise, smooths banded skies and brings edge detail back. The safe starting point if you are not sure what you want.
|
|
||||||
chain=Denoise.fx|Denoise|Strength=0.14,Curve=1.2;Deband.fx|Deband|;Sharpen.fx|Sharpen|Amount=0.75
|
|
||||||
Vendored
-3
@@ -1,3 +0,0 @@
|
|||||||
name=Dreamy
|
|
||||||
description=Soft focus: the centre of the screen stays sharp while everything around it blurs, with a wide glow over the highlights. Good for slower games and cutscenes.
|
|
||||||
chain=Blur.fx|Blur|Radius=6,Strength=0.85,FocusSize=0.28,FocusSoftness=0.5;Bloom.fx|Bloom|Radius=2.0,Amount=0.55
|
|
||||||
Vendored
-3
@@ -1,3 +0,0 @@
|
|||||||
name=Retro
|
|
||||||
description=Old television look: colour fringing at the edges of the screen, curved scanlines with a phosphor mask, and darkened corners. The scanline roll is switched off so it does not crawl.
|
|
||||||
chain=ChromaticAberration.fx|ChromaticAberration|Strength=1.0;CRT.fx|CRT|RollSpeed=0,Bleed=1.2;Vignette.fx|Vignette|Strength=0.7
|
|
||||||
Vendored
-3
@@ -1,3 +0,0 @@
|
|||||||
name=Vivid
|
|
||||||
description=Punchier colour without stylising the image: warmer and more saturated, blacks and whites pushed to the ends of the range, and a light sharpen.
|
|
||||||
chain=NaturalColors.fx|NaturalColors|Luma=1.15,Chroma=1.35;Levels.fx|Levels|InputBlack=0.02,InputWhite=0.98;Sharpen.fx|Sharpen|Amount=0.5
|
|
||||||
Vendored
-70
@@ -1,70 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2012 PPSSPP Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
// Ported from bloomnoblur.fsh in PPSSPP.
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float Radius <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Radius";
|
|
||||||
ui_tooltip = "How far the glow spreads from bright areas.";
|
|
||||||
ui_min = 0.0; ui_max = 4.0; ui_step = 0.05;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
uniform float Amount <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Amount";
|
|
||||||
ui_tooltip = "Strength of the glow added on top of the image.";
|
|
||||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.05;
|
|
||||||
> = 0.6;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float Weight(float3 color)
|
|
||||||
{
|
|
||||||
float gray = (color.r + color.g + color.b) / 3.0;
|
|
||||||
float saturation = (abs(color.r - gray) + abs(color.g - gray) + abs(color.b - gray)) / 3.0;
|
|
||||||
return gray * gray / max(saturation, 0.25);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_Bloom(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float3 color = tex2D(BackBuffer, uv).rgb;
|
|
||||||
|
|
||||||
float gray = (color.r + color.g + color.b) / 3.0;
|
|
||||||
float saturation = (abs(color.r - gray) + abs(color.g - gray) + abs(color.b - gray)) / 3.0;
|
|
||||||
float spread = 0.002 * gray / max(saturation, 0.25) * Radius;
|
|
||||||
|
|
||||||
float3 sum = float3(0.0, 0.0, 0.0);
|
|
||||||
[unroll] for (int x = -3; x <= 3; x += 2)
|
|
||||||
{
|
|
||||||
[unroll] for (int y = -3; y <= 3; y += 2)
|
|
||||||
{
|
|
||||||
float3 tap = tex2D(BackBuffer, uv + float2(x, y) * spread).rgb;
|
|
||||||
sum += tap * Weight(tap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sum /= 16.0;
|
|
||||||
|
|
||||||
return float4(saturate(color + sum * Amount), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique Bloom <
|
|
||||||
ui_label = "Bloom";
|
|
||||||
ui_tooltip = "Bleeds light out of the brightest areas into a soft halo, the way a camera does when pointed at something too bright.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_Bloom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-87
@@ -1,87 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float Radius <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Radius";
|
|
||||||
ui_tooltip = "How far the blur reaches, in pixels.";
|
|
||||||
ui_min = 1.0; ui_max = 12.0; ui_step = 0.5;
|
|
||||||
> = 4.0;
|
|
||||||
|
|
||||||
uniform float Strength <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Strength";
|
|
||||||
ui_tooltip = "Blend between the original image and the blurred one.";
|
|
||||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
uniform float FocusSize <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Sharp Centre";
|
|
||||||
ui_tooltip = "Size of the region left in focus at the centre of the screen. At zero the whole image is blurred evenly.";
|
|
||||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
|
||||||
> = 0.0;
|
|
||||||
|
|
||||||
uniform float FocusSoftness <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Focus Falloff";
|
|
||||||
ui_tooltip = "How gradually the sharp centre gives way to the blur.";
|
|
||||||
ui_min = 0.05; ui_max = 1.0; ui_step = 0.05;
|
|
||||||
> = 0.4;
|
|
||||||
|
|
||||||
static const int TAPS = 17;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_Blur(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float2 texel = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT);
|
|
||||||
float3 original = tex2D(BackBuffer, uv).rgb;
|
|
||||||
|
|
||||||
float2 centred = (uv - 0.5) * float2(BUFFER_WIDTH * BUFFER_RCP_HEIGHT, 1.0) * 2.0;
|
|
||||||
float distance_from_centre = length(centred);
|
|
||||||
float no_focus = 1.0 - step(0.001, FocusSize);
|
|
||||||
float focus = max(smoothstep(FocusSize, FocusSize + FocusSoftness, distance_from_centre), no_focus);
|
|
||||||
float amount = Strength * focus;
|
|
||||||
|
|
||||||
float angle = frac(sin(dot(pos.xy, float2(12.9898, 78.233))) * 43758.5453) * 6.2831853;
|
|
||||||
float2 spoke = float2(cos(angle), sin(angle));
|
|
||||||
|
|
||||||
const float2 turn = float2(cos(2.39996323), sin(2.39996323));
|
|
||||||
const float decay = exp(-2.0 / float(TAPS));
|
|
||||||
float weight = exp(-1.0 / float(TAPS));
|
|
||||||
|
|
||||||
float3 sum = float3(0.0, 0.0, 0.0);
|
|
||||||
float total = 0.0;
|
|
||||||
[unroll] for (int i = 0; i < TAPS; ++i)
|
|
||||||
{
|
|
||||||
float reach = sqrt((float(i) + 0.5) / float(TAPS));
|
|
||||||
sum += tex2D(BackBuffer, uv + spoke * reach * texel * Radius).rgb * weight;
|
|
||||||
total += weight;
|
|
||||||
weight *= decay;
|
|
||||||
spoke = float2(spoke.x * turn.x - spoke.y * turn.y,
|
|
||||||
spoke.x * turn.y + spoke.y * turn.x);
|
|
||||||
}
|
|
||||||
|
|
||||||
float3 blurred = sum / total;
|
|
||||||
return float4(lerp(original, blurred, amount), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique Blur <
|
|
||||||
ui_label = "Blur";
|
|
||||||
ui_tooltip = "Gaussian blur with an optional sharp centre, for softening the picture or faking depth of field.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_Blur;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-74
@@ -1,74 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2012 PPSSPP Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
// Ported from crt.fsh in PPSSPP, by KillaMaaki.
|
|
||||||
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float Timer < source = "timer"; > = 0.0;
|
|
||||||
|
|
||||||
uniform float Density <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Line Density";
|
|
||||||
ui_min = 60.0; ui_max = 720.0; ui_step = 10.0;
|
|
||||||
> = 272.0;
|
|
||||||
|
|
||||||
uniform float RollSpeed <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Roll Speed";
|
|
||||||
ui_tooltip = "Speed of the rolling bar. Zero disables it.";
|
|
||||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.05;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
uniform float Bleed <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Colour Bleed";
|
|
||||||
ui_tooltip = "Horizontal separation of the red and green channels.";
|
|
||||||
ui_min = 0.0; ui_max = 4.0; ui_step = 0.1;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_CRT(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float seconds = Timer * 0.001;
|
|
||||||
float scan = floor((uv.y + seconds * RollSpeed * 0.5) * Density);
|
|
||||||
float line_intensity = frac(scan * 0.5) * 2.0;
|
|
||||||
|
|
||||||
float2 shift = float2(line_intensity * 0.0005, 0.0);
|
|
||||||
float2 bleed = float2(BUFFER_RCP_WIDTH * Bleed, 0.0);
|
|
||||||
|
|
||||||
float r = tex2D(BackBuffer, uv + bleed + shift).r;
|
|
||||||
float g = tex2D(BackBuffer, uv - bleed + shift).g;
|
|
||||||
float b = tex2D(BackBuffer, uv).b;
|
|
||||||
|
|
||||||
float3 color = float3(r, g * 0.99, b) * clamp(line_intensity, 0.85, 1.0);
|
|
||||||
|
|
||||||
if (RollSpeed > 0.0)
|
|
||||||
{
|
|
||||||
float rollbar = sin((uv.y + seconds * RollSpeed) * 4.0);
|
|
||||||
color += rollbar * 0.02;
|
|
||||||
}
|
|
||||||
|
|
||||||
return float4(saturate(color), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique CRT <
|
|
||||||
ui_label = "CRT";
|
|
||||||
ui_tooltip = "Curved scanlines and the phosphor mask of a CRT television, for games that were drawn with that kind of screen in mind.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_CRT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-79
@@ -1,79 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2012 PPSSPP Project
|
|
||||||
// SPDX-FileCopyrightText: guest(r)
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
// Ported from cartoon.fsh in PPSSPP, Advanced Cartoon shader I by guest(r).
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float EdgeStrength <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Edge Strength";
|
|
||||||
ui_tooltip = "Darkness of the ink outline drawn around detected edges.";
|
|
||||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.05;
|
|
||||||
> = 0.5;
|
|
||||||
|
|
||||||
uniform float Levels <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Colour Levels";
|
|
||||||
ui_tooltip = "How many bands the colours are quantised into.";
|
|
||||||
ui_min = 2.0; ui_max = 16.0; ui_step = 1.0;
|
|
||||||
> = 4.0;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_Cartoon(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float2 texel = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT);
|
|
||||||
|
|
||||||
float3 c00 = tex2D(BackBuffer, uv + texel * float2(-1.0, -1.0)).rgb;
|
|
||||||
float3 c10 = tex2D(BackBuffer, uv + texel * float2( 0.0, -1.0)).rgb;
|
|
||||||
float3 c20 = tex2D(BackBuffer, uv + texel * float2( 1.0, -1.0)).rgb;
|
|
||||||
float3 c01 = tex2D(BackBuffer, uv + texel * float2(-1.0, 0.0)).rgb;
|
|
||||||
float3 c11 = tex2D(BackBuffer, uv).rgb;
|
|
||||||
float3 c21 = tex2D(BackBuffer, uv + texel * float2( 1.0, 0.0)).rgb;
|
|
||||||
float3 c02 = tex2D(BackBuffer, uv + texel * float2(-1.0, 1.0)).rgb;
|
|
||||||
float3 c12 = tex2D(BackBuffer, uv + texel * float2( 0.0, 1.0)).rgb;
|
|
||||||
float3 c22 = tex2D(BackBuffer, uv + texel * float2( 1.0, 1.0)).rgb;
|
|
||||||
|
|
||||||
const float3 dt = float3(1.0, 1.0, 1.0);
|
|
||||||
|
|
||||||
float d1 = dot(abs(c00 - c22), dt);
|
|
||||||
float d2 = dot(abs(c20 - c02), dt);
|
|
||||||
float hl = dot(abs(c01 - c21), dt);
|
|
||||||
float vl = dot(abs(c10 - c12), dt);
|
|
||||||
float edge = EdgeStrength * (d1 + d2 + hl + vl) / (dot(c11, dt) + 0.15);
|
|
||||||
|
|
||||||
float lc = Levels * length(c11);
|
|
||||||
float f = frac(lc);
|
|
||||||
f *= f;
|
|
||||||
lc = (floor(lc) + f * f) / Levels + 0.05;
|
|
||||||
|
|
||||||
float3 unit = normalize(max(c11, 0.0001));
|
|
||||||
float3 quant = Levels * unit;
|
|
||||||
float3 frct = frac(quant);
|
|
||||||
frct *= frct;
|
|
||||||
quant = floor(quant) + 0.05 * dt + frct * frct;
|
|
||||||
|
|
||||||
float3 color = lc * (1.1 - edge * sqrt(edge)) * quant / Levels;
|
|
||||||
return float4(saturate(color), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique Cartoon <
|
|
||||||
ui_label = "Cartoon";
|
|
||||||
ui_tooltip = "Ink outlines and flat colour bands. Faithful port of the PPSSPP shader; the outline gets heavy in dark scenes, so try Cartoon Soft or Cel Shading if the blacks smear.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_Cartoon;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-100
@@ -1,100 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2012 PPSSPP Project
|
|
||||||
// SPDX-FileCopyrightText: guest(r)
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float EdgeStrength <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Edge Strength";
|
|
||||||
ui_tooltip = "Darkness of the ink outline drawn around detected edges.";
|
|
||||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.05;
|
|
||||||
> = 0.45;
|
|
||||||
|
|
||||||
uniform float ShadowGuard <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Shadow Guard";
|
|
||||||
ui_tooltip = "Holds the outline back in dark areas. Raise it if shadows turn into black blobs.";
|
|
||||||
ui_min = 0.1; ui_max = 2.0; ui_step = 0.05;
|
|
||||||
> = 0.8;
|
|
||||||
|
|
||||||
uniform float Levels <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Colour Levels";
|
|
||||||
ui_tooltip = "How many bands the colours are quantised into.";
|
|
||||||
ui_min = 2.0; ui_max = 16.0; ui_step = 1.0;
|
|
||||||
> = 6.0;
|
|
||||||
|
|
||||||
uniform float Smoothing <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Banding";
|
|
||||||
ui_tooltip = "How far the picture is pushed towards flat bands.";
|
|
||||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
|
||||||
> = 0.75;
|
|
||||||
|
|
||||||
uniform float Saturation <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Saturation";
|
|
||||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.05;
|
|
||||||
> = 1.15;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_CartoonSoft(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float2 texel = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT);
|
|
||||||
|
|
||||||
float3 c00 = tex2D(BackBuffer, uv + texel * float2(-1.0, -1.0)).rgb;
|
|
||||||
float3 c10 = tex2D(BackBuffer, uv + texel * float2( 0.0, -1.0)).rgb;
|
|
||||||
float3 c20 = tex2D(BackBuffer, uv + texel * float2( 1.0, -1.0)).rgb;
|
|
||||||
float3 c01 = tex2D(BackBuffer, uv + texel * float2(-1.0, 0.0)).rgb;
|
|
||||||
float3 c11 = tex2D(BackBuffer, uv).rgb;
|
|
||||||
float3 c21 = tex2D(BackBuffer, uv + texel * float2( 1.0, 0.0)).rgb;
|
|
||||||
float3 c02 = tex2D(BackBuffer, uv + texel * float2(-1.0, 1.0)).rgb;
|
|
||||||
float3 c12 = tex2D(BackBuffer, uv + texel * float2( 0.0, 1.0)).rgb;
|
|
||||||
float3 c22 = tex2D(BackBuffer, uv + texel * float2( 1.0, 1.0)).rgb;
|
|
||||||
|
|
||||||
const float3 dt = float3(1.0, 1.0, 1.0);
|
|
||||||
const float3 luma_weights = float3(0.299, 0.587, 0.114);
|
|
||||||
|
|
||||||
float d1 = dot(abs(c00 - c22), dt);
|
|
||||||
float d2 = dot(abs(c20 - c02), dt);
|
|
||||||
float hl = dot(abs(c01 - c21), dt);
|
|
||||||
float vl = dot(abs(c10 - c12), dt);
|
|
||||||
|
|
||||||
float luma = dot(c11, luma_weights);
|
|
||||||
float response = (d1 + d2 + hl + vl) / (luma * 2.0 + ShadowGuard);
|
|
||||||
float ink = 1.0 - saturate(response * EdgeStrength);
|
|
||||||
|
|
||||||
float scaled = luma * Levels;
|
|
||||||
float step_position = frac(scaled);
|
|
||||||
float eased = step_position * step_position * (3.0 - 2.0 * step_position);
|
|
||||||
float banded = (floor(scaled) + eased) / Levels;
|
|
||||||
float target = lerp(luma, banded, Smoothing);
|
|
||||||
|
|
||||||
float3 tinted = c11 * (target / max(luma, 0.001));
|
|
||||||
float3 grey = dot(tinted, luma_weights);
|
|
||||||
float3 color = lerp(grey, tinted, Saturation) * ink;
|
|
||||||
|
|
||||||
return float4(saturate(color), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique CartoonSoft <
|
|
||||||
ui_label = "Cartoon Soft";
|
|
||||||
ui_tooltip = "Ink outlines and flat colour bands, with the outline held back in the shadows so dark scenes do not turn into black blobs.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_CartoonSoft;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-120
@@ -1,120 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float Bands <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Shading Bands";
|
|
||||||
ui_tooltip = "How many flat steps the lighting is collapsed into. Three or four gives the classic look.";
|
|
||||||
ui_min = 2.0; ui_max = 8.0; ui_step = 1.0;
|
|
||||||
> = 4.0;
|
|
||||||
|
|
||||||
uniform float BandContrast <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Band Contrast";
|
|
||||||
ui_tooltip = "Spreads the bands towards pure black and white. Lower it if the shadows crush.";
|
|
||||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
|
||||||
> = 0.5;
|
|
||||||
|
|
||||||
uniform float BandEdge <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Band Edge";
|
|
||||||
ui_tooltip = "Width of the transition between bands. Low values give hard cel steps.";
|
|
||||||
ui_min = 0.02; ui_max = 1.0; ui_step = 0.02;
|
|
||||||
> = 0.15;
|
|
||||||
|
|
||||||
uniform float Detail <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Texture Detail";
|
|
||||||
ui_tooltip = "How much surface texture survives the flattening. At zero the bands are completely flat.";
|
|
||||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
|
||||||
> = 0.6;
|
|
||||||
|
|
||||||
uniform float OutlineStrength <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Outline Strength";
|
|
||||||
ui_tooltip = "Opacity of the ink line drawn along detected edges.";
|
|
||||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
|
||||||
> = 0.8;
|
|
||||||
|
|
||||||
uniform float OutlineThreshold <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Outline Threshold";
|
|
||||||
ui_tooltip = "How strong an edge has to be before it is inked. Raise it to keep ink off textures and specular highlights.";
|
|
||||||
ui_min = 0.01; ui_max = 0.4; ui_step = 0.01;
|
|
||||||
> = 0.18;
|
|
||||||
|
|
||||||
uniform float Saturation <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Saturation";
|
|
||||||
ui_tooltip = "Colour intensity of the flat regions.";
|
|
||||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.05;
|
|
||||||
> = 1.25;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_CelShading(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
const float3 luma_weights = float3(0.2126, 0.7152, 0.0722);
|
|
||||||
float2 texel = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT);
|
|
||||||
|
|
||||||
float3 centre = tex2D(BackBuffer, uv).rgb;
|
|
||||||
float luma = dot(centre, luma_weights);
|
|
||||||
|
|
||||||
float2 near = texel * 1.5;
|
|
||||||
float2 far = texel * 3.5;
|
|
||||||
|
|
||||||
float a00 = dot(tex2D(BackBuffer, uv + near * float2(-1.0, -1.0)).rgb, luma_weights);
|
|
||||||
float a20 = dot(tex2D(BackBuffer, uv + near * float2( 1.0, -1.0)).rgb, luma_weights);
|
|
||||||
float a02 = dot(tex2D(BackBuffer, uv + near * float2(-1.0, 1.0)).rgb, luma_weights);
|
|
||||||
float a22 = dot(tex2D(BackBuffer, uv + near * float2( 1.0, 1.0)).rgb, luma_weights);
|
|
||||||
|
|
||||||
float b00 = dot(tex2D(BackBuffer, uv + far * float2(-1.0, -1.0)).rgb, luma_weights);
|
|
||||||
float b20 = dot(tex2D(BackBuffer, uv + far * float2( 1.0, -1.0)).rgb, luma_weights);
|
|
||||||
float b02 = dot(tex2D(BackBuffer, uv + far * float2(-1.0, 1.0)).rgb, luma_weights);
|
|
||||||
float b22 = dot(tex2D(BackBuffer, uv + far * float2( 1.0, 1.0)).rgb, luma_weights);
|
|
||||||
|
|
||||||
float gx = (a00 + a02) - (a20 + a22);
|
|
||||||
float gy = (a00 + a20) - (a02 + a22);
|
|
||||||
float gradient = sqrt(gx * gx + gy * gy);
|
|
||||||
float ink = smoothstep(OutlineThreshold, OutlineThreshold + 0.04, gradient);
|
|
||||||
|
|
||||||
float lighting = (a00 + a20 + a02 + a22 + b00 + b20 + b02 + b22) * 0.125;
|
|
||||||
float detail = luma - lighting;
|
|
||||||
|
|
||||||
float softness = max(BandEdge, 0.001);
|
|
||||||
float coord = lighting * Bands - softness * 0.5;
|
|
||||||
float index = floor(coord) + smoothstep(1.0 - softness, 1.0, frac(coord));
|
|
||||||
|
|
||||||
float centred = (index + 0.5) / Bands;
|
|
||||||
float stretched = index / max(Bands - 1.0, 1.0);
|
|
||||||
float banded = saturate(lerp(centred, stretched, BandContrast));
|
|
||||||
|
|
||||||
float target = saturate(banded + detail * Detail);
|
|
||||||
|
|
||||||
float gain = min(target / max(luma, 0.001), 4.0);
|
|
||||||
float3 shaded = centre * gain;
|
|
||||||
float3 grey = dot(shaded, luma_weights);
|
|
||||||
float3 color = lerp(grey, shaded, Saturation);
|
|
||||||
color *= 1.0 - ink * OutlineStrength;
|
|
||||||
|
|
||||||
return float4(saturate(color), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique CelShading <
|
|
||||||
ui_label = "Cel Shading";
|
|
||||||
ui_tooltip = "Collapses the lighting into a few hard steps and inks the edges, keeping texture detail and hue intact.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_CelShading;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-53
@@ -1,53 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float Strength <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Strength";
|
|
||||||
ui_tooltip = "Channel separation in pixels, measured at the edge of the screen.";
|
|
||||||
ui_min = 0.0; ui_max = 8.0; ui_step = 0.1;
|
|
||||||
> = 1.5;
|
|
||||||
|
|
||||||
uniform float Falloff <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Falloff";
|
|
||||||
ui_tooltip = "How fast the separation grows away from the centre. Higher keeps the middle clean.";
|
|
||||||
ui_min = 1.0; ui_max = 4.0; ui_step = 0.1;
|
|
||||||
> = 2.0;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_ChromaticAberration(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float2 texel = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT);
|
|
||||||
|
|
||||||
float2 direction = uv - float2(0.5, 0.5);
|
|
||||||
float radius = length(direction);
|
|
||||||
float2 unit = direction / max(radius, 0.0001);
|
|
||||||
float2 offset = unit * Strength * pow(radius * 2.0, Falloff) * texel;
|
|
||||||
|
|
||||||
float red = tex2D(BackBuffer, uv + offset).r;
|
|
||||||
float green = tex2D(BackBuffer, uv).g;
|
|
||||||
float blue = tex2D(BackBuffer, uv - offset).b;
|
|
||||||
|
|
||||||
return float4(red, green, blue, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique ChromaticAberration <
|
|
||||||
ui_label = "Chromatic Aberration";
|
|
||||||
ui_tooltip = "Splits the colour channels apart towards the edges of the screen, the way a cheap lens fails to focus every colour on the same spot.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_ChromaticAberration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-64
@@ -1,64 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2012 PPSSPP Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
// Based on colorcorrection.fsh in PPSSPP.
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float Saturation <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Saturation";
|
|
||||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.01;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
uniform float Brightness <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Brightness";
|
|
||||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.01;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
uniform float Contrast <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Contrast";
|
|
||||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.01;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
uniform float Gamma <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Gamma";
|
|
||||||
ui_min = 0.5; ui_max = 2.0; ui_step = 0.01;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_ColorGrade(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float3 rgb = tex2D(BackBuffer, uv).rgb;
|
|
||||||
|
|
||||||
float luma = dot(rgb, float3(0.2126, 0.7152, 0.0722));
|
|
||||||
rgb = lerp(float3(luma, luma, luma), rgb, Saturation);
|
|
||||||
rgb *= Brightness;
|
|
||||||
rgb = (rgb - 0.5) * Contrast + 0.5;
|
|
||||||
rgb = pow(max(rgb, 0.0), 1.0 / max(Gamma, 0.0001));
|
|
||||||
|
|
||||||
return float4(saturate(rgb), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique ColorGrade <
|
|
||||||
ui_label = "Colour Grade";
|
|
||||||
ui_tooltip = "The four basic colour controls in one pass: saturation, brightness, contrast and gamma. Reach for this before anything more specialised.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_ColorGrade;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-91
@@ -1,91 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2015 Niklas Haas
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float Threshold <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Threshold";
|
|
||||||
ui_tooltip = "How flat a neighbourhood must be before it gets smoothed. Raise it to catch wider bands, lower it to keep more detail.";
|
|
||||||
ui_min = 0.002; ui_max = 0.05; ui_step = 0.001;
|
|
||||||
> = 0.012;
|
|
||||||
|
|
||||||
uniform float Radius <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Radius";
|
|
||||||
ui_tooltip = "How far the sampling reaches, in pixels. Wider gradients need a larger radius.";
|
|
||||||
ui_min = 1.0; ui_max = 32.0; ui_step = 1.0;
|
|
||||||
> = 8.0;
|
|
||||||
|
|
||||||
uniform float Grain <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Dither";
|
|
||||||
ui_tooltip = "Noise added to break up whatever banding survives the smoothing.";
|
|
||||||
ui_min = 0.0; ui_max = 0.02; ui_step = 0.001;
|
|
||||||
> = 0.004;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float Hash(float2 p)
|
|
||||||
{
|
|
||||||
float3 scattered = frac(float3(p.x, p.y, p.x) * 0.1031);
|
|
||||||
scattered += dot(scattered, scattered.yzx + 33.33);
|
|
||||||
return frac((scattered.x + scattered.y) * scattered.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_Deband(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float2 texel = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT);
|
|
||||||
|
|
||||||
float3 centre = tex2D(BackBuffer, uv).rgb;
|
|
||||||
float base = Hash(pos.xy) * 6.2831853;
|
|
||||||
|
|
||||||
float3 total = float3(0.0, 0.0, 0.0);
|
|
||||||
float3 deviation = float3(0.0, 0.0, 0.0);
|
|
||||||
|
|
||||||
[unroll] for (int ring = 1; ring <= 2; ++ring)
|
|
||||||
{
|
|
||||||
float angle = base + float(ring) * 2.3999632;
|
|
||||||
float reach = Radius * float(ring) * 0.5;
|
|
||||||
float2 along = float2(cos(angle), sin(angle)) * reach;
|
|
||||||
float2 across = float2(-along.y, along.x);
|
|
||||||
|
|
||||||
float3 s0 = tex2D(BackBuffer, uv + along * texel).rgb;
|
|
||||||
float3 s1 = tex2D(BackBuffer, uv - along * texel).rgb;
|
|
||||||
float3 s2 = tex2D(BackBuffer, uv + across * texel).rgb;
|
|
||||||
float3 s3 = tex2D(BackBuffer, uv - across * texel).rgb;
|
|
||||||
|
|
||||||
total += s0 + s1 + s2 + s3;
|
|
||||||
deviation = max(deviation, max(max(abs(s0 - centre), abs(s1 - centre)),
|
|
||||||
max(abs(s2 - centre), abs(s3 - centre))));
|
|
||||||
}
|
|
||||||
|
|
||||||
float3 average = total * 0.125;
|
|
||||||
float3 flatness = float3(1.0, 1.0, 1.0) -
|
|
||||||
smoothstep(Threshold * 0.5, Threshold, deviation);
|
|
||||||
float3 result = lerp(centre, average, flatness);
|
|
||||||
|
|
||||||
float dither = (Hash(pos.xy + float2(71.3, 41.7)) - 0.5) * Grain;
|
|
||||||
|
|
||||||
return float4(saturate(result + dither), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique Deband <
|
|
||||||
ui_label = "Deband";
|
|
||||||
ui_tooltip = "Smooths the visible steps in gradients such as skies, then dithers whatever survives. Worth adding whenever large flat areas show rings.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_Deband;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-83
@@ -1,83 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2019-2021 bloc97
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float Strength <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Strength";
|
|
||||||
ui_min = 0.01; ui_max = 0.5; ui_step = 0.01;
|
|
||||||
> = 0.1;
|
|
||||||
|
|
||||||
uniform float Radius <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Radius";
|
|
||||||
ui_min = 0.3; ui_max = 2.0; ui_step = 0.05;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
uniform float Curve <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Shadow Bias";
|
|
||||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.05;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float3 IntensityWeight(float3 value, float3 sigma, float3 centre)
|
|
||||||
{
|
|
||||||
float3 scaled = (value - centre) / sigma;
|
|
||||||
return exp(-0.5 * scaled * scaled);
|
|
||||||
}
|
|
||||||
|
|
||||||
float SpatialWeight(float distance, float sigma)
|
|
||||||
{
|
|
||||||
float scaled = distance / sigma;
|
|
||||||
return exp(-0.5 * scaled * scaled);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_Denoise(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float2 texel = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT);
|
|
||||||
|
|
||||||
float3 centre = tex2D(BackBuffer, uv).rgb;
|
|
||||||
float3 intensity_sigma = max(pow(centre + 0.0001, Curve) * Strength, 0.0001);
|
|
||||||
float spatial_sigma = max(Radius, 0.05);
|
|
||||||
|
|
||||||
float3 sum = float3(0.0, 0.0, 0.0);
|
|
||||||
float3 total = float3(0.0, 0.0, 0.0);
|
|
||||||
|
|
||||||
[unroll] for (int y = -2; y <= 2; ++y)
|
|
||||||
{
|
|
||||||
[unroll] for (int x = -2; x <= 2; ++x)
|
|
||||||
{
|
|
||||||
float2 offset = float2(x, y);
|
|
||||||
float3 tap = tex2D(BackBuffer, uv + offset * texel).rgb;
|
|
||||||
float3 weight = IntensityWeight(tap, intensity_sigma, centre) *
|
|
||||||
SpatialWeight(length(offset), spatial_sigma);
|
|
||||||
sum += weight * tap;
|
|
||||||
total += weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return float4(sum / total, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique Denoise <
|
|
||||||
ui_label = "Denoise";
|
|
||||||
ui_tooltip = "Edge preserving blur that clears dithering and compression noise while leaving outlines sharp. Ported from Anime4K.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_Denoise;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-65
@@ -1,65 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float Intensity <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Intensity";
|
|
||||||
ui_min = 0.0; ui_max = 0.2; ui_step = 0.005;
|
|
||||||
> = 0.03;
|
|
||||||
|
|
||||||
uniform float Size <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Size";
|
|
||||||
ui_tooltip = "Grain cell size in pixels.";
|
|
||||||
ui_min = 1.0; ui_max = 4.0; ui_step = 1.0;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
uniform float Colored <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Colour";
|
|
||||||
ui_tooltip = "Zero gives monochrome grain, one gives independent noise per channel.";
|
|
||||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.01;
|
|
||||||
> = 0.0;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float Hash(float2 p)
|
|
||||||
{
|
|
||||||
float3 scattered = frac(float3(p.x, p.y, p.x) * 0.1031);
|
|
||||||
scattered += dot(scattered, scattered.yzx + 33.33);
|
|
||||||
return frac((scattered.x + scattered.y) * scattered.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_FilmGrain(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float3 rgb = tex2D(BackBuffer, uv).rgb;
|
|
||||||
|
|
||||||
float2 cell = floor(pos.xy / max(Size, 1.0));
|
|
||||||
float mono = Hash(cell) - 0.5;
|
|
||||||
float3 chroma = float3(Hash(cell + 11.7), Hash(cell + 23.1), Hash(cell + 37.5)) - 0.5;
|
|
||||||
float3 noise = lerp(float3(mono, mono, mono), chroma, Colored);
|
|
||||||
|
|
||||||
float luma = dot(rgb, float3(0.2126, 0.7152, 0.0722));
|
|
||||||
float response = 1.0 - abs(luma * 2.0 - 1.0);
|
|
||||||
|
|
||||||
return float4(saturate(rgb + noise * Intensity * response), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique FilmGrain <
|
|
||||||
ui_label = "Film Grain";
|
|
||||||
ui_tooltip = "Adds photographic grain, strongest in the midtones and fading out in blacks and whites.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_FilmGrain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-60
@@ -1,60 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float Exposure <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Exposure";
|
|
||||||
ui_min = 0.5; ui_max = 2.0; ui_step = 0.01;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
uniform float Toe <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Toe";
|
|
||||||
ui_tooltip = "Above 1.0 deepens the shadows, below 1.0 lifts them.";
|
|
||||||
ui_min = 0.5; ui_max = 2.0; ui_step = 0.01;
|
|
||||||
> = 1.2;
|
|
||||||
|
|
||||||
uniform float Shoulder <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Shoulder";
|
|
||||||
ui_tooltip = "Above 1.0 opens up the highlights, below 1.0 compresses them.";
|
|
||||||
ui_min = 0.5; ui_max = 2.0; ui_step = 0.01;
|
|
||||||
> = 1.2;
|
|
||||||
|
|
||||||
uniform float Amount <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Amount";
|
|
||||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.01;
|
|
||||||
> = 0.7;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_FilmicCurve(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float3 rgb = tex2D(BackBuffer, uv).rgb;
|
|
||||||
|
|
||||||
float3 curved = saturate(rgb * Exposure);
|
|
||||||
curved = pow(max(curved, 0.0), Toe);
|
|
||||||
curved = 1.0 - pow(max(1.0 - curved, 0.0), Shoulder);
|
|
||||||
|
|
||||||
return float4(saturate(lerp(rgb, curved, Amount)), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique FilmicCurve <
|
|
||||||
ui_label = "Filmic Curve";
|
|
||||||
ui_tooltip = "Filmic contrast curve. Deepens the shadows and opens the highlights without clipping either end.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_FilmicCurve;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-53
@@ -1,53 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float Distortion <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Distortion";
|
|
||||||
ui_tooltip = "Positive bulges the picture outwards, negative pinches it inwards.";
|
|
||||||
ui_min = -0.5; ui_max = 0.5; ui_step = 0.01;
|
|
||||||
> = 0.1;
|
|
||||||
|
|
||||||
uniform float Zoom <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Zoom";
|
|
||||||
ui_tooltip = "Scales the picture to hide the edges the warp pulls in.";
|
|
||||||
ui_min = 0.5; ui_max = 1.5; ui_step = 0.01;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_LensDistortion(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float aspect = BUFFER_WIDTH * BUFFER_RCP_HEIGHT;
|
|
||||||
float2 half_size = float2(aspect, 1.0);
|
|
||||||
float2 unit = half_size / length(half_size);
|
|
||||||
|
|
||||||
float2 centred = (uv - 0.5) * 2.0 * unit;
|
|
||||||
float r2 = dot(centred, centred);
|
|
||||||
centred *= 1.0 + Distortion * r2;
|
|
||||||
centred /= max(Zoom, 0.001);
|
|
||||||
|
|
||||||
float2 source = centred / (2.0 * unit) + 0.5;
|
|
||||||
|
|
||||||
return float4(tex2D(BackBuffer, source).rgb, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique LensDistortion <
|
|
||||||
ui_label = "Lens Distortion";
|
|
||||||
ui_tooltip = "Barrel or pincushion warp, like looking through a wide angle lens.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_LensDistortion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-66
@@ -1,66 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float InputBlack <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Input Black";
|
|
||||||
ui_tooltip = "Input level mapped to black. Raise it to deepen washed out shadows.";
|
|
||||||
ui_min = 0.0; ui_max = 0.5; ui_step = 0.005;
|
|
||||||
> = 0.0;
|
|
||||||
|
|
||||||
uniform float InputWhite <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Input White";
|
|
||||||
ui_min = 0.5; ui_max = 1.0; ui_step = 0.005;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
uniform float Gamma <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Gamma";
|
|
||||||
ui_min = 0.2; ui_max = 3.0; ui_step = 0.01;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
uniform float OutputBlack <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Output Black";
|
|
||||||
ui_tooltip = "Lifts crushed shadows so detail stops collapsing into one flat black.";
|
|
||||||
ui_min = 0.0; ui_max = 0.5; ui_step = 0.005;
|
|
||||||
> = 0.0;
|
|
||||||
|
|
||||||
uniform float OutputWhite <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Output White";
|
|
||||||
ui_min = 0.5; ui_max = 1.0; ui_step = 0.005;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_Levels(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float3 rgb = tex2D(BackBuffer, uv).rgb;
|
|
||||||
|
|
||||||
rgb = saturate((rgb - InputBlack) / max(InputWhite - InputBlack, 0.001));
|
|
||||||
rgb = pow(max(rgb, 0.0), 1.0 / max(Gamma, 0.001));
|
|
||||||
rgb = lerp(OutputBlack, OutputWhite, rgb);
|
|
||||||
|
|
||||||
return float4(saturate(rgb), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique Levels <
|
|
||||||
ui_label = "Levels";
|
|
||||||
ui_tooltip = "Black point, white point, gamma and output range. Use it to fix crushed or washed out shadows.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_Levels;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-88
@@ -1,88 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float Length <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Length";
|
|
||||||
ui_tooltip = "How far the streaks reach, as a percentage of screen height.";
|
|
||||||
ui_min = 0.0; ui_max = 20.0; ui_step = 0.5;
|
|
||||||
> = 5.0;
|
|
||||||
|
|
||||||
uniform float Zoom <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Zoom";
|
|
||||||
ui_tooltip = "Streaks running out from the centre of the screen, as if rushing forward. The centre stays sharp.";
|
|
||||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
uniform float Pan <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Pan";
|
|
||||||
ui_tooltip = "Streaks running in one fixed direction, as if the camera were sweeping across.";
|
|
||||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
|
||||||
> = 0.0;
|
|
||||||
|
|
||||||
uniform float Angle <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Pan Angle";
|
|
||||||
ui_tooltip = "Direction of the sweep, in degrees.";
|
|
||||||
ui_min = 0.0; ui_max = 360.0; ui_step = 5.0;
|
|
||||||
> = 0.0;
|
|
||||||
|
|
||||||
uniform float Spin <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Spin";
|
|
||||||
ui_tooltip = "Streaks curling around the centre, as if the camera were rolling. Negative turns the other way.";
|
|
||||||
ui_min = -1.0; ui_max = 1.0; ui_step = 0.05;
|
|
||||||
> = 0.0;
|
|
||||||
|
|
||||||
static const int TAPS = 24;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_MotionBlur(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float aspect = BUFFER_WIDTH * BUFFER_RCP_HEIGHT;
|
|
||||||
float2 to_screen = float2(aspect, 1.0);
|
|
||||||
|
|
||||||
float2 centred = (uv - 0.5) * to_screen * 2.0;
|
|
||||||
float2 outward = centred;
|
|
||||||
float2 around = float2(-centred.y, centred.x);
|
|
||||||
|
|
||||||
float radians_angle = Angle * 0.01745329;
|
|
||||||
float2 sweep = float2(cos(radians_angle), sin(radians_angle));
|
|
||||||
|
|
||||||
float2 velocity = sweep * Pan + outward * Zoom + around * Spin;
|
|
||||||
velocity *= Length * 0.01;
|
|
||||||
velocity /= to_screen;
|
|
||||||
|
|
||||||
float jitter = frac(sin(dot(pos.xy, float2(12.9898, 78.233))) * 43758.5453);
|
|
||||||
|
|
||||||
float3 sum = float3(0.0, 0.0, 0.0);
|
|
||||||
[unroll] for (int i = 0; i < TAPS; ++i)
|
|
||||||
{
|
|
||||||
float t = (float(i) + jitter) / float(TAPS) - 0.5;
|
|
||||||
sum += tex2D(BackBuffer, uv + velocity * t).rgb;
|
|
||||||
}
|
|
||||||
|
|
||||||
return float4(sum / float(TAPS), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique MotionBlur <
|
|
||||||
ui_label = "Motion Blur";
|
|
||||||
ui_tooltip = "Camera style motion blur: streaks the picture outwards, sideways or around, without touching still detail at the centre.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_MotionBlur;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-60
@@ -1,60 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2012 PPSSPP Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
// Ported from naturalA.fsh in PPSSPP, by ShadX, modified by SimoneT.
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float Luma <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Luma Curve";
|
|
||||||
ui_tooltip = "Gamma applied to the luminance channel in YIQ space.";
|
|
||||||
ui_min = 0.5; ui_max = 2.0; ui_step = 0.01;
|
|
||||||
> = 1.2;
|
|
||||||
|
|
||||||
uniform float Chroma <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Chroma Gain";
|
|
||||||
ui_tooltip = "Boost applied to the two colour difference channels.";
|
|
||||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.01;
|
|
||||||
> = 1.2;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_Natural(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
const float3x3 RGBtoYIQ = float3x3(0.299, 0.587, 0.114,
|
|
||||||
0.596, -0.275, -0.321,
|
|
||||||
0.212, -0.523, 0.311);
|
|
||||||
|
|
||||||
const float3x3 YIQtoRGB = float3x3(1.0, 0.95568806, 0.61985809,
|
|
||||||
1.0, -0.27158180, -0.64687382,
|
|
||||||
1.0, -1.10817733, 1.70506456);
|
|
||||||
|
|
||||||
float3 rgb = tex2D(BackBuffer, uv).rgb;
|
|
||||||
float3 yiq = mul(RGBtoYIQ, rgb);
|
|
||||||
|
|
||||||
yiq.x = pow(max(yiq.x, 0.0), Luma);
|
|
||||||
yiq.yz *= Chroma;
|
|
||||||
|
|
||||||
return float4(saturate(mul(YIQtoRGB, yiq)), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique NaturalColors <
|
|
||||||
ui_label = "Natural Colours";
|
|
||||||
ui_tooltip = "Warms the picture and lifts saturation for a less washed out look. Ported from the PPSSPP shader.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_Natural;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-90
@@ -1,90 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float Timer < source = "timer"; > = 0.0;
|
|
||||||
|
|
||||||
uniform float Horizon <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Reflection Line";
|
|
||||||
ui_tooltip = "Height on screen where the reflective floor begins. Everything above it is left untouched.";
|
|
||||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.01;
|
|
||||||
> = 0.55;
|
|
||||||
|
|
||||||
uniform float Amount <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Amount";
|
|
||||||
ui_tooltip = "How strongly the reflection shows through the floor.";
|
|
||||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
|
||||||
> = 0.35;
|
|
||||||
|
|
||||||
uniform float Falloff <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Falloff";
|
|
||||||
ui_tooltip = "How quickly the reflection fades as the floor comes towards the viewer. At zero it stays even.";
|
|
||||||
ui_min = 0.0; ui_max = 4.0; ui_step = 0.1;
|
|
||||||
> = 1.2;
|
|
||||||
|
|
||||||
uniform float Perspective <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Perspective";
|
|
||||||
ui_tooltip = "Stretches or squashes the mirrored image. One is a true mirror, higher values pull it towards the line.";
|
|
||||||
ui_min = 0.2; ui_max = 2.0; ui_step = 0.05;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
uniform float Ripple <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Ripple";
|
|
||||||
ui_tooltip = "Amplitude of the waves disturbing the reflection. At zero the mirror is perfectly still.";
|
|
||||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
|
||||||
> = 0.0;
|
|
||||||
|
|
||||||
uniform float RippleSpeed <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Ripple Speed";
|
|
||||||
ui_tooltip = "How fast the waves travel.";
|
|
||||||
ui_min = 0.0; ui_max = 4.0; ui_step = 0.1;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_Reflections(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float3 color = tex2D(BackBuffer, uv).rgb;
|
|
||||||
|
|
||||||
float depth = uv.y - Horizon;
|
|
||||||
float on_floor = step(0.0, depth);
|
|
||||||
float span = max(1.0 - Horizon, 0.001);
|
|
||||||
float distance_down = saturate(depth / span);
|
|
||||||
|
|
||||||
float seconds = Timer * 0.001;
|
|
||||||
float wave = sin(uv.x * 38.0 + seconds * RippleSpeed * 2.0) *
|
|
||||||
sin(uv.y * 21.0 - seconds * RippleSpeed * 1.3);
|
|
||||||
float2 disturbance = float2(wave * 0.004, wave * 0.002) * Ripple * distance_down;
|
|
||||||
|
|
||||||
float2 mirrored = float2(uv.x, Horizon - depth * Perspective) + disturbance;
|
|
||||||
float3 reflection = tex2D(BackBuffer, saturate(mirrored)).rgb;
|
|
||||||
|
|
||||||
float fade = pow(max(1.0 - distance_down, 0.0001), Falloff);
|
|
||||||
float strength = Amount * fade * on_floor;
|
|
||||||
|
|
||||||
return float4(lerp(color, reflection, strength), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique Reflections <
|
|
||||||
ui_label = "Reflections";
|
|
||||||
ui_tooltip = "Mirrors the picture into a reflective floor below a line you choose, with optional water ripples.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_Reflections;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-66
@@ -1,66 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2012 PPSSPP Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
// Ported from scanlines.fsh in PPSSPP.
|
|
||||||
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float Density <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Line Density";
|
|
||||||
ui_tooltip = "Number of scanline pairs across the screen.";
|
|
||||||
ui_min = 60.0; ui_max = 720.0; ui_step = 10.0;
|
|
||||||
> = 340.0;
|
|
||||||
|
|
||||||
uniform float Intensity <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Intensity";
|
|
||||||
ui_tooltip = "How dark the gaps between lines become.";
|
|
||||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
|
||||||
> = 0.5;
|
|
||||||
|
|
||||||
uniform float Tint <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Phosphor Tint";
|
|
||||||
ui_tooltip = "Strength of the green-warm phosphor cast.";
|
|
||||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.05;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_Scanlines(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float line_pos = uv.y * Density * 0.5;
|
|
||||||
float gate = cos((frac(line_pos) - 0.5) * 3.1415926 * Intensity) * 1.5;
|
|
||||||
|
|
||||||
float3 rgb = tex2D(BackBuffer, uv).rgb;
|
|
||||||
float3 color = rgb * 0.5 + 0.5 * rgb * rgb * 1.2;
|
|
||||||
|
|
||||||
float3 phosphor = lerp(float3(1.0, 1.0, 1.0), float3(0.9, 1.0, 0.7), Tint);
|
|
||||||
color *= phosphor;
|
|
||||||
|
|
||||||
float2 diff = uv - 0.5;
|
|
||||||
color *= 1.1 - 0.6 * (dot(diff, diff) * 2.0);
|
|
||||||
|
|
||||||
return float4(saturate(color * saturate(gate)), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique Scanlines <
|
|
||||||
ui_label = "Scanlines";
|
|
||||||
ui_tooltip = "Darkens alternating rows of pixels to imitate the horizontal scanlines of a CRT. Cheaper than the full CRT effect when you only want the lines.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_Scanlines;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-43
@@ -1,43 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float Amount <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Amount";
|
|
||||||
ui_min = 0.0; ui_max = 3.0; ui_step = 0.01;
|
|
||||||
> = 0.6;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_Sharpen(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float2 texel = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT);
|
|
||||||
|
|
||||||
float3 centre = tex2D(BackBuffer, uv).rgb;
|
|
||||||
float3 blur = tex2D(BackBuffer, uv + float2(-texel.x, 0.0)).rgb;
|
|
||||||
blur += tex2D(BackBuffer, uv + float2(texel.x, 0.0)).rgb;
|
|
||||||
blur += tex2D(BackBuffer, uv + float2(0.0, -texel.y)).rgb;
|
|
||||||
blur += tex2D(BackBuffer, uv + float2(0.0, texel.y)).rgb;
|
|
||||||
blur *= 0.25;
|
|
||||||
|
|
||||||
return float4(centre + (centre - blur) * Amount, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique Sharpen <
|
|
||||||
ui_label = "Sharpen";
|
|
||||||
ui_tooltip = "Unsharp mask that brings back edge detail lost to scaling. Most useful after upscaling a low internal resolution.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_Sharpen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-75
@@ -1,75 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float ShadowHue <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Shadow Hue";
|
|
||||||
ui_min = 0.0; ui_max = 360.0; ui_step = 1.0;
|
|
||||||
> = 210.0;
|
|
||||||
|
|
||||||
uniform float ShadowStrength <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Shadow Strength";
|
|
||||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.01;
|
|
||||||
> = 0.0;
|
|
||||||
|
|
||||||
uniform float HighlightHue <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Highlight Hue";
|
|
||||||
ui_min = 0.0; ui_max = 360.0; ui_step = 1.0;
|
|
||||||
> = 45.0;
|
|
||||||
|
|
||||||
uniform float HighlightStrength <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Highlight Strength";
|
|
||||||
ui_min = 0.0; ui_max = 1.0; ui_step = 0.01;
|
|
||||||
> = 0.0;
|
|
||||||
|
|
||||||
uniform float Balance <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Balance";
|
|
||||||
ui_tooltip = "Moves the split between what counts as shadow and what counts as highlight.";
|
|
||||||
ui_min = -0.5; ui_max = 0.5; ui_step = 0.01;
|
|
||||||
> = 0.0;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float3 HueToRGB(float hue)
|
|
||||||
{
|
|
||||||
float h = frac(hue / 360.0) * 6.0;
|
|
||||||
return saturate(float3(abs(h - 3.0) - 1.0, 2.0 - abs(h - 2.0), 2.0 - abs(h - 4.0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_SplitToning(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float3 rgb = tex2D(BackBuffer, uv).rgb;
|
|
||||||
|
|
||||||
float luma = saturate(dot(rgb, float3(0.2126, 0.7152, 0.0722)) + Balance);
|
|
||||||
|
|
||||||
float3 shadow_tint = HueToRGB(ShadowHue) - 0.5;
|
|
||||||
float3 highlight_tint = HueToRGB(HighlightHue) - 0.5;
|
|
||||||
|
|
||||||
rgb += shadow_tint * ShadowStrength * 0.25 * (1.0 - luma);
|
|
||||||
rgb += highlight_tint * HighlightStrength * 0.25 * luma;
|
|
||||||
|
|
||||||
return float4(saturate(rgb), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique SplitToning <
|
|
||||||
ui_label = "Split Toning";
|
|
||||||
ui_tooltip = "Tints the shadows and the highlights towards two different hues.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_SplitToning;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-52
@@ -1,52 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2012 PPSSPP Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
// Ported from vignette.fsh in PPSSPP, by Henrik Rydgard.
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float Strength <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Strength";
|
|
||||||
ui_tooltip = "How dark the corners become.";
|
|
||||||
ui_min = 0.0; ui_max = 2.0; ui_step = 0.01;
|
|
||||||
> = 0.6;
|
|
||||||
|
|
||||||
uniform float Aspect <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Aspect";
|
|
||||||
ui_min = 0.5; ui_max = 2.0; ui_step = 0.01;
|
|
||||||
> = 1.0;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_Vignette(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float2 diff = uv - 0.5;
|
|
||||||
diff.x *= Aspect;
|
|
||||||
diff.y /= max(Aspect, 0.0001);
|
|
||||||
|
|
||||||
float falloff = 1.0 - min(1.0, Strength * dot(diff, diff) * 2.0);
|
|
||||||
float3 rgb = tex2D(BackBuffer, uv).rgb;
|
|
||||||
|
|
||||||
return float4(rgb * falloff, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique Vignette <
|
|
||||||
ui_label = "Vignette";
|
|
||||||
ui_tooltip = "Darkens the corners of the screen to pull the eye towards the middle, the way a camera lens falls off at its edges.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_Vignette;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-76
@@ -1,76 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
texture BackBufferTex : COLOR;
|
|
||||||
sampler BackBuffer { Texture = BackBufferTex; };
|
|
||||||
|
|
||||||
uniform float Temperature <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Temperature";
|
|
||||||
ui_tooltip = "Negative cools the picture towards blue, positive warms it towards orange.";
|
|
||||||
ui_min = -100.0; ui_max = 100.0; ui_step = 1.0;
|
|
||||||
> = 0.0;
|
|
||||||
|
|
||||||
uniform float Tint <
|
|
||||||
ui_type = "slider";
|
|
||||||
ui_label = "Tint";
|
|
||||||
ui_tooltip = "Negative shifts towards green, positive towards magenta.";
|
|
||||||
ui_min = -100.0; ui_max = 100.0; ui_step = 1.0;
|
|
||||||
> = 0.0;
|
|
||||||
|
|
||||||
void VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD)
|
|
||||||
{
|
|
||||||
uv = float2(float(id & 2), float((id & 1) << 1));
|
|
||||||
pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float3 WhitePointLMS(float t1, float t2)
|
|
||||||
{
|
|
||||||
float shift = 0.05;
|
|
||||||
if (t1 < 0.0)
|
|
||||||
{
|
|
||||||
shift = 0.10;
|
|
||||||
}
|
|
||||||
float x = 0.31271 - t1 * shift;
|
|
||||||
float y = 2.87 * x - 3.0 * x * x - 0.27509507 + t2 * 0.05;
|
|
||||||
|
|
||||||
float big_y = 1.0;
|
|
||||||
float big_x = big_y * x / y;
|
|
||||||
float big_z = big_y * (1.0 - x - y) / y;
|
|
||||||
|
|
||||||
return float3( 0.7328 * big_x + 0.4296 * big_y - 0.1624 * big_z,
|
|
||||||
-0.7036 * big_x + 1.6975 * big_y + 0.0061 * big_z,
|
|
||||||
0.0030 * big_x + 0.0136 * big_y + 0.9834 * big_z);
|
|
||||||
}
|
|
||||||
|
|
||||||
float4 PS_WhiteBalance(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target
|
|
||||||
{
|
|
||||||
float3 rgb = pow(max(tex2D(BackBuffer, uv).rgb, 0.0), 2.2);
|
|
||||||
|
|
||||||
float3 balance = float3(0.949237, 1.03542, 1.08728) /
|
|
||||||
WhitePointLMS(Temperature / 65.0, Tint / 65.0);
|
|
||||||
|
|
||||||
const float3x3 rgb_to_lms = float3x3(0.390405, 0.549941, 0.008926,
|
|
||||||
0.070841, 0.963172, 0.001358,
|
|
||||||
0.023108, 0.128021, 0.936245);
|
|
||||||
const float3x3 lms_to_rgb = float3x3( 2.858470, -1.628790, -0.024891,
|
|
||||||
-0.210182, 1.158200, 0.000324,
|
|
||||||
-0.041812, -0.118169, 1.068670);
|
|
||||||
|
|
||||||
float3 lms = mul(rgb_to_lms, rgb) * balance;
|
|
||||||
rgb = mul(lms_to_rgb, lms);
|
|
||||||
|
|
||||||
return float4(saturate(pow(max(rgb, 0.0), 1.0 / 2.2)), 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
technique WhiteBalance <
|
|
||||||
ui_label = "White Balance";
|
|
||||||
ui_tooltip = "Corrects a picture that looks too cool, too warm or tinted.";
|
|
||||||
>
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
VertexShader = VS_PostProcess;
|
|
||||||
PixelShader = PS_WhiteBalance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+137
-1
@@ -2,7 +2,122 @@
|
|||||||
|
|
||||||
General guide for cross compiling.
|
General guide for cross compiling.
|
||||||
|
|
||||||
## Debian ARM64
|
## Gentoo
|
||||||
|
|
||||||
|
Gentoo's cross-compilation setup is relatively easy, provided you're already familiar with portage.
|
||||||
|
|
||||||
|
### Crossdev
|
||||||
|
|
||||||
|
First, emerge crossdev via `sudo emerge -a sys-devel/crossdev`.
|
||||||
|
|
||||||
|
Now, set up the environment depending on the target architecture; e.g.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo crossdev powerpc64le
|
||||||
|
sudo crossdev aarch64
|
||||||
|
```
|
||||||
|
|
||||||
|
### QEMU
|
||||||
|
|
||||||
|
Installing a qemu user setup is recommended for testing. To do so, you will need the relevant USE flags:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
app-emulation/qemu static-user qemu_user_targets_ppc64le qemu_user_targets_aarch64
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that to use cross-emerged libraries, you will need to tell qemu where the sysroot is. You can do this with an alias:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
alias qemu-ppc64le="qemu-ppc64le -L /usr/powerpc64le-unknown-linux-gnu"
|
||||||
|
alias qemu-aarch64="qemu-aarch64 -L /usr/aarch64-unknown-linux-gnu"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
Some packages have broken USE flags on other architectures; you'll also need to set up python targets. In `/usr/<target>-unknown-linux-gnu/etc/portage/package.use`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
>=net-misc/curl-8.16.0-r1 ssl
|
||||||
|
|
||||||
|
*/* PYTHON_TARGETS: python3_13 PYTHON_SINGLE_TARGET: python3_13
|
||||||
|
*/* pam
|
||||||
|
|
||||||
|
sys-apps/util-linux pam su
|
||||||
|
app-shells/bash -readline
|
||||||
|
>=dev-libs/libpcre2-10.47 unicode
|
||||||
|
>=x11-libs/libxkbcommon-1.12.3 X
|
||||||
|
>=sys-libs/zlib-1.3.1-r1 minizip
|
||||||
|
>=app-alternatives/gpg-1-r3 ssl
|
||||||
|
>=app-crypt/gnupg-2.5.13-r2 ssl
|
||||||
|
|
||||||
|
dev-libs/* -introspection
|
||||||
|
media-libs/harfbuzz -introspection
|
||||||
|
dev-libs/quazip -qt5 qt6
|
||||||
|
```
|
||||||
|
|
||||||
|
Dependencies should be about the same [as normal Gentoo](./Deps.md), but removing gamemode and renderdoc is recommended. Keep in mind that when emerging, you want to use `emerge-<target>-unknown-linux-gnu`, e.g. `emerge-powerpc64le-unknown-linux-gnu`.
|
||||||
|
|
||||||
|
Enable GURU in the cross environment (as root):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
mkdir -p /usr/powerpc64le-unknown-linux-gnu/etc/portage/repos.conf
|
||||||
|
cat << EOF > /usr/powerpc64le-unknown-linux-gnu/etc/portage/repos.conf/guru.conf
|
||||||
|
[guru]
|
||||||
|
location = /var/db/repos/guru
|
||||||
|
auto-sync = no
|
||||||
|
priority = 1
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
Now emerge your dependencies:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo emerge-powerpc64le-unknown-linux-gnu -aU app-arch/lz4 app-arch/zstd app-arch/unzip \
|
||||||
|
dev-libs/libfmt dev-libs/libusb dev-libs/mcl dev-libs/sirit dev-libs/oaknut \
|
||||||
|
dev-libs/unordered_dense dev-libs/boost dev-libs/openssl dev-libs/discord-rpc \
|
||||||
|
dev-util/spirv-tools dev-util/spirv-headers dev-util/vulkan-headers \
|
||||||
|
dev-util/vulkan-utility-libraries dev-util/glslang \
|
||||||
|
media-libs/libva media-libs/opus media-video/ffmpeg \
|
||||||
|
media-libs/VulkanMemoryAllocator media-libs/libsdl2 media-libs/cubeb \
|
||||||
|
net-libs/enet net-libs/mbedtls \
|
||||||
|
sys-libs/zlib \
|
||||||
|
dev-cpp/nlohmann_json dev-cpp/simpleini dev-cpp/cpp-httplib dev-cpp/cpp-jwt dev-cpp/catch \
|
||||||
|
net-wireless/wireless-tools \
|
||||||
|
dev-qt/qtbase:6 dev-libs/quazip \
|
||||||
|
virtual/pkgconfig
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building
|
||||||
|
|
||||||
|
A toolchain is provided in `CMakeModules/GentooCross.cmake`. To use it:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cmake -S . -B build/ppc64 -DCMAKE_TOOLCHAIN_FILE=CMakeModules/GentooCross.cmake -G Ninja -DCROSS_TARGET=powerpc64le -DENABLE_OPENGL=OFF
|
||||||
|
```
|
||||||
|
|
||||||
|
Now build as normal:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cmake --build build/ppc64 -j$(nproc)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Alternatively
|
||||||
|
|
||||||
|
Only emerge the absolute necessities:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo emerge-powerpc64le-unknown-linux-gnu -aU media-video/ffmpeg media-libs/libsdl2 dev-qt/qtbase:6
|
||||||
|
```
|
||||||
|
|
||||||
|
Then set `YUZU_USE_CPM=ON`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cmake -S . -B build/ppc64 -DCMAKE_TOOLCHAIN_FILE=CMakeModules/GentooCross.cmake -G Ninja -DCROSS_TARGET=powerpc64le -DENABLE_OPENGL=OFF -DYUZU_USE_CPM=ON
|
||||||
|
```
|
||||||
|
|
||||||
|
## ARM64
|
||||||
|
|
||||||
|
### Debian ARM64
|
||||||
|
|
||||||
A painless guide for cross compilation (or to test NCE) from a x86_64 system without polluting your main.
|
A painless guide for cross compilation (or to test NCE) from a x86_64 system without polluting your main.
|
||||||
|
|
||||||
@@ -88,3 +203,24 @@ And finally, run the compiled executable with QEMU!
|
|||||||
```sh
|
```sh
|
||||||
qemu-aarch64 build/aarch64/bin/eden
|
qemu-aarch64 build/aarch64/bin/eden
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## PowerPC
|
||||||
|
|
||||||
|
This is a guide for FreeBSD users mainly.
|
||||||
|
|
||||||
|
Now you got a PowerPC sysroot - quickly decompress it somewhere, say `/home/user/opt/powerpc64le`. Create a toolchain file, for example `powerpc64le-toolchain.cmake`; always [consult the manual](https://man.freebsd.org/cgi/man.cgi?query=cmake-toolchains&sektion=7&manpath=FreeBSD+13.2-RELEASE+and+Ports).
|
||||||
|
|
||||||
|
There is a script to automatically do all of this under `./tools/setup-cross-sysroot.sh`.
|
||||||
|
|
||||||
|
Remember to add `-mabi=elfv1` to `CFLAGS`/`CXXFLAGS` otherwise the program will crash.
|
||||||
|
|
||||||
|
Specify:
|
||||||
|
|
||||||
|
- `YUZU_USE_CPM`: Set this to `ON` so packages can be found and built if your sysroot doesn't have them.
|
||||||
|
- `YUZU_USE_EXTERNAL_FFMPEG`: Set this to `ON` as well.
|
||||||
|
|
||||||
|
Then run using a program such as QEMU to emulate userland syscalls:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cmake --build build-ppc64-pc-freebsd -t dynarmic_tests -- -j8 && qemu-ppc64-static -L $HOME/opt/ppc64-freebsd/sysroot ./build-ppc64-pc-freebsd/bin/dynarmic_tests
|
||||||
|
```
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# PowerPC 64 backend
|
||||||
|
|
||||||
|
The ppc64 backend currently only supports the little endian variant, with big endian support being experimental for the time being. Additionally only A32 is supported (for now).
|
||||||
|
|
||||||
|
- Flag handling: Flags are emulated via software, while there may be some funny tricks with the CTR, I'd rather not bother - plus it's widely known that those instructions are not nice on real metal - so I would rather take the i-cache cost.
|
||||||
|
- 128-bit atomics: No 128-bit atomic support is provided, this may cause wrong or erroneous execution in some contexts.
|
||||||
|
|
||||||
|
To handle endianess differences all 16/32/64-bit loads and stores to the "emulated memory" are byteswapped beforehand.
|
||||||
@@ -7,11 +7,12 @@ A dynamic recompiler for ARM.
|
|||||||
|
|
||||||
Cortex-A57 (32 and 64 bit) is the emulated guest target. See [ArchVersion](../../src/dynarmic/src/dynarmic/interface/A32/arch_version.h).
|
Cortex-A57 (32 and 64 bit) is the emulated guest target. See [ArchVersion](../../src/dynarmic/src/dynarmic/interface/A32/arch_version.h).
|
||||||
|
|
||||||
The only supported host architectures are x86-64, and AArch64. There are no plans to support any 32-bit architectures.
|
The only supported host architectures are x86-64, PowerPC 64, and AArch64. There are no plans to support any 32-bit architectures.
|
||||||
|
|
||||||
See [an example usage](../../src/dynarmic/tests/print_info.cpp).
|
See [an example usage](../../src/dynarmic/tests/print_info.cpp).
|
||||||
|
|
||||||
Design documentation can be found at [./Design.md](./Design.md).
|
Design documentation can be found at [./Design.md](./Design.md).
|
||||||
|
PowerPC design documentation can be found at [./PowerPC](./PowerPC.md).
|
||||||
|
|
||||||
Alternatives to Dynarmic
|
Alternatives to Dynarmic
|
||||||
------------------------
|
------------------------
|
||||||
|
|||||||
Vendored
+5
-44
@@ -195,50 +195,6 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# reshadefx
|
|
||||||
if (ENABLE_RESHADE)
|
|
||||||
AddJsonPackage(NAME reshade DOWNLOAD_ONLY)
|
|
||||||
|
|
||||||
set(RESHADEFX_SHIM_DIR ${CMAKE_CURRENT_BINARY_DIR}/reshadefx_shim)
|
|
||||||
file(WRITE ${RESHADEFX_SHIM_DIR}/spirv.hpp "#include <spirv/unified1/spirv.hpp>\n")
|
|
||||||
file(WRITE ${RESHADEFX_SHIM_DIR}/GLSL.std.450.h "#include <spirv/unified1/GLSL.std.450.h>\n")
|
|
||||||
if (APPLE)
|
|
||||||
file(WRITE ${RESHADEFX_SHIM_DIR}/malloc.h "#include <stdlib.h>\n#include <alloca.h>\n")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_library(reshadefx STATIC
|
|
||||||
${reshade_SOURCE_DIR}/source/effect_codegen_spirv.cpp
|
|
||||||
${reshade_SOURCE_DIR}/source/effect_expression.cpp
|
|
||||||
${reshade_SOURCE_DIR}/source/effect_lexer.cpp
|
|
||||||
${reshade_SOURCE_DIR}/source/effect_parser_exp.cpp
|
|
||||||
${reshade_SOURCE_DIR}/source/effect_parser_stmt.cpp
|
|
||||||
${reshade_SOURCE_DIR}/source/effect_preprocessor.cpp
|
|
||||||
${reshade_SOURCE_DIR}/source/effect_symbol_table.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
target_include_directories(reshadefx SYSTEM PUBLIC ${reshade_SOURCE_DIR}/source)
|
|
||||||
target_include_directories(reshadefx PRIVATE ${RESHADEFX_SHIM_DIR})
|
|
||||||
target_link_libraries(reshadefx PUBLIC SPIRV-Headers::SPIRV-Headers)
|
|
||||||
|
|
||||||
if (NOT MSVC)
|
|
||||||
target_compile_options(reshadefx PRIVATE -w -fno-char8_t)
|
|
||||||
else()
|
|
||||||
target_compile_options(reshadefx PRIVATE /w /Zc:char8_t-)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (WIN32)
|
|
||||||
if (NOT MSVC)
|
|
||||||
target_compile_options(reshadefx PRIVATE -include share.h)
|
|
||||||
else()
|
|
||||||
target_compile_options(reshadefx PRIVATE /FIshare.h)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT TARGET reshadefx::reshadefx)
|
|
||||||
add_library(reshadefx::reshadefx ALIAS reshadefx)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Catch2
|
# Catch2
|
||||||
if (YUZU_TESTS OR DYNARMIC_TESTS)
|
if (YUZU_TESTS OR DYNARMIC_TESTS)
|
||||||
AddJsonPackage(catch2)
|
AddJsonPackage(catch2)
|
||||||
@@ -293,6 +249,11 @@ endif()
|
|||||||
# TZDB (Time Zone Database)
|
# TZDB (Time Zone Database)
|
||||||
add_subdirectory(nx_tzdb)
|
add_subdirectory(nx_tzdb)
|
||||||
|
|
||||||
|
# PowerPC emitter
|
||||||
|
if (ARCHITECTURE_powerpc64)
|
||||||
|
add_subdirectory(powah)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_library(tz tz/tz/tz.cpp)
|
add_library(tz tz/tz/tz.cpp)
|
||||||
target_include_directories(tz PUBLIC ./tz)
|
target_include_directories(tz PUBLIC ./tz)
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -166,7 +166,7 @@ detect_architecture_symbols(
|
|||||||
"_M_MRX000")
|
"_M_MRX000")
|
||||||
|
|
||||||
detect_architecture_symbols(
|
detect_architecture_symbols(
|
||||||
ARCH ppc64
|
ARCH powerpc64
|
||||||
SYMBOLS
|
SYMBOLS
|
||||||
"__ppc64__"
|
"__ppc64__"
|
||||||
"__powerpc64__"
|
"__powerpc64__"
|
||||||
@@ -174,7 +174,7 @@ detect_architecture_symbols(
|
|||||||
"_M_PPC64")
|
"_M_PPC64")
|
||||||
|
|
||||||
detect_architecture_symbols(
|
detect_architecture_symbols(
|
||||||
ARCH ppc
|
ARCH powerpc
|
||||||
SYMBOLS
|
SYMBOLS
|
||||||
"__ppc__"
|
"__ppc__"
|
||||||
"__ppc"
|
"__ppc"
|
||||||
|
|||||||
Vendored
+10
@@ -0,0 +1,10 @@
|
|||||||
|
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
add_library(powah INTERFACE)
|
||||||
|
target_include_directories(powah INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
target_compile_options(powah INTERFACE -Wno-unused-parameter)
|
||||||
|
|
||||||
|
add_executable(powah_tests tests.cpp)
|
||||||
|
create_target_directory_groups(powah_tests)
|
||||||
|
target_link_libraries(powah_tests PRIVATE Catch2::Catch2WithMain)
|
||||||
Vendored
+145
@@ -0,0 +1,145 @@
|
|||||||
|
vabsdub,VX,04,1027
|
||||||
|
vabsduh,VX,04,1091
|
||||||
|
vabsduw,VX,04,1155
|
||||||
|
vaddcuw,VX,04,384
|
||||||
|
vaddfp,VX,04,10
|
||||||
|
vaddsbs,VX,04,768
|
||||||
|
vaddshs,VX,04,832
|
||||||
|
vaddsws,VX,04,896
|
||||||
|
vaddubm,VX,04,0
|
||||||
|
vaddubs,VX,04,512
|
||||||
|
vadduhm,VX,04,64
|
||||||
|
vadduhs,VX,04,576
|
||||||
|
vadduwm,VX,04,128
|
||||||
|
vadduws,VX,04,640
|
||||||
|
vand,VX,04,1028
|
||||||
|
vandc,VX,04,1092
|
||||||
|
vavgsb,VX,04,1282
|
||||||
|
vavgsh,VX,04,1346
|
||||||
|
vavgsw,VX,04,1410
|
||||||
|
vavgub,VX,04,1026
|
||||||
|
vavguh,VX,04,1090
|
||||||
|
vavguw,VX,04,1154
|
||||||
|
vcfsx,VDU,04842
|
||||||
|
vcfux,VDU,04778
|
||||||
|
vcmpbfp,VXR,04,966
|
||||||
|
vcmpeqfp,VXR,04,198
|
||||||
|
vcmpequb,VXR,04,6
|
||||||
|
vcmpequh,VXR,04,70
|
||||||
|
vcmpequw,VXR,04,134
|
||||||
|
vcmpgefp,VXR,04,454
|
||||||
|
vcmpgtfp,VXR,04,710
|
||||||
|
vcmpgtsb,VXR,04,774
|
||||||
|
vcmpgtsh,VXR,04,838
|
||||||
|
vcmpgtsw,VXR,04,902
|
||||||
|
vcmpgtub,VXR,04,518
|
||||||
|
vcmpgtuh,VXR,04,582
|
||||||
|
vcmpgtuw,VXR,04,646
|
||||||
|
vctsxs,VDU,04970
|
||||||
|
vctuxs,VDU,04906
|
||||||
|
vexptefp,VY,04,394
|
||||||
|
vlogefp,VY,04,458
|
||||||
|
vmaddfp,VXC,46
|
||||||
|
vmaxfp,VX,04,1034
|
||||||
|
vmaxsb,VX,04,258
|
||||||
|
vmaxsh,VX,04,322
|
||||||
|
vmaxsw,VX,04,386
|
||||||
|
vmaxub,VX,04,2
|
||||||
|
vmaxuh,VX,04,66
|
||||||
|
vmaxuw,VX,04,130
|
||||||
|
vmhaddshs,VXC,32
|
||||||
|
vmhraddshs,VXC,33
|
||||||
|
vminfp,VX,04,1098
|
||||||
|
vminsb,VX,04,770
|
||||||
|
vminsh,VX,04,834
|
||||||
|
vminsw,VX,04,898
|
||||||
|
vminub,VX,04,514
|
||||||
|
vminuh,VX,04,578
|
||||||
|
vminuw,VX,04,642
|
||||||
|
vmladduhm,VXC,34
|
||||||
|
vmrghb,VX,04,12
|
||||||
|
vmrghh,VX,04,76
|
||||||
|
vmrghw,VX,04,140
|
||||||
|
vmrglb,VX,04,268
|
||||||
|
vmrglh,VX,04,332
|
||||||
|
vmrglw,VX,04,396
|
||||||
|
vmsummbm,VXC,37
|
||||||
|
vmsumshm,VXC,40
|
||||||
|
vmsumshs,VXC,41
|
||||||
|
vmsumubm,VXC,36
|
||||||
|
vmsumuhm,VXC,38
|
||||||
|
vmsumuhs,VXC,39
|
||||||
|
vmulesb,VX,04,776
|
||||||
|
vmulesh,VX,04,840
|
||||||
|
vmuleub,VX,04,520
|
||||||
|
vmuleuh,VX,04,584
|
||||||
|
vmulosb,VX,04,264
|
||||||
|
vmulosh,VX,04,328
|
||||||
|
vmuloub,VX,04,8
|
||||||
|
vmulouh,VX,04,72
|
||||||
|
vnmsubfp,VXC,47
|
||||||
|
vnor,VX,04,1284
|
||||||
|
vor,VX,04,1156
|
||||||
|
vperm,VXC,43
|
||||||
|
vpkpx,VX,04,782
|
||||||
|
vpkshss,VX,04,398
|
||||||
|
vpkshus,VX,04,270
|
||||||
|
vpkswss,VX,04,462
|
||||||
|
vpkswus,VX,04,334
|
||||||
|
vpkuhum,VX,04,14
|
||||||
|
vpkuhus,VX,04,142
|
||||||
|
vpkuwum,VX,04,78
|
||||||
|
vpkuwus,VX,04,206
|
||||||
|
vrefp,VY,04,266
|
||||||
|
vrfim,VY,04,714
|
||||||
|
vrfin,VY,04,522
|
||||||
|
vrfip,VY,04,650
|
||||||
|
vrfiz,VY,04,586
|
||||||
|
vrlb,VX,04,4
|
||||||
|
vrlh,VX,04,68
|
||||||
|
vrlw,VX,04,132
|
||||||
|
vrsqrtefp,VY,04,330
|
||||||
|
vsel,VXC,42
|
||||||
|
vsl,VX,04,452
|
||||||
|
vslb,VX,04,260
|
||||||
|
vsldoi,VX,04,/ SH 44
|
||||||
|
vslh,VX,04,324
|
||||||
|
vslo,VX,04,1036
|
||||||
|
vslw,VX,04,388
|
||||||
|
vspltb,VU,04,524
|
||||||
|
vsplth,VU,04,588
|
||||||
|
vspltisb,VS,04,780
|
||||||
|
vspltish,VS,04,844
|
||||||
|
vspltisw,VS,04,908
|
||||||
|
vspltw,VSU,04,652
|
||||||
|
vsr,VX,04,708
|
||||||
|
vsrab,VX,04,772
|
||||||
|
vsrah,VX,04,836
|
||||||
|
vsraw,VX,04,900
|
||||||
|
vsrb,VX,04,516
|
||||||
|
vsrh,VX,04,580
|
||||||
|
vsro,VX,04,1100
|
||||||
|
vsrw,VX,04,644
|
||||||
|
vsubcuw,VX,04,1408
|
||||||
|
vsubfp,VX,04,74
|
||||||
|
vsubsbs,VX,04,1792
|
||||||
|
vsubshs,VX,04,1856
|
||||||
|
vsubsws,VX,04,1920
|
||||||
|
vsububm,VX,04,1024
|
||||||
|
vsububs,VX,04,1536
|
||||||
|
vsubuhm,VX,04,1088
|
||||||
|
vsubuhs,VX,04,1600
|
||||||
|
vsubuwm,VX,04,1152
|
||||||
|
vsubuws,VX,04,1664
|
||||||
|
vsumsws,VX,04,1928
|
||||||
|
vsum2sws,VX,04,1672
|
||||||
|
vsum4sbs,VX,04,1800
|
||||||
|
vsum4shs,VX,04,1608
|
||||||
|
vsum4ubs,VX,04,1544
|
||||||
|
vupkhpx,VY,04,846
|
||||||
|
vupkhsb,VY,04,526
|
||||||
|
vupkhsh,VY,04,590
|
||||||
|
vupklpx,VY,04,974
|
||||||
|
vupklsb,VY,04,654
|
||||||
|
vupklsh,VY,04,718
|
||||||
|
vxor,VX,04,122
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
$CC data2code.c -o data2code && ./data2code data.txt >powah_gen_base.hpp
|
||||||
|
$CC --target=powerpc64le test.S -c -o test && objdump -SC test
|
||||||
Vendored
+222
@@ -0,0 +1,222 @@
|
|||||||
|
add[o][.],Add,XO,31,266
|
||||||
|
addc[o][.],Add Carrying,XO,31,10
|
||||||
|
adde[o][.],Add Extended,XO,31,138
|
||||||
|
addi,Add Immediate,D,14,
|
||||||
|
addic,Add Immediate Carrying,D,12,
|
||||||
|
addic.,Add Immediate Carrying and Record,D,13,
|
||||||
|
addis,Add Immediate Shifted,D,15,
|
||||||
|
addme[o][.],Add to Minus One Extended,XO,31,234
|
||||||
|
addze[o][.],Add to Zero Extended,XO,31,202
|
||||||
|
and[.],AND,X,31,28
|
||||||
|
andc[.],AND with Complement,X,31,60
|
||||||
|
andi.,AND Immediate,D,28,
|
||||||
|
andis.,AND Immediate Shifted,D,29,
|
||||||
|
b[l][a],Branch,I,18,
|
||||||
|
bc[l][a],Branch Conditional,B,16,
|
||||||
|
bcctr[l],Branch Conditional to Count Register,XL,19,528
|
||||||
|
bclr[l],Branch Conditional Link Register,XL,19,16
|
||||||
|
cmp,Compare,X,31,0
|
||||||
|
cmpi,Compare Immediate,D,11,
|
||||||
|
cmpl,Compare Logical,X,31,32
|
||||||
|
cmpli,Compare Logical Immediate,D,10,
|
||||||
|
cntlzd,Count Leading Zeros Doubleword,X,31,58
|
||||||
|
cntlzw[.],Count Leading Zeros Word,X,31,26
|
||||||
|
crand,Condition Register AND,XL,19,257
|
||||||
|
crandc,Condition Register AND with Complement,XL,19,129
|
||||||
|
creqv,Condition Register Equivalent,XL,19,289
|
||||||
|
crnand,Condition Register NAND,XL,19,225
|
||||||
|
crnor,Condition Register NOR,XL,19,33
|
||||||
|
cror,Condition Register OR,XL,19,449
|
||||||
|
crorc,Condition Register OR with Complement,XL,19,417
|
||||||
|
crxor,Condition Register XOR,XL,19,193
|
||||||
|
dcbf,Data Cache Block Flush,X,31,86
|
||||||
|
dcbi,Data Cache Block Invalidate,X,31,470
|
||||||
|
dcbst,Data Cache Block Store,X,31,54
|
||||||
|
dcbt,Data Cache Block Touch,X,31,278
|
||||||
|
dcbtst,Data Cache Block Touch for Store,X,31,246
|
||||||
|
dcbz,Data Cache Block Set to Zero,X,31,1014
|
||||||
|
divd,Divide Doubleword,XO,31,489
|
||||||
|
divdu,Divide Doubleword Unsigned,XO,31,457
|
||||||
|
divw[o][.],Divide Word,XO,31,491
|
||||||
|
divwu[o][.],Divide Word Unsigned,XO,31,459
|
||||||
|
eciwx,External Control in Word Indexed (opt.),X,31,310
|
||||||
|
ecowx,External Control out Word Indexed (opt.),X,31,438
|
||||||
|
eieio,Enforce In-order Execution of I/O,X,31,854
|
||||||
|
eqv[.],Equivalent,X,31,284
|
||||||
|
extsb[.],Extend Sign Byte,X,31,954
|
||||||
|
extsh[.],Extend Sign Halfword,XO,31,922
|
||||||
|
extsw,Extend Sign Word,X,31,986
|
||||||
|
fabs[.],Floating Absolute Value,X,63,264
|
||||||
|
fadd[.],Floating Add,A,63,21
|
||||||
|
fadds[.],Floating Add Single,A,59,21
|
||||||
|
fcfid,Floating Convert from Integer Doubleword,X,63,846
|
||||||
|
fcmpo,Floating Compare Ordered,X,63,32
|
||||||
|
fcmpu,Floating Compare Unordered,XL,63,0
|
||||||
|
fctid,Floating Convert to Integer Doubleword,X,63,814
|
||||||
|
fctidz,Floating Convert to Integer Doubleword with Round Toward Zero,X,63,815
|
||||||
|
fctiw[.],Floating Convert to Integer Word,X,63,14
|
||||||
|
fctiwz[.],Floating Convert to Integer Word with Round to Zero,XL,63,15
|
||||||
|
fdiv[.],Floating Divide,A,63,18
|
||||||
|
fdivs[.],Floating Divide Single,A,59,18
|
||||||
|
fmadd[.],Floating Multiply-Add,A,63,29
|
||||||
|
fmadds[.],Floating Multiply-Add Single,A,59,29
|
||||||
|
fmr[.],Floating Move Register,X,63,72
|
||||||
|
fmsub[.],Floating Multiply-Subtract,A,63,28
|
||||||
|
fmsubs[.],Floating Multiply-Subtract Single,A,59,28
|
||||||
|
fmul[.],Floating Multiply,A,63,25
|
||||||
|
fmuls[.],Floating Multiply Single,A,59,25
|
||||||
|
fnabs[.],Floating Negative Absolute Value,X,63,136
|
||||||
|
fneg[.],Floating Negate,X,63,40
|
||||||
|
fnmadd[.],Floating Negative Multiply-Add,A,63,31
|
||||||
|
fnmadds[.],Floating Negative Multiply-Add Single,A,59,31
|
||||||
|
fnmsub[.],Floating Negative Multiply-Subtract,A,63,30
|
||||||
|
fnmsubs[.],Floating Negative Multiply-Subtract Single,A,59,30
|
||||||
|
fres[.],Floating Reciprocal Estimate Single (optional),A,59,24
|
||||||
|
frsp[.],Floating Round to Single Precision,X,63,12
|
||||||
|
frsqrte[.],Floating Reciprocal Square Root Estimate (optional),A,63,26
|
||||||
|
fsel[.],Floating-Point Select (optional),A,63,23
|
||||||
|
fsub[.],Floating Subtract,A,63,20
|
||||||
|
fsubs[.],Floating Subtract Single,A,59,20
|
||||||
|
icbi,Instruction Cache Block Invalidate,X,31,982
|
||||||
|
isync,Instruction Synchronize,X,19,150
|
||||||
|
lbz,Load Byte and Zero,D,34,
|
||||||
|
lbzu,Load Byte and Zero with Update,D,35,
|
||||||
|
lbzux,Load Byte and Zero with Update Indexed,X,31,119
|
||||||
|
lbzx,Load Byte and Zero Indexed,X,31,87
|
||||||
|
ld,Load Doubleword,DS,58,0
|
||||||
|
ldarx,Load Doubleword and Reserve Indexed,X,31,84
|
||||||
|
ldu,Load Doubleword with Update,DS,58,1
|
||||||
|
ldux,Load Doubleword with Update Indexed,X,31,53
|
||||||
|
ldx,Load Doubleword Indexed,X,31,21
|
||||||
|
lfd,Load Floating-Point Double,D,50,
|
||||||
|
lfdu,Load Floating-Point Double with Update,D,51,
|
||||||
|
lfdux,Load Floating-Point Double with Update Indexed,X,31,631
|
||||||
|
lfdx,Load Floating-Point Double Indexed,X,31,599
|
||||||
|
lfs,Load Floating-Point Single,D,48,
|
||||||
|
lfsu,Load Floating-Point Single with Update,D,49,
|
||||||
|
lfsux,Load Floating-Point Single with Update Indexed,X,31,567
|
||||||
|
lfsx,Load Floating-Point Single Indexed,X,31,535
|
||||||
|
lha,Load Half Algebraic,D,42,
|
||||||
|
lhau,Load Half Algebraic with Update,D,43,
|
||||||
|
lhaux,Load Half Algebraic with Update Indexed,X,31,375
|
||||||
|
lhax,Load Half Algebraic Indexed,X,31,343
|
||||||
|
lhbrx,Load Half Byte-Reversed Indexed,X,31,790
|
||||||
|
lhz,Load Half and Zero,D,40,
|
||||||
|
lhzu,Load Half and Zero with Update,D,41,
|
||||||
|
lhzux,Load Half and Zero with Update Indexed,X,31,331
|
||||||
|
lhzx,Load Half and Zero Indexed,X,31,279
|
||||||
|
lmw,Load Multiple Word,D,46,
|
||||||
|
lswi,Load String Word Immediate,X,31,597
|
||||||
|
lswx,Load String Word Indexed,X,31,533
|
||||||
|
lwa,Load Word Algebraic,DS,58,2
|
||||||
|
lwarx,Load Word and Reserve Indexed,X,31,20
|
||||||
|
lwaux,Load Word Algebraic with Update Indexed,X,31,373
|
||||||
|
lwax,Load Word Algebraic Indexed,X,31,341
|
||||||
|
lwbrx,Load Word Byte-Reversed Indexed,X,31,534
|
||||||
|
lwz,Load Word and Zero,D,32,
|
||||||
|
lwzu,Load Word with Zero Update,D,33,
|
||||||
|
lwzux,Load Word and Zero with Update Indexed,X,31,55
|
||||||
|
lwzx,Load Word and Zero Indexed,X,31,23
|
||||||
|
mcrf,Move Condition Register Field,XL,19,0
|
||||||
|
mcrfs,Move to Condition Register from FPSCR,X,63,64
|
||||||
|
mcrxr,Move to Condition Register from XER,X,31,512
|
||||||
|
mfcr,Move from Condition Register,X,31,19
|
||||||
|
mffs[.],Move from FPSCR,X,63,583
|
||||||
|
mfmsr,Move from Machine State Register,X,31,83
|
||||||
|
mfspr,Move from Special-Purpose Register,X,31,339
|
||||||
|
mfsr,Move from Segment Register,X,31,595
|
||||||
|
mfsrin,Move from Segment Register Indirect,X,31,659
|
||||||
|
mtcrf,Move to Condition Register Fields,XFX,31,144
|
||||||
|
mtfsb0[.],Move to FPSCR Bit 0,X,63,70
|
||||||
|
mtfsb1[.],Move to FPSCR Bit 1,X,63,38
|
||||||
|
mtfsf[.],Move to FPSCR Fields,XFL,63,711
|
||||||
|
mtfsfi[.],Move to FPSCR Field Immediate,X,63,134
|
||||||
|
mtmsr,Move to Machine State Register,X,31,146
|
||||||
|
mtspr,Move to Special-Purpose Register,X,31,467
|
||||||
|
mtsr,Move to Segment Register,X,31,210
|
||||||
|
mtsrin,Move to Segment Register Indirect,X,31,242
|
||||||
|
mulhd,Multiply High Doubleword,XO,31,73
|
||||||
|
mulhdu,Multiply High Doubleword Unsigned,XO,31,9
|
||||||
|
mulhw[.],Multiply High Word,XO,31,75
|
||||||
|
mulhwu[.],Multiply High Word Unsigned,XO,31,11
|
||||||
|
mulld,Multiply Low Doubleword,XO,31,233
|
||||||
|
mulli,Multiply Low Immediate,D,07,
|
||||||
|
mullw[o][.],Multiply Low Word,XO,31,235
|
||||||
|
nand[.],NAND,X,31,476
|
||||||
|
neg[o][.],Negate,XO,31,104
|
||||||
|
nor[.],NOR,X,31,124
|
||||||
|
or[.],OR,X,31,444
|
||||||
|
orc[.],OR with Complement,X,31,412
|
||||||
|
ori,OR Immediate,D,24,
|
||||||
|
oris,OR Immediate Shifted,D,25,
|
||||||
|
rfi,Return from Interrupt,X,19,50
|
||||||
|
rldcl,Rotate Left Doubleword then Clear Left,MDS,30,8
|
||||||
|
rldcr,Rotate Left Doubleword then Clear Right,MDS,30,9
|
||||||
|
rldic,Rotate Left Doubleword Immediate then Clear,MD,30,2
|
||||||
|
rldicl,Rotate Left Doubleword Immediate then Clear Left,MD,30,0
|
||||||
|
rldicr,Rotate Left Doubleword Immediate then Clear Right,MD,30,1
|
||||||
|
rldimi,Rotate Left Doubleword Immediate then Mask Insert,MD,30,3
|
||||||
|
rlwimi[.],Rotate Left Word Immediate then Mask Insert,M,20,
|
||||||
|
rlwinm[.],Rotate Left Word Immediate then AND with Mask,M,21,
|
||||||
|
rlwnm[.],Rotate Left Word then AND with Mask,M,23,
|
||||||
|
sc,System Call,SC,17,
|
||||||
|
si,Subtract Immediate,D,12,
|
||||||
|
si.,Subtract Immediate and Record,D,13,
|
||||||
|
slbia,SLB Invalidate All,X,31,498
|
||||||
|
slbie,SLB Invalidate Entry,X,31,434
|
||||||
|
sld,Shift Left Doubleword,X,31,27
|
||||||
|
slw[.],Shift Left Word,X,31,24
|
||||||
|
srad,Shift Right Algebraic Doubleword,X,31,794
|
||||||
|
sradi,Shift Right Algebraic Doubleword Immediate,XS,31,413
|
||||||
|
srd,Shift Right Doubleword,X,31,539
|
||||||
|
sraw[.],Shift Right Algebraic Word,X,31,792
|
||||||
|
srawi[.],Shift Right Algebraic Word Immediate,X,31,824
|
||||||
|
srw[.],Shift Right Word,X,31,536
|
||||||
|
stb,Store Byte,D,38,
|
||||||
|
stbu,Store Byte with Update,D,39,
|
||||||
|
stbux,Store Byte with Update Indexed,X,31,247
|
||||||
|
stbx,Store Byte Indexed,X,31,215
|
||||||
|
std,Store Doubleword,DS,62,0
|
||||||
|
stdcx,Store Doubleword Conditional Indexed,X,31,214
|
||||||
|
stdu,Store Doubleword with Update,DS,62,1
|
||||||
|
stdux,Store Doubleword with Update Indexed,X,31,181
|
||||||
|
stdx,Store Doubleword Indexed,X,31,149
|
||||||
|
stfd,Store Floating-Point Double,D,54,
|
||||||
|
stfdu,Store Floating-Point Double with Update,D,55,
|
||||||
|
stfdux,Store Floating-Point Double with Update Indexed,X,31,759
|
||||||
|
stfdx,Store Floating-Point Double Indexed,X,31,727
|
||||||
|
stfiwx,Store Floating-Point as Integer Word Indexed (optional),X,31,983
|
||||||
|
stfs,Store Floating-Point Single,D,52,
|
||||||
|
stfsu,Store Floating-Point Single with Update,D,53,
|
||||||
|
stfsux,Store Floating-Point Single with Update Indexed,X,31,695
|
||||||
|
stfsx,Store Floating-Point Single Indexed,X,31,663
|
||||||
|
sth,Store Half,D,44,
|
||||||
|
sthbrx,Store Half Byte-Reverse Indexed,X,31,918
|
||||||
|
sthu,Store Half with Update,D,45,
|
||||||
|
sthux,Store Half with Update Indexed,X,31,439
|
||||||
|
sthx,Store Half Indexed,X,31,407
|
||||||
|
stmw,Store Multiple Word,D,47,
|
||||||
|
stswi,Store String Word Immediate,X,31,725
|
||||||
|
stswx,Store String Word Indexed,X,31,661
|
||||||
|
stw,Store,D,36,
|
||||||
|
stwbrx,Store Word Byte-Reversed Indexed,X,31,662
|
||||||
|
stwcx.,Store Word Conditional Indexed,X,31,150
|
||||||
|
stwu,Store Word with Update,D,37,
|
||||||
|
stwux,Store Word with Update Indexed,X,31,183
|
||||||
|
stwx,Store Word Indexed,X,31,151
|
||||||
|
subf[o][.],Subtract from,XO,31,40
|
||||||
|
subfc[o][.],Subtract from Carrying,XO,31,08
|
||||||
|
subfe[o][.],Subtract from Extended,XO,31,136
|
||||||
|
subfic,Subtract from Immediate Carrying,D,08,
|
||||||
|
subfme[o][.],Subtract from Minus One Extended,XO,31,232
|
||||||
|
subfze[o][.],Subtract from Zero Extended,XO,31,200
|
||||||
|
sync,Synchronize,X,31,598
|
||||||
|
td,Trap Doubleword,X,31,68
|
||||||
|
tdi,Trap Doubleword Immediate,D,2,
|
||||||
|
tlbie,Translation Look-aside Buffer Invalidate Entry (optional),X,31,306
|
||||||
|
tlbsync,Translation Look-aside Buffer Synchronize (optional),X,31,566
|
||||||
|
tw,Trap Word,X,31,04
|
||||||
|
twi,Trap Word Immediate,D,03,
|
||||||
|
xor[.],XOR,X,31,316
|
||||||
|
xori,XOR Immediate,D,26,
|
||||||
|
xoris,XOR Immediate Shift,D,27,
|
||||||
Vendored
+343
@@ -0,0 +1,343 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
printf(
|
||||||
|
"// this file is autogenerated DO NOT MODIFY\n"
|
||||||
|
"#pragma once\n"
|
||||||
|
);
|
||||||
|
FILE* fp = fopen(argv[1], "rt");
|
||||||
|
if (fp) {
|
||||||
|
char line[80];
|
||||||
|
while (fgets(line, sizeof line, fp) != NULL) {
|
||||||
|
bool with_o = strstr(line, "[o]"), with_d = strstr(line, "[.]");
|
||||||
|
char* p = strchr(line, '\n'), *name = strchr(line, ','), *mem = line;
|
||||||
|
if (p) *p = '\0';
|
||||||
|
if (name) {
|
||||||
|
*name++ = '\0';
|
||||||
|
char *form = strchr(name, ',');
|
||||||
|
if (form) {
|
||||||
|
*form++ = '\0';
|
||||||
|
char *opc = strchr(form, ',');
|
||||||
|
if (opc) {
|
||||||
|
*opc++ = '\0';
|
||||||
|
char *sec = strchr(opc, ',');
|
||||||
|
if (sec) {
|
||||||
|
struct b_info { const char *s; int o; int p; } infos[] = {
|
||||||
|
{"",1,0},
|
||||||
|
{"LT",1,12},
|
||||||
|
{"LE",2,4},
|
||||||
|
{"NG",2,4},
|
||||||
|
{"EQ",3,12},
|
||||||
|
{"GE",1,4},
|
||||||
|
{"NL",1,4},
|
||||||
|
{"GT",2,12},
|
||||||
|
{"NE",3,4},
|
||||||
|
{"SO",4,12},
|
||||||
|
{"UN",4,12},
|
||||||
|
{"NS",4,4},
|
||||||
|
{"NU",4,4},
|
||||||
|
};
|
||||||
|
#define OP_EXT ((i_opcode << 26) | (i_extopc << 1))
|
||||||
|
if (strchr(mem, '[') != NULL) *strchr(mem, '[') = '\0';
|
||||||
|
if (strchr(mem, '.') != NULL) *strchr(mem, '.') = '_';
|
||||||
|
*sec++ = '\0';
|
||||||
|
for (int i = 0; i < strlen(mem); ++i)
|
||||||
|
mem[i] = toupper(mem[i]);
|
||||||
|
int i_opcode = atoi(opc);
|
||||||
|
int i_extopc = atoi(sec);
|
||||||
|
//printf("// %s\n", mem);
|
||||||
|
if (!strcmp(form, "XO")) {
|
||||||
|
if (!strcmp(mem, "EXTSH")) {
|
||||||
|
printf(
|
||||||
|
"void %s(GPR const rt, GPR const ra) {"
|
||||||
|
" emit_%s(0x%08x, rt, ra, R0, false, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
printf(
|
||||||
|
"void %sC(GPR const rt, GPR const ra) {"
|
||||||
|
" emit_%s(0x%08x, rt, ra, R0, true, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
printf(
|
||||||
|
"void %s_(GPR const rt, GPR const ra) {"
|
||||||
|
" emit_%s(0x%08x, rt, ra, R0, false, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
printf(
|
||||||
|
"void %sC_(GPR const rt, GPR const ra) {"
|
||||||
|
" emit_%s(0x%08x, rt, ra, R0, true, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
} else {
|
||||||
|
printf(
|
||||||
|
"void %s(GPR const rt, GPR const ra, GPR const rb) {"
|
||||||
|
" emit_%s(0x%08x, rt, ra, rb, false, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
printf(
|
||||||
|
"void %sO(GPR const rt, GPR const ra, GPR const rb) {"
|
||||||
|
" emit_%s(0x%08x, rt, ra, rb, true, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
printf(
|
||||||
|
"void %s_(GPR const rt, GPR const ra, GPR const rb) {"
|
||||||
|
" emit_%s(0x%08x, rt, ra, rb, false, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
printf(
|
||||||
|
"void %sO_(GPR const rt, GPR const ra, GPR const rb) {"
|
||||||
|
" emit_%s(0x%08x, rt, ra, rb, true, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
}
|
||||||
|
} else if (!strcmp(form, "X")) {
|
||||||
|
if (!strcmp(mem, "CMPL") || !strcmp(mem, "CMP")) {
|
||||||
|
printf(
|
||||||
|
"void %s(uint32_t bf, uint32_t l, GPR const ra, GPR const rb) {"
|
||||||
|
" emit_%s(0x%08x, GPR{(bf << 2) | l}, ra, rb, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
} else if (!strcmp(mem, "CNTLZD") || !strcmp(mem, "CNTLZW") || !strcmp(mem, "EXTSB") || !strcmp(mem, "EXTSH") || !strcmp(mem, "EXTSW")) {
|
||||||
|
printf(
|
||||||
|
"void %s(GPR const rt, GPR const ra) {"
|
||||||
|
" emit_%s(0x%08x, ra, rt, R0, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
printf(
|
||||||
|
"void %s_(GPR const rt, GPR const ra) {"
|
||||||
|
" emit_%s(0x%08x, ra, rt, R0, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
} else {
|
||||||
|
printf(
|
||||||
|
"void %s(GPR const rt, GPR const ra, GPR const rb) {"
|
||||||
|
" emit_%s(0x%08x, ra, rt, rb, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
printf(
|
||||||
|
"void %s_(GPR const rt, GPR const ra, GPR const rb) {"
|
||||||
|
" emit_%s(0x%08x, ra, rt, rb, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
}
|
||||||
|
} else if (!strcmp(form, "I")) {
|
||||||
|
printf(
|
||||||
|
"void %s(Label const& i) {"
|
||||||
|
" emit_reloc_%s(0x%08x, i, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, i_opcode << 26);
|
||||||
|
printf(
|
||||||
|
"void %sL(Label const& i) {"
|
||||||
|
" emit_reloc_%s(0x%08x, i, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, i_opcode << 26);
|
||||||
|
} else if (!strcmp(form, "B")) {
|
||||||
|
for (int i = 0; i < 12; ++i) {
|
||||||
|
printf(
|
||||||
|
"void %s%s(CPR const cr, Label const& i) {"
|
||||||
|
" emit_reloc_%s(0x%08x, %i, cr.index + %i, i, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, infos[i].s, form, i_opcode << 26, infos[i].p, infos[i].o - 1);
|
||||||
|
printf(
|
||||||
|
"void %s%sL(CPR const cr, Label const& i) {"
|
||||||
|
" emit_reloc_%s(0x%08x, %i, cr.index + %i, i, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, infos[i].s, form, i_opcode << 26, infos[i].p, infos[i].o - 1);
|
||||||
|
if (!strcmp(mem, "BC")) mem[1] = '\0';
|
||||||
|
}
|
||||||
|
} else if (!strcmp(form, "D")) {
|
||||||
|
if (!strcmp(mem, "CMPLI") || !strcmp(mem, "CMPI")) {
|
||||||
|
printf(
|
||||||
|
"void %s(uint32_t bf, uint32_t l, GPR const ra, uint32_t d) {"
|
||||||
|
" emit_%s(0x%08x, GPR{(bf << 2) | l}, ra, d); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, i_opcode << 26);
|
||||||
|
} else if (!strcmp(mem, "ANDIS_") || !strcmp(mem, "ANDI_")
|
||||||
|
|| !strcmp(mem, "ORI") || !strcmp(mem, "ORIS")
|
||||||
|
|| !strcmp(mem, "XORI") || !strcmp(mem, "XORIS")) {
|
||||||
|
printf(
|
||||||
|
"void %s(GPR const rt, GPR const ra, uint32_t d) {"
|
||||||
|
" emit_%s(0x%08x, ra, rt, d); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, i_opcode << 26);
|
||||||
|
} else {
|
||||||
|
printf(
|
||||||
|
"void %s(GPR const rt, GPR const ra, uint32_t d) {"
|
||||||
|
" emit_%s(0x%08x, rt, ra, d); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, i_opcode << 26);
|
||||||
|
}
|
||||||
|
} else if (!strcmp(form, "SC")) {
|
||||||
|
printf(
|
||||||
|
"void %s(uint32_t lev) {"
|
||||||
|
" emit_%s(0x%08x, lev); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, i_opcode << 26);
|
||||||
|
} else if (!strcmp(form, "DS")) {
|
||||||
|
#define OP_EXT_DS ((i_opcode << 26) | (i_extopc << 0))
|
||||||
|
printf(
|
||||||
|
"void %s(GPR const rt, GPR const ra, uint32_t d) {"
|
||||||
|
" emit_%s(0x%08x, rt, ra, d >> 2); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT_DS);
|
||||||
|
#undef OP_EXT_DS
|
||||||
|
} else if (!strcmp(form, "XS")) {
|
||||||
|
#define OP_EXT_XS ((i_opcode << 26) | (i_extopc << 2))
|
||||||
|
/* HUGE DIFFERENCE DO NOT REMOVE */
|
||||||
|
printf(
|
||||||
|
"void %s(GPR const rt, GPR const ra, uint32_t sh) {"
|
||||||
|
" emit_%s(0x%08x, rt, ra, sh, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT_XS);
|
||||||
|
printf(
|
||||||
|
"void %s_(GPR const rt, GPR const ra, uint32_t sh) {"
|
||||||
|
" emit_%s(0x%08x, rt, ra, sh, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT_XS);
|
||||||
|
#undef OP_EXT_XS
|
||||||
|
} else if (!strcmp(form, "XL")) {
|
||||||
|
if (!strcmp(mem, "BCLR")) {
|
||||||
|
printf(
|
||||||
|
"void %s(GPR const bt, CPR const ba, GPR const bb) {"
|
||||||
|
" emit_%s(0x%08x, bt.index, ba.index, bb.index, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
printf(
|
||||||
|
"void %sL(GPR const bt, CPR const ba, GPR const bb) {"
|
||||||
|
" emit_%s(0x%08x, bt.index, ba.index, bb.index, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
if (!strcmp(mem, "BCLR")) mem[1] = '\0';
|
||||||
|
for (int i = 1; i < 12; ++i) {
|
||||||
|
printf(
|
||||||
|
"void %s%sLR(CPR const cr) {"
|
||||||
|
" emit_%s(0x%08x, %i, cr.index + %i, 0, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, infos[i].s, form, OP_EXT, infos[i].p, infos[i].o - 1);
|
||||||
|
printf(
|
||||||
|
"void %s%sLRL(CPR const cr) {"
|
||||||
|
" emit_%s(0x%08x, %i, cr.index + %i, 0, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, infos[i].s, form, OP_EXT, infos[i].p, infos[i].o - 1);
|
||||||
|
}
|
||||||
|
} else if (mem[0] == 'B') {
|
||||||
|
printf(
|
||||||
|
"void %s(GPR const bt, CPR const ba, GPR const bb) {"
|
||||||
|
" emit_%s(0x%08x, bt.index, ba.index, bb.index, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
printf(
|
||||||
|
"void %sL(GPR const bt, CPR const ba, GPR const bb) {"
|
||||||
|
" emit_%s(0x%08x, bt.index, ba.index, bb.index, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
printf(
|
||||||
|
"void %s(GPR const bt, Cond const ba, GPR const bb) {"
|
||||||
|
" emit_%s(0x%08x, bt.index, cond2offset(ba), bb.index, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
printf(
|
||||||
|
"void %sL(GPR const bt, Cond const ba, GPR const bb) {"
|
||||||
|
" emit_%s(0x%08x, bt.index, cond2offset(ba), bb.index, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
} else {
|
||||||
|
printf(
|
||||||
|
"void %s(CPR const bt, CPR const ba, CPR const bb) {"
|
||||||
|
" emit_%s(0x%08x, bt.index, ba.index, bb.index, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
printf(
|
||||||
|
"void %sL(CPR const bt, CPR const ba, CPR const bb) {"
|
||||||
|
" emit_%s(0x%08x, bt.index, ba.index, bb.index, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
}
|
||||||
|
} else if (!strcmp(form, "M")) {
|
||||||
|
if (!strcmp(mem, "RLWNM")) {
|
||||||
|
printf(
|
||||||
|
"void %s(GPR const rs, GPR const ra, GPR const rb, uint32_t mb, uint32_t me = 0) {"
|
||||||
|
" emit_%s(0x%08x, ra, rs, rb.index, mb, me, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
printf(
|
||||||
|
"void %s_(GPR const rs, GPR const ra, GPR const rb, uint32_t mb, uint32_t me = 0) {"
|
||||||
|
" emit_%s(0x%08x, ra, rs, rb.index, mb, me, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
} else {
|
||||||
|
printf(
|
||||||
|
"void %s(GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, uint32_t me = 0) {"
|
||||||
|
" emit_%s(0x%08x, ra, rs, sh, mb, me, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
printf(
|
||||||
|
"void %s_(GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, uint32_t me = 0) {"
|
||||||
|
" emit_%s(0x%08x, ra, rs, sh, mb, me, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
}
|
||||||
|
} else if (!strcmp(form, "MD")) {
|
||||||
|
printf(
|
||||||
|
"void %s(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) {"
|
||||||
|
" emit_%s(0x%08x, ra, rs, mb, sh, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, (i_opcode << 26) | (i_extopc << 2));
|
||||||
|
printf(
|
||||||
|
"void %s_(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) {"
|
||||||
|
" emit_%s(0x%08x, ra, rs, mb, sh, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, (i_opcode << 26) | (i_extopc << 2));
|
||||||
|
} else if (!strcmp(form, "MDS")) {
|
||||||
|
printf(
|
||||||
|
"void %s(GPR const rs, GPR const ra, GPR const rb, uint32_t mb) {"
|
||||||
|
" emit_%s(0x%08x, ra, rs, rb, mb, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
printf(
|
||||||
|
"void %s_(GPR const rs, GPR const ra, GPR const rb, uint32_t mb) {"
|
||||||
|
" emit_%s(0x%08x, ra, rs, rb, mb, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
} else if (!strcmp(form, "A")) {
|
||||||
|
printf(
|
||||||
|
"void %s(FPR const frt, FPR const fra, FPR const frb, FPR const frc) {"
|
||||||
|
" emit_%s(0x%08x, frt, fra, frb, frc, false); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
printf(
|
||||||
|
"void %s_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) {"
|
||||||
|
" emit_%s(0x%08x, frt, fra, frb, frc, true); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
} else if (!strcmp(form, "XFX")) {
|
||||||
|
printf(
|
||||||
|
"void %s(GPR const rt, uint32_t spr) {"
|
||||||
|
" emit_%s(0x%08x, rt, spr); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
} else {
|
||||||
|
printf(
|
||||||
|
"void %s() {"
|
||||||
|
" emit_%s(0x%08x); "
|
||||||
|
"}\n"
|
||||||
|
, mem, form, OP_EXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//printf("%s\n", line);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
Vendored
+401
@@ -0,0 +1,401 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#undef NDEBUG
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cassert>
|
||||||
|
#include <vector>
|
||||||
|
#include <utility>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
//#ifndef __cpp_lib_unreachable
|
||||||
|
namespace std {
|
||||||
|
[[noreturn]] inline void unreachable() {
|
||||||
|
#if defined(_MSC_VER) && !defined(__clang__) // MSVC
|
||||||
|
__assume(false);
|
||||||
|
#else // GCC, Clang
|
||||||
|
__builtin_unreachable();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
namespace powah {
|
||||||
|
|
||||||
|
// Symbolic conditions
|
||||||
|
enum class Cond : uint8_t {
|
||||||
|
LT, LE, NG, EQ, GE, NL, GT, NE, SO, UN, NS, NU
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GPR { uint32_t index; };
|
||||||
|
struct FPR { uint32_t index; };
|
||||||
|
struct VPR { uint32_t index; };
|
||||||
|
struct CPR { uint32_t index; };
|
||||||
|
struct Label { uint32_t index; };
|
||||||
|
|
||||||
|
constexpr inline GPR R0{0};
|
||||||
|
constexpr inline GPR R1{1};
|
||||||
|
constexpr inline GPR R2{2};
|
||||||
|
constexpr inline GPR R3{3};
|
||||||
|
constexpr inline GPR R4{4};
|
||||||
|
constexpr inline GPR R5{5};
|
||||||
|
constexpr inline GPR R6{6};
|
||||||
|
constexpr inline GPR R7{7};
|
||||||
|
constexpr inline GPR R8{8};
|
||||||
|
constexpr inline GPR R9{9};
|
||||||
|
constexpr inline GPR R10{10};
|
||||||
|
constexpr inline GPR R11{11};
|
||||||
|
constexpr inline GPR R12{12};
|
||||||
|
constexpr inline GPR R13{13};
|
||||||
|
constexpr inline GPR R14{14};
|
||||||
|
constexpr inline GPR R15{15};
|
||||||
|
constexpr inline GPR R16{16};
|
||||||
|
constexpr inline GPR R17{17};
|
||||||
|
constexpr inline GPR R18{18};
|
||||||
|
constexpr inline GPR R19{19};
|
||||||
|
constexpr inline GPR R20{20};
|
||||||
|
constexpr inline GPR R21{21};
|
||||||
|
constexpr inline GPR R22{22};
|
||||||
|
constexpr inline GPR R23{23};
|
||||||
|
constexpr inline GPR R24{24};
|
||||||
|
constexpr inline GPR R25{25};
|
||||||
|
constexpr inline GPR R26{26};
|
||||||
|
constexpr inline GPR R27{27};
|
||||||
|
constexpr inline GPR R28{28};
|
||||||
|
constexpr inline GPR R29{29};
|
||||||
|
constexpr inline GPR R30{30};
|
||||||
|
constexpr inline GPR R31{31};
|
||||||
|
|
||||||
|
constexpr inline FPR FR0{0};
|
||||||
|
constexpr inline FPR FR1{1};
|
||||||
|
constexpr inline FPR FR2{2};
|
||||||
|
constexpr inline FPR FR3{3};
|
||||||
|
constexpr inline FPR FR4{4};
|
||||||
|
constexpr inline FPR FR5{5};
|
||||||
|
constexpr inline FPR FR6{6};
|
||||||
|
constexpr inline FPR FR7{7};
|
||||||
|
constexpr inline FPR FR8{8};
|
||||||
|
constexpr inline FPR FR9{9};
|
||||||
|
constexpr inline FPR FR10{10};
|
||||||
|
constexpr inline FPR FR11{11};
|
||||||
|
constexpr inline FPR FR12{12};
|
||||||
|
constexpr inline FPR FR13{13};
|
||||||
|
constexpr inline FPR FR14{14};
|
||||||
|
constexpr inline FPR FR15{15};
|
||||||
|
constexpr inline FPR FR16{16};
|
||||||
|
constexpr inline FPR FR17{17};
|
||||||
|
constexpr inline FPR FR18{18};
|
||||||
|
constexpr inline FPR FR19{19};
|
||||||
|
constexpr inline FPR FR20{20};
|
||||||
|
constexpr inline FPR FR21{21};
|
||||||
|
constexpr inline FPR FR22{22};
|
||||||
|
constexpr inline FPR FR23{23};
|
||||||
|
constexpr inline FPR FR24{24};
|
||||||
|
constexpr inline FPR FR25{25};
|
||||||
|
constexpr inline FPR FR26{26};
|
||||||
|
constexpr inline FPR FR27{27};
|
||||||
|
constexpr inline FPR FR28{28};
|
||||||
|
constexpr inline FPR FR29{29};
|
||||||
|
constexpr inline FPR FR30{30};
|
||||||
|
constexpr inline FPR FR31{31};
|
||||||
|
|
||||||
|
// They call it CPR because when programmers see this code they-
|
||||||
|
constexpr inline CPR CR0{0};
|
||||||
|
constexpr inline CPR CR1{4};
|
||||||
|
constexpr inline CPR CR2{8};
|
||||||
|
constexpr inline CPR CR3{12};
|
||||||
|
constexpr inline CPR CR4{16};
|
||||||
|
constexpr inline CPR CR5{20};
|
||||||
|
constexpr inline CPR CR6{24};
|
||||||
|
constexpr inline CPR CR7{28};
|
||||||
|
|
||||||
|
constexpr uint32_t XER_SO = 32;
|
||||||
|
constexpr uint32_t XER_OV = 33;
|
||||||
|
constexpr uint32_t XER_CA = 34;
|
||||||
|
|
||||||
|
enum class RelocKind : uint8_t {
|
||||||
|
FormB,
|
||||||
|
FormI,
|
||||||
|
};
|
||||||
|
struct RelocInfo {
|
||||||
|
uint32_t offset;
|
||||||
|
RelocKind kind;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Context {
|
||||||
|
Context() = default;
|
||||||
|
Context(void* ptr, size_t size)
|
||||||
|
: base{reinterpret_cast<uint32_t*>(ptr)}
|
||||||
|
, offset{0}
|
||||||
|
, size{uint32_t(size)} {
|
||||||
|
|
||||||
|
}
|
||||||
|
~Context() = default;
|
||||||
|
|
||||||
|
std::vector<uint32_t> labels;
|
||||||
|
std::vector<std::pair<uint32_t, RelocInfo>> relocs;
|
||||||
|
|
||||||
|
Label DefineLabel() {
|
||||||
|
labels.push_back(0);
|
||||||
|
return Label{ uint32_t(labels.size() - 1) };
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApplyRelocs() {
|
||||||
|
for (auto const &[index, info] : relocs) {
|
||||||
|
//assert(labels[index] != 0); //label must have an addr
|
||||||
|
int32_t rel = (int32_t)labels[index] - (int32_t)info.offset;
|
||||||
|
switch (info.kind) {
|
||||||
|
case RelocKind::FormB:
|
||||||
|
base[info.offset] |= bitExt(rel, 16, 14);
|
||||||
|
break;
|
||||||
|
case RelocKind::FormI:
|
||||||
|
base[info.offset] |= bitExt(rel, 6, 24);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
relocs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LABEL(Label l) {
|
||||||
|
assert(labels[l.index] == 0);
|
||||||
|
labels[l.index] = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr uint32_t cond2offset(Cond c) noexcept {
|
||||||
|
switch (c) {
|
||||||
|
case Cond::LT: return 1;
|
||||||
|
case Cond::LE: return 2;
|
||||||
|
case Cond::NG: return 2;
|
||||||
|
case Cond::EQ: return 3;
|
||||||
|
case Cond::GE: return 1;
|
||||||
|
case Cond::NL: return 1;
|
||||||
|
case Cond::GT: return 2;
|
||||||
|
case Cond::NE: return 3;
|
||||||
|
case Cond::SO: return 4;
|
||||||
|
case Cond::UN: return 4;
|
||||||
|
case Cond::NS: return 4;
|
||||||
|
case Cond::NU: return 4;
|
||||||
|
default: return 0; //hopefully icc isn't stupid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t bitExt(uint32_t value, uint32_t offs, uint32_t n) {
|
||||||
|
uint32_t mask = (1UL << n) - 1;
|
||||||
|
return (value & mask) << (32 - (n + offs));
|
||||||
|
}
|
||||||
|
void emit_XO(uint32_t op, GPR const rt, GPR const ra, GPR const rb, bool oe, bool rc) {
|
||||||
|
base[offset++] = (op |
|
||||||
|
bitExt(rt.index, 6, 5)
|
||||||
|
| bitExt(ra.index, 11, 5)
|
||||||
|
| bitExt(rb.index, 16, 5)
|
||||||
|
| bitExt(oe, 21, 1)
|
||||||
|
| bitExt(rc, 31, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
void emit_D(uint32_t op, GPR const rt, GPR const ra, uint32_t d) {
|
||||||
|
base[offset++] = (op |
|
||||||
|
bitExt(rt.index, 6, 5)
|
||||||
|
| bitExt(ra.index, 11, 5)
|
||||||
|
| (d & 0xffff)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
void emit_X(uint32_t op, GPR const rt, GPR const ra, GPR const rb, bool rc) {
|
||||||
|
base[offset++] = (op |
|
||||||
|
bitExt(rt.index, 6, 5)
|
||||||
|
| bitExt(ra.index, 11, 5)
|
||||||
|
| bitExt(rb.index, 16, 5)
|
||||||
|
| bitExt(rc, 31, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
void emit_XS(uint32_t op, GPR const rt, GPR const ra, uint32_t sh, bool rc) {
|
||||||
|
base[offset++] = (op |
|
||||||
|
((rt.index & 0x1f) << 16)
|
||||||
|
| ((ra.index & 0x1f) << 21)
|
||||||
|
| ((sh & 0x1f) << 11)
|
||||||
|
| ((sh >> 4) & 0x02)
|
||||||
|
| bitExt(rc, 31, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
void emit_reloc_I(uint32_t op, Label const& l, bool lk) {
|
||||||
|
relocs.emplace_back(l.index, RelocInfo{ offset, RelocKind::FormI });
|
||||||
|
base[offset++] = (op |
|
||||||
|
bitExt(lk, 31, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
void emit_reloc_B(uint32_t op, uint32_t bo, uint32_t cri, Label const& l, bool lk) {
|
||||||
|
relocs.emplace_back(l.index, RelocInfo{ offset, RelocKind::FormB });
|
||||||
|
base[offset++] = (op |
|
||||||
|
bitExt(bo, 6, 5)
|
||||||
|
| bitExt(cri, 11, 5)
|
||||||
|
| bitExt(lk, 31, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
void emit_XL(uint32_t op, uint32_t bt, uint32_t ba, uint32_t bb, bool lk) {
|
||||||
|
base[offset++] = (op |
|
||||||
|
bitExt(bt, 6, 5)
|
||||||
|
| bitExt(ba, 11, 5)
|
||||||
|
| bitExt(bb, 16, 5)
|
||||||
|
| bitExt(lk, 31, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
void emit_A(uint32_t op, FPR const frt, FPR const fra, FPR const frb, FPR const frc, bool rc) {
|
||||||
|
base[offset++] = (op |
|
||||||
|
bitExt(frt.index, 6, 5)
|
||||||
|
| bitExt(fra.index, 11, 5)
|
||||||
|
| bitExt(frb.index, 16, 5)
|
||||||
|
| bitExt(frc.index, 21, 5)
|
||||||
|
| bitExt(rc, 31, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
void emit_DS(uint32_t op, GPR const rt, GPR const ra, uint32_t d) {
|
||||||
|
//assert(d & 0x03 == 0);
|
||||||
|
base[offset++] = (op |
|
||||||
|
bitExt(rt.index, 6, 5)
|
||||||
|
| bitExt(ra.index, 11, 5)
|
||||||
|
| bitExt(d, 16, 14)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
void emit_M(uint32_t op, GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, uint32_t me, bool rc) {
|
||||||
|
assert(sh <= 0x3f && mb <= 0x3f);
|
||||||
|
base[offset++] = (op |
|
||||||
|
bitExt(rs.index, 6, 5)
|
||||||
|
| bitExt(ra.index, 11, 5)
|
||||||
|
| ((sh & 0x1f) << 11)
|
||||||
|
| ((mb & 0x1f) << 6)
|
||||||
|
| ((me & 0x1f) << 1)
|
||||||
|
| bitExt(rc, 31, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
void emit_MD(uint32_t op, GPR const rs, GPR const ra, GPR const rb, uint32_t mb, bool rc) {
|
||||||
|
assert(mb <= 0x3f);
|
||||||
|
base[offset++] = (op |
|
||||||
|
bitExt(rs.index, 6, 5)
|
||||||
|
| bitExt(ra.index, 11, 5)
|
||||||
|
| bitExt(rb.index, 16, 5)
|
||||||
|
| ((mb & 0x1f) << 6) | (mb & 0x20)
|
||||||
|
| bitExt(rc, 31, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
void emit_MD(uint32_t op, GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, bool rc) {
|
||||||
|
assert(sh <= 0x3f && mb <= 0x3f);
|
||||||
|
base[offset++] = (op |
|
||||||
|
bitExt(rs.index, 6, 5)
|
||||||
|
| bitExt(ra.index, 11, 5)
|
||||||
|
| ((mb & 0x1f) << 6) | (mb & 0x20)
|
||||||
|
| ((sh & 0x1f) << 11) | ((sh >> 4) & 0x02)
|
||||||
|
| bitExt(rc, 31, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
void emit_MDS(uint32_t op, GPR const rs, GPR const ra, GPR const rb, uint32_t mb, bool rc) {
|
||||||
|
base[offset++] = (op |
|
||||||
|
bitExt(rs.index, 6, 5)
|
||||||
|
| bitExt(ra.index, 11, 5)
|
||||||
|
| bitExt(rb.index, 16, 5)
|
||||||
|
| ((mb & 0x1f) << 6) | (mb & 0x20)
|
||||||
|
| bitExt(rc, 31, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
void emit_XFL(uint32_t op) {
|
||||||
|
(void)op;
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
void emit_XFX(uint32_t op, GPR const rt, uint32_t spr) {
|
||||||
|
base[offset++] = (op |
|
||||||
|
(rt.index & 0x1f) << 21
|
||||||
|
| ((spr & 0xff) << 12)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
void emit_SC(uint32_t op, uint32_t lev) {
|
||||||
|
(void)op;
|
||||||
|
(void)lev;
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extended Memmonics, hand coded :)
|
||||||
|
void MR(GPR const ra, GPR const rs) { OR(ra, rs, rs); }
|
||||||
|
void NOP() { ORI(R0, R0, 0); }
|
||||||
|
void NOT(GPR const ra, GPR const rs) { NOR(ra, rs, rs); }
|
||||||
|
|
||||||
|
void ROTLDI(GPR const ra, GPR const rs, uint32_t n) { RLDICL(ra, rs, n, 0); }
|
||||||
|
void ROTRDI(GPR const ra, GPR const rs, uint32_t n) { RLDICL(ra, rs, 64 - n, 0); }
|
||||||
|
|
||||||
|
void ROTLWI(GPR const ra, GPR const rs, uint32_t n) { RLWINM(ra, rs, n, 0, 31); }
|
||||||
|
void ROTRWI(GPR const ra, GPR const rs, uint32_t n) { RLWINM(ra, rs, 32 - n, 0, 31); }
|
||||||
|
|
||||||
|
void ROTLW(GPR const ra, GPR const rs, GPR const rb) { RLWNM(ra, rs, rb, 0, 31); }
|
||||||
|
void ROTLD(GPR const ra, GPR const rs, GPR const rb) { RLDCL(ra, rs, rb, 0); }
|
||||||
|
|
||||||
|
void EXTLDI(GPR const ra, GPR const rs, uint32_t n, uint32_t b) { RLDICR(ra, rs, b, n - 1); }
|
||||||
|
void SLDI(GPR const ra, GPR const rs, uint32_t n) { RLDICR(ra, rs, n, 63 - n); }
|
||||||
|
void CLRLDI(GPR const ra, GPR const rs, uint32_t n) { RLDICL(ra, rs, 0, n); }
|
||||||
|
|
||||||
|
void EXTRDI(GPR const ra, GPR const rs, uint32_t n, uint32_t b) { RLDICL(ra, rs, b + n, 64 - n); }
|
||||||
|
void SRDI(GPR const ra, GPR const rs, uint32_t n) { RLDICL(ra, rs, 64 - n, n); }
|
||||||
|
void CLLDI(GPR const ra, GPR const rs, uint32_t n) { RLDICR(ra, rs, 0, n); }
|
||||||
|
void CLRSLDI(GPR const ra, GPR const rs, uint32_t n, uint32_t b) { RLDICR(ra, rs, n, b - n); }
|
||||||
|
|
||||||
|
void EXTLWI(GPR const ra, GPR const rs, uint32_t n, uint32_t b) { RLWINM(ra, rs, b, 0, n - 1); }
|
||||||
|
void SRWI(GPR const ra, GPR const rs, uint32_t n) { RLWINM(ra, rs, 32 - n, n, 31); }
|
||||||
|
void CLRRWI(GPR const ra, GPR const rs, uint32_t n) { RLWINM(ra, rs, 0, 0, 31 - n); }
|
||||||
|
|
||||||
|
void CRSET(CPR const bx) { CREQV(bx, bx, bx); }
|
||||||
|
void CRCLR(CPR const bx) { CRXOR(bx, bx, bx); }
|
||||||
|
void CRMOVE(CPR const bx, CPR const by) { CROR(bx, by, by); }
|
||||||
|
void CRNOT(CPR const bx, CPR const by) { CRNOR(bx, by, by); }
|
||||||
|
|
||||||
|
void CMPLDI(CPR const cr, GPR const rx, uint32_t v) { CMPLI(cr.index, 1, rx, v); }
|
||||||
|
void CMPLWI(CPR const cr, GPR const rx, uint32_t v) { CMPLI(cr.index, 0, rx, v); }
|
||||||
|
void CMPLD(CPR const cr, GPR const rx, GPR const ry) { CMPL(cr.index, 1, rx, ry); }
|
||||||
|
void CMPLW(CPR const cr, GPR const rx, GPR const ry) { CMPL(cr.index, 0, rx, ry); }
|
||||||
|
void CMPLDI(GPR const rx, uint32_t v) { CMPLI(0, 1, rx, v); }
|
||||||
|
void CMPLWI(GPR const rx, uint32_t v) { CMPLI(0, 0, rx, v); }
|
||||||
|
void CMPLD(GPR const rx, GPR const ry) { CMPL(0, 1, rx, ry); }
|
||||||
|
void CMPLW(GPR const rx, GPR const ry) { CMPL(0, 0, rx, ry); }
|
||||||
|
|
||||||
|
void CMPWI(CPR const cr, GPR const rx, uint32_t si) { CMPI(cr.index, 0, rx, si); }
|
||||||
|
void CMPW(CPR const cr, GPR const rx, GPR const ry) { CMP(cr.index, 0, rx, ry); }
|
||||||
|
void CMPDI(CPR const cr, GPR const rx, uint32_t si) { CMPI(cr.index, 1, rx, si); }
|
||||||
|
void CMPD(CPR const cr, GPR const rx, GPR const ry) { CMP(cr.index, 1, rx, ry); }
|
||||||
|
void CMPWI(GPR const rx, uint32_t si) { CMPI(0, 0, rx, si); }
|
||||||
|
void CMPW(GPR const rx, GPR const ry) { CMP(0, 0, rx, ry); }
|
||||||
|
void CMPDI(GPR const rx, uint32_t si) { CMPI(0, 1, rx, si); }
|
||||||
|
void CMPD(GPR const rx, GPR const ry) { CMP(0, 1, rx, ry); }
|
||||||
|
|
||||||
|
void LI(GPR const rx, uint32_t value) { ADDI(rx, R0, value); }
|
||||||
|
void LIS(GPR const rx, uint32_t value) { ADDIS(rx, R0, value); }
|
||||||
|
|
||||||
|
void MFLR(GPR const rt) { MFSPR(powah::GPR{8}, rt, powah::GPR{0}); }
|
||||||
|
void MTLR(GPR const rt) { MTSPR(powah::GPR{8}, rt, powah::GPR{0}); }
|
||||||
|
void BLR() { base[offset++] = 0x4e800020; } //BCLR(R0, CR0, R0);
|
||||||
|
|
||||||
|
void MFCTR(GPR const rt) { MFSPR(powah::GPR{9}, rt, powah::GPR{0}); }
|
||||||
|
void MTCTR(GPR const rt) { MTSPR(powah::GPR{9}, rt, powah::GPR{0}); }
|
||||||
|
void BCTRL() { base[offset++] = 0x4e800421; } //BCCTRL(R0, CR0, R0);
|
||||||
|
void BCTR() { base[offset++] = 0x4e800420; } //BCCTR(R0, CR0, R0);
|
||||||
|
|
||||||
|
// TODO: PowerPC 11 stuff
|
||||||
|
void ISEL(GPR const rd, GPR const ra, GPR const rb, uint32_t d) {
|
||||||
|
(void)rd;
|
||||||
|
(void)ra;
|
||||||
|
(void)rb;
|
||||||
|
(void)d;
|
||||||
|
std::unreachable();
|
||||||
|
}
|
||||||
|
void ISELLT(GPR const rd, GPR const ra, GPR const rb) { ISEL(rd, ra, rb, 0); }
|
||||||
|
void ISELGT(GPR const rd, GPR const ra, GPR const rb) { ISEL(rd, ra, rb, 1); }
|
||||||
|
void ISELEQ(GPR const rd, GPR const ra, GPR const rb) { ISEL(rd, ra, rb, 2); }
|
||||||
|
|
||||||
|
// Rawly pasted because fuck you
|
||||||
|
#include "powah_gen_base.hpp"
|
||||||
|
|
||||||
|
uint32_t* base = nullptr;
|
||||||
|
uint32_t offset = 0;
|
||||||
|
uint32_t size = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
Vendored
+487
@@ -0,0 +1,487 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
// this file is autogenerated DO NOT MODIFY
|
||||||
|
#pragma once
|
||||||
|
void ADD(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000214, rt, ra, rb, false, false); }
|
||||||
|
void ADDO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000214, rt, ra, rb, true, false); }
|
||||||
|
void ADD_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000214, rt, ra, rb, false, true); }
|
||||||
|
void ADDO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000214, rt, ra, rb, true, true); }
|
||||||
|
void ADDC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000014, rt, ra, rb, false, false); }
|
||||||
|
void ADDCO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000014, rt, ra, rb, true, false); }
|
||||||
|
void ADDC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000014, rt, ra, rb, false, true); }
|
||||||
|
void ADDCO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000014, rt, ra, rb, true, true); }
|
||||||
|
void ADDE(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000114, rt, ra, rb, false, false); }
|
||||||
|
void ADDEO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000114, rt, ra, rb, true, false); }
|
||||||
|
void ADDE_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000114, rt, ra, rb, false, true); }
|
||||||
|
void ADDEO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000114, rt, ra, rb, true, true); }
|
||||||
|
void ADDI(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x38000000, rt, ra, d); }
|
||||||
|
void ADDIC(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x30000000, rt, ra, d); }
|
||||||
|
void ADDIC_(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x34000000, rt, ra, d); }
|
||||||
|
void ADDIS(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x3c000000, rt, ra, d); }
|
||||||
|
void ADDME(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d4, rt, ra, rb, false, false); }
|
||||||
|
void ADDMEO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d4, rt, ra, rb, true, false); }
|
||||||
|
void ADDME_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d4, rt, ra, rb, false, true); }
|
||||||
|
void ADDMEO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d4, rt, ra, rb, true, true); }
|
||||||
|
void ADDZE(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000194, rt, ra, rb, false, false); }
|
||||||
|
void ADDZEO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000194, rt, ra, rb, true, false); }
|
||||||
|
void ADDZE_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000194, rt, ra, rb, false, true); }
|
||||||
|
void ADDZEO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000194, rt, ra, rb, true, true); }
|
||||||
|
void AND(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000038, ra, rt, rb, false); }
|
||||||
|
void AND_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000038, ra, rt, rb, true); }
|
||||||
|
void ANDC(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000078, ra, rt, rb, false); }
|
||||||
|
void ANDC_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000078, ra, rt, rb, true); }
|
||||||
|
void ANDI_(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x70000000, ra, rt, d); }
|
||||||
|
void ANDIS_(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x74000000, ra, rt, d); }
|
||||||
|
void B(Label const& i) { emit_reloc_I(0x48000000, i, false); }
|
||||||
|
void BL(Label const& i) { emit_reloc_I(0x48000000, i, true); }
|
||||||
|
void BC(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 0, cr.index + 0, i, false); }
|
||||||
|
void BCL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 0, cr.index + 0, i, true); }
|
||||||
|
void BLT(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 0, i, false); }
|
||||||
|
void BLTL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 0, i, true); }
|
||||||
|
void BLE(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 1, i, false); }
|
||||||
|
void BLEL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 1, i, true); }
|
||||||
|
void BNG(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 1, i, false); }
|
||||||
|
void BNGL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 1, i, true); }
|
||||||
|
void BEQ(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 2, i, false); }
|
||||||
|
void BEQL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 2, i, true); }
|
||||||
|
void BGE(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 0, i, false); }
|
||||||
|
void BGEL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 0, i, true); }
|
||||||
|
void BNL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 0, i, false); }
|
||||||
|
void BNLL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 0, i, true); }
|
||||||
|
void BGT(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 1, i, false); }
|
||||||
|
void BGTL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 1, i, true); }
|
||||||
|
void BNE(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 2, i, false); }
|
||||||
|
void BNEL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 2, i, true); }
|
||||||
|
void BSO(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 3, i, false); }
|
||||||
|
void BSOL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 3, i, true); }
|
||||||
|
void BUN(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 3, i, false); }
|
||||||
|
void BUNL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 3, i, true); }
|
||||||
|
void BNS(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 3, i, false); }
|
||||||
|
void BNSL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 3, i, true); }
|
||||||
|
void BCCTR(GPR const bt, CPR const ba, GPR const bb) { emit_XL(0x4c000420, bt.index, ba.index, bb.index, false); }
|
||||||
|
void BCCTRL(GPR const bt, CPR const ba, GPR const bb) { emit_XL(0x4c000420, bt.index, ba.index, bb.index, true); }
|
||||||
|
void BCCTR(GPR const bt, Cond const ba, GPR const bb) { emit_XL(0x4c000420, bt.index, cond2offset(ba), bb.index, false); }
|
||||||
|
void BCCTRL(GPR const bt, Cond const ba, GPR const bb) { emit_XL(0x4c000420, bt.index, cond2offset(ba), bb.index, true); }
|
||||||
|
void BCLR(GPR const bt, CPR const ba, GPR const bb) { emit_XL(0x4c000020, bt.index, ba.index, bb.index, false); }
|
||||||
|
void BCLRL(GPR const bt, CPR const ba, GPR const bb) { emit_XL(0x4c000020, bt.index, ba.index, bb.index, true); }
|
||||||
|
void BLTLR(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 0, 0, false); }
|
||||||
|
void BLTLRL(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 0, 0, true); }
|
||||||
|
void BLELR(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 1, 0, false); }
|
||||||
|
void BLELRL(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 1, 0, true); }
|
||||||
|
void BNGLR(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 1, 0, false); }
|
||||||
|
void BNGLRL(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 1, 0, true); }
|
||||||
|
void BEQLR(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 2, 0, false); }
|
||||||
|
void BEQLRL(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 2, 0, true); }
|
||||||
|
void BGELR(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 0, 0, false); }
|
||||||
|
void BGELRL(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 0, 0, true); }
|
||||||
|
void BNLLR(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 0, 0, false); }
|
||||||
|
void BNLLRL(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 0, 0, true); }
|
||||||
|
void BGTLR(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 1, 0, false); }
|
||||||
|
void BGTLRL(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 1, 0, true); }
|
||||||
|
void BNELR(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 2, 0, false); }
|
||||||
|
void BNELRL(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 2, 0, true); }
|
||||||
|
void BSOLR(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 3, 0, false); }
|
||||||
|
void BSOLRL(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 3, 0, true); }
|
||||||
|
void BUNLR(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 3, 0, false); }
|
||||||
|
void BUNLRL(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 3, 0, true); }
|
||||||
|
void BNSLR(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 3, 0, false); }
|
||||||
|
void BNSLRL(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 3, 0, true); }
|
||||||
|
void CMP(uint32_t bf, uint32_t l, GPR const ra, GPR const rb) { emit_X(0x7c000000, GPR{(bf << 2) | l}, ra, rb, false); }
|
||||||
|
void CMPI(uint32_t bf, uint32_t l, GPR const ra, uint32_t d) { emit_D(0x2c000000, GPR{(bf << 2) | l}, ra, d); }
|
||||||
|
void CMPL(uint32_t bf, uint32_t l, GPR const ra, GPR const rb) { emit_X(0x7c000040, GPR{(bf << 2) | l}, ra, rb, false); }
|
||||||
|
void CMPLI(uint32_t bf, uint32_t l, GPR const ra, uint32_t d) { emit_D(0x28000000, GPR{(bf << 2) | l}, ra, d); }
|
||||||
|
void CNTLZD(GPR const rt, GPR const ra) { emit_X(0x7c000074, ra, rt, R0, false); }
|
||||||
|
void CNTLZD_(GPR const rt, GPR const ra) { emit_X(0x7c000074, ra, rt, R0, true); }
|
||||||
|
void CNTLZW(GPR const rt, GPR const ra) { emit_X(0x7c000034, ra, rt, R0, false); }
|
||||||
|
void CNTLZW_(GPR const rt, GPR const ra) { emit_X(0x7c000034, ra, rt, R0, true); }
|
||||||
|
void CRAND(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000202, bt.index, ba.index, bb.index, false); }
|
||||||
|
void CRANDL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000202, bt.index, ba.index, bb.index, true); }
|
||||||
|
void CRANDC(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000102, bt.index, ba.index, bb.index, false); }
|
||||||
|
void CRANDCL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000102, bt.index, ba.index, bb.index, true); }
|
||||||
|
void CREQV(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000242, bt.index, ba.index, bb.index, false); }
|
||||||
|
void CREQVL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000242, bt.index, ba.index, bb.index, true); }
|
||||||
|
void CRNAND(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c0001c2, bt.index, ba.index, bb.index, false); }
|
||||||
|
void CRNANDL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c0001c2, bt.index, ba.index, bb.index, true); }
|
||||||
|
void CRNOR(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000042, bt.index, ba.index, bb.index, false); }
|
||||||
|
void CRNORL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000042, bt.index, ba.index, bb.index, true); }
|
||||||
|
void CROR(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000382, bt.index, ba.index, bb.index, false); }
|
||||||
|
void CRORL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000382, bt.index, ba.index, bb.index, true); }
|
||||||
|
void CRORC(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000342, bt.index, ba.index, bb.index, false); }
|
||||||
|
void CRORCL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000342, bt.index, ba.index, bb.index, true); }
|
||||||
|
void CRXOR(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000182, bt.index, ba.index, bb.index, false); }
|
||||||
|
void CRXORL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000182, bt.index, ba.index, bb.index, true); }
|
||||||
|
void DCBF(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000ac, ra, rt, rb, false); }
|
||||||
|
void DCBF_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000ac, ra, rt, rb, true); }
|
||||||
|
void DCBI(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0003ac, ra, rt, rb, false); }
|
||||||
|
void DCBI_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0003ac, ra, rt, rb, true); }
|
||||||
|
void DCBST(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00006c, ra, rt, rb, false); }
|
||||||
|
void DCBST_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00006c, ra, rt, rb, true); }
|
||||||
|
void DCBT(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00022c, ra, rt, rb, false); }
|
||||||
|
void DCBT_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00022c, ra, rt, rb, true); }
|
||||||
|
void DCBTST(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ec, ra, rt, rb, false); }
|
||||||
|
void DCBTST_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ec, ra, rt, rb, true); }
|
||||||
|
void DCBZ(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0007ec, ra, rt, rb, false); }
|
||||||
|
void DCBZ_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0007ec, ra, rt, rb, true); }
|
||||||
|
void DIVD(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d2, rt, ra, rb, false, false); }
|
||||||
|
void DIVDO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d2, rt, ra, rb, true, false); }
|
||||||
|
void DIVD_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d2, rt, ra, rb, false, true); }
|
||||||
|
void DIVDO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d2, rt, ra, rb, true, true); }
|
||||||
|
void DIVDU(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000392, rt, ra, rb, false, false); }
|
||||||
|
void DIVDUO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000392, rt, ra, rb, true, false); }
|
||||||
|
void DIVDU_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000392, rt, ra, rb, false, true); }
|
||||||
|
void DIVDUO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000392, rt, ra, rb, true, true); }
|
||||||
|
void DIVW(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d6, rt, ra, rb, false, false); }
|
||||||
|
void DIVWO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d6, rt, ra, rb, true, false); }
|
||||||
|
void DIVW_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d6, rt, ra, rb, false, true); }
|
||||||
|
void DIVWO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d6, rt, ra, rb, true, true); }
|
||||||
|
void DIVWU(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000396, rt, ra, rb, false, false); }
|
||||||
|
void DIVWUO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000396, rt, ra, rb, true, false); }
|
||||||
|
void DIVWU_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000396, rt, ra, rb, false, true); }
|
||||||
|
void DIVWUO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000396, rt, ra, rb, true, true); }
|
||||||
|
void ECIWX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00026c, ra, rt, rb, false); }
|
||||||
|
void ECIWX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00026c, ra, rt, rb, true); }
|
||||||
|
void ECOWX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00036c, ra, rt, rb, false); }
|
||||||
|
void ECOWX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00036c, ra, rt, rb, true); }
|
||||||
|
void EIEIO(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0006ac, ra, rt, rb, false); }
|
||||||
|
void EIEIO_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0006ac, ra, rt, rb, true); }
|
||||||
|
void EQV(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000238, ra, rt, rb, false); }
|
||||||
|
void EQV_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000238, ra, rt, rb, true); }
|
||||||
|
void EXTSB(GPR const rt, GPR const ra) { emit_X(0x7c000774, ra, rt, R0, false); }
|
||||||
|
void EXTSB_(GPR const rt, GPR const ra) { emit_X(0x7c000774, ra, rt, R0, true); }
|
||||||
|
void EXTSH(GPR const rt, GPR const ra) { emit_XO(0x7c000734, rt, ra, R0, false, false); }
|
||||||
|
void EXTSHC(GPR const rt, GPR const ra) { emit_XO(0x7c000734, rt, ra, R0, true, false); }
|
||||||
|
void EXTSH_(GPR const rt, GPR const ra) { emit_XO(0x7c000734, rt, ra, R0, false, true); }
|
||||||
|
void EXTSHC_(GPR const rt, GPR const ra) { emit_XO(0x7c000734, rt, ra, R0, true, true); }
|
||||||
|
void EXTSW(GPR const rt, GPR const ra) { emit_X(0x7c0007b4, ra, rt, R0, false); }
|
||||||
|
void EXTSW_(GPR const rt, GPR const ra) { emit_X(0x7c0007b4, ra, rt, R0, true); }
|
||||||
|
void FABS(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000210, ra, rt, rb, false); }
|
||||||
|
void FABS_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000210, ra, rt, rb, true); }
|
||||||
|
void FADD(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00002a, frt, fra, frb, frc, false); }
|
||||||
|
void FADD_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00002a, frt, fra, frb, frc, true); }
|
||||||
|
void FADDS(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec00002a, frt, fra, frb, frc, false); }
|
||||||
|
void FADDS_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec00002a, frt, fra, frb, frc, true); }
|
||||||
|
void FCFID(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00069c, ra, rt, rb, false); }
|
||||||
|
void FCFID_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00069c, ra, rt, rb, true); }
|
||||||
|
void FCMPO(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000040, ra, rt, rb, false); }
|
||||||
|
void FCMPO_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000040, ra, rt, rb, true); }
|
||||||
|
void FCMPU(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0xfc000000, bt.index, ba.index, bb.index, false); }
|
||||||
|
void FCMPUL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0xfc000000, bt.index, ba.index, bb.index, true); }
|
||||||
|
void FCTID(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00065c, ra, rt, rb, false); }
|
||||||
|
void FCTID_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00065c, ra, rt, rb, true); }
|
||||||
|
void FCTIDZ(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00065e, ra, rt, rb, false); }
|
||||||
|
void FCTIDZ_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00065e, ra, rt, rb, true); }
|
||||||
|
void FCTIW(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00001c, ra, rt, rb, false); }
|
||||||
|
void FCTIW_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00001c, ra, rt, rb, true); }
|
||||||
|
void FCTIWZ(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0xfc00001e, bt.index, ba.index, bb.index, false); }
|
||||||
|
void FCTIWZL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0xfc00001e, bt.index, ba.index, bb.index, true); }
|
||||||
|
void FDIV(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000024, frt, fra, frb, frc, false); }
|
||||||
|
void FDIV_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000024, frt, fra, frb, frc, true); }
|
||||||
|
void FDIVS(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000024, frt, fra, frb, frc, false); }
|
||||||
|
void FDIVS_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000024, frt, fra, frb, frc, true); }
|
||||||
|
void FMADD(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00003a, frt, fra, frb, frc, false); }
|
||||||
|
void FMADD_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00003a, frt, fra, frb, frc, true); }
|
||||||
|
void FMADDS(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec00003a, frt, fra, frb, frc, false); }
|
||||||
|
void FMADDS_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec00003a, frt, fra, frb, frc, true); }
|
||||||
|
void FMR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000090, ra, rt, rb, false); }
|
||||||
|
void FMR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000090, ra, rt, rb, true); }
|
||||||
|
void FMSUB(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000038, frt, fra, frb, frc, false); }
|
||||||
|
void FMSUB_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000038, frt, fra, frb, frc, true); }
|
||||||
|
void FMSUBS(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000038, frt, fra, frb, frc, false); }
|
||||||
|
void FMSUBS_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000038, frt, fra, frb, frc, true); }
|
||||||
|
void FMUL(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000032, frt, fra, frb, frc, false); }
|
||||||
|
void FMUL_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000032, frt, fra, frb, frc, true); }
|
||||||
|
void FMULS(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000032, frt, fra, frb, frc, false); }
|
||||||
|
void FMULS_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000032, frt, fra, frb, frc, true); }
|
||||||
|
void FNABS(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000110, ra, rt, rb, false); }
|
||||||
|
void FNABS_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000110, ra, rt, rb, true); }
|
||||||
|
void FNEG(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000050, ra, rt, rb, false); }
|
||||||
|
void FNEG_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000050, ra, rt, rb, true); }
|
||||||
|
void FNMADD(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00003e, frt, fra, frb, frc, false); }
|
||||||
|
void FNMADD_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00003e, frt, fra, frb, frc, true); }
|
||||||
|
void FNMADDS(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec00003e, frt, fra, frb, frc, false); }
|
||||||
|
void FNMADDS_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec00003e, frt, fra, frb, frc, true); }
|
||||||
|
void FNMSUB(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00003c, frt, fra, frb, frc, false); }
|
||||||
|
void FNMSUB_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00003c, frt, fra, frb, frc, true); }
|
||||||
|
void FNMSUBS(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec00003c, frt, fra, frb, frc, false); }
|
||||||
|
void FNMSUBS_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec00003c, frt, fra, frb, frc, true); }
|
||||||
|
void FRES(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000030, frt, fra, frb, frc, false); }
|
||||||
|
void FRES_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000030, frt, fra, frb, frc, true); }
|
||||||
|
void FRSP(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000018, ra, rt, rb, false); }
|
||||||
|
void FRSP_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000018, ra, rt, rb, true); }
|
||||||
|
void FRSQRTE(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000034, frt, fra, frb, frc, false); }
|
||||||
|
void FRSQRTE_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000034, frt, fra, frb, frc, true); }
|
||||||
|
void FSEL(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00002e, frt, fra, frb, frc, false); }
|
||||||
|
void FSEL_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00002e, frt, fra, frb, frc, true); }
|
||||||
|
void FSUB(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000028, frt, fra, frb, frc, false); }
|
||||||
|
void FSUB_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000028, frt, fra, frb, frc, true); }
|
||||||
|
void FSUBS(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000028, frt, fra, frb, frc, false); }
|
||||||
|
void FSUBS_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000028, frt, fra, frb, frc, true); }
|
||||||
|
void ICBI(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0007ac, ra, rt, rb, false); }
|
||||||
|
void ICBI_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0007ac, ra, rt, rb, true); }
|
||||||
|
void ISYNC(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x4c00012c, ra, rt, rb, false); }
|
||||||
|
void ISYNC_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x4c00012c, ra, rt, rb, true); }
|
||||||
|
void LBZ(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x88000000, rt, ra, d); }
|
||||||
|
void LBZU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x8c000000, rt, ra, d); }
|
||||||
|
void LBZUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000ee, ra, rt, rb, false); }
|
||||||
|
void LBZUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000ee, ra, rt, rb, true); }
|
||||||
|
void LBZX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000ae, ra, rt, rb, false); }
|
||||||
|
void LBZX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000ae, ra, rt, rb, true); }
|
||||||
|
void LD(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xe8000000, rt, ra, d >> 2); }
|
||||||
|
void LDARX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000a8, ra, rt, rb, false); }
|
||||||
|
void LDARX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000a8, ra, rt, rb, true); }
|
||||||
|
void LDU(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xe8000001, rt, ra, d >> 2); }
|
||||||
|
void LDUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00006a, ra, rt, rb, false); }
|
||||||
|
void LDUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00006a, ra, rt, rb, true); }
|
||||||
|
void LDX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00002a, ra, rt, rb, false); }
|
||||||
|
void LDX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00002a, ra, rt, rb, true); }
|
||||||
|
void LFD(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xc8000000, rt, ra, d); }
|
||||||
|
void LFDU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xcc000000, rt, ra, d); }
|
||||||
|
void LFDUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004ee, ra, rt, rb, false); }
|
||||||
|
void LFDUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004ee, ra, rt, rb, true); }
|
||||||
|
void LFDX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004ae, ra, rt, rb, false); }
|
||||||
|
void LFDX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004ae, ra, rt, rb, true); }
|
||||||
|
void LFS(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xc0000000, rt, ra, d); }
|
||||||
|
void LFSU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xc4000000, rt, ra, d); }
|
||||||
|
void LFSUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00046e, ra, rt, rb, false); }
|
||||||
|
void LFSUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00046e, ra, rt, rb, true); }
|
||||||
|
void LFSX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00042e, ra, rt, rb, false); }
|
||||||
|
void LFSX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00042e, ra, rt, rb, true); }
|
||||||
|
void LHA(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xa8000000, rt, ra, d); }
|
||||||
|
void LHAU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xac000000, rt, ra, d); }
|
||||||
|
void LHAUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002ee, ra, rt, rb, false); }
|
||||||
|
void LHAUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002ee, ra, rt, rb, true); }
|
||||||
|
void LHAX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002ae, ra, rt, rb, false); }
|
||||||
|
void LHAX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002ae, ra, rt, rb, true); }
|
||||||
|
void LHBRX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00062c, ra, rt, rb, false); }
|
||||||
|
void LHBRX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00062c, ra, rt, rb, true); }
|
||||||
|
void LHZ(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xa0000000, rt, ra, d); }
|
||||||
|
void LHZU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xa4000000, rt, ra, d); }
|
||||||
|
void LHZUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000296, ra, rt, rb, false); }
|
||||||
|
void LHZUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000296, ra, rt, rb, true); }
|
||||||
|
void LHZX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00022e, ra, rt, rb, false); }
|
||||||
|
void LHZX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00022e, ra, rt, rb, true); }
|
||||||
|
void LMW(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xb8000000, rt, ra, d); }
|
||||||
|
void LSWI(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004aa, ra, rt, rb, false); }
|
||||||
|
void LSWI_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004aa, ra, rt, rb, true); }
|
||||||
|
void LSWX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00042a, ra, rt, rb, false); }
|
||||||
|
void LSWX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00042a, ra, rt, rb, true); }
|
||||||
|
void LWA(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xe8000002, rt, ra, d >> 2); }
|
||||||
|
void LWARX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000028, ra, rt, rb, false); }
|
||||||
|
void LWARX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000028, ra, rt, rb, true); }
|
||||||
|
void LWAUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002ea, ra, rt, rb, false); }
|
||||||
|
void LWAUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002ea, ra, rt, rb, true); }
|
||||||
|
void LWAX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002aa, ra, rt, rb, false); }
|
||||||
|
void LWAX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002aa, ra, rt, rb, true); }
|
||||||
|
void LWBRX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00042c, ra, rt, rb, false); }
|
||||||
|
void LWBRX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00042c, ra, rt, rb, true); }
|
||||||
|
void LWZ(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x80000000, rt, ra, d); }
|
||||||
|
void LWZU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x84000000, rt, ra, d); }
|
||||||
|
void LWZUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00006e, ra, rt, rb, false); }
|
||||||
|
void LWZUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00006e, ra, rt, rb, true); }
|
||||||
|
void LWZX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00002e, ra, rt, rb, false); }
|
||||||
|
void LWZX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00002e, ra, rt, rb, true); }
|
||||||
|
void MCRF(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000000, bt.index, ba.index, bb.index, false); }
|
||||||
|
void MCRFL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000000, bt.index, ba.index, bb.index, true); }
|
||||||
|
void MCRFS(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000080, ra, rt, rb, false); }
|
||||||
|
void MCRFS_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000080, ra, rt, rb, true); }
|
||||||
|
void MCRXR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000400, ra, rt, rb, false); }
|
||||||
|
void MCRXR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000400, ra, rt, rb, true); }
|
||||||
|
void MFCR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000026, ra, rt, rb, false); }
|
||||||
|
void MFCR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000026, ra, rt, rb, true); }
|
||||||
|
void MFFS(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00048e, ra, rt, rb, false); }
|
||||||
|
void MFFS_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00048e, ra, rt, rb, true); }
|
||||||
|
void MFMSR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000a6, ra, rt, rb, false); }
|
||||||
|
void MFMSR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000a6, ra, rt, rb, true); }
|
||||||
|
void MFSPR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002a6, ra, rt, rb, false); }
|
||||||
|
void MFSPR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002a6, ra, rt, rb, true); }
|
||||||
|
void MFSR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004a6, ra, rt, rb, false); }
|
||||||
|
void MFSR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004a6, ra, rt, rb, true); }
|
||||||
|
void MFSRIN(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000526, ra, rt, rb, false); }
|
||||||
|
void MFSRIN_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000526, ra, rt, rb, true); }
|
||||||
|
void MTCRF(GPR const rt, uint32_t spr) { emit_XFX(0x7c000120, rt, spr); }
|
||||||
|
void MTFSB0(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00008c, ra, rt, rb, false); }
|
||||||
|
void MTFSB0_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00008c, ra, rt, rb, true); }
|
||||||
|
void MTFSB1(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00004c, ra, rt, rb, false); }
|
||||||
|
void MTFSB1_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00004c, ra, rt, rb, true); }
|
||||||
|
void MTFSF() { emit_XFL(0xfc00058e); }
|
||||||
|
void MTFSFI(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00010c, ra, rt, rb, false); }
|
||||||
|
void MTFSFI_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00010c, ra, rt, rb, true); }
|
||||||
|
void MTMSR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000124, ra, rt, rb, false); }
|
||||||
|
void MTMSR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000124, ra, rt, rb, true); }
|
||||||
|
void MTSPR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0003a6, ra, rt, rb, false); }
|
||||||
|
void MTSPR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0003a6, ra, rt, rb, true); }
|
||||||
|
void MTSR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001a4, ra, rt, rb, false); }
|
||||||
|
void MTSR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001a4, ra, rt, rb, true); }
|
||||||
|
void MTSRIN(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001e4, ra, rt, rb, false); }
|
||||||
|
void MTSRIN_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001e4, ra, rt, rb, true); }
|
||||||
|
void MULHD(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000092, rt, ra, rb, false, false); }
|
||||||
|
void MULHDO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000092, rt, ra, rb, true, false); }
|
||||||
|
void MULHD_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000092, rt, ra, rb, false, true); }
|
||||||
|
void MULHDO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000092, rt, ra, rb, true, true); }
|
||||||
|
void MULHDU(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000012, rt, ra, rb, false, false); }
|
||||||
|
void MULHDUO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000012, rt, ra, rb, true, false); }
|
||||||
|
void MULHDU_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000012, rt, ra, rb, false, true); }
|
||||||
|
void MULHDUO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000012, rt, ra, rb, true, true); }
|
||||||
|
void MULHW(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000096, rt, ra, rb, false, false); }
|
||||||
|
void MULHWO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000096, rt, ra, rb, true, false); }
|
||||||
|
void MULHW_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000096, rt, ra, rb, false, true); }
|
||||||
|
void MULHWO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000096, rt, ra, rb, true, true); }
|
||||||
|
void MULHWU(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000016, rt, ra, rb, false, false); }
|
||||||
|
void MULHWUO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000016, rt, ra, rb, true, false); }
|
||||||
|
void MULHWU_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000016, rt, ra, rb, false, true); }
|
||||||
|
void MULHWUO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000016, rt, ra, rb, true, true); }
|
||||||
|
void MULLD(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d2, rt, ra, rb, false, false); }
|
||||||
|
void MULLDO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d2, rt, ra, rb, true, false); }
|
||||||
|
void MULLD_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d2, rt, ra, rb, false, true); }
|
||||||
|
void MULLDO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d2, rt, ra, rb, true, true); }
|
||||||
|
void MULLI(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x1c000000, rt, ra, d); }
|
||||||
|
void MULLW(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d6, rt, ra, rb, false, false); }
|
||||||
|
void MULLWO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d6, rt, ra, rb, true, false); }
|
||||||
|
void MULLW_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d6, rt, ra, rb, false, true); }
|
||||||
|
void MULLWO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d6, rt, ra, rb, true, true); }
|
||||||
|
void NAND(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0003b8, ra, rt, rb, false); }
|
||||||
|
void NAND_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0003b8, ra, rt, rb, true); }
|
||||||
|
void NEG(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0000d0, rt, ra, rb, false, false); }
|
||||||
|
void NEGO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0000d0, rt, ra, rb, true, false); }
|
||||||
|
void NEG_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0000d0, rt, ra, rb, false, true); }
|
||||||
|
void NEGO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0000d0, rt, ra, rb, true, true); }
|
||||||
|
void NOR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000f8, ra, rt, rb, false); }
|
||||||
|
void NOR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000f8, ra, rt, rb, true); }
|
||||||
|
void OR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000378, ra, rt, rb, false); }
|
||||||
|
void OR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000378, ra, rt, rb, true); }
|
||||||
|
void ORC(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000338, ra, rt, rb, false); }
|
||||||
|
void ORC_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000338, ra, rt, rb, true); }
|
||||||
|
void ORI(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x60000000, ra, rt, d); }
|
||||||
|
void ORIS(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x64000000, ra, rt, d); }
|
||||||
|
void RFI(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x4c000064, ra, rt, rb, false); }
|
||||||
|
void RFI_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x4c000064, ra, rt, rb, true); }
|
||||||
|
void RLDCL(GPR const rs, GPR const ra, GPR const rb, uint32_t mb) { emit_MDS(0x78000010, ra, rs, rb, mb, false); }
|
||||||
|
void RLDCL_(GPR const rs, GPR const ra, GPR const rb, uint32_t mb) { emit_MDS(0x78000010, ra, rs, rb, mb, true); }
|
||||||
|
void RLDCR(GPR const rs, GPR const ra, GPR const rb, uint32_t mb) { emit_MDS(0x78000012, ra, rs, rb, mb, false); }
|
||||||
|
void RLDCR_(GPR const rs, GPR const ra, GPR const rb, uint32_t mb) { emit_MDS(0x78000012, ra, rs, rb, mb, true); }
|
||||||
|
void RLDIC(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) { emit_MD(0x78000008, ra, rs, mb, sh, false); }
|
||||||
|
void RLDIC_(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) { emit_MD(0x78000008, ra, rs, mb, sh, true); }
|
||||||
|
void RLDICL(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) { emit_MD(0x78000000, ra, rs, mb, sh, false); }
|
||||||
|
void RLDICL_(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) { emit_MD(0x78000000, ra, rs, mb, sh, true); }
|
||||||
|
void RLDICR(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) { emit_MD(0x78000004, ra, rs, mb, sh, false); }
|
||||||
|
void RLDICR_(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) { emit_MD(0x78000004, ra, rs, mb, sh, true); }
|
||||||
|
void RLDIMI(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) { emit_MD(0x7800000c, ra, rs, mb, sh, false); }
|
||||||
|
void RLDIMI_(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) { emit_MD(0x7800000c, ra, rs, mb, sh, true); }
|
||||||
|
void RLWIMI(GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, uint32_t me = 0) { emit_M(0x50000000, ra, rs, sh, mb, me, false); }
|
||||||
|
void RLWIMI_(GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, uint32_t me = 0) { emit_M(0x50000000, ra, rs, sh, mb, me, true); }
|
||||||
|
void RLWINM(GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, uint32_t me = 0) { emit_M(0x54000000, ra, rs, sh, mb, me, false); }
|
||||||
|
void RLWINM_(GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, uint32_t me = 0) { emit_M(0x54000000, ra, rs, sh, mb, me, true); }
|
||||||
|
void RLWNM(GPR const rs, GPR const ra, GPR const rb, uint32_t mb, uint32_t me = 0) { emit_M(0x5c000000, ra, rs, rb.index, mb, me, false); }
|
||||||
|
void RLWNM_(GPR const rs, GPR const ra, GPR const rb, uint32_t mb, uint32_t me = 0) { emit_M(0x5c000000, ra, rs, rb.index, mb, me, true); }
|
||||||
|
void SC(uint32_t lev) { emit_SC(0x44000000, lev); }
|
||||||
|
void SI(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x30000000, rt, ra, d); }
|
||||||
|
void SI_(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x34000000, rt, ra, d); }
|
||||||
|
void SLBIA(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0003e4, ra, rt, rb, false); }
|
||||||
|
void SLBIA_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0003e4, ra, rt, rb, true); }
|
||||||
|
void SLBIE(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000364, ra, rt, rb, false); }
|
||||||
|
void SLBIE_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000364, ra, rt, rb, true); }
|
||||||
|
void SLD(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000036, ra, rt, rb, false); }
|
||||||
|
void SLD_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000036, ra, rt, rb, true); }
|
||||||
|
void SLW(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000030, ra, rt, rb, false); }
|
||||||
|
void SLW_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000030, ra, rt, rb, true); }
|
||||||
|
void SRAD(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000634, ra, rt, rb, false); }
|
||||||
|
void SRAD_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000634, ra, rt, rb, true); }
|
||||||
|
void SRADI(GPR const rt, GPR const ra, uint32_t sh) { emit_XS(0x7c000674, rt, ra, sh, false); }
|
||||||
|
void SRADI_(GPR const rt, GPR const ra, uint32_t sh) { emit_XS(0x7c000674, rt, ra, sh, true); }
|
||||||
|
void SRD(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000436, ra, rt, rb, false); }
|
||||||
|
void SRD_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000436, ra, rt, rb, true); }
|
||||||
|
void SRAW(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000630, ra, rt, rb, false); }
|
||||||
|
void SRAW_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000630, ra, rt, rb, true); }
|
||||||
|
void SRAWI(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000670, ra, rt, rb, false); }
|
||||||
|
void SRAWI_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000670, ra, rt, rb, true); }
|
||||||
|
void SRW(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000430, ra, rt, rb, false); }
|
||||||
|
void SRW_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000430, ra, rt, rb, true); }
|
||||||
|
void STB(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x98000000, rt, ra, d); }
|
||||||
|
void STBU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x9c000000, rt, ra, d); }
|
||||||
|
void STBUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ee, ra, rt, rb, false); }
|
||||||
|
void STBUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ee, ra, rt, rb, true); }
|
||||||
|
void STBX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ae, ra, rt, rb, false); }
|
||||||
|
void STBX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ae, ra, rt, rb, true); }
|
||||||
|
void STD(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xf8000000, rt, ra, d >> 2); }
|
||||||
|
void STDCX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ac, ra, rt, rb, false); }
|
||||||
|
void STDCX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ac, ra, rt, rb, true); }
|
||||||
|
void STDU(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xf8000001, rt, ra, d >> 2); }
|
||||||
|
void STDUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00016a, ra, rt, rb, false); }
|
||||||
|
void STDUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00016a, ra, rt, rb, true); }
|
||||||
|
void STDX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00012a, ra, rt, rb, false); }
|
||||||
|
void STDX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00012a, ra, rt, rb, true); }
|
||||||
|
void STFD(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xd8000000, rt, ra, d); }
|
||||||
|
void STFDU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xdc000000, rt, ra, d); }
|
||||||
|
void STFDUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0005ee, ra, rt, rb, false); }
|
||||||
|
void STFDUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0005ee, ra, rt, rb, true); }
|
||||||
|
void STFDX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0005ae, ra, rt, rb, false); }
|
||||||
|
void STFDX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0005ae, ra, rt, rb, true); }
|
||||||
|
void STFIWX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0007ae, ra, rt, rb, false); }
|
||||||
|
void STFIWX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0007ae, ra, rt, rb, true); }
|
||||||
|
void STFS(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xd0000000, rt, ra, d); }
|
||||||
|
void STFSU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xd4000000, rt, ra, d); }
|
||||||
|
void STFSUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00056e, ra, rt, rb, false); }
|
||||||
|
void STFSUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00056e, ra, rt, rb, true); }
|
||||||
|
void STFSX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00052e, ra, rt, rb, false); }
|
||||||
|
void STFSX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00052e, ra, rt, rb, true); }
|
||||||
|
void STH(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xb0000000, rt, ra, d); }
|
||||||
|
void STHBRX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00072c, ra, rt, rb, false); }
|
||||||
|
void STHBRX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00072c, ra, rt, rb, true); }
|
||||||
|
void STHU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xb4000000, rt, ra, d); }
|
||||||
|
void STHUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00036e, ra, rt, rb, false); }
|
||||||
|
void STHUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00036e, ra, rt, rb, true); }
|
||||||
|
void STHX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00032e, ra, rt, rb, false); }
|
||||||
|
void STHX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00032e, ra, rt, rb, true); }
|
||||||
|
void STMW(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xbc000000, rt, ra, d); }
|
||||||
|
void STSWI(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0005aa, ra, rt, rb, false); }
|
||||||
|
void STSWI_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0005aa, ra, rt, rb, true); }
|
||||||
|
void STSWX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00052a, ra, rt, rb, false); }
|
||||||
|
void STSWX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00052a, ra, rt, rb, true); }
|
||||||
|
void STW(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x90000000, rt, ra, d); }
|
||||||
|
void STWBRX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00052c, ra, rt, rb, false); }
|
||||||
|
void STWBRX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00052c, ra, rt, rb, true); }
|
||||||
|
void STWCX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00012c, ra, rt, rb, false); }
|
||||||
|
void STWCX__(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00012c, ra, rt, rb, true); }
|
||||||
|
void STWU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x94000000, rt, ra, d); }
|
||||||
|
void STWUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00016e, ra, rt, rb, false); }
|
||||||
|
void STWUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00016e, ra, rt, rb, true); }
|
||||||
|
void STWX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00012e, ra, rt, rb, false); }
|
||||||
|
void STWX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00012e, ra, rt, rb, true); }
|
||||||
|
void SUBF(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000050, rt, ra, rb, false, false); }
|
||||||
|
void SUBFO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000050, rt, ra, rb, true, false); }
|
||||||
|
void SUBF_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000050, rt, ra, rb, false, true); }
|
||||||
|
void SUBFO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000050, rt, ra, rb, true, true); }
|
||||||
|
void SUBFC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000010, rt, ra, rb, false, false); }
|
||||||
|
void SUBFCO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000010, rt, ra, rb, true, false); }
|
||||||
|
void SUBFC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000010, rt, ra, rb, false, true); }
|
||||||
|
void SUBFCO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000010, rt, ra, rb, true, true); }
|
||||||
|
void SUBFE(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000110, rt, ra, rb, false, false); }
|
||||||
|
void SUBFEO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000110, rt, ra, rb, true, false); }
|
||||||
|
void SUBFE_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000110, rt, ra, rb, false, true); }
|
||||||
|
void SUBFEO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000110, rt, ra, rb, true, true); }
|
||||||
|
void SUBFIC(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x20000000, rt, ra, d); }
|
||||||
|
void SUBFME(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d0, rt, ra, rb, false, false); }
|
||||||
|
void SUBFMEO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d0, rt, ra, rb, true, false); }
|
||||||
|
void SUBFME_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d0, rt, ra, rb, false, true); }
|
||||||
|
void SUBFMEO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d0, rt, ra, rb, true, true); }
|
||||||
|
void SUBFZE(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000190, rt, ra, rb, false, false); }
|
||||||
|
void SUBFZEO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000190, rt, ra, rb, true, false); }
|
||||||
|
void SUBFZE_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000190, rt, ra, rb, false, true); }
|
||||||
|
void SUBFZEO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000190, rt, ra, rb, true, true); }
|
||||||
|
void SYNC(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004ac, ra, rt, rb, false); }
|
||||||
|
void SYNC_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004ac, ra, rt, rb, true); }
|
||||||
|
void TD(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000088, ra, rt, rb, false); }
|
||||||
|
void TD_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000088, ra, rt, rb, true); }
|
||||||
|
void TDI(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x08000000, rt, ra, d); }
|
||||||
|
void TLBIE(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000264, ra, rt, rb, false); }
|
||||||
|
void TLBIE_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000264, ra, rt, rb, true); }
|
||||||
|
void TLBSYNC(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00046c, ra, rt, rb, false); }
|
||||||
|
void TLBSYNC_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00046c, ra, rt, rb, true); }
|
||||||
|
void TW(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000008, ra, rt, rb, false); }
|
||||||
|
void TW_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000008, ra, rt, rb, true); }
|
||||||
|
void TWI(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x0c000000, rt, ra, d); }
|
||||||
|
void XOR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000278, ra, rt, rb, false); }
|
||||||
|
void XOR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000278, ra, rt, rb, true); }
|
||||||
|
void XORI(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x68000000, ra, rt, d); }
|
||||||
|
void XORIS(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x6c000000, ra, rt, d); }
|
||||||
Vendored
+340
@@ -0,0 +1,340 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include "powah_emit.hpp"
|
||||||
|
|
||||||
|
#define EB32(X) __bswap32(X)
|
||||||
|
|
||||||
|
TEST_CASE("ppc64: addi", "[ppc64]") {
|
||||||
|
std::vector<uint32_t> data(64);
|
||||||
|
powah::Context ctx(data.data(), data.size());
|
||||||
|
|
||||||
|
ctx.ADDI(powah::R2, powah::R2, 0);
|
||||||
|
ctx.ADDIS(powah::R2, powah::R12, 0);
|
||||||
|
REQUIRE(data[0] == EB32(0x00004238));
|
||||||
|
REQUIRE(data[1] == EB32(0x00004c3c));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ppc64: std/mr", "[ppc64]") {
|
||||||
|
std::vector<uint32_t> data(64);
|
||||||
|
powah::Context ctx(data.data(), data.size());
|
||||||
|
|
||||||
|
ctx.STD(powah::R26, powah::R1, 144);
|
||||||
|
ctx.MR(powah::R26, powah::R4);
|
||||||
|
ctx.STD(powah::R30, powah::R1, 176);
|
||||||
|
ctx.MR(powah::R30, powah::R3);
|
||||||
|
ctx.RLDICR(powah::R4, powah::R5, 25, 6);
|
||||||
|
ctx.STD(powah::R28, powah::R1, 160);
|
||||||
|
REQUIRE(data[0] == EB32(0x900041fb));
|
||||||
|
REQUIRE(data[1] == EB32(0x78239a7c));
|
||||||
|
REQUIRE(data[2] == EB32(0xb000c1fb));
|
||||||
|
REQUIRE(data[3] == EB32(0x781b7e7c));
|
||||||
|
REQUIRE(data[4] == EB32(0x84c9a478));
|
||||||
|
REQUIRE(data[5] == EB32(0xa00081fb));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ppc64: sldi", "[ppc64]") {
|
||||||
|
std::vector<uint32_t> data(64);
|
||||||
|
powah::Context ctx(data.data(), data.size());
|
||||||
|
|
||||||
|
ctx.SLDI(powah::R3, powah::R5, 37);
|
||||||
|
REQUIRE(data[0] == EB32(0x862ea378));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ppc64: rldicr", "[ppc64]") {
|
||||||
|
std::vector<uint32_t> data(64);
|
||||||
|
powah::Context ctx(data.data(), data.size());
|
||||||
|
ctx.RLDICR(powah::R1, powah::R1, 0, 0);
|
||||||
|
ctx.RLDICR(powah::R1, powah::R1, 1, 0);
|
||||||
|
ctx.RLDICR(powah::R1, powah::R1, 0, 1);
|
||||||
|
ctx.RLDICR(powah::R1, powah::R1, 1, 1);
|
||||||
|
ctx.RLDICR(powah::R1, powah::R1, 31, 31);
|
||||||
|
REQUIRE(data[0] == EB32(0x04002178));
|
||||||
|
REQUIRE(data[1] == EB32(0x04082178));
|
||||||
|
REQUIRE(data[2] == EB32(0x44002178));
|
||||||
|
REQUIRE(data[3] == EB32(0x44082178));
|
||||||
|
REQUIRE(data[4] == EB32(0xc4ff2178));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ppc64: mr/or/std", "[ppc64]") {
|
||||||
|
std::vector<uint32_t> data(64);
|
||||||
|
powah::Context ctx(data.data(), data.size());
|
||||||
|
ctx.MR(powah::R27, powah::R7);
|
||||||
|
ctx.MR(powah::R29, powah::R6);
|
||||||
|
ctx.OR(powah::R3, powah::R3, powah::R4);
|
||||||
|
ctx.MR(powah::R4, powah::R28);
|
||||||
|
ctx.CRMOVE(powah::CPR{8}, powah::CPR{1});
|
||||||
|
ctx.MR(powah::R25, powah::R5);
|
||||||
|
ctx.OR(powah::R3, powah::R3, powah::R26);
|
||||||
|
ctx.STD(powah::R3, powah::R1, 56);
|
||||||
|
ctx.MR(powah::R3, powah::R30);
|
||||||
|
REQUIRE(data[0] == EB32(0x783bfb7c));
|
||||||
|
REQUIRE(data[1] == EB32(0x7833dd7c));
|
||||||
|
REQUIRE(data[2] == EB32(0x7823637c));
|
||||||
|
REQUIRE(data[3] == EB32(0x78e3847f));
|
||||||
|
REQUIRE(data[4] == EB32(0x820b014d));
|
||||||
|
REQUIRE(data[5] == EB32(0x782bb97c));
|
||||||
|
REQUIRE(data[6] == EB32(0x78d3637c));
|
||||||
|
REQUIRE(data[7] == EB32(0x380061f8));
|
||||||
|
REQUIRE(data[8] == EB32(0x78f3c37f));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ppc64: ld/crand+addi", "[ppc64]") {
|
||||||
|
std::vector<uint32_t> data(64);
|
||||||
|
powah::Context ctx(data.data(), data.size());
|
||||||
|
ctx.LD(powah::R4, powah::R1, 72);
|
||||||
|
ctx.LWZ(powah::R5, powah::R1, 80);
|
||||||
|
ctx.CRAND(powah::CPR{20}, powah::CPR{10}, powah::CPR{9});
|
||||||
|
ctx.ADDI(powah::R6, powah::R4, 4);
|
||||||
|
ctx.ANDIS_(powah::R4, powah::R5, 1992);
|
||||||
|
ctx.LD(powah::R5, powah::R30, 1984);
|
||||||
|
ctx.LBZ(powah::R3, powah::R1, 84);
|
||||||
|
ctx.CLRLDI(powah::R26, powah::R6, 8);
|
||||||
|
ctx.STW(powah::R4, powah::R1, 80);
|
||||||
|
ctx.ADDI(powah::R5, powah::R5, 1);
|
||||||
|
ctx.STD(powah::R26, powah::R1, 72);
|
||||||
|
ctx.STD(powah::R5, powah::R30, 1984);
|
||||||
|
REQUIRE(data[0] == EB32(0x480081e8));
|
||||||
|
REQUIRE(data[1] == EB32(0x5000a180));
|
||||||
|
REQUIRE(data[2] == EB32(0x024a8a4e));
|
||||||
|
REQUIRE(data[3] == EB32(0x0400c438));
|
||||||
|
REQUIRE(data[4] == EB32(0xc807a474));
|
||||||
|
REQUIRE(data[5] == EB32(0xc007bee8));
|
||||||
|
REQUIRE(data[6] == EB32(0x54006188));
|
||||||
|
REQUIRE(data[7] == EB32(0x0002da78));
|
||||||
|
REQUIRE(data[8] == EB32(0x50008190));
|
||||||
|
REQUIRE(data[9] == EB32(0x0100a538));
|
||||||
|
REQUIRE(data[10] == EB32(0x480041fb));
|
||||||
|
REQUIRE(data[11] == EB32(0xc007bef8));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ppc64: rotldi", "[ppc64]") {
|
||||||
|
std::vector<uint32_t> data(64);
|
||||||
|
powah::Context ctx(data.data(), data.size());
|
||||||
|
ctx.ROTLDI(powah::R5, powah::R3, 16);
|
||||||
|
ctx.ROTLDI(powah::R4, powah::R3, 8);
|
||||||
|
ctx.RLDIMI(powah::R4, powah::R5, 8, 48);
|
||||||
|
ctx.ROTLDI(powah::R5, powah::R3, 24);
|
||||||
|
ctx.RLDIMI(powah::R4, powah::R5, 16, 40);
|
||||||
|
ctx.ROTLDI(powah::R5, powah::R3, 32);
|
||||||
|
ctx.RLDIMI(powah::R4, powah::R5, 24, 32);
|
||||||
|
ctx.ROTLDI(powah::R5, powah::R3, 48);
|
||||||
|
ctx.RLDIMI(powah::R4, powah::R5, 40, 16);
|
||||||
|
ctx.ROTLDI(powah::R5, powah::R3, 56);
|
||||||
|
ctx.RLDIMI(powah::R4, powah::R5, 48, 8);
|
||||||
|
ctx.RLDIMI(powah::R4, powah::R3, 56, 0);
|
||||||
|
ctx.MR(powah::R3, powah::R4);
|
||||||
|
REQUIRE(data[0] == EB32(0x00806578));
|
||||||
|
REQUIRE(data[1] == EB32(0x00406478));
|
||||||
|
REQUIRE(data[2] == EB32(0x2c44a478));
|
||||||
|
REQUIRE(data[3] == EB32(0x00c06578));
|
||||||
|
REQUIRE(data[4] == EB32(0x2c82a478));
|
||||||
|
REQUIRE(data[5] == EB32(0x02006578));
|
||||||
|
REQUIRE(data[6] == EB32(0x2cc0a478));
|
||||||
|
REQUIRE(data[7] == EB32(0x02806578));
|
||||||
|
REQUIRE(data[8] == EB32(0x0e44a478));
|
||||||
|
REQUIRE(data[9] == EB32(0x02c06578));
|
||||||
|
REQUIRE(data[10] == EB32(0x0e82a478));
|
||||||
|
REQUIRE(data[11] == EB32(0x0ec06478));
|
||||||
|
REQUIRE(data[12] == EB32(0x7823837c));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ppc64: branch-backwards", "[ppc64]") {
|
||||||
|
std::vector<uint32_t> data(64);
|
||||||
|
powah::Context ctx(data.data(), data.size());
|
||||||
|
powah::Label l_3 = ctx.DefineLabel();
|
||||||
|
ctx.LABEL(l_3);
|
||||||
|
ctx.ADD(powah::R1, powah::R2, powah::R3);
|
||||||
|
ctx.B(l_3);
|
||||||
|
ctx.ApplyRelocs();
|
||||||
|
REQUIRE(data[0] == EB32(0x141a227c));
|
||||||
|
REQUIRE(data[1] == EB32(0xfcffff4b));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ppc64: rlwimi madness", "[ppc64]") {
|
||||||
|
std::vector<uint32_t> data(64);
|
||||||
|
powah::Context ctx(data.data(), data.size());
|
||||||
|
ctx.ROTLWI(powah::R10, powah::R3, 24);
|
||||||
|
ctx.SRDI(powah::R9, powah::R3, 32);
|
||||||
|
ctx.RLWIMI(powah::R10, powah::R3, 8, 8, 15);
|
||||||
|
ctx.RLWIMI(powah::R10, powah::R3, 8, 24, 31);
|
||||||
|
ctx.ROTLWI(powah::R3, powah::R9, 24);
|
||||||
|
ctx.RLWIMI(powah::R3, powah::R9, 8, 8, 15);
|
||||||
|
ctx.RLWIMI(powah::R3, powah::R9, 8, 24, 31);
|
||||||
|
ctx.RLDIMI(powah::R3, powah::R10, 32, 0);
|
||||||
|
REQUIRE(data[0] == EB32(0x3ec06a54));
|
||||||
|
REQUIRE(data[1] == EB32(0x22006978));
|
||||||
|
REQUIRE(data[2] == EB32(0x1e426a50));
|
||||||
|
REQUIRE(data[3] == EB32(0x3e466a50));
|
||||||
|
REQUIRE(data[4] == EB32(0x3ec02355));
|
||||||
|
REQUIRE(data[5] == EB32(0x1e422351));
|
||||||
|
REQUIRE(data[6] == EB32(0x3e462351));
|
||||||
|
REQUIRE(data[7] == EB32(0x0e004379));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
0: 78 1b 68 7c mr 8, 3
|
||||||
|
4: 38 28 83 7c and 3, 4, 5
|
||||||
|
8: 74 00 6a 7c cntlzd 10, 3
|
||||||
|
c: 76 06 69 7c sradi 9, 3, 32
|
||||||
|
10: 82 d1 4a 79 rldicl 10, 10, 58, 6
|
||||||
|
14: 00 00 29 55 rlwinm 9, 9, 0, 0, 0
|
||||||
|
18: 64 f0 4a 79 sldi 10, 10, 30
|
||||||
|
1c: 78 53 29 7d or 9, 9, 10
|
||||||
|
20: 00 00 28 f9 std 9, 0(8)
|
||||||
|
24: 20 00 80 4e blr
|
||||||
|
*/
|
||||||
|
TEST_CASE("ppc64: functor-2", "[ppc64]") {
|
||||||
|
std::vector<uint32_t> data(64);
|
||||||
|
powah::Context ctx(data.data(), data.size());
|
||||||
|
ctx.MR(powah::R8, powah::R3);
|
||||||
|
ctx.AND(powah::R3, powah::R4, powah::R5);
|
||||||
|
ctx.CNTLZD(powah::R10, powah::R3);
|
||||||
|
ctx.SRADI(powah::R9, powah::R3, 32);
|
||||||
|
ctx.RLDICL(powah::R10, powah::R10, 58, 6);
|
||||||
|
ctx.RLWINM(powah::R9, powah::R9, 0, 0, 0);
|
||||||
|
ctx.SLDI(powah::R10, powah::R10, 30);
|
||||||
|
ctx.OR(powah::R9, powah::R9, powah::R10);
|
||||||
|
ctx.STD(powah::R9, powah::R8, 0);
|
||||||
|
ctx.BLR();
|
||||||
|
REQUIRE(data[0] == EB32(0x781b687c));
|
||||||
|
REQUIRE(data[1] == EB32(0x3828837c));
|
||||||
|
REQUIRE(data[2] == EB32(0x74006a7c));
|
||||||
|
REQUIRE(data[3] == EB32(0x7606697c));
|
||||||
|
REQUIRE(data[4] == EB32(0x82d14a79));
|
||||||
|
REQUIRE(data[5] == EB32(0x00002955));
|
||||||
|
REQUIRE(data[6] == EB32(0x64f04a79));
|
||||||
|
REQUIRE(data[7] == EB32(0x7853297d));
|
||||||
|
REQUIRE(data[8] == EB32(0x000028f9));
|
||||||
|
REQUIRE(data[9] == EB32(0x2000804e));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ppc64: functor-1", "[ppc64]") {
|
||||||
|
std::vector<uint32_t> data(64);
|
||||||
|
powah::Context ctx(data.data(), data.size());
|
||||||
|
powah::Label l_4 = ctx.DefineLabel();
|
||||||
|
powah::Label l_7 = ctx.DefineLabel();
|
||||||
|
ctx.CMPLD(powah::CR0, powah::R3, powah::R4);
|
||||||
|
ctx.MR(powah::R9, powah::R3);
|
||||||
|
ctx.BGT(powah::CR0, l_7);
|
||||||
|
ctx.CMPLDI(powah::CR0, powah::R3, 3781);
|
||||||
|
ctx.LI(powah::R3, 1);
|
||||||
|
ctx.BGTLR(powah::CR0);
|
||||||
|
ctx.CMPLD(powah::CR0, powah::R9, powah::R5);
|
||||||
|
ctx.BLE(powah::CR0, l_4);
|
||||||
|
ctx.SUBF(powah::R5, powah::R9, powah::R5);
|
||||||
|
ctx.XOR(powah::R3, powah::R5, powah::R4);
|
||||||
|
ctx.BLR();
|
||||||
|
ctx.LABEL(l_4);
|
||||||
|
ctx.ADD(powah::R5, powah::R4, powah::R5);
|
||||||
|
ctx.ADD(powah::R3, powah::R5, powah::R9);
|
||||||
|
ctx.BLR();
|
||||||
|
ctx.LABEL(l_7);
|
||||||
|
ctx.ADD(powah::R3, powah::R4, powah::R5);
|
||||||
|
ctx.BLR();
|
||||||
|
ctx.ApplyRelocs();
|
||||||
|
REQUIRE(data[0] == EB32(0x4020237c));
|
||||||
|
REQUIRE(data[1] == EB32(0x781b697c));
|
||||||
|
REQUIRE(data[2] == EB32(0x30008141));
|
||||||
|
REQUIRE(data[3] == EB32(0xc50e2328));
|
||||||
|
REQUIRE(data[4] == EB32(0x01006038));
|
||||||
|
REQUIRE(data[5] == EB32(0x2000814d));
|
||||||
|
REQUIRE(data[6] == EB32(0x4028297c));
|
||||||
|
REQUIRE(data[7] == EB32(0x10008140));
|
||||||
|
REQUIRE(data[8] == EB32(0x5028a97c));
|
||||||
|
REQUIRE(data[9] == EB32(0x7822a37c));
|
||||||
|
REQUIRE(data[10] == EB32(0x2000804e));
|
||||||
|
REQUIRE(data[11] == EB32(0x142aa47c));
|
||||||
|
REQUIRE(data[12] == EB32(0x144a657c));
|
||||||
|
REQUIRE(data[13] == EB32(0x2000804e));
|
||||||
|
REQUIRE(data[14] == EB32(0x142a647c));
|
||||||
|
REQUIRE(data[15] == EB32(0x2000804e));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(ARCHITECTURE_powerpc64)
|
||||||
|
/*
|
||||||
|
0: d619637c mullw 3, 3, 3
|
||||||
|
4: 20006378 clrldi 3, 3, 32
|
||||||
|
8: 2000804e blr
|
||||||
|
*/
|
||||||
|
TEST_CASE("ppc64: live-exec square", "[ppc64]") {
|
||||||
|
uint32_t* data = (uint32_t*)mmap(nullptr, 4096, PROT_WRITE | PROT_READ | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||||
|
REQUIRE(data != nullptr);
|
||||||
|
|
||||||
|
powah::Context ctx((void*)data, 4096);
|
||||||
|
ctx.MULLW(powah::R3, powah::R3, powah::R3);
|
||||||
|
ctx.CLRLDI(powah::R3, powah::R3, 32);
|
||||||
|
ctx.BLR();
|
||||||
|
REQUIRE(data[0] == EB32(0xd619637c));
|
||||||
|
REQUIRE(data[1] == EB32(0x20006378));
|
||||||
|
REQUIRE(data[2] == EB32(0x2000804e));
|
||||||
|
|
||||||
|
auto* fn = (int (*)(int))data;
|
||||||
|
REQUIRE(fn(4) == 4 * 4);
|
||||||
|
REQUIRE(fn(8) == 8 * 8);
|
||||||
|
|
||||||
|
munmap((void*)data, 4096);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
int f(int a, int b, int c) {
|
||||||
|
a += (a > b) ? b - 0xffff : c + 402, b += 2, c &= b*c;
|
||||||
|
return a * a + b ^ c & b;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
TEST_CASE("ppc64: live-exec xoralu", "[ppc64]") {
|
||||||
|
uint32_t* data = (uint32_t*)mmap(nullptr, 4096, PROT_WRITE | PROT_READ | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||||
|
REQUIRE(data != nullptr);
|
||||||
|
|
||||||
|
powah::Context ctx((void*)data, 4096);
|
||||||
|
powah::Label l_2 = ctx.DefineLabel();
|
||||||
|
powah::Label l_3 = ctx.DefineLabel();
|
||||||
|
ctx.CMPW(powah::R3, powah::R4);
|
||||||
|
ctx.BGT(powah::CR0, l_2);
|
||||||
|
ctx.ADDI(powah::R6, powah::R5, 402);
|
||||||
|
ctx.B(l_3);
|
||||||
|
ctx.LABEL(l_2);
|
||||||
|
ctx.ADDI(powah::R6, powah::R4, 1);
|
||||||
|
ctx.ADDIS(powah::R6, powah::R6, -1);
|
||||||
|
ctx.LABEL(l_3);
|
||||||
|
ctx.ADDI(powah::R4, powah::R4, 2);
|
||||||
|
ctx.ADD(powah::R3, powah::R6, powah::R3);
|
||||||
|
ctx.MULLW(powah::R6, powah::R4, powah::R5);
|
||||||
|
ctx.MULLW(powah::R3, powah::R3, powah::R3);
|
||||||
|
ctx.AND(powah::R5, powah::R5, powah::R6);
|
||||||
|
ctx.ADD(powah::R3, powah::R3, powah::R4);
|
||||||
|
ctx.AND(powah::R4, powah::R5, powah::R4);
|
||||||
|
ctx.XOR(powah::R3, powah::R3, powah::R4);
|
||||||
|
ctx.EXTSW(powah::R3, powah::R3);
|
||||||
|
ctx.BLR();
|
||||||
|
ctx.ApplyRelocs();
|
||||||
|
REQUIRE(data[0] == EB32(0x0020037c));
|
||||||
|
REQUIRE(data[1] == EB32(0x0c008141));
|
||||||
|
REQUIRE(data[2] == EB32(0x9201c538));
|
||||||
|
REQUIRE(data[3] == EB32(0x0c000048));
|
||||||
|
REQUIRE(data[4] == EB32(0x0100c438));
|
||||||
|
REQUIRE(data[5] == EB32(0xffffc63c));
|
||||||
|
REQUIRE(data[6] == EB32(0x02008438));
|
||||||
|
REQUIRE(data[7] == EB32(0x141a667c));
|
||||||
|
REQUIRE(data[8] == EB32(0xd629c47c));
|
||||||
|
REQUIRE(data[9] == EB32(0xd619637c));
|
||||||
|
REQUIRE(data[10] == EB32(0x3830a57c));
|
||||||
|
REQUIRE(data[11] == EB32(0x1422637c));
|
||||||
|
REQUIRE(data[12] == EB32(0x3820a47c));
|
||||||
|
REQUIRE(data[13] == EB32(0x7822637c));
|
||||||
|
REQUIRE(data[14] == EB32(0xb407637c));
|
||||||
|
REQUIRE(data[15] == EB32(0x2000804e));
|
||||||
|
|
||||||
|
auto const orig = [](int a, int b, int c) {
|
||||||
|
a += (a > b) ? b - 0xffff : c + 402, b += 2, c &= b*c;
|
||||||
|
return a * a + b ^ c & b;
|
||||||
|
};
|
||||||
|
auto* fn = (int (*)(int, int, int))data;
|
||||||
|
REQUIRE(fn(0, 1, 2) == orig(0, 1, 2));
|
||||||
|
REQUIRE(fn(6456, 4564, 4564561) == orig(6456, 4564, 4564561));
|
||||||
|
|
||||||
|
munmap((void*)data, 4096);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
include_directories(.)
|
include_directories(.)
|
||||||
|
|
||||||
# Dynarmic
|
# Dynarmic
|
||||||
if ((ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64 OR ARCHITECTURE_riscv64 OR ARCHITECTURE_loongarch64) AND NOT YUZU_STATIC_ROOM)
|
if ((ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64 OR ARCHITECTURE_riscv64 OR ARCHITECTURE_loongarch64 OR ARCHITECTURE_powerpc64) AND NOT YUZU_STATIC_ROOM)
|
||||||
add_subdirectory(dynarmic)
|
add_subdirectory(dynarmic)
|
||||||
add_library(dynarmic::dynarmic ALIAS dynarmic)
|
add_library(dynarmic::dynarmic ALIAS dynarmic)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
package org.yuzu.yuzu_emu.dialogs
|
package org.yuzu.yuzu_emu.dialogs
|
||||||
|
|
||||||
import android.content.res.ColorStateList
|
|
||||||
import android.graphics.Rect
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@@ -20,28 +18,11 @@ import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
|||||||
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||||
import org.yuzu.yuzu_emu.fragments.EmulationFragment
|
import org.yuzu.yuzu_emu.fragments.EmulationFragment
|
||||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||||
import org.yuzu.yuzu_emu.utils.NativePostProcessing
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.AbstractShortSetting
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractShortSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting
|
||||||
|
|
||||||
class QuickSettings(val emulationFragment: EmulationFragment) {
|
class QuickSettings(val emulationFragment: EmulationFragment) {
|
||||||
private val expandedShaders = mutableSetOf<Int>()
|
|
||||||
|
|
||||||
private fun forgetShaderSlot(index: Int) {
|
|
||||||
val shifted = mutableSetOf<Int>()
|
|
||||||
for (slot in expandedShaders) {
|
|
||||||
if (slot < index) {
|
|
||||||
shifted.add(slot)
|
|
||||||
}
|
|
||||||
if (slot > index) {
|
|
||||||
shifted.add(slot - 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expandedShaders.clear()
|
|
||||||
expandedShaders.addAll(shifted)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun saveSettings() {
|
private fun saveSettings() {
|
||||||
if (emulationFragment.shouldUseCustom) {
|
if (emulationFragment.shouldUseCustom) {
|
||||||
NativeConfig.savePerGameConfig()
|
NativeConfig.savePerGameConfig()
|
||||||
@@ -251,428 +232,6 @@ class QuickSettings(val emulationFragment: EmulationFragment) {
|
|||||||
container.addView(itemView)
|
container.addView(itemView)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addChoice(
|
|
||||||
title: String,
|
|
||||||
container: ViewGroup,
|
|
||||||
choices: List<String>,
|
|
||||||
selectedIndex: Int,
|
|
||||||
onSelected: (Int) -> Unit
|
|
||||||
) {
|
|
||||||
val inflater = LayoutInflater.from(emulationFragment.requireContext())
|
|
||||||
val itemView = inflater.inflate(R.layout.item_quick_settings_menu, container, false)
|
|
||||||
val headerView = itemView.findViewById<ViewGroup>(R.id.setting_header)
|
|
||||||
val titleView = itemView.findViewById<TextView>(R.id.setting_title)
|
|
||||||
val valueView = itemView.findViewById<TextView>(R.id.setting_value)
|
|
||||||
val expandIcon = itemView.findViewById<android.widget.ImageView>(R.id.expand_icon)
|
|
||||||
val radioGroup = itemView.findViewById<RadioGroup>(R.id.radio_group)
|
|
||||||
|
|
||||||
titleView.text = title
|
|
||||||
|
|
||||||
var current = ""
|
|
||||||
if (selectedIndex in choices.indices) {
|
|
||||||
current = choices[selectedIndex]
|
|
||||||
}
|
|
||||||
valueView.text = current
|
|
||||||
headerView.visibility = View.VISIBLE
|
|
||||||
|
|
||||||
var isExpanded = false
|
|
||||||
choices.forEachIndexed { index, name ->
|
|
||||||
val radioButton = com.google.android.material.radiobutton.MaterialRadioButton(
|
|
||||||
emulationFragment.requireContext()
|
|
||||||
)
|
|
||||||
radioButton.text = name
|
|
||||||
radioButton.id = View.generateViewId()
|
|
||||||
radioButton.isChecked = index == selectedIndex
|
|
||||||
radioButton.setPadding(16, 8, 16, 8)
|
|
||||||
|
|
||||||
radioButton.setOnCheckedChangeListener { _, isChecked ->
|
|
||||||
if (isChecked) {
|
|
||||||
valueView.text = name
|
|
||||||
onSelected(index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
radioGroup.addView(radioButton)
|
|
||||||
}
|
|
||||||
|
|
||||||
headerView.setOnClickListener {
|
|
||||||
isExpanded = !isExpanded
|
|
||||||
if (isExpanded) {
|
|
||||||
radioGroup.visibility = View.VISIBLE
|
|
||||||
expandIcon.animate().rotation(180f).setDuration(200).start()
|
|
||||||
} else {
|
|
||||||
radioGroup.visibility = View.GONE
|
|
||||||
expandIcon.animate().rotation(0f).setDuration(200).start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
container.addView(itemView)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addStepSlider(
|
|
||||||
title: String,
|
|
||||||
container: ViewGroup,
|
|
||||||
steps: Int,
|
|
||||||
selectedStep: Int,
|
|
||||||
describe: (Int) -> String,
|
|
||||||
onCommitted: (Int) -> Unit,
|
|
||||||
onChanged: (Int) -> Unit
|
|
||||||
) {
|
|
||||||
val inflater = LayoutInflater.from(emulationFragment.requireContext())
|
|
||||||
val itemView = inflater.inflate(R.layout.item_quick_settings_menu, container, false)
|
|
||||||
|
|
||||||
val sliderContainer = itemView.findViewById<ViewGroup>(R.id.slider_container)
|
|
||||||
val titleView = itemView.findViewById<TextView>(R.id.slider_title)
|
|
||||||
val valueDisplay = itemView.findViewById<TextView>(R.id.slider_value_display)
|
|
||||||
val slider = itemView.findViewById<com.google.android.material.slider.Slider>(
|
|
||||||
R.id.setting_slider
|
|
||||||
)
|
|
||||||
|
|
||||||
titleView.text = title
|
|
||||||
sliderContainer.visibility = View.VISIBLE
|
|
||||||
|
|
||||||
slider.valueFrom = 0f
|
|
||||||
slider.valueTo = steps.toFloat()
|
|
||||||
slider.stepSize = 1f
|
|
||||||
slider.value = selectedStep.toFloat().coerceIn(0f, steps.toFloat())
|
|
||||||
valueDisplay.text = describe(slider.value.toInt())
|
|
||||||
|
|
||||||
slider.addOnChangeListener { _, value, fromUser ->
|
|
||||||
if (fromUser) {
|
|
||||||
val step = value.toInt()
|
|
||||||
onChanged(step)
|
|
||||||
valueDisplay.text = describe(step)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var pressedValue = slider.value
|
|
||||||
|
|
||||||
slider.setOnTouchListener { _, event ->
|
|
||||||
val drawer = emulationFragment.view?.findViewById<DrawerLayout>(R.id.drawer_layout)
|
|
||||||
when (event.action) {
|
|
||||||
MotionEvent.ACTION_DOWN -> {
|
|
||||||
drawer?.requestDisallowInterceptTouchEvent(true)
|
|
||||||
pressedValue = slider.value
|
|
||||||
}
|
|
||||||
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
|
||||||
drawer?.requestDisallowInterceptTouchEvent(false)
|
|
||||||
if (slider.value != pressedValue) {
|
|
||||||
onCommitted(slider.value.toInt())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
container.addView(itemView)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addShaderCard(
|
|
||||||
index: Int,
|
|
||||||
title: String,
|
|
||||||
summary: String,
|
|
||||||
container: ViewGroup,
|
|
||||||
onRemove: () -> Unit
|
|
||||||
): ViewGroup {
|
|
||||||
val inflater = LayoutInflater.from(emulationFragment.requireContext())
|
|
||||||
val itemView = inflater.inflate(R.layout.item_quick_settings_shader, container, false)
|
|
||||||
|
|
||||||
val headerView = itemView.findViewById<ViewGroup>(R.id.shader_header)
|
|
||||||
val titleView = itemView.findViewById<TextView>(R.id.shader_title)
|
|
||||||
val summaryView = itemView.findViewById<TextView>(R.id.shader_summary)
|
|
||||||
val removeView = itemView.findViewById<android.widget.ImageView>(R.id.shader_remove)
|
|
||||||
val expandIcon = itemView.findViewById<android.widget.ImageView>(R.id.shader_expand)
|
|
||||||
val bodyView = itemView.findViewById<ViewGroup>(R.id.shader_body)
|
|
||||||
|
|
||||||
titleView.text = title
|
|
||||||
if (summary.isEmpty()) {
|
|
||||||
summaryView.visibility = View.GONE
|
|
||||||
} else {
|
|
||||||
summaryView.text = summary
|
|
||||||
}
|
|
||||||
|
|
||||||
var isExpanded = expandedShaders.contains(index)
|
|
||||||
if (isExpanded) {
|
|
||||||
bodyView.visibility = View.VISIBLE
|
|
||||||
expandIcon.rotation = 180f
|
|
||||||
}
|
|
||||||
|
|
||||||
headerView.setOnClickListener {
|
|
||||||
isExpanded = !isExpanded
|
|
||||||
if (isExpanded) {
|
|
||||||
expandedShaders.add(index)
|
|
||||||
bodyView.visibility = View.VISIBLE
|
|
||||||
expandIcon.animate().rotation(180f).setDuration(200).start()
|
|
||||||
} else {
|
|
||||||
expandedShaders.remove(index)
|
|
||||||
bodyView.visibility = View.GONE
|
|
||||||
expandIcon.animate().rotation(0f).setDuration(200).start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
removeView.setOnClickListener {
|
|
||||||
onRemove()
|
|
||||||
}
|
|
||||||
|
|
||||||
container.addView(itemView)
|
|
||||||
return bodyView
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addEffectPicker(
|
|
||||||
container: ViewGroup,
|
|
||||||
choices: List<String>,
|
|
||||||
hasEffects: Boolean,
|
|
||||||
onRemoveAll: () -> Unit,
|
|
||||||
onPicked: (Int) -> Unit
|
|
||||||
) {
|
|
||||||
val context = emulationFragment.requireContext()
|
|
||||||
val inflater = LayoutInflater.from(context)
|
|
||||||
val itemView = inflater.inflate(R.layout.item_quick_settings_add, container, false)
|
|
||||||
|
|
||||||
val button = itemView.findViewById<com.google.android.material.button.MaterialButton>(
|
|
||||||
R.id.add_button
|
|
||||||
)
|
|
||||||
val removeButton =
|
|
||||||
itemView.findViewById<com.google.android.material.button.MaterialButton>(
|
|
||||||
R.id.remove_all_button
|
|
||||||
)
|
|
||||||
val choiceGroup = itemView.findViewById<RadioGroup>(R.id.add_choices)
|
|
||||||
|
|
||||||
choices.forEachIndexed { index, name ->
|
|
||||||
val radioButton = com.google.android.material.radiobutton.MaterialRadioButton(context)
|
|
||||||
radioButton.text = name
|
|
||||||
radioButton.id = View.generateViewId()
|
|
||||||
radioButton.setPadding(16, 8, 16, 8)
|
|
||||||
radioButton.setOnCheckedChangeListener { _, isChecked ->
|
|
||||||
if (isChecked) {
|
|
||||||
onPicked(index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
choiceGroup.addView(radioButton)
|
|
||||||
}
|
|
||||||
|
|
||||||
var closedLabel = R.string.post_processing_add
|
|
||||||
if (hasEffects) {
|
|
||||||
closedLabel = R.string.post_processing_open_list
|
|
||||||
removeButton.visibility = View.VISIBLE
|
|
||||||
}
|
|
||||||
button.setText(closedLabel)
|
|
||||||
|
|
||||||
val removeBackground = MaterialColors.getColor(
|
|
||||||
removeButton,
|
|
||||||
com.google.android.material.R.attr.colorErrorContainer
|
|
||||||
)
|
|
||||||
val removeForeground = MaterialColors.getColor(
|
|
||||||
removeButton,
|
|
||||||
com.google.android.material.R.attr.colorOnErrorContainer
|
|
||||||
)
|
|
||||||
removeButton.backgroundTintList = ColorStateList.valueOf(removeBackground)
|
|
||||||
removeButton.setTextColor(removeForeground)
|
|
||||||
removeButton.iconTint = ColorStateList.valueOf(removeForeground)
|
|
||||||
removeButton.setOnClickListener {
|
|
||||||
onRemoveAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
val slide = context.resources.displayMetrics.density * 24.0f
|
|
||||||
|
|
||||||
var isOpen = false
|
|
||||||
button.setOnClickListener {
|
|
||||||
isOpen = !isOpen
|
|
||||||
if (isOpen) {
|
|
||||||
choiceGroup.alpha = 0.0f
|
|
||||||
choiceGroup.translationY = slide
|
|
||||||
choiceGroup.visibility = View.VISIBLE
|
|
||||||
choiceGroup.animate()
|
|
||||||
.alpha(1.0f)
|
|
||||||
.translationY(0.0f)
|
|
||||||
.setDuration(220)
|
|
||||||
.withEndAction {
|
|
||||||
choiceGroup.requestRectangleOnScreen(
|
|
||||||
Rect(0, 0, choiceGroup.width, choiceGroup.height),
|
|
||||||
false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
.start()
|
|
||||||
|
|
||||||
button.setText(R.string.post_processing_close_list)
|
|
||||||
button.setIconResource(R.drawable.ic_clear)
|
|
||||||
} else {
|
|
||||||
choiceGroup.animate()
|
|
||||||
.alpha(0.0f)
|
|
||||||
.translationY(slide)
|
|
||||||
.setDuration(160)
|
|
||||||
.withEndAction {
|
|
||||||
choiceGroup.visibility = View.GONE
|
|
||||||
}
|
|
||||||
.start()
|
|
||||||
|
|
||||||
button.setText(closedLabel)
|
|
||||||
button.setIconResource(R.drawable.ic_add)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
container.addView(itemView)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addPresetBand(container: ViewGroup, name: String, summary: String) {
|
|
||||||
val inflater = LayoutInflater.from(emulationFragment.requireContext())
|
|
||||||
val itemView = inflater.inflate(R.layout.item_quick_settings_preset, container, false)
|
|
||||||
|
|
||||||
val titleView = itemView.findViewById<TextView>(R.id.preset_title)
|
|
||||||
val summaryView = itemView.findViewById<TextView>(R.id.preset_summary)
|
|
||||||
val switchView = itemView.findViewById<MaterialSwitch>(R.id.preset_switch)
|
|
||||||
|
|
||||||
titleView.text = name
|
|
||||||
if (summary.isEmpty()) {
|
|
||||||
summaryView.visibility = View.GONE
|
|
||||||
} else {
|
|
||||||
summaryView.text = summary
|
|
||||||
}
|
|
||||||
|
|
||||||
switchView.isChecked = NativePostProcessing.isEnabled()
|
|
||||||
switchView.setOnCheckedChangeListener { _, checked ->
|
|
||||||
emulationFragment.editPostProcessing {
|
|
||||||
NativePostProcessing.setEnabled(checked)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
container.addView(itemView)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addPostProcessing(container: ViewGroup, onStructureChanged: () -> Unit) {
|
|
||||||
val usable = NativePostProcessing.catalog().filter { it.valid }
|
|
||||||
if (usable.isEmpty()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val preset = NativePostProcessing.getActivePreset()
|
|
||||||
if (preset.isNotEmpty()) {
|
|
||||||
addDivider(container)
|
|
||||||
|
|
||||||
var summary = ""
|
|
||||||
val described = NativePostProcessing.presets().firstOrNull { it.name == preset }
|
|
||||||
if (described != null) {
|
|
||||||
summary = described.description
|
|
||||||
}
|
|
||||||
if (summary.isEmpty()) {
|
|
||||||
summary =
|
|
||||||
YuzuApplication.appContext.getString(R.string.post_processing_preset_locked)
|
|
||||||
}
|
|
||||||
if (NativePostProcessing.isPresetModified()) {
|
|
||||||
summary = summary + "\n" +
|
|
||||||
YuzuApplication.appContext.getString(R.string.post_processing_preset_modified)
|
|
||||||
}
|
|
||||||
|
|
||||||
addPresetBand(container, preset, summary)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val labels = mutableListOf<String>()
|
|
||||||
val files = mutableListOf<String>()
|
|
||||||
val techniques = mutableListOf<String>()
|
|
||||||
|
|
||||||
for (effect in usable) {
|
|
||||||
for (technique in effect.techniques) {
|
|
||||||
var label = effect.label
|
|
||||||
if (effect.techniques.size > 1) {
|
|
||||||
label = effect.label + " \u00b7 " + technique
|
|
||||||
}
|
|
||||||
labels.add(label)
|
|
||||||
files.add(effect.file)
|
|
||||||
techniques.add(technique)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addDivider(container)
|
|
||||||
|
|
||||||
val chain = NativePostProcessing.chain()
|
|
||||||
chain.forEachIndexed { index, entry ->
|
|
||||||
val effect = usable.firstOrNull { it.file == entry.file }
|
|
||||||
|
|
||||||
var title = entry.file
|
|
||||||
var summary = ""
|
|
||||||
if (effect != null) {
|
|
||||||
title = effect.label
|
|
||||||
if (effect.techniques.size > 1) {
|
|
||||||
title = effect.label + " \u00b7 " + entry.technique
|
|
||||||
}
|
|
||||||
summary = effect.description
|
|
||||||
}
|
|
||||||
|
|
||||||
val body = addShaderCard(index, title, summary, container) {
|
|
||||||
emulationFragment.editPostProcessing {
|
|
||||||
NativePostProcessing.remove(index)
|
|
||||||
}
|
|
||||||
forgetShaderSlot(index)
|
|
||||||
onStructureChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (effect != null) {
|
|
||||||
for (uniform in effect.uniforms) {
|
|
||||||
addUniformSliders(body, index, uniform)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addEffectPicker(
|
|
||||||
container,
|
|
||||||
labels,
|
|
||||||
chain.isNotEmpty(),
|
|
||||||
{
|
|
||||||
emulationFragment.editPostProcessing {
|
|
||||||
NativePostProcessing.clearChain()
|
|
||||||
}
|
|
||||||
expandedShaders.clear()
|
|
||||||
onStructureChanged()
|
|
||||||
}
|
|
||||||
) { picked ->
|
|
||||||
emulationFragment.editPostProcessing {
|
|
||||||
NativePostProcessing.append(files[picked], techniques[picked])
|
|
||||||
}
|
|
||||||
onStructureChanged()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addUniformSliders(
|
|
||||||
container: ViewGroup,
|
|
||||||
index: Int,
|
|
||||||
uniform: NativePostProcessing.Uniform
|
|
||||||
) {
|
|
||||||
if (uniform.uiType == NativePostProcessing.UI_HIDDEN) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for (component in 0 until uniform.components) {
|
|
||||||
var title = uniform.label
|
|
||||||
if (uniform.components > 1) {
|
|
||||||
title = uniform.label + " [" + component + "]"
|
|
||||||
}
|
|
||||||
|
|
||||||
var value = uniform.defaultAt(component)
|
|
||||||
if (NativePostProcessing.hasValue(index, uniform.name)) {
|
|
||||||
value = NativePostProcessing.getValue(index, uniform.name, component)
|
|
||||||
}
|
|
||||||
|
|
||||||
val steps = uniform.steps
|
|
||||||
val step = Math.round((value - uniform.min) / uniform.step)
|
|
||||||
|
|
||||||
addStepSlider(
|
|
||||||
title,
|
|
||||||
container,
|
|
||||||
steps,
|
|
||||||
step,
|
|
||||||
{ position -> uniform.describe(position) },
|
|
||||||
{ emulationFragment.persistPostProcessing() }
|
|
||||||
) { position ->
|
|
||||||
NativePostProcessing.setValue(
|
|
||||||
index,
|
|
||||||
uniform.name,
|
|
||||||
component,
|
|
||||||
uniform.min + position * uniform.step
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addDivider(container: ViewGroup) {
|
fun addDivider(container: ViewGroup) {
|
||||||
val inflater = LayoutInflater.from(emulationFragment.requireContext())
|
val inflater = LayoutInflater.from(emulationFragment.requireContext())
|
||||||
val dividerView = inflater.inflate(R.layout.item_quick_settings_divider, container, false)
|
val dividerView = inflater.inflate(R.layout.item_quick_settings_divider, container, false)
|
||||||
|
|||||||
-36
@@ -1,36 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model
|
|
||||||
|
|
||||||
class FxPresetNameSetting(private val onNamed: (String) -> Unit) : AbstractStringSetting {
|
|
||||||
override val key: String
|
|
||||||
get() = "fx_preset_name"
|
|
||||||
|
|
||||||
override val defaultValue: Any
|
|
||||||
get() = ""
|
|
||||||
|
|
||||||
override val isRuntimeModifiable: Boolean
|
|
||||||
get() = true
|
|
||||||
|
|
||||||
override val pairedSettingKey: String
|
|
||||||
get() = ""
|
|
||||||
|
|
||||||
override val isSwitchable: Boolean
|
|
||||||
get() = false
|
|
||||||
|
|
||||||
override val isSaveable: Boolean
|
|
||||||
get() = true
|
|
||||||
|
|
||||||
override var global: Boolean
|
|
||||||
get() = true
|
|
||||||
set(_) {}
|
|
||||||
|
|
||||||
override fun getString(needsGlobal: Boolean): String = ""
|
|
||||||
|
|
||||||
override fun setString(value: String) = onNamed(value)
|
|
||||||
|
|
||||||
override fun getValueAsString(needsGlobal: Boolean): String = ""
|
|
||||||
|
|
||||||
override fun reset() {}
|
|
||||||
}
|
|
||||||
-67
@@ -1,67 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model
|
|
||||||
|
|
||||||
import org.yuzu.yuzu_emu.utils.NativePostProcessing
|
|
||||||
import kotlin.math.roundToInt
|
|
||||||
|
|
||||||
abstract class FxUniformSetting(
|
|
||||||
protected val index: Int,
|
|
||||||
protected val uniform: NativePostProcessing.Uniform,
|
|
||||||
protected val component: Int
|
|
||||||
) : AbstractSetting {
|
|
||||||
override val key: String
|
|
||||||
get() = "fx_${index}_${uniform.name}_$component"
|
|
||||||
|
|
||||||
override val isRuntimeModifiable: Boolean
|
|
||||||
get() = true
|
|
||||||
|
|
||||||
override val pairedSettingKey: String
|
|
||||||
get() = ""
|
|
||||||
|
|
||||||
override val isSwitchable: Boolean
|
|
||||||
get() = false
|
|
||||||
|
|
||||||
override val isSaveable: Boolean
|
|
||||||
get() = true
|
|
||||||
|
|
||||||
override var global: Boolean
|
|
||||||
get() = true
|
|
||||||
set(_) {}
|
|
||||||
|
|
||||||
protected fun currentValue(): Float {
|
|
||||||
if (NativePostProcessing.hasValue(index, uniform.name)) {
|
|
||||||
return NativePostProcessing.getValue(index, uniform.name, component)
|
|
||||||
}
|
|
||||||
return uniform.defaultAt(component)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun commit(value: Float) {
|
|
||||||
NativePostProcessing.setValue(index, uniform.name, component, value)
|
|
||||||
NativePostProcessing.store()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun reset() = commit(uniform.defaultAt(component))
|
|
||||||
}
|
|
||||||
|
|
||||||
class FxUniformSliderSetting(
|
|
||||||
index: Int,
|
|
||||||
uniform: NativePostProcessing.Uniform,
|
|
||||||
component: Int
|
|
||||||
) : FxUniformSetting(index, uniform, component), AbstractIntSetting {
|
|
||||||
override val defaultValue: Any
|
|
||||||
get() = ((uniform.defaultAt(component) - uniform.min) / uniform.step).roundToInt()
|
|
||||||
|
|
||||||
override fun getInt(needsGlobal: Boolean): Int =
|
|
||||||
((currentValue() - uniform.min) / uniform.step).roundToInt()
|
|
||||||
|
|
||||||
override fun setInt(value: Int) = commit(uniform.min + value * uniform.step)
|
|
||||||
|
|
||||||
override fun getValueAsString(needsGlobal: Boolean): String {
|
|
||||||
if (uniform.kind == NativePostProcessing.KIND_FLOAT) {
|
|
||||||
return String.format("%.3f", currentValue())
|
|
||||||
}
|
|
||||||
return currentValue().roundToInt().toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -12,7 +12,6 @@ object Settings {
|
|||||||
SECTION_SYSTEM(R.string.preferences_system),
|
SECTION_SYSTEM(R.string.preferences_system),
|
||||||
SECTION_RENDERER(R.string.preferences_graphics),
|
SECTION_RENDERER(R.string.preferences_graphics),
|
||||||
SECTION_FRAME_GEN(R.string.frame_gen),
|
SECTION_FRAME_GEN(R.string.frame_gen),
|
||||||
SECTION_POST_PROCESSING(R.string.post_processing),
|
|
||||||
SECTION_PERFORMANCE_STATS(R.string.stats_overlay_options),
|
SECTION_PERFORMANCE_STATS(R.string.stats_overlay_options),
|
||||||
SECTION_INPUT_OVERLAY(R.string.input_overlay_options),
|
SECTION_INPUT_OVERLAY(R.string.input_overlay_options),
|
||||||
SECTION_SOC_OVERLAY(R.string.soc_overlay_options),
|
SECTION_SOC_OVERLAY(R.string.soc_overlay_options),
|
||||||
|
|||||||
-1
@@ -13,7 +13,6 @@ enum class StringSetting(override val key: String) : AbstractStringSetting {
|
|||||||
DEVICE_NAME("device_name"),
|
DEVICE_NAME("device_name"),
|
||||||
LOG_FILTER("log_filter"),
|
LOG_FILTER("log_filter"),
|
||||||
PROGRAM_ARGS("program_args"),
|
PROGRAM_ARGS("program_args"),
|
||||||
POST_SHADER_CHAIN("post_shader_chain"),
|
|
||||||
|
|
||||||
WEB_TOKEN("eden_token"),
|
WEB_TOKEN("eden_token"),
|
||||||
WEB_USERNAME("eden_username")
|
WEB_USERNAME("eden_username")
|
||||||
|
|||||||
-13
@@ -1,13 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model.view
|
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
|
|
||||||
class FxButtonSetting(
|
|
||||||
@StringRes titleId: Int,
|
|
||||||
val onClick: () -> Unit
|
|
||||||
) : SettingsItem(emptySetting, titleId, "", 0, "") {
|
|
||||||
override val type = TYPE_FX_BUTTON
|
|
||||||
}
|
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model.view
|
|
||||||
|
|
||||||
class FxPresetSetting(
|
|
||||||
titleString: String,
|
|
||||||
descriptionString: String = "",
|
|
||||||
val deletable: Boolean = false,
|
|
||||||
val onApply: () -> Unit,
|
|
||||||
val onDelete: () -> Unit = {}
|
|
||||||
) : SettingsItem(emptySetting, 0, titleString, 0, descriptionString) {
|
|
||||||
override val type = TYPE_FX_PRESET
|
|
||||||
}
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model.view
|
|
||||||
|
|
||||||
import org.yuzu.yuzu_emu.utils.NativePostProcessing
|
|
||||||
|
|
||||||
class FxShaderCardSetting(
|
|
||||||
titleString: String,
|
|
||||||
descriptionString: String,
|
|
||||||
val index: Int,
|
|
||||||
val expanded: Boolean,
|
|
||||||
val uniforms: List<NativePostProcessing.Uniform>,
|
|
||||||
val onToggle: () -> Unit,
|
|
||||||
val onRemove: () -> Unit,
|
|
||||||
val onReset: () -> Unit
|
|
||||||
) : SettingsItem(emptySetting, 0, titleString, 0, descriptionString) {
|
|
||||||
override val type = TYPE_FX_SHADER
|
|
||||||
}
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model.view
|
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
|
|
||||||
class FxToolbarSetting(
|
|
||||||
@StringRes val addLabelId: Int,
|
|
||||||
val listOpen: Boolean,
|
|
||||||
val presetLabel: String,
|
|
||||||
val hasEffects: Boolean,
|
|
||||||
val createPreset: StringInputSetting,
|
|
||||||
val onAdd: () -> Unit,
|
|
||||||
val onPresets: () -> Unit,
|
|
||||||
val onRemoveAll: () -> Unit
|
|
||||||
) : SettingsItem(emptySetting, 0, "", 0, "") {
|
|
||||||
override val type = TYPE_FX_TOOLBAR
|
|
||||||
}
|
|
||||||
-4
@@ -144,10 +144,6 @@ abstract class SettingsItem(
|
|||||||
const val TYPE_LAUNCHABLE = 13
|
const val TYPE_LAUNCHABLE = 13
|
||||||
const val TYPE_PATH = 14
|
const val TYPE_PATH = 14
|
||||||
const val TYPE_GPU_UNSWIZZLE = 15
|
const val TYPE_GPU_UNSWIZZLE = 15
|
||||||
const val TYPE_FX_TOOLBAR = 16
|
|
||||||
const val TYPE_FX_PRESET = 17
|
|
||||||
const val TYPE_FX_SHADER = 18
|
|
||||||
const val TYPE_FX_BUTTON = 19
|
|
||||||
|
|
||||||
const val FASTMEM_COMBINED = "fastmem_combined"
|
const val FASTMEM_COMBINED = "fastmem_combined"
|
||||||
const val GPU_UNSWIZZLE_COMBINED = "gpu_unswizzle_combined"
|
const val GPU_UNSWIZZLE_COMBINED = "gpu_unswizzle_combined"
|
||||||
|
|||||||
-32
@@ -23,10 +23,6 @@ import com.google.android.material.timepicker.TimeFormat
|
|||||||
import org.yuzu.yuzu_emu.R
|
import org.yuzu.yuzu_emu.R
|
||||||
import org.yuzu.yuzu_emu.SettingsNavigationDirections
|
import org.yuzu.yuzu_emu.SettingsNavigationDirections
|
||||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
|
import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
|
||||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxButtonBinding
|
|
||||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxPresetBinding
|
|
||||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxShaderBinding
|
|
||||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxToolbarBinding
|
|
||||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingInputBinding
|
import org.yuzu.yuzu_emu.databinding.ListItemSettingInputBinding
|
||||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingSwitchBinding
|
import org.yuzu.yuzu_emu.databinding.ListItemSettingSwitchBinding
|
||||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingsHeaderBinding
|
import org.yuzu.yuzu_emu.databinding.ListItemSettingsHeaderBinding
|
||||||
@@ -110,34 +106,6 @@ class SettingsAdapter(
|
|||||||
GpuUnswizzleViewHolder(ListItemSettingBinding.inflate(inflater), this)
|
GpuUnswizzleViewHolder(ListItemSettingBinding.inflate(inflater), this)
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsItem.TYPE_FX_TOOLBAR -> {
|
|
||||||
FxToolbarViewHolder(
|
|
||||||
ListItemSettingFxToolbarBinding.inflate(inflater, parent, false),
|
|
||||||
this
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsItem.TYPE_FX_PRESET -> {
|
|
||||||
FxPresetViewHolder(
|
|
||||||
ListItemSettingFxPresetBinding.inflate(inflater, parent, false),
|
|
||||||
this
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsItem.TYPE_FX_SHADER -> {
|
|
||||||
FxShaderCardViewHolder(
|
|
||||||
ListItemSettingFxShaderBinding.inflate(inflater, parent, false),
|
|
||||||
this
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsItem.TYPE_FX_BUTTON -> {
|
|
||||||
FxButtonViewHolder(
|
|
||||||
ListItemSettingFxButtonBinding.inflate(inflater, parent, false),
|
|
||||||
this
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
HeaderViewHolder(ListItemSettingsHeaderBinding.inflate(inflater), this)
|
HeaderViewHolder(ListItemSettingsHeaderBinding.inflate(inflater), this)
|
||||||
}
|
}
|
||||||
|
|||||||
-214
@@ -18,7 +18,6 @@ import org.yuzu.yuzu_emu.features.input.model.NpadStyleIndex
|
|||||||
import org.yuzu.yuzu_emu.features.settings.model.AbstractBooleanSetting
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractBooleanSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.FxPresetNameSetting
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.ByteSetting
|
import org.yuzu.yuzu_emu.features.settings.model.ByteSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.LongSetting
|
import org.yuzu.yuzu_emu.features.settings.model.LongSetting
|
||||||
@@ -31,7 +30,6 @@ import org.yuzu.yuzu_emu.features.settings.model.view.*
|
|||||||
import org.yuzu.yuzu_emu.utils.InputHandler
|
import org.yuzu.yuzu_emu.utils.InputHandler
|
||||||
import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
|
import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
|
||||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||||
import org.yuzu.yuzu_emu.utils.NativePostProcessing
|
|
||||||
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
|
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
|
||||||
import org.yuzu.yuzu_emu.utils.FullscreenHelper
|
import org.yuzu.yuzu_emu.utils.FullscreenHelper
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
@@ -46,14 +44,6 @@ class SettingsFragmentPresenter(
|
|||||||
) {
|
) {
|
||||||
private var settingsList = ArrayList<SettingsItem>()
|
private var settingsList = ArrayList<SettingsItem>()
|
||||||
|
|
||||||
private val expandedShaderSlots = mutableSetOf<Int>()
|
|
||||||
|
|
||||||
private var shaderPickerOpen = false
|
|
||||||
|
|
||||||
private var presetPickerOpen = false
|
|
||||||
|
|
||||||
private var postProcessingSynced = false
|
|
||||||
|
|
||||||
private val context get() = YuzuApplication.appContext
|
private val context get() = YuzuApplication.appContext
|
||||||
|
|
||||||
// Extension for altering settings list based on each setting's properties
|
// Extension for altering settings list based on each setting's properties
|
||||||
@@ -173,7 +163,6 @@ class SettingsFragmentPresenter(
|
|||||||
MenuTag.SECTION_SYSTEM -> addSystemSettings(sl)
|
MenuTag.SECTION_SYSTEM -> addSystemSettings(sl)
|
||||||
MenuTag.SECTION_RENDERER -> addGraphicsSettings(sl)
|
MenuTag.SECTION_RENDERER -> addGraphicsSettings(sl)
|
||||||
MenuTag.SECTION_FRAME_GEN -> addFrameGenSettings(sl)
|
MenuTag.SECTION_FRAME_GEN -> addFrameGenSettings(sl)
|
||||||
MenuTag.SECTION_POST_PROCESSING -> addPostProcessingSettings(sl)
|
|
||||||
MenuTag.SECTION_PERFORMANCE_STATS -> addPerformanceOverlaySettings(sl)
|
MenuTag.SECTION_PERFORMANCE_STATS -> addPerformanceOverlaySettings(sl)
|
||||||
MenuTag.SECTION_SOC_OVERLAY -> addSocOverlaySettings(sl)
|
MenuTag.SECTION_SOC_OVERLAY -> addSocOverlaySettings(sl)
|
||||||
MenuTag.SECTION_INPUT_OVERLAY -> addInputOverlaySettings(sl)
|
MenuTag.SECTION_INPUT_OVERLAY -> addInputOverlaySettings(sl)
|
||||||
@@ -201,209 +190,6 @@ class SettingsFragmentPresenter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addPostProcessingSettings(sl: ArrayList<SettingsItem>) {
|
|
||||||
if (!postProcessingSynced) {
|
|
||||||
postProcessingSynced = true
|
|
||||||
NativePostProcessing.reload()
|
|
||||||
}
|
|
||||||
|
|
||||||
val usable = NativePostProcessing.catalog().filter { it.valid }
|
|
||||||
|
|
||||||
sl.apply {
|
|
||||||
if (usable.isEmpty()) {
|
|
||||||
add(
|
|
||||||
RunnableSetting(
|
|
||||||
titleId = R.string.post_processing_empty,
|
|
||||||
descriptionString = NativePostProcessing.getShaderDirectory(),
|
|
||||||
isRunnable = false
|
|
||||||
) {}
|
|
||||||
)
|
|
||||||
return@apply
|
|
||||||
}
|
|
||||||
|
|
||||||
val labels = mutableListOf<String>()
|
|
||||||
val summaries = mutableListOf<String>()
|
|
||||||
val files = mutableListOf<String>()
|
|
||||||
val techniques = mutableListOf<String>()
|
|
||||||
for (effect in usable) {
|
|
||||||
for (technique in effect.techniques) {
|
|
||||||
if (effect.techniques.size == 1) {
|
|
||||||
labels.add(effect.label)
|
|
||||||
} else {
|
|
||||||
labels.add(effect.label + " \u00b7 " + technique)
|
|
||||||
}
|
|
||||||
summaries.add(effect.description)
|
|
||||||
files.add(effect.file)
|
|
||||||
techniques.add(technique)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val chain = NativePostProcessing.chain()
|
|
||||||
val active = NativePostProcessing.getActivePreset()
|
|
||||||
|
|
||||||
var addLabel = R.string.post_processing_add
|
|
||||||
if (chain.isNotEmpty()) {
|
|
||||||
addLabel = R.string.post_processing_open_list
|
|
||||||
}
|
|
||||||
if (shaderPickerOpen) {
|
|
||||||
addLabel = R.string.post_processing_close_list
|
|
||||||
}
|
|
||||||
|
|
||||||
var presetLabel = context.getString(R.string.post_processing_presets)
|
|
||||||
if (active.isNotEmpty()) {
|
|
||||||
presetLabel = active
|
|
||||||
}
|
|
||||||
|
|
||||||
val createPreset = StringInputSetting(
|
|
||||||
setting = FxPresetNameSetting { name ->
|
|
||||||
NativePostProcessing.savePreset(name, "")
|
|
||||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
|
||||||
},
|
|
||||||
titleId = R.string.post_processing_preset_new,
|
|
||||||
descriptionId = R.string.post_processing_preset_new_description,
|
|
||||||
validator = { it != null && it.isNotBlank() && !it.contains('=') },
|
|
||||||
errorId = R.string.post_processing_preset_name_invalid
|
|
||||||
)
|
|
||||||
|
|
||||||
add(
|
|
||||||
FxToolbarSetting(
|
|
||||||
addLabelId = addLabel,
|
|
||||||
listOpen = shaderPickerOpen,
|
|
||||||
presetLabel = presetLabel,
|
|
||||||
hasEffects = chain.isNotEmpty(),
|
|
||||||
createPreset = createPreset,
|
|
||||||
onAdd = {
|
|
||||||
shaderPickerOpen = !shaderPickerOpen
|
|
||||||
presetPickerOpen = false
|
|
||||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
|
||||||
},
|
|
||||||
onPresets = {
|
|
||||||
presetPickerOpen = !presetPickerOpen
|
|
||||||
shaderPickerOpen = false
|
|
||||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
|
||||||
},
|
|
||||||
onRemoveAll = {
|
|
||||||
NativePostProcessing.clearChain()
|
|
||||||
NativePostProcessing.clearPreset()
|
|
||||||
NativePostProcessing.store()
|
|
||||||
expandedShaderSlots.clear()
|
|
||||||
shaderPickerOpen = false
|
|
||||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (shaderPickerOpen) {
|
|
||||||
for (choice in labels.indices) {
|
|
||||||
add(
|
|
||||||
RunnableSetting(
|
|
||||||
titleString = labels[choice],
|
|
||||||
descriptionString = summaries[choice],
|
|
||||||
isRunnable = true
|
|
||||||
) {
|
|
||||||
NativePostProcessing.append(files[choice], techniques[choice])
|
|
||||||
NativePostProcessing.store()
|
|
||||||
shaderPickerOpen = false
|
|
||||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (presetPickerOpen) {
|
|
||||||
add(
|
|
||||||
FxPresetSetting(
|
|
||||||
titleString = context.getString(R.string.post_processing_preset_none),
|
|
||||||
onApply = {
|
|
||||||
NativePostProcessing.clearPreset()
|
|
||||||
presetPickerOpen = false
|
|
||||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
for (preset in NativePostProcessing.presets()) {
|
|
||||||
add(
|
|
||||||
FxPresetSetting(
|
|
||||||
titleString = preset.name,
|
|
||||||
descriptionString = preset.description,
|
|
||||||
deletable = !preset.bundled,
|
|
||||||
onApply = {
|
|
||||||
NativePostProcessing.applyPreset(preset.name)
|
|
||||||
NativePostProcessing.store()
|
|
||||||
presetPickerOpen = false
|
|
||||||
expandedShaderSlots.clear()
|
|
||||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
|
||||||
},
|
|
||||||
onDelete = {
|
|
||||||
NativePostProcessing.deletePreset(preset.name)
|
|
||||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (active.isNotEmpty()) {
|
|
||||||
add(
|
|
||||||
FxButtonSetting(titleId = R.string.post_processing_preset_reset) {
|
|
||||||
NativePostProcessing.applyPreset(active)
|
|
||||||
NativePostProcessing.store()
|
|
||||||
expandedShaderSlots.clear()
|
|
||||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (index in chain.indices) {
|
|
||||||
val entry = chain[index]
|
|
||||||
val effect = usable.firstOrNull { it.file == entry.file }
|
|
||||||
|
|
||||||
var header = entry.file
|
|
||||||
var summary = ""
|
|
||||||
var uniforms = emptyList<NativePostProcessing.Uniform>()
|
|
||||||
if (effect != null) {
|
|
||||||
header = effect.label
|
|
||||||
if (effect.techniques.size > 1) {
|
|
||||||
header = effect.label + " \u00b7 " + entry.technique
|
|
||||||
}
|
|
||||||
summary = effect.description
|
|
||||||
uniforms = effect.uniforms
|
|
||||||
}
|
|
||||||
|
|
||||||
val isOpen = expandedShaderSlots.contains(index)
|
|
||||||
|
|
||||||
add(
|
|
||||||
FxShaderCardSetting(
|
|
||||||
titleString = header,
|
|
||||||
descriptionString = summary,
|
|
||||||
index = index,
|
|
||||||
expanded = isOpen,
|
|
||||||
uniforms = uniforms,
|
|
||||||
onToggle = {
|
|
||||||
if (isOpen) {
|
|
||||||
expandedShaderSlots.remove(index)
|
|
||||||
} else {
|
|
||||||
expandedShaderSlots.add(index)
|
|
||||||
}
|
|
||||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
|
||||||
},
|
|
||||||
onRemove = {
|
|
||||||
NativePostProcessing.remove(index)
|
|
||||||
NativePostProcessing.store()
|
|
||||||
expandedShaderSlots.clear()
|
|
||||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
|
||||||
},
|
|
||||||
onReset = {
|
|
||||||
NativePostProcessing.resetValues(index)
|
|
||||||
NativePostProcessing.store()
|
|
||||||
settingsViewModel.setReloadListAndNotifyDataset(true)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addConfigSettings(sl: ArrayList<SettingsItem>) {
|
private fun addConfigSettings(sl: ArrayList<SettingsItem>) {
|
||||||
sl.apply {
|
sl.apply {
|
||||||
add(
|
add(
|
||||||
|
|||||||
-28
@@ -1,28 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.ui.viewholder
|
|
||||||
|
|
||||||
import android.view.View
|
|
||||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxButtonBinding
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.view.FxButtonSetting
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
|
|
||||||
|
|
||||||
class FxButtonViewHolder(
|
|
||||||
val binding: ListItemSettingFxButtonBinding,
|
|
||||||
adapter: SettingsAdapter
|
|
||||||
) : SettingViewHolder(binding.root, adapter) {
|
|
||||||
private lateinit var setting: FxButtonSetting
|
|
||||||
|
|
||||||
override fun bind(item: SettingsItem) {
|
|
||||||
setting = item as FxButtonSetting
|
|
||||||
|
|
||||||
binding.fxButton.text = item.title
|
|
||||||
binding.fxButton.setOnClickListener { setting.onClick.invoke() }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onClick(clicked: View) {}
|
|
||||||
|
|
||||||
override fun onLongClick(clicked: View): Boolean = true
|
|
||||||
}
|
|
||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.ui.viewholder
|
|
||||||
|
|
||||||
import android.view.View
|
|
||||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxPresetBinding
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.view.FxPresetSetting
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
|
|
||||||
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
|
|
||||||
|
|
||||||
class FxPresetViewHolder(
|
|
||||||
val binding: ListItemSettingFxPresetBinding,
|
|
||||||
adapter: SettingsAdapter
|
|
||||||
) : SettingViewHolder(binding.root, adapter) {
|
|
||||||
private lateinit var setting: FxPresetSetting
|
|
||||||
|
|
||||||
override fun bind(item: SettingsItem) {
|
|
||||||
setting = item as FxPresetSetting
|
|
||||||
|
|
||||||
binding.presetName.text = item.title
|
|
||||||
binding.presetDescription.text = item.description
|
|
||||||
binding.presetDescription.setVisible(item.description.isNotEmpty())
|
|
||||||
|
|
||||||
binding.presetRow.setOnClickListener { setting.onApply.invoke() }
|
|
||||||
|
|
||||||
binding.presetDelete.setVisible(setting.deletable)
|
|
||||||
binding.presetDelete.setOnClickListener { setting.onDelete.invoke() }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onClick(clicked: View) {}
|
|
||||||
|
|
||||||
override fun onLongClick(clicked: View): Boolean = true
|
|
||||||
}
|
|
||||||
-100
@@ -1,100 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.ui.viewholder
|
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import org.yuzu.yuzu_emu.databinding.ItemSettingFxActionsBinding
|
|
||||||
import org.yuzu.yuzu_emu.databinding.ItemSettingFxSliderBinding
|
|
||||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxShaderBinding
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.FxUniformSliderSetting
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.view.FxShaderCardSetting
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
|
|
||||||
import org.yuzu.yuzu_emu.utils.NativePostProcessing
|
|
||||||
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
|
|
||||||
|
|
||||||
class FxShaderCardViewHolder(
|
|
||||||
val binding: ListItemSettingFxShaderBinding,
|
|
||||||
adapter: SettingsAdapter
|
|
||||||
) : SettingViewHolder(binding.root, adapter) {
|
|
||||||
private lateinit var setting: FxShaderCardSetting
|
|
||||||
|
|
||||||
override fun bind(item: SettingsItem) {
|
|
||||||
setting = item as FxShaderCardSetting
|
|
||||||
|
|
||||||
binding.shaderTitle.text = item.title
|
|
||||||
binding.shaderSummary.text = item.description
|
|
||||||
binding.shaderSummary.setVisible(item.description.isNotEmpty())
|
|
||||||
|
|
||||||
var rotation = 0f
|
|
||||||
if (setting.expanded) {
|
|
||||||
rotation = 180f
|
|
||||||
}
|
|
||||||
binding.shaderExpand.rotation = rotation
|
|
||||||
|
|
||||||
binding.shaderHeader.setOnClickListener { setting.onToggle.invoke() }
|
|
||||||
binding.shaderRemove.setOnClickListener { setting.onRemove.invoke() }
|
|
||||||
|
|
||||||
binding.shaderBody.removeAllViews()
|
|
||||||
binding.shaderBody.setVisible(setting.expanded)
|
|
||||||
if (!setting.expanded) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val inflater = LayoutInflater.from(binding.root.context)
|
|
||||||
for (uniform in setting.uniforms) {
|
|
||||||
if (uniform.uiType == NativePostProcessing.UI_HIDDEN) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for (component in 0 until uniform.components) {
|
|
||||||
addSlider(inflater, uniform, component)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addActions(inflater)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addSlider(
|
|
||||||
inflater: LayoutInflater,
|
|
||||||
uniform: NativePostProcessing.Uniform,
|
|
||||||
component: Int
|
|
||||||
) {
|
|
||||||
val row = ItemSettingFxSliderBinding.inflate(inflater, binding.shaderBody, false)
|
|
||||||
val value = FxUniformSliderSetting(setting.index, uniform, component)
|
|
||||||
|
|
||||||
var title = uniform.label
|
|
||||||
if (uniform.components > 1) {
|
|
||||||
title = uniform.label + " [" + component + "]"
|
|
||||||
}
|
|
||||||
row.fxSliderTitle.text = title
|
|
||||||
|
|
||||||
val steps = uniform.steps.toFloat()
|
|
||||||
row.fxSlider.valueFrom = 0f
|
|
||||||
row.fxSlider.valueTo = steps
|
|
||||||
row.fxSlider.stepSize = 1f
|
|
||||||
row.fxSlider.value = value.getInt(false).toFloat().coerceIn(0f, steps)
|
|
||||||
row.fxSliderValue.text = uniform.describe(row.fxSlider.value.toInt())
|
|
||||||
|
|
||||||
row.fxSlider.addOnChangeListener { _, position, fromUser ->
|
|
||||||
if (fromUser) {
|
|
||||||
value.setInt(position.toInt())
|
|
||||||
row.fxSliderValue.text = uniform.describe(position.toInt())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.shaderBody.addView(row.root)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addActions(inflater: LayoutInflater) {
|
|
||||||
val row = ItemSettingFxActionsBinding.inflate(inflater, binding.shaderBody, false)
|
|
||||||
|
|
||||||
row.fxReset.setOnClickListener { setting.onReset.invoke() }
|
|
||||||
|
|
||||||
binding.shaderBody.addView(row.root)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onClick(clicked: View) {}
|
|
||||||
|
|
||||||
override fun onLongClick(clicked: View): Boolean = true
|
|
||||||
}
|
|
||||||
-57
@@ -1,57 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.ui.viewholder
|
|
||||||
|
|
||||||
import android.content.res.ColorStateList
|
|
||||||
import android.view.View
|
|
||||||
import com.google.android.material.color.MaterialColors
|
|
||||||
import org.yuzu.yuzu_emu.R
|
|
||||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxToolbarBinding
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.view.FxToolbarSetting
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
|
|
||||||
|
|
||||||
class FxToolbarViewHolder(
|
|
||||||
val binding: ListItemSettingFxToolbarBinding,
|
|
||||||
adapter: SettingsAdapter
|
|
||||||
) : SettingViewHolder(binding.root, adapter) {
|
|
||||||
private lateinit var setting: FxToolbarSetting
|
|
||||||
|
|
||||||
override fun bind(item: SettingsItem) {
|
|
||||||
setting = item as FxToolbarSetting
|
|
||||||
|
|
||||||
binding.fxAdd.setText(setting.addLabelId)
|
|
||||||
var addIcon = R.drawable.ic_add
|
|
||||||
if (setting.listOpen) {
|
|
||||||
addIcon = R.drawable.ic_clear
|
|
||||||
}
|
|
||||||
binding.fxAdd.setIconResource(addIcon)
|
|
||||||
binding.fxAdd.setOnClickListener { setting.onAdd.invoke() }
|
|
||||||
|
|
||||||
binding.fxPresets.text = setting.presetLabel
|
|
||||||
binding.fxPresets.setOnClickListener { setting.onPresets.invoke() }
|
|
||||||
|
|
||||||
binding.fxCreatePreset.isEnabled = setting.hasEffects
|
|
||||||
binding.fxCreatePreset.setOnClickListener {
|
|
||||||
adapter.onStringInputClick(setting.createPreset, bindingAdapterPosition)
|
|
||||||
}
|
|
||||||
|
|
||||||
val removeBackground = MaterialColors.getColor(
|
|
||||||
binding.fxRemoveAll,
|
|
||||||
com.google.android.material.R.attr.colorErrorContainer
|
|
||||||
)
|
|
||||||
val removeForeground = MaterialColors.getColor(
|
|
||||||
binding.fxRemoveAll,
|
|
||||||
com.google.android.material.R.attr.colorOnErrorContainer
|
|
||||||
)
|
|
||||||
binding.fxRemoveAll.backgroundTintList = ColorStateList.valueOf(removeBackground)
|
|
||||||
binding.fxRemoveAll.iconTint = ColorStateList.valueOf(removeForeground)
|
|
||||||
binding.fxRemoveAll.isEnabled = setting.hasEffects
|
|
||||||
binding.fxRemoveAll.setOnClickListener { setting.onRemoveAll.invoke() }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onClick(clicked: View) {}
|
|
||||||
|
|
||||||
override fun onLongClick(clicked: View): Boolean = true
|
|
||||||
}
|
|
||||||
@@ -94,7 +94,6 @@ import org.yuzu.yuzu_emu.utils.InputHandler
|
|||||||
import org.yuzu.yuzu_emu.utils.Log
|
import org.yuzu.yuzu_emu.utils.Log
|
||||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||||
import org.yuzu.yuzu_emu.utils.NativeFreedrenoConfig
|
import org.yuzu.yuzu_emu.utils.NativeFreedrenoConfig
|
||||||
import org.yuzu.yuzu_emu.utils.NativePostProcessing
|
|
||||||
import org.yuzu.yuzu_emu.utils.ViewUtils
|
import org.yuzu.yuzu_emu.utils.ViewUtils
|
||||||
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
|
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
|
||||||
import org.yuzu.yuzu_emu.utils.collect
|
import org.yuzu.yuzu_emu.utils.collect
|
||||||
@@ -884,8 +883,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
if (shouldUseCustom) {
|
if (shouldUseCustom) {
|
||||||
SettingsFile.loadCustomConfig(game!!)
|
SettingsFile.loadCustomConfig(game!!)
|
||||||
}
|
}
|
||||||
refreshPostProcessing()
|
|
||||||
addQuickSettings()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1090,34 +1087,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun withPerGameConfig(create: Boolean, action: () -> Unit) {
|
|
||||||
val target = game
|
|
||||||
var owned = false
|
|
||||||
if (target != null && !NativeConfig.isPerGameConfigLoaded()) {
|
|
||||||
if (create || SettingsFile.getCustomSettingsFile(target).exists()) {
|
|
||||||
SettingsFile.loadCustomConfig(target)
|
|
||||||
owned = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
action()
|
|
||||||
if (owned) {
|
|
||||||
NativeConfig.unloadPerGameConfig()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun refreshPostProcessing() = withPerGameConfig(false) {
|
|
||||||
NativePostProcessing.reload()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun persistPostProcessing() = withPerGameConfig(true) {
|
|
||||||
NativePostProcessing.persist()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun editPostProcessing(action: () -> Unit) = withPerGameConfig(true) {
|
|
||||||
action()
|
|
||||||
NativePostProcessing.persist()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addQuickSettings() {
|
private fun addQuickSettings() {
|
||||||
binding.quickSettingsSheet.apply {
|
binding.quickSettingsSheet.apply {
|
||||||
val container = binding.quickSettingsSheet.findViewById<ViewGroup>(R.id.quick_settings_container)
|
val container = binding.quickSettingsSheet.findViewById<ViewGroup>(R.id.quick_settings_container)
|
||||||
@@ -1225,10 +1194,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
R.array.rendererAntiAliasingNames,
|
R.array.rendererAntiAliasingNames,
|
||||||
R.array.rendererAntiAliasingValues
|
R.array.rendererAntiAliasingValues
|
||||||
)
|
)
|
||||||
|
|
||||||
quickSettings.addPostProcessing(container) {
|
|
||||||
addQuickSettings()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -383,20 +383,6 @@ class GamePropertiesFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
|
||||||
SubmenuProperty(
|
|
||||||
R.string.post_processing,
|
|
||||||
R.string.post_processing_per_game_description,
|
|
||||||
R.drawable.ic_post_processing,
|
|
||||||
action = {
|
|
||||||
val action = HomeNavigationDirections.actionGlobalSettingsActivity(
|
|
||||||
args.game,
|
|
||||||
Settings.MenuTag.SECTION_POST_PROCESSING
|
|
||||||
)
|
|
||||||
binding.root.findNavController().navigate(action)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (GpuDriverHelper.isAdrenoGpu()) {
|
if (GpuDriverHelper.isAdrenoGpu()) {
|
||||||
add(
|
add(
|
||||||
|
|||||||
@@ -171,20 +171,6 @@ class HomeSettingsFragment : Fragment() {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
add(
|
|
||||||
HomeSetting(
|
|
||||||
R.string.post_processing,
|
|
||||||
R.string.post_processing_description,
|
|
||||||
R.drawable.ic_post_processing,
|
|
||||||
{
|
|
||||||
val action = HomeNavigationDirections.actionGlobalSettingsActivity(
|
|
||||||
null,
|
|
||||||
Settings.MenuTag.SECTION_POST_PROCESSING
|
|
||||||
)
|
|
||||||
binding.root.findNavController().navigate(action)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
add(
|
add(
|
||||||
HomeSetting(
|
HomeSetting(
|
||||||
R.string.lossless_scaling,
|
R.string.lossless_scaling,
|
||||||
|
|||||||
@@ -1,242 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.utils
|
|
||||||
|
|
||||||
import org.json.JSONArray
|
|
||||||
import org.json.JSONObject
|
|
||||||
|
|
||||||
object NativePostProcessing {
|
|
||||||
const val KIND_BOOL = 0
|
|
||||||
const val KIND_INT = 1
|
|
||||||
const val KIND_FLOAT = 2
|
|
||||||
|
|
||||||
const val UI_HIDDEN = 0
|
|
||||||
const val UI_SLIDER = 1
|
|
||||||
const val UI_DRAG = 2
|
|
||||||
const val UI_COMBO = 3
|
|
||||||
const val UI_RADIO = 4
|
|
||||||
const val UI_CHECKBOX = 5
|
|
||||||
const val UI_COLOR = 6
|
|
||||||
const val UI_INPUT_BOX = 7
|
|
||||||
|
|
||||||
external fun getCatalogJson(): String
|
|
||||||
|
|
||||||
external fun getChainJson(): String
|
|
||||||
|
|
||||||
external fun append(file: String, technique: String)
|
|
||||||
|
|
||||||
external fun replace(index: Int, file: String, technique: String)
|
|
||||||
|
|
||||||
external fun remove(index: Int)
|
|
||||||
|
|
||||||
external fun move(index: Int, delta: Int)
|
|
||||||
|
|
||||||
external fun resetValues(index: Int)
|
|
||||||
|
|
||||||
external fun getValue(index: Int, uniform: String, component: Int): Float
|
|
||||||
|
|
||||||
external fun hasValue(index: Int, uniform: String): Boolean
|
|
||||||
|
|
||||||
external fun setValue(index: Int, uniform: String, component: Int, value: Float)
|
|
||||||
|
|
||||||
external fun store()
|
|
||||||
|
|
||||||
external fun reload()
|
|
||||||
|
|
||||||
external fun clearChain()
|
|
||||||
|
|
||||||
external fun getPresetsJson(): String
|
|
||||||
|
|
||||||
external fun getActivePreset(): String
|
|
||||||
|
|
||||||
external fun isPresetModified(): Boolean
|
|
||||||
|
|
||||||
external fun applyPreset(name: String): Boolean
|
|
||||||
|
|
||||||
external fun savePreset(name: String, description: String): Boolean
|
|
||||||
|
|
||||||
external fun deletePreset(name: String): Boolean
|
|
||||||
|
|
||||||
external fun clearPreset()
|
|
||||||
|
|
||||||
external fun isEnabled(): Boolean
|
|
||||||
|
|
||||||
external fun setEnabled(enabled: Boolean)
|
|
||||||
|
|
||||||
external fun getPresetDirectory(): String
|
|
||||||
|
|
||||||
fun persist() {
|
|
||||||
val perGame = NativeConfig.isPerGameConfigLoaded()
|
|
||||||
store()
|
|
||||||
if (perGame) {
|
|
||||||
NativeConfig.savePerGameConfig()
|
|
||||||
} else {
|
|
||||||
NativeConfig.saveGlobalConfig()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
external fun getShaderDirectory(): String
|
|
||||||
|
|
||||||
data class Uniform(
|
|
||||||
val name: String,
|
|
||||||
val label: String,
|
|
||||||
val tooltip: String,
|
|
||||||
val category: String,
|
|
||||||
val kind: Int,
|
|
||||||
val uiType: Int,
|
|
||||||
val components: Int,
|
|
||||||
val min: Float,
|
|
||||||
val max: Float,
|
|
||||||
val step: Float,
|
|
||||||
val items: List<String>,
|
|
||||||
val defaults: List<Float>
|
|
||||||
) {
|
|
||||||
val steps: Int
|
|
||||||
get() {
|
|
||||||
val span = max - min
|
|
||||||
if (step <= 0f) {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
val count = Math.round(span / step)
|
|
||||||
if (count < 1) {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return count
|
|
||||||
}
|
|
||||||
|
|
||||||
fun describe(position: Int): String {
|
|
||||||
val value = min + position * step
|
|
||||||
if (kind == NativePostProcessing.KIND_FLOAT) {
|
|
||||||
return String.format("%.3f", value)
|
|
||||||
}
|
|
||||||
return Math.round(value).toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun defaultAt(component: Int): Float {
|
|
||||||
if (component < defaults.size) {
|
|
||||||
return defaults[component]
|
|
||||||
}
|
|
||||||
return 0f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class Effect(
|
|
||||||
val file: String,
|
|
||||||
val name: String,
|
|
||||||
val label: String,
|
|
||||||
val description: String,
|
|
||||||
val error: String,
|
|
||||||
val techniques: List<String>,
|
|
||||||
val uniforms: List<Uniform>
|
|
||||||
) {
|
|
||||||
val valid: Boolean
|
|
||||||
get() = error.isEmpty() && techniques.isNotEmpty()
|
|
||||||
}
|
|
||||||
|
|
||||||
data class ChainEntry(val file: String, val technique: String)
|
|
||||||
|
|
||||||
data class Preset(
|
|
||||||
val name: String,
|
|
||||||
val description: String,
|
|
||||||
val bundled: Boolean
|
|
||||||
)
|
|
||||||
|
|
||||||
fun presets(): List<Preset> {
|
|
||||||
val out = mutableListOf<Preset>()
|
|
||||||
val array = JSONArray(getPresetsJson())
|
|
||||||
for (i in 0 until array.length()) {
|
|
||||||
val obj = array.getJSONObject(i)
|
|
||||||
out.add(
|
|
||||||
Preset(
|
|
||||||
name = obj.optString("name"),
|
|
||||||
description = obj.optString("description"),
|
|
||||||
bundled = obj.optBoolean("bundled")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
fun catalog(): List<Effect> {
|
|
||||||
val out = mutableListOf<Effect>()
|
|
||||||
val array = JSONArray(getCatalogJson())
|
|
||||||
for (i in 0 until array.length()) {
|
|
||||||
val obj = array.getJSONObject(i)
|
|
||||||
out.add(
|
|
||||||
Effect(
|
|
||||||
file = obj.optString("file"),
|
|
||||||
name = obj.optString("name"),
|
|
||||||
label = obj.optString("label"),
|
|
||||||
description = obj.optString("description"),
|
|
||||||
error = obj.optString("error"),
|
|
||||||
techniques = obj.optJSONArray("techniques").toStringList(),
|
|
||||||
uniforms = obj.optJSONArray("uniforms").toUniformList()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
fun chain(): List<ChainEntry> {
|
|
||||||
val out = mutableListOf<ChainEntry>()
|
|
||||||
val array = JSONArray(getChainJson())
|
|
||||||
for (i in 0 until array.length()) {
|
|
||||||
val obj = array.getJSONObject(i)
|
|
||||||
out.add(ChainEntry(obj.optString("file"), obj.optString("technique")))
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
fun findEffect(file: String): Effect? = catalog().firstOrNull { it.file == file }
|
|
||||||
|
|
||||||
private fun JSONArray?.toStringList(): List<String> {
|
|
||||||
if (this == null) {
|
|
||||||
return emptyList()
|
|
||||||
}
|
|
||||||
val out = mutableListOf<String>()
|
|
||||||
for (i in 0 until length()) {
|
|
||||||
out.add(optString(i))
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun JSONArray?.toFloatList(): List<Float> {
|
|
||||||
if (this == null) {
|
|
||||||
return emptyList()
|
|
||||||
}
|
|
||||||
val out = mutableListOf<Float>()
|
|
||||||
for (i in 0 until length()) {
|
|
||||||
out.add(optDouble(i, 0.0).toFloat())
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun JSONArray?.toUniformList(): List<Uniform> {
|
|
||||||
if (this == null) {
|
|
||||||
return emptyList()
|
|
||||||
}
|
|
||||||
val out = mutableListOf<Uniform>()
|
|
||||||
for (i in 0 until length()) {
|
|
||||||
val obj: JSONObject = optJSONObject(i) ?: continue
|
|
||||||
out.add(
|
|
||||||
Uniform(
|
|
||||||
name = obj.optString("name"),
|
|
||||||
label = obj.optString("label"),
|
|
||||||
tooltip = obj.optString("tooltip"),
|
|
||||||
category = obj.optString("category"),
|
|
||||||
kind = obj.optInt("kind", KIND_FLOAT),
|
|
||||||
uiType = obj.optInt("uiType", UI_HIDDEN),
|
|
||||||
components = obj.optInt("components", 1),
|
|
||||||
min = obj.optDouble("min", 0.0).toFloat(),
|
|
||||||
max = obj.optDouble("max", 1.0).toFloat(),
|
|
||||||
step = obj.optDouble("step", 0.01).toFloat(),
|
|
||||||
items = obj.optJSONArray("items").toStringList(),
|
|
||||||
defaults = obj.optJSONArray("defaults").toFloatList()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -17,7 +17,6 @@ add_library(yuzu-android SHARED
|
|||||||
android_config.cpp
|
android_config.cpp
|
||||||
android_config.h
|
android_config.h
|
||||||
native_input.cpp
|
native_input.cpp
|
||||||
native_post_processing.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR})
|
set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR})
|
||||||
|
|||||||
@@ -15,22 +15,10 @@
|
|||||||
#include "frontend_common/config.h"
|
#include "frontend_common/config.h"
|
||||||
#include "frontend_common/settings_generator.h"
|
#include "frontend_common/settings_generator.h"
|
||||||
#include "native.h"
|
#include "native.h"
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
#include "video_core/post_processing/fx_chain.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::unique_ptr<AndroidConfig> global_config;
|
std::unique_ptr<AndroidConfig> global_config;
|
||||||
std::unique_ptr<AndroidConfig> per_game_config;
|
std::unique_ptr<AndroidConfig> per_game_config;
|
||||||
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
static void ResetFxChainToGlobal() {
|
|
||||||
VideoCore::UseGlobalFxSettings();
|
|
||||||
VideoCore::FxChain::Instance().LoadFromSettings();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static void ResetFxChainToGlobal() {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Settings::Setting<T>* getSetting(JNIEnv* env, jstring jkey) {
|
Settings::Setting<T>* getSetting(JNIEnv* env, jstring jkey) {
|
||||||
auto key = Common::Android::GetJString(env, jkey);
|
auto key = Common::Android::GetJString(env, jkey);
|
||||||
@@ -51,7 +39,6 @@ extern "C" {
|
|||||||
void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_initializeGlobalConfig(JNIEnv* env, jobject obj) {
|
void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_initializeGlobalConfig(JNIEnv* env, jobject obj) {
|
||||||
global_config = std::make_unique<AndroidConfig>();
|
global_config = std::make_unique<AndroidConfig>();
|
||||||
FrontendCommon::GenerateSettings();
|
FrontendCommon::GenerateSettings();
|
||||||
ResetFxChainToGlobal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_unloadGlobalConfig(JNIEnv* env, jobject obj) {
|
void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_unloadGlobalConfig(JNIEnv* env, jobject obj) {
|
||||||
@@ -60,7 +47,6 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_unloadGlobalConfig(JNIEnv* env,
|
|||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_reloadGlobalConfig(JNIEnv* env, jobject obj) {
|
void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_reloadGlobalConfig(JNIEnv* env, jobject obj) {
|
||||||
global_config->AndroidConfig::ReloadAllValues();
|
global_config->AndroidConfig::ReloadAllValues();
|
||||||
ResetFxChainToGlobal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_saveGlobalConfig(JNIEnv* env, jobject obj) {
|
void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_saveGlobalConfig(JNIEnv* env, jobject obj) {
|
||||||
|
|||||||
@@ -1,350 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <jni.h>
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
|
|
||||||
#include "common/android/android_common.h"
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
#include "android_config.h"
|
|
||||||
#include "video_core/post_processing/fx_chain.h"
|
|
||||||
#include "common/settings.h"
|
|
||||||
#include "video_core/post_processing/fx_effect.h"
|
|
||||||
#include "video_core/post_processing/fx_preset.h"
|
|
||||||
|
|
||||||
extern std::unique_ptr<AndroidConfig> per_game_config;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
bool EditingPerGame() {
|
|
||||||
return per_game_config != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BeginFxEdit() {
|
|
||||||
if (!EditingPerGame()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
VideoCore::UsePerGameFxSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
nlohmann::json SerializeUniform(const VideoCore::FxUniformDesc& uniform) {
|
|
||||||
nlohmann::json out;
|
|
||||||
out["name"] = uniform.name;
|
|
||||||
out["label"] = uniform.label;
|
|
||||||
out["tooltip"] = uniform.tooltip;
|
|
||||||
out["category"] = uniform.category;
|
|
||||||
out["kind"] = static_cast<int>(uniform.kind);
|
|
||||||
out["uiType"] = static_cast<int>(uniform.ui_type);
|
|
||||||
out["components"] = uniform.components;
|
|
||||||
out["min"] = uniform.ui_min;
|
|
||||||
out["max"] = uniform.ui_max;
|
|
||||||
out["step"] = uniform.ui_step;
|
|
||||||
out["items"] = uniform.items;
|
|
||||||
|
|
||||||
nlohmann::json defaults = nlohmann::json::array();
|
|
||||||
for (u32 i = 0; i < uniform.components; ++i) {
|
|
||||||
defaults.push_back(uniform.default_value[i]);
|
|
||||||
}
|
|
||||||
out["defaults"] = defaults;
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::array<f32, 4> DefaultValueOf(size_t index, const std::string& uniform) {
|
|
||||||
const auto entries = VideoCore::FxChain::Instance().Entries();
|
|
||||||
if (index >= entries.size()) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
const VideoCore::FxEffectDesc* effect = VideoCore::FindFxEffect(entries[index].file);
|
|
||||||
if (effect == nullptr) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
const VideoCore::FxUniformDesc* desc = VideoCore::FindFxUniform(*effect, uniform);
|
|
||||||
if (desc == nullptr) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return desc->default_value;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // Anonymous namespace
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_getCatalogJson(JNIEnv* env,
|
|
||||||
jobject obj) {
|
|
||||||
nlohmann::json out = nlohmann::json::array();
|
|
||||||
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
VideoCore::FxChain::Instance().DropUnknownEntries();
|
|
||||||
|
|
||||||
for (const auto& effect : VideoCore::GetFxCatalog()) {
|
|
||||||
nlohmann::json entry;
|
|
||||||
entry["file"] = effect.file;
|
|
||||||
entry["name"] = effect.name;
|
|
||||||
entry["label"] = effect.label;
|
|
||||||
entry["description"] = effect.description;
|
|
||||||
entry["error"] = effect.error;
|
|
||||||
entry["techniques"] = effect.techniques;
|
|
||||||
|
|
||||||
nlohmann::json uniforms = nlohmann::json::array();
|
|
||||||
for (const auto& uniform : effect.uniforms) {
|
|
||||||
uniforms.push_back(SerializeUniform(uniform));
|
|
||||||
}
|
|
||||||
entry["uniforms"] = uniforms;
|
|
||||||
|
|
||||||
out.push_back(entry);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return Common::Android::ToJString(env, out.dump());
|
|
||||||
}
|
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_getChainJson(JNIEnv* env, jobject obj) {
|
|
||||||
nlohmann::json out = nlohmann::json::array();
|
|
||||||
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
for (const auto& entry : VideoCore::FxChain::Instance().Entries()) {
|
|
||||||
nlohmann::json item;
|
|
||||||
item["file"] = entry.file;
|
|
||||||
item["technique"] = entry.technique;
|
|
||||||
|
|
||||||
nlohmann::json values = nlohmann::json::object();
|
|
||||||
for (const auto& [name, value] : entry.values) {
|
|
||||||
values[name] = {value[0], value[1], value[2], value[3]};
|
|
||||||
}
|
|
||||||
item["values"] = values;
|
|
||||||
|
|
||||||
out.push_back(item);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return Common::Android::ToJString(env, out.dump());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_append(JNIEnv* env, jobject obj,
|
|
||||||
jstring jfile, jstring jtechnique) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
VideoCore::FxChain::Instance().Append(Common::Android::GetJString(env, jfile),
|
|
||||||
Common::Android::GetJString(env, jtechnique));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_replace(JNIEnv* env, jobject obj,
|
|
||||||
jint index, jstring jfile,
|
|
||||||
jstring jtechnique) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
VideoCore::FxChain::Instance().Replace(static_cast<size_t>(index),
|
|
||||||
Common::Android::GetJString(env, jfile),
|
|
||||||
Common::Android::GetJString(env, jtechnique));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_remove(JNIEnv* env, jobject obj,
|
|
||||||
jint index) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
VideoCore::FxChain::Instance().Remove(static_cast<size_t>(index));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_move(JNIEnv* env, jobject obj, jint index,
|
|
||||||
jint delta) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
VideoCore::FxChain::Instance().Move(static_cast<size_t>(index), delta);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_resetValues(JNIEnv* env, jobject obj,
|
|
||||||
jint index) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
VideoCore::FxChain::Instance().ResetValues(static_cast<size_t>(index));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
jfloat Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_getValue(JNIEnv* env, jobject obj,
|
|
||||||
jint index, jstring juniform,
|
|
||||||
jint component) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
if (component < 0 || component >= 4) {
|
|
||||||
return 0.0f;
|
|
||||||
}
|
|
||||||
const auto value = VideoCore::FxChain::Instance().GetValue(
|
|
||||||
static_cast<size_t>(index), Common::Android::GetJString(env, juniform));
|
|
||||||
return value[static_cast<size_t>(component)];
|
|
||||||
#else
|
|
||||||
return 0.0f;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
jboolean Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_hasValue(JNIEnv* env, jobject obj,
|
|
||||||
jint index,
|
|
||||||
jstring juniform) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
return static_cast<jboolean>(VideoCore::FxChain::Instance().HasValue(
|
|
||||||
static_cast<size_t>(index), Common::Android::GetJString(env, juniform)));
|
|
||||||
#else
|
|
||||||
return static_cast<jboolean>(false);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_setValue(JNIEnv* env, jobject obj,
|
|
||||||
jint index, jstring juniform,
|
|
||||||
jint component, jfloat value) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
if (component < 0 || component >= 4) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const std::string uniform = Common::Android::GetJString(env, juniform);
|
|
||||||
auto& chain = VideoCore::FxChain::Instance();
|
|
||||||
const auto slot = static_cast<size_t>(index);
|
|
||||||
|
|
||||||
auto current = chain.GetValue(slot, uniform);
|
|
||||||
if (!chain.HasValue(slot, uniform)) {
|
|
||||||
current = DefaultValueOf(slot, uniform);
|
|
||||||
}
|
|
||||||
|
|
||||||
current[static_cast<size_t>(component)] = value;
|
|
||||||
chain.SetValue(slot, uniform, current);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_store(JNIEnv* env, jobject obj) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
BeginFxEdit();
|
|
||||||
VideoCore::FxChain::Instance().StoreToSettings();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_reload(JNIEnv* env, jobject obj) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
if (!EditingPerGame()) {
|
|
||||||
VideoCore::UseGlobalFxSettings();
|
|
||||||
}
|
|
||||||
VideoCore::FxChain::Instance().LoadFromSettings();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_clearChain(JNIEnv* env, jobject obj) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
VideoCore::FxChain::Instance().Clear();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_getShaderDirectory(JNIEnv* env,
|
|
||||||
jobject obj) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
return Common::Android::ToJString(env, VideoCore::GetFxRootDirectory().string());
|
|
||||||
#else
|
|
||||||
return Common::Android::ToJString(env, "");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_getPresetsJson(JNIEnv* env,
|
|
||||||
jobject obj) {
|
|
||||||
nlohmann::json out = nlohmann::json::array();
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
VideoCore::ReloadFxPresetCatalog();
|
|
||||||
|
|
||||||
for (const auto& preset : VideoCore::GetFxPresetCatalog()) {
|
|
||||||
nlohmann::json entry;
|
|
||||||
entry["name"] = preset.name;
|
|
||||||
entry["description"] = preset.description;
|
|
||||||
entry["bundled"] = preset.bundled;
|
|
||||||
out.push_back(entry);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return Common::Android::ToJString(env, out.dump());
|
|
||||||
}
|
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_getActivePreset(JNIEnv* env,
|
|
||||||
jobject obj) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
return Common::Android::ToJString(env, VideoCore::GetActiveFxPreset());
|
|
||||||
#else
|
|
||||||
return Common::Android::ToJString(env, "");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
jboolean Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_isPresetModified(JNIEnv* env,
|
|
||||||
jobject obj) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
return static_cast<jboolean>(VideoCore::IsActiveFxPresetModified());
|
|
||||||
#else
|
|
||||||
return static_cast<jboolean>(false);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
jboolean Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_applyPreset(JNIEnv* env, jobject obj,
|
|
||||||
jstring jname) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
BeginFxEdit();
|
|
||||||
return static_cast<jboolean>(
|
|
||||||
VideoCore::ApplyFxPreset(Common::Android::GetJString(env, jname)));
|
|
||||||
#else
|
|
||||||
return static_cast<jboolean>(false);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
jboolean Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_savePreset(JNIEnv* env, jobject obj,
|
|
||||||
jstring jname,
|
|
||||||
jstring jdescription) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
BeginFxEdit();
|
|
||||||
return static_cast<jboolean>(
|
|
||||||
VideoCore::SaveFxPreset(Common::Android::GetJString(env, jname),
|
|
||||||
Common::Android::GetJString(env, jdescription)));
|
|
||||||
#else
|
|
||||||
return static_cast<jboolean>(false);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
jboolean Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_deletePreset(JNIEnv* env, jobject obj,
|
|
||||||
jstring jname) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
BeginFxEdit();
|
|
||||||
return static_cast<jboolean>(
|
|
||||||
VideoCore::DeleteFxPreset(Common::Android::GetJString(env, jname)));
|
|
||||||
#else
|
|
||||||
return static_cast<jboolean>(false);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_clearPreset(JNIEnv* env, jobject obj) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
BeginFxEdit();
|
|
||||||
VideoCore::SetActiveFxPreset(std::string_view());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
jboolean Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_isEnabled(JNIEnv* env, jobject obj) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
return static_cast<jboolean>(Settings::values.post_shader_enabled.GetValue());
|
|
||||||
#else
|
|
||||||
return static_cast<jboolean>(false);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_setEnabled(JNIEnv* env, jobject obj,
|
|
||||||
jboolean enabled) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
BeginFxEdit();
|
|
||||||
Settings::values.post_shader_enabled.SetValue(enabled != JNI_FALSE);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_utils_NativePostProcessing_getPresetDirectory(JNIEnv* env,
|
|
||||||
jobject obj) {
|
|
||||||
#ifdef HAS_RESHADE
|
|
||||||
return Common::Android::ToJString(env, VideoCore::GetFxPresetDirectory().string());
|
|
||||||
#else
|
|
||||||
return Common::Android::ToJString(env, "");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} // extern "C"
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:viewportWidth="24"
|
|
||||||
android:viewportHeight="24">
|
|
||||||
<path
|
|
||||||
android:fillColor="?attr/colorControlNormal"
|
|
||||||
android:fillType="evenOdd"
|
|
||||||
android:pathData="M8.5,3 L19.4,3 Q21,3 21,4.6 L21,16.5 L19.4,16.5 L19.4,4.6 L8.5,4.6 Z M5,7 L15,7 Q17,7 17,9 L17,19 Q17,21 15,21 L5,21 Q3,21 3,19 L3,9 Q3,7 5,7 Z M5.2,8.6 L14.8,8.6 Q15.4,8.6 15.4,9.2 L15.4,18.8 Q15.4,19.4 14.8,19.4 L5.2,19.4 Q4.6,19.4 4.6,18.8 L4.6,9.2 Q4.6,8.6 5.2,8.6 Z M10,10.9 A3.1,3.1 0 0 1 10,17.1 Z"/>
|
|
||||||
</vector>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:shape="rectangle">
|
|
||||||
|
|
||||||
<solid android:color="?attr/colorSurfaceVariant" />
|
|
||||||
|
|
||||||
<corners android:radius="16dp" />
|
|
||||||
|
|
||||||
<stroke
|
|
||||||
android:width="1dp"
|
|
||||||
android:color="?attr/colorOutline" />
|
|
||||||
|
|
||||||
</shape>
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:baselineAligned="false"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/add_button"
|
|
||||||
style="@style/Widget.Material3.Button.TonalButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:minHeight="48dp"
|
|
||||||
android:paddingStart="12dp"
|
|
||||||
android:paddingEnd="12dp"
|
|
||||||
android:text="@string/post_processing_add"
|
|
||||||
app:icon="@drawable/ic_add"
|
|
||||||
app:iconPadding="6dp" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/remove_all_button"
|
|
||||||
style="@style/Widget.Material3.Button.TonalButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:minHeight="48dp"
|
|
||||||
android:paddingStart="12dp"
|
|
||||||
android:paddingEnd="12dp"
|
|
||||||
android:text="@string/post_processing_remove_all"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:icon="@drawable/ic_delete"
|
|
||||||
app:iconPadding="6dp" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<RadioGroup
|
|
||||||
android:id="@+id/add_choices"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingStart="24dp"
|
|
||||||
android:paddingEnd="24dp"
|
|
||||||
android:paddingTop="4dp"
|
|
||||||
android:paddingBottom="8dp"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginTop="6dp"
|
|
||||||
android:layout_marginBottom="6dp"
|
|
||||||
android:background="@drawable/shader_card_background"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingStart="20dp"
|
|
||||||
android:paddingEnd="16dp"
|
|
||||||
android:paddingTop="16dp"
|
|
||||||
android:paddingBottom="16dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/preset_title"
|
|
||||||
style="@style/TextAppearance.Material3.TitleMedium"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/preset_summary"
|
|
||||||
style="@style/TextAppearance.Material3.BodySmall"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:textColor="?attr/colorOnSurfaceVariant" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.materialswitch.MaterialSwitch
|
|
||||||
android:id="@+id/preset_switch"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:minHeight="48dp" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginTop="6dp"
|
|
||||||
android:layout_marginBottom="6dp"
|
|
||||||
android:background="@drawable/shader_card_background"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/shader_header"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingStart="16dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:paddingTop="12dp"
|
|
||||||
android:paddingBottom="12dp"
|
|
||||||
android:background="?attr/selectableItemBackground"
|
|
||||||
android:clickable="true"
|
|
||||||
android:focusable="true">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/shader_title"
|
|
||||||
style="@style/TextAppearance.Material3.TitleSmall"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/shader_summary"
|
|
||||||
style="@style/TextAppearance.Material3.BodySmall"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="2dp"
|
|
||||||
android:textColor="?attr/colorOnSurfaceVariant" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/shader_remove"
|
|
||||||
android:layout_width="40dp"
|
|
||||||
android:layout_height="40dp"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:padding="8dp"
|
|
||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
|
||||||
android:clickable="true"
|
|
||||||
android:focusable="true"
|
|
||||||
android:src="@drawable/ic_delete"
|
|
||||||
android:contentDescription="@string/post_processing_remove"
|
|
||||||
app:tint="?attr/colorOnSurfaceVariant" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/shader_expand"
|
|
||||||
android:layout_width="24dp"
|
|
||||||
android:layout_height="24dp"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:src="@drawable/ic_dropdown_arrow"
|
|
||||||
android:contentDescription=""
|
|
||||||
app:tint="?attr/colorPrimary" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/shader_body"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingBottom="8dp"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingStart="20dp"
|
|
||||||
android:paddingEnd="20dp"
|
|
||||||
android:paddingTop="8dp"
|
|
||||||
android:paddingBottom="8dp">
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/fx_reset"
|
|
||||||
style="@style/Widget.Material3.Button.TonalButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:text="@string/post_processing_reset" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingStart="20dp"
|
|
||||||
android:paddingEnd="20dp"
|
|
||||||
android:paddingTop="8dp"
|
|
||||||
android:paddingBottom="4dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/fx_slider_title"
|
|
||||||
style="@style/TextAppearance.Material3.TitleSmall"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/fx_slider_value"
|
|
||||||
style="@style/TextAppearance.Material3.BodySmall"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:textColor="?attr/colorOnSurfaceVariant" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.slider.Slider
|
|
||||||
android:id="@+id/fx_slider"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:stepSize="1"
|
|
||||||
android:valueFrom="0"
|
|
||||||
android:valueTo="100" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginTop="6dp"
|
|
||||||
android:layout_marginBottom="6dp"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/fx_button"
|
|
||||||
style="@style/Widget.Material3.Button.TonalButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:maxLines="1" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginTop="6dp"
|
|
||||||
android:layout_marginBottom="6dp"
|
|
||||||
android:background="@drawable/shader_card_background"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/preset_row"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="?attr/selectableItemBackground"
|
|
||||||
android:clickable="true"
|
|
||||||
android:focusable="true"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingStart="16dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:paddingTop="12dp"
|
|
||||||
android:paddingBottom="12dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/preset_name"
|
|
||||||
style="@style/TextAppearance.Material3.TitleSmall"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/preset_description"
|
|
||||||
style="@style/TextAppearance.Material3.BodySmall"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="2dp"
|
|
||||||
android:textColor="?attr/colorOnSurfaceVariant" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/preset_delete"
|
|
||||||
android:layout_width="40dp"
|
|
||||||
android:layout_height="40dp"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
|
||||||
android:clickable="true"
|
|
||||||
android:contentDescription="@string/post_processing_preset_delete"
|
|
||||||
android:focusable="true"
|
|
||||||
android:padding="8dp"
|
|
||||||
android:src="@drawable/ic_delete"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:tint="?attr/colorOnSurfaceVariant" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginTop="6dp"
|
|
||||||
android:layout_marginBottom="6dp"
|
|
||||||
android:background="@drawable/shader_card_background"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/shader_header"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="?attr/selectableItemBackground"
|
|
||||||
android:clickable="true"
|
|
||||||
android:focusable="true"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingStart="20dp"
|
|
||||||
android:paddingEnd="8dp"
|
|
||||||
android:paddingTop="14dp"
|
|
||||||
android:paddingBottom="14dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/shader_title"
|
|
||||||
style="@style/TextAppearance.Material3.TitleMedium"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
|
||||||
android:id="@+id/shader_summary"
|
|
||||||
style="@style/TextAppearance.Material3.BodySmall"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:textColor="?attr/colorOnSurfaceVariant" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/shader_remove"
|
|
||||||
android:layout_width="40dp"
|
|
||||||
android:layout_height="40dp"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
|
||||||
android:clickable="true"
|
|
||||||
android:contentDescription="@string/post_processing_remove"
|
|
||||||
android:focusable="true"
|
|
||||||
android:padding="8dp"
|
|
||||||
android:src="@drawable/ic_delete"
|
|
||||||
app:tint="?attr/colorOnSurfaceVariant" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/shader_expand"
|
|
||||||
android:layout_width="24dp"
|
|
||||||
android:layout_height="24dp"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_marginStart="4dp"
|
|
||||||
android:contentDescription=""
|
|
||||||
android:src="@drawable/ic_dropdown_arrow"
|
|
||||||
app:tint="?attr/colorPrimary" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/shader_body"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingBottom="8dp"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginTop="6dp"
|
|
||||||
android:layout_marginBottom="6dp"
|
|
||||||
android:baselineAligned="false"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/fx_add"
|
|
||||||
style="@style/Widget.Material3.Button.TonalButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:minHeight="48dp"
|
|
||||||
android:paddingStart="12dp"
|
|
||||||
android:paddingEnd="12dp"
|
|
||||||
android:text="@string/post_processing_add"
|
|
||||||
app:icon="@drawable/ic_add"
|
|
||||||
app:iconPadding="6dp" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/fx_presets"
|
|
||||||
style="@style/Widget.Material3.Button.TonalButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_weight="1.4"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:minHeight="48dp"
|
|
||||||
android:paddingStart="12dp"
|
|
||||||
android:paddingEnd="12dp"
|
|
||||||
android:text="@string/post_processing_presets"
|
|
||||||
app:icon="@drawable/ic_dropdown_arrow"
|
|
||||||
app:iconGravity="textEnd"
|
|
||||||
app:iconPadding="6dp" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/fx_create_preset"
|
|
||||||
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
|
|
||||||
android:layout_width="48dp"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:contentDescription="@string/post_processing_preset_new"
|
|
||||||
app:icon="@drawable/ic_add" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/fx_remove_all"
|
|
||||||
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
|
|
||||||
android:layout_width="48dp"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:contentDescription="@string/post_processing_remove_all"
|
|
||||||
app:icon="@drawable/ic_delete" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -298,25 +298,6 @@
|
|||||||
<string name="gpu_driver_fetcher">GPU driver fetcher</string>
|
<string name="gpu_driver_fetcher">GPU driver fetcher</string>
|
||||||
<string name="gpu_driver_manager">GPU driver manager</string>
|
<string name="gpu_driver_manager">GPU driver manager</string>
|
||||||
<string name="install_gpu_driver_description">Install alternative drivers for potentially better performance or accuracy</string>
|
<string name="install_gpu_driver_description">Install alternative drivers for potentially better performance or accuracy</string>
|
||||||
<string name="post_processing">Post-Processing Effects</string>
|
|
||||||
<string name="post_processing_description">ReShade FX effects applied after rendering</string>
|
|
||||||
<string name="post_processing_per_game_description">Configure the effect chain for this game</string>
|
|
||||||
<string name="post_processing_add">Add effect</string>
|
|
||||||
<string name="post_processing_remove">Remove</string>
|
|
||||||
<string name="post_processing_open_list">Open list</string>
|
|
||||||
<string name="post_processing_close_list">Close list</string>
|
|
||||||
<string name="post_processing_remove_all">Remove effects</string>
|
|
||||||
<string name="post_processing_preset_locked">Preset active. Edit it in Post-Processing Effects before starting a game.</string>
|
|
||||||
<string name="post_processing_preset_modified">Values changed from the original preset.</string>
|
|
||||||
<string name="post_processing_presets">Presets</string>
|
|
||||||
<string name="post_processing_preset_new">New preset</string>
|
|
||||||
<string name="post_processing_preset_new_description">Saves the effects you have loaded, with their current values, as a preset you can pick later.</string>
|
|
||||||
<string name="post_processing_preset_name_invalid">Give the preset a name without an equals sign.</string>
|
|
||||||
<string name="post_processing_preset_none">No preset</string>
|
|
||||||
<string name="post_processing_preset_delete">Delete preset</string>
|
|
||||||
<string name="post_processing_preset_reset">Reset preset values</string>
|
|
||||||
<string name="post_processing_reset">Reset to default</string>
|
|
||||||
<string name="post_processing_empty">No effects found. Place .fx files in this folder:</string>
|
|
||||||
<string name="frame_gen">Frame generation</string>
|
<string name="frame_gen">Frame generation</string>
|
||||||
<string name="frame_gen_per_game_description">Configure frame generation for this game</string>
|
<string name="frame_gen_per_game_description">Configure frame generation for this game</string>
|
||||||
<string name="frame_gen_description">Insert interpolated frames between rendered ones using Lossless Scaling. Forces FIFO presentation while enabled.</string>
|
<string name="frame_gen_description">Insert interpolated frames between rendered ones using Lossless Scaling. Forces FIFO presentation while enabled.</string>
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include "audio_core/opus/hardware_opus.h"
|
#include "audio_core/opus/hardware_opus.h"
|
||||||
#include "audio_core/opus/parameters.h"
|
#include "audio_core/opus/parameters.h"
|
||||||
#include "common/alignment.h"
|
#include "common/alignment.h"
|
||||||
#include "common/scope_exit.h"
|
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
|
||||||
@@ -29,18 +28,10 @@ OpusDecoder::OpusDecoder(Core::System& system_, HardwareOpus& hardware_opus_)
|
|||||||
OpusDecoder::~OpusDecoder() {
|
OpusDecoder::~OpusDecoder() {
|
||||||
if (decode_object_initialized) {
|
if (decode_object_initialized) {
|
||||||
hardware_opus.ShutdownDecodeObject(shared_buffer.data(), shared_buffer.size());
|
hardware_opus.ShutdownDecodeObject(shared_buffer.data(), shared_buffer.size());
|
||||||
hardware_opus.UnregisterDecoder(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Result OpusDecoder::Initialize(const OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) {
|
Result OpusDecoder::Initialize(const OpusParametersEx& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) {
|
||||||
R_TRY(hardware_opus.RegisterDecoder(this));
|
|
||||||
SCOPE_EXIT {
|
|
||||||
if (!decode_object_initialized) {
|
|
||||||
hardware_opus.UnregisterDecoder(this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
auto frame_size{params.use_large_frame_size ? 5760 : 1920};
|
auto frame_size{params.use_large_frame_size ? 5760 : 1920};
|
||||||
shared_buffer.resize(transfer_memory_size);
|
shared_buffer.resize(transfer_memory_size);
|
||||||
shared_memory_mapped = true;
|
shared_memory_mapped = true;
|
||||||
@@ -70,13 +61,6 @@ Result OpusDecoder::Initialize(const OpusParametersEx& params, Kernel::KTransfer
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result OpusDecoder::Initialize(const OpusMultiStreamParametersEx& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) {
|
Result OpusDecoder::Initialize(const OpusMultiStreamParametersEx& params, Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size) {
|
||||||
R_TRY(hardware_opus.RegisterDecoder(this));
|
|
||||||
SCOPE_EXIT {
|
|
||||||
if (!decode_object_initialized) {
|
|
||||||
hardware_opus.UnregisterDecoder(this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
auto frame_size{params.use_large_frame_size ? 5760 : 1920};
|
auto frame_size{params.use_large_frame_size ? 5760 : 1920};
|
||||||
shared_buffer.resize(transfer_memory_size, 0);
|
shared_buffer.resize(transfer_memory_size, 0);
|
||||||
shared_memory_mapped = true;
|
shared_memory_mapped = true;
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "audio_core/audio_core.h"
|
#include "audio_core/audio_core.h"
|
||||||
@@ -46,25 +45,6 @@ HardwareOpus::HardwareOpus(Core::System& system_)
|
|||||||
opus_decoder.SetSharedMemory(shared_memory);
|
opus_decoder.SetSharedMemory(shared_memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result HardwareOpus::RegisterDecoder(OpusDecoder* decoder) {
|
|
||||||
std::scoped_lock l{mutex};
|
|
||||||
const auto slot = std::ranges::find(decoders, nullptr);
|
|
||||||
if (slot == decoders.end()) {
|
|
||||||
R_THROW(ResultOutOfOpusDecoders);
|
|
||||||
}
|
|
||||||
*slot = decoder;
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
void HardwareOpus::UnregisterDecoder(OpusDecoder* decoder) {
|
|
||||||
std::scoped_lock l{mutex};
|
|
||||||
const auto slot = std::ranges::find(decoders, decoder);
|
|
||||||
if (slot == decoders.end()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*slot = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 HardwareOpus::GetWorkBufferSize(u32 channel) {
|
u32 HardwareOpus::GetWorkBufferSize(u32 channel) {
|
||||||
if (!opus_decoder.IsRunning()) {
|
if (!opus_decoder.IsRunning()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <opus.h>
|
#include <opus.h>
|
||||||
|
|
||||||
@@ -16,12 +12,9 @@
|
|||||||
#include "core/hle/service/audio/errors.h"
|
#include "core/hle/service/audio/errors.h"
|
||||||
|
|
||||||
namespace AudioCore::OpusDecoder {
|
namespace AudioCore::OpusDecoder {
|
||||||
class OpusDecoder;
|
|
||||||
class HardwareOpus {
|
class HardwareOpus {
|
||||||
public:
|
public:
|
||||||
HardwareOpus(Core::System& system);
|
HardwareOpus(Core::System& system);
|
||||||
Result RegisterDecoder(OpusDecoder* decoder);
|
|
||||||
void UnregisterDecoder(OpusDecoder* decoder);
|
|
||||||
|
|
||||||
u32 GetWorkBufferSize(u32 channel);
|
u32 GetWorkBufferSize(u32 channel);
|
||||||
u32 GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 stereo_stream_count);
|
u32 GetWorkBufferSizeForMultiStream(u32 total_stream_count, u32 stereo_stream_count);
|
||||||
@@ -46,7 +39,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
std::mutex mutex;
|
std::mutex mutex;
|
||||||
std::array<OpusDecoder*, 24> decoders{};
|
|
||||||
ADSP::OpusDecoder::OpusDecoder& opus_decoder;
|
ADSP::OpusDecoder::OpusDecoder& opus_decoder;
|
||||||
ADSP::OpusDecoder::SharedMemory shared_memory;
|
ADSP::OpusDecoder::SharedMemory shared_memory;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,8 +23,6 @@
|
|||||||
#define LOSSLESS_DIR "lossless"
|
#define LOSSLESS_DIR "lossless"
|
||||||
#define NAND_DIR "nand"
|
#define NAND_DIR "nand"
|
||||||
#define PLAY_TIME_DIR "play_time"
|
#define PLAY_TIME_DIR "play_time"
|
||||||
#define POST_PRESET_DIR "post_presets"
|
|
||||||
#define POST_SHADER_DIR "post_shaders"
|
|
||||||
#define SCREENSHOTS_DIR "screenshots"
|
#define SCREENSHOTS_DIR "screenshots"
|
||||||
#define SDMC_DIR "sdmc"
|
#define SDMC_DIR "sdmc"
|
||||||
#define SHADER_DIR "shader"
|
#define SHADER_DIR "shader"
|
||||||
|
|||||||
@@ -160,8 +160,6 @@ public:
|
|||||||
GenerateEdenPath(EdenPath::LosslessDir, eden_path / LOSSLESS_DIR);
|
GenerateEdenPath(EdenPath::LosslessDir, eden_path / LOSSLESS_DIR);
|
||||||
GenerateEdenPath(EdenPath::NANDDir, eden_path / NAND_DIR);
|
GenerateEdenPath(EdenPath::NANDDir, eden_path / NAND_DIR);
|
||||||
GenerateEdenPath(EdenPath::PlayTimeDir, eden_path / PLAY_TIME_DIR);
|
GenerateEdenPath(EdenPath::PlayTimeDir, eden_path / PLAY_TIME_DIR);
|
||||||
GenerateEdenPath(EdenPath::PostPresetDir, eden_path / POST_PRESET_DIR);
|
|
||||||
GenerateEdenPath(EdenPath::PostShaderDir, eden_path / POST_SHADER_DIR);
|
|
||||||
GenerateEdenPath(EdenPath::SaveDir, eden_path / NAND_DIR);
|
GenerateEdenPath(EdenPath::SaveDir, eden_path / NAND_DIR);
|
||||||
GenerateEdenPath(EdenPath::ScreenshotsDir, eden_path / SCREENSHOTS_DIR);
|
GenerateEdenPath(EdenPath::ScreenshotsDir, eden_path / SCREENSHOTS_DIR);
|
||||||
GenerateEdenPath(EdenPath::SDMCDir, eden_path / SDMC_DIR);
|
GenerateEdenPath(EdenPath::SDMCDir, eden_path / SDMC_DIR);
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ enum class EdenPath {
|
|||||||
LosslessDir, // Where the user-supplied Lossless Scaling library is stored.
|
LosslessDir, // Where the user-supplied Lossless Scaling library is stored.
|
||||||
NANDDir, // Where the emulated NAND is stored.
|
NANDDir, // Where the emulated NAND is stored.
|
||||||
PlayTimeDir, // Where play time data is stored.
|
PlayTimeDir, // Where play time data is stored.
|
||||||
PostPresetDir,
|
|
||||||
PostShaderDir, // Where user post-processing shaders are stored.
|
|
||||||
SaveDir, // Where save data is stored.
|
SaveDir, // Where save data is stored.
|
||||||
ScreenshotsDir, // Where yuzu screenshots are stored.
|
ScreenshotsDir, // Where yuzu screenshots are stored.
|
||||||
SDMCDir, // Where the emulated SDMC is stored.
|
SDMCDir, // Where the emulated SDMC is stored.
|
||||||
|
|||||||
@@ -388,30 +388,6 @@ struct Values {
|
|||||||
true,
|
true,
|
||||||
true};
|
true};
|
||||||
|
|
||||||
SwitchableSetting<std::string> post_shader_chain{linkage,
|
|
||||||
std::string(),
|
|
||||||
"post_shader_chain",
|
|
||||||
Category::Renderer,
|
|
||||||
Specialization::Default,
|
|
||||||
true,
|
|
||||||
true};
|
|
||||||
|
|
||||||
SwitchableSetting<std::string> post_shader_preset{linkage,
|
|
||||||
std::string(),
|
|
||||||
"post_shader_preset",
|
|
||||||
Category::Renderer,
|
|
||||||
Specialization::Default,
|
|
||||||
true,
|
|
||||||
true};
|
|
||||||
|
|
||||||
SwitchableSetting<bool> post_shader_enabled{linkage,
|
|
||||||
true,
|
|
||||||
"post_shader_enabled",
|
|
||||||
Category::Renderer,
|
|
||||||
Specialization::Default,
|
|
||||||
true,
|
|
||||||
true};
|
|
||||||
|
|
||||||
SwitchableSetting<bool> frame_gen{linkage, false, "frame_gen", Category::Renderer,
|
SwitchableSetting<bool> frame_gen{linkage, false, "frame_gen", Category::Renderer,
|
||||||
Specialization::Default, true, false};
|
Specialization::Default, true, false};
|
||||||
|
|
||||||
|
|||||||
+19
-7
@@ -1241,7 +1241,7 @@ if (HAS_NCE)
|
|||||||
target_link_libraries(core PRIVATE merry::oaknut)
|
target_link_libraries(core PRIVATE merry::oaknut)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64 OR ARCHITECTURE_riscv64 OR ARCHITECTURE_loongarch64)
|
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64 OR ARCHITECTURE_riscv64 OR ARCHITECTURE_powerpc64 OR ARCHITECTURE_powerpc64)
|
||||||
target_sources(core PRIVATE
|
target_sources(core PRIVATE
|
||||||
arm/dynarmic/arm_dynarmic.h
|
arm/dynarmic/arm_dynarmic.h
|
||||||
arm/dynarmic/arm_dynarmic_64.cpp
|
arm/dynarmic/arm_dynarmic_64.cpp
|
||||||
@@ -1261,11 +1261,23 @@ if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64 OR ARCHITECTURE_riscv64 OR ARCHITE
|
|||||||
target_link_libraries(core PRIVATE dynarmic::dynarmic)
|
target_link_libraries(core PRIVATE dynarmic::dynarmic)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (TARGET OpenSSL::SSL)
|
target_sources(core PRIVATE hle/service/ssl/ssl_backend_openssl.cpp)
|
||||||
target_sources(core PRIVATE hle/service/ssl/ssl_backend_openssl.cpp)
|
|
||||||
target_link_libraries(core PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
target_link_libraries(core PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
||||||
else()
|
|
||||||
target_sources(core PRIVATE hle/service/ssl/ssl_backend_none.cpp)
|
# TODO
|
||||||
endif()
|
|
||||||
|
# elseif (APPLE)
|
||||||
|
# target_sources(core PRIVATE
|
||||||
|
# hle/service/ssl/ssl_backend_securetransport.cpp)
|
||||||
|
# target_link_libraries(core PRIVATE "-framework Security")
|
||||||
|
# elseif (WIN32)
|
||||||
|
# target_sources(core PRIVATE
|
||||||
|
# hle/service/ssl/ssl_backend_schannel.cpp)
|
||||||
|
# target_link_libraries(core PRIVATE crypt32 secur32)
|
||||||
|
# else()
|
||||||
|
# target_sources(core PRIVATE
|
||||||
|
# hle/service/ssl/ssl_backend_none.cpp)
|
||||||
|
# endif()
|
||||||
|
|
||||||
create_target_directory_groups(core)
|
create_target_directory_groups(core)
|
||||||
|
|||||||
@@ -312,10 +312,6 @@ struct System::Impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window, const std::string& filepath, Service::AM::FrontendAppletParameters& params) {
|
SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window, const std::string& filepath, Service::AM::FrontendAppletParameters& params) {
|
||||||
if (params.launch_type == Service::AM::LaunchType::FrontendInitiated) {
|
|
||||||
fs_controller.InitTempStorage();
|
|
||||||
}
|
|
||||||
|
|
||||||
InitializeKernel(system);
|
InitializeKernel(system);
|
||||||
|
|
||||||
if (params.applet_type == Service::AM::AppletType::Application) {
|
if (params.applet_type == Service::AM::AppletType::Application) {
|
||||||
|
|||||||
@@ -57,7 +57,11 @@ std::string GetFutureSaveDataPath(SaveDataSpaceId space_id, SaveDataType type, u
|
|||||||
|
|
||||||
SaveDataFactory::SaveDataFactory(Core::System& system_, ProgramId program_id_,
|
SaveDataFactory::SaveDataFactory(Core::System& system_, ProgramId program_id_,
|
||||||
VirtualDir save_directory_)
|
VirtualDir save_directory_)
|
||||||
: system{system_}, program_id{program_id_}, dir{std::move(save_directory_)} {}
|
: system{system_}, program_id{program_id_}, dir{std::move(save_directory_)} {
|
||||||
|
// Delete all temporary storages
|
||||||
|
// On hardware, it is expected that temporary storage be empty at first use.
|
||||||
|
dir->DeleteSubdirectoryRecursive("temp");
|
||||||
|
}
|
||||||
|
|
||||||
SaveDataFactory::~SaveDataFactory() = default;
|
SaveDataFactory::~SaveDataFactory() = default;
|
||||||
|
|
||||||
|
|||||||
@@ -40,14 +40,10 @@ VirtualDir SystemVersion() {
|
|||||||
VirtualFile file = std::make_shared<VectorVfsFile>(file_data, "file");
|
VirtualFile file = std::make_shared<VectorVfsFile>(file_data, "file");
|
||||||
|
|
||||||
// the "/digest"
|
// the "/digest"
|
||||||
if (HLE::ApiVersion::VERSION_DIGEST[0] == '\0') {
|
std::vector<u8> digest_data(sizeof(HLE::ApiVersion::VERSION_DIGEST));
|
||||||
return std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{file}, std::vector<VirtualDir>{}, "data");
|
std::memcpy(digest_data.data(), HLE::ApiVersion::VERSION_DIGEST, sizeof(HLE::ApiVersion::VERSION_DIGEST));
|
||||||
} else {
|
VirtualFile digest_file = std::make_shared<VectorVfsFile>(digest_data, "digest");
|
||||||
std::vector<u8> digest_data(sizeof(HLE::ApiVersion::VERSION_DIGEST));
|
return std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{file, digest_file}, std::vector<VirtualDir>{}, "data");
|
||||||
std::memcpy(digest_data.data(), HLE::ApiVersion::VERSION_DIGEST, sizeof(HLE::ApiVersion::VERSION_DIGEST));
|
|
||||||
VirtualFile digest_file = std::make_shared<VectorVfsFile>(digest_data, "digest");
|
|
||||||
return std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{file, digest_file}, std::vector<VirtualDir>{}, "data");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace FileSys::SystemArchive
|
} // namespace FileSys::SystemArchive
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ namespace HLE::ApiVersion {
|
|||||||
|
|
||||||
// Horizon OS version constants.
|
// Horizon OS version constants.
|
||||||
|
|
||||||
constexpr u8 HOS_VERSION_MAJOR = 23;
|
constexpr u8 HOS_VERSION_MAJOR = 22;
|
||||||
constexpr u8 HOS_VERSION_MINOR = 0;
|
constexpr u8 HOS_VERSION_MINOR = 5;
|
||||||
constexpr u8 HOS_VERSION_MICRO = 0;
|
constexpr u8 HOS_VERSION_MICRO = 0;
|
||||||
|
|
||||||
// NintendoSDK version constants.
|
// NintendoSDK version constants.
|
||||||
@@ -25,16 +25,15 @@ constexpr u8 SDK_REVISION_MAJOR = 1;
|
|||||||
constexpr u8 SDK_REVISION_MINOR = 0;
|
constexpr u8 SDK_REVISION_MINOR = 0;
|
||||||
|
|
||||||
constexpr char PLATFORM_STRING[0x20] = "NX";
|
constexpr char PLATFORM_STRING[0x20] = "NX";
|
||||||
constexpr char VERSION_HASH[0x40] = "c2663accb7490a6ccfe9bc4dfd120ca215490525";
|
constexpr char VERSION_HASH[0x40] = "ae93061abbc7791fcf8d2f7e7b7b2d62163af697";
|
||||||
constexpr char DISPLAY_VERSION[0x18] = "23.0.0";
|
constexpr char DISPLAY_VERSION[0x18] = "22.5.0";
|
||||||
constexpr char DISPLAY_TITLE[0x80] = "NintendoSDK Firmware for NX 23.0.0-4.0";
|
constexpr char DISPLAY_TITLE[0x80] = "NintendoSDK Firmware for NX 22.5.0-1.0 ";
|
||||||
// Leave empty when there's no digest (N/A)
|
constexpr char VERSION_DIGEST[0x40] = "CusHY#00160500#WxlZDREksAFSi6bQJEV6nm6-cHLg2jikdYRVN3bwqyE=";
|
||||||
constexpr char VERSION_DIGEST[0x40] = "";
|
|
||||||
|
|
||||||
// Atmosphere version constants.
|
// Atmosphere version constants.
|
||||||
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MAJOR = 1;
|
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MAJOR = 1;
|
||||||
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MINOR = 12;
|
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MINOR = 11;
|
||||||
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MICRO = 0;
|
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MICRO = 2;
|
||||||
|
|
||||||
constexpr u32 AtmosphereTargetFirmwareWithRevision(u8 major, u8 minor, u8 micro, u8 rev) {
|
constexpr u32 AtmosphereTargetFirmwareWithRevision(u8 major, u8 minor, u8 micro, u8 rev) {
|
||||||
return u32{major} << 24 | u32{minor} << 16 | u32{micro} << 8 | u32{rev};
|
return u32{major} << 24 | u32{minor} << 16 | u32{micro} << 8 | u32{rev};
|
||||||
|
|||||||
@@ -210,13 +210,6 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
|
|||||||
*result = system.Kernel().CurrentScheduler()->GetIdleThread()->GetCpuTime();
|
*result = system.Kernel().CurrentScheduler()->GetIdleThread()->GetCpuTime();
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
case InfoType::Unknown37:
|
|
||||||
case InfoType::Unknown38: {
|
|
||||||
LOG_WARNING(Kernel_SVC, "(STUBBED) called, info_id={:#x}, info_sub_id={:#x}, handle={:#08x}",
|
|
||||||
info_id, info_sub_id, handle);
|
|
||||||
*result = 0;
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
case InfoType::MesosphereMeta: {
|
case InfoType::MesosphereMeta: {
|
||||||
enum MesosphereMetaInfo : u64 {
|
enum MesosphereMetaInfo : u64 {
|
||||||
KernelVersion = 0,
|
KernelVersion = 0,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
@@ -158,11 +158,6 @@ enum class InfoType : u32 {
|
|||||||
IoRegionHint = 27,
|
IoRegionHint = 27,
|
||||||
AliasRegionExtraSize = 28,
|
AliasRegionExtraSize = 28,
|
||||||
|
|
||||||
TransferMemoryHint = 34,
|
|
||||||
|
|
||||||
Unknown37 = 37,
|
|
||||||
Unknown38 = 38,
|
|
||||||
|
|
||||||
MesosphereMeta = 65000,
|
MesosphereMeta = 65000,
|
||||||
MesosphereCurrentProcess = 65001,
|
MesosphereCurrentProcess = 65001,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "core/launch_timestamp_cache.h"
|
#include "core/launch_timestamp_cache.h"
|
||||||
#include "core/hle/api_version.h"
|
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
@@ -88,7 +87,7 @@ Result IApplicationCreator::CreateSystemApplication(
|
|||||||
|
|
||||||
std::vector<u8> control;
|
std::vector<u8> control;
|
||||||
std::unique_ptr<Loader::AppLoader> loader;
|
std::unique_ptr<Loader::AppLoader> loader;
|
||||||
auto process = CreateProcess(system, application_id, 1, HLE::ApiVersion::HOS_VERSION_MAJOR);
|
auto process = CreateProcess(system, application_id, 1, 22);
|
||||||
R_UNLESS(process != nullptr, ResultUnknown);
|
R_UNLESS(process != nullptr, ResultUnknown);
|
||||||
|
|
||||||
const auto applet = std::make_shared<Applet>(system, std::move(process), true);
|
const auto applet = std::make_shared<Applet>(system, std::move(process), true);
|
||||||
|
|||||||
@@ -13,8 +13,6 @@
|
|||||||
#include "core/hle/service/am/process_creation.h"
|
#include "core/hle/service/am/process_creation.h"
|
||||||
#include "core/hle/service/am/service/library_applet_accessor.h"
|
#include "core/hle/service/am/service/library_applet_accessor.h"
|
||||||
#include "core/hle/service/am/service/library_applet_creator.h"
|
#include "core/hle/service/am/service/library_applet_creator.h"
|
||||||
|
|
||||||
#include "core/hle/api_version.h"
|
|
||||||
#include "core/hle/service/am/service/storage.h"
|
#include "core/hle/service/am/service/storage.h"
|
||||||
#include "core/hle/service/am/window_system.h"
|
#include "core/hle/service/am/window_system.h"
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
@@ -110,7 +108,20 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto process = CreateProcess(system, program_id, 1, HLE::ApiVersion::HOS_VERSION_MAJOR);
|
// TODO: enable other versions of applets
|
||||||
|
enum : u8 {
|
||||||
|
Firmware1400 = 14,
|
||||||
|
Firmware1500 = 15,
|
||||||
|
Firmware1600 = 16,
|
||||||
|
Firmware1700 = 17,
|
||||||
|
Firmware1800 = 18,
|
||||||
|
Firmware1900 = 19,
|
||||||
|
Firmware2000 = 20,
|
||||||
|
Firmware2100 = 21,
|
||||||
|
Firmware2200 = 22,
|
||||||
|
};
|
||||||
|
|
||||||
|
auto process = CreateProcess(system, program_id, Firmware1400, Firmware2200);
|
||||||
if (process) {
|
if (process) {
|
||||||
const auto applet = std::make_shared<Applet>(system, std::move(process), false);
|
const auto applet = std::make_shared<Applet>(system, std::move(process), false);
|
||||||
applet->program_id = program_id;
|
applet->program_id = program_id;
|
||||||
|
|||||||
@@ -71,7 +71,6 @@ ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet>
|
|||||||
{120, D<&ISelfController::SaveCurrentScreenshot>, "SaveCurrentScreenshot"},
|
{120, D<&ISelfController::SaveCurrentScreenshot>, "SaveCurrentScreenshot"},
|
||||||
{130, D<&ISelfController::SetRecordVolumeMuted>, "SetRecordVolumeMuted"},
|
{130, D<&ISelfController::SetRecordVolumeMuted>, "SetRecordVolumeMuted"},
|
||||||
{230, D<&ISelfController::Unknown230>, "Unknown230"},
|
{230, D<&ISelfController::Unknown230>, "Unknown230"},
|
||||||
{240, D<&ISelfController::Unknown240>, "Unknown240"},
|
|
||||||
{1000, nullptr, "GetDebugStorageChannel"},
|
{1000, nullptr, "GetDebugStorageChannel"},
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
@@ -423,10 +422,4 @@ Result ISelfController::Unknown230(u32 in_val, Out<u16> out_val) {
|
|||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ISelfController::Unknown240(u32 in_val) {
|
|
||||||
LOG_WARNING(Service_AM, "(STUBBED) called, in_val={}", in_val);
|
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Service::AM
|
} // namespace Service::AM
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ private:
|
|||||||
Result SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option);
|
Result SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option);
|
||||||
Result SetRecordVolumeMuted(bool muted);
|
Result SetRecordVolumeMuted(bool muted);
|
||||||
Result Unknown230(u32 in_val, Out<u16> out_val);
|
Result Unknown230(u32 in_val, Out<u16> out_val);
|
||||||
Result Unknown240(u32 in_val);
|
|
||||||
|
|
||||||
Kernel::KProcess* const m_process;
|
Kernel::KProcess* const m_process;
|
||||||
const std::shared_ptr<Applet> m_applet;
|
const std::shared_ptr<Applet> m_applet;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user