Compare commits
16
Commits
09bc223b8b
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b312f54ae | ||
|
|
a1dcd25710 | ||
|
|
068c15d781 | ||
|
|
46c7bacd04 | ||
|
|
effdbe1c84 | ||
|
|
4b776663bb | ||
|
|
86f326a8b4 | ||
|
|
6b1b79062c | ||
|
|
a4ed30111c | ||
|
|
bd58bfd0a0 | ||
|
|
1fdbf82abd | ||
|
|
4fb48cc647 | ||
|
|
b018db1851 | ||
|
|
950a83c48d | ||
|
|
a7b2e3be8e | ||
|
|
55067e9761 |
@@ -19,15 +19,20 @@ jobs:
|
|||||||
# The JDK comes from the runner's tool cache. `cache: gradle` stores Gradle's
|
# The JDK comes from the runner's tool cache. `cache: gradle` stores Gradle's
|
||||||
# dependencies, Loom's Minecraft cache and the build cache in the runner's
|
# dependencies, Loom's Minecraft cache and the build cache in the runner's
|
||||||
# actions cache.
|
# actions cache.
|
||||||
- name: Set up Java 21
|
# 1.21.x builds with Java 21 and 26.x with Java 25. The last version listed is the default
|
||||||
|
# (Gradle runs on it), and the Gradle commands below point toolchain detection at both.
|
||||||
|
- name: Set up Java 25 and 21
|
||||||
uses: actions/setup-java@v5
|
uses: actions/setup-java@v5
|
||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: temurin
|
||||||
java-version: 21
|
java-version: |
|
||||||
|
25
|
||||||
|
21
|
||||||
cache: gradle
|
cache: gradle
|
||||||
|
|
||||||
- name: Compile all versions
|
- name: Compile all versions
|
||||||
run: |
|
run: |
|
||||||
chmod +x gradlew
|
chmod +x gradlew
|
||||||
# --continue reports every version that fails, not just the first.
|
# --continue reports every version that fails, not just the first.
|
||||||
./gradlew compileJava --no-daemon --stacktrace --continue
|
./gradlew compileJava --no-daemon --stacktrace --continue \
|
||||||
|
-Porg.gradle.java.installations.fromEnv=JAVA_HOME_21_X64,JAVA_HOME_25_X64
|
||||||
|
|||||||
@@ -47,11 +47,15 @@ jobs:
|
|||||||
# The JDK comes from the runner's tool cache. `cache: gradle` stores Gradle's
|
# The JDK comes from the runner's tool cache. `cache: gradle` stores Gradle's
|
||||||
# dependencies, Loom's Minecraft cache and the build cache in the runner's
|
# dependencies, Loom's Minecraft cache and the build cache in the runner's
|
||||||
# actions cache.
|
# actions cache.
|
||||||
- name: Set up Java 21
|
# 1.21.x builds with Java 21 and 26.x with Java 25. The last version listed is the default
|
||||||
|
# (Gradle runs on it), and the Gradle commands below point toolchain detection at both.
|
||||||
|
- name: Set up Java 25 and 21
|
||||||
uses: actions/setup-java@v5
|
uses: actions/setup-java@v5
|
||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: temurin
|
||||||
java-version: 21
|
java-version: |
|
||||||
|
25
|
||||||
|
21
|
||||||
cache: gradle
|
cache: gradle
|
||||||
|
|
||||||
- name: Build all versions
|
- name: Build all versions
|
||||||
@@ -59,7 +63,8 @@ jobs:
|
|||||||
chmod +x gradlew
|
chmod +x gradlew
|
||||||
# buildAll remaps every Minecraft version (two at a time, to stay within the
|
# buildAll remaps every Minecraft version (two at a time, to stay within the
|
||||||
# Gradle heap) into build/allJars.
|
# Gradle heap) into build/allJars.
|
||||||
./gradlew buildAll --no-daemon --stacktrace
|
./gradlew buildAll --no-daemon --stacktrace \
|
||||||
|
-Porg.gradle.java.installations.fromEnv=JAVA_HOME_21_X64,JAVA_HOME_25_X64
|
||||||
|
|
||||||
- name: Upload jars to the release
|
- name: Upload jars to the release
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
Saturn Client is a free, open-source Minecraft client designed to enhance the gameplay experience while staying lightweight and customizable.
|
Saturn Client is a free, open-source Minecraft client designed to enhance the gameplay experience while staying lightweight and customizable.
|
||||||
Our goal is to build a clean, optimized client that the community can contribute to and improve together.
|
Our goal is to build a clean, optimized client that the community can contribute to and improve together.
|
||||||
|
|
||||||
Saturn runs on Fabric and supports **Minecraft 1.21.4 to 1.21.11**, with one build per version. If something doesn't work on your version, please open an issue.
|
Saturn runs on Fabric and supports **Minecraft 1.21.4 to 1.21.11 and 26.1 to 26.3**, with one build per version (the 26.1 build also runs on 26.1.1 and 26.1.2). If something doesn't work on your version, please open an issue.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ cd saturnclient
|
|||||||
./gradlew :1.21.11:runClient # launch a development client
|
./gradlew :1.21.11:runClient # launch a development client
|
||||||
```
|
```
|
||||||
|
|
||||||
Building needs Java 21.
|
Building needs Java 21. The 26.x versions compile with Java 25, which Gradle downloads when it isn't installed.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
|||||||
+12
-6
@@ -4,21 +4,27 @@ How Saturn Client supports several Minecraft versions, and how to change or add
|
|||||||
|
|
||||||
## Layout
|
## Layout
|
||||||
|
|
||||||
Every supported Minecraft version (1.21.4 to 1.21.11) builds from one copy of the version-specific code with [Stonecutter](https://stonecutter.kikugie.dev/):
|
Every supported Minecraft version (1.21.4 to 1.21.11, and 26.1 to 26.3) builds from one copy of the version-specific code with [Stonecutter](https://stonecutter.kikugie.dev/):
|
||||||
|
|
||||||
- `common/`: all version-independent code (mods, UI, cosmetics, the server client). It has no Minecraft dependency and reaches the game only through the interfaces in `org.saturnclient.common`.
|
- `common/`: all version-independent code (mods, UI, cosmetics, the server client). It has no Minecraft dependency and reaches the game only through the interfaces in `org.saturnclient.common`.
|
||||||
- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs), one copy for every version. Where Minecraft's API differs between versions, the code goes behind version comments (see below).
|
- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs), one copy for every version. Where Minecraft's API differs between versions, the code goes behind version comments (see below).
|
||||||
- `versions/<mc>/`: each version's `gradle.properties` (Minecraft, Fabric Loader and Fabric API versions), plus its `build/` and `run/` folders. Each version is the Gradle project `:<mc>`.
|
- `versions/<mc>/`: each version's `gradle.properties` (Minecraft, Fabric Loader and Fabric API versions), plus its `build/` and `run/` folders. Each version is the Gradle project `:<mc>`.
|
||||||
|
|
||||||
`settings.gradle.kts` lists the versions in `stonecutterVersions`. The root `build.gradle.kts` builds each version, and `stonecutter.gradle.kts` configures the root project (shared repositories, the `common` wiring and `buildAll`). Loom's version is `loom_version` in the root `gradle.properties`.
|
`settings.gradle.kts` lists the versions in `stonecutterVersions`. The root `build.gradle.kts` builds each version, and `stonecutter.gradle.kts` configures the root project (shared repositories, the `common` wiring and `buildAll`). Loom's version is `loomx.loom_version` in the root `gradle.properties`.
|
||||||
|
|
||||||
|
Minecraft is obfuscated up to 1.21.11 and ships with Mojang's names from 26.1. The `loom-back-compat` plugin (`loomx`) applies the matching Loom for each version: the remapping one for 1.21.x, whose jar is `remapJar`'s output, and the plain one for 26.x, whose jar is `jar`'s. 26.x also compiles with Java 25 (21 before), set per version in `build.gradle.kts`; Gradle downloads a missing JDK through the foojay resolver, and CI installs both. An optional `minecraft_compat` in a version's `gradle.properties` widens the Minecraft versions its jar loads on, as 26.1's does for its hotfixes.
|
||||||
|
|
||||||
## Mappings
|
## Mappings
|
||||||
|
|
||||||
Every version is built with Mojang's official names (`loom.officialMojangMappings()`), the names Minecraft itself ships from 26.1 on. Yarn isn't used any more: 1.21.11 has the last Yarn release.
|
Every version is built with Mojang's official names (`loom.officialMojangMappings()`), the names Minecraft itself ships from 26.1 on. Yarn isn't used any more: 1.21.11 has the last Yarn release.
|
||||||
|
|
||||||
Mojang renamed a few classes within 1.21.x. `src/` uses the newest names, and `stonecutter.gradle.kts` lists replacements that swap in the older name when Stonecutter processes an older version (for example `Identifier`, which was `ResourceLocation` before 1.21.11, and `AvatarRenderState`, which was `PlayerRenderState` before 1.21.9). Add a replacement there when a rename touches many lines. A class that only moved package needs just a version comment on its import, and a renamed method a version comment where it's called.
|
Mojang renames things between versions. `src/` uses the active version's (1.21.11's) names, and `stonecutter.gradle.kts` lists replacements that swap in each version's name when Stonecutter processes it: for example `Identifier`, which was `ResourceLocation` before 1.21.11, `AvatarRenderState`, which was `PlayerRenderState` before 1.21.9, and `GuiGraphics`, which is `GuiGraphicsExtractor` from 26.1. Add a replacement there when a rename touches many lines, and only for a name that appears nowhere else in `src/`: replacements work both ways, so the new name is also turned back into the old one for older versions (a `mulPose`/`rotate` replacement would rename `MatrixStackRef.rotate` too). From 26.2 the open screen and overlay live on `Gui` rather than `Minecraft`, so code goes through `impl.ui.Screens` for them.
|
||||||
|
|
||||||
Released jars run on intermediary names (`method_1234`), not Mojang's, and Loom renames everything that refers to Minecraft when it builds them. So a mixin can't implement one of `common`'s Ref interfaces by relying on a vanilla method that happens to have the same name: the vanilla method is renamed in the jar, and the interface method is left without an implementation (`AbstractMethodError`). Shadow the vanilla method and implement the Ref method explicitly, as `WindowMixin` does. For the same reason, Ref methods mustn't share a name and parameters with a method of the class they're mixed into, or the mixin replaces the vanilla method in development.
|
From 26.3 Minecraft uses SDL instead of GLFW, with SDL's numbers for keys (scancodes), modifiers and mouse buttons. Saturn keeps GLFW's numbers, which `common` uses and the config's keybinds store, and `impl.provider.Keys` converts at the boundary: key events and mouse buttons coming in, and key codes going to the game. Use `InputConstants`' key constants rather than GLFW's in version-specific code.
|
||||||
|
|
||||||
|
26.3 also compiles every shader through SPIR-V, so shader inputs and outputs need an explicit `layout(location = …)`. Saturn's `glass.fsh` is shared by every version from 1.21.6 and switches its layout with the defines `GlassRenderer` sets, as it already did for `HAS_LINE_WIDTH`. A class that only moved package needs just a version comment on its import, and a renamed method a version comment where it's called.
|
||||||
|
|
||||||
|
Released 1.21.x jars run on intermediary names (`method_1234`), not Mojang's, and Loom renames everything that refers to Minecraft when it builds them. So a mixin can't implement one of `common`'s Ref interfaces by relying on a vanilla method that happens to have the same name: the vanilla method is renamed in the jar, and the interface method is left without an implementation (`AbstractMethodError`). Shadow the vanilla method and implement the Ref method explicitly, as `WindowMixin` does. For the same reason, Ref methods mustn't share a name and parameters with a method of the class they're mixed into, or the mixin replaces the vanilla method in development.
|
||||||
|
|
||||||
## Version-specific code with Stonecutter
|
## Version-specific code with Stonecutter
|
||||||
|
|
||||||
@@ -48,7 +54,7 @@ When a newer version leaves something out that an older one implements, keep the
|
|||||||
|
|
||||||
A whole class that only exists for some versions (such as `MatrixStackMixin`, which only makes sense before 1.21.6's GUI rewrite) can keep an empty class body on the other versions. Before splitting a class like that, look for a hook that works on every version: nametags used to hook label rendering, which 1.21.9 changed, and now replace the name while the render state is built (`LivingEntityRendererMixin`), with no version condition at all. An empty mixin changes nothing, and it keeps the mixin configs the same for every version, since JSON can't hold version comments.
|
A whole class that only exists for some versions (such as `MatrixStackMixin`, which only makes sense before 1.21.6's GUI rewrite) can keep an empty class body on the other versions. Before splitting a class like that, look for a hook that works on every version: nametags used to hook label rendering, which 1.21.9 changed, and now replace the name while the render state is built (`LivingEntityRendererMixin`), with no version condition at all. An empty mixin changes nothing, and it keeps the mixin configs the same for every version, since JSON can't hold version comments.
|
||||||
|
|
||||||
Inactive code sits inside a `/* … */` comment, so it can't contain `/* … */` comments itself: use `//` comments in code that's only active for some versions. For the same reason, don't nest multi-line version blocks; use `//?} else if <condition> {` for more than two version ranges, as in `PlayerEntityRendererMixin` and `SaturnRenderState`.
|
Inactive code sits inside a `/* … */` comment, so it can't contain `/* … */` comments itself: use `//` comments in code that's only active for some versions. Version blocks can nest (Stonecutter writes an inactive block inside another as `/^ … ^/`, as in `GlassRenderer`), but for more than two ranges of the same thing, prefer `//?} else if <condition> {`, as in `PlayerEntityRendererMixin` and `SaturnRenderState`.
|
||||||
|
|
||||||
- `./gradlew "Set active project to <mc>"` (or the Stonecutter IntelliJ plugin) rewrites `src/` so that version's code is the uncommented one, for editing it in the IDE.
|
- `./gradlew "Set active project to <mc>"` (or the Stonecutter IntelliJ plugin) rewrites `src/` so that version's code is the uncommented one, for editing it in the IDE.
|
||||||
- `./gradlew "Reset active project"` switches back to 1.21.11. **Run it before committing**, so `src/` is always committed with 1.21.11 active.
|
- `./gradlew "Reset active project"` switches back to 1.21.11. **Run it before committing**, so `src/` is always committed with 1.21.11 active.
|
||||||
@@ -72,5 +78,5 @@ For bigger changes, `./gradlew buildAll` builds every version's jar into `build/
|
|||||||
|
|
||||||
1. Create `versions/<new>/gradle.properties` with `minecraft_version`, `loader_version` and `fabric_api_version` (copy 1.21.11's and change the values; they're listed at <https://fabricmc.net/develop>). Loom's version is shared, in the root `gradle.properties`.
|
1. Create `versions/<new>/gradle.properties` with `minecraft_version`, `loader_version` and `fabric_api_version` (copy 1.21.11's and change the values; they're listed at <https://fabricmc.net/develop>). Loom's version is shared, in the root `gradle.properties`.
|
||||||
2. Add `<new>` to `stonecutterVersions` in `settings.gradle.kts`.
|
2. Add `<new>` to `stonecutterVersions` in `settings.gradle.kts`.
|
||||||
3. Build it with `./gradlew :<new>:compileJava` and put what Minecraft changed behind version comments. Check the mixin configs in `src/main/resources/*.mixins.json` as well: a mixin whose target changed fails at startup, not at compile time, so launch it with `./gradlew :<new>:runClient`.
|
3. Build it with `./gradlew :<new>:compileJava` and put what Minecraft changed behind version comments. Check the mixin configs in `src/main/resources/*.mixins.json` as well: a mixin whose target changed fails at startup (or when its class first loads, such as in a world), not at compile time, so launch it with `./gradlew :<new>:runClient`.
|
||||||
4. The release workflow builds everything through `buildAll`, and "Publish to Modrinth" takes the game version from each jar's name, so neither needs changing.
|
4. The release workflow builds everything through `buildAll`, and "Publish to Modrinth" takes the game version from each jar's name, so neither needs changing.
|
||||||
|
|||||||
+10
-7
@@ -1,11 +1,14 @@
|
|||||||
// Builds one Minecraft version from the shared src/. Stonecutter runs this for each version in
|
// Builds one Minecraft version from the shared src/. Stonecutter runs this for each version in
|
||||||
// stonecutterVersions (settings.gradle.kts), with that version's versions/<v>/gradle.properties.
|
// stonecutterVersions (settings.gradle.kts), with that version's versions/<v>/gradle.properties.
|
||||||
plugins {
|
plugins {
|
||||||
id("net.fabricmc.fabric-loom-remap")
|
id("dev.kikugie.loom-back-compat")
|
||||||
`maven-publish`
|
`maven-publish`
|
||||||
}
|
}
|
||||||
|
|
||||||
val minecraftVersion = property("minecraft_version") as String
|
val minecraftVersion = property("minecraft_version") as String
|
||||||
|
// The Minecraft versions the jar loads on (fabric.mod.json); a range where hotfixes share a jar.
|
||||||
|
val minecraftCompat = findProperty("minecraft_compat") as String? ?: minecraftVersion
|
||||||
|
val javaVersion = if (sc.current.parsed >= "26.1") 25 else 21
|
||||||
val loaderVersion = property("loader_version") as String
|
val loaderVersion = property("loader_version") as String
|
||||||
|
|
||||||
version = "${property("mod_version")}+$minecraftVersion"
|
version = "${property("mod_version")}+$minecraftVersion"
|
||||||
@@ -17,7 +20,7 @@ base {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft("com.mojang:minecraft:$minecraftVersion")
|
minecraft("com.mojang:minecraft:$minecraftVersion")
|
||||||
mappings(loom.officialMojangMappings())
|
loomx.applyMojangMappings()
|
||||||
modImplementation("net.fabricmc:fabric-loader:$loaderVersion")
|
modImplementation("net.fabricmc:fabric-loader:$loaderVersion")
|
||||||
modImplementation("net.fabricmc.fabric-api:fabric-api:${property("fabric_api_version")}")
|
modImplementation("net.fabricmc.fabric-api:fabric-api:${property("fabric_api_version")}")
|
||||||
|
|
||||||
@@ -42,23 +45,23 @@ dependencies {
|
|||||||
tasks.processResources {
|
tasks.processResources {
|
||||||
val values = mapOf(
|
val values = mapOf(
|
||||||
"version" to project.version.toString(),
|
"version" to project.version.toString(),
|
||||||
"minecraft_version" to minecraftVersion,
|
"minecraft_version" to minecraftCompat,
|
||||||
"loader_version" to loaderVersion,
|
"loader_version" to loaderVersion,
|
||||||
|
"java" to "JAVA_$javaVersion",
|
||||||
)
|
)
|
||||||
inputs.properties(values)
|
inputs.properties(values)
|
||||||
filteringCharset = "UTF-8"
|
filteringCharset = "UTF-8"
|
||||||
filesMatching("fabric.mod.json") { expand(values) }
|
filesMatching(listOf("fabric.mod.json", "*.mixins.json")) { expand(values) }
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<JavaCompile>().configureEach {
|
tasks.withType<JavaCompile>().configureEach {
|
||||||
options.release = 21
|
options.release = javaVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
// Loom attaches the sources jar to remapSourcesJar and build.
|
// Loom attaches the sources jar to remapSourcesJar and build.
|
||||||
withSourcesJar()
|
withSourcesJar()
|
||||||
sourceCompatibility = JavaVersion.VERSION_21
|
toolchain.languageVersion = JavaLanguageVersion.of(javaVersion)
|
||||||
targetCompatibility = JavaVersion.VERSION_21
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.jar {
|
tasks.jar {
|
||||||
|
|||||||
+1
-1
Submodule common updated: a6a324a61a...e8f686b2d3
+4
-4
@@ -6,10 +6,10 @@ org.gradle.caching=true
|
|||||||
# IntelliJ IDEA is not yet fully compatible with configuration cache, see: https://github.com/FabricMC/fabric-loom/issues/1349
|
# IntelliJ IDEA is not yet fully compatible with configuration cache, see: https://github.com/FabricMC/fabric-loom/issues/1349
|
||||||
org.gradle.configuration-cache=false
|
org.gradle.configuration-cache=false
|
||||||
|
|
||||||
mod_version=0.1.4-beta
|
mod_version=0.1.5-beta
|
||||||
|
|
||||||
# Saturn's emote library (git.selimaj.dev/saturnclientmc/emotes)
|
# Saturn's emote library (git.selimaj.dev/saturnclientmc/emotes)
|
||||||
emotes_version=0.1.1
|
emotes_version=0.1.2
|
||||||
|
|
||||||
# Loom, for every Minecraft version (read in settings.gradle.kts).
|
# Loom, for every Minecraft version (read by loom-back-compat).
|
||||||
loom_version=1.17.21
|
loomx.loom_version=1.17.21
|
||||||
|
|||||||
+9
-7
@@ -5,16 +5,15 @@ pluginManagement {
|
|||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loom's version for build.gradle.kts, which can't read properties in its plugins block.
|
|
||||||
val loom_version: String by settings
|
|
||||||
plugins {
|
|
||||||
id("net.fabricmc.fabric-loom-remap") version loom_version
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
|
// Downloads the Java toolchain a version needs (Java 25 for 26.1+) when it isn't installed.
|
||||||
|
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
|
||||||
id("dev.kikugie.stonecutter") version "0.9.8"
|
id("dev.kikugie.stonecutter") version "0.9.8"
|
||||||
|
// Picks the Loom variant per version: remapping for 1.21.x, plain for the unobfuscated 26.1+.
|
||||||
|
// Its version is loomx.loom_version in gradle.properties.
|
||||||
|
id("dev.kikugie.loom-back-compat") version "0.4.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
rootProject.name = "saturn-client"
|
rootProject.name = "saturn-client"
|
||||||
@@ -23,7 +22,10 @@ include("common")
|
|||||||
|
|
||||||
// Versions built by Stonecutter from the shared src/ (see stonecutter.gradle.kts). Each one's
|
// Versions built by Stonecutter from the shared src/ (see stonecutter.gradle.kts). Each one's
|
||||||
// versions/<v>/gradle.properties holds its Minecraft, Fabric Loader and Fabric API versions.
|
// versions/<v>/gradle.properties holds its Minecraft, Fabric Loader and Fabric API versions.
|
||||||
val stonecutterVersions = listOf("1.21.4", "1.21.5", "1.21.6", "1.21.7", "1.21.8", "1.21.9", "1.21.10", "1.21.11")
|
val stonecutterVersions = listOf(
|
||||||
|
"1.21.4", "1.21.5", "1.21.6", "1.21.7", "1.21.8", "1.21.9", "1.21.10", "1.21.11",
|
||||||
|
"26.1", "26.2", "26.3",
|
||||||
|
)
|
||||||
|
|
||||||
stonecutter {
|
stonecutter {
|
||||||
create(rootProject) {
|
create(rootProject) {
|
||||||
|
|||||||
@@ -435,7 +435,11 @@ public class CloakFeatureRenderer extends RenderLayer<AvatarRenderState, PlayerM
|
|||||||
matrices.translate(top[0] / 16.0f, top[1] / 16.0f, top[2] / 16.0f);
|
matrices.translate(top[0] / 16.0f, top[1] / 16.0f, top[2] / 16.0f);
|
||||||
|
|
||||||
Vec3 axis = bend.axis();
|
Vec3 axis = bend.axis();
|
||||||
matrices.mulPose(new Quaternionf().rotationAxis(bend.angleAt(0), axis.x(), axis.y(), axis.z()));
|
Quaternionf rotation = new Quaternionf().rotationAxis(bend.angleAt(0), axis.x(), axis.y(), axis.z());
|
||||||
|
//? if >=26.3 {
|
||||||
|
/*matrices.rotate(rotation);
|
||||||
|
*///?} else
|
||||||
|
matrices.mulPose(rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shift array left and insert new value at the start
|
// Shift array left and insert new value at the start
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import net.minecraft.client.renderer.SubmitNodeCollector;
|
|||||||
//?} else
|
//?} else
|
||||||
//import net.minecraft.client.renderer.MultiBufferSource;
|
//import net.minecraft.client.renderer.MultiBufferSource;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import org.joml.Quaternionf;
|
||||||
import net.minecraft.server.packs.resources.Resource;
|
import net.minecraft.server.packs.resources.Resource;
|
||||||
import net.minecraft.server.packs.resources.ResourceManager;
|
import net.minecraft.server.packs.resources.ResourceManager;
|
||||||
import net.minecraft.resources.Identifier;
|
import net.minecraft.resources.Identifier;
|
||||||
@@ -89,21 +90,29 @@ public class ObjModel {
|
|||||||
int light, int overlay) {
|
int light, int overlay) {
|
||||||
matrices.pushPose();
|
matrices.pushPose();
|
||||||
|
|
||||||
matrices.mulPose(com.mojang.math.Axis.XP.rotationDegrees(180.0f));
|
rotate(matrices, com.mojang.math.Axis.XP.rotationDegrees(180.0f));
|
||||||
matrices.mulPose(com.mojang.math.Axis.YP.rotationDegrees(180.0f));
|
rotate(matrices, com.mojang.math.Axis.YP.rotationDegrees(180.0f));
|
||||||
|
|
||||||
if (this.config != null) {
|
if (this.config != null) {
|
||||||
matrices.translate(config.transform.x, config.transform.y, config.transform.z);
|
matrices.translate(config.transform.x, config.transform.y, config.transform.z);
|
||||||
|
|
||||||
matrices.scale(config.scale.x, config.scale.y, config.scale.z);
|
matrices.scale(config.scale.x, config.scale.y, config.scale.z);
|
||||||
|
|
||||||
matrices.mulPose(com.mojang.math.Axis.XP.rotationDegrees(config.rotation.x));
|
rotate(matrices, com.mojang.math.Axis.XP.rotationDegrees(config.rotation.x));
|
||||||
matrices.mulPose(com.mojang.math.Axis.YP.rotationDegrees(config.rotation.y));
|
rotate(matrices, com.mojang.math.Axis.YP.rotationDegrees(config.rotation.y));
|
||||||
matrices.mulPose(com.mojang.math.Axis.ZP.rotationDegrees(config.rotation.z));
|
rotate(matrices, com.mojang.math.Axis.ZP.rotationDegrees(config.rotation.z));
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjRenderer.renderObj(this.obj, mtlMap, matrices, output, light, overlay);
|
ObjRenderer.renderObj(this.obj, mtlMap, matrices, output, light, overlay);
|
||||||
|
|
||||||
matrices.popPose();
|
matrices.popPose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 26.3 renamed PoseStack's quaternion mulPose to rotate.
|
||||||
|
private static void rotate(PoseStack matrices, Quaternionf rotation) {
|
||||||
|
//? if >=26.3 {
|
||||||
|
/*matrices.rotate(rotation);
|
||||||
|
*///?} else
|
||||||
|
matrices.mulPose(rotation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,12 @@ import net.minecraft.client.renderer.blockentity.AbstractEndPortalRenderer;
|
|||||||
import net.minecraft.client.renderer.blockentity.TheEndPortalRenderer;
|
import net.minecraft.client.renderer.blockentity.TheEndPortalRenderer;
|
||||||
*///?}
|
*///?}
|
||||||
import net.minecraft.resources.Identifier;
|
import net.minecraft.resources.Identifier;
|
||||||
|
//? if >=26.3
|
||||||
|
//import com.mojang.renderpearl.api.pipeline.ColorTargetState;
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
*///?}
|
||||||
|
|
||||||
public class ShaderUtils {
|
public class ShaderUtils {
|
||||||
// Render pipelines exist from 1.21.5; before that the layer names a shader program directly.
|
// Render pipelines exist from 1.21.5; before that the layer names a shader program directly.
|
||||||
@@ -87,8 +93,30 @@ public class ShaderUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cosmetics are drawn unlit, without the lightmap or the directional shading, as the dragon's
|
||||||
|
// alpha pipeline drew them before 26.1. 26.1 dropped that pipeline, so this is the entity shader
|
||||||
|
// with its lighting and overlay turned off.
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*public static final RenderPipeline UNLIT_CUTOUT_PIPELINE = RenderPipelines.register(
|
||||||
|
RenderPipeline.builder(new RenderPipeline.Snippet[] {
|
||||||
|
RenderPipelines.ENTITY_EMISSIVE_SNIPPET })
|
||||||
|
.withLocation(Identifier.fromNamespaceAndPath("saturnclient", "pipeline/unlit_cutout"))
|
||||||
|
.withShaderDefine("ALPHA_CUTOUT", 0.1f)
|
||||||
|
.withShaderDefine("NO_CARDINAL_LIGHTING")
|
||||||
|
.withShaderDefine("NO_OVERLAY")
|
||||||
|
.withCull(false)
|
||||||
|
// From 26.3 the snippet leaves the color target to each pipeline.
|
||||||
|
//? if >=26.3
|
||||||
|
//.withColorTargetState(ColorTargetState.DEFAULT)
|
||||||
|
.build());
|
||||||
|
private static final Map<Identifier, RenderType> UNLIT_CUTOUT = new HashMap<>();
|
||||||
|
*///?}
|
||||||
|
|
||||||
private static RenderType entityAlpha(Identifier texture) {
|
private static RenderType entityAlpha(Identifier texture) {
|
||||||
//? if >=1.21.11 {
|
//? if >=26.1 {
|
||||||
|
/*return UNLIT_CUTOUT.computeIfAbsent(texture, id -> RenderType.create("saturn_unlit_cutout",
|
||||||
|
RenderSetup.builder(UNLIT_CUTOUT_PIPELINE).withTexture("Sampler0", id).createRenderSetup()));
|
||||||
|
*///?} else if >=1.21.11 {
|
||||||
return RenderTypes.dragonExplosionAlpha(texture);
|
return RenderTypes.dragonExplosionAlpha(texture);
|
||||||
//?} else
|
//?} else
|
||||||
//return RenderType.dragonExplosionAlpha(texture);
|
//return RenderType.dragonExplosionAlpha(texture);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.saturnclient.impl.features.mixins.entity;
|
package org.saturnclient.impl.features.mixins.entity;
|
||||||
|
|
||||||
import org.saturnclient.impl.features.entity.CameraOverriddenEntity;
|
import org.saturnclient.impl.features.entity.CameraOverriddenEntity;
|
||||||
|
import org.saturnclient.impl.features.render.ZoomFov;
|
||||||
import org.saturnclient.mod.mods.FreelookMod;
|
import org.saturnclient.mod.mods.FreelookMod;
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
@@ -9,6 +10,8 @@ import org.spongepowered.asm.mixin.Unique;
|
|||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
//? if >=26.1
|
||||||
|
//import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
import net.minecraft.client.player.LocalPlayer;
|
import net.minecraft.client.player.LocalPlayer;
|
||||||
import net.minecraft.client.Camera;
|
import net.minecraft.client.Camera;
|
||||||
@@ -26,17 +29,38 @@ public abstract class CameraMixin {
|
|||||||
@Shadow
|
@Shadow
|
||||||
protected abstract void setRotation(float yaw, float pitch);
|
protected abstract void setRotation(float yaw, float pitch);
|
||||||
|
|
||||||
|
// Freelook keeps the camera's rotation after vanilla points it along the entity's view. From 26.1
|
||||||
|
// that happens in alignWithEntity, which takes the camera's own entity.
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*@Shadow
|
||||||
|
public abstract Entity entity();
|
||||||
|
|
||||||
|
@Inject(method = "alignWithEntity", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;setRotation(FF)V", ordinal = 1, shift = At.Shift.AFTER))
|
||||||
|
public void lockRotation(float tickDelta, CallbackInfo ci) {
|
||||||
|
saturn$lockRotation(entity());
|
||||||
|
}
|
||||||
|
|
||||||
|
// The camera works out the FOV from 26.1 (GameRenderer.getFov before).
|
||||||
|
@Inject(method = "calculateFov", at = @At("RETURN"), cancellable = true)
|
||||||
|
private void onCalculateFov(float tickDelta, CallbackInfoReturnable<Float> cir) {
|
||||||
|
cir.setReturnValue(ZoomFov.apply(cir.getReturnValue()));
|
||||||
|
}
|
||||||
|
*///?} else if >=1.21.11 {
|
||||||
@Inject(method = "setup", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;setRotation(FF)V", ordinal = 1, shift = At.Shift.AFTER))
|
@Inject(method = "setup", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;setRotation(FF)V", ordinal = 1, shift = At.Shift.AFTER))
|
||||||
public void lockRotation(
|
public void lockRotation(Level focusedBlock, Entity cameraEntity, boolean isThirdPerson, boolean isFrontFacing,
|
||||||
//? if >=1.21.11 {
|
float tickDelta, CallbackInfo ci) {
|
||||||
Level focusedBlock,
|
saturn$lockRotation(cameraEntity);
|
||||||
//?} else
|
}
|
||||||
//BlockGetter focusedBlock,
|
//?} else {
|
||||||
Entity cameraEntity,
|
/*@Inject(method = "setup", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;setRotation(FF)V", ordinal = 1, shift = At.Shift.AFTER))
|
||||||
boolean isThirdPerson,
|
public void lockRotation(BlockGetter focusedBlock, Entity cameraEntity, boolean isThirdPerson, boolean isFrontFacing,
|
||||||
boolean isFrontFacing,
|
float tickDelta, CallbackInfo ci) {
|
||||||
float tickDelta,
|
saturn$lockRotation(cameraEntity);
|
||||||
CallbackInfo ci) {
|
}
|
||||||
|
*///?}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private void saturn$lockRotation(Entity cameraEntity) {
|
||||||
if (FreelookMod.isFreeLooking() && cameraEntity instanceof LocalPlayer) {
|
if (FreelookMod.isFreeLooking() && cameraEntity instanceof LocalPlayer) {
|
||||||
CameraOverriddenEntity cameraOverriddenEntity = (CameraOverriddenEntity) cameraEntity;
|
CameraOverriddenEntity cameraOverriddenEntity = (CameraOverriddenEntity) cameraEntity;
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,9 @@ import net.minecraft.client.renderer.GameRenderer;
|
|||||||
|
|
||||||
//? if >=1.21.6
|
//? if >=1.21.6
|
||||||
import org.saturnclient.impl.ui.SaturnScreenFabric;
|
import org.saturnclient.impl.ui.SaturnScreenFabric;
|
||||||
import org.saturnclient.mod.mods.FreelookMod;
|
//? if >=1.21.6
|
||||||
import org.saturnclient.mod.mods.ZoomMod;
|
import org.saturnclient.impl.ui.Screens;
|
||||||
|
import org.saturnclient.impl.features.render.ZoomFov;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
@@ -18,11 +19,11 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
|||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides the game's field-of-view when {@link ZoomMod} is active.
|
* Overrides the game's field-of-view when {@link org.saturnclient.mod.mods.ZoomMod} is active.
|
||||||
*
|
*
|
||||||
* The old code checked both {@code Zoom.isZooming} and
|
* The old code checked both {@code Zoom.isZooming} and
|
||||||
* {@code Zoom.shouldZoom()} separately. The refactored
|
* {@code Zoom.shouldZoom()} separately. The refactored
|
||||||
* {@link ZoomMod#shouldZoom()} already ORs both conditions
|
* {@link org.saturnclient.mod.mods.ZoomMod#shouldZoom()} already ORs both conditions
|
||||||
* ({@code enabled.value && isZooming}), so only one check is needed.
|
* ({@code enabled.value && isZooming}), so only one check is needed.
|
||||||
*
|
*
|
||||||
* No {@link org.saturnclient.common.module.ModProvider} is required
|
* No {@link org.saturnclient.common.module.ModProvider} is required
|
||||||
@@ -36,24 +37,25 @@ public class GameRendererMixin {
|
|||||||
* After the vanilla FOV has been computed, divide it by the zoom
|
* After the vanilla FOV has been computed, divide it by the zoom
|
||||||
* level to produce the narrowed field-of-view.
|
* level to produce the narrowed field-of-view.
|
||||||
*/
|
*/
|
||||||
|
// From 26.1 the camera works out the FOV, so CameraMixin applies the zoom there.
|
||||||
|
//? if <26.1 {
|
||||||
@Inject(method = "getFov", at = @At("RETURN"), cancellable = true)
|
@Inject(method = "getFov", at = @At("RETURN"), cancellable = true)
|
||||||
private void onGetFov(CallbackInfoReturnable<Float> cir) {
|
private void onGetFov(CallbackInfoReturnable<Float> cir) {
|
||||||
if (ZoomMod.shouldZoom()) {
|
cir.setReturnValue(ZoomFov.apply(cir.getReturnValue()));
|
||||||
float zoomedFov = cir.getReturnValue() / ZoomMod.getZoomLevel();
|
|
||||||
cir.setReturnValue(zoomedFov);
|
|
||||||
} else if (FreelookMod.shouldZoomOut()) {
|
|
||||||
float zoomedFov = cir.getReturnValue() / FreelookMod.getZoomLevel();
|
|
||||||
cir.setReturnValue(zoomedFov);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
//?}
|
||||||
|
|
||||||
//? if >=1.21.6 {
|
//? if >=1.21.6 {
|
||||||
// From 1.21.6 the menu blur's strength is the vanilla setting, read here every frame. While a
|
// From 1.21.6 the menu blur's strength is the vanilla setting, read here every frame. While a
|
||||||
// Saturn screen is open, it's Saturn's background blur instead, faded in with the screen.
|
// Saturn screen is open, it's Saturn's background blur instead, faded in with the screen.
|
||||||
|
// From 26.1 the setting is read while extracting the options' render state.
|
||||||
|
//? if >=26.1
|
||||||
|
//@Redirect(method = "extractOptions", at = @At(value = "INVOKE",
|
||||||
|
//? if <26.1
|
||||||
@Redirect(method = "render", at = @At(value = "INVOKE",
|
@Redirect(method = "render", at = @At(value = "INVOKE",
|
||||||
target = "Lnet/minecraft/client/Options;getMenuBackgroundBlurriness()I"))
|
target = "Lnet/minecraft/client/Options;getMenuBackgroundBlurriness()I"))
|
||||||
private int useSaturnBlur(Options options) {
|
private int useSaturnBlur(Options options) {
|
||||||
if (Minecraft.getInstance().screen instanceof SaturnScreenFabric saturnScreen) {
|
if (Screens.current() instanceof SaturnScreenFabric saturnScreen) {
|
||||||
return saturnScreen.screen.getBackgroundBlur();
|
return saturnScreen.screen.getBackgroundBlur();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
@@ -3,6 +3,9 @@ package org.saturnclient.impl.features.mixins.render;
|
|||||||
// Code approach adapted from Gamma Utils: https://github.com/Sjouwer/gamma-utils
|
// Code approach adapted from Gamma Utils: https://github.com/Sjouwer/gamma-utils
|
||||||
|
|
||||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*import net.minecraft.client.renderer.LightmapRenderStateExtractor;
|
||||||
|
*///?} else
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
|
|
||||||
import org.saturnclient.mod.mods.FullbrightMod;
|
import org.saturnclient.mod.mods.FullbrightMod;
|
||||||
@@ -18,6 +21,10 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||||||
* it is now {@link FullbrightMod}. The injection target and
|
* it is now {@link FullbrightMod}. The injection target and
|
||||||
* strategy are unchanged.
|
* strategy are unchanged.
|
||||||
*/
|
*/
|
||||||
|
// From 26.1 the gamma is worked out while extracting the lightmap's render state.
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*@Mixin(LightmapRenderStateExtractor.class)
|
||||||
|
*///?} else
|
||||||
@Mixin(LightTexture.class)
|
@Mixin(LightTexture.class)
|
||||||
public class LightmapTextureManagerMixin {
|
public class LightmapTextureManagerMixin {
|
||||||
|
|
||||||
@@ -25,6 +32,9 @@ public class LightmapTextureManagerMixin {
|
|||||||
* If fullbright is active, substitute the feature's brightness
|
* If fullbright is active, substitute the feature's brightness
|
||||||
* value for whatever vanilla calculated.
|
* value for whatever vanilla calculated.
|
||||||
*/
|
*/
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*@ModifyExpressionValue(method = "extract", at = @At(value = "INVOKE", target = "Ljava/lang/Math;max(FF)F", ordinal = 0))
|
||||||
|
*///?} else
|
||||||
@ModifyExpressionValue(method = "updateLightTexture", at = @At(value = "INVOKE", target = "Ljava/lang/Math;max(FF)F", ordinal = 0))
|
@ModifyExpressionValue(method = "updateLightTexture", at = @At(value = "INVOKE", target = "Ljava/lang/Math;max(FF)F", ordinal = 0))
|
||||||
private float modifyGamma(float original) {
|
private float modifyGamma(float original) {
|
||||||
if (FullbrightMod.shouldOverrideBrightness()) {
|
if (FullbrightMod.shouldOverrideBrightness()) {
|
||||||
|
|||||||
@@ -2,11 +2,15 @@ package org.saturnclient.impl.features.mixins.render;
|
|||||||
|
|
||||||
import net.minecraft.client.gui.Font;
|
import net.minecraft.client.gui.Font;
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
//? if >=26.2 {
|
||||||
|
/*import net.minecraft.client.gui.Hud;
|
||||||
|
*///?} else
|
||||||
import net.minecraft.client.gui.Gui;
|
import net.minecraft.client.gui.Gui;
|
||||||
import net.minecraft.client.DeltaTracker;
|
import net.minecraft.client.DeltaTracker;
|
||||||
|
|
||||||
import org.saturnclient.impl.ui.RenderScopeImpl;
|
import org.saturnclient.impl.ui.RenderScopeImpl;
|
||||||
import org.saturnclient.impl.ui.SaturnScreenFabric;
|
import org.saturnclient.impl.ui.SaturnScreenFabric;
|
||||||
|
import org.saturnclient.impl.ui.Screens;
|
||||||
import org.saturnclient.mod.HudMod;
|
import org.saturnclient.mod.HudMod;
|
||||||
import org.saturnclient.mod.Mod;
|
import org.saturnclient.mod.Mod;
|
||||||
import org.saturnclient.mod.ModLayout;
|
import org.saturnclient.mod.ModLayout;
|
||||||
@@ -37,9 +41,16 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
* {@link SaturnScreenFabric} / {@link HudEditor} pair; that is
|
* {@link SaturnScreenFabric} / {@link HudEditor} pair; that is
|
||||||
* unchanged infrastructure.
|
* unchanged infrastructure.
|
||||||
*/
|
*/
|
||||||
|
// The HUD is drawn by Hud from 26.2 (by Gui before).
|
||||||
|
//? if >=26.2 {
|
||||||
|
/*@Mixin(Hud.class)
|
||||||
|
*///?} else
|
||||||
@Mixin(Gui.class)
|
@Mixin(Gui.class)
|
||||||
public class RenderMixin {
|
public class RenderMixin {
|
||||||
|
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*@Inject(method = "extractChat", at = @At("TAIL"))
|
||||||
|
*///?} else
|
||||||
@Inject(method = "renderChat", at = @At("TAIL"))
|
@Inject(method = "renderChat", at = @At("TAIL"))
|
||||||
public void renderMods(GuiGraphics context, DeltaTracker tickCounter, CallbackInfo ci) {
|
public void renderMods(GuiGraphics context, DeltaTracker tickCounter, CallbackInfo ci) {
|
||||||
Font textRenderer = SaturnClient.client.font;
|
Font textRenderer = SaturnClient.client.font;
|
||||||
@@ -48,7 +59,7 @@ public class RenderMixin {
|
|||||||
// can draw its own preview layout without double-drawing.
|
// can draw its own preview layout without double-drawing.
|
||||||
if (textRenderer == null)
|
if (textRenderer == null)
|
||||||
return;
|
return;
|
||||||
if (SaturnClient.client.screen instanceof SaturnScreenFabric f
|
if (Screens.current() instanceof SaturnScreenFabric f
|
||||||
&& f.screen instanceof HudEditor)
|
&& f.screen instanceof HudEditor)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package org.saturnclient.impl.features.render;
|
||||||
|
|
||||||
|
import org.saturnclient.mod.mods.FreelookMod;
|
||||||
|
import org.saturnclient.mod.mods.ZoomMod;
|
||||||
|
|
||||||
|
/** The zoom mods' change to the field of view, applied where each version computes it. */
|
||||||
|
public final class ZoomFov {
|
||||||
|
private ZoomFov() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float apply(float fov) {
|
||||||
|
if (ZoomMod.shouldZoom()) {
|
||||||
|
return fov / ZoomMod.getZoomLevel();
|
||||||
|
} else if (FreelookMod.shouldZoomOut()) {
|
||||||
|
return fov / FreelookMod.getZoomLevel();
|
||||||
|
}
|
||||||
|
return fov;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,11 +4,11 @@ import java.io.File;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.saturnclient.common.ref.asset.IdentifierRef;
|
import org.saturnclient.common.ref.asset.IdentifierRef;
|
||||||
import org.saturnclient.common.ref.game.MinecraftClientRef;
|
import org.saturnclient.common.ref.game.MinecraftClientRef;
|
||||||
import org.saturnclient.common.ref.render.WindowRef;
|
import org.saturnclient.common.ref.render.WindowRef;
|
||||||
import org.saturnclient.impl.ui.SaturnScreenFabric;
|
import org.saturnclient.impl.ui.SaturnScreenFabric;
|
||||||
|
import org.saturnclient.impl.ui.Screens;
|
||||||
import org.saturnclient.ui.SaturnScreen;
|
import org.saturnclient.ui.SaturnScreen;
|
||||||
import org.saturnclient.ui.screens.TitleMenu;
|
import org.saturnclient.ui.screens.TitleMenu;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
@@ -16,7 +16,6 @@ import org.spongepowered.asm.mixin.Shadow;
|
|||||||
|
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
|
||||||
import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen;
|
import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen;
|
||||||
import net.minecraft.client.gui.screens.options.OptionsScreen;
|
import net.minecraft.client.gui.screens.options.OptionsScreen;
|
||||||
import net.minecraft.client.gui.screens.worldselection.SelectWorldScreen;
|
import net.minecraft.client.gui.screens.worldselection.SelectWorldScreen;
|
||||||
@@ -43,9 +42,6 @@ public abstract class MinecraftClientMixin implements MinecraftClientRef {
|
|||||||
@Shadow
|
@Shadow
|
||||||
private User user;
|
private User user;
|
||||||
|
|
||||||
@Shadow
|
|
||||||
public abstract void setScreen(@Nullable Screen screen);
|
|
||||||
|
|
||||||
@Shadow
|
@Shadow
|
||||||
public abstract void stop();
|
public abstract void stop();
|
||||||
|
|
||||||
@@ -75,7 +71,7 @@ public abstract class MinecraftClientMixin implements MinecraftClientRef {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setScreen(SaturnScreen screen) {
|
public void setScreen(SaturnScreen screen) {
|
||||||
this.setScreen(new SaturnScreenFabric(screen));
|
Screens.set(new SaturnScreenFabric(screen));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -84,15 +80,21 @@ public abstract class MinecraftClientMixin implements MinecraftClientRef {
|
|||||||
|
|
||||||
switch (screen) {
|
switch (screen) {
|
||||||
case SelectWorld:
|
case SelectWorld:
|
||||||
this.setScreen(new SelectWorldScreen(exitTarget));
|
Screens.set(new SelectWorldScreen(exitTarget));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Multiplayer:
|
case Multiplayer:
|
||||||
this.setScreen(new JoinMultiplayerScreen(exitTarget));
|
Screens.set(new JoinMultiplayerScreen(exitTarget));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Options:
|
case Options:
|
||||||
this.setScreen(new OptionsScreen(exitTarget, this.options));
|
// Only 26.1 and 26.2 take whether a world is open.
|
||||||
|
//? if >=26.3 {
|
||||||
|
/*Screens.set(new OptionsScreen(exitTarget, this.options));
|
||||||
|
*///?} else if >=26.1 {
|
||||||
|
/*Screens.set(new OptionsScreen(exitTarget, this.options, ((Minecraft) (Object) this).level != null));
|
||||||
|
*///?} else
|
||||||
|
Screens.set(new OptionsScreen(exitTarget, this.options));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ import org.saturnclient.common.ref.game.EffectRef;
|
|||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
//? if >=26.2 {
|
||||||
|
/*import net.minecraft.client.gui.Hud;
|
||||||
|
*///?} else
|
||||||
import net.minecraft.client.gui.Gui;
|
import net.minecraft.client.gui.Gui;
|
||||||
import net.minecraft.world.effect.MobEffect;
|
import net.minecraft.world.effect.MobEffect;
|
||||||
import net.minecraft.world.effect.MobEffectInstance;
|
import net.minecraft.world.effect.MobEffectInstance;
|
||||||
@@ -55,6 +58,9 @@ public abstract class StatusEffectMixin implements EffectRef {
|
|||||||
//? if >=1.21.6 {
|
//? if >=1.21.6 {
|
||||||
@Override
|
@Override
|
||||||
public IdentifierRef getIconId() {
|
public IdentifierRef getIconId() {
|
||||||
|
//? if >=26.2 {
|
||||||
|
/*Identifier id = Hud.getMobEffectSprite(getEffect());
|
||||||
|
*///?} else
|
||||||
Identifier id = Gui.getMobEffectSprite(getEffect());
|
Identifier id = Gui.getMobEffectSprite(getEffect());
|
||||||
|
|
||||||
return IdentifierRef.of(id.getNamespace(), "textures/" + id.getPath() + ".png");
|
return IdentifierRef.of(id.getNamespace(), "textures/" + id.getPath() + ".png");
|
||||||
|
|||||||
@@ -1,22 +1,36 @@
|
|||||||
package org.saturnclient.impl.provider;
|
package org.saturnclient.impl.provider;
|
||||||
|
|
||||||
|
// 26.3 uses SDL, not GLFW; Keys converts Saturn's GLFW key codes to its own.
|
||||||
|
//? if >=26.3 {
|
||||||
|
/*import com.mojang.blaze3d.platform.InputConstants;
|
||||||
|
*///?} else
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
import org.saturnclient.common.provider.GLFWProvider;
|
import org.saturnclient.common.provider.GLFWProvider;
|
||||||
|
import org.saturnclient.impl.ui.Screens;
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
import org.saturnclient.saturnclient.SaturnClient;
|
||||||
|
|
||||||
public class GLFWProviderImpl implements GLFWProvider {
|
public class GLFWProviderImpl implements GLFWProvider {
|
||||||
@Override
|
@Override
|
||||||
public boolean isKeyPressed(int key) {
|
public boolean isKeyPressed(int key) {
|
||||||
|
//? if >=26.3 {
|
||||||
|
/*int gameKey = Keys.toGame(key);
|
||||||
|
return gameKey >= 0 && InputConstants.isKeyDown(gameKey) && Screens.current() == null;
|
||||||
|
*///?} else {
|
||||||
//? if >=1.21.9 {
|
//? if >=1.21.9 {
|
||||||
long window = SaturnClient.client.getWindow().handle();
|
long window = SaturnClient.client.getWindow().handle();
|
||||||
//?} else
|
//?} else
|
||||||
//long window = SaturnClient.client.getWindow().getWindow();
|
//long window = SaturnClient.client.getWindow().getWindow();
|
||||||
return GLFW.glfwGetKey(window, key) == GLFW.GLFW_PRESS
|
return GLFW.glfwGetKey(window, key) == GLFW.GLFW_PRESS
|
||||||
&& SaturnClient.client.screen == null;
|
&& Screens.current() == null;
|
||||||
|
//?}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getKeyName(int key) {
|
public String getKeyName(int key) {
|
||||||
|
//? if >=26.3 {
|
||||||
|
/*int gameKey = Keys.toGame(key);
|
||||||
|
return gameKey < 0 ? null : InputConstants.Type.KEYBOARD.getOrCreate(gameKey).getDisplayName().getString();
|
||||||
|
*///?} else
|
||||||
return GLFW.glfwGetKeyName(key, GLFW.glfwGetKeyScancode(key));
|
return GLFW.glfwGetKeyName(key, GLFW.glfwGetKeyScancode(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,189 @@
|
|||||||
|
package org.saturnclient.impl.provider;
|
||||||
|
|
||||||
|
//? if >=26.3 {
|
||||||
|
/*import com.mojang.blaze3d.platform.InputConstants;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||||
|
import org.saturnclient.common.provider.GLFWProvider;
|
||||||
|
*///?}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saturn's key codes are GLFW's, which the config's keybinds store. From 26.3 Minecraft uses SDL,
|
||||||
|
* whose keys (scancodes), modifiers and mouse buttons are numbered differently, so these convert
|
||||||
|
* between the two there. Before 26.3 Minecraft's numbers are GLFW's and pass through.
|
||||||
|
*/
|
||||||
|
public final class Keys {
|
||||||
|
private Keys() {
|
||||||
|
}
|
||||||
|
|
||||||
|
//? if >=26.3 {
|
||||||
|
/*private static final Int2IntOpenHashMap TO_GAME = new Int2IntOpenHashMap();
|
||||||
|
private static final Int2IntOpenHashMap TO_SATURN = new Int2IntOpenHashMap();
|
||||||
|
|
||||||
|
private static void key(int glfw, int game) {
|
||||||
|
TO_GAME.put(glfw, game);
|
||||||
|
TO_SATURN.put(game, glfw);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GLFW's key codes, and the same keys' constants in 26.3
|
||||||
|
static {
|
||||||
|
TO_GAME.defaultReturnValue(-1);
|
||||||
|
TO_SATURN.defaultReturnValue(-1);
|
||||||
|
key(32, InputConstants.KEY_SPACE);
|
||||||
|
key(39, InputConstants.KEY_APOSTROPHE);
|
||||||
|
key(44, InputConstants.KEY_COMMA);
|
||||||
|
key(45, InputConstants.KEY_MINUS);
|
||||||
|
key(46, InputConstants.KEY_PERIOD);
|
||||||
|
key(47, InputConstants.KEY_SLASH);
|
||||||
|
key(48, InputConstants.KEY_0);
|
||||||
|
key(49, InputConstants.KEY_1);
|
||||||
|
key(50, InputConstants.KEY_2);
|
||||||
|
key(51, InputConstants.KEY_3);
|
||||||
|
key(52, InputConstants.KEY_4);
|
||||||
|
key(53, InputConstants.KEY_5);
|
||||||
|
key(54, InputConstants.KEY_6);
|
||||||
|
key(55, InputConstants.KEY_7);
|
||||||
|
key(56, InputConstants.KEY_8);
|
||||||
|
key(57, InputConstants.KEY_9);
|
||||||
|
key(59, InputConstants.KEY_SEMICOLON);
|
||||||
|
key(61, InputConstants.KEY_EQUALS);
|
||||||
|
key(65, InputConstants.KEY_A);
|
||||||
|
key(66, InputConstants.KEY_B);
|
||||||
|
key(67, InputConstants.KEY_C);
|
||||||
|
key(68, InputConstants.KEY_D);
|
||||||
|
key(69, InputConstants.KEY_E);
|
||||||
|
key(70, InputConstants.KEY_F);
|
||||||
|
key(71, InputConstants.KEY_G);
|
||||||
|
key(72, InputConstants.KEY_H);
|
||||||
|
key(73, InputConstants.KEY_I);
|
||||||
|
key(74, InputConstants.KEY_J);
|
||||||
|
key(75, InputConstants.KEY_K);
|
||||||
|
key(76, InputConstants.KEY_L);
|
||||||
|
key(77, InputConstants.KEY_M);
|
||||||
|
key(78, InputConstants.KEY_N);
|
||||||
|
key(79, InputConstants.KEY_O);
|
||||||
|
key(80, InputConstants.KEY_P);
|
||||||
|
key(81, InputConstants.KEY_Q);
|
||||||
|
key(82, InputConstants.KEY_R);
|
||||||
|
key(83, InputConstants.KEY_S);
|
||||||
|
key(84, InputConstants.KEY_T);
|
||||||
|
key(85, InputConstants.KEY_U);
|
||||||
|
key(86, InputConstants.KEY_V);
|
||||||
|
key(87, InputConstants.KEY_W);
|
||||||
|
key(88, InputConstants.KEY_X);
|
||||||
|
key(89, InputConstants.KEY_Y);
|
||||||
|
key(90, InputConstants.KEY_Z);
|
||||||
|
key(91, InputConstants.KEY_LBRACKET);
|
||||||
|
key(92, InputConstants.KEY_BACKSLASH);
|
||||||
|
key(93, InputConstants.KEY_RBRACKET);
|
||||||
|
key(96, InputConstants.KEY_GRAVE);
|
||||||
|
key(256, InputConstants.KEY_ESCAPE);
|
||||||
|
key(257, InputConstants.KEY_RETURN);
|
||||||
|
key(258, InputConstants.KEY_TAB);
|
||||||
|
key(259, InputConstants.KEY_BACKSPACE);
|
||||||
|
key(260, InputConstants.KEY_INSERT);
|
||||||
|
key(261, InputConstants.KEY_DELETE);
|
||||||
|
key(262, InputConstants.KEY_RIGHT);
|
||||||
|
key(263, InputConstants.KEY_LEFT);
|
||||||
|
key(264, InputConstants.KEY_DOWN);
|
||||||
|
key(265, InputConstants.KEY_UP);
|
||||||
|
key(266, InputConstants.KEY_PAGEUP);
|
||||||
|
key(267, InputConstants.KEY_PAGEDOWN);
|
||||||
|
key(268, InputConstants.KEY_HOME);
|
||||||
|
key(269, InputConstants.KEY_END);
|
||||||
|
key(280, InputConstants.KEY_CAPSLOCK);
|
||||||
|
key(281, InputConstants.KEY_SCROLLLOCK);
|
||||||
|
key(282, InputConstants.KEY_NUMLOCK);
|
||||||
|
key(283, InputConstants.KEY_PRINTSCREEN);
|
||||||
|
key(284, InputConstants.KEY_PAUSE);
|
||||||
|
key(290, InputConstants.KEY_F1);
|
||||||
|
key(291, InputConstants.KEY_F2);
|
||||||
|
key(292, InputConstants.KEY_F3);
|
||||||
|
key(293, InputConstants.KEY_F4);
|
||||||
|
key(294, InputConstants.KEY_F5);
|
||||||
|
key(295, InputConstants.KEY_F6);
|
||||||
|
key(296, InputConstants.KEY_F7);
|
||||||
|
key(297, InputConstants.KEY_F8);
|
||||||
|
key(298, InputConstants.KEY_F9);
|
||||||
|
key(299, InputConstants.KEY_F10);
|
||||||
|
key(300, InputConstants.KEY_F11);
|
||||||
|
key(301, InputConstants.KEY_F12);
|
||||||
|
key(302, InputConstants.KEY_F13);
|
||||||
|
key(303, InputConstants.KEY_F14);
|
||||||
|
key(304, InputConstants.KEY_F15);
|
||||||
|
key(305, InputConstants.KEY_F16);
|
||||||
|
key(306, InputConstants.KEY_F17);
|
||||||
|
key(307, InputConstants.KEY_F18);
|
||||||
|
key(308, InputConstants.KEY_F19);
|
||||||
|
key(309, InputConstants.KEY_F20);
|
||||||
|
key(310, InputConstants.KEY_F21);
|
||||||
|
key(311, InputConstants.KEY_F22);
|
||||||
|
key(312, InputConstants.KEY_F23);
|
||||||
|
key(313, InputConstants.KEY_F24);
|
||||||
|
key(320, InputConstants.KEY_NUMPAD0);
|
||||||
|
key(321, InputConstants.KEY_NUMPAD1);
|
||||||
|
key(322, InputConstants.KEY_NUMPAD2);
|
||||||
|
key(323, InputConstants.KEY_NUMPAD3);
|
||||||
|
key(324, InputConstants.KEY_NUMPAD4);
|
||||||
|
key(325, InputConstants.KEY_NUMPAD5);
|
||||||
|
key(326, InputConstants.KEY_NUMPAD6);
|
||||||
|
key(327, InputConstants.KEY_NUMPAD7);
|
||||||
|
key(328, InputConstants.KEY_NUMPAD8);
|
||||||
|
key(329, InputConstants.KEY_NUMPAD9);
|
||||||
|
key(330, InputConstants.KEY_NUMPADCOMMA);
|
||||||
|
key(332, InputConstants.KEY_MULTIPLY);
|
||||||
|
key(334, InputConstants.KEY_ADD);
|
||||||
|
key(335, InputConstants.KEY_NUMPADENTER);
|
||||||
|
key(336, InputConstants.KEY_NUMPADEQUALS);
|
||||||
|
key(340, InputConstants.KEY_LSHIFT);
|
||||||
|
key(341, InputConstants.KEY_LCONTROL);
|
||||||
|
key(342, InputConstants.KEY_LALT);
|
||||||
|
key(343, InputConstants.KEY_LGUI);
|
||||||
|
key(344, InputConstants.KEY_RSHIFT);
|
||||||
|
key(345, InputConstants.KEY_RCONTROL);
|
||||||
|
key(346, InputConstants.KEY_RALT);
|
||||||
|
key(347, InputConstants.KEY_RGUI);
|
||||||
|
}
|
||||||
|
*///?}
|
||||||
|
|
||||||
|
/** A Saturn (GLFW) key code as the game's, or -1 */
|
||||||
|
public static int toGame(int key) {
|
||||||
|
//? if >=26.3 {
|
||||||
|
/*return TO_GAME.get(key);
|
||||||
|
*///?} else
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A key code from the game as Saturn's (GLFW), or -1 */
|
||||||
|
public static int toSaturn(int key) {
|
||||||
|
//? if >=26.3 {
|
||||||
|
/*return TO_SATURN.get(key);
|
||||||
|
*///?} else
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The game's modifier flags as GLFW's */
|
||||||
|
public static int modifiersToSaturn(int modifiers) {
|
||||||
|
//? if >=26.3 {
|
||||||
|
/*int glfw = 0;
|
||||||
|
if ((modifiers & InputConstants.MOD_SHIFT) != 0) glfw |= GLFWProvider.GLFW_MOD_SHIFT;
|
||||||
|
if ((modifiers & InputConstants.MOD_CONTROL) != 0) glfw |= GLFWProvider.GLFW_MOD_CONTROL;
|
||||||
|
if ((modifiers & InputConstants.MOD_ALT) != 0) glfw |= GLFWProvider.GLFW_MOD_ALT;
|
||||||
|
if ((modifiers & InputConstants.MOD_SUPER) != 0) glfw |= GLFWProvider.GLFW_MOD_SUPER;
|
||||||
|
if ((modifiers & InputConstants.MOD_CAPS_LOCK) != 0) glfw |= GLFWProvider.GLFW_MOD_CAPS_LOCK;
|
||||||
|
if ((modifiers & InputConstants.MOD_NUM_LOCK) != 0) glfw |= GLFWProvider.GLFW_MOD_NUM_LOCK;
|
||||||
|
return glfw;
|
||||||
|
*///?} else
|
||||||
|
return modifiers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A mouse button from the game as GLFW's (left 0, right 1, middle 2, then the side buttons) */
|
||||||
|
public static int mouseButtonToSaturn(int button) {
|
||||||
|
//? if >=26.3 {
|
||||||
|
/*if (button == InputConstants.MOUSE_BUTTON_LEFT) return 0;
|
||||||
|
if (button == InputConstants.MOUSE_BUTTON_RIGHT) return 1;
|
||||||
|
if (button == InputConstants.MOUSE_BUTTON_MIDDLE) return 2;
|
||||||
|
return button - 1;
|
||||||
|
*///?} else
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -86,8 +86,13 @@ public class SaturnProviderImpl implements SaturnProvider {
|
|||||||
@Override
|
@Override
|
||||||
public void showWarning(String title, String message) {
|
public void showWarning(String title, String message) {
|
||||||
Minecraft client = Minecraft.getInstance();
|
Minecraft client = Minecraft.getInstance();
|
||||||
|
//? if >=26.2 {
|
||||||
|
/*client.execute(() -> SystemToast.add(client.gui.toastManager(), WARNING_TOAST, Component.literal(title),
|
||||||
|
Component.literal(message)));
|
||||||
|
*///?} else {
|
||||||
client.execute(() -> client.getToastManager().addToast(
|
client.execute(() -> client.getToastManager().addToast(
|
||||||
SystemToast.multiline(client, WARNING_TOAST, Component.literal(title), Component.literal(message))));
|
SystemToast.multiline(client, WARNING_TOAST, Component.literal(title), Component.literal(message))));
|
||||||
|
//?}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -17,7 +17,11 @@ package org.saturnclient.impl.ui;
|
|||||||
//? if >=1.21.6 {
|
//? if >=1.21.6 {
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
//? if >=26.1
|
||||||
|
//import java.util.LinkedHashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
//? if >=26.1
|
||||||
|
//import java.util.Set;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
@@ -37,6 +41,14 @@ import net.minecraft.client.renderer.PostChain;
|
|||||||
import net.minecraft.client.renderer.RenderPipelines;
|
import net.minecraft.client.renderer.RenderPipelines;
|
||||||
import com.mojang.blaze3d.pipeline.TextureTarget;
|
import com.mojang.blaze3d.pipeline.TextureTarget;
|
||||||
import net.minecraft.client.renderer.LevelTargetBundle;
|
import net.minecraft.client.renderer.LevelTargetBundle;
|
||||||
|
//? if >=26.2 {
|
||||||
|
/*import com.mojang.blaze3d.GpuFormat;
|
||||||
|
import net.minecraft.client.renderer.BindGroupLayouts;
|
||||||
|
*///?}
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*import net.minecraft.client.renderer.Projection;
|
||||||
|
import net.minecraft.client.renderer.ProjectionMatrixBuffer;
|
||||||
|
*///?} else
|
||||||
import net.minecraft.client.renderer.CachedOrthoProjectionMatrixBuffer;
|
import net.minecraft.client.renderer.CachedOrthoProjectionMatrixBuffer;
|
||||||
import net.minecraft.client.renderer.texture.AbstractTexture;
|
import net.minecraft.client.renderer.texture.AbstractTexture;
|
||||||
import net.minecraft.client.gui.render.TextureSetup;
|
import net.minecraft.client.gui.render.TextureSetup;
|
||||||
@@ -47,13 +59,28 @@ public final class GlassRenderer {
|
|||||||
public static final RenderPipeline PIPELINE = RenderPipeline.builder(RenderPipelines.GUI_TEXTURED_SNIPPET)
|
public static final RenderPipeline PIPELINE = RenderPipeline.builder(RenderPipelines.GUI_TEXTURED_SNIPPET)
|
||||||
.withLocation(Identifier.fromNamespaceAndPath("saturnclient", "pipeline/glass"))
|
.withLocation(Identifier.fromNamespaceAndPath("saturnclient", "pipeline/glass"))
|
||||||
.withFragmentShader(Identifier.fromNamespaceAndPath("saturnclient", "core/glass"))
|
.withFragmentShader(Identifier.fromNamespaceAndPath("saturnclient", "core/glass"))
|
||||||
|
//? if >=26.2 {
|
||||||
|
/*.withBindGroupLayout(BindGroupLayouts.SAMPLER1)
|
||||||
|
*///?} else
|
||||||
.withSampler("Sampler1")
|
.withSampler("Sampler1")
|
||||||
// The transforms block ends with LineWidth before 1.21.11 (see glass.fsh).
|
// The transforms block ends with LineWidth before 1.21.11 (see glass.fsh).
|
||||||
//? if <1.21.11
|
//? if <1.21.11
|
||||||
//.withShaderDefine("HAS_LINE_WIDTH")
|
//.withShaderDefine("HAS_LINE_WIDTH")
|
||||||
|
// 26.3 compiles through SPIR-V and moved TextureMat up the transforms block.
|
||||||
|
//? if >=26.3
|
||||||
|
//.withShaderDefine("EXPLICIT_LOCATIONS").withShaderDefine("TEXTURE_MAT_SECOND")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
private static final Identifier BLUR = Identifier.withDefaultNamespace("post_effect/blur.json");
|
private static final Identifier BLUR = Identifier.withDefaultNamespace("post_effect/blur.json");
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*private static final Projection PROJECTION = new Projection();
|
||||||
|
private static final ProjectionMatrixBuffer PROJECTION_BUFFER = new ProjectionMatrixBuffer("saturn glass");
|
||||||
|
|
||||||
|
static {
|
||||||
|
// As vanilla sets up its post chains' projection; the chain sizes it when it runs.
|
||||||
|
PROJECTION.setupOrtho(0.1f, 1000f, 1f, 1f, false);
|
||||||
|
}
|
||||||
|
*///?} else
|
||||||
private static final CachedOrthoProjectionMatrixBuffer PROJECTION = new CachedOrthoProjectionMatrixBuffer("saturn glass", 0.1f, 1000f, false);
|
private static final CachedOrthoProjectionMatrixBuffer PROJECTION = new CachedOrthoProjectionMatrixBuffer("saturn glass", 0.1f, 1000f, false);
|
||||||
// For the blurs' intermediate targets, freed once unused for a few frames
|
// For the blurs' intermediate targets, freed once unused for a few frames
|
||||||
private static final CrossFrameResourcePool POOL = new CrossFrameResourcePool(3);
|
private static final CrossFrameResourcePool POOL = new CrossFrameResourcePool(3);
|
||||||
@@ -65,15 +92,35 @@ public final class GlassRenderer {
|
|||||||
private GlassRenderer() {
|
private GlassRenderer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// From 26.1 the GUI is built before the frame's world is drawn, so the main framebuffer still
|
||||||
|
// holds the last frame, glass included. The copies wait until the GUI renderer is about to draw
|
||||||
|
// (GuiRendererMixin), when it holds this frame's world and panorama.
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*private static final Set<Integer> PENDING = new LinkedHashSet<>();
|
||||||
|
*///?}
|
||||||
|
|
||||||
|
private static RenderTarget mainTarget() {
|
||||||
|
//? if >=26.2 {
|
||||||
|
/*return SaturnClient.client.gameRenderer.mainRenderTarget();
|
||||||
|
*///?} else
|
||||||
|
return SaturnClient.client.getMainRenderTarget();
|
||||||
|
}
|
||||||
|
|
||||||
// Copies the main framebuffer and blurs the copy by blur. Call once a frame for each blur, while
|
// Copies the main framebuffer and blurs the copy by blur. Call once a frame for each blur, while
|
||||||
// the screen builds its GUI, before drawing glass with it.
|
// the screen builds its GUI, before drawing glass with it.
|
||||||
public static void captureBackdrop(int blur) {
|
public static void captureBackdrop(int blur) {
|
||||||
RenderTarget main = SaturnClient.client.getMainRenderTarget();
|
RenderTarget main = mainTarget();
|
||||||
int width = main.width;
|
int width = main.width;
|
||||||
int height = main.height;
|
int height = main.height;
|
||||||
|
|
||||||
TextureTarget backdrop = BACKDROPS.get(blur);
|
TextureTarget backdrop = BACKDROPS.get(blur);
|
||||||
if (backdrop == null) {
|
if (backdrop == null) {
|
||||||
|
// From 26.3 the depth format picks the depth buffer (none here); 26.2 takes a flag.
|
||||||
|
//? if >=26.3 {
|
||||||
|
/*backdrop = new TextureTarget("Saturn glass " + blur, width, height, GpuFormat.RGBA8_UNORM, null);
|
||||||
|
*///?} else if >=26.2 {
|
||||||
|
/*backdrop = new TextureTarget("Saturn glass " + blur, width, height, false, GpuFormat.RGBA8_UNORM);
|
||||||
|
*///?} else
|
||||||
backdrop = new TextureTarget("Saturn glass " + blur, width, height, false);
|
backdrop = new TextureTarget("Saturn glass " + blur, width, height, false);
|
||||||
BACKDROPS.put(blur, backdrop);
|
BACKDROPS.put(blur, backdrop);
|
||||||
} else if (backdrop.width != width || backdrop.height != height) {
|
} else if (backdrop.width != width || backdrop.height != height) {
|
||||||
@@ -82,6 +129,29 @@ public final class GlassRenderer {
|
|||||||
//? if <1.21.11
|
//? if <1.21.11
|
||||||
//backdrop.getColorTexture().setTextureFilter(FilterMode.LINEAR, false);
|
//backdrop.getColorTexture().setTextureFilter(FilterMode.LINEAR, false);
|
||||||
|
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*PENDING.add(blur);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copies and blurs the backdrops the GUI asked for this frame. GuiRendererMixin calls it once the
|
||||||
|
// world and the panorama are drawn, before the GUI.
|
||||||
|
public static void blurPendingBackdrops() {
|
||||||
|
RenderTarget main = mainTarget();
|
||||||
|
for (int blur : PENDING) {
|
||||||
|
TextureTarget backdrop = BACKDROPS.get(blur);
|
||||||
|
// The GUI already refers to the backdrop's texture, so after a resize it keeps the last
|
||||||
|
// frame's until the next one.
|
||||||
|
if (backdrop != null && backdrop.width == main.width && backdrop.height == main.height) {
|
||||||
|
blurBackdrop(main, backdrop, blur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PENDING.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void blurBackdrop(RenderTarget main, TextureTarget backdrop, int blur) {
|
||||||
|
int width = main.width;
|
||||||
|
int height = main.height;
|
||||||
|
*///?}
|
||||||
RenderSystem.getDevice().createCommandEncoder().copyTextureToTexture(
|
RenderSystem.getDevice().createCommandEncoder().copyTextureToTexture(
|
||||||
main.getColorTexture(), backdrop.getColorTexture(), 0, 0, 0, 0, 0, width, height);
|
main.getColorTexture(), backdrop.getColorTexture(), 0, 0, 0, 0, 0, width, height);
|
||||||
|
|
||||||
@@ -106,6 +176,9 @@ public final class GlassRenderer {
|
|||||||
private static void release(int kept) {
|
private static void release(int kept) {
|
||||||
BACKDROPS.entrySet().removeIf(entry -> {
|
BACKDROPS.entrySet().removeIf(entry -> {
|
||||||
boolean unused = entry.getKey() != kept && !isSet(entry.getKey());
|
boolean unused = entry.getKey() != kept && !isSet(entry.getKey());
|
||||||
|
// The GUI already refers to this frame's pending backdrops.
|
||||||
|
//? if >=26.1
|
||||||
|
//unused &= !PENDING.contains(entry.getKey());
|
||||||
if (unused) {
|
if (unused) {
|
||||||
entry.getValue().destroyBuffers();
|
entry.getValue().destroyBuffers();
|
||||||
}
|
}
|
||||||
@@ -113,6 +186,9 @@ public final class GlassRenderer {
|
|||||||
});
|
});
|
||||||
BLURS.entrySet().removeIf(entry -> {
|
BLURS.entrySet().removeIf(entry -> {
|
||||||
boolean unused = entry.getKey() != kept && !isSet(entry.getKey());
|
boolean unused = entry.getKey() != kept && !isSet(entry.getKey());
|
||||||
|
// The GUI already refers to this frame's pending backdrops.
|
||||||
|
//? if >=26.1
|
||||||
|
//unused &= !PENDING.contains(entry.getKey());
|
||||||
if (unused && entry.getValue() != null) {
|
if (unused && entry.getValue() != null) {
|
||||||
entry.getValue().close();
|
entry.getValue().close();
|
||||||
}
|
}
|
||||||
@@ -140,6 +216,9 @@ public final class GlassRenderer {
|
|||||||
|
|
||||||
PostChainConfig pipeline = PostChainConfig.CODEC.parse(JsonOps.INSTANCE, json).getOrThrow();
|
PostChainConfig pipeline = PostChainConfig.CODEC.parse(JsonOps.INSTANCE, json).getOrThrow();
|
||||||
return PostChain.load(pipeline, SaturnClient.client.getTextureManager(),
|
return PostChain.load(pipeline, SaturnClient.client.getTextureManager(),
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*LevelTargetBundle.MAIN_TARGETS, Identifier.fromNamespaceAndPath("saturnclient", "glass_blur_" + blur), PROJECTION, PROJECTION_BUFFER);
|
||||||
|
*///?} else
|
||||||
LevelTargetBundle.MAIN_TARGETS, Identifier.fromNamespaceAndPath("saturnclient", "glass_blur_" + blur), PROJECTION);
|
LevelTargetBundle.MAIN_TARGETS, Identifier.fromNamespaceAndPath("saturnclient", "glass_blur_" + blur), PROJECTION);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
SaturnClient.LOGGER.error("Couldn't load the glass blur", e);
|
SaturnClient.LOGGER.error("Couldn't load the glass blur", e);
|
||||||
|
|||||||
@@ -325,6 +325,9 @@ public class RenderScopeImpl implements RenderScope {
|
|||||||
entity, seed);
|
entity, seed);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*this.state.submitItem(new GuiItemRenderState(
|
||||||
|
*///?} else
|
||||||
this.state.submitItem(new GuiItemRenderState(stack.getItem().getName().toString(),
|
this.state.submitItem(new GuiItemRenderState(stack.getItem().getName().toString(),
|
||||||
new Matrix3x2f(this.matrices.stack), keyedItemRenderState, x, y,
|
new Matrix3x2f(this.matrices.stack), keyedItemRenderState, x, y,
|
||||||
this.scissorStack.peekLast()));
|
this.scissorStack.peekLast()));
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.time.Duration;
|
|||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
|
||||||
import org.saturnclient.config.Config;
|
import org.saturnclient.config.Config;
|
||||||
|
import org.saturnclient.impl.provider.Keys;
|
||||||
import org.saturnclient.ui.RenderScope;
|
import org.saturnclient.ui.RenderScope;
|
||||||
import org.saturnclient.ui.SaturnScreen;
|
import org.saturnclient.ui.SaturnScreen;
|
||||||
import org.saturnclient.ui.SaturnScreen.ScreenProvider;
|
import org.saturnclient.ui.SaturnScreen.ScreenProvider;
|
||||||
@@ -13,6 +14,9 @@ import net.minecraft.client.Minecraft;
|
|||||||
import net.minecraft.client.input.MouseButtonEvent;
|
import net.minecraft.client.input.MouseButtonEvent;
|
||||||
import net.minecraft.client.renderer.CubeMap;
|
import net.minecraft.client.renderer.CubeMap;
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*import net.minecraft.client.renderer.Panorama;
|
||||||
|
*///?} else
|
||||||
import net.minecraft.client.renderer.PanoramaRenderer;
|
import net.minecraft.client.renderer.PanoramaRenderer;
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
//? if >=1.21.6 {
|
//? if >=1.21.6 {
|
||||||
@@ -34,13 +38,18 @@ import net.minecraft.resources.Identifier;
|
|||||||
public class SaturnScreenFabric extends Screen implements ScreenProvider {
|
public class SaturnScreenFabric extends Screen implements ScreenProvider {
|
||||||
protected static final Identifier PANORAMA = Identifier.fromNamespaceAndPath("saturnclient",
|
protected static final Identifier PANORAMA = Identifier.fromNamespaceAndPath("saturnclient",
|
||||||
"textures/gui/title/background/panorama");
|
"textures/gui/title/background/panorama");
|
||||||
protected static final CubeMap PANORAMA_RENDERER = new CubeMap(PANORAMA);
|
public static final CubeMap PANORAMA_RENDERER = new CubeMap(PANORAMA);
|
||||||
|
|
||||||
|
// From 26.1 vanilla draws the panorama from its own cube map; GuiRendererMixin swaps in Saturn's.
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*public static final Panorama ROTATING_PANORAMA_RENDERER = new Panorama();
|
||||||
|
*///?} else {
|
||||||
public static final PanoramaRenderer ROTATING_PANORAMA_RENDERER;
|
public static final PanoramaRenderer ROTATING_PANORAMA_RENDERER;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
ROTATING_PANORAMA_RENDERER = new PanoramaRenderer(PANORAMA_RENDERER);
|
ROTATING_PANORAMA_RENDERER = new PanoramaRenderer(PANORAMA_RENDERER);
|
||||||
}
|
}
|
||||||
|
//?}
|
||||||
|
|
||||||
//? if <1.21.6
|
//? if <1.21.6
|
||||||
//private final CrossFrameResourcePool pool = new CrossFrameResourcePool(3);
|
//private final CrossFrameResourcePool pool = new CrossFrameResourcePool(3);
|
||||||
@@ -81,6 +90,9 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider {
|
|||||||
//? if <1.21.6
|
//? if <1.21.6
|
||||||
//@SuppressWarnings("deprecation")
|
//@SuppressWarnings("deprecation")
|
||||||
@Override
|
@Override
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*public void extractRenderState(GuiGraphics context, int mouseX, int mouseY, float delta) {
|
||||||
|
*///?} else
|
||||||
public void render(GuiGraphics context, int mouseX, int mouseY, float delta) {
|
public void render(GuiGraphics context, int mouseX, int mouseY, float delta) {
|
||||||
if (screen.start == null) {
|
if (screen.start == null) {
|
||||||
screen.start = Instant.now();
|
screen.start = Instant.now();
|
||||||
@@ -128,10 +140,18 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider {
|
|||||||
// Vanilla's background would cover Saturn's panorama, and blurs by the vanilla setting. The
|
// Vanilla's background would cover Saturn's panorama, and blurs by the vanilla setting. The
|
||||||
// strength of this blur comes from GameRendererMixin, which gives Saturn's setting instead.
|
// strength of this blur comes from GameRendererMixin, which gives Saturn's setting instead.
|
||||||
@Override
|
@Override
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*public void extractBackground(GuiGraphics context, int mouseX, int mouseY, float delta) {
|
||||||
|
*///?} else
|
||||||
public void renderBackground(GuiGraphics context, int mouseX, int mouseY, float delta) {
|
public void renderBackground(GuiGraphics context, int mouseX, int mouseY, float delta) {
|
||||||
// The panorama renderer has no opacity (and takes no delta) from 1.21.6, so it's drawn fully
|
// The panorama renderer has no opacity (and takes no delta) from 1.21.6, so it's drawn fully
|
||||||
// opaque.
|
// opaque.
|
||||||
if (isShowingPanorama()) {
|
if (isShowingPanorama()) {
|
||||||
|
//? if >=26.2 {
|
||||||
|
/*ROTATING_PANORAMA_RENDERER.extractRenderState(context, this.width, this.height);
|
||||||
|
*///?} else if >=26.1 {
|
||||||
|
/*ROTATING_PANORAMA_RENDERER.extractRenderState(context, this.width, this.height, true);
|
||||||
|
*///?} else
|
||||||
ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, true);
|
ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,6 +160,9 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (minecraft.level != null) {
|
if (minecraft.level != null) {
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*extractMenuBackground(context);
|
||||||
|
*///?} else
|
||||||
renderMenuBackground(context);
|
renderMenuBackground(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,7 +177,7 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider {
|
|||||||
//? if >=1.21.9 {
|
//? if >=1.21.9 {
|
||||||
@Override
|
@Override
|
||||||
public boolean mouseClicked(MouseButtonEvent click, boolean doubled) {
|
public boolean mouseClicked(MouseButtonEvent click, boolean doubled) {
|
||||||
if (screen.mouseClicked(click.x(), click.y(), click.button())) {
|
if (screen.mouseClicked(click.x(), click.y(), Keys.mouseButtonToSaturn(click.button()))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +187,7 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider {
|
|||||||
@Override
|
@Override
|
||||||
public boolean mouseDragged(MouseButtonEvent click, double offsetX, double offsetY) {
|
public boolean mouseDragged(MouseButtonEvent click, double offsetX, double offsetY) {
|
||||||
// offsetX and offsetY are the drag deltas, as mouseDragged's deltaX and deltaY were before 1.21.9.
|
// offsetX and offsetY are the drag deltas, as mouseDragged's deltaX and deltaY were before 1.21.9.
|
||||||
if (screen.mouseDragged(click.x(), click.y(), click.button(), offsetX, offsetY)) {
|
if (screen.mouseDragged(click.x(), click.y(), Keys.mouseButtonToSaturn(click.button()), offsetX, offsetY)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +196,7 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean mouseReleased(MouseButtonEvent click) {
|
public boolean mouseReleased(MouseButtonEvent click) {
|
||||||
if (screen.mouseReleased(click.x(), click.y(), click.button())) {
|
if (screen.mouseReleased(click.x(), click.y(), Keys.mouseButtonToSaturn(click.button()))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,6 +239,10 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider {
|
|||||||
//? if >=1.21.9 {
|
//? if >=1.21.9 {
|
||||||
@Override
|
@Override
|
||||||
public boolean keyPressed(KeyEvent input) {
|
public boolean keyPressed(KeyEvent input) {
|
||||||
|
// 26.3's key() is SDL's scancode; Saturn's key codes are GLFW's (see Keys).
|
||||||
|
//? if >=26.3 {
|
||||||
|
/*if (screen.keyPressed(Keys.toSaturn(input.key()), input.key(), Keys.modifiersToSaturn(input.modifiers()))) {
|
||||||
|
*///?} else
|
||||||
if (screen.keyPressed(input.input(), input.scancode(), input.modifiers())) {
|
if (screen.keyPressed(input.input(), input.scancode(), input.modifiers())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package org.saturnclient.impl.ui;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
|
|
||||||
|
/** The open screen and overlay, which Minecraft holds before 26.2 and its Gui from 26.2. */
|
||||||
|
public final class Screens {
|
||||||
|
private Screens() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @Nullable Screen current() {
|
||||||
|
//? if >=26.2 {
|
||||||
|
/*return Minecraft.getInstance().gui.screen();
|
||||||
|
*///?} else
|
||||||
|
return Minecraft.getInstance().screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void set(@Nullable Screen screen) {
|
||||||
|
//? if >=26.2 {
|
||||||
|
/*Minecraft.getInstance().gui.setScreen(screen);
|
||||||
|
*///?} else
|
||||||
|
Minecraft.getInstance().setScreen(screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clearOverlay() {
|
||||||
|
//? if >=26.2 {
|
||||||
|
/*Minecraft.getInstance().gui.setOverlay(null);
|
||||||
|
*///?} else
|
||||||
|
Minecraft.getInstance().setOverlay(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
package org.saturnclient.saturnclient.event;
|
package org.saturnclient.saturnclient.event;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*import net.fabricmc.fabric.api.client.keymapping.v1.KeyMappingHelper;
|
||||||
|
*///?} else
|
||||||
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||||
import net.minecraft.client.KeyMapping;
|
import net.minecraft.client.KeyMapping;
|
||||||
import com.mojang.blaze3d.platform.InputConstants;
|
import com.mojang.blaze3d.platform.InputConstants;
|
||||||
@@ -13,10 +16,10 @@ import org.saturnclient.common.provider.Providers;
|
|||||||
import org.saturnclient.client.ServiceClient;
|
import org.saturnclient.client.ServiceClient;
|
||||||
import org.saturnclient.emotes.fabric.Emotes;
|
import org.saturnclient.emotes.fabric.Emotes;
|
||||||
import org.saturnclient.impl.ui.SaturnScreenFabric;
|
import org.saturnclient.impl.ui.SaturnScreenFabric;
|
||||||
|
import org.saturnclient.impl.ui.Screens;
|
||||||
import org.saturnclient.ui.screens.EmoteWheel;
|
import org.saturnclient.ui.screens.EmoteWheel;
|
||||||
import org.saturnclient.ui.screens.ShiftMenu;
|
import org.saturnclient.ui.screens.ShiftMenu;
|
||||||
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles keyboard input events for the Saturn Client.
|
* Handles keyboard input events for the Saturn Client.
|
||||||
@@ -28,11 +31,17 @@ public class KeyInputHandler {
|
|||||||
//?} else
|
//?} else
|
||||||
//private static final String KEY_CATEGORY = "key.category.saturnclient";
|
//private static final String KEY_CATEGORY = "key.category.saturnclient";
|
||||||
private static final String MAIN_MENU_KEY_ID = "key.saturnclient.main_menu";
|
private static final String MAIN_MENU_KEY_ID = "key.saturnclient.main_menu";
|
||||||
private static final int DEFAULT_MENU_KEY = GLFW.GLFW_KEY_RIGHT_SHIFT;
|
private static final int DEFAULT_MENU_KEY = InputConstants.KEY_RSHIFT;
|
||||||
private static KeyMapping mainMenuKeyBinding;
|
private static KeyMapping mainMenuKeyBinding;
|
||||||
|
|
||||||
public static void register() {
|
public static void register() {
|
||||||
//? if >=1.21.9 {
|
//? if >=26.1 {
|
||||||
|
/*mainMenuKeyBinding = KeyMappingHelper.registerKeyMapping(
|
||||||
|
new KeyMapping(
|
||||||
|
MAIN_MENU_KEY_ID,
|
||||||
|
DEFAULT_MENU_KEY,
|
||||||
|
KeyMapping.Category.register(KEY_CATEGORY)));
|
||||||
|
*///?} else if >=1.21.9 {
|
||||||
mainMenuKeyBinding = KeyBindingHelper.registerKeyBinding(
|
mainMenuKeyBinding = KeyBindingHelper.registerKeyBinding(
|
||||||
new KeyMapping(
|
new KeyMapping(
|
||||||
MAIN_MENU_KEY_ID,
|
MAIN_MENU_KEY_ID,
|
||||||
@@ -56,13 +65,15 @@ public class KeyInputHandler {
|
|||||||
// from the screen's own key handling would reopen it on the next tick, since the key is
|
// from the screen's own key handling would reopen it on the next tick, since the key is
|
||||||
// still down and no screen is open by then.
|
// still down and no screen is open by then.
|
||||||
if (Config.openEmoteWheel.wasKeyPressed()
|
if (Config.openEmoteWheel.wasKeyPressed()
|
||||||
//? if >=1.21.9 {
|
//? if >=26.3 {
|
||||||
&& !InputConstants.isKeyDown(client.getWindow(), GLFW.GLFW_KEY_F3)) {
|
/*&& !InputConstants.isKeyDown(InputConstants.KEY_F3)) {
|
||||||
|
*///?} else if >=1.21.9 {
|
||||||
|
&& !InputConstants.isKeyDown(client.getWindow(), InputConstants.KEY_F3)) {
|
||||||
//?} else
|
//?} else
|
||||||
//&& !InputConstants.isKeyDown(client.getWindow().getWindow(), GLFW.GLFW_KEY_F3)) {
|
//&& !InputConstants.isKeyDown(client.getWindow().getWindow(), InputConstants.KEY_F3)) {
|
||||||
if (client.screen == null) {
|
if (Screens.current() == null) {
|
||||||
Providers.saturn.getClient().setScreen(new EmoteWheel());
|
Providers.saturn.getClient().setScreen(new EmoteWheel());
|
||||||
} else if (client.screen instanceof SaturnScreenFabric saturnScreen
|
} else if (Screens.current() instanceof SaturnScreenFabric saturnScreen
|
||||||
&& saturnScreen.screen instanceof EmoteWheel) {
|
&& saturnScreen.screen instanceof EmoteWheel) {
|
||||||
saturnScreen.onClose();
|
saturnScreen.onClose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package org.saturnclient.saturnclient.mixin;
|
||||||
|
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||||
|
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||||
|
import net.minecraft.client.gui.render.GuiRenderer;
|
||||||
|
import net.minecraft.client.renderer.CubeMap;
|
||||||
|
import org.saturnclient.impl.ui.GlassRenderer;
|
||||||
|
import org.saturnclient.impl.ui.SaturnScreenFabric;
|
||||||
|
import org.saturnclient.impl.ui.Screens;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
*///?} else
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* From 26.1 GuiRenderer draws the menu panorama from its own cube map, which is vanilla's. While a
|
||||||
|
* Saturn screen is open, this draws Saturn's panorama instead. It also blurs the glass backdrops
|
||||||
|
* once the panorama is drawn. Before 26.1 SaturnScreenFabric draws
|
||||||
|
* the panorama itself, so this mixin is empty there, and it targets Minecraft because GuiRenderer
|
||||||
|
* doesn't exist before 1.21.6. It stays registered, keeping saturnclient.mixins.json the same for
|
||||||
|
* every version.
|
||||||
|
*/
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*@Mixin(GuiRenderer.class)
|
||||||
|
public class GuiRendererMixin {
|
||||||
|
@WrapOperation(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/CubeMap;render(FF)V"))
|
||||||
|
private void saturn$drawSaturnPanorama(CubeMap cubeMap, float xRot, float yRot, Operation<Void> original) {
|
||||||
|
boolean saturnScreen = Screens.current() instanceof SaturnScreenFabric;
|
||||||
|
original.call(saturnScreen ? SaturnScreenFabric.PANORAMA_RENDERER : cubeMap, xRot, yRot);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The glass backdrops are copied here, with the frame's world and panorama drawn and the GUI not
|
||||||
|
// yet: the GUI is built before the frame is drawn (see GlassRenderer).
|
||||||
|
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/render/GuiRenderer;prepare()V"))
|
||||||
|
private void saturn$blurGlassBackdrops(CallbackInfo ci) {
|
||||||
|
GlassRenderer.blurPendingBackdrops();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*///?} else {
|
||||||
|
@Mixin(Minecraft.class)
|
||||||
|
public class GuiRendererMixin {
|
||||||
|
}
|
||||||
|
//?}
|
||||||
@@ -8,9 +8,15 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
//? if >=26.2
|
||||||
|
//import net.minecraft.client.gui.Gui;
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.client.gui.screens.TitleScreen;
|
import net.minecraft.client.gui.screens.TitleScreen;
|
||||||
|
|
||||||
|
// Screens are opened through Gui from 26.2 (through Minecraft before).
|
||||||
|
//? if >=26.2 {
|
||||||
|
/*@Mixin(Gui.class)
|
||||||
|
*///?} else
|
||||||
@Mixin(Minecraft.class)
|
@Mixin(Minecraft.class)
|
||||||
public class SetScreenMixin {
|
public class SetScreenMixin {
|
||||||
@ModifyVariable(method = "setScreen", at = @At("HEAD"), argsOnly = true)
|
@ModifyVariable(method = "setScreen", at = @At("HEAD"), argsOnly = true)
|
||||||
@@ -18,7 +24,7 @@ public class SetScreenMixin {
|
|||||||
if (Config.saturnTitleScreen.value) {
|
if (Config.saturnTitleScreen.value) {
|
||||||
if (screen instanceof TitleScreen)
|
if (screen instanceof TitleScreen)
|
||||||
return new SaturnScreenFabric(new TitleMenu());
|
return new SaturnScreenFabric(new TitleMenu());
|
||||||
if (screen == null && ((Minecraft) (Object) this).level == null)
|
if (screen == null && Minecraft.getInstance().level == null)
|
||||||
return new SaturnScreenFabric(new TitleMenu());
|
return new SaturnScreenFabric(new TitleMenu());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.saturnclient.saturnclient.mixin;
|
package org.saturnclient.saturnclient.mixin;
|
||||||
|
|
||||||
|
import org.saturnclient.impl.ui.Screens;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@@ -54,6 +56,9 @@ public abstract class SplashOverlayMixin {
|
|||||||
* @reason Replace vanilla splash rendering completely but keep exit logic
|
* @reason Replace vanilla splash rendering completely but keep exit logic
|
||||||
*/
|
*/
|
||||||
@Overwrite
|
@Overwrite
|
||||||
|
//? if >=26.1 {
|
||||||
|
/*public void extractRenderState(GuiGraphics context, int mouseX, int mouseY, float delta) {
|
||||||
|
*///?} else
|
||||||
public void render(GuiGraphics context, int mouseX, int mouseY, float delta) {
|
public void render(GuiGraphics context, int mouseX, int mouseY, float delta) {
|
||||||
int screenWidth = context.guiWidth();
|
int screenWidth = context.guiWidth();
|
||||||
int screenHeight = context.guiHeight();
|
int screenHeight = context.guiHeight();
|
||||||
@@ -107,7 +112,7 @@ public abstract class SplashOverlayMixin {
|
|||||||
|
|
||||||
// Remove overlay after fade-out completes
|
// Remove overlay after fade-out completes
|
||||||
if (fadeOutProgress >= 2.0F) {
|
if (fadeOutProgress >= 2.0F) {
|
||||||
minecraft.setOverlay(null);
|
Screens.clearOverlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle reload completion and exceptions
|
// Handle reload completion and exceptions
|
||||||
@@ -115,8 +120,11 @@ public abstract class SplashOverlayMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void renderCurrentScreen(GuiGraphics context, int mouseX, int mouseY, float delta) {
|
private void renderCurrentScreen(GuiGraphics context, int mouseX, int mouseY, float delta) {
|
||||||
if (minecraft.screen != null) {
|
if (Screens.current() != null) {
|
||||||
minecraft.screen.render(context, mouseX, mouseY, delta);
|
//? if >=26.1 {
|
||||||
|
/*Screens.current().extractRenderState(context, mouseX, mouseY, delta);
|
||||||
|
*///?} else
|
||||||
|
Screens.current().render(context, mouseX, mouseY, delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +137,9 @@ public abstract class SplashOverlayMixin {
|
|||||||
private void renderProgressBar(RenderScope scope, GuiGraphics context, int screenWidth, int screenHeight,
|
private void renderProgressBar(RenderScope scope, GuiGraphics context, int screenWidth, int screenHeight,
|
||||||
int alpha) {
|
int alpha) {
|
||||||
int progressY = ((screenHeight - 5) / 2) + 25;
|
int progressY = ((screenHeight - 5) / 2) + 25;
|
||||||
//? if >=1.21.11 {
|
//? if >=26.1 {
|
||||||
|
/*context.outline((screenWidth - 120) / 2, progressY, 120, 5, Theme.withAlpha(alpha, 0xFFFFFFFF));
|
||||||
|
*///?} else if >=1.21.11 {
|
||||||
context.renderOutline((screenWidth - 120) / 2, progressY, 120, 5, Theme.withAlpha(alpha, 0xFFFFFFFF));
|
context.renderOutline((screenWidth - 120) / 2, progressY, 120, 5, Theme.withAlpha(alpha, 0xFFFFFFFF));
|
||||||
//?} else if >=1.21.9 {
|
//?} else if >=1.21.9 {
|
||||||
/*context.submitOutline((screenWidth - 120) / 2, progressY, 120, 5, Theme.withAlpha(alpha, 0xFFFFFFFF));
|
/*context.submitOutline((screenWidth - 120) / 2, progressY, 120, 5, Theme.withAlpha(alpha, 0xFFFFFFFF));
|
||||||
@@ -165,11 +175,11 @@ public abstract class SplashOverlayMixin {
|
|||||||
|
|
||||||
//? if >=1.21.11
|
//? if >=1.21.11
|
||||||
Window window = minecraft.getWindow();
|
Window window = minecraft.getWindow();
|
||||||
if (minecraft.screen != null) {
|
if (Screens.current() != null) {
|
||||||
//? if >=1.21.11 {
|
//? if >=1.21.11 {
|
||||||
minecraft.screen.init(window.getGuiScaledWidth(), window.getGuiScaledHeight());
|
Screens.current().init(window.getGuiScaledWidth(), window.getGuiScaledHeight());
|
||||||
//?} else
|
//?} else
|
||||||
//minecraft.screen.init(minecraft, context.guiWidth(), context.guiHeight());
|
//Screens.current().init(minecraft, context.guiWidth(), context.guiHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,26 @@
|
|||||||
#version 330
|
#version 330
|
||||||
|
// 26.3 compiles shaders through SPIR-V, which needs every input and output's location.
|
||||||
|
#ifdef EXPLICIT_LOCATIONS
|
||||||
|
#extension GL_ARB_separate_shader_objects : require
|
||||||
|
#endif
|
||||||
|
|
||||||
// Saturn's glass: the blurred game behind the screen, cut to a panel's shape. For 1.21.6 and
|
// Saturn's glass: the blurred game behind the screen, cut to a panel's shape. For 1.21.6 and
|
||||||
// later; glass_pre_1_21_6.fsh (with glass.json, the program 1.21.4 loads) is for older versions.
|
// later; glass_pre_1_21_6.fsh (with glass.json, the program 1.21.4 loads) is for older versions.
|
||||||
|
|
||||||
// Vanilla's transforms, laid out as the version has them: 1.21.6 to 1.21.10 end with LineWidth, which
|
// Vanilla's transforms, laid out as the version has them: 1.21.6 to 1.21.10 end with LineWidth, which
|
||||||
// 1.21.11 dropped (GlassRenderer defines HAS_LINE_WIDTH there). Not imported: the include only exists
|
// 1.21.11 dropped (GlassRenderer defines HAS_LINE_WIDTH there), and 26.3 moved TextureMat up
|
||||||
// from 1.21.6, and 1.21.4 and 1.21.5 still read every shader's imports while loading resources.
|
// (TEXTURE_MAT_SECOND). Not imported: the include only exists from 1.21.6, and 1.21.4 and 1.21.5 still
|
||||||
|
// read every shader's imports while loading resources.
|
||||||
layout(std140) uniform DynamicTransforms {
|
layout(std140) uniform DynamicTransforms {
|
||||||
mat4 ModelViewMat;
|
mat4 ModelViewMat;
|
||||||
|
#ifdef TEXTURE_MAT_SECOND
|
||||||
|
mat4 TextureMat;
|
||||||
|
#endif
|
||||||
vec4 ColorModulator;
|
vec4 ColorModulator;
|
||||||
vec3 ModelOffset;
|
vec3 ModelOffset;
|
||||||
|
#ifndef TEXTURE_MAT_SECOND
|
||||||
mat4 TextureMat;
|
mat4 TextureMat;
|
||||||
|
#endif
|
||||||
#ifdef HAS_LINE_WIDTH
|
#ifdef HAS_LINE_WIDTH
|
||||||
float LineWidth;
|
float LineWidth;
|
||||||
#endif
|
#endif
|
||||||
@@ -21,10 +31,17 @@ uniform sampler2D Sampler0;
|
|||||||
// The game behind the screen, blurred, the size of the framebuffer
|
// The game behind the screen, blurred, the size of the framebuffer
|
||||||
uniform sampler2D Sampler1;
|
uniform sampler2D Sampler1;
|
||||||
|
|
||||||
|
#ifdef EXPLICIT_LOCATIONS
|
||||||
|
layout(location = 0) in vec2 texCoord0;
|
||||||
|
layout(location = 1) in vec4 vertexColor;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 fragColor;
|
||||||
|
#else
|
||||||
in vec2 texCoord0;
|
in vec2 texCoord0;
|
||||||
in vec4 vertexColor;
|
in vec4 vertexColor;
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
#endif
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
float mask = texture(Sampler0, texCoord0).a * vertexColor.a;
|
float mask = texture(Sampler0, texCoord0).a * vertexColor.a;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
],
|
],
|
||||||
"depends": {
|
"depends": {
|
||||||
"fabricloader": ">=${loader_version}",
|
"fabricloader": ">=${loader_version}",
|
||||||
"fabric": "*",
|
"fabric-api": "*",
|
||||||
"minecraft": "${minecraft_version}"
|
"minecraft": "${minecraft_version}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"required": true,
|
"required": true,
|
||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"package": "org.saturnclient.impl.features.mixins",
|
"package": "org.saturnclient.impl.features.mixins",
|
||||||
"compatibilityLevel": "JAVA_21",
|
"compatibilityLevel": "${java}",
|
||||||
"client": [
|
"client": [
|
||||||
"render.GameRendererMixin",
|
"render.GameRendererMixin",
|
||||||
"render.LightmapTextureManagerMixin",
|
"render.LightmapTextureManagerMixin",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"required": true,
|
"required": true,
|
||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"package": "org.saturnclient.impl.mixins",
|
"package": "org.saturnclient.impl.mixins",
|
||||||
"compatibilityLevel": "JAVA_21",
|
"compatibilityLevel": "${java}",
|
||||||
"client": [
|
"client": [
|
||||||
"IdentifierMixin",
|
"IdentifierMixin",
|
||||||
"ItemStackMixin",
|
"ItemStackMixin",
|
||||||
|
|||||||
@@ -2,14 +2,15 @@
|
|||||||
"required": true,
|
"required": true,
|
||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"package": "org.saturnclient.saturnclient.mixin",
|
"package": "org.saturnclient.saturnclient.mixin",
|
||||||
"compatibilityLevel": "JAVA_21",
|
"compatibilityLevel": "${java}",
|
||||||
"client": [
|
"client": [
|
||||||
"TabListMixin",
|
"TabListMixin",
|
||||||
"PlayerEntityRendererMixin",
|
"PlayerEntityRendererMixin",
|
||||||
"WhoAmI",
|
"WhoAmI",
|
||||||
"DrawContextAccessor",
|
"DrawContextAccessor",
|
||||||
"SplashOverlayMixin",
|
"SplashOverlayMixin",
|
||||||
"SetScreenMixin"
|
"SetScreenMixin",
|
||||||
|
"GuiRendererMixin"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|||||||
+24
-8
@@ -6,16 +6,27 @@ plugins {
|
|||||||
// "Reset active project" before committing.
|
// "Reset active project" before committing.
|
||||||
stonecutter active "1.21.11"
|
stonecutter active "1.21.11"
|
||||||
|
|
||||||
// src/ uses the newest Mojang names. These classes were renamed in the versions given, so Stonecutter
|
// src/ uses 1.21.11's Mojang names (the active version). These names changed in the versions given,
|
||||||
// swaps in the older names when it processes an older version.
|
// so Stonecutter swaps in each version's name when it processes it.
|
||||||
stonecutter parameters {
|
stonecutter parameters {
|
||||||
for ((since, old, new) in listOf(
|
for ((since, old, new) in listOf(
|
||||||
Triple("1.21.11", "ResourceLocation", "Identifier"),
|
Triple("1.21.11", "ResourceLocation", "Identifier"),
|
||||||
Triple("1.21.9", "PlayerRenderer", "AvatarRenderer"),
|
Triple("1.21.9", "PlayerRenderer", "AvatarRenderer"),
|
||||||
Triple("1.21.9", "PlayerRenderState", "AvatarRenderState"),
|
Triple("1.21.9", "PlayerRenderState", "AvatarRenderState"),
|
||||||
|
Triple("26.1", "GuiGraphics", "GuiGraphicsExtractor"),
|
||||||
|
Triple("26.1", "net.minecraft.client.gui.render.state", "net.minecraft.client.renderer.state.gui"),
|
||||||
|
// GuiRenderState's methods
|
||||||
|
Triple("26.1", "submitGuiElement", "addGuiElement"),
|
||||||
|
Triple("26.1", "submitText", "addText"),
|
||||||
|
Triple("26.1", "submitItem", "addItem"),
|
||||||
|
Triple("26.1", "submitPicturesInPictureState", "addPicturesInPictureState"),
|
||||||
|
// 26.3 moves Blaze3D's API to renderpearl
|
||||||
|
Triple("26.3", "com.mojang.blaze3d.GpuFormat", "com.mojang.renderpearl.api.GpuFormat"),
|
||||||
|
Triple("26.3", "com.mojang.blaze3d.pipeline.RenderPipeline", "com.mojang.renderpearl.api.pipeline.RenderPipeline"),
|
||||||
|
Triple("26.3", "com.mojang.blaze3d.textures", "com.mojang.renderpearl.api.textures"),
|
||||||
)) {
|
)) {
|
||||||
replacements.regex(eval(current.version, ">=$since")) {
|
replacements.regex(eval(current.version, ">=$since")) {
|
||||||
replace("\\b$old\\b", new, "\\b$new\\b", old)
|
replace("\\b${Regex.escape(old)}\\b", new, "\\b${Regex.escape(new)}\\b", old)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,17 +80,22 @@ subprojects {
|
|||||||
|
|
||||||
tasks.register("buildAll") {
|
tasks.register("buildAll") {
|
||||||
group = "build"
|
group = "build"
|
||||||
description = "Builds every Minecraft version's remapped jar and collects them in build/allJars"
|
description = "Builds every Minecraft version's mod jar and collects them in build/allJars"
|
||||||
|
|
||||||
val remapJars = subprojects.flatMap { it.tasks.matching { task -> task.name == "remapJar" } }
|
// The mod jar is remapJar's output for 1.21.x, and jar's for 26.1+, which isn't obfuscated.
|
||||||
dependsOn(remapJars)
|
val modJars = subprojects.filter { it.name != "common" }.flatMap { project ->
|
||||||
|
val unobfuscated = project.name.substringBefore('.').toInt() >= 26
|
||||||
|
val task = if (unobfuscated) "jar" else "remapJar"
|
||||||
|
project.tasks.matching { it.name == task }
|
||||||
|
}
|
||||||
|
dependsOn(modJars)
|
||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
val outputDir = layout.buildDirectory.dir("allJars").get().asFile
|
val outputDir = layout.buildDirectory.dir("allJars").get().asFile
|
||||||
outputDir.mkdirs()
|
outputDir.mkdirs()
|
||||||
remapJars.map { (it as AbstractArchiveTask).archiveFile.get().asFile }
|
modJars.map { (it as AbstractArchiveTask).archiveFile.get().asFile }
|
||||||
.filter { it.exists() && !it.name.contains("sources") }
|
.filter { it.exists() && !it.name.contains("sources") }
|
||||||
.forEach { it.copyTo(outputDir.resolve(it.name), overwrite = true) }
|
.forEach { it.copyTo(outputDir.resolve(it.name), overwrite = true) }
|
||||||
println("All remapped jars collected in: $outputDir")
|
println("All mod jars collected in: $outputDir")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# Done to increase the memory available to gradle.
|
||||||
|
org.gradle.jvmargs=-Xmx1G
|
||||||
|
org.gradle.parallel=true
|
||||||
|
|
||||||
|
# IntelliJ IDEA is not yet fully compatible with configuration cache, see: https://github.com/FabricMC/fabric-loom/issues/1349
|
||||||
|
org.gradle.configuration-cache=false
|
||||||
|
|
||||||
|
# Fabric Properties
|
||||||
|
# check these on https://fabricmc.net/develop
|
||||||
|
minecraft_version=26.1
|
||||||
|
# Built against 26.1 and allowed on its hotfixes (26.1.1, 26.1.2).
|
||||||
|
minecraft_compat=~26.1
|
||||||
|
loader_version=0.19.5
|
||||||
|
|
||||||
|
fabric_api_version=0.145.1+26.1
|
||||||
|
|
||||||
|
# Mod Properties
|
||||||
|
maven_group=org.saturnclient
|
||||||
|
archives_base_name=saturn-client
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Done to increase the memory available to gradle.
|
||||||
|
org.gradle.jvmargs=-Xmx1G
|
||||||
|
org.gradle.parallel=true
|
||||||
|
|
||||||
|
# IntelliJ IDEA is not yet fully compatible with configuration cache, see: https://github.com/FabricMC/fabric-loom/issues/1349
|
||||||
|
org.gradle.configuration-cache=false
|
||||||
|
|
||||||
|
# Fabric Properties
|
||||||
|
# check these on https://fabricmc.net/develop
|
||||||
|
minecraft_version=26.2
|
||||||
|
loader_version=0.19.5
|
||||||
|
|
||||||
|
fabric_api_version=0.161.0+26.2
|
||||||
|
|
||||||
|
# Mod Properties
|
||||||
|
maven_group=org.saturnclient
|
||||||
|
archives_base_name=saturn-client
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Done to increase the memory available to gradle.
|
||||||
|
org.gradle.jvmargs=-Xmx1G
|
||||||
|
org.gradle.parallel=true
|
||||||
|
|
||||||
|
# IntelliJ IDEA is not yet fully compatible with configuration cache, see: https://github.com/FabricMC/fabric-loom/issues/1349
|
||||||
|
org.gradle.configuration-cache=false
|
||||||
|
|
||||||
|
# Fabric Properties
|
||||||
|
# check these on https://fabricmc.net/develop
|
||||||
|
minecraft_version=26.3
|
||||||
|
loader_version=0.19.5
|
||||||
|
|
||||||
|
fabric_api_version=0.161.0+26.3
|
||||||
|
|
||||||
|
# Mod Properties
|
||||||
|
maven_group=org.saturnclient
|
||||||
|
archives_base_name=saturn-client
|
||||||
Reference in New Issue
Block a user