Build 1.21.4 with Stonecutter; every version now shares src/
Check / compile (pull_request) Successful in 7m44s

Step 6 of #8. versions/1.21.4/src is gone, so all eight versions (1.21.4 to
1.21.11) build from src/.

1.21.4's differences from 1.21.5 are behind version comments:
- The end gateway render layer has no render pipeline before 1.21.5
  (ShaderUtils: the pipeline field only exists from 1.21.5, and the layer
  is a four-way chain).
- Hat head rotation, the NativeImageBackedTexture constructor, armor slots
  (inventory.armor vs getEquippedStack), MatrixStackMixin's Quaternionf,
  and inside the pre-1.21.6 implementations: prevHeadYaw, GUI lighting,
  ModelTransformationMode, item depth, setShaderTexture and the blur
  uniform call. Those are one-line version comments, since the pre-1.21.6
  blocks are already inside /* */ on newer versions.

1.21.5's drawItem wrapped its body in a second isEmpty check after already
returning early for empty stacks; the redundant check is gone, so 1.21.4
and 1.21.5 share the body.

Freelook's zoom-out (FreelookMod.shouldZoomOut in GameRendererMixin) only
existed on 1.21.4. It doesn't depend on the Minecraft version, so it's
back on every version.

With no old copies left, the mc-<v> fallback in settings.gradle.kts and
scripts/port.sh are removed, and README and VERSION_GUIDE describe the
single layout.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-09-27 06:34:32 +02:00
co-authored by claude
parent c5665548a0
commit 25a19d7951
70 changed files with 128 additions and 4076 deletions
@@ -41,8 +41,11 @@ public class HatFeatureRenderer extends FeatureRenderer<PlayerEntityRenderState,
matrices.push();
//? if >=1.21.5 {
ModelPart head = this.getContextModel().head;
matrices.multiply(new Quaternionf().rotationZYX(head.roll, head.yaw, head.pitch));
//?} else
//this.getContextModel().head.rotate(matrices);
ObjModel.cosmetic("hat", player.hat).render(MtlLoader.cosmetic(player.hat),
matrices, output, light,
@@ -43,9 +43,12 @@ public class IdentifierUtils {
}
SaturnClient.client.execute(() -> {
//? if >=1.21.5 {
NativeImageBackedTexture texture = new NativeImageBackedTexture(
() -> identifier.toString(),
nativeImage);
//?} else
//NativeImageBackedTexture texture = new NativeImageBackedTexture(nativeImage);
SaturnClient.client.getTextureManager().registerTexture(identifier, texture);
});
@@ -3,10 +3,17 @@ package org.saturnclient.impl.cosmetics.utils;
import org.saturnclient.common.ref.asset.IdentifierRef;
import org.saturnclient.cosmetics.utils.GifUtils;
//? if >=1.21.5
import com.mojang.blaze3d.pipeline.RenderPipeline;
//? if >=1.21.5
import net.minecraft.client.gl.RenderPipelines;
import net.minecraft.client.render.RenderLayer;
//? if <1.21.5 {
/*import net.minecraft.client.render.RenderPhase;
import net.minecraft.client.render.VertexFormat.DrawMode;
import net.minecraft.client.render.VertexFormats;
*///?}
//? if >=1.21.11 {
import net.minecraft.client.render.RenderLayers;
import net.minecraft.client.render.RenderSetup;
@@ -18,6 +25,8 @@ import net.minecraft.client.render.block.entity.EndPortalBlockEntityRenderer;
import net.minecraft.util.Identifier;
public class ShaderUtils {
// Render pipelines exist from 1.21.5; before that the layer names a shader program directly.
//? if >=1.21.5 {
public static final RenderPipeline END_GATEWAY_PIPELINE = RenderPipelines.register(
RenderPipeline.builder(new RenderPipeline.Snippet[] {
RenderPipelines.RENDERTYPE_END_PORTAL_SNIPPET })
@@ -25,6 +34,7 @@ public class ShaderUtils {
.withShaderDefine("PORTAL_LAYERS", 16)
.withCull(false)
.build());
//?}
//? if >=1.21.11 {
public static final RenderLayer END_GATEWAY = RenderLayer.of("end_gateway",
@@ -38,13 +48,29 @@ public class ShaderUtils {
.texture(Textures.create().add(EndPortalBlockEntityRenderer.SKY_TEXTURE, false)
.add(EndPortalBlockEntityRenderer.PORTAL_TEXTURE, false).build())
.build(false));
*///?} else {
*///?} else if >=1.21.5 {
/*public static final RenderLayer END_GATEWAY = RenderLayer.of("end_gateway", 1536, false, false,
END_GATEWAY_PIPELINE,
RenderLayer.MultiPhaseParameters.builder()
.texture(Textures.create().add(EndPortalBlockEntityRenderer.SKY_TEXTURE, false, false)
.add(EndPortalBlockEntityRenderer.PORTAL_TEXTURE, false, false).build())
.build(false));
*///?} else {
/*public static final RenderLayer END_GATEWAY = RenderLayer.of(
"end_gateway",
VertexFormats.POSITION,
DrawMode.QUADS,
1536,
false,
false,
RenderLayer.MultiPhaseParameters.builder()
.program(RenderLayer.END_GATEWAY_PROGRAM)
.texture(Textures.create()
.add(EndPortalBlockEntityRenderer.SKY_TEXTURE, false, false)
.add(EndPortalBlockEntityRenderer.PORTAL_TEXTURE, false, false)
.build())
.cull(RenderPhase.DISABLE_CULLING)
.build(false));
*///?}
public static RenderLayer getRenderLayer(IdentifierRef texture) {
@@ -2,6 +2,7 @@ package org.saturnclient.impl.features.mixins.render;
import net.minecraft.client.render.GameRenderer;
import org.saturnclient.mod.mods.FreelookMod;
import org.saturnclient.mod.mods.ZoomMod;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@@ -32,6 +33,9 @@ public class GameRendererMixin {
if (ZoomMod.shouldZoom()) {
float zoomedFov = cir.getReturnValue() / ZoomMod.getZoomLevel();
cir.setReturnValue(zoomedFov);
} else if (FreelookMod.shouldZoomOut()) {
float zoomedFov = cir.getReturnValue() / FreelookMod.getZoomLevel();
cir.setReturnValue(zoomedFov);
}
}
}
@@ -169,22 +169,34 @@ public class PlayerFeatureImpl implements PlayerFeature {
@Override
public ItemStackRef getHelmet() {
//? if >=1.21.5 {
return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.HEAD) : ItemStack.EMPTY);
//?} else
//return wrap(hasPlayer() ? player().getInventory().armor.get(3) : ItemStack.EMPTY);
}
@Override
public ItemStackRef getChestplate() {
//? if >=1.21.5 {
return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.CHEST) : ItemStack.EMPTY);
//?} else
//return wrap(hasPlayer() ? player().getInventory().armor.get(2) : ItemStack.EMPTY);
}
@Override
public ItemStackRef getLeggings() {
//? if >=1.21.5 {
return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.LEGS) : ItemStack.EMPTY);
//?} else
//return wrap(hasPlayer() ? player().getInventory().armor.get(1) : ItemStack.EMPTY);
}
@Override
public ItemStackRef getBoots() {
//? if >=1.21.5 {
return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.FEET) : ItemStack.EMPTY);
//?} else
//return wrap(hasPlayer() ? player().getInventory().armor.get(0) : ItemStack.EMPTY);
}
// ---------------------------------------------------------------
@@ -3,8 +3,11 @@ package org.saturnclient.impl.mixins;
import net.minecraft.client.util.math.MatrixStack;
import org.spongepowered.asm.mixin.Mixin;
//? if <1.21.6 {
/*import org.joml.Quaternionfc;
import org.saturnclient.common.ref.render.MatrixStackRef;
/*import org.saturnclient.common.ref.render.MatrixStackRef;
//? if >=1.21.5
import org.joml.Quaternionfc;
//? if <1.21.5
//import org.joml.Quaternionf;
import org.spongepowered.asm.mixin.Shadow;
import net.minecraft.util.math.RotationAxis;
*///?}
@@ -30,10 +33,16 @@ import net.minecraft.util.math.RotationAxis;
public abstract void scale(float x, float y, float z);
@Shadow
//? if >=1.21.5
public abstract void multiply(Quaternionfc quaternion);
//? if <1.21.5
//public abstract void multiply(Quaternionf quaternion);
@Shadow
//? if >=1.21.5
public abstract void multiply(Quaternionfc quaternion, float originX, float originY, float originZ);
//? if <1.21.5
//public abstract void multiply(Quaternionf quaternion, float originX, float originY, float originZ);
@Override
public void translate(float x, float y) {
@@ -104,13 +104,19 @@ public class EntityDrawerImpl implements EntityDrawer {
float k = entity.bodyYaw;
float l = entity.getYaw();
float m = entity.getPitch();
//? if >=1.21.5
float n = entity.lastHeadYaw;
//? if <1.21.5
//float n = entity.prevHeadYaw;
float o = entity.headYaw;
entity.setYaw(angle);
entity.bodyYaw = angle;
entity.setPitch(-(j * 20.0F));
entity.headYaw = negativeAngle ? (i * 40.0F) + 180f : -(i * 40.0F);
//? if >=1.21.5
entity.lastHeadYaw = entity.getHeadYaw();
//? if <1.21.5
//entity.prevHeadYaw = entity.getHeadYaw();
entity.setCustomNameVisible(false);
float p = entity.getScale();
@@ -122,7 +128,10 @@ public class EntityDrawerImpl implements EntityDrawer {
entity.bodyYaw = k;
entity.setYaw(l);
entity.setPitch(m);
//? if >=1.21.5
entity.lastHeadYaw = n;
//? if <1.21.5
//entity.prevHeadYaw = n;
entity.headYaw = o;
renderScope.disableScissor();
}
@@ -136,7 +145,10 @@ public class EntityDrawerImpl implements EntityDrawer {
scopeImpl.matrices.translate(vector3f.x, vector3f.y, vector3f.z);
scopeImpl.matrices.multiply(quaternionf);
scopeImpl.draw();
//? if >=1.21.5
DiffuseLighting.disableGuiDepthLighting();
//? if <1.21.5
//DiffuseLighting.method_34742();
EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher();
entityRenderDispatcher.setRenderShadows(false);
@@ -400,7 +400,10 @@ import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.Window;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.LivingEntity;
//? if >=1.21.5
import net.minecraft.item.ItemDisplayContext;
//? if <1.21.5
//import net.minecraft.item.ModelTransformationMode;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
@@ -645,6 +648,8 @@ public class RenderScopeImpl implements RenderScope {
matrices.push();
matrices.scale(0.25f, 0.25f, 1.0f);
//? if <1.21.5
//RenderSystem.setShaderTexture(0, sprite);
RenderLayer renderLayer = RenderLayer.getGuiTextured(sprite);
Matrix4f matrix4f = matrices.peek().getPositionMatrix();
VertexConsumer vertexConsumer = vertexConsumers.getBuffer(renderLayer);
@@ -673,40 +678,42 @@ public class RenderScopeImpl implements RenderScope {
if (stack.isEmpty())
return;
SaturnClient.client.getItemModelManager().update(itemRenderState, stack, ItemDisplayContext.GUI, world, entity,
seed);
//? if >=1.21.5
SaturnClient.client.getItemModelManager().update(itemRenderState, stack, ItemDisplayContext.GUI, world, entity, seed);
//? if >=1.21.5
SaturnClient.client.getItemModelManager().clearAndUpdate(this.itemRenderState, stack, ItemDisplayContext.GUI, world, entity, seed);
//? if <1.21.5
//SaturnClient.client.getItemModelManager().update(itemRenderState, stack, ModelTransformationMode.GUI, false, world, entity, seed);
if (!stack.isEmpty()) {
SaturnClient.client.getItemModelManager().clearAndUpdate(this.itemRenderState, stack,
ItemDisplayContext.GUI, world,
entity, seed);
this.matrices.push();
this.matrices.translate((float) (x + 8), (float) (y + 8), (float) (150 + z));
this.matrices.push();
//? if >=1.21.5
this.matrices.translate((float) (x + 8), (float) (y + 8), (float) (150 + z));
//? if <1.21.5
//this.matrices.translate(x + 8, y + 8, 150 + (itemRenderState.hasDepth() ? z : 0));
try {
this.matrices.scale(16.0F, -16.0F, 16.0F);
boolean bl = !this.itemRenderState.isSideLit();
if (bl) {
this.draw();
DiffuseLighting.disableGuiDepthLighting();
}
this.itemRenderState.render(this.matrices, this.vertexConsumers, 15728880, OverlayTexture.DEFAULT_UV);
try {
this.matrices.scale(16.0F, -16.0F, 16.0F);
boolean bl = !this.itemRenderState.isSideLit();
if (bl) {
this.draw();
if (bl) {
DiffuseLighting.enableGuiDepthLighting();
}
} catch (Throwable throwable) {
CrashReport crashReport = CrashReport.create(throwable, "Rendering item");
CrashReportSection crashReportSection = crashReport.addElement("Item being rendered");
crashReportSection.add("Item Type", () -> String.valueOf(stack.getItem()));
crashReportSection.add("Item Components", () -> String.valueOf(stack.getComponents()));
crashReportSection.add("Item Foil", () -> String.valueOf(stack.hasGlint()));
throw new CrashException(crashReport);
DiffuseLighting.disableGuiDepthLighting();
}
this.matrices.pop();
this.itemRenderState.render(this.matrices, this.vertexConsumers, 15728880, OverlayTexture.DEFAULT_UV);
this.draw();
if (bl) {
DiffuseLighting.enableGuiDepthLighting();
}
} catch (Throwable throwable) {
CrashReport crashReport = CrashReport.create(throwable, "Rendering item");
CrashReportSection crashReportSection = crashReport.addElement("Item being rendered");
crashReportSection.add("Item Type", () -> String.valueOf(stack.getItem()));
crashReportSection.add("Item Components", () -> String.valueOf(stack.getComponents()));
crashReportSection.add("Item Foil", () -> String.valueOf(stack.hasGlint()));
throw new CrashException(crashReport);
}
this.matrices.pop();
}
// ----------------------------
@@ -88,11 +88,12 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider {
if (postEffectProcessor != null) {
float radius = screen.backgroundBlur * Math.min((float) elapsed / 700, 1.0f);
postEffectProcessor.render(
this.client.getFramebuffer(),
this.pool,
pass -> pass.setUniform("Radius", radius)
);
//? if >=1.21.5
postEffectProcessor.render(this.client.getFramebuffer(), this.pool, pass -> pass.setUniform("Radius", radius));
//? if <1.21.5
//postEffectProcessor.setUniforms("Radius", radius);
//? if <1.21.5
//postEffectProcessor.render(this.client.getFramebuffer(), this.pool);
}
*///?}