Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package malte0811.ferritecore.impl;

import it.unimi.dsi.fastutil.chars.CharComparator;
import it.unimi.dsi.fastutil.chars.CharList;
import it.unimi.dsi.fastutil.ints.AbstractIntList;
import it.unimi.dsi.fastutil.ints.IntComparator;
import it.unimi.dsi.fastutil.ints.IntList;

public class CharListIntListWrapper extends AbstractIntList {
public final CharList delegate;

public CharListIntListWrapper(CharList delegate) {
this.delegate = delegate;
}

@Override
public int getInt(int index) {
return charToInt(delegate.getChar(index));
}

@Override
public int size() {
return delegate.size();
}

@Override
public void size(int size) {
delegate.size(size);
}

@Override
public void add(int index, int k) {
delegate.add(index, intToChar(k));
}

@Override
public boolean add(int k) {
return delegate.add(intToChar(k));
}

@Override
public int removeInt(int i) {
return charToInt(delegate.removeChar(i));
}

@Override
public int set(int index, int k) {
return delegate.set(index, intToChar(k));
}

@Override
public int indexOf(int k) {
return delegate.indexOf(intToChar(k));
}

@Override
public int lastIndexOf(int k) {
return delegate.lastIndexOf(intToChar(k));
}

@Override
public boolean rem(int k) {
return delegate.rem(intToChar(k));
}

@Override
public void clear() {
delegate.clear();
}

@Override
public IntList subList(int from, int to) {
return new CharListIntListWrapper(delegate.subList(from, to));
}

@Override
public void sort(IntComparator comparator) {
delegate.sort(wrapComparator(comparator));
}

@Override
public void unstableSort(IntComparator comparator) {
delegate.unstableSort(wrapComparator(comparator));
}

@Override
public void removeElements(int from, int to) {
delegate.removeElements(from, to);
}

public static CharComparator wrapComparator(IntComparator comparator) {
return (k1, k2) -> comparator.compare(charToInt(k1), charToInt(k2));
}

// we use \u0000 to represent -1 or the end
public static char intToChar(int i) {
if (i > Character.MAX_VALUE || i == 0)
throw new IllegalArgumentException();
return i < 0 ? '\u0000' : (char)i;
}

public static int charToInt(char c) {
return c == '\u0000' ? -1 : (int)c;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package malte0811.ferritecore.impl;

import malte0811.ferritecore.util.CollectionUtil;
import net.minecraft.Util;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.core.Direction;
Expand All @@ -22,7 +23,7 @@ public class ModelSidesImpl {
});

public static List<BakedQuad> minimizeUnculled(List<BakedQuad> quads) {
return List.copyOf(quads);
return CollectionUtil.minimize(quads);
}

public static Map<Direction, List<BakedQuad>> minimizeCulled(Map<Direction, List<BakedQuad>> quadsBySide) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package malte0811.ferritecore.impl.compactunihex;

import net.minecraft.client.gui.font.providers.UnihexProvider.LineData;
import org.jetbrains.annotations.Range;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class CompactByteContents implements LineData {
private final long upperBytes;
private final long lowerBytes;

public CompactByteContents(long upperBytes, long lowerBytes) {
this.upperBytes = upperBytes;
this.lowerBytes = lowerBytes;
}

public CompactByteContents(byte[] bytes) {
if (bytes.length != 16)
throw new IllegalArgumentException();
ByteBuffer buffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
// not really sure why i have to flip these, but it only works if i do, so...
this.lowerBytes = buffer.getLong();
this.upperBytes = buffer.getLong();
}

@Override
public int line(@Range(from = 0, to = 15) int index) {
// index should always be between 0 and 15
long bytes = index >= Long.BYTES ? upperBytes : lowerBytes;
int bits = Byte.SIZE * (index % Byte.SIZE);
// basically the structure is like b7 b6 b5 b4 b3 b2 b1 b0 (little endian)
return (byte)((bytes >> bits) & 0xFF) << 24; // shift 24 bits to the left (mc does this idk)
}

@Override
public int bitWidth() {
return Byte.SIZE; // 8
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package malte0811.ferritecore.impl.compactunihex;

import net.minecraft.client.gui.font.providers.UnihexProvider.LineData;
import org.jetbrains.annotations.Range;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class CompactShortContents implements LineData {
private final long shorts1;
private final long shorts2;
private final long shorts3;
private final long shorts4;

public CompactShortContents(short[] shorts) {
if (shorts.length != 16)
throw new IllegalArgumentException();
ByteBuffer buffer = ByteBuffer.allocate(16 * Short.BYTES).order(ByteOrder.LITTLE_ENDIAN);
buffer.asShortBuffer().put(shorts);
this.shorts1 = buffer.getLong();
this.shorts2 = buffer.getLong();
this.shorts3 = buffer.getLong();
this.shorts4 = buffer.getLong();
}

@Override
public int line(@Range(from = 0, to = 15) int index) {
// index should always be between 0 and 15
long shorts = switch (index) {
case 0, 1, 2, 3 -> shorts1;
// 4 shorts in a long
case 4, 5, 6, 7 -> shorts2;
case 8, 9, 10, 11 -> shorts3;
case 12, 13, 14, 15 -> shorts4;
default -> throw new IllegalArgumentException();
};
int bits = Short.SIZE * (index % 4);
// basically the structure is like s3 s2 s1 s0 (little endian)
return (short)((shorts >> bits) & 0xFFFF) << 16; // shift 16 bits to the left (mc does this idk)
}

@Override
public int bitWidth() {
return Short.SIZE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package malte0811.ferritecore.mixin.accessors;

import it.unimi.dsi.fastutil.bytes.ByteList;
import net.minecraft.client.gui.font.providers.UnihexProvider;
import org.jetbrains.annotations.Contract;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;

@Mixin(UnihexProvider.class)
public interface UnihexProviderAccess {
@Contract("_, _, _ -> _") // ij thinks it always throws :(
@Invoker("decodeHex")
static int decodeHex(int lineNumber, ByteList byteList, int index) {
//noinspection Contract
throw new AssertionError();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package malte0811.ferritecore.mixin.blockmodellists;

import com.mojang.datafixers.util.Either;
import malte0811.ferritecore.util.CollectionUtil;
import net.minecraft.client.renderer.block.model.BlockElement;
import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.client.renderer.block.model.ItemOverride;
import net.minecraft.client.resources.model.Material;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;

import java.util.List;
import java.util.Map;

@Mixin(BlockModel.Deserializer.class)
public class BlockModelDeserializerMixin {
@ModifyArg(method = "deserialize(Lcom/google/gson/JsonElement;Ljava/lang/reflect/Type;Lcom/google/gson/JsonDeserializationContext;)Lnet/minecraft/client/renderer/block/model/BlockModel;", index = 1, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/block/model/BlockModel;<init>(Lnet/minecraft/resources/ResourceLocation;Ljava/util/List;Ljava/util/Map;Ljava/lang/Boolean;Lnet/minecraft/client/renderer/block/model/BlockModel$GuiLight;Lnet/minecraft/client/renderer/block/model/ItemTransforms;Ljava/util/List;)V"))
private List<BlockElement> elementsImmutableCopy(List<BlockElement> list) {
return CollectionUtil.minimize(list);
}

@ModifyArg(method = "deserialize(Lcom/google/gson/JsonElement;Ljava/lang/reflect/Type;Lcom/google/gson/JsonDeserializationContext;)Lnet/minecraft/client/renderer/block/model/BlockModel;", index = 2, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/block/model/BlockModel;<init>(Lnet/minecraft/resources/ResourceLocation;Ljava/util/List;Ljava/util/Map;Ljava/lang/Boolean;Lnet/minecraft/client/renderer/block/model/BlockModel$GuiLight;Lnet/minecraft/client/renderer/block/model/ItemTransforms;Ljava/util/List;)V"))
private Map<String, Either<Material, String>> immutableCopy(Map<String, Either<Material, String>> map) {
return Map.copyOf(map);
}

@ModifyArg(method = "deserialize(Lcom/google/gson/JsonElement;Ljava/lang/reflect/Type;Lcom/google/gson/JsonDeserializationContext;)Lnet/minecraft/client/renderer/block/model/BlockModel;", index = 6, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/block/model/BlockModel;<init>(Lnet/minecraft/resources/ResourceLocation;Ljava/util/List;Ljava/util/Map;Ljava/lang/Boolean;Lnet/minecraft/client/renderer/block/model/BlockModel$GuiLight;Lnet/minecraft/client/renderer/block/model/ItemTransforms;Ljava/util/List;)V"))
private List<ItemOverride> overridesImmutableCopy(List<ItemOverride> list) {
return CollectionUtil.minimize(list);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package malte0811.ferritecore.mixin.blockmodellists;

import malte0811.ferritecore.mixin.config.FerriteConfig;
import malte0811.ferritecore.mixin.config.FerriteMixinConfig;

public class Config extends FerriteMixinConfig {
public Config() {
super(FerriteConfig.DEDUP_MULTIPART);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package malte0811.ferritecore.mixin.compactunihex;

import malte0811.ferritecore.mixin.config.FerriteConfig;
import malte0811.ferritecore.mixin.config.FerriteMixinConfig;

// could probably also do the int ones but its probably not worth it
public class Config extends FerriteMixinConfig {
public Config() {
super(FerriteConfig.COMPACT_UNIHEX);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package malte0811.ferritecore.mixin.compactunihex;

import it.unimi.dsi.fastutil.bytes.ByteList;
import malte0811.ferritecore.impl.compactunihex.CompactByteContents;
import net.minecraft.client.gui.font.providers.UnihexProvider;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;

import static malte0811.ferritecore.mixin.accessors.UnihexProviderAccess.decodeHex;

@Mixin(targets = "net/minecraft/client/gui/font/providers/UnihexProvider$ByteContents")
public class UnihexByteContentsMixin {
/**
* @author AnAwesomGuy (ferritecore)
* @reason redirect to more compact instance
*/
@Overwrite
public static UnihexProvider.LineData read(int index, ByteList byteList) {
// i eliminated the for loop mwuahaha >:)
long upper = ((((long)decodeHex(index, byteList, 31) << 4) |
decodeHex(index, byteList, 30)) << 56) |
((((long)decodeHex(index, byteList, 29) << 4) |
decodeHex(index, byteList, 28)) << 48) |
((((long)decodeHex(index, byteList, 27) << 4) |
decodeHex(index, byteList, 26)) << 40) |
((((long)decodeHex(index, byteList, 25) << 4) |
decodeHex(index, byteList, 24)) << 32) |
((((long)decodeHex(index, byteList, 23) << 4) |
decodeHex(index, byteList, 21)) << 24) |
((((long)decodeHex(index, byteList, 20) << 4) |
decodeHex(index, byteList, 19)) << 16) |
((((long)decodeHex(index, byteList, 18) << 4) |
decodeHex(index, byteList, 17)) << 8) |
((((long)decodeHex(index, byteList, 16) << 4) |
decodeHex(index, byteList, 15)));
long lower = ((((long)decodeHex(index, byteList, 15) << 4) |
decodeHex(index, byteList, 14)) << 56) |
((((long)decodeHex(index, byteList, 13) << 4) |
decodeHex(index, byteList, 12)) << 48) |
((((long)decodeHex(index, byteList, 11) << 4) |
decodeHex(index, byteList, 10)) << 40) |
((((long)decodeHex(index, byteList, 9) << 4) |
decodeHex(index, byteList, 8)) << 32) |
((((long)decodeHex(index, byteList, 7) << 4) |
decodeHex(index, byteList, 6)) << 24) |
((((long)decodeHex(index, byteList, 5) << 4) |
decodeHex(index, byteList, 6)) << 16) |
((((long)decodeHex(index, byteList, 3) << 4) |
decodeHex(index, byteList, 2)) << 8) |
((((long)decodeHex(index, byteList, 1) << 4) |
decodeHex(index, byteList, 0)));
return new CompactByteContents(upper, lower);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package malte0811.ferritecore.mixin.compactunihex;

import it.unimi.dsi.fastutil.bytes.ByteList;
import malte0811.ferritecore.impl.compactunihex.CompactShortContents;
import net.minecraft.client.gui.font.providers.UnihexProvider.LineData;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;

@Mixin(targets = "net/minecraft/client/gui/font/providers/UnihexProvider$ShortContents")
public class UnihexShortContentsMixin {
@Inject(method = "read", at = @At(value = "NEW", target = "([S)Lnet/minecraft/client/gui/font/providers/UnihexProvider$ShortContents;"), cancellable = true, locals = LocalCapture.CAPTURE_FAILSOFT)
private static void redirectByteContentsToOurs(int index, ByteList byteList, CallbackInfoReturnable<LineData> cir, short[] bytes, int i) {
cir.setReturnValue(new CompactShortContents(bytes));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ public class FerriteConfig {
public static final Option POPULATE_NEIGHBOR_TABLE;
public static final Option THREADING_DETECTOR;
public static final Option MODEL_SIDES;
public static final Option BLOCK_MODEL_LISTS;
public static final Option COMPACT_UNIHEX;
public static final Option SUFFIX_ARRAY;

static {
ConfigBuilder builder = new ConfigBuilder();
Expand Down Expand Up @@ -74,6 +77,18 @@ public class FerriteConfig {
"Populate the neighbor table used by vanilla. Enabling this slightly increases memory usage, but" +
" can help with issues in the rare case where mods access it directly."
);
BLOCK_MODEL_LISTS = builder.createOption(
"blockModelLists",
"Use smaller data structures in BlockModel, reducing the amount of empty ArrayLists."
);
COMPACT_UNIHEX = builder.createOption(
"compactUnihex",
"Compacts unihex font glyphs into longs instead of using short and byte arrays, saving some memory."
);
SUFFIX_ARRAY = builder.createOption(
"suffixArray",
"Replaces the int list in SuffixArray with a char list, halving the memory usage."
);
builder.finish();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package malte0811.ferritecore.mixin.suffixarray;

import malte0811.ferritecore.mixin.config.FerriteConfig;
import malte0811.ferritecore.mixin.config.FerriteMixinConfig;

public class Config extends FerriteMixinConfig {
public Config() {
super(FerriteConfig.PREDICATES);
}
}
Loading