mirror of
https://github.com/meowarex/rl-mobile.git
synced 2026-08-26 22:17:44 +10:00
Kawarp Shader <3
This commit is contained in:
@@ -31,8 +31,8 @@ android {
|
||||
defaultConfig {
|
||||
minSdk = 24
|
||||
targetSdk = 36
|
||||
versionCode = 53
|
||||
versionName = "1.0.1"
|
||||
versionCode = 62
|
||||
versionName = "1.7.7"
|
||||
|
||||
vectorDrawables {
|
||||
useSupportLibrary = true
|
||||
|
||||
@@ -14,17 +14,16 @@
|
||||
"DebugMenuUnlock"
|
||||
],
|
||||
"disables": [
|
||||
"LyricsDisableCover",
|
||||
"LyricsReplaceLyricsButton",
|
||||
"LyricsReplaceShareButton",
|
||||
"LyricsRlApi",
|
||||
"LyricsKeepControlsVisible",
|
||||
"PlayerBackdrop",
|
||||
"QualityBadgeColors",
|
||||
"PlayerMovePlayingFrom",
|
||||
"PlayerOneHanded",
|
||||
"LyricsProgressPill",
|
||||
"MiniPlayerRedesign"
|
||||
"LyricsDisableCover",
|
||||
"LyricsReplaceLyricsButton",
|
||||
"LyricsReplaceShareButton",
|
||||
"LyricsKeepControlsVisible"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -119,36 +118,29 @@
|
||||
"order": 30,
|
||||
"fileNames": [],
|
||||
"title": "Player Backdrop",
|
||||
"description": "Lets you fully adjust how the player backdrop blur looks and behaves",
|
||||
"description": "Swap the player backdrop for the Kawarp shader, or fine-tune TIDAL's own blurred cover",
|
||||
"default": true,
|
||||
"defaultVariantIndex": 2,
|
||||
"defaultVariantIndex": 1,
|
||||
"variants": [
|
||||
{
|
||||
"title": "Static",
|
||||
"fileNames": [
|
||||
"player-backdrop-static.patch"
|
||||
],
|
||||
"extensionFiles": [
|
||||
"radiant/BackdropFx.smali"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Animated",
|
||||
"fileNames": [
|
||||
"player-backdrop-animated.patch"
|
||||
],
|
||||
"extensionFiles": [
|
||||
"radiant/BackdropFx.smali"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Playback",
|
||||
"title": "Tidal",
|
||||
"fileNames": [
|
||||
"player-backdrop-playback.patch"
|
||||
],
|
||||
"extensionFiles": [
|
||||
"radiant/BackdropFx.smali"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Radiant",
|
||||
"fileNames": [
|
||||
"player-backdrop-kawarp.patch"
|
||||
],
|
||||
"extensionFiles": [
|
||||
"radiant/Kawarp.smali",
|
||||
"dev/kawarp/KawarpEngine.smali"
|
||||
],
|
||||
"minSdk": 33
|
||||
}
|
||||
],
|
||||
"advancedOptions": [
|
||||
@@ -166,7 +158,8 @@
|
||||
"encode": {
|
||||
"kind": "int",
|
||||
"scale": 1.0
|
||||
}
|
||||
},
|
||||
"requiresVariant": 0
|
||||
},
|
||||
{
|
||||
"type": "slider",
|
||||
@@ -182,7 +175,8 @@
|
||||
"encode": {
|
||||
"kind": "floatBits",
|
||||
"scale": 0.02
|
||||
}
|
||||
},
|
||||
"requiresVariant": 0
|
||||
},
|
||||
{
|
||||
"type": "slider",
|
||||
@@ -198,7 +192,8 @@
|
||||
"encode": {
|
||||
"kind": "floatBits",
|
||||
"scale": 0.02
|
||||
}
|
||||
},
|
||||
"requiresVariant": 0
|
||||
},
|
||||
{
|
||||
"type": "slider",
|
||||
@@ -214,7 +209,170 @@
|
||||
"encode": {
|
||||
"kind": "floatBits",
|
||||
"scale": 0.02
|
||||
}
|
||||
},
|
||||
"requiresVariant": 0
|
||||
},
|
||||
{
|
||||
"type": "toggle",
|
||||
"key": "kawarp_reactive",
|
||||
"title": "Playback Reactive",
|
||||
"description": "Cover shader reacts to playback state by freezing/resuming",
|
||||
"default": true,
|
||||
"token": "RL_KW_REACTIVE",
|
||||
"requiresVariant": 1
|
||||
},
|
||||
{
|
||||
"type": "slider",
|
||||
"key": "kawarp_blur",
|
||||
"title": "Blur Passes",
|
||||
"description": "Kawase blur passes, higher is softer but costs more GPU",
|
||||
"default": 5,
|
||||
"min": 1,
|
||||
"max": 40,
|
||||
"steps": 38,
|
||||
"displayAsPercent": false,
|
||||
"token": "RL_KW_BLUR",
|
||||
"encode": {
|
||||
"kind": "int",
|
||||
"scale": 1.0
|
||||
},
|
||||
"requiresVariant": 1
|
||||
},
|
||||
{
|
||||
"type": "slider",
|
||||
"key": "kawarp_warp",
|
||||
"title": "Warp Intensity",
|
||||
"description": "Strength of the fluidity effect",
|
||||
"default": 100,
|
||||
"min": 0,
|
||||
"max": 100,
|
||||
"steps": 19,
|
||||
"displayAsPercent": true,
|
||||
"token": "RL_KW_WARP",
|
||||
"encode": {
|
||||
"kind": "floatBits",
|
||||
"scale": 0.01
|
||||
},
|
||||
"requiresVariant": 1
|
||||
},
|
||||
{
|
||||
"type": "slider",
|
||||
"key": "kawarp_speed",
|
||||
"title": "Animation Speed",
|
||||
"description": "How fast the backdrop flows",
|
||||
"default": 175,
|
||||
"min": 0,
|
||||
"max": 500,
|
||||
"steps": 19,
|
||||
"displayAsPercent": true,
|
||||
"token": "RL_KW_SPEED",
|
||||
"encode": {
|
||||
"kind": "floatBits",
|
||||
"scale": 0.01
|
||||
},
|
||||
"requiresVariant": 1
|
||||
},
|
||||
{
|
||||
"type": "slider",
|
||||
"key": "kawarp_scale",
|
||||
"title": "Backdrop Scale",
|
||||
"description": "Zoom level of the effect",
|
||||
"default": 100,
|
||||
"min": 10,
|
||||
"max": 400,
|
||||
"steps": 12,
|
||||
"displayAsPercent": true,
|
||||
"token": "RL_KW_SCALE",
|
||||
"encode": {
|
||||
"kind": "floatBits",
|
||||
"scale": 0.01
|
||||
},
|
||||
"requiresVariant": 1
|
||||
},
|
||||
{
|
||||
"type": "slider",
|
||||
"key": "kawarp_contrast",
|
||||
"title": "Contrast",
|
||||
"description": "Contrast of the backdrop",
|
||||
"default": 125,
|
||||
"min": 0,
|
||||
"max": 300,
|
||||
"steps": 11,
|
||||
"displayAsPercent": true,
|
||||
"token": "RL_KW_CONTRAST",
|
||||
"encode": {
|
||||
"kind": "floatBits",
|
||||
"scale": 0.01
|
||||
},
|
||||
"requiresVariant": 1
|
||||
},
|
||||
{
|
||||
"type": "slider",
|
||||
"key": "kawarp_saturation",
|
||||
"title": "Saturation",
|
||||
"description": "Colour intensity of the backdrop",
|
||||
"default": 125,
|
||||
"min": 0,
|
||||
"max": 400,
|
||||
"steps": 15,
|
||||
"displayAsPercent": true,
|
||||
"token": "RL_KW_SAT",
|
||||
"encode": {
|
||||
"kind": "floatBits",
|
||||
"scale": 0.01
|
||||
},
|
||||
"requiresVariant": 1
|
||||
},
|
||||
{
|
||||
"type": "slider",
|
||||
"key": "kawarp_brightness",
|
||||
"title": "Brightness",
|
||||
"description": "The value of Brightness applied to the backdrop",
|
||||
"default": 100,
|
||||
"min": 0,
|
||||
"max": 200,
|
||||
"steps": 19,
|
||||
"displayAsPercent": true,
|
||||
"token": "RL_KW_BRIGHT",
|
||||
"encode": {
|
||||
"kind": "floatBits",
|
||||
"scale": 0.01
|
||||
},
|
||||
"requiresVariant": 1
|
||||
},
|
||||
{
|
||||
"type": "slider",
|
||||
"key": "kawarp_darken",
|
||||
"title": "Auto Darken Bright Covers",
|
||||
"description": "Prevents bright covers from making text unreadable",
|
||||
"default": 80,
|
||||
"min": 0,
|
||||
"max": 100,
|
||||
"steps": 19,
|
||||
"displayAsPercent": true,
|
||||
"token": "RL_KW_DARKEN",
|
||||
"encode": {
|
||||
"kind": "floatBits",
|
||||
"scale": 0.01
|
||||
},
|
||||
"requiresVariant": 1
|
||||
},
|
||||
{
|
||||
"type": "slider",
|
||||
"key": "kawarp_dither",
|
||||
"title": "Dithering",
|
||||
"description": "Breaks up color banding in smooth gradients",
|
||||
"default": 15,
|
||||
"min": 0,
|
||||
"max": 100,
|
||||
"steps": 19,
|
||||
"displayAsPercent": false,
|
||||
"token": "RL_KW_DITHER",
|
||||
"encode": {
|
||||
"kind": "floatBits",
|
||||
"scale": 0.001
|
||||
},
|
||||
"requiresVariant": 1
|
||||
},
|
||||
{
|
||||
"type": "toggle",
|
||||
|
||||
+3
@@ -37,6 +37,7 @@ import com.meowarex.rlmobile.ui.legacy.components.ResetToDefaultButton
|
||||
import com.meowarex.rlmobile.ui.screens.patchopts.OptionLock
|
||||
import com.meowarex.rlmobile.ui.screens.patchopts.OptionSpec
|
||||
import com.meowarex.rlmobile.ui.screens.patchopts.PatchOptionState
|
||||
import com.meowarex.rlmobile.ui.screens.patchopts.hiddenForVariant
|
||||
import com.meowarex.rlmobile.ui.screens.patchopts.optionLock
|
||||
import com.meowarex.rlmobile.ui.screens.patchopts.PatchSpec
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -109,6 +110,8 @@ fun PatchAdvancedOptionsSheet(
|
||||
when {
|
||||
option is OptionSpec.Toggle && option.inline -> false
|
||||
option is OptionSpec.Toggle && option.requiresOption in parentKeys -> false
|
||||
// Options belonging to another variant are hidden, not greyed out.
|
||||
option.hiddenForVariant(selectedVariant) -> false
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
+27
-2
@@ -1,6 +1,7 @@
|
||||
package com.meowarex.rlmobile.ui.screens.patchopts
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.Stable
|
||||
import kotlinx.serialization.SerialName
|
||||
@@ -49,7 +50,13 @@ data class VariantSpec(
|
||||
val fileNames: List<String> = emptyList(),
|
||||
val extensionFiles: List<String> = emptyList(),
|
||||
val enabled: Boolean = true,
|
||||
)
|
||||
/**
|
||||
* Hidden from the picker on devices below this API level (AGSL needs 33)
|
||||
*/
|
||||
val minSdk: Int = 0,
|
||||
) {
|
||||
val supportedHere: Boolean get() = Build.VERSION.SDK_INT >= minSdk
|
||||
}
|
||||
|
||||
/** A single advanced option. Discriminated by `"type"` in JSON. */
|
||||
@Serializable
|
||||
@@ -101,6 +108,8 @@ sealed interface OptionSpec {
|
||||
val token: String? = null,
|
||||
/** How the chosen value becomes the smali literal that replaces the token. */
|
||||
val encode: SmaliEncode? = null,
|
||||
/** Hidden unless this variant index is the selected one. */
|
||||
val requiresVariant: Int? = null,
|
||||
) : OptionSpec {
|
||||
val valueRange: ClosedFloatingPointRange<Float> get() = min..max
|
||||
}
|
||||
@@ -187,7 +196,9 @@ fun PatchSpec.effectiveVariants(isOptionOn: (OptionSpec.Toggle) -> Boolean): Lis
|
||||
}
|
||||
}
|
||||
return variants.mapIndexedNotNull { index, variant ->
|
||||
if (index in hidden) null
|
||||
// Everything downstream (variantIndex -> resolveVariantIndex) picks from this list, so
|
||||
// dropping an unsupported variant here also keeps the patcher from ever applying it.
|
||||
if (index in hidden || !variant.supportedHere) null
|
||||
else EffectiveVariant(index, relabel[index] ?: variant.title, variant.enabled)
|
||||
}
|
||||
}
|
||||
@@ -206,6 +217,20 @@ fun PatchSpec.resolveVariantIndex(stored: Int, isOptionOn: (OptionSpec.Toggle) -
|
||||
?: visible.first().originalIndex
|
||||
}
|
||||
|
||||
/**
|
||||
* The variant this option belongs to
|
||||
*/
|
||||
val OptionSpec.variantGate: Int?
|
||||
get() = when (this) {
|
||||
is OptionSpec.Toggle -> requiresVariant
|
||||
is OptionSpec.Slider -> requiresVariant
|
||||
is OptionSpec.Choice -> null
|
||||
is OptionSpec.Color -> null
|
||||
}
|
||||
|
||||
fun OptionSpec.hiddenForVariant(selectedVariant: Int): Boolean =
|
||||
variantGate.let { it != null && it != selectedVariant }
|
||||
|
||||
sealed interface OptionLock {
|
||||
data object Free : OptionLock
|
||||
data class NeedsVariant(val title: String) : OptionLock
|
||||
|
||||
+3
@@ -43,6 +43,7 @@ import com.meowarex.rlmobile.ui.components.ResetToDefaultButton
|
||||
import com.meowarex.rlmobile.ui.screens.patchopts.OptionLock
|
||||
import com.meowarex.rlmobile.ui.screens.patchopts.OptionSpec
|
||||
import com.meowarex.rlmobile.ui.screens.patchopts.PatchOptionState
|
||||
import com.meowarex.rlmobile.ui.screens.patchopts.hiddenForVariant
|
||||
import com.meowarex.rlmobile.ui.screens.patchopts.optionLock
|
||||
import com.meowarex.rlmobile.ui.screens.patchopts.PatchSpec
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -115,6 +116,8 @@ fun PatchAdvancedOptionsSheet(
|
||||
when {
|
||||
option is OptionSpec.Toggle && option.inline -> false
|
||||
option is OptionSpec.Toggle && option.requiresOption in parentKeys -> false
|
||||
// Options belonging to another variant are hidden, not greyed out.
|
||||
option.hiddenForVariant(selectedVariant) -> false
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user