Update #48 - Added some features from OptiFine

This commit is contained in:
lax1dude
2025-01-24 18:39:36 -08:00
parent 1f0d593a8c
commit e83a912e38
1056 changed files with 17706 additions and 898 deletions

View File

@ -58,6 +58,8 @@ class OpenGLObjects {
static class TextureGL implements ITextureGL {
final int ptr;
int width;
int height;
TextureGL(int ptr) {
this.ptr = ptr;
@ -71,7 +73,23 @@ class OpenGLObjects {
public void free() {
PlatformOpenGL._wglDeleteTextures(this);
}
@Override
public void setCacheSize(int w, int h) {
width = w;
height = h;
}
@Override
public int getWidth() {
return width;
}
@Override
public int getHeight() {
return height;
}
}
static class ProgramGL implements IProgramGL {

View File

@ -0,0 +1,496 @@
package dev.redstudio.alfheim.lighting;
import dev.redstudio.alfheim.utils.DeduplicatedLongQueue;
import dev.redstudio.redcore.math.ClampUtil;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Vec3i;
import net.minecraft.world.EnumSkyBlock;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
/**
* Modified by lax1dude not to abuse interfaces
*
* @author Luna Lage (Desoroxxx)
* @author kappa-maintainer
* @author embeddedt
* @author Angeline (@jellysquid)
* @since 1.0
*/
public final class LightingEngine {
private static final byte MAX_LIGHT_LEVEL = 15;
private final World world;
// Layout of longs: [padding(4)] [y(8)] [x(26)] [z(26)]
private final DeduplicatedLongQueue[] lightUpdateQueues = new DeduplicatedLongQueue[EnumSkyBlock.values().length];
// Layout of longs: see above
private final DeduplicatedLongQueue[] darkeningQueues = new DeduplicatedLongQueue[MAX_LIGHT_LEVEL + 1];
private final DeduplicatedLongQueue[] brighteningQueues = new DeduplicatedLongQueue[MAX_LIGHT_LEVEL + 1];
// Layout of longs: [newLight(4)] [pos(60)]
private final DeduplicatedLongQueue initialBrightenings;
// Layout of longs: [padding(4)] [pos(60)]
private final DeduplicatedLongQueue initialDarkenings;
private boolean updating = false;
// Layout parameters
// Length of bit segments
private static final int L_X = 26, L_Y = 8, L_Z = 26, L_L = 4;
// Bit segment shifts/positions
private static final int S_Z = 0, S_X = S_Z + L_Z, S_Y = S_X + L_X, S_L = S_Y + L_Y;
// Bit segment masks
private static final long M_X = (1L << L_X) - 1, M_Y = (1L << L_Y) - 1, M_Z = (1L << L_Z) - 1,
M_L = (1L << L_L) - 1, M_POS = (M_Y << S_Y) | (M_X << S_X) | (M_Z << S_Z);
// Bit to check whether y had overflow
private static final long Y_CHECK = 1L << (S_Y + L_Y);
private static final long[] neighborShifts = new long[6];
static {
for (byte i = 0; i < 6; ++i) {
final Vec3i offset = EnumFacing._VALUES[i].getDirectionVec();
neighborShifts[i] = ((long) offset.getY() << S_Y) | ((long) offset.getX() << S_X)
| ((long) offset.getZ() << S_Z);
}
}
// Mask to extract chunk identifier
private static final long M_CHUNK = ((M_X >> 4) << (4 + S_X)) | ((M_Z >> 4) << (4 + S_Z));
// Iteration state data
// Cache position to avoid allocation of new object each time
private final BlockPos currentPos = new BlockPos();
private Chunk currentChunk;
private long currentChunkIdentifier;
private long currentData;
// Cached data about neighboring blocks (of tempPos)
private boolean isNeighborDataValid = false;
private final NeighborInfo[] neighborInfos = new NeighborInfo[6];
private DeduplicatedLongQueue currentQueue;
public LightingEngine(final World world) {
this.world = world;
initialBrightenings = new DeduplicatedLongQueue(16384);
initialDarkenings = new DeduplicatedLongQueue(16384);
for (int i = 0; i < EnumSkyBlock.values().length; ++i)
lightUpdateQueues[i] = new DeduplicatedLongQueue(16384);
for (int i = 0; i < darkeningQueues.length; ++i)
darkeningQueues[i] = new DeduplicatedLongQueue(16384);
for (int i = 0; i < brighteningQueues.length; ++i)
brighteningQueues[i] = new DeduplicatedLongQueue(16384);
for (int i = 0; i < neighborInfos.length; ++i)
neighborInfos[i] = new NeighborInfo();
}
/**
* Schedules a light update for the specified light type and position to be
* processed later by
* {@link LightingEngine#processLightUpdatesForType(EnumSkyBlock)}
*/
public void scheduleLightUpdate(final EnumSkyBlock lightType, final BlockPos pos) {
scheduleLightUpdate(lightType, encodeWorldCoord(pos));
}
/**
* Schedules a light update for the specified light type and position to be
* processed later by {@link LightingEngine#processLightUpdates()}
*/
private void scheduleLightUpdate(final EnumSkyBlock lightType, final long blockPos) {
lightUpdateQueues[lightType.ordinal()].enqueue(blockPos);
}
/**
* Calls {@link LightingEngine#processLightUpdatesForType(EnumSkyBlock)} for
* both light types
*/
public void processLightUpdates() {
processLightUpdatesForType(EnumSkyBlock.SKY);
processLightUpdatesForType(EnumSkyBlock.BLOCK);
}
/**
* Processes light updates of the given light type
*/
public void processLightUpdatesForType(final EnumSkyBlock lightType) {
final DeduplicatedLongQueue queue = lightUpdateQueues[lightType.ordinal()];
// Quickly check if the queue is empty before we acquire a more expensive lock.
if (queue.isEmpty())
return;
processLightUpdatesForTypeInner(lightType, queue);
}
private void processLightUpdatesForTypeInner(final EnumSkyBlock lightType, final DeduplicatedLongQueue queue) {
// Avoid nested calls
if (updating)
throw new IllegalStateException("Already processing updates!");
updating = true;
currentChunkIdentifier = -1; // Reset chunk cache
currentQueue = queue;
if (currentQueue != null)
currentQueue.newDeduplicationSet();
// Process the queued updates and enqueue them for further processing
while (nextItem()) {
if (currentChunk == null)
continue;
final byte oldLight = getCursorCachedLight(lightType);
final byte newLight = calculateNewLightFromCursor(lightType);
if (oldLight < newLight)
initialBrightenings.enqueue(((long) newLight << S_L) | currentData); // Don't enqueue directly for
// brightening to avoid
// duplicate scheduling
else if (oldLight > newLight)
initialDarkenings.enqueue(currentData); // Don't enqueue directly for darkening to avoid duplicate
// scheduling
}
currentQueue = initialBrightenings;
if (currentQueue != null)
currentQueue.newDeduplicationSet();
while (nextItem()) {
final byte newLight = (byte) (currentData >> S_L & M_L);
if (newLight > getCursorCachedLight(lightType))
enqueueBrightening(currentPos, currentData & M_POS, newLight, currentChunk, lightType); // Sets the
// light to
// newLight to
// only schedule
// once. Clear
// leading bits
// of curData
// for later
}
currentQueue = initialDarkenings;
if (currentQueue != null)
currentQueue.newDeduplicationSet();
while (nextItem()) {
final byte oldLight = getCursorCachedLight(lightType);
if (oldLight != 0)
enqueueDarkening(currentPos, currentData, oldLight, currentChunk, lightType); // Sets the light to zero
// to only schedule once
}
// Iterate through enqueued updates (brightening and darkening in parallel) from
// brightest to darkest so that we only need to iterate once
for (byte currentLight = MAX_LIGHT_LEVEL; currentLight >= 0; --currentLight) {
currentQueue = darkeningQueues[currentLight];
if (currentQueue != null)
currentQueue.newDeduplicationSet();
while (nextItem()) {
// Don't darken if we got brighter due to some other change
if (getCursorCachedLight(lightType) >= currentLight)
continue;
final IBlockState blockState = currentChunk.getBlockState(currentPos);
final byte luminosity = getCursorLuminosity(blockState, lightType);
final byte opacity; // If luminosity is high enough, opacity is irrelevant
if (luminosity >= MAX_LIGHT_LEVEL - 1)
opacity = 1;
else
opacity = getPosOpacity(currentPos, blockState);
// Only darken neighbors if we indeed became darker
if (calculateNewLightFromCursor(luminosity, opacity, lightType) < currentLight) {
// Need to calculate new light value from neighbors IGNORING neighbors which are
// scheduled for darkening
byte newLight = luminosity;
fetchNeighborDataFromCursor(lightType);
for (final NeighborInfo neighborInfo : neighborInfos) {
final Chunk neighborChunk = neighborInfo.chunk;
if (neighborChunk == null)
continue;
final byte neighborLight = neighborInfo.light;
if (neighborLight == 0)
continue;
final BlockPos neighborPos = neighborInfo.mutableBlockPos;
if (currentLight - getPosOpacity(neighborPos, neighborChunk
.getBlockState(neighborPos)) >= neighborLight) /*
* Schedule neighbor for darkening if we
* possibly light it
*/ {
enqueueDarkening(neighborPos, neighborInfo.key, neighborLight, neighborChunk, lightType);
} else /* Only use for new light calculation if not */ {
// If we can't darken the neighbor, no one else can (because of processing
// order) -> safe to let us be illuminated by it
newLight = (byte) Math.max(newLight, neighborLight - opacity);
}
}
// Schedule brightening since light level was set to 0
enqueueBrighteningFromCursor(newLight, lightType);
} else /*
* We didn't become darker, so we need to re-set our initial light value (was
* set to zero) and notify neighbors
*/ {
enqueueBrighteningFromCursor(currentLight, lightType); // Do not spread to neighbors immediately to
// avoid scheduling multiple times
}
}
currentQueue = brighteningQueues[currentLight];
if (currentQueue != null)
currentQueue.newDeduplicationSet();
while (nextItem()) {
final byte oldLight = getCursorCachedLight(lightType);
// Only process this if nothing else has happened at this position since
// scheduling
if (oldLight == currentLight) {
world.notifyLightSet(currentPos);
if (currentLight > 1)
spreadLightFromCursor(currentLight, lightType);
}
}
}
updating = false;
}
/**
* Gets data for neighbors of {@link #currentPos} and saves the results into
* neighbor state data members. If a neighbor can't be accessed/doesn't exist,
* the corresponding entry in neighborChunks is null - others are not reset
*/
private void fetchNeighborDataFromCursor(final EnumSkyBlock lightType) {
// Only update if curPos was changed
if (isNeighborDataValid)
return;
isNeighborDataValid = true;
for (int i = 0; i < neighborInfos.length; ++i) {
final NeighborInfo neighborInfo = neighborInfos[i];
final long neighborLongPos = neighborInfo.key = currentData + neighborShifts[i];
if ((neighborLongPos & Y_CHECK) != 0) {
neighborInfo.chunk = null;
continue;
}
final BlockPos neighborPos = decodeWorldCoord(neighborInfo.mutableBlockPos, neighborLongPos);
final Chunk neighborChunk;
if ((neighborLongPos & M_CHUNK) == currentChunkIdentifier)
neighborChunk = neighborInfo.chunk = currentChunk;
else
neighborChunk = neighborInfo.chunk = getChunk(neighborPos);
if (neighborChunk != null) {
final ExtendedBlockStorage neighborSection = neighborChunk
.getBlockStorageArray()[neighborPos.getY() >> 4];
neighborInfo.light = getCachedLightFor(neighborChunk, neighborSection, neighborPos, lightType);
}
}
}
private static byte getCachedLightFor(final Chunk chunk, final ExtendedBlockStorage storage,
final BlockPos blockPos, final EnumSkyBlock type) {
final int x = blockPos.getX() & 15;
final int y = blockPos.getY();
final int z = blockPos.getZ() & 15;
if (storage == null)
return type == EnumSkyBlock.SKY && chunk.canSeeSky(blockPos) ? (byte) type.defaultLightValue : 0;
else if (type == EnumSkyBlock.SKY)
return chunk.getWorld().provider.getHasNoSky() ? 0 : (byte) storage.getExtSkylightValue(x, y & 15, z);
else
return type == EnumSkyBlock.BLOCK ? (byte) storage.getExtBlocklightValue(x, y & 15, z)
: (byte) type.defaultLightValue;
}
private byte calculateNewLightFromCursor(final EnumSkyBlock lightType) {
final IBlockState blockState = currentChunk.getBlockState(currentPos);
final byte luminosity = getCursorLuminosity(blockState, lightType);
final byte opacity;
if (luminosity >= MAX_LIGHT_LEVEL - 1)
opacity = 1;
else
opacity = getPosOpacity(currentPos, blockState);
return calculateNewLightFromCursor(luminosity, opacity, lightType);
}
private byte calculateNewLightFromCursor(final byte luminosity, final byte opacity, final EnumSkyBlock lightType) {
if (luminosity >= MAX_LIGHT_LEVEL - opacity)
return luminosity;
byte newLight = luminosity;
fetchNeighborDataFromCursor(lightType);
for (final NeighborInfo neighborInfo : neighborInfos) {
if (neighborInfo.chunk == null)
continue;
newLight = (byte) Math.max(neighborInfo.light - opacity, newLight);
}
return newLight;
}
private void spreadLightFromCursor(final byte currentLight, final EnumSkyBlock lightType) {
fetchNeighborDataFromCursor(lightType);
for (final NeighborInfo neighborInfo : neighborInfos) {
final Chunk neighborChunk = neighborInfo.chunk;
if (neighborChunk == null || currentLight < neighborInfo.light)
continue;
final BlockPos neighborBlockPos = neighborInfo.mutableBlockPos;
final byte newLight = (byte) (currentLight
- getPosOpacity(neighborBlockPos, neighborChunk.getBlockState(neighborBlockPos)));
if (newLight > neighborInfo.light)
enqueueBrightening(neighborBlockPos, neighborInfo.key, newLight, neighborChunk, lightType);
}
}
private void enqueueBrighteningFromCursor(final byte newLight, final EnumSkyBlock lightType) {
enqueueBrightening(currentPos, currentData, newLight, currentChunk, lightType);
}
/**
* Enqueues the blockPos for brightening and sets its light value to newLight
*/
private void enqueueBrightening(final BlockPos blockPos, final long longPos, final byte newLight, final Chunk chunk,
final EnumSkyBlock lightType) {
brighteningQueues[newLight].enqueue(longPos);
chunk.setLightFor(lightType, blockPos, newLight);
}
/**
* Enqueues the blockPos for darkening and sets its light value to 0
*/
private void enqueueDarkening(final BlockPos blockPos, final long longPos, final byte oldLight, final Chunk chunk,
final EnumSkyBlock lightType) {
darkeningQueues[oldLight].enqueue(longPos);
chunk.setLightFor(lightType, blockPos, 0);
}
private static BlockPos decodeWorldCoord(final BlockPos mutableBlockPos, final long longPos) {
return mutableBlockPos.func_181079_c((int) (longPos >> S_X & M_X) - (1 << L_X - 1), (int) (longPos >> S_Y & M_Y),
(int) (longPos >> S_Z & M_Z) - (1 << L_Z - 1));
}
private static long encodeWorldCoord(final BlockPos pos) {
return ((long) pos.getY() << S_Y) | ((long) pos.getX() + (1 << L_X - 1) << S_X)
| ((long) pos.getZ() + (1 << L_Z - 1) << S_Z);
}
/**
* Polls a new item from {@link #currentQueue} and fills in state data members
*
* @return If there was an item to poll
*/
private boolean nextItem() {
if (currentQueue.isEmpty()) {
currentQueue = null;
return false;
}
currentData = currentQueue.dequeue();
isNeighborDataValid = false;
decodeWorldCoord(currentPos, currentData);
final long chunkIdentifier = currentData & M_CHUNK;
if (currentChunkIdentifier != chunkIdentifier) {
currentChunk = getChunk(currentPos);
currentChunkIdentifier = chunkIdentifier;
}
return true;
}
private byte getCursorCachedLight(final EnumSkyBlock lightType) {
return currentChunk.alfheim$getCachedLightFor(lightType, currentPos);
}
/**
* Calculates the luminosity for {@link #currentPos}, taking into account the
* light type
*/
private byte getCursorLuminosity(final IBlockState state, final EnumSkyBlock lightType) {
if (lightType == EnumSkyBlock.SKY) {
if (currentChunk.canSeeSky(currentPos))
return (byte) EnumSkyBlock.SKY.defaultLightValue;
else
return 0;
}
return (byte) ClampUtil.clampMinFirst(state.getBlock().getLightValue(), 0, MAX_LIGHT_LEVEL);
}
private byte getPosOpacity(final BlockPos blockPos, final IBlockState blockState) {
return (byte) ClampUtil.clampMinFirst(blockState.getBlock().getLightOpacity(), 1, MAX_LIGHT_LEVEL);
}
private Chunk getChunk(final BlockPos blockPos) {
return world.getChunkProvider().getLoadedChunk(blockPos.getX() >> 4, blockPos.getZ() >> 4);
}
private static final class NeighborInfo {
public final BlockPos mutableBlockPos = new BlockPos();
public Chunk chunk;
public byte light;
public long key;
}
}

View File

@ -0,0 +1,75 @@
package dev.redstudio.alfheim.utils;
import com.carrotsearch.hppc.LongArrayDeque;
import com.carrotsearch.hppc.LongHashSet;
/**
* A queue implementation for long values that are deduplicated on addition.
* <p>
* This is achieved by storing the values in a {@link LongOpenHashSet} and a
* {@link LongArrayFIFOQueue}.
*
* @author Luna Lage (Desoroxxx)
* @since 1.3
*/
public final class DeduplicatedLongQueue {
// TODO: Fully Implement my own implementation to get rid of the downsides of
// reduce etc...
private final LongArrayDeque queue;
private LongHashSet set;
/**
* Creates a new deduplicated queue with the given capacity.
*
* @param capacity The capacity of the deduplicated queue
*/
public DeduplicatedLongQueue(final int capacity) {
set = new LongHashSet(capacity);
queue = new LongArrayDeque(capacity);
}
/**
* Adds a value to the queue.
*
* @param value The value to add to the queue
*/
public void enqueue(final long value) {
if (set.add(value))
queue.addLast(value);
}
/**
* Removes and returns the first value in the queue.
*
* @return The first value in the queue
*/
public long dequeue() {
return queue.removeFirst();
}
/**
* Returns whether the queue is empty.
*
* @return {@code true} if the queue is empty, {@code false} otherwise
*/
public boolean isEmpty() {
return queue.isEmpty();
}
/**
* Creates a new deduplication set.
*/
public void newDeduplicationSet() {
int i = queue.size();
if(i < 4) {
i = 4;
}
if((set.keys.length * 3 / 2) > i) {
set = new LongHashSet(i);
}else {
set.clear();
}
}
}

View File

@ -0,0 +1,5 @@
package dev.redstudio.alfheim.utils;
public enum EnumBoundaryFacing {
IN, OUT
}

View File

@ -0,0 +1,88 @@
package dev.redstudio.alfheim.utils;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.IChunkProvider;
/**
* Represents a slice of a world containing a collection of chunks.
*
* @author Luna Lage (Desoroxxx)
* @author Angeline (@jellysquid)
* @since 1.0
*/
public class WorldChunkSlice {
private static final int DIAMETER = 5;
private static final int RADIUS = DIAMETER / 2;
private final int x, z;
private final Chunk[] chunks;
/**
* Initializes a {@link WorldChunkSlice} object using a given chunk provider and
* coordinates.
*
* @param chunkProvider The chunk provider to get chunks from
* @param x The X-coordinate of the center chunk
* @param z The Z-coordinate of the center chunk
*/
public WorldChunkSlice(final IChunkProvider chunkProvider, final int x, final int z) {
chunks = new Chunk[DIAMETER * DIAMETER];
for (int xDiff = -RADIUS; xDiff <= RADIUS; xDiff++)
for (int zDiff = -RADIUS; zDiff <= RADIUS; zDiff++)
chunks[((xDiff + RADIUS) * DIAMETER) + (zDiff + RADIUS)] = chunkProvider.getLoadedChunk(x + xDiff,
z + zDiff);
this.x = x - RADIUS;
this.z = z - RADIUS;
}
/**
* Checks if all chunks within a radius around a coordinate are loaded.
*
* @param x The X-coordinate to check around
* @param z The Z-coordinate to check around
* @param radius The radius around the coordinates to check
*
* @return true if all chunks are loaded, false otherwise
*/
public boolean isLoaded(final int x, final int z, final int radius) {
final int xStart = ((x - radius) >> 4) - this.x;
final int zStart = ((z - radius) >> 4) - this.z;
final int xEnd = ((x + radius) >> 4) - this.x;
final int zEnd = ((z + radius) >> 4) - this.z;
for (int currentX = xStart; currentX <= xEnd; ++currentX)
for (int currentZ = zStart; currentZ <= zEnd; ++currentZ)
if (getChunk(currentX, currentZ) == null)
return false;
return true;
}
/**
* Retrieves the chunk that includes the provided world coordinates.
*
* @param x The X-coordinate in the world
* @param z The Z-coordinate in the world
*
* @return The Chunk object that includes these coordinates
*/
public Chunk getChunkFromWorldCoords(final int x, final int z) {
return getChunk((x >> 4) - this.x, (z >> 4) - this.z);
}
/**
* Retrieves the chunk located at the given coordinates within this chunk slice.
*
* @param x The X-coordinate within the slice
* @param z The Z-coordinate within the slice
*
* @return The Chunk object at these coordinates
*/
private Chunk getChunk(final int x, final int z) {
return chunks[(x * DIAMETER) + z];
}
}

View File

@ -0,0 +1,201 @@
package dev.redstudio.redcore.math;
public class ClampUtil {
/**
* Clamps a value within a specified range [min, max], checking for the minimum
* value first.
* <p>
* If the input is less than min, it returns min. If the input is greater than
* max, it returns max. Otherwise, it returns the input.
*
* @param input The input value to clamp
* @param min The minimum value to clamp to
* @param max The maximum value to clamp to
*
* @return The clamped value
*/
public static byte clampMinFirst(final byte input, final byte min, final byte max) {
return input < min ? min : input > max ? max : input;
}
/**
* Clamps a value within a specified range [min, max], checking for the minimum
* value first.
* <p>
* If the input is less than min, it returns min. If the input is greater than
* max, it returns max. Otherwise, it returns the input.
*
* @param input The input value to clamp
* @param min The minimum value to clamp to
* @param max The maximum value to clamp to
*
* @return The clamped value
*/
public static short clampMinFirst(final short input, final short min, final short max) {
return input < min ? min : input > max ? max : input;
}
/**
* Clamps a value within a specified range [min, max], checking for the minimum
* value first.
* <p>
* If the input is less than min, it returns min. If the input is greater than
* max, it returns max. Otherwise, it returns the input.
*
* @param input The input value to clamp
* @param min The minimum value to clamp to
* @param max The maximum value to clamp to
*
* @return The clamped value
*/
public static int clampMinFirst(final int input, final int min, final int max) {
return input < min ? min : input > max ? max : input;
}
/**
* Clamps a value within a specified range [min, max], checking for the minimum
* value first.
* <p>
* If the input is less than min, it returns min. If the input is greater than
* max, it returns max. Otherwise, it returns the input.
*
* @param input The input value to clamp
* @param min The minimum value to clamp to
* @param max The maximum value to clamp to
*
* @return The clamped value
*/
public static long clampMinFirst(final long input, final long min, final long max) {
return input < min ? min : input > max ? max : input;
}
/**
* Clamps a value within a specified range [min, max], checking for the minimum
* value first.
* <p>
* If the input is less than min, it returns min. If the input is greater than
* max, it returns max. Otherwise, it returns the input.
*
* @param input The input value to clamp
* @param min The minimum value to clamp to
* @param max The maximum value to clamp to
*
* @return The clamped value
*/
public static float clampMinFirst(final float input, final float min, final float max) {
return input < min ? min : input > max ? max : input;
}
/**
* Clamps a value within a specified range [min, max], checking for the minimum
* value first.
* <p>
* If the input is less than min, it returns min. If the input is greater than
* max, it returns max. Otherwise, it returns the input.
*
* @param input The input value to clamp
* @param min The minimum value to clamp to
* @param max The maximum value to clamp to
*
* @return The clamped value
*/
public static double clampMinFirst(final double input, final double min, final double max) {
return input < min ? min : input > max ? max : input;
}
/**
* Clamps a value within a specified range [min, max], checking for the maximum
* value first.
* <p>
* If the input is greater than max, it returns max. If the input is less than
* min, it returns min. Otherwise, it returns the input.
*
* @param input The input value to clamp
* @param min The minimum value to clamp to
* @param max The maximum value to clamp to
* @return The clamped value
*/
public static byte clampMaxFirst(final byte input, final byte min, final byte max) {
return input > max ? max : input < min ? min : input;
}
/**
* Clamps a value within a specified range [min, max], checking for the maximum
* value first.
* <p>
* If the input is greater than max, it returns max. If the input is less than
* min, it returns min. Otherwise, it returns the input.
*
* @param input The input value to clamp
* @param min The minimum value to clamp to
* @param max The maximum value to clamp to
* @return The clamped value
*/
public static short clampMaxFirst(final short input, final short min, final short max) {
return input > max ? max : input < min ? min : input;
}
/**
* Clamps a value within a specified range [min, max], checking for the maximum
* value first.
* <p>
* If the input is greater than max, it returns max. If the input is less than
* min, it returns min. Otherwise, it returns the input.
*
* @param input The input value to clamp
* @param min The minimum value to clamp to
* @param max The maximum value to clamp to
* @return The clamped value
*/
public static int clampMaxFirst(final int input, final int min, final int max) {
return input > max ? max : input < min ? min : input;
}
/**
* Clamps a value within a specified range [min, max], checking for the maximum
* value first.
* <p>
* If the input is greater than max, it returns max. If the input is less than
* min, it returns min. Otherwise, it returns the input.
*
* @param input The input value to clamp
* @param min The minimum value to clamp to
* @param max The maximum value to clamp to
* @return The clamped value
*/
public static long clampMaxFirst(final long input, final long min, final long max) {
return input > max ? max : input < min ? min : input;
}
/**
* Clamps a value within a specified range [min, max], checking for the maximum
* value first.
* <p>
* If the input is greater than max, it returns max. If the input is less than
* min, it returns min. Otherwise, it returns the input.
*
* @param input The input value to clamp
* @param min The minimum value to clamp to
* @param max The maximum value to clamp to
* @return The clamped value
*/
public static float clampMaxFirst(final float input, final float min, final float max) {
return input > max ? max : input < min ? min : input;
}
/**
* Clamps a value within a specified range [min, max], checking for the maximum
* value first.
* <p>
* If the input is greater than max, it returns max. If the input is less than
* min, it returns min. Otherwise, it returns the input.
*
* @param input The input value to clamp
* @param min The minimum value to clamp to
* @param max The maximum value to clamp to
* @return The clamped value
*/
public static double clampMaxFirst(final double input, final double min, final double max) {
return input > max ? max : input < min ? min : input;
}
}

View File

@ -35,7 +35,7 @@
package jdk_internal.bidi;
import jdk_internal.bidi.icu.text.BidiBase;
import jdk_internal.icu.text.BidiBase;
/**
* This class implements the Unicode Bidirectional Algorithm.

View File

@ -37,7 +37,7 @@
package jdk_internal.bidi;
import jdk_internal.bidi.icu.text.NormalizerBase;
import jdk_internal.icu.text.NormalizerBase;
/**
* This class provides the method {@code normalize} which transforms Unicode

View File

@ -25,8 +25,8 @@
package jdk_internal.bidi;
import jdk_internal.bidi.icu.lang.UCharacter;
import jdk_internal.bidi.icu.text.NormalizerBase;
import jdk_internal.icu.lang.UCharacter;
import jdk_internal.icu.text.NormalizerBase;
/**
* This Normalizer is for Unicode 3.2 support for IDNA only. Developers should

View File

@ -32,10 +32,10 @@
******************************************************************************
*/
package jdk_internal.bidi.icu.impl;
package jdk_internal.icu.impl;
import jdk_internal.bidi.icu.text.UnicodeSet.SpanCondition;
import jdk_internal.bidi.icu.util.OutputInt;
import jdk_internal.icu.text.UnicodeSet.SpanCondition;
import jdk_internal.icu.util.OutputInt;
/**
* Helper class for frozen UnicodeSets, implements contains() and span()

View File

@ -30,12 +30,12 @@
******************************************************************************
*/
package jdk_internal.bidi.icu.impl;
package jdk_internal.icu.impl;
import java.io.DataInputStream;
import java.io.InputStream;
import jdk_internal.bidi.icu.text.UTF16;
import jdk_internal.icu.text.UTF16;
import java.io.IOException;

View File

@ -35,10 +35,10 @@
*******************************************************************************
*/
package jdk_internal.bidi.icu.impl;
package jdk_internal.icu.impl;
import jdk_internal.bidi.CharacterIterator;
import jdk_internal.bidi.icu.text.UCharacterIterator;
import jdk_internal.icu.text.UCharacterIterator;
/**
* This class is a wrapper around CharacterIterator and implements the

View File

@ -30,7 +30,7 @@
*******************************************************************************
*/
package jdk_internal.bidi.icu.impl;
package jdk_internal.icu.impl;
import java.io.DataInputStream;
import java.io.InputStream;
@ -40,7 +40,7 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import jdk_internal.bidi.icu.util.VersionInfo;
import jdk_internal.icu.util.VersionInfo;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
public final class ICUBinary {

View File

@ -30,11 +30,11 @@
*******************************************************************************
*/
package jdk_internal.bidi.icu.impl;
package jdk_internal.icu.impl;
import java.io.IOException;
import jdk_internal.bidi.icu.text.Normalizer2;
import jdk_internal.icu.text.Normalizer2;
public final class Norm2AllModes {
// Public API dispatch via Normalizer2 subclasses -------------------------- ***

View File

@ -29,16 +29,16 @@
* Corporation and others. All Rights Reserved.
*******************************************************************************
*/
package jdk_internal.bidi.icu.impl;
package jdk_internal.icu.impl;
import java.io.IOException;
import java.nio.ByteBuffer;
import jdk_internal.bidi.icu.lang.UCharacter;
import jdk_internal.bidi.icu.text.Normalizer2;
import jdk_internal.bidi.icu.text.UTF16;
import jdk_internal.bidi.icu.util.CodePointTrie;
import jdk_internal.bidi.icu.util.VersionInfo;
import jdk_internal.icu.lang.UCharacter;
import jdk_internal.icu.text.Normalizer2;
import jdk_internal.icu.text.UTF16;
import jdk_internal.icu.util.CodePointTrie;
import jdk_internal.icu.util.VersionInfo;
// Original filename in ICU4J: Normalizer2Impl.java
public final class NormalizerImpl {

View File

@ -37,12 +37,12 @@
// 2007-08-14 Martin Buchholz
// - remove redundant casts
//
package jdk_internal.bidi.icu.impl;
package jdk_internal.icu.impl;
import java.text.ParseException;
import jdk_internal.bidi.icu.lang.UCharacter;
import jdk_internal.bidi.icu.text.UTF16;
import jdk_internal.icu.lang.UCharacter;
import jdk_internal.icu.text.UTF16;
/**
* Ported code from ICU punycode.c

View File

@ -35,11 +35,11 @@
*******************************************************************************
*/
package jdk_internal.bidi.icu.impl;
package jdk_internal.icu.impl;
import jdk_internal.bidi.icu.text.Replaceable;
import jdk_internal.bidi.icu.text.ReplaceableString;
import jdk_internal.bidi.icu.text.UCharacterIterator;
import jdk_internal.icu.text.Replaceable;
import jdk_internal.icu.text.ReplaceableString;
import jdk_internal.icu.text.UCharacterIterator;
/**
* DLF docs must define behavior when Replaceable is mutated underneath the

View File

@ -39,7 +39,7 @@
// - copy this file from icu4jsrc_3_2/src/com/ibm/icu/impl/StringPrepDataReader.java
// - move from package com.ibm.icu.impl to package sun.net.idn
//
package jdk_internal.bidi.icu.impl;
package jdk_internal.icu.impl;
import java.io.DataInputStream;
import java.io.IOException;

View File

@ -30,13 +30,13 @@
******************************************************************************
*/
package jdk_internal.bidi.icu.impl;
package jdk_internal.icu.impl;
import java.io.DataInputStream;
import java.io.InputStream;
import jdk_internal.bidi.icu.lang.UCharacter;
import jdk_internal.bidi.icu.text.UTF16;
import jdk_internal.icu.lang.UCharacter;
import jdk_internal.icu.text.UTF16;
import java.io.IOException;

View File

@ -30,7 +30,7 @@
*******************************************************************************
*/
package jdk_internal.bidi.icu.impl;
package jdk_internal.icu.impl;
import java.io.IOException;
import java.nio.ByteBuffer;

View File

@ -30,7 +30,7 @@
*******************************************************************************
*/
package jdk_internal.bidi.icu.impl;
package jdk_internal.icu.impl;
import java.io.IOException;
import java.nio.ByteBuffer;

View File

@ -41,11 +41,12 @@
* Java port of ubidi_props.h/.c.
*/
package jdk_internal.bidi.icu.impl;
package jdk_internal.icu.impl;
import java.io.IOException;
import java.nio.ByteBuffer;
import jdk_internal.bidi.icu.lang.UCharacter;
import jdk_internal.icu.lang.UCharacter;
public final class UBiDiProps {
// constructors etc. --------------------------------------------------- ***

View File

@ -29,17 +29,17 @@
*******************************************************************************
*/
package jdk_internal.bidi.icu.impl;
package jdk_internal.icu.impl;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Iterator;
import jdk_internal.bidi.icu.lang.UCharacter.HangulSyllableType;
import jdk_internal.bidi.icu.lang.UCharacter.NumericType;
import jdk_internal.bidi.icu.text.UTF16;
import jdk_internal.bidi.icu.text.UnicodeSet;
import jdk_internal.bidi.icu.util.VersionInfo;
import jdk_internal.icu.lang.UCharacter.HangulSyllableType;
import jdk_internal.icu.lang.UCharacter.NumericType;
import jdk_internal.icu.text.UTF16;
import jdk_internal.icu.text.UnicodeSet;
import jdk_internal.icu.util.VersionInfo;
/**
* <p>

View File

@ -32,14 +32,14 @@
******************************************************************************
*/
package jdk_internal.bidi.icu.impl;
package jdk_internal.icu.impl;
import java.util.ArrayList;
import jdk_internal.bidi.icu.text.UTF16;
import jdk_internal.bidi.icu.text.UnicodeSet;
import jdk_internal.bidi.icu.text.UnicodeSet.SpanCondition;
import jdk_internal.bidi.icu.util.OutputInt;
import jdk_internal.icu.text.UTF16;
import jdk_internal.icu.text.UnicodeSet;
import jdk_internal.icu.text.UnicodeSet.SpanCondition;
import jdk_internal.icu.util.OutputInt;
/*
* Implement span() etc. for a set with strings.

View File

@ -29,13 +29,13 @@
*******************************************************************************
*/
package jdk_internal.bidi.icu.impl;
package jdk_internal.icu.impl;
import java.io.IOException;
import java.util.Locale;
import jdk_internal.bidi.icu.lang.UCharacter;
import jdk_internal.bidi.icu.text.UTF16;
import jdk_internal.icu.lang.UCharacter;
import jdk_internal.icu.text.UTF16;
public final class Utility {

View File

@ -30,13 +30,13 @@
*******************************************************************************
*/
package jdk_internal.bidi.icu.lang;
package jdk_internal.icu.lang;
import jdk_internal.bidi.icu.impl.UBiDiProps;
import jdk_internal.bidi.icu.impl.UCharacterProperty;
import jdk_internal.bidi.icu.text.Normalizer2;
import jdk_internal.bidi.icu.text.UTF16;
import jdk_internal.bidi.icu.util.VersionInfo;
import jdk_internal.icu.impl.UBiDiProps;
import jdk_internal.icu.impl.UCharacterProperty;
import jdk_internal.icu.text.Normalizer2;
import jdk_internal.icu.text.UTF16;
import jdk_internal.icu.util.VersionInfo;
/**
* <p>

View File

@ -35,7 +35,7 @@
// - move from package com.ibm.icu.lang to package sun.net.idn
//
package jdk_internal.bidi.icu.lang;
package jdk_internal.icu.lang;
/**
* Enumerated Unicode character linguistic direction constants. Used as return

View File

@ -51,7 +51,7 @@
// DIRECTIONALITY_BOUNDARY_NEUTRAL, DIRECTIONALITY_UNDEFINED
//
package jdk_internal.bidi.icu.lang;
package jdk_internal.icu.lang;
/**
* A container for the different 'enumerated types' used by UCharacter.

View File

@ -46,7 +46,7 @@
* fallbacks for unsupported combinations.
*/
package jdk_internal.bidi.icu.text;
package jdk_internal.icu.text;
import java.lang.reflect.Array;
import java.util.Arrays;
@ -55,8 +55,8 @@ import jdk_internal.bidi.AttributedCharacterIterator;
import jdk_internal.bidi.Bidi;
import jdk_internal.bidi.NumericShaper;
import jdk_internal.bidi.TextAttribute;
import jdk_internal.bidi.icu.impl.UBiDiProps;
import jdk_internal.bidi.icu.lang.UCharacter;
import jdk_internal.icu.impl.UBiDiProps;
import jdk_internal.icu.lang.UCharacter;
/**
*

View File

@ -33,7 +33,7 @@
* (ported from C code written by Markus W. Scherer)
*/
package jdk_internal.bidi.icu.text;
package jdk_internal.icu.text;
import java.util.Arrays;

View File

@ -37,7 +37,7 @@
* (ported from C code written by Markus W. Scherer)
*/
package jdk_internal.bidi.icu.text;
package jdk_internal.icu.text;
/**
* A BidiRun represents a sequence of characters at the same embedding level.

View File

@ -33,9 +33,9 @@
* (ported from C code written by Markus W. Scherer)
*/
package jdk_internal.bidi.icu.text;
package jdk_internal.icu.text;
import jdk_internal.bidi.icu.lang.UCharacter;
import jdk_internal.icu.lang.UCharacter;
final class BidiWriter {

View File

@ -29,7 +29,7 @@
* Corporation and others. All Rights Reserved.
*******************************************************************************
*/
package jdk_internal.bidi.icu.text;
package jdk_internal.icu.text;
import java.io.IOException;

View File

@ -30,9 +30,9 @@
*******************************************************************************
*/
package jdk_internal.bidi.icu.text;
package jdk_internal.icu.text;
import jdk_internal.bidi.icu.impl.Norm2AllModes;
import jdk_internal.icu.impl.Norm2AllModes;
/**
* Unicode normalization functionality for standard Unicode normalization or for

View File

@ -29,11 +29,11 @@
* others. All Rights Reserved.
*******************************************************************************
*/
package jdk_internal.bidi.icu.text;
package jdk_internal.icu.text;
import jdk_internal.bidi.CharacterIterator;
import jdk_internal.bidi.Normalizer;
import jdk_internal.bidi.icu.impl.Norm2AllModes;
import jdk_internal.icu.impl.Norm2AllModes;
/**
* Unicode Normalization

View File

@ -35,7 +35,7 @@
*******************************************************************************
*/
package jdk_internal.bidi.icu.text;
package jdk_internal.icu.text;
/**
* <code>Replaceable</code> is an interface representing a string of characters

View File

@ -30,7 +30,7 @@
*******************************************************************************
*/
package jdk_internal.bidi.icu.text;
package jdk_internal.icu.text;
/**
* <code>ReplaceableString</code> is an adapter class that implements the

View File

@ -40,7 +40,7 @@
// 2007-08-14 Martin Buchholz
// - remove redundant casts
//
package jdk_internal.bidi.icu.text;
package jdk_internal.icu.text;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
@ -50,12 +50,12 @@ import java.io.InputStream;
import jdk_internal.bidi.Normalizer;
import jdk_internal.bidi.ParseException;
import jdk_internal.bidi.SunNormalizer;
import jdk_internal.bidi.icu.impl.CharTrie;
import jdk_internal.bidi.icu.impl.StringPrepDataReader;
import jdk_internal.bidi.icu.impl.Trie;
import jdk_internal.bidi.icu.lang.UCharacter;
import jdk_internal.bidi.icu.lang.UCharacterDirection;
import jdk_internal.bidi.icu.util.VersionInfo;
import jdk_internal.icu.impl.CharTrie;
import jdk_internal.icu.impl.StringPrepDataReader;
import jdk_internal.icu.impl.Trie;
import jdk_internal.icu.lang.UCharacter;
import jdk_internal.icu.lang.UCharacterDirection;
import jdk_internal.icu.util.VersionInfo;
/**
* StringPrep API implements the StingPrep framework as described by

View File

@ -30,12 +30,12 @@
*******************************************************************************
*/
package jdk_internal.bidi.icu.text;
package jdk_internal.icu.text;
import jdk_internal.bidi.CharacterIterator;
import jdk_internal.bidi.icu.impl.CharacterIteratorWrapper;
import jdk_internal.bidi.icu.impl.ReplaceableUCharacterIterator;
import jdk_internal.bidi.icu.impl.UCharacterProperty;
import jdk_internal.icu.impl.CharacterIteratorWrapper;
import jdk_internal.icu.impl.ReplaceableUCharacterIterator;
import jdk_internal.icu.impl.UCharacterProperty;
/**
* Abstract class that defines an API for iteration on text objects.This is an

View File

@ -29,9 +29,9 @@
*******************************************************************************
*/
package jdk_internal.bidi.icu.text;
package jdk_internal.icu.text;
import jdk_internal.bidi.icu.impl.UCharacterProperty;
import jdk_internal.icu.impl.UCharacterProperty;
/**
* <p>

View File

@ -29,19 +29,19 @@
* others. All Rights Reserved.
*******************************************************************************
*/
package jdk_internal.bidi.icu.text;
package jdk_internal.icu.text;
import java.text.ParsePosition;
import java.util.ArrayList;
import java.util.TreeSet;
import jdk_internal.bidi.icu.impl.BMPSet;
import jdk_internal.bidi.icu.impl.UCharacterProperty;
import jdk_internal.bidi.icu.impl.UnicodeSetStringSpan;
import jdk_internal.bidi.icu.impl.Utility;
import jdk_internal.bidi.icu.lang.UCharacter;
import jdk_internal.bidi.icu.util.OutputInt;
import jdk_internal.bidi.icu.util.VersionInfo;
import jdk_internal.icu.impl.BMPSet;
import jdk_internal.icu.impl.UCharacterProperty;
import jdk_internal.icu.impl.UnicodeSetStringSpan;
import jdk_internal.icu.impl.Utility;
import jdk_internal.icu.lang.UCharacter;
import jdk_internal.icu.util.OutputInt;
import jdk_internal.icu.util.VersionInfo;
/**
* A mutable set of Unicode characters and multicharacter strings. Objects of

View File

@ -27,7 +27,7 @@
// created: 2018may10 Markus W. Scherer
package jdk_internal.bidi.icu.util;
package jdk_internal.icu.util;
import java.util.Iterator;
import java.util.NoSuchElementException;

View File

@ -27,9 +27,9 @@
// created: 2018may04 Markus W. Scherer
package jdk_internal.bidi.icu.util;
package jdk_internal.icu.util;
import static jdk_internal.bidi.icu.impl.NormalizerImpl.UTF16Plus;
import static jdk_internal.icu.impl.NormalizerImpl.UTF16Plus;
import java.io.DataOutputStream;
import java.io.IOException;
@ -38,7 +38,7 @@ import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import jdk_internal.bidi.icu.impl.ICUBinary;
import jdk_internal.icu.impl.ICUBinary;
/**
* Immutable Unicode code point trie. Fast, reasonably compact, map from Unicode

View File

@ -29,7 +29,7 @@
* others. All Rights Reserved.
*******************************************************************************
*/
package jdk_internal.bidi.icu.util;
package jdk_internal.icu.util;
/**
* Simple struct-like class for int output parameters. Like

View File

@ -34,7 +34,7 @@
*******************************************************************************
*/
package jdk_internal.bidi.icu.util;
package jdk_internal.icu.util;
import java.util.HashMap;

View File

@ -0,0 +1,326 @@
/*
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package net.lax1dude.eaglercraft.v1_8;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.Properties;
public class EaglerProperties extends Properties {
public void load(Reader reader) throws IOException {
load0(new LineReader(reader));
}
public void load(InputStream inStream) throws IOException {
load0(new LineReader(inStream));
}
private void load0(LineReader lr) throws IOException {
StringBuilder outBuffer = new StringBuilder();
int limit;
int keyLen;
int valueStart;
boolean hasSep;
boolean precedingBackslash;
boolean first = true;
while ((limit = lr.readLine()) >= 0) {
keyLen = 0;
valueStart = limit;
hasSep = false;
if(first && limit > 0) {
if(lr.lineBuf[0] == 65279) {
keyLen = 1;
}
}
first = false;
// System.out.println("line=<" + new String(lineBuf, 0, limit) + ">");
precedingBackslash = false;
while (keyLen < limit) {
char c = lr.lineBuf[keyLen];
// need check if escaped.
if ((c == '=' || c == ':') && !precedingBackslash) {
valueStart = keyLen + 1;
hasSep = true;
break;
} else if ((c == ' ' || c == '\t' || c == '\f') && !precedingBackslash) {
valueStart = keyLen + 1;
break;
}
if (c == '\\') {
precedingBackslash = !precedingBackslash;
} else {
precedingBackslash = false;
}
keyLen++;
}
while (valueStart < limit) {
char c = lr.lineBuf[valueStart];
if (c != ' ' && c != '\t' && c != '\f') {
if (!hasSep && (c == '=' || c == ':')) {
hasSep = true;
} else {
break;
}
}
valueStart++;
}
String key = loadConvert(lr.lineBuf, 0, keyLen, outBuffer);
String value = loadConvert(lr.lineBuf, valueStart, limit - valueStart, outBuffer);
put(key, value);
}
}
/*
* Read in a "logical line" from an InputStream/Reader, skip all comment and
* blank lines and filter out those leading whitespace characters (\u0020,
* \u0009 and \u000c) from the beginning of a "natural line". Method returns the
* char length of the "logical line" and stores the line in "lineBuf".
*/
private static class LineReader {
LineReader(InputStream inStream) {
this.inStream = inStream;
inByteBuf = new byte[8192];
}
LineReader(Reader reader) {
this.reader = reader;
inCharBuf = new char[8192];
}
char[] lineBuf = new char[1024];
private byte[] inByteBuf;
private char[] inCharBuf;
private int inLimit = 0;
private int inOff = 0;
private InputStream inStream;
private Reader reader;
int readLine() throws IOException {
// use locals to optimize for interpreted performance
int len = 0;
int off = inOff;
int limit = inLimit;
boolean skipWhiteSpace = true;
boolean appendedLineBegin = false;
boolean precedingBackslash = false;
boolean fromStream = inStream != null;
byte[] byteBuf = inByteBuf;
char[] charBuf = inCharBuf;
char[] lineBuf = this.lineBuf;
char c;
while (true) {
if (off >= limit) {
inLimit = limit = fromStream ? inStream.read(byteBuf) : reader.read(charBuf);
if (limit <= 0) {
if (len == 0) {
return -1;
}
return precedingBackslash ? len - 1 : len;
}
off = 0;
}
// (char)(byte & 0xFF) is equivalent to calling a ISO8859-1 decoder.
c = (fromStream) ? (char) (byteBuf[off++] & 0xFF) : charBuf[off++];
if (skipWhiteSpace) {
if (c == ' ' || c == '\t' || c == '\f') {
continue;
}
if (!appendedLineBegin && (c == '\r' || c == '\n')) {
continue;
}
skipWhiteSpace = false;
appendedLineBegin = false;
}
if (len == 0) { // Still on a new logical line
if (c == '#' || c == '!') {
// Comment, quickly consume the rest of the line
// When checking for new line characters a range check,
// starting with the higher bound ('\r') means one less
// branch in the common case.
commentLoop: while (true) {
if (fromStream) {
byte b;
while (off < limit) {
b = byteBuf[off++];
if (b <= '\r' && (b == '\r' || b == '\n'))
break commentLoop;
}
if (off == limit) {
inLimit = limit = inStream.read(byteBuf);
if (limit <= 0) { // EOF
return -1;
}
off = 0;
}
} else {
while (off < limit) {
c = charBuf[off++];
if (c <= '\r' && (c == '\r' || c == '\n'))
break commentLoop;
}
if (off == limit) {
inLimit = limit = reader.read(charBuf);
if (limit <= 0) { // EOF
return -1;
}
off = 0;
}
}
}
skipWhiteSpace = true;
continue;
}
}
if (c != '\n' && c != '\r') {
lineBuf[len++] = c;
if (len == lineBuf.length) {
lineBuf = new char[len + (len << 1)];
System.arraycopy(this.lineBuf, 0, lineBuf, 0, len);
this.lineBuf = lineBuf;
}
// flip the preceding backslash flag
precedingBackslash = (c == '\\') ? !precedingBackslash : false;
} else {
// reached EOL
if (len == 0) {
skipWhiteSpace = true;
continue;
}
if (off >= limit) {
inLimit = limit = fromStream ? inStream.read(byteBuf) : reader.read(charBuf);
off = 0;
if (limit <= 0) { // EOF
return precedingBackslash ? len - 1 : len;
}
}
if (precedingBackslash) {
// backslash at EOL is not part of the line
len -= 1;
// skip leading whitespace characters in the following line
skipWhiteSpace = true;
appendedLineBegin = true;
precedingBackslash = false;
// take care not to include any subsequent \n
if (c == '\r') {
if (fromStream) {
if (byteBuf[off] == '\n') {
off++;
}
} else {
if (charBuf[off] == '\n') {
off++;
}
}
}
} else {
inOff = off;
return len;
}
}
}
}
}
/*
* Converts encoded &#92;uxxxx to unicode chars and changes special saved chars
* to their original forms
*/
private String loadConvert(char[] in, int off, int len, StringBuilder out) {
char aChar;
int end = off + len;
int start = off;
while (off < end) {
aChar = in[off++];
if (aChar == '\\') {
break;
}
}
if (off == end) { // No backslash
return new String(in, start, len);
}
// backslash found at off - 1, reset the shared buffer, rewind offset
out.setLength(0);
off--;
out.append(in, start, off - start);
while (off < end) {
aChar = in[off++];
if (aChar == '\\') {
// No need to bounds check since LineReader::readLine excludes
// unescaped \s at the end of the line
aChar = in[off++];
if (aChar == 'u') {
// Read the xxxx
if (off > end - 4)
throw new IllegalArgumentException("Malformed \\uxxxx encoding.");
int value = 0;
for (int i = 0; i < 4; i++) {
aChar = in[off++];
switch (aChar) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
value = (value << 4) + aChar - '0';
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
value = (value << 4) + 10 + aChar - 'a';
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
value = (value << 4) + 10 + aChar - 'A';
break;
default:
throw new IllegalArgumentException("Malformed \\uxxxx encoding.");
};
}
out.append((char) value);
} else {
if (aChar == 't')
aChar = '\t';
else if (aChar == 'r')
aChar = '\r';
else if (aChar == 'n')
aChar = '\n';
else if (aChar == 'f')
aChar = '\f';
out.append(aChar);
}
} else {
out.append(aChar);
}
}
return out.toString();
}
}

View File

@ -10,7 +10,7 @@ public class EaglercraftVersion {
/// Customize these to fit your fork:
public static final String projectForkName = "EaglercraftX";
public static final String projectForkVersion = "u47";
public static final String projectForkVersion = "u48";
public static final String projectForkVendor = "lax1dude";
public static final String projectForkURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8";
@ -20,20 +20,20 @@ public class EaglercraftVersion {
public static final String projectOriginName = "EaglercraftX";
public static final String projectOriginAuthor = "lax1dude";
public static final String projectOriginRevision = "1.8";
public static final String projectOriginVersion = "u47";
public static final String projectOriginVersion = "u48";
public static final String projectOriginURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8"; // rest in peace
// EPK Version Identifier
public static final String EPKVersionIdentifier = "u47"; // Set to null to disable EPK version check
public static final String EPKVersionIdentifier = "u48"; // Set to null to disable EPK version check
// Updating configuration
public static final boolean enableUpdateService = true;
public static final String updateBundlePackageName = "net.lax1dude.eaglercraft.v1_8.client";
public static final int updateBundlePackageVersionInt = 47;
public static final int updateBundlePackageVersionInt = 48;
public static final String updateLatestLocalStorageKey = "latestUpdate_" + updateBundlePackageName;

View File

@ -6,6 +6,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -64,7 +65,12 @@ public class IOUtils {
while((s = rd.readLine()) != null) {
b.append(s).append('\n');
}
return b.toString();
// Handle BOM
if(c == StandardCharsets.UTF_8 && b.length() > 0 && b.charAt(0) == 65279) {
return b.substring(1, b.length());
}else {
return b.toString();
}
}finally {
is.close();
}

View File

@ -17,4 +17,10 @@ package net.lax1dude.eaglercraft.v1_8.internal;
*/
public interface ITextureGL extends IObjectGL {
void setCacheSize(int w, int h);
int getWidth();
int getHeight();
}

View File

@ -3,6 +3,7 @@ package net.lax1dude.eaglercraft.v1_8.minecraft;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@ -19,6 +20,7 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import net.lax1dude.eaglercraft.v1_8.ArrayUtils;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.EaglerInputStream;
import net.lax1dude.eaglercraft.v1_8.crypto.SHA1Digest;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
@ -28,7 +30,7 @@ import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.minecraft.client.resources.AbstractResourcePack;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
* Copyright (c) 2024-2025 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -70,6 +72,80 @@ public class EaglerFolderResourcePack extends AbstractResourcePack {
this.prefix = prefix;
this.domains = domains;
this.timestamp = timestamp;
this.resourceIndex = new ResourceIndex() {
@Override
protected Collection<String> getPropertiesFiles0() {
VFile2 file = new VFile2(prefix, resourcePackFile, "assets/minecraft/optifine/_property_files_index.json");
String str = file.getAllChars();
Collection<String> propertyFiles = null;
if(str != null) {
propertyFiles = loadPropertyFileList(str);
if(propertyFiles != null) {
return propertyFiles;
}
}
VFile2 mcDir = new VFile2(prefix, resourcePackFile, "assets/minecraft");
int pfxLen = mcDir.getPath().length() + 1;
List<String> philes = mcDir.listFilenames(true);
propertyFiles = new ArrayList<>();
JSONArray arr = new JSONArray();
for(int i = 0, l = philes.size(); i < l; ++i) {
String name = philes.get(i);
if(name.length() > pfxLen && name.endsWith(".properties")) {
name = name.substring(pfxLen);
propertyFiles.add(name);
arr.put(name);
}
}
JSONObject json = new JSONObject();
json.put("propertyFiles", arr);
file.setAllChars(json.toString());
return propertyFiles;
}
@Override
protected Collection<String> getCITPotionsFiles0() {
VFile2 file = new VFile2(prefix, resourcePackFile, "assets/minecraft/mcpatcher/cit/potion/_potions_files_index.json");
String str = file.getAllChars();
Collection<String> propertyFiles = null;
if(str != null) {
propertyFiles = loadPotionsFileList(str);
if(propertyFiles != null) {
return propertyFiles;
}
}
VFile2 mcDir = new VFile2(prefix, resourcePackFile, "assets/minecraft/mcpatcher/cit/potion");
int pfxLen = mcDir.getPath().length() - 20;
List<String> philes = mcDir.listFilenames(true);
propertyFiles = new ArrayList<>();
JSONArray arr = new JSONArray();
for(int i = 0, l = philes.size(); i < l; ++i) {
String name = philes.get(i);
if(name.length() > pfxLen && name.endsWith(".png")) {
name = name.substring(pfxLen);
propertyFiles.add(name);
arr.put(name);
}
}
mcDir = new VFile2(prefix, resourcePackFile, "assets/minecraft/optifine/cit/potion");
pfxLen = mcDir.getPath().length() - 19;
philes = mcDir.listFilenames(true);
for(int i = 0, l = philes.size(); i < l; ++i) {
String name = philes.get(i);
if(name.length() > pfxLen && name.endsWith(".png")) {
name = name.substring(pfxLen);
propertyFiles.add(name);
arr.put(name);
}
}
JSONObject json = new JSONObject();
json.put("potionsFiles", arr);
file.setAllChars(json.toString());
return propertyFiles;
}
};
}
@Override
@ -177,6 +253,8 @@ public class EaglerFolderResourcePack extends AbstractResourcePack {
}
Set<String> domainsList = Sets.newHashSet();
JSONArray propertyFiles = new JSONArray();
JSONArray potionsFiles = new JSONArray();
String fn;
for(int i = 0, l = fileNames.size(); i < l; ++i) {
fn = fileNames.get(i);
@ -184,7 +262,18 @@ public class EaglerFolderResourcePack extends AbstractResourcePack {
fn = fn.substring(prefixLen + 7);
int j = fn.indexOf('/');
if(j != -1) {
domainsList.add(fn.substring(0, j));
String dm = fn.substring(0, j);
domainsList.add(dm);
if("minecraft".equals(dm)) {
if(fn.endsWith(".properties")) {
propertyFiles.put(fn.substring(10));
}else if((fn.startsWith("minecraft/mcpatcher/cit/potion/")
|| fn.startsWith("minecraft/mcpatcher/cit/Potion/")) && fn.endsWith(".png")) {
potionsFiles.put(fn.substring(10));
}else if(fn.startsWith("minecraft/optifine/cit/potion/") && fn.endsWith(".png")) {
potionsFiles.put(fn.substring(10));
}
}
}
}
}
@ -234,9 +323,19 @@ public class EaglerFolderResourcePack extends AbstractResourcePack {
}
throw ex;
}
logger.info("Updating manifest...");
JSONObject json = new JSONObject();
json.put("propertyFiles", propertyFiles);
(new VFile2(prefix, folderName, "assets/minecraft/optifine/_property_files_index.json"))
.setAllChars(json.toString());
json = new JSONObject();
json.put("potionsFiles", propertyFiles);
(new VFile2(prefix, folderName, "assets/minecraft/mcpatcher/cit/potion/_potions_files_index.json"))
.setAllChars(json.toString());
VFile2 manifestFile = new VFile2(prefix, "manifest.json");
String str = manifestFile.getAllChars();
JSONArray arr = null;
@ -363,4 +462,37 @@ public class EaglerFolderResourcePack extends AbstractResourcePack {
}
}
}
public static Collection<String> loadPropertyFileList(String str) {
try {
JSONObject json = new JSONObject(str);
JSONArray arr = json.getJSONArray("propertyFiles");
int l = arr.length();
Collection<String> ret = new ArrayList<>(l);
for(int i = 0; i < l; ++i) {
ret.add(arr.getString(i));
}
return ret;
}catch(JSONException ex) {
EagRuntime.debugPrintStackTrace(ex);
return null;
}
}
public static Collection<String> loadPotionsFileList(String str) {
try {
JSONObject json = new JSONObject(str);
JSONArray arr = json.getJSONArray("potionsFiles");
int l = arr.length();
Collection<String> ret = new ArrayList<>(l);
for(int i = 0; i < l; ++i) {
ret.add(arr.getString(i));
}
return ret;
}catch(JSONException ex) {
EagRuntime.debugPrintStackTrace(ex);
return null;
}
}
}

View File

@ -8,10 +8,10 @@ import com.carrotsearch.hppc.cursors.IntCursor;
import com.google.common.collect.Lists;
import net.lax1dude.eaglercraft.v1_8.HString;
import net.lax1dude.eaglercraft.v1_8.internal.IFramebufferGL;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.opengl.ImageData;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureClock;
import net.minecraft.client.renderer.texture.TextureCompass;
import net.minecraft.client.renderer.texture.TextureUtil;
@ -21,9 +21,10 @@ import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.util.ReportedException;
import net.minecraft.util.ResourceLocation;
import net.optifine.util.CounterInt;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
* Copyright (c) 2022-2025 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -56,11 +57,14 @@ public class EaglerTextureAtlasSprite {
protected float maxV;
protected int frameCounter;
protected int tickCounter;
private int indexInMap = -1;
protected static String locationNameClock = "builtin/clock";
protected static String locationNameCompass = "builtin/compass";
protected TextureAnimationCache animationCache = null;
public String optifineBaseTextureName = null;
public EaglerTextureAtlasSprite(String spriteName) {
this.iconName = spriteName;
}
@ -101,6 +105,9 @@ public class EaglerTextureAtlasSprite {
this.maxU = atlasSpirit.maxU;
this.minV = atlasSpirit.minV;
this.maxV = atlasSpirit.maxV;
if (atlasSpirit != Minecraft.getMinecraft().getTextureMapBlocks().getMissingSprite()) {
this.indexInMap = atlasSpirit.indexInMap;
}
}
public int getOriginX() {
@ -149,7 +156,13 @@ public class EaglerTextureAtlasSprite {
return this.iconName;
}
public void updateAnimation(IFramebufferGL[] copyColorFramebuffer) {
protected static interface IAnimCopyFunction {
void updateAnimation(int mapWidth, int mapHeight, int mapLevel);
}
protected IAnimCopyFunction currentAnimUpdater = null;
public void updateAnimation() {
if(animationCache == null) {
throw new IllegalStateException("Animation cache for '" + this.iconName + "' was never baked!");
}
@ -162,7 +175,12 @@ public class EaglerTextureAtlasSprite {
this.tickCounter = 0;
int k = this.animationMetadata.getFrameIndex(this.frameCounter);
if (i != k && k >= 0 && k < this.framesTextureData.size()) {
animationCache.copyFrameLevelsToTex2D(k, this.originX, this.originY, this.width, this.height, copyColorFramebuffer);
currentAnimUpdater = (mapWidth, mapHeight, mapLevel) -> {
animationCache.copyFrameToTex2D(k, mapLevel, this.originX >> mapLevel, this.originY >> mapLevel,
this.width >> mapLevel, this.height >> mapLevel, mapWidth, mapHeight);
};
}else {
currentAnimUpdater = null;
}
} else if (this.animationMetadata.isInterpolate()) {
float f = 1.0f - (float) this.tickCounter / (float) this.animationMetadata.getFrameTimeSingle(this.frameCounter);
@ -171,8 +189,22 @@ public class EaglerTextureAtlasSprite {
: this.animationMetadata.getFrameCount();
int k = this.animationMetadata.getFrameIndex((this.frameCounter + 1) % j);
if (i != k && k >= 0 && k < this.framesTextureData.size()) {
animationCache.copyInterpolatedFrameLevelsToTex2D(i, k, f, this.originX, this.originY, this.width, this.height, copyColorFramebuffer);
currentAnimUpdater = (mapWidth, mapHeight, mapLevel) -> {
animationCache.copyInterpolatedFrameToTex2D(i, k, f, mapLevel, this.originX >> mapLevel,
this.originY >> mapLevel, this.width >> mapLevel, this.height >> mapLevel, mapWidth,
mapHeight);
};
}else {
currentAnimUpdater = null;
}
} else {
currentAnimUpdater = null;
}
}
public void copyAnimationFrame(int mapWidth, int mapHeight, int mapLevel) {
if(currentAnimUpdater != null) {
currentAnimUpdater.updateAnimation(mapWidth, mapHeight, mapLevel);
}
}
@ -367,7 +399,7 @@ public class EaglerTextureAtlasSprite {
}
}
public void updateAnimationPBR(IFramebufferGL[] copyColorFramebuffer, IFramebufferGL[] copyMaterialFramebuffer, int materialTexOffset) {
public void updateAnimationPBR() {
Throwable t = new UnsupportedOperationException("PBR is not enabled");
try {
throw t;
@ -375,4 +407,37 @@ public class EaglerTextureAtlasSprite {
logger.error(t);
}
}
public void copyAnimationFramePBR(int pass, int width, int height, int level) {
Throwable t = new UnsupportedOperationException("PBR is not enabled");
try {
throw t;
}catch(Throwable tt) {
logger.error(t);
}
}
public int getIndexInMap() {
return this.indexInMap;
}
public void setIndexInMap(int p_setIndexInMap_1_) {
this.indexInMap = p_setIndexInMap_1_;
}
public void updateIndexInMap(CounterInt p_updateIndexInMap_1_) {
if (this.indexInMap < 0) {
this.indexInMap = p_updateIndexInMap_1_.nextValue();
}
}
public double getSpriteU16(float p_getSpriteU16_1_) {
float f = this.maxU - this.minU;
return (double) ((p_getSpriteU16_1_ - this.minU) / f * 16.0F);
}
public double getSpriteV16(float p_getSpriteV16_1_) {
float f = this.maxV - this.minV;
return (double) ((p_getSpriteV16_1_ - this.minV) / f * 16.0F);
}
}

View File

@ -0,0 +1,43 @@
package net.lax1dude.eaglercraft.v1_8.minecraft;
import java.util.Collection;
/**
* Copyright (c) 2025 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public abstract class ResourceIndex {
protected Collection<String> propertiesCache = null;
protected Collection<String> citPotionsCache = null;
public Collection<String> getPropertiesFiles() {
if(propertiesCache == null) {
propertiesCache = getPropertiesFiles0();
}
return propertiesCache;
}
protected abstract Collection<String> getPropertiesFiles0();
public Collection<String> getCITPotionsFiles() {
if(citPotionsCache == null) {
citPotionsCache = getCITPotionsFiles0();
}
return citPotionsCache;
}
protected abstract Collection<String> getCITPotionsFiles0();
}

View File

@ -1,22 +1,19 @@
package net.lax1dude.eaglercraft.v1_8.minecraft;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.IFramebufferGL;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.IntBuffer;
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.lax1dude.eaglercraft.v1_8.opengl.SpriteLevelMixer;
import net.lax1dude.eaglercraft.v1_8.opengl.TextureCopyUtil;
import net.lax1dude.eaglercraft.v1_8.vector.Matrix3f;
import net.minecraft.client.renderer.GLAllocation;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
* Copyright (c) 2022-2025 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -40,8 +37,6 @@ public class TextureAnimationCache {
private int[] cacheTextures = null;
public static final int _GL_FRAMEBUFFER = 0x8D40;
public TextureAnimationCache(int width, int height, int mipLevels) {
this.width = width;
this.height = height;
@ -105,76 +100,40 @@ public class TextureAnimationCache {
}
}
public void copyFrameLevelsToTex2D(int animationFrame, int dx, int dy, int w, int h, IFramebufferGL[] dstFramebuffers) {
copyFrameLevelsToTex2D(animationFrame, mipLevels, dx, dy, w, h, dstFramebuffers);
}
/**
* WARNING: call <code>_wglBindFramebuffer(_GL_FRAMEBUFFER, null);</code> when complete
*/
public void copyFrameLevelsToTex2D(int animationFrame, int levels, int dx, int dy, int w, int h, IFramebufferGL[] dstFramebuffers) {
for(int i = 0; i < levels; ++i) {
_wglBindFramebuffer(_GL_FRAMEBUFFER, dstFramebuffers[i]);
copyFrameToTex2D(animationFrame, i, dx >> i, dy >> i, w >> i, h >> i);
}
}
public void copyFrameToTex2D(int animationFrame, int level, int dx, int dy, int w, int h) {
public void copyFrameToTex2D(int animationFrame, int level, int dx, int dy, int w, int h, int mapWidth, int mapHeight) {
if(cacheTextures == null) {
throw new IllegalStateException("Cannot copy from uninitialized TextureAnimationCache");
}
GlStateManager.disableBlend();
GlStateManager.disableAlpha();
GlStateManager.bindTexture(cacheTextures[level]);
TextureCopyUtil.srcSize(width >> level, (height >> level) * frameCount);
TextureCopyUtil.blitTextureUsingViewports(0, h * animationFrame, dx, dy, w, h);
}
public void copyInterpolatedFrameLevelsToTex2D(int animationFrameFrom, int animationFrameTo, float factor, int dx,
int dy, int w, int h, IFramebufferGL[] dstFramebuffers) {
copyInterpolatedFrameLevelsToTex2D(animationFrameFrom, animationFrameTo, factor, mipLevels, dx, dy, w, h, dstFramebuffers);
}
/**
* WARNING: call <code>_wglBindFramebuffer(_GL_FRAMEBUFFER, null);</code> when complete
*/
public void copyInterpolatedFrameLevelsToTex2D(int animationFrameFrom, int animationFrameTo, float factor,
int levels, int dx, int dy, int w, int h, IFramebufferGL[] dstFramebuffers) {
for(int i = 0; i < levels; ++i) {
_wglBindFramebuffer(_GL_FRAMEBUFFER, dstFramebuffers[i]);
copyInterpolatedFrameToTex2D(animationFrameFrom, animationFrameTo, factor, i, dx >> i, dy >> i, w >> i, h >> i);
}
TextureCopyUtil.dstSize(mapWidth, mapHeight);
TextureCopyUtil.blitTexture(0, h * animationFrame, dx, dy, w, h);
}
public void copyInterpolatedFrameToTex2D(int animationFrameFrom, int animationFrameTo, float factor, int level,
int dx, int dy, int w, int h) {
int dx, int dy, int w, int h, int mapWidth, int mapHeight) {
if(cacheTextures == null) {
throw new IllegalStateException("Cannot copy from uninitialized TextureAnimationCache");
}
GlStateManager.viewport(dx, dy, w, h);
GlStateManager.bindTexture(cacheTextures[level]);
GlStateManager.disableBlend();
Matrix3f matrix = new Matrix3f();
matrix.m11 = 1.0f / frameCount;
matrix.m21 = matrix.m11 * animationFrameFrom;
SpriteLevelMixer.setMatrix3f(matrix);
SpriteLevelMixer.srcSize(width >> level, (height >> level) * frameCount);
SpriteLevelMixer.dstSize(mapWidth, mapHeight);
SpriteLevelMixer.setBlendColor(factor, factor, factor, factor);
SpriteLevelMixer.setBiasColor(0.0f, 0.0f, 0.0f, 0.0f);
SpriteLevelMixer.drawSprite(0);
SpriteLevelMixer.drawSprite(0, 0, h * animationFrameFrom, w, h, dx, dy, w, h);
matrix.m21 = matrix.m11 * animationFrameTo;
SpriteLevelMixer.setMatrix3f(matrix);
float fac1 = 1.0f - factor;
SpriteLevelMixer.setBlendColor(fac1, fac1, fac1, fac1);
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL_ONE, GL_ONE);
SpriteLevelMixer.drawSprite(0);
SpriteLevelMixer.drawSprite(0, 0, h * animationFrameTo, w, h, dx, dy, w, h);
GlStateManager.disableBlend();
GlStateManager.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

View File

@ -246,6 +246,7 @@ public class EaglercraftGPU {
public static final void glTexImage2D(int target, int level, int internalFormat, int w, int h, int unused,
int format, int type, ByteBuffer pixels) {
GlStateManager.setTextureCachedSize(target, w, h);
if(glesVers >= 300) {
_wglTexImage2D(target, level, internalFormat, w, h, unused, format, type, pixels);
}else {
@ -256,6 +257,7 @@ public class EaglercraftGPU {
public static final void glTexImage2D(int target, int level, int internalFormat, int w, int h, int unused,
int format, int type, IntBuffer pixels) {
GlStateManager.setTextureCachedSize(target, w, h);
if(glesVers >= 300) {
_wglTexImage2D(target, level, internalFormat, w, h, unused, format, type, pixels);
}else {
@ -270,6 +272,7 @@ public class EaglercraftGPU {
}
public static final void glTexStorage2D(int target, int levels, int internalFormat, int w, int h) {
GlStateManager.setTextureCachedSize(target, w, h);
if(texStorageCapable && (glesVers >= 300 || levels == 1 || (MathHelper.calculateLogBaseTwo(Math.max(w, h)) + 1) == levels)) {
_wglTexStorage2D(target, levels, internalFormat, w, h);
}else {
@ -914,7 +917,6 @@ public class EaglercraftGPU {
PlatformOpenGL.enterVAOEmulationHook();
GLSLHeader.init();
DrawUtils.init();
SpriteLevelMixer.initialize();
if(instancingCapable) {
InstancedFontRenderer.initialize();
InstancedParticleRenderer.initialize();
@ -928,7 +930,6 @@ public class EaglercraftGPU {
public static final void destroyCache() {
GLSLHeader.destroy();
DrawUtils.destroy();
SpriteLevelMixer.destroy();
InstancedFontRenderer.destroy();
InstancedParticleRenderer.destroy();
EffectPipelineFXAA.destroy();

View File

@ -1,11 +1,13 @@
package net.lax1dude.eaglercraft.v1_8.opengl;
import net.lax1dude.eaglercraft.v1_8.internal.ITextureGL;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.FloatBuffer;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.vector.Matrix4f;
import net.lax1dude.eaglercraft.v1_8.vector.Vector3f;
import net.lax1dude.eaglercraft.v1_8.vector.Vector4f;
import net.minecraft.util.MathHelper;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
@ -159,8 +161,8 @@ public class GlStateManager {
static final Matrix4f[][] textureMatrixStack = new Matrix4f[8][8];
static final int[][] textureMatrixStackAccessSerial = new int[8][8];
static int[] textureMatrixAccessSerial = new int[8];
static int[] textureMatrixStackPointer = new int[8];
static final int[] textureMatrixAccessSerial = new int[8];
static final int[] textureMatrixStackPointer = new int[8];
static boolean stateUseExtensionPipeline = false;
@ -821,6 +823,32 @@ public class GlStateManager {
}
}
private static Matrix4f getMatrixIncr() {
Matrix4f mat;
int _i, _j;
switch(stateMatrixMode) {
case GL_MODELVIEW:
_j = modelMatrixStackPointer;
mat = modelMatrixStack[_j];
modelMatrixStackAccessSerial[_j] = ++modelMatrixAccessSerial;
break;
case GL_PROJECTION:
_j = projectionMatrixStackPointer;
mat = projectionMatrixStack[_j];
projectionMatrixStackAccessSerial[_j] = ++projectionMatrixAccessSerial;
break;
case GL_TEXTURE:
_i = activeTexture;
_j = textureMatrixStackPointer[_i];
mat = textureMatrixStack[_i][_j];
textureMatrixStackAccessSerial[_i][_j] = ++textureCoordsAccessSerial[_i];
break;
default:
throw new IllegalStateException();
}
return mat;
}
public static final void getFloat(int pname, float[] params) {
switch(pname) {
case GL_MODELVIEW_MATRIX:
@ -854,24 +882,7 @@ public class GlStateManager {
}
public static final void ortho(double left, double right, double bottom, double top, double zNear, double zFar) {
Matrix4f matrix;
switch(stateMatrixMode) {
case GL_MODELVIEW:
matrix = modelMatrixStack[modelMatrixStackPointer];
modelMatrixStackAccessSerial[modelMatrixStackPointer] = ++modelMatrixAccessSerial;
break;
case GL_PROJECTION:
default:
matrix = projectionMatrixStack[projectionMatrixStackPointer];
projectionMatrixStackAccessSerial[projectionMatrixStackPointer] = ++projectionMatrixAccessSerial;
break;
case GL_TEXTURE:
int ptr = textureMatrixStackPointer[activeTexture];
matrix = textureMatrixStack[activeTexture][ptr];
textureMatrixStackAccessSerial[activeTexture][textureMatrixStackPointer[activeTexture]] =
++textureMatrixAccessSerial[activeTexture];
break;
}
Matrix4f matrix = getMatrixIncr();
paramMatrix.m00 = 2.0f / (float)(right - left);
paramMatrix.m01 = 0.0f;
paramMatrix.m02 = 0.0f;
@ -894,169 +905,200 @@ public class GlStateManager {
private static final Vector3f paramVector = new Vector3f();
private static final float toRad = 0.0174532925f;
public static final void rotate(float angle, float x, float y, float z) {
paramVector.x = x;
paramVector.y = y;
paramVector.z = z;
switch(stateMatrixMode) {
case GL_MODELVIEW:
default:
modelMatrixStack[modelMatrixStackPointer].rotate(angle * toRad, paramVector);
modelMatrixStackAccessSerial[modelMatrixStackPointer] = ++modelMatrixAccessSerial;
break;
case GL_PROJECTION:
projectionMatrixStack[projectionMatrixStackPointer].rotate(angle * toRad, paramVector);
projectionMatrixStackAccessSerial[projectionMatrixStackPointer] = ++projectionMatrixAccessSerial;
break;
case GL_TEXTURE:
int ptr = textureMatrixStackPointer[activeTexture];
textureMatrixStack[activeTexture][ptr].rotate(angle * toRad, paramVector);
textureMatrixStackAccessSerial[activeTexture][textureMatrixStackPointer[activeTexture]] =
++textureMatrixAccessSerial[activeTexture];
break;
Matrix4f matrix = getMatrixIncr();
if(x == 0.0f) {
if(y == 0.0f) {
if(z == 1.0f || z == -1.0f) {
_glRotatefZ(matrix, toRad * angle * z);
return;
}
}else if((y == 1.0f || y == -1.0f) && z == 0.0f) {
_glRotatefY(matrix, toRad * angle * y);
return;
}
}else if((x == 1.0f || x == -1.0f) && y == 0.0f && z == 0.0f) {
_glRotatefX(matrix, toRad * angle * x);
return;
}
_glRotatef(matrix, toRad * angle, x, y, z);
}
public static final void rotateXYZ(float x, float y, float z) {
Matrix4f matrix = getMatrixIncr();
if(x != 0.0f) _glRotatefX(matrix, toRad * x);
if(y != 0.0f) _glRotatefY(matrix, toRad * y);
if(z != 0.0f) _glRotatefZ(matrix, toRad * z);
}
public static final void rotateZYX(float x, float y, float z) {
Matrix4f matrix = getMatrixIncr();
if(z != 0.0f) _glRotatefZ(matrix, toRad * z);
if(y != 0.0f) _glRotatefY(matrix, toRad * y);
if(x != 0.0f) _glRotatefX(matrix, toRad * x);
}
public static final void rotateXYZRad(float x, float y, float z) {
Matrix4f matrix = getMatrixIncr();
if(x != 0.0f) _glRotatefX(matrix, x);
if(y != 0.0f) _glRotatefY(matrix, y);
if(z != 0.0f) _glRotatefZ(matrix, z);
}
public static final void rotateZYXRad(float x, float y, float z) {
Matrix4f matrix = getMatrixIncr();
if(z != 0.0f) _glRotatefZ(matrix, z);
if(y != 0.0f) _glRotatefY(matrix, y);
if(x != 0.0f) _glRotatefX(matrix, x);
}
private static void _glRotatefX(Matrix4f mat, float angle) {
float sin = MathHelper.sin(angle);
float cos = MathHelper.cos(angle);
float lm10 = mat.m10, lm11 = mat.m11, lm12 = mat.m12, lm13 = mat.m13, lm20 = mat.m20, lm21 = mat.m21,
lm22 = mat.m22, lm23 = mat.m23;
mat.m20 = lm10 * -sin + lm20 * cos;
mat.m21 = lm11 * -sin + lm21 * cos;
mat.m22 = lm12 * -sin + lm22 * cos;
mat.m23 = lm13 * -sin + lm23 * cos;
mat.m10 = lm10 * cos + lm20 * sin;
mat.m11 = lm11 * cos + lm21 * sin;
mat.m12 = lm12 * cos + lm22 * sin;
mat.m13 = lm13 * cos + lm23 * sin;
}
private static void _glRotatefY(Matrix4f mat, float angle) {
float sin = MathHelper.sin(angle);
float cos = MathHelper.cos(angle);
float nm00 = mat.m00 * cos + mat.m20 * -sin;
float nm01 = mat.m01 * cos + mat.m21 * -sin;
float nm02 = mat.m02 * cos + mat.m22 * -sin;
float nm03 = mat.m03 * cos + mat.m23 * -sin;
mat.m20 = mat.m00 * sin + mat.m20 * cos;
mat.m21 = mat.m01 * sin + mat.m21 * cos;
mat.m22 = mat.m02 * sin + mat.m22 * cos;
mat.m23 = mat.m03 * sin + mat.m23 * cos;
mat.m00 = nm00;
mat.m01 = nm01;
mat.m02 = nm02;
mat.m03 = nm03;
}
private static void _glRotatefZ(Matrix4f mat, float angle) {
float dirX = MathHelper.sin(angle);
float dirY = MathHelper.cos(angle);
float nm00 = mat.m00 * dirY + mat.m10 * dirX;
float nm01 = mat.m01 * dirY + mat.m11 * dirX;
float nm02 = mat.m02 * dirY + mat.m12 * dirX;
float nm03 = mat.m03 * dirY + mat.m13 * dirX;
mat.m10 = mat.m00 * -dirX + mat.m10 * dirY;
mat.m11 = mat.m01 * -dirX + mat.m11 * dirY;
mat.m12 = mat.m02 * -dirX + mat.m12 * dirY;
mat.m13 = mat.m03 * -dirX + mat.m13 * dirY;
mat.m00 = nm00;
mat.m01 = nm01;
mat.m02 = nm02;
mat.m03 = nm03;
}
private static void _glRotatef(Matrix4f mat, float angle, float x, float y, float z) {
float s = MathHelper.sin(angle);
float c = MathHelper.cos(angle);
float C = 1.0f - c;
float xx = x * x, xy = x * y, xz = x * z;
float yy = y * y, yz = y * z;
float zz = z * z;
float rm00 = xx * C + c;
float rm01 = xy * C + z * s;
float rm02 = xz * C - y * s;
float rm10 = xy * C - z * s;
float rm11 = yy * C + c;
float rm12 = yz * C + x * s;
float rm20 = xz * C + y * s;
float rm21 = yz * C - x * s;
float rm22 = zz * C + c;
float nm00 = mat.m00 * rm00 + mat.m10 * rm01 + mat.m20 * rm02;
float nm01 = mat.m01 * rm00 + mat.m11 * rm01 + mat.m21 * rm02;
float nm02 = mat.m02 * rm00 + mat.m12 * rm01 + mat.m22 * rm02;
float nm03 = mat.m03 * rm00 + mat.m13 * rm01 + mat.m23 * rm02;
float nm10 = mat.m00 * rm10 + mat.m10 * rm11 + mat.m20 * rm12;
float nm11 = mat.m01 * rm10 + mat.m11 * rm11 + mat.m21 * rm12;
float nm12 = mat.m02 * rm10 + mat.m12 * rm11 + mat.m22 * rm12;
float nm13 = mat.m03 * rm10 + mat.m13 * rm11 + mat.m23 * rm12;
mat.m20 = mat.m00 * rm20 + mat.m10 * rm21 + mat.m20 * rm22;
mat.m21 = mat.m01 * rm20 + mat.m11 * rm21 + mat.m21 * rm22;
mat.m22 = mat.m02 * rm20 + mat.m12 * rm21 + mat.m22 * rm22;
mat.m23 = mat.m03 * rm20 + mat.m13 * rm21 + mat.m23 * rm22;
mat.m00 = nm00;
mat.m01 = nm01;
mat.m02 = nm02;
mat.m03 = nm03;
mat.m10 = nm10;
mat.m11 = nm11;
mat.m12 = nm12;
mat.m13 = nm13;
}
public static final void scale(float x, float y, float z) {
paramVector.x = x;
paramVector.y = y;
paramVector.z = z;
switch(stateMatrixMode) {
case GL_MODELVIEW:
default:
modelMatrixStack[modelMatrixStackPointer].scale(paramVector);
modelMatrixStackAccessSerial[modelMatrixStackPointer] = ++modelMatrixAccessSerial;
break;
case GL_PROJECTION:
projectionMatrixStack[projectionMatrixStackPointer].scale(paramVector);
projectionMatrixStackAccessSerial[projectionMatrixStackPointer] = ++projectionMatrixAccessSerial;
break;
case GL_TEXTURE:
int ptr = textureMatrixStackPointer[activeTexture];
textureMatrixStack[activeTexture][ptr].scale(paramVector);
textureMatrixStackAccessSerial[activeTexture][textureMatrixStackPointer[activeTexture]] =
++textureMatrixAccessSerial[activeTexture];
break;
}
Matrix4f matrix = getMatrixIncr();
matrix.m00 *= x;
matrix.m01 *= x;
matrix.m02 *= x;
matrix.m03 *= x;
matrix.m10 *= y;
matrix.m11 *= y;
matrix.m12 *= y;
matrix.m13 *= y;
matrix.m20 *= z;
matrix.m21 *= z;
matrix.m22 *= z;
matrix.m23 *= z;
}
public static final void scale(double x, double y, double z) {
paramVector.x = (float)x;
paramVector.y = (float)y;
paramVector.z = (float)z;
switch(stateMatrixMode) {
case GL_MODELVIEW:
default:
modelMatrixStack[modelMatrixStackPointer].scale(paramVector);
modelMatrixStackAccessSerial[modelMatrixStackPointer] = ++modelMatrixAccessSerial;
break;
case GL_PROJECTION:
projectionMatrixStack[projectionMatrixStackPointer].scale(paramVector);
projectionMatrixStackAccessSerial[projectionMatrixStackPointer] = ++projectionMatrixAccessSerial;
break;
case GL_TEXTURE:
int ptr = textureMatrixStackPointer[activeTexture];
textureMatrixStack[activeTexture][ptr].scale(paramVector);
textureMatrixStackAccessSerial[activeTexture][textureMatrixStackPointer[activeTexture]] =
++textureMatrixAccessSerial[activeTexture];
break;
}
Matrix4f matrix = getMatrixIncr();
matrix.m00 *= x;
matrix.m01 *= x;
matrix.m02 *= x;
matrix.m03 *= x;
matrix.m10 *= y;
matrix.m11 *= y;
matrix.m12 *= y;
matrix.m13 *= y;
matrix.m20 *= z;
matrix.m21 *= z;
matrix.m22 *= z;
matrix.m23 *= z;
}
public static final void translate(float x, float y, float z) {
paramVector.x = x;
paramVector.y = y;
paramVector.z = z;
switch(stateMatrixMode) {
case GL_MODELVIEW:
default:
modelMatrixStack[modelMatrixStackPointer].translate(paramVector);
modelMatrixStackAccessSerial[modelMatrixStackPointer] = ++modelMatrixAccessSerial;
break;
case GL_PROJECTION:
projectionMatrixStack[projectionMatrixStackPointer].translate(paramVector);
projectionMatrixStackAccessSerial[projectionMatrixStackPointer] = ++projectionMatrixAccessSerial;
break;
case GL_TEXTURE:
int ptr = textureMatrixStackPointer[activeTexture];
textureMatrixStack[activeTexture][ptr].translate(paramVector);
textureMatrixStackAccessSerial[activeTexture][textureMatrixStackPointer[activeTexture]] =
++textureMatrixAccessSerial[activeTexture];
break;
}
Matrix4f matrix = getMatrixIncr();
matrix.m30 = matrix.m00 * x + matrix.m10 * y + matrix.m20 * z + matrix.m30;
matrix.m31 = matrix.m01 * x + matrix.m11 * y + matrix.m21 * z + matrix.m31;
matrix.m32 = matrix.m02 * x + matrix.m12 * y + matrix.m22 * z + matrix.m32;
matrix.m33 = matrix.m03 * x + matrix.m13 * y + matrix.m23 * z + matrix.m33;
}
public static final void translate(double x, double y, double z) {
paramVector.x = (float)x;
paramVector.y = (float)y;
paramVector.z = (float)z;
switch(stateMatrixMode) {
case GL_MODELVIEW:
default:
modelMatrixStack[modelMatrixStackPointer].translate(paramVector);
modelMatrixStackAccessSerial[modelMatrixStackPointer] = ++modelMatrixAccessSerial;
break;
case GL_PROJECTION:
projectionMatrixStack[projectionMatrixStackPointer].translate(paramVector);
projectionMatrixStackAccessSerial[projectionMatrixStackPointer] = ++projectionMatrixAccessSerial;
break;
case GL_TEXTURE:
int ptr = textureMatrixStackPointer[activeTexture];
textureMatrixStack[activeTexture][ptr].translate(paramVector);
textureMatrixStackAccessSerial[activeTexture][textureMatrixStackPointer[activeTexture]] =
++textureMatrixAccessSerial[activeTexture];
break;
}
float _x = (float)x;
float _y = (float)y;
float _z = (float)z;
Matrix4f matrix = getMatrixIncr();
matrix.m30 = matrix.m00 * _x + matrix.m10 * _y + matrix.m20 * _z + matrix.m30;
matrix.m31 = matrix.m01 * _x + matrix.m11 * _y + matrix.m21 * _z + matrix.m31;
matrix.m32 = matrix.m02 * _x + matrix.m12 * _y + matrix.m22 * _z + matrix.m32;
matrix.m33 = matrix.m03 * _x + matrix.m13 * _y + matrix.m23 * _z + matrix.m33;
}
private static final Matrix4f paramMatrix = new Matrix4f();
public static final void multMatrix(float[] matrix) {
Matrix4f modeMatrix;
switch(stateMatrixMode) {
case GL_MODELVIEW:
default:
modeMatrix = modelMatrixStack[modelMatrixStackPointer];
modelMatrixStackAccessSerial[modelMatrixStackPointer] = ++modelMatrixAccessSerial;
break;
case GL_PROJECTION:
modeMatrix = projectionMatrixStack[projectionMatrixStackPointer];
projectionMatrixStackAccessSerial[projectionMatrixStackPointer] = ++projectionMatrixAccessSerial;
break;
case GL_TEXTURE:
int ptr = textureMatrixStackPointer[activeTexture];
modeMatrix = textureMatrixStack[activeTexture][ptr];
textureMatrixStackAccessSerial[activeTexture][textureMatrixStackPointer[activeTexture]] =
++textureMatrixAccessSerial[activeTexture];
break;
}
paramMatrix.load(matrix);
Matrix4f.mul(modeMatrix, paramMatrix, modeMatrix);
Matrix4f mat = getMatrixIncr();
Matrix4f.mul(mat, paramMatrix, mat);
}
public static final void multMatrix(Matrix4f matrix) {
Matrix4f modeMatrix;
switch(stateMatrixMode) {
case GL_MODELVIEW:
default:
modeMatrix = modelMatrixStack[modelMatrixStackPointer];
modelMatrixStackAccessSerial[modelMatrixStackPointer] = ++modelMatrixAccessSerial;
break;
case GL_PROJECTION:
modeMatrix = projectionMatrixStack[projectionMatrixStackPointer];
projectionMatrixStackAccessSerial[projectionMatrixStackPointer] = ++projectionMatrixAccessSerial;
break;
case GL_TEXTURE:
int ptr = textureMatrixStackPointer[activeTexture];
modeMatrix = textureMatrixStack[activeTexture][ptr];
textureMatrixStackAccessSerial[activeTexture][textureMatrixStackPointer[activeTexture]] =
++textureMatrixAccessSerial[activeTexture];
break;
}
Matrix4f.mul(modeMatrix, matrix, modeMatrix);
Matrix4f mat = getMatrixIncr();
Matrix4f.mul(mat, matrix, mat);
}
public static final void color(float colorRed, float colorGreen, float colorBlue, float colorAlpha) {
@ -1088,24 +1130,7 @@ public class GlStateManager {
}
public static final void gluPerspective(float fovy, float aspect, float zNear, float zFar) {
Matrix4f matrix;
switch(stateMatrixMode) {
case GL_MODELVIEW:
matrix = modelMatrixStack[modelMatrixStackPointer];
modelMatrixStackAccessSerial[modelMatrixStackPointer] = ++modelMatrixAccessSerial;
break;
case GL_PROJECTION:
default:
matrix = projectionMatrixStack[projectionMatrixStackPointer];
projectionMatrixStackAccessSerial[projectionMatrixStackPointer] = ++projectionMatrixAccessSerial;
break;
case GL_TEXTURE:
int ptr = textureMatrixStackPointer[activeTexture];
matrix = textureMatrixStack[activeTexture][ptr];
textureMatrixStackAccessSerial[activeTexture][textureMatrixStackPointer[activeTexture]] =
++textureMatrixAccessSerial[activeTexture];
break;
}
Matrix4f matrix = getMatrixIncr();
float cotangent = (float) Math.cos(fovy * toRad * 0.5f) / (float) Math.sin(fovy * toRad * 0.5f);
paramMatrix.m00 = cotangent / aspect;
paramMatrix.m01 = 0.0f;
@ -1127,24 +1152,7 @@ public class GlStateManager {
}
public static final void gluLookAt(Vector3f eye, Vector3f center, Vector3f up) {
Matrix4f matrix;
switch(stateMatrixMode) {
case GL_MODELVIEW:
matrix = modelMatrixStack[modelMatrixStackPointer];
modelMatrixStackAccessSerial[modelMatrixStackPointer] = ++modelMatrixAccessSerial;
break;
case GL_PROJECTION:
default:
matrix = projectionMatrixStack[projectionMatrixStackPointer];
projectionMatrixStackAccessSerial[projectionMatrixStackPointer] = ++projectionMatrixAccessSerial;
break;
case GL_TEXTURE:
int ptr = textureMatrixStackPointer[activeTexture];
matrix = textureMatrixStack[activeTexture][ptr];
textureMatrixStackAccessSerial[activeTexture][textureMatrixStackPointer[activeTexture]] =
++textureMatrixAccessSerial[activeTexture];
break;
}
Matrix4f matrix = getMatrixIncr();
float x = center.x - eye.x;
float y = center.y - eye.y;
float z = center.z - eye.z;
@ -1262,4 +1270,18 @@ public class GlStateManager {
public static void recompileShaders() {
FixedFunctionPipeline.flushCache();
}
public static int getBoundTexture() {
return boundTexture[activeTexture];
}
static void setTextureCachedSize(int target, int w, int h) {
if(target == GL_TEXTURE_2D) {
ITextureGL tex = EaglercraftGPU.getNativeTexture(boundTexture[activeTexture]);
if(tex != null) {
tex.setCacheSize(w, h);
}
}
}
}

View File

@ -1,6 +1,9 @@
package net.lax1dude.eaglercraft.v1_8.opengl;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import java.util.List;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
@ -10,10 +13,11 @@ import net.lax1dude.eaglercraft.v1_8.internal.IUniformGL;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.FloatBuffer;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.opengl.VSHInputLayoutParser.ShaderInput;
import net.lax1dude.eaglercraft.v1_8.vector.Matrix3f;
/**
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
* Copyright (c) 2022-2025 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -39,7 +43,8 @@ public class SpriteLevelMixer {
private static IUniformGL u_textureLod1f = null;
private static IUniformGL u_blendFactor4f = null;
private static IUniformGL u_blendBias4f = null;
private static IUniformGL u_matrixTransform = null;
private static IUniformGL u_srcCoords4f = null;
private static IUniformGL u_dstCoords4f = null;
private static FloatBuffer matrixCopyBuffer = null;
@ -55,12 +60,15 @@ public class SpriteLevelMixer {
private static float biasColorB = 0.0f;
private static float biasColorA = 0.0f;
private static boolean matrixChanged = true;
private static final Matrix3f transformMatrix = new Matrix3f();
private static float srcViewW = 100.0f;
private static float srcViewH = 100.0f;
private static float dstViewW = 50.0f;
private static float dstViewH = 50.0f;
private static final Matrix3f identityMatrix = new Matrix3f();
static void initialize() {
static void initialize(IShaderGL vertexShader, List<ShaderInput> vshSourceLayout) {
String fragmentSource = EagRuntime.getRequiredResourceString(fragmentShaderPath);
IShaderGL frag = _wglCreateShader(GL_FRAGMENT_SHADER);
@ -82,16 +90,16 @@ public class SpriteLevelMixer {
shaderProgram = _wglCreateProgram();
_wglAttachShader(shaderProgram, DrawUtils.vshLocal);
_wglAttachShader(shaderProgram, vertexShader);
_wglAttachShader(shaderProgram, frag);
if(EaglercraftGPU.checkOpenGLESVersion() == 200) {
VSHInputLayoutParser.applyLayout(shaderProgram, DrawUtils.vshLocalLayout);
VSHInputLayoutParser.applyLayout(shaderProgram, vshSourceLayout);
}
_wglLinkProgram(shaderProgram);
_wglDetachShader(shaderProgram, DrawUtils.vshLocal);
_wglDetachShader(shaderProgram, vertexShader);
_wglDetachShader(shaderProgram, frag);
_wglDeleteShader(frag);
@ -115,7 +123,8 @@ public class SpriteLevelMixer {
u_textureLod1f = _wglGetUniformLocation(shaderProgram, "u_textureLod1f");
u_blendFactor4f = _wglGetUniformLocation(shaderProgram, "u_blendFactor4f");
u_blendBias4f = _wglGetUniformLocation(shaderProgram, "u_blendBias4f");
u_matrixTransform = _wglGetUniformLocation(shaderProgram, "u_matrixTransform");
u_srcCoords4f = _wglGetUniformLocation(shaderProgram, "u_srcCoords4f");
u_dstCoords4f = _wglGetUniformLocation(shaderProgram, "u_dstCoords4f");
_wglUniform1i(_wglGetUniformLocation(shaderProgram, "u_inputTexture"), 0);
@ -141,25 +150,31 @@ public class SpriteLevelMixer {
}
}
public static void setIdentityMatrix() {
setMatrix3f(identityMatrix);
public static void srcSize(int w, int h) {
srcViewW = w;
srcViewH = h;
}
public static void setMatrix3f(Matrix3f matrix) {
if(!matrix.equals(transformMatrix)) {
matrixChanged = true;
transformMatrix.load(matrix);
}
public static void dstSize(int w, int h) {
dstViewW = w * 0.5f;
dstViewH = h * 0.5f;
}
public static void drawSprite(float level) {
public static void srcDstSize(int w, int h) {
srcViewW = w;
srcViewH = h;
dstViewW = w * 0.5f;
dstViewH = h * 0.5f;
}
public static void drawSprite(int lvl, int srcX, int srcY, int srcW, int srcH, int dstX, int dstY, int dstW, int dstH) {
EaglercraftGPU.bindGLShaderProgram(shaderProgram);
if(EaglercraftGPU.checkTextureLODCapable()) {
_wglUniform1f(u_textureLod1f, level);
_wglUniform1f(u_textureLod1f, lvl);
}else {
if(level != 0.0f) {
LOGGER.error("Tried to copy from mipmap level {}, but this GPU does not support textureLod!", level);
if(lvl != 0) {
LOGGER.error("Tried to copy from mipmap level {}, but this GPU does not support textureLod!", lvl);
}
_wglUniform1f(u_textureLod1f, 0.0f);
}
@ -174,13 +189,9 @@ public class SpriteLevelMixer {
biasColorChanged = false;
}
if(matrixChanged) {
matrixCopyBuffer.clear();
transformMatrix.store(matrixCopyBuffer);
matrixCopyBuffer.flip();
_wglUniformMatrix3fv(u_matrixTransform, false, matrixCopyBuffer);
matrixChanged = false;
}
_wglUniform4f(u_srcCoords4f, (float)srcX / srcViewW, (float)srcY / srcViewH, (float)srcW / srcViewW, (float)srcH / srcViewH);
_wglUniform4f(u_dstCoords4f, (float) dstX / dstViewW - 1.0f, (float) dstY / dstViewH - 1.0f,
(float) dstW / dstViewW, (float) dstH / dstViewH);
DrawUtils.drawStandardQuad2D();
}
@ -197,7 +208,8 @@ public class SpriteLevelMixer {
u_textureLod1f = null;
u_blendFactor4f = null;
u_blendBias4f = null;
u_matrixTransform = null;
u_srcCoords4f = null;
u_dstCoords4f = null;
}
}

View File

@ -113,6 +113,8 @@ public class TextureCopyUtil {
if(EaglercraftGPU.checkOpenGLESVersion() == 200) {
vshSourceLayout = VSHInputLayoutParser.getShaderInputs(vshSource);
}
SpriteLevelMixer.initialize(vshShader, vshSourceLayout);
}
private static TextureCopyShader compileShader(boolean align, boolean depth) {
@ -283,18 +285,22 @@ public class TextureCopyUtil {
DrawUtils.drawStandardQuad2D();
}
@Deprecated
public static void blitTextureUsingViewports(int srcX, int srcY, int dstX, int dstY, int w, int h) {
blitTextureUsingViewports(0, srcX, srcY, w, h, dstX, dstY, w, h);
}
@Deprecated
public static void blitTextureUsingViewports(int lvl, int srcX, int srcY, int dstX, int dstY, int w, int h) {
blitTextureUsingViewports(lvl, srcX, srcY, w, h, dstX, dstY, w, h);
}
@Deprecated
public static void blitTextureUsingViewports(int srcX, int srcY, int srcW, int srcH, int dstX, int dstY, int dstW, int dstH) {
blitTextureUsingViewports(0, srcX, srcY, srcW, srcH, dstX, dstY, dstW, dstH);
}
@Deprecated
public static void blitTextureUsingViewports(int lvl, int srcX, int srcY, int srcW, int srcH, int dstX, int dstY, int dstW, int dstH) {
TextureCopyShader shaderObj = getShaderObj(isAligned, false);
EaglercraftGPU.bindGLShaderProgram(shaderObj.shaderProgram);
@ -376,18 +382,22 @@ public class TextureCopyUtil {
DrawUtils.drawStandardQuad2D();
}
@Deprecated
public static void blitTextureDepthUsingViewports(int srcX, int srcY, int dstX, int dstY, int w, int h) {
blitTextureDepthUsingViewports(0, srcX, srcY, w, h, dstX, dstY, w, h);
}
@Deprecated
public static void blitTextureDepthUsingViewports(int lvl, int srcX, int srcY, int dstX, int dstY, int w, int h) {
blitTextureDepthUsingViewports(lvl, srcX, srcY, w, h, dstX, dstY, w, h);
}
@Deprecated
public static void blitTextureDepthUsingViewports(int srcX, int srcY, int srcW, int srcH, int dstX, int dstY, int dstW, int dstH) {
blitTextureDepthUsingViewports(0, srcX, srcY, srcW, srcH, dstX, dstY, dstW, dstH);
}
@Deprecated
public static void blitTextureDepthUsingViewports(int lvl, int srcX, int srcY, int srcW, int srcH, int dstX, int dstY, int dstW, int dstH) {
TextureCopyShader shaderObj = getShaderObj(isAligned, true);
EaglercraftGPU.bindGLShaderProgram(shaderObj.shaderProgram);
@ -431,5 +441,6 @@ public class TextureCopyUtil {
textureBlitDepthAligned.destroy();
textureBlitDepthAligned = null;
}
SpriteLevelMixer.destroy();
}
}

View File

@ -12,8 +12,12 @@ import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.vector.Vector3f;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumWorldBlockLayer;
import net.minecraft.util.MathHelper;
import net.optifine.render.RenderEnv;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
@ -50,6 +54,9 @@ public class WorldRenderer {
private boolean hasBeenFreed = false;
private EnumWorldBlockLayer blockLayer = null;
public RenderEnv renderEnv = null;
public WorldRenderer(int bufferSizeIn) {
this.byteBuffer = GLAllocation.createDirectByteBuffer(bufferSizeIn << 2);
this.intBuffer = this.byteBuffer.asIntBuffer();
@ -555,6 +562,20 @@ public class WorldRenderer {
}
public RenderEnv getRenderEnv(IBlockState p_getRenderEnv_1_, BlockPos p_getRenderEnv_2_) {
if (this.renderEnv == null) {
this.renderEnv = new RenderEnv(p_getRenderEnv_1_, p_getRenderEnv_2_);
return this.renderEnv;
} else {
this.renderEnv.reset(p_getRenderEnv_1_, p_getRenderEnv_2_);
return this.renderEnv;
}
}
public EnumWorldBlockLayer getBlockLayer() {
return this.blockLayer;
}
public class State {
private final IntBuffer stateRawBuffer;
private final VertexFormat stateVertexFormat;

View File

@ -2440,6 +2440,15 @@ public class EaglerDeferredPipeline {
GlStateManager.setActiveTexture(GL_TEXTURE10);
GlStateManager.bindTexture(skyIrradianceTexture);
GlStateManager.setActiveTexture(GL_TEXTURE0);
GlStateManager.disableDepth();
GlStateManager.disableBlend();
GlStateManager.depthMask(false);
GlStateManager.bindTexture(envMapSkyTexture);
GlStateManager.viewport(0, 0, 128, 256);
TextureCopyUtil.blitTexture();
GlStateManager.depthMask(true);
GlStateManager.enableBlend();
GlStateManager.enableDepth();
DeferredStateManager.checkGLError("Post: beginDrawEnvMap()");
}
@ -2470,7 +2479,7 @@ public class EaglerDeferredPipeline {
public void beginDrawEnvMapTranslucent() {
DeferredStateManager.checkGLError("Pre: beginDrawEnvMapTranslucent()");
GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE);
GlStateManager.tryBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
bindEnvMapBlockTexture();
DeferredStateManager.checkGLError("Post: beginDrawEnvMapTranslucent()");
}

View File

@ -8,7 +8,6 @@ import com.carrotsearch.hppc.cursors.IntCursor;
import com.google.common.collect.Lists;
import net.lax1dude.eaglercraft.v1_8.HString;
import net.lax1dude.eaglercraft.v1_8.internal.IFramebufferGL;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.minecraft.EaglerTextureAtlasSprite;
@ -219,7 +218,9 @@ public class EaglerTextureAtlasSpritePBR extends EaglerTextureAtlasSprite {
}
}
public void updateAnimationPBR(IFramebufferGL[] copyColorFramebuffer, IFramebufferGL[] copyMaterialFramebuffer, int materialTexOffset) {
protected IAnimCopyFunction currentAnimUpdaterPBR = null;
public void updateAnimationPBR() {
if(animationCachePBR[0] == null || (!dontAnimateNormals && animationCachePBR[1] == null)
|| (!dontAnimateMaterial && animationCachePBR[2] == null)) {
throw new IllegalStateException("Animation cache for '" + this.iconName + "' was never baked!");
@ -233,9 +234,28 @@ public class EaglerTextureAtlasSpritePBR extends EaglerTextureAtlasSprite {
this.tickCounter = 0;
int k = this.animationMetadata.getFrameIndex(this.frameCounter);
if (i != k && k >= 0 && k < this.frameTextureDataPBR[0].size()) {
animationCachePBR[0].copyFrameLevelsToTex2D(k, this.originX, this.originY, this.width, this.height, copyColorFramebuffer);
if(!dontAnimateNormals) animationCachePBR[1].copyFrameLevelsToTex2D(k, this.originX, this.originY, this.width, this.height, copyMaterialFramebuffer);
if(!dontAnimateMaterial) animationCachePBR[2].copyFrameLevelsToTex2D(k, this.originX, this.originY + materialTexOffset, this.width, this.height, copyMaterialFramebuffer);
currentAnimUpdater = (mapWidth, mapHeight, mapLevel) -> {
animationCachePBR[0].copyFrameToTex2D(k, mapLevel, this.originX >> mapLevel,
this.originY >> mapLevel, this.width >> mapLevel, this.height >> mapLevel, mapWidth,
mapHeight);
};
if(!dontAnimateNormals || !dontAnimateMaterial) {
currentAnimUpdaterPBR = (mapWidth, mapHeight, mapLevel) -> {
if (!dontAnimateNormals)
animationCachePBR[1].copyFrameToTex2D(k, mapLevel, this.originX >> mapLevel,
this.originY >> mapLevel, this.width >> mapLevel, this.height >> mapLevel, mapWidth,
mapHeight);
if (!dontAnimateMaterial)
animationCachePBR[2].copyFrameToTex2D(k, mapLevel, this.originX >> mapLevel,
(this.originY >> mapLevel) + (mapHeight >> 1), this.width >> mapLevel,
this.height >> mapLevel, mapWidth, mapHeight);
};
}else {
currentAnimUpdaterPBR = null;
}
}else {
currentAnimUpdater = null;
currentAnimUpdaterPBR = null;
}
} else if (this.animationMetadata.isInterpolate()) {
float f = 1.0f - (float) this.tickCounter / (float) this.animationMetadata.getFrameTimeSingle(this.frameCounter);
@ -244,9 +264,43 @@ public class EaglerTextureAtlasSpritePBR extends EaglerTextureAtlasSprite {
: this.animationMetadata.getFrameCount();
int k = this.animationMetadata.getFrameIndex((this.frameCounter + 1) % j);
if (i != k && k >= 0 && k < this.frameTextureDataPBR[0].size()) {
animationCachePBR[0].copyInterpolatedFrameLevelsToTex2D(i, k, f, this.originX, this.originY, this.width, this.height, copyColorFramebuffer);
if(!dontAnimateNormals) animationCachePBR[1].copyInterpolatedFrameLevelsToTex2D(i, k, f, this.originX, this.originY, this.width, this.height, copyMaterialFramebuffer);
if(!dontAnimateMaterial) animationCachePBR[2].copyInterpolatedFrameLevelsToTex2D(i, k, f, this.originX, this.originY + materialTexOffset, this.width, this.height, copyMaterialFramebuffer);
currentAnimUpdater = (mapWidth, mapHeight, mapLevel) -> {
animationCachePBR[0].copyInterpolatedFrameToTex2D(i, k, f, mapLevel, this.originX >> mapLevel,
this.originY >> mapLevel, this.width >> mapLevel, this.height >> mapLevel, mapWidth,
mapHeight);
};
if(!dontAnimateNormals || !dontAnimateMaterial) {
currentAnimUpdaterPBR = (mapWidth, mapHeight, mapLevel) -> {
if (!dontAnimateNormals)
animationCachePBR[1].copyInterpolatedFrameToTex2D(i, k, f, mapLevel,
this.originX >> mapLevel, this.originY >> mapLevel, this.width >> mapLevel,
this.height >> mapLevel, mapWidth, mapHeight);
if (!dontAnimateMaterial)
animationCachePBR[2].copyInterpolatedFrameToTex2D(i, k, f, mapLevel,
this.originX >> mapLevel, (this.originY >> mapLevel) + (mapHeight >> 1),
this.width >> mapLevel, this.height >> mapLevel, mapWidth, mapHeight);
};
}else {
currentAnimUpdaterPBR = null;
}
}else {
currentAnimUpdater = null;
currentAnimUpdaterPBR = null;
}
}else {
currentAnimUpdater = null;
currentAnimUpdaterPBR = null;
}
}
public void copyAnimationFramePBR(int pass, int mapWidth, int mapHeight, int mapLevel) {
if(pass == 0) {
if(currentAnimUpdater != null) {
currentAnimUpdater.updateAnimation(mapWidth, mapHeight, mapLevel);
}
}else {
if(currentAnimUpdaterPBR != null) {
currentAnimUpdaterPBR.updateAnimation(mapWidth, mapHeight, mapLevel);
}
}
}
@ -279,7 +333,7 @@ public class EaglerTextureAtlasSpritePBR extends EaglerTextureAtlasSprite {
}
}
public void updateAnimation(IFramebufferGL[] fb) {
public void updateAnimation() {
Throwable t = new UnsupportedOperationException("Cannot call regular updateAnimation in PBR mode, use updateAnimationPBR");
try {
throw t;
@ -288,6 +342,15 @@ public class EaglerTextureAtlasSpritePBR extends EaglerTextureAtlasSprite {
}
}
public void copyAnimationFrame(int mapWidth, int mapHeight, int mapLevel) {
Throwable t = new UnsupportedOperationException("Cannot call regular copyAnimationFrame in PBR mode, use updateAnimationPBR");
try {
throw t;
}catch(Throwable tt) {
logger.error(t);
}
}
protected void resetSprite() {
this.animationMetadata = null;
this.setFramesTextureDataPBR(new List[] { Lists.newArrayList(), Lists.newArrayList(), Lists.newArrayList() });

View File

@ -27,7 +27,7 @@ import net.minecraft.util.ResourceLocation;
*/
public class PBRTextureMapUtils {
public static final ImageData defaultNormalsTexture = new ImageData(1, 1, new int[] { 0 }, true);
public static final ImageData defaultNormalsTexture = new ImageData(1, 1, new int[] { 0xFFFF7F7F }, true);
public static final PBRMaterialConstants blockMaterialConstants = new PBRMaterialConstants(new ResourceLocation("eagler:glsl/deferred/material_block_constants.csv"));
@ -125,13 +125,17 @@ public class PBRTextureMapUtils {
}
}
public static ImageData generateMaterialTextureFor(String iconName) {
public static ImageData generateMaterialTextureFor(String iconName, String iconName2) {
if(iconName.startsWith("minecraft:")) {
iconName = iconName.substring(10);
}
Integer in = blockMaterialConstants.spriteNameToMaterialConstants.get(iconName);
if(in == null) {
return new ImageData(1, 1, new int[] { blockMaterialConstants.defaultMaterial }, true);
if(iconName2 != null) {
return generateMaterialTextureFor(iconName2, null);
}else {
return new ImageData(1, 1, new int[] { blockMaterialConstants.defaultMaterial }, true);
}
}else {
return new ImageData(1, 1, new int[] { in.intValue() }, true);
}
@ -150,8 +154,8 @@ public class PBRTextureMapUtils {
ret[i] = new int[len];
int x, y, s1, s2, s3, s4, c1, c2, c3, c4;
for(int j = 0; j < len; ++j) {
x = (j % len) << 1;
y = (j / len) << 1;
x = (j % lvlW) << 1;
y = (j / lvlW) << 1;
s1 = ret[i - 1][x + y * lvl2W];
s2 = ret[i - 1][x + y * lvl2W + 1];
s3 = ret[i - 1][x + y * lvl2W + lvl2W];

View File

@ -27,7 +27,7 @@ public class TextureClockPBRImpl extends EaglerTextureAtlasSpritePBR {
super(spriteName);
}
public void updateAnimationPBR(IFramebufferGL[] copyColorFramebuffer, IFramebufferGL[] copyMaterialFramebuffer, int materialTexOffset) {
public void updateAnimationPBR() {
if (!this.frameTextureDataPBR[0].isEmpty()) {
Minecraft minecraft = Minecraft.getMinecraft();
double d0 = 0.0;
@ -59,16 +59,32 @@ public class TextureClockPBRImpl extends EaglerTextureAtlasSpritePBR {
if (i != this.frameCounter) {
this.frameCounter = i;
animationCachePBR[0].copyFrameLevelsToTex2D(this.frameCounter, this.originX, this.originY, this.width,
this.height, copyColorFramebuffer);
if (!dontAnimateNormals)
animationCachePBR[1].copyFrameLevelsToTex2D(this.frameCounter, this.originX, this.originY,
this.width, this.height, copyMaterialFramebuffer);
if (!dontAnimateMaterial)
animationCachePBR[2].copyFrameLevelsToTex2D(this.frameCounter, this.originX,
this.originY + materialTexOffset, this.width, this.height, copyMaterialFramebuffer);
currentAnimUpdater = (mapWidth, mapHeight, mapLevel) -> {
animationCachePBR[0].copyFrameToTex2D(this.frameCounter, mapLevel, this.originX >> mapLevel,
this.originY >> mapLevel, this.width >> mapLevel, this.height >> mapLevel, mapWidth,
mapHeight);
};
if(!dontAnimateNormals || !dontAnimateMaterial) {
currentAnimUpdaterPBR = (mapWidth, mapHeight, mapLevel) -> {
if (!dontAnimateNormals)
animationCachePBR[1].copyFrameToTex2D(this.frameCounter, mapLevel, this.originX,
this.originY, this.width, this.height, mapWidth, mapHeight);
if (!dontAnimateMaterial)
animationCachePBR[2].copyFrameToTex2D(this.frameCounter, mapLevel, this.originX >> mapLevel,
(this.originY >> mapLevel) + (mapHeight >> 1), this.width >> mapLevel,
this.height >> mapLevel, mapWidth, mapHeight);
};
}else {
currentAnimUpdaterPBR = null;
}
}else {
currentAnimUpdater = null;
currentAnimUpdaterPBR = null;
}
}else {
currentAnimUpdater = null;
currentAnimUpdaterPBR = null;
}
}

View File

@ -29,18 +29,17 @@ public class TextureCompassPBRImpl extends EaglerTextureAtlasSpritePBR {
super(spriteName);
}
public void updateAnimationPBR(IFramebufferGL[] copyColorFramebuffer, IFramebufferGL[] copyMaterialFramebuffer, int materialOffset) {
public void updateAnimationPBR() {
Minecraft minecraft = Minecraft.getMinecraft();
if (minecraft.theWorld != null && minecraft.thePlayer != null) {
this.updateCompassPBR(minecraft.theWorld, minecraft.thePlayer.posX, minecraft.thePlayer.posZ,
(double) minecraft.thePlayer.rotationYaw, false, copyColorFramebuffer, copyMaterialFramebuffer, materialOffset);
(double) minecraft.thePlayer.rotationYaw, false);
} else {
this.updateCompassPBR((World) null, 0.0, 0.0, 0.0, true, copyColorFramebuffer, copyMaterialFramebuffer, materialOffset);
this.updateCompassPBR((World) null, 0.0, 0.0, 0.0, true);
}
}
public void updateCompassPBR(World worldIn, double playerX, double playerY, double playerZ, boolean noWorld,
IFramebufferGL[] copyColorFramebuffer, IFramebufferGL[] copyMaterialFramebuffer, int materialOffset) {
public void updateCompassPBR(World worldIn, double playerX, double playerY, double playerZ, boolean noWorld) {
if (!this.frameTextureDataPBR[0].isEmpty()) {
double d0 = 0.0;
if (worldIn != null && !noWorld) {
@ -76,15 +75,33 @@ public class TextureCompassPBRImpl extends EaglerTextureAtlasSpritePBR {
if (i != this.frameCounter) {
this.frameCounter = i;
animationCachePBR[0].copyFrameLevelsToTex2D(this.frameCounter, this.originX, this.originY, this.width,
this.height, copyColorFramebuffer);
if (!dontAnimateNormals)
animationCachePBR[1].copyFrameLevelsToTex2D(this.frameCounter, this.originX, this.originY,
this.width, this.height, copyMaterialFramebuffer);
if (!dontAnimateMaterial)
animationCachePBR[2].copyFrameLevelsToTex2D(this.frameCounter, this.originX,
this.originY + materialOffset, this.width, this.height, copyMaterialFramebuffer);
currentAnimUpdater = (mapWidth, mapHeight, mapLevel) -> {
animationCachePBR[0].copyFrameToTex2D(this.frameCounter, mapLevel, this.originX >> mapLevel,
this.originY >> mapLevel, this.width >> mapLevel, this.height >> mapLevel, mapWidth,
mapHeight);
};
if(!dontAnimateNormals || !dontAnimateMaterial) {
currentAnimUpdaterPBR = (mapWidth, mapHeight, mapLevel) -> {
if (!dontAnimateNormals)
animationCachePBR[1].copyFrameToTex2D(this.frameCounter, mapLevel, this.originX >> mapLevel,
this.originY >> mapLevel, this.width >> mapLevel, this.height >> mapLevel, mapWidth,
mapHeight);
if (!dontAnimateMaterial)
animationCachePBR[2].copyFrameToTex2D(this.frameCounter, mapLevel, this.originX >> mapLevel,
(this.originY >> mapLevel) + (mapHeight >> 1), this.width >> mapLevel,
this.height >> mapLevel, mapWidth, mapHeight);
};
}else {
currentAnimUpdaterPBR = null;
}
}else {
currentAnimUpdater = null;
currentAnimUpdaterPBR = null;
}
}else {
currentAnimUpdater = null;
currentAnimUpdaterPBR = null;
}
}

View File

@ -88,6 +88,7 @@ public class EaglerChunkLoader extends AnvilChunkLoader {
@Override
public void saveChunk(World var1, Chunk var2) throws IOException {
var1.alfheim$getLightingEngine().processLightUpdates();
NBTTagCompound chunkData = new NBTTagCompound();
this.writeChunkToNBT(var2, var1, chunkData);
NBTTagCompound fileData = new NBTTagCompound();

View File

@ -0,0 +1,243 @@
package net.optifine;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Properties;
import net.lax1dude.eaglercraft.v1_8.minecraft.EaglerTextureAtlasSprite;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDirt;
import net.minecraft.block.BlockGrass;
import net.minecraft.block.BlockMycelium;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.resources.model.IBakedModel;
import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.IBlockAccess;
import net.optifine.model.BlockModelUtils;
import net.optifine.util.PropertiesOrdered;
public class BetterGrass {
private static boolean betterGrass = true;
private static boolean betterMycelium = true;
private static boolean betterPodzol = true;
private static boolean betterGrassSnow = true;
private static boolean betterMyceliumSnow = true;
private static boolean betterPodzolSnow = true;
private static boolean grassMultilayer = false;
private static EaglerTextureAtlasSprite spriteGrass = null;
private static EaglerTextureAtlasSprite spriteGrassSide = null;
private static EaglerTextureAtlasSprite spriteMycelium = null;
private static EaglerTextureAtlasSprite spritePodzol = null;
private static EaglerTextureAtlasSprite spriteSnow = null;
private static boolean spritesLoaded = false;
private static IBakedModel modelCubeGrass = null;
private static IBakedModel modelCubeMycelium = null;
private static IBakedModel modelCubePodzol = null;
private static IBakedModel modelCubeSnow = null;
private static boolean modelsLoaded = false;
private static final String TEXTURE_GRASS_DEFAULT = "blocks/grass_top";
private static final String TEXTURE_GRASS_SIDE_DEFAULT = "blocks/grass_side";
private static final String TEXTURE_MYCELIUM_DEFAULT = "blocks/mycelium_top";
private static final String TEXTURE_PODZOL_DEFAULT = "blocks/dirt_podzol_top";
private static final String TEXTURE_SNOW_DEFAULT = "blocks/snow";
public static void updateIcons(TextureMap textureMap) {
spritesLoaded = false;
modelsLoaded = false;
loadProperties(textureMap);
}
public static void update() {
if (spritesLoaded) {
modelCubeGrass = BlockModelUtils.makeModelCube(spriteGrass, 0);
if (grassMultilayer) {
IBakedModel ibakedmodel = BlockModelUtils.makeModelCube(spriteGrassSide, -1);
modelCubeGrass = BlockModelUtils.joinModelsCube(ibakedmodel, modelCubeGrass);
}
modelCubeMycelium = BlockModelUtils.makeModelCube(spriteMycelium, -1);
modelCubePodzol = BlockModelUtils.makeModelCube(spritePodzol, 0);
modelCubeSnow = BlockModelUtils.makeModelCube(spriteSnow, -1);
modelsLoaded = true;
}
}
private static void loadProperties(TextureMap textureMap) {
betterGrass = true;
betterMycelium = true;
betterPodzol = true;
betterGrassSnow = true;
betterMyceliumSnow = true;
betterPodzolSnow = true;
spriteGrass = textureMap.registerSprite(new ResourceLocation("blocks/grass_top"));
spriteGrassSide = textureMap.registerSprite(new ResourceLocation("blocks/grass_side"));
spriteMycelium = textureMap.registerSprite(new ResourceLocation("blocks/mycelium_top"));
spritePodzol = textureMap.registerSprite(new ResourceLocation("blocks/dirt_podzol_top"));
spriteSnow = textureMap.registerSprite(new ResourceLocation("blocks/snow"));
spritesLoaded = true;
String s = "optifine/bettergrass.properties";
try (InputStream inputstream = Minecraft.getMinecraft().getResourceManager()
.getResource(new ResourceLocation(s)).getInputStream()) {
Properties properties = new PropertiesOrdered();
properties.load(inputstream);
inputstream.close();
betterGrass = getBoolean(properties, "grass", true);
betterMycelium = getBoolean(properties, "mycelium", true);
betterPodzol = getBoolean(properties, "podzol", true);
betterGrassSnow = getBoolean(properties, "grass.snow", true);
betterMyceliumSnow = getBoolean(properties, "mycelium.snow", true);
betterPodzolSnow = getBoolean(properties, "podzol.snow", true);
grassMultilayer = getBoolean(properties, "grass.multilayer", false);
spriteGrass = registerSprite(properties, "texture.grass", "blocks/grass_top", textureMap);
spriteGrassSide = registerSprite(properties, "texture.grass_side", "blocks/grass_side", textureMap);
spriteMycelium = registerSprite(properties, "texture.mycelium", "blocks/mycelium_top", textureMap);
spritePodzol = registerSprite(properties, "texture.podzol", "blocks/dirt_podzol_top", textureMap);
spriteSnow = registerSprite(properties, "texture.snow", "blocks/snow", textureMap);
} catch (IOException ioexception) {
Config.warn(
"Error reading: " + s + ", " + ioexception.getClass().getName() + ": " + ioexception.getMessage());
}
}
private static EaglerTextureAtlasSprite registerSprite(Properties props, String key, String textureDefault,
TextureMap textureMap) {
String s = props.getProperty(key);
if (s == null) {
s = textureDefault;
}
// ResourceLocation resourcelocation = new ResourceLocation("textures/" + s + ".png");
//
// if (!Config.hasResource(resourcelocation)) {
// Config.warn("BetterGrass texture not found: " + resourcelocation);
// s = textureDefault;
// }
ResourceLocation resourcelocation1 = new ResourceLocation(s);
EaglerTextureAtlasSprite textureatlassprite = textureMap.registerSprite(resourcelocation1, key);
return textureatlassprite;
}
public static List getFaceQuads(IBlockAccess blockAccess, IBlockState blockState, BlockPos blockPos,
EnumFacing facing, List quads) {
if (facing != EnumFacing.UP && facing != EnumFacing.DOWN) {
if (!modelsLoaded) {
return quads;
} else {
Block block = blockState.getBlock();
return block instanceof BlockMycelium
? getFaceQuadsMycelium(blockAccess, blockState, blockPos, facing, quads)
: (block instanceof BlockDirt
? getFaceQuadsDirt(blockAccess, blockState, blockPos, facing, quads)
: (block instanceof BlockGrass
? getFaceQuadsGrass(blockAccess, blockState, blockPos, facing, quads)
: quads));
}
} else {
return quads;
}
}
private static List getFaceQuadsMycelium(IBlockAccess blockAccess, IBlockState blockState, BlockPos blockPos,
EnumFacing facing, List quads) {
Block block = blockAccess.getBlockState(blockPos.up()).getBlock();
boolean flag = block == Blocks.snow || block == Blocks.snow_layer;
if (Config.isBetterGrassFancy()) {
if (flag) {
if (betterMyceliumSnow && getBlockAt(blockPos, facing, blockAccess) == Blocks.snow_layer) {
return modelCubeSnow.getFaceQuads(facing);
}
} else if (betterMycelium && getBlockAt(blockPos.down(), facing, blockAccess) == Blocks.mycelium) {
return modelCubeMycelium.getFaceQuads(facing);
}
} else if (flag) {
if (betterMyceliumSnow) {
return modelCubeSnow.getFaceQuads(facing);
}
} else if (betterMycelium) {
return modelCubeMycelium.getFaceQuads(facing);
}
return quads;
}
private static List getFaceQuadsDirt(IBlockAccess blockAccess, IBlockState blockState, BlockPos blockPos,
EnumFacing facing, List quads) {
Block block = getBlockAt(blockPos, EnumFacing.UP, blockAccess);
if (blockState.getValue(BlockDirt.VARIANT) != BlockDirt.DirtType.PODZOL) {
return quads;
} else {
boolean flag = block == Blocks.snow || block == Blocks.snow_layer;
if (Config.isBetterGrassFancy()) {
if (flag) {
if (betterPodzolSnow && getBlockAt(blockPos, facing, blockAccess) == Blocks.snow_layer) {
return modelCubeSnow.getFaceQuads(facing);
}
} else if (betterPodzol) {
BlockPos blockpos = blockPos.down().offset(facing);
IBlockState iblockstate = blockAccess.getBlockState(blockpos);
if (iblockstate.getBlock() == Blocks.dirt
&& iblockstate.getValue(BlockDirt.VARIANT) == BlockDirt.DirtType.PODZOL) {
return modelCubePodzol.getFaceQuads(facing);
}
}
} else if (flag) {
if (betterPodzolSnow) {
return modelCubeSnow.getFaceQuads(facing);
}
} else if (betterPodzol) {
return modelCubePodzol.getFaceQuads(facing);
}
return quads;
}
}
private static List getFaceQuadsGrass(IBlockAccess blockAccess, IBlockState blockState, BlockPos blockPos,
EnumFacing facing, List quads) {
Block block = blockAccess.getBlockState(blockPos.up()).getBlock();
boolean flag = block == Blocks.snow || block == Blocks.snow_layer;
if (Config.isBetterGrassFancy()) {
if (flag) {
if (betterGrassSnow && getBlockAt(blockPos, facing, blockAccess) == Blocks.snow_layer) {
return modelCubeSnow.getFaceQuads(facing);
}
} else if (betterGrass && getBlockAt(blockPos.down(), facing, blockAccess) == Blocks.grass) {
return modelCubeGrass.getFaceQuads(facing);
}
} else if (flag) {
if (betterGrassSnow) {
return modelCubeSnow.getFaceQuads(facing);
}
} else if (betterGrass) {
return modelCubeGrass.getFaceQuads(facing);
}
return quads;
}
private static Block getBlockAt(BlockPos blockPos, EnumFacing facing, IBlockAccess blockAccess) {
BlockPos blockpos = blockPos.offset(facing);
Block block = blockAccess.getBlockState(blockpos).getBlock();
return block;
}
private static boolean getBoolean(Properties props, String key, boolean def) {
String s = props.getProperty(key);
return s == null ? def : Boolean.parseBoolean(s);
}
}

View File

@ -0,0 +1,91 @@
package net.optifine;
import net.minecraft.block.Block;
import net.minecraft.block.BlockBush;
import net.minecraft.block.BlockDoublePlant;
import net.minecraft.block.BlockFence;
import net.minecraft.block.BlockFenceGate;
import net.minecraft.block.BlockFlower;
import net.minecraft.block.BlockFlowerPot;
import net.minecraft.block.BlockLever;
import net.minecraft.block.BlockMushroom;
import net.minecraft.block.BlockPane;
import net.minecraft.block.BlockRedstoneTorch;
import net.minecraft.block.BlockReed;
import net.minecraft.block.BlockSapling;
import net.minecraft.block.BlockSnow;
import net.minecraft.block.BlockTallGrass;
import net.minecraft.block.BlockTorch;
import net.minecraft.block.BlockWall;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.model.IBakedModel;
import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.IBlockAccess;
public class BetterSnow {
private static IBakedModel modelSnowLayer = null;
public static void update() {
modelSnowLayer = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes()
.getModelForState(Blocks.snow_layer.getDefaultState());
}
public static IBakedModel getModelSnowLayer() {
return modelSnowLayer;
}
public static IBlockState getStateSnowLayer() {
return Blocks.snow_layer.getDefaultState();
}
public static boolean shouldRender(IBlockAccess blockAccess, IBlockState blockState, BlockPos blockPos) {
Block block = blockState.getBlock();
return !checkBlock(block, blockState) ? false : hasSnowNeighbours(blockAccess, blockPos);
}
private static boolean hasSnowNeighbours(IBlockAccess blockAccess, BlockPos pos) {
Block block = Blocks.snow_layer;
return blockAccess.getBlockState(pos.north()).getBlock() != block
&& blockAccess.getBlockState(pos.south()).getBlock() != block
&& blockAccess.getBlockState(pos.west()).getBlock() != block
&& blockAccess.getBlockState(pos.east()).getBlock() != block ? false
: blockAccess.getBlockState(pos.down()).getBlock().isOpaqueCube();
}
private static boolean checkBlock(Block block, IBlockState blockState) {
if (block.isFullCube()) {
return false;
} else if (block.isOpaqueCube()) {
return false;
} else if (block instanceof BlockSnow) {
return false;
} else if (!(block instanceof BlockBush) || !(block instanceof BlockDoublePlant)
&& !(block instanceof BlockFlower) && !(block instanceof BlockMushroom)
&& !(block instanceof BlockSapling) && !(block instanceof BlockTallGrass)) {
if (!(block instanceof BlockFence) && !(block instanceof BlockFenceGate)
&& !(block instanceof BlockFlowerPot) && !(block instanceof BlockPane)
&& !(block instanceof BlockReed) && !(block instanceof BlockWall)) {
if (block instanceof BlockRedstoneTorch && blockState.getValue(BlockTorch.FACING) == EnumFacing.UP) {
return true;
} else {
if (block instanceof BlockLever) {
Object object = blockState.getValue(BlockLever.FACING);
if (object == BlockLever.EnumOrientation.UP_X || object == BlockLever.EnumOrientation.UP_Z) {
return true;
}
}
return false;
}
} else {
return true;
}
} else {
return true;
}
}
}

View File

@ -0,0 +1,78 @@
package net.optifine;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
public enum BlockDir {
DOWN(EnumFacing.DOWN), UP(EnumFacing.UP), NORTH(EnumFacing.NORTH), SOUTH(EnumFacing.SOUTH), WEST(EnumFacing.WEST),
EAST(EnumFacing.EAST), NORTH_WEST(EnumFacing.NORTH, EnumFacing.WEST), NORTH_EAST(EnumFacing.NORTH, EnumFacing.EAST),
SOUTH_WEST(EnumFacing.SOUTH, EnumFacing.WEST), SOUTH_EAST(EnumFacing.SOUTH, EnumFacing.EAST),
DOWN_NORTH(EnumFacing.DOWN, EnumFacing.NORTH), DOWN_SOUTH(EnumFacing.DOWN, EnumFacing.SOUTH),
UP_NORTH(EnumFacing.UP, EnumFacing.NORTH), UP_SOUTH(EnumFacing.UP, EnumFacing.SOUTH),
DOWN_WEST(EnumFacing.DOWN, EnumFacing.WEST), DOWN_EAST(EnumFacing.DOWN, EnumFacing.EAST),
UP_WEST(EnumFacing.UP, EnumFacing.WEST), UP_EAST(EnumFacing.UP, EnumFacing.EAST);
private EnumFacing facing1;
private EnumFacing facing2;
private BlockDir(EnumFacing facing1) {
this.facing1 = facing1;
}
private BlockDir(EnumFacing facing1, EnumFacing facing2) {
this.facing1 = facing1;
this.facing2 = facing2;
}
public EnumFacing getFacing1() {
return this.facing1;
}
public EnumFacing getFacing2() {
return this.facing2;
}
BlockPos offset(BlockPos pos) {
pos = pos.offset(this.facing1, 1);
if (this.facing2 != null) {
pos = pos.offset(this.facing2, 1);
}
return pos;
}
public int getOffsetX() {
int i = this.facing1.getFrontOffsetX();
if (this.facing2 != null) {
i += this.facing2.getFrontOffsetX();
}
return i;
}
public int getOffsetY() {
int i = this.facing1.getFrontOffsetY();
if (this.facing2 != null) {
i += this.facing2.getFrontOffsetY();
}
return i;
}
public int getOffsetZ() {
int i = this.facing1.getFrontOffsetZ();
if (this.facing2 != null) {
i += this.facing2.getFrontOffsetZ();
}
return i;
}
public boolean isDouble() {
return this.facing2 != null;
}
}

View File

@ -0,0 +1,339 @@
package net.optifine;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.DefaultResourcePack;
import net.minecraft.client.resources.IResourcePack;
import net.minecraft.client.resources.ResourcePackRepository;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.util.BlockPos;
import net.minecraft.util.ResourceLocation;
import net.optifine.util.TextureUtils;
public class Config {
private static final Logger logger = LogManager.getLogger("OptiFine");
private static Minecraft mc;
private static GameSettings gameSettings;
public static void setGameObj(Minecraft mc) {
Config.mc = mc;
Config.gameSettings = mc.gameSettings;
}
public static String[] tokenize(String p_tokenize_0_, String p_tokenize_1_) {
StringTokenizer stringtokenizer = new StringTokenizer(p_tokenize_0_, p_tokenize_1_);
List list = new ArrayList();
while (stringtokenizer.hasMoreTokens()) {
String s = stringtokenizer.nextToken();
list.add(s);
}
String[] astring = (String[]) list.toArray(new String[list.size()]);
return astring;
}
public static boolean isCustomSky() {
return gameSettings.customSkyOF;
}
public static boolean isBetterGrass() {
return gameSettings.betterGrassOF != 0;
}
public static boolean isBetterGrassFancy() {
return gameSettings.betterGrassOF == 2;
}
public static boolean isBetterSnow() {
return gameSettings.betterGrassOF != 0;
}
public static boolean isConnectedTextures() {
return gameSettings.connectedTexturesOF != 0;
}
public static boolean isConnectedTexturesFancy() {
return gameSettings.connectedTexturesOF == 2;
}
public static boolean isTreesFancy() {
return gameSettings.fancyGraphics;
}
public static boolean isTreesSmart() {
return gameSettings.fancyGraphics && gameSettings.smartLeavesOF;
}
public static boolean isCullFacesLeaves() {
return !gameSettings.fancyGraphics;
}
public static boolean isCustomItems() {
return gameSettings.customItemsOF;
}
public static void dbg(String string) {
logger.debug(string);
}
public static void warn(String string) {
logger.warn(string);
}
public static void error(String string) {
logger.error(string);
}
public static int limit(int p_limit_0_, int p_limit_1_, int p_limit_2_) {
return p_limit_0_ < p_limit_1_ ? p_limit_1_ : (p_limit_0_ > p_limit_2_ ? p_limit_2_ : p_limit_0_);
}
public static float limit(float p_limit_0_, float p_limit_1_, float p_limit_2_) {
return p_limit_0_ < p_limit_1_ ? p_limit_1_ : (p_limit_0_ > p_limit_2_ ? p_limit_2_ : p_limit_0_);
}
public static double limit(double p_limit_0_, double p_limit_2_, double p_limit_4_) {
return p_limit_0_ < p_limit_2_ ? p_limit_2_ : (p_limit_0_ > p_limit_4_ ? p_limit_4_ : p_limit_0_);
}
public static int parseInt(String p_parseInt_0_, int p_parseInt_1_) {
try {
if (p_parseInt_0_ == null) {
return p_parseInt_1_;
} else {
p_parseInt_0_ = p_parseInt_0_.trim();
return Integer.parseInt(p_parseInt_0_);
}
} catch (NumberFormatException var3) {
return p_parseInt_1_;
}
}
public static float parseFloat(String p_parseFloat_0_, float p_parseFloat_1_) {
try {
if (p_parseFloat_0_ == null) {
return p_parseFloat_1_;
} else {
p_parseFloat_0_ = p_parseFloat_0_.trim();
return Float.parseFloat(p_parseFloat_0_);
}
} catch (NumberFormatException var3) {
return p_parseFloat_1_;
}
}
public static boolean parseBoolean(String p_parseBoolean_0_, boolean p_parseBoolean_1_) {
try {
if (p_parseBoolean_0_ == null) {
return p_parseBoolean_1_;
} else {
p_parseBoolean_0_ = p_parseBoolean_0_.trim();
return Boolean.parseBoolean(p_parseBoolean_0_);
}
} catch (NumberFormatException var3) {
return p_parseBoolean_1_;
}
}
public static int[] addIntToArray(int[] p_addIntToArray_0_, int p_addIntToArray_1_) {
if (p_addIntToArray_0_ != null) {
int[] ret = new int[p_addIntToArray_0_.length + 1];
System.arraycopy(p_addIntToArray_0_, 0, ret, 0, p_addIntToArray_0_.length);
ret[p_addIntToArray_0_.length] = p_addIntToArray_1_;
return ret;
} else {
throw new NullPointerException("The given array is NULL");
}
}
public static int[] addIntsToArray(int[] p_addIntsToArray_0_, int[] p_addIntsToArray_1_) {
if (p_addIntsToArray_0_ != null && p_addIntsToArray_1_ != null) {
int i = p_addIntsToArray_0_.length;
int j = i + p_addIntsToArray_1_.length;
int[] aint = new int[j];
System.arraycopy(p_addIntsToArray_0_, 0, aint, 0, i);
for (int k = 0; k < p_addIntsToArray_1_.length; ++k) {
aint[k + i] = p_addIntsToArray_1_[k];
}
return aint;
} else {
throw new NullPointerException("The given array is NULL");
}
}
public static String arrayToString(Object[] p_arrayToString_0_) {
return arrayToString(p_arrayToString_0_, ", ");
}
public static String arrayToString(Object[] p_arrayToString_0_, String p_arrayToString_1_) {
if (p_arrayToString_0_ == null) {
return "";
} else {
StringBuffer stringbuffer = new StringBuffer(p_arrayToString_0_.length * 5);
for (int i = 0; i < p_arrayToString_0_.length; ++i) {
Object object = p_arrayToString_0_[i];
if (i > 0) {
stringbuffer.append(p_arrayToString_1_);
}
stringbuffer.append(String.valueOf(object));
}
return stringbuffer.toString();
}
}
public static String arrayToString(int[] p_arrayToString_0_) {
return arrayToString(p_arrayToString_0_, ", ");
}
public static String arrayToString(int[] p_arrayToString_0_, String p_arrayToString_1_) {
if (p_arrayToString_0_ == null) {
return "";
} else {
StringBuffer stringbuffer = new StringBuffer(p_arrayToString_0_.length * 5);
for (int i = 0; i < p_arrayToString_0_.length; ++i) {
int j = p_arrayToString_0_[i];
if (i > 0) {
stringbuffer.append(p_arrayToString_1_);
}
stringbuffer.append(String.valueOf(j));
}
return stringbuffer.toString();
}
}
public static int[] toPrimitive(Integer[] p_toPrimitive_0_) {
if (p_toPrimitive_0_ == null) {
return null;
} else if (p_toPrimitive_0_.length == 0) {
return new int[0];
} else {
int[] aint = new int[p_toPrimitive_0_.length];
for (int i = 0; i < aint.length; ++i) {
aint[i] = p_toPrimitive_0_[i].intValue();
}
return aint;
}
}
public static boolean isSameOne(Object p_isSameOne_0_, Object[] p_isSameOne_1_) {
if (p_isSameOne_1_ == null) {
return false;
} else {
for (int i = 0; i < p_isSameOne_1_.length; ++i) {
Object object = p_isSameOne_1_[i];
if (p_isSameOne_0_ == object) {
return true;
}
}
return false;
}
}
public static boolean equals(Object p_equals_0_, Object p_equals_1_) {
return p_equals_0_ == p_equals_1_ ? true : (p_equals_0_ == null ? false : p_equals_0_.equals(p_equals_1_));
}
public static boolean isFromDefaultResourcePack(ResourceLocation p_isFromDefaultResourcePack_0_) {
IResourcePack iresourcepack = getDefiningResourcePack(p_isFromDefaultResourcePack_0_);
return iresourcepack == mc.getDefaultResourcePack();
}
public static IResourcePack getDefiningResourcePack(ResourceLocation p_getDefiningResourcePack_0_) {
ResourcePackRepository resourcepackrepository = mc.getResourcePackRepository();
IResourcePack iresourcepack = resourcepackrepository.getResourcePackInstance();
if (iresourcepack != null && iresourcepack.resourceExists(p_getDefiningResourcePack_0_)) {
return iresourcepack;
} else {
List<ResourcePackRepository.Entry> list = resourcepackrepository.getRepositoryEntries();
for (int i = list.size() - 1; i >= 0; --i) {
ResourcePackRepository.Entry resourcepackrepository$entry = (ResourcePackRepository.Entry) list.get(i);
IResourcePack iresourcepack1 = resourcepackrepository$entry.getResourcePack();
if (iresourcepack1.resourceExists(p_getDefiningResourcePack_0_)) {
return iresourcepack1;
}
}
DefaultResourcePack res = mc.getDefaultResourcePack();
if (res.resourceExists(p_getDefiningResourcePack_0_)) {
return res;
} else {
return null;
}
}
}
public static boolean hasResource(ResourceLocation p_hasResource_0_) {
if (p_hasResource_0_ == null) {
return false;
} else {
IResourcePack iresourcepack = getDefiningResourcePack(p_hasResource_0_);
return iresourcepack != null;
}
}
public static IResourcePack[] getResourcePacks() {
ResourcePackRepository resourcepackrepository = mc.getResourcePackRepository();
List list = resourcepackrepository.getRepositoryEntries();
List list1 = new ArrayList();
for (Object resourcepackrepository$entry0 : list) {
ResourcePackRepository.Entry resourcepackrepository$entry = (ResourcePackRepository.Entry) resourcepackrepository$entry0;
list1.add(resourcepackrepository$entry.getResourcePack());
}
if (resourcepackrepository.getResourcePackInstance() != null) {
list1.add(resourcepackrepository.getResourcePackInstance());
}
IResourcePack[] airesourcepack = (IResourcePack[]) ((IResourcePack[]) list1
.toArray(new IResourcePack[list1.size()]));
return airesourcepack;
}
public static int intHash(int p_intHash_0_) {
p_intHash_0_ = p_intHash_0_ ^ 61 ^ p_intHash_0_ >> 16;
p_intHash_0_ = p_intHash_0_ + (p_intHash_0_ << 3);
p_intHash_0_ = p_intHash_0_ ^ p_intHash_0_ >> 4;
p_intHash_0_ = p_intHash_0_ * 668265261;
p_intHash_0_ = p_intHash_0_ ^ p_intHash_0_ >> 15;
return p_intHash_0_;
}
public static int getRandom(BlockPos p_getRandom_0_, int p_getRandom_1_) {
int i = intHash(p_getRandom_1_ + 37);
i = intHash(i + p_getRandom_0_.getX());
i = intHash(i + p_getRandom_0_.getZ());
i = intHash(i + p_getRandom_0_.getY());
return i;
}
public static void frameInitHook() {
TextureUtils.registerResourceListener();
}
}

View File

@ -0,0 +1,993 @@
package net.optifine;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.function.Function;
import net.lax1dude.eaglercraft.v1_8.minecraft.EaglerTextureAtlasSprite;
import net.minecraft.block.Block;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumWorldBlockLayer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.biome.BiomeGenBase;
import net.optifine.config.ConnectedParser;
import net.optifine.config.MatchBlock;
import net.optifine.config.Matches;
import net.optifine.config.NbtTagValue;
import net.optifine.config.RangeInt;
import net.optifine.config.RangeListInt;
import net.optifine.util.MathUtils;
import net.optifine.util.TextureUtils;
public class ConnectedProperties {
public String name = null;
public String basePath = null;
public MatchBlock[] matchBlocks = null;
public int[] metadatas = null;
public String[] matchTiles = null;
public int method = 0;
public String[] tiles = null;
public int connect = 0;
public int faces = 63;
public BiomeGenBase[] biomes = null;
public RangeListInt heights = null;
public int renderPass = 0;
public boolean innerSeams = false;
public int[] ctmTileIndexes = null;
public int width = 0;
public int height = 0;
public int[] weights = null;
public int randomLoops = 0;
public int symmetry = 1;
public boolean linked = false;
public NbtTagValue nbtName = null;
public int[] sumWeights = null;
public int sumAllWeights = 1;
public EaglerTextureAtlasSprite[] matchTileIcons = null;
public EaglerTextureAtlasSprite[] tileIcons = null;
public MatchBlock[] connectBlocks = null;
public String[] connectTiles = null;
public EaglerTextureAtlasSprite[] connectTileIcons = null;
public int tintIndex = -1;
public IBlockState tintBlockState = Blocks.air.getDefaultState();
public EnumWorldBlockLayer layer = null;
public static final int METHOD_NONE = 0;
public static final int METHOD_CTM = 1;
public static final int METHOD_HORIZONTAL = 2;
public static final int METHOD_TOP = 3;
public static final int METHOD_RANDOM = 4;
public static final int METHOD_REPEAT = 5;
public static final int METHOD_VERTICAL = 6;
public static final int METHOD_FIXED = 7;
public static final int METHOD_HORIZONTAL_VERTICAL = 8;
public static final int METHOD_VERTICAL_HORIZONTAL = 9;
public static final int METHOD_CTM_COMPACT = 10;
public static final int METHOD_OVERLAY = 11;
public static final int METHOD_OVERLAY_FIXED = 12;
public static final int METHOD_OVERLAY_RANDOM = 13;
public static final int METHOD_OVERLAY_REPEAT = 14;
public static final int METHOD_OVERLAY_CTM = 15;
public static final int CONNECT_NONE = 0;
public static final int CONNECT_BLOCK = 1;
public static final int CONNECT_TILE = 2;
public static final int CONNECT_MATERIAL = 3;
public static final int CONNECT_UNKNOWN = 128;
public static final int FACE_BOTTOM = 1;
public static final int FACE_TOP = 2;
public static final int FACE_NORTH = 4;
public static final int FACE_SOUTH = 8;
public static final int FACE_WEST = 16;
public static final int FACE_EAST = 32;
public static final int FACE_SIDES = 60;
public static final int FACE_ALL = 63;
public static final int FACE_UNKNOWN = 128;
public static final int SYMMETRY_NONE = 1;
public static final int SYMMETRY_OPPOSITE = 2;
public static final int SYMMETRY_ALL = 6;
public static final int SYMMETRY_UNKNOWN = 128;
public static final String TILE_SKIP_PNG = "<skip>.png";
public static final String TILE_DEFAULT_PNG = "<default>.png";
public ConnectedProperties(Properties props, String path) {
ConnectedParser connectedparser = new ConnectedParser("ConnectedTextures");
this.name = connectedparser.parseName(path);
this.basePath = connectedparser.parseBasePath(path);
this.matchBlocks = connectedparser.parseMatchBlocks(props.getProperty("matchBlocks"));
this.metadatas = connectedparser.parseIntList(props.getProperty("metadata"));
this.matchTiles = this.parseMatchTiles(props.getProperty("matchTiles"));
this.method = parseMethod(props.getProperty("method"));
this.tiles = this.parseTileNames(props.getProperty("tiles"));
this.connect = parseConnect(props.getProperty("connect"));
this.faces = parseFaces(props.getProperty("faces"));
this.biomes = connectedparser.parseBiomes(props.getProperty("biomes"));
this.heights = connectedparser.parseRangeListInt(props.getProperty("heights"));
if (this.heights == null) {
int i = connectedparser.parseInt(props.getProperty("minHeight"), -1);
int j = connectedparser.parseInt(props.getProperty("maxHeight"), 1024);
if (i != -1 || j != 1024) {
this.heights = new RangeListInt(new RangeInt(i, j));
}
}
this.renderPass = connectedparser.parseInt(props.getProperty("renderPass"), -1);
this.innerSeams = connectedparser.parseBoolean(props.getProperty("innerSeams"), false);
this.ctmTileIndexes = this.parseCtmTileIndexes(props);
this.width = connectedparser.parseInt(props.getProperty("width"), -1);
this.height = connectedparser.parseInt(props.getProperty("height"), -1);
this.weights = connectedparser.parseIntList(props.getProperty("weights"));
this.randomLoops = connectedparser.parseInt(props.getProperty("randomLoops"), 0);
this.symmetry = parseSymmetry(props.getProperty("symmetry"));
this.linked = connectedparser.parseBoolean(props.getProperty("linked"), false);
this.nbtName = connectedparser.parseNbtTagValue("name", props.getProperty("name"));
this.connectBlocks = connectedparser.parseMatchBlocks(props.getProperty("connectBlocks"));
this.connectTiles = this.parseMatchTiles(props.getProperty("connectTiles"));
this.tintIndex = connectedparser.parseInt(props.getProperty("tintIndex"), -1);
this.tintBlockState = connectedparser.parseBlockState(props.getProperty("tintBlock"),
Blocks.air.getDefaultState());
this.layer = connectedparser.parseBlockRenderLayer(props.getProperty("layer"),
EnumWorldBlockLayer.CUTOUT_MIPPED);
}
private int[] parseCtmTileIndexes(Properties props) {
if (this.tiles == null) {
return null;
} else {
Map<Integer, Integer> map = new HashMap();
for (Object object : props.keySet()) {
if (object instanceof String) {
String s = (String) object;
String s1 = "ctm.";
if (s.startsWith(s1)) {
String s2 = s.substring(s1.length());
String s3 = props.getProperty(s);
if (s3 != null) {
s3 = s3.trim();
int i = Config.parseInt(s2, -1);
if (i >= 0 && i <= 46) {
int j = Config.parseInt(s3, -1);
if (j >= 0 && j < this.tiles.length) {
map.put(Integer.valueOf(i), Integer.valueOf(j));
} else {
Config.warn("Invalid CTM tile index: " + s3);
}
} else {
Config.warn("Invalid CTM index: " + s2);
}
}
}
}
}
if (map.isEmpty()) {
return null;
} else {
int[] aint = new int[47];
for (int k = 0; k < aint.length; ++k) {
aint[k] = -1;
if (map.containsKey(Integer.valueOf(k))) {
aint[k] = ((Integer) map.get(Integer.valueOf(k))).intValue();
}
}
return aint;
}
}
}
private String[] parseMatchTiles(String str) {
if (str == null) {
return null;
} else {
String[] astring = Config.tokenize(str, " ");
for (int i = 0; i < astring.length; ++i) {
String s = astring[i];
if (s.endsWith(".png")) {
s = s.substring(0, s.length() - 4);
}
s = TextureUtils.fixResourcePath(s, this.basePath);
astring[i] = s;
}
return astring;
}
}
private static String parseName(String path) {
String s = path;
int i = path.lastIndexOf(47);
if (i >= 0) {
s = path.substring(i + 1);
}
int j = s.lastIndexOf(46);
if (j >= 0) {
s = s.substring(0, j);
}
return s;
}
private static String parseBasePath(String path) {
int i = path.lastIndexOf(47);
return i < 0 ? "" : path.substring(0, i);
}
private String[] parseTileNames(String str) {
if (str == null) {
return null;
} else {
List list = new ArrayList();
String[] astring = Config.tokenize(str, " ,");
label32:
for (int i = 0; i < astring.length; ++i) {
String s = astring[i];
if (s.contains("-")) {
String[] astring1 = Config.tokenize(s, "-");
if (astring1.length == 2) {
int j = Config.parseInt(astring1[0], -1);
int k = Config.parseInt(astring1[1], -1);
if (j >= 0 && k >= 0) {
if (j > k) {
Config.warn("Invalid interval: " + s + ", when parsing: " + str);
continue;
}
int l = j;
while (true) {
if (l > k) {
continue label32;
}
list.add(String.valueOf(l));
++l;
}
}
}
}
list.add(s);
}
String[] astring2 = (String[]) list.toArray(new String[list.size()]);
for (int i1 = 0; i1 < astring2.length; ++i1) {
String s1 = astring2[i1];
s1 = TextureUtils.fixResourcePath(s1, this.basePath);
if (!s1.startsWith(this.basePath) && !s1.startsWith("textures/") && !s1.startsWith("mcpatcher/")) {
s1 = this.basePath + "/" + s1;
}
if (s1.endsWith(".png")) {
s1 = s1.substring(0, s1.length() - 4);
}
if (s1.startsWith("/")) {
s1 = s1.substring(1);
}
astring2[i1] = s1;
}
return astring2;
}
}
private static int parseSymmetry(String str) {
if (str == null) {
return 1;
} else {
str = str.trim();
if (str.equals("opposite")) {
return 2;
} else if (str.equals("all")) {
return 6;
} else {
Config.warn("Unknown symmetry: " + str);
return 1;
}
}
}
private static int parseFaces(String str) {
if (str == null) {
return 63;
} else {
String[] astring = Config.tokenize(str, " ,");
int i = 0;
for (int j = 0; j < astring.length; ++j) {
String s = astring[j];
int k = parseFace(s);
i |= k;
}
return i;
}
}
private static int parseFace(String str) {
str = str.toLowerCase();
if (!str.equals("bottom") && !str.equals("down")) {
if (!str.equals("top") && !str.equals("up")) {
if (str.equals("north")) {
return 4;
} else if (str.equals("south")) {
return 8;
} else if (str.equals("east")) {
return 32;
} else if (str.equals("west")) {
return 16;
} else if (str.equals("sides")) {
return 60;
} else if (str.equals("all")) {
return 63;
} else {
Config.warn("Unknown face: " + str);
return 128;
}
} else {
return 2;
}
} else {
return 1;
}
}
private static int parseConnect(String str) {
if (str == null) {
return 0;
} else {
str = str.trim();
if (str.equals("block")) {
return 1;
} else if (str.equals("tile")) {
return 2;
} else if (str.equals("material")) {
return 3;
} else {
Config.warn("Unknown connect: " + str);
return 128;
}
}
}
public static IProperty getProperty(String key, Collection properties) {
for (Object iproperty0 : properties) {
IProperty iproperty = (IProperty) iproperty0;
if (key.equals(iproperty.getName())) {
return iproperty;
}
}
return null;
}
private static int parseMethod(String str) {
if (str == null) {
return 1;
} else {
str = str.trim();
if (!str.equals("ctm") && !str.equals("glass")) {
if (str.equals("ctm_compact")) {
return 10;
} else if (!str.equals("horizontal") && !str.equals("bookshelf")) {
if (str.equals("vertical")) {
return 6;
} else if (str.equals("top")) {
return 3;
} else if (str.equals("random")) {
return 4;
} else if (str.equals("repeat")) {
return 5;
} else if (str.equals("fixed")) {
return 7;
} else if (!str.equals("horizontal+vertical") && !str.equals("h+v")) {
if (!str.equals("vertical+horizontal") && !str.equals("v+h")) {
if (str.equals("overlay")) {
return 11;
} else if (str.equals("overlay_fixed")) {
return 12;
} else if (str.equals("overlay_random")) {
return 13;
} else if (str.equals("overlay_repeat")) {
return 14;
} else if (str.equals("overlay_ctm")) {
return 15;
} else {
Config.warn("Unknown method: " + str);
return 0;
}
} else {
return 9;
}
} else {
return 8;
}
} else {
return 2;
}
} else {
return 1;
}
}
}
public boolean isValid(String path) {
if (this.name != null && this.name.length() > 0) {
if (this.basePath == null) {
Config.warn("No base path found: " + path);
return false;
} else {
if (this.matchBlocks == null) {
this.matchBlocks = this.detectMatchBlocks();
}
if (this.matchTiles == null && this.matchBlocks == null) {
this.matchTiles = this.detectMatchTiles();
}
if (this.matchBlocks == null && this.matchTiles == null) {
Config.warn("No matchBlocks or matchTiles specified: " + path);
return false;
} else if (this.method == 0) {
Config.warn("No method: " + path);
return false;
} else if (this.tiles != null && this.tiles.length > 0) {
if (this.connect == 0) {
this.connect = this.detectConnect();
}
if (this.connect == 128) {
Config.warn("Invalid connect in: " + path);
return false;
} else if (this.renderPass > 0) {
Config.warn("Render pass not supported: " + this.renderPass);
return false;
} else if ((this.faces & 128) != 0) {
Config.warn("Invalid faces in: " + path);
return false;
} else if ((this.symmetry & 128) != 0) {
Config.warn("Invalid symmetry in: " + path);
return false;
} else {
switch (this.method) {
case 1:
return this.isValidCtm(path);
case 2:
return this.isValidHorizontal(path);
case 3:
return this.isValidTop(path);
case 4:
return this.isValidRandom(path);
case 5:
return this.isValidRepeat(path);
case 6:
return this.isValidVertical(path);
case 7:
return this.isValidFixed(path);
case 8:
return this.isValidHorizontalVertical(path);
case 9:
return this.isValidVerticalHorizontal(path);
case 10:
return this.isValidCtmCompact(path);
case 11:
return this.isValidOverlay(path);
case 12:
return this.isValidOverlayFixed(path);
case 13:
return this.isValidOverlayRandom(path);
case 14:
return this.isValidOverlayRepeat(path);
case 15:
return this.isValidOverlayCtm(path);
default:
Config.warn("Unknown method: " + path);
return false;
}
}
} else {
Config.warn("No tiles specified: " + path);
return false;
}
}
} else {
Config.warn("No name found: " + path);
return false;
}
}
private int detectConnect() {
return this.matchBlocks != null ? 1 : (this.matchTiles != null ? 2 : 128);
}
private MatchBlock[] detectMatchBlocks() {
int[] aint = this.detectMatchBlockIds();
if (aint == null) {
return null;
} else {
MatchBlock[] amatchblock = new MatchBlock[aint.length];
for (int i = 0; i < amatchblock.length; ++i) {
amatchblock[i] = new MatchBlock(aint[i]);
}
return amatchblock;
}
}
private int[] detectMatchBlockIds() {
if (!this.name.startsWith("block")) {
return null;
} else {
int i = "block".length();
int j;
for (j = i; j < this.name.length(); ++j) {
char c0 = this.name.charAt(j);
if (c0 < 48 || c0 > 57) {
break;
}
}
if (j == i) {
return null;
} else {
String s = this.name.substring(i, j);
int k = Config.parseInt(s, -1);
return k < 0 ? null : new int[] { k };
}
}
}
private String[] detectMatchTiles() {
EaglerTextureAtlasSprite textureatlassprite = getIcon(this.name);
return textureatlassprite == null ? null : new String[] { this.name };
}
private static EaglerTextureAtlasSprite getIcon(String iconName) {
TextureMap texturemap = Minecraft.getMinecraft().getTextureMapBlocks();
EaglerTextureAtlasSprite textureatlassprite = texturemap.getSpriteSafe(iconName);
if (textureatlassprite != null) {
return textureatlassprite;
} else {
textureatlassprite = texturemap.getSpriteSafe("blocks/" + iconName);
return textureatlassprite;
}
}
private boolean isValidCtm(String path) {
if (this.tiles == null) {
this.tiles = this.parseTileNames("0-11 16-27 32-43 48-58");
}
if (this.tiles.length < 47) {
Config.warn("Invalid tiles, must be at least 47: " + path);
return false;
} else {
return true;
}
}
private boolean isValidCtmCompact(String path) {
if (this.tiles == null) {
this.tiles = this.parseTileNames("0-4");
}
if (this.tiles.length < 5) {
Config.warn("Invalid tiles, must be at least 5: " + path);
return false;
} else {
return true;
}
}
private boolean isValidOverlay(String path) {
if (this.tiles == null) {
this.tiles = this.parseTileNames("0-16");
}
if (this.tiles.length < 17) {
Config.warn("Invalid tiles, must be at least 17: " + path);
return false;
} else if (this.layer != null && this.layer != EnumWorldBlockLayer.SOLID) {
return true;
} else {
Config.warn("Invalid overlay layer: " + this.layer);
return false;
}
}
private boolean isValidOverlayFixed(String path) {
if (!this.isValidFixed(path)) {
return false;
} else if (this.layer != null && this.layer != EnumWorldBlockLayer.SOLID) {
return true;
} else {
Config.warn("Invalid overlay layer: " + this.layer);
return false;
}
}
private boolean isValidOverlayRandom(String path) {
if (!this.isValidRandom(path)) {
return false;
} else if (this.layer != null && this.layer != EnumWorldBlockLayer.SOLID) {
return true;
} else {
Config.warn("Invalid overlay layer: " + this.layer);
return false;
}
}
private boolean isValidOverlayRepeat(String path) {
if (!this.isValidRepeat(path)) {
return false;
} else if (this.layer != null && this.layer != EnumWorldBlockLayer.SOLID) {
return true;
} else {
Config.warn("Invalid overlay layer: " + this.layer);
return false;
}
}
private boolean isValidOverlayCtm(String path) {
if (!this.isValidCtm(path)) {
return false;
} else if (this.layer != null && this.layer != EnumWorldBlockLayer.SOLID) {
return true;
} else {
Config.warn("Invalid overlay layer: " + this.layer);
return false;
}
}
private boolean isValidHorizontal(String path) {
if (this.tiles == null) {
this.tiles = this.parseTileNames("12-15");
}
if (this.tiles.length != 4) {
Config.warn("Invalid tiles, must be exactly 4: " + path);
return false;
} else {
return true;
}
}
private boolean isValidVertical(String path) {
if (this.tiles == null) {
Config.warn("No tiles defined for vertical: " + path);
return false;
} else if (this.tiles.length != 4) {
Config.warn("Invalid tiles, must be exactly 4: " + path);
return false;
} else {
return true;
}
}
private boolean isValidHorizontalVertical(String path) {
if (this.tiles == null) {
Config.warn("No tiles defined for horizontal+vertical: " + path);
return false;
} else if (this.tiles.length != 7) {
Config.warn("Invalid tiles, must be exactly 7: " + path);
return false;
} else {
return true;
}
}
private boolean isValidVerticalHorizontal(String path) {
if (this.tiles == null) {
Config.warn("No tiles defined for vertical+horizontal: " + path);
return false;
} else if (this.tiles.length != 7) {
Config.warn("Invalid tiles, must be exactly 7: " + path);
return false;
} else {
return true;
}
}
private boolean isValidRandom(String path) {
if (this.tiles != null && this.tiles.length > 0) {
if (this.weights != null) {
if (this.weights.length > this.tiles.length) {
Config.warn("More weights defined than tiles, trimming weights: " + path);
int[] aint = new int[this.tiles.length];
System.arraycopy(this.weights, 0, aint, 0, aint.length);
this.weights = aint;
}
if (this.weights.length < this.tiles.length) {
Config.warn("Less weights defined than tiles, expanding weights: " + path);
int[] aint1 = new int[this.tiles.length];
System.arraycopy(this.weights, 0, aint1, 0, this.weights.length);
int i = MathUtils.getAverage(this.weights);
for (int j = this.weights.length; j < aint1.length; ++j) {
aint1[j] = i;
}
this.weights = aint1;
}
this.sumWeights = new int[this.weights.length];
int k = 0;
for (int l = 0; l < this.weights.length; ++l) {
k += this.weights[l];
this.sumWeights[l] = k;
}
this.sumAllWeights = k;
if (this.sumAllWeights <= 0) {
Config.warn("Invalid sum of all weights: " + k);
this.sumAllWeights = 1;
}
}
if (this.randomLoops >= 0 && this.randomLoops <= 9) {
return true;
} else {
Config.warn("Invalid randomLoops: " + this.randomLoops);
return false;
}
} else {
Config.warn("Tiles not defined: " + path);
return false;
}
}
private boolean isValidRepeat(String path) {
if (this.tiles == null) {
Config.warn("Tiles not defined: " + path);
return false;
} else if (this.width <= 0) {
Config.warn("Invalid width: " + path);
return false;
} else if (this.height <= 0) {
Config.warn("Invalid height: " + path);
return false;
} else if (this.tiles.length != this.width * this.height) {
Config.warn("Number of tiles does not equal width x height: " + path);
return false;
} else {
return true;
}
}
private boolean isValidFixed(String path) {
if (this.tiles == null) {
Config.warn("Tiles not defined: " + path);
return false;
} else if (this.tiles.length != 1) {
Config.warn("Number of tiles should be 1 for method: fixed.");
return false;
} else {
return true;
}
}
private boolean isValidTop(String path) {
if (this.tiles == null) {
this.tiles = this.parseTileNames("66");
}
if (this.tiles.length != 1) {
Config.warn("Invalid tiles, must be exactly 1: " + path);
return false;
} else {
return true;
}
}
public void updateIcons(TextureMap textureMap) {
String baseName = null;
if (this.matchTiles != null) {
this.matchTileIcons = registerIcons(this.matchTiles, null, textureMap, false, false);
if(this.matchTiles.length > 0) {
baseName = "blocks/" + this.matchTiles[0];
}
}
if(baseName == null) {
int blockBaseID = -1;
int metaBase = -1;
if(this.matchBlocks != null && this.matchBlocks.length > 0) {
MatchBlock b = this.matchBlocks[0];
blockBaseID = b.getBlockId();
int[] metas = b.getMetadatas();
if(metas != null && metas.length > 0) {
metaBase = metas[0];
}
}
if(blockBaseID != -1) {
if(metaBase == -1 && this.metadatas != null && this.metadatas.length > 0) {
metaBase = this.metadatas[0];
}
if(metaBase == -1) {
metaBase = 0;
}
baseName = Minecraft.getMinecraft().getModelManager().modelbakerytmp.getBaseTextureForBlockPre(blockBaseID, metaBase);
}
}
if (this.connectTiles != null) {
this.connectTileIcons = registerIcons(this.connectTiles, baseName, textureMap, false, false);
}
if (this.tiles != null) {
this.tileIcons = registerIcons(this.tiles, baseName, textureMap, true, !isMethodOverlay(this.method));
}
}
private static boolean isMethodOverlay(int method) {
switch (method) {
case 11:
case 12:
case 13:
case 14:
case 15:
return true;
default:
return false;
}
}
private static EaglerTextureAtlasSprite[] registerIcons(String[] tileNames, String baseName,
TextureMap textureMap, boolean skipTiles, boolean defaultTiles) {
if (tileNames == null) {
return null;
} else {
List list = new ArrayList();
for (int i = 0; i < tileNames.length; ++i) {
String s = tileNames[i];
ResourceLocation resourcelocation = new ResourceLocation(s);
String s1 = resourcelocation.getResourceDomain();
String s2 = resourcelocation.getResourcePath();
if (!s2.contains("/")) {
s2 = "textures/blocks/" + s2;
}
String s3 = s2 + ".png";
if (skipTiles && s3.endsWith("<skip>.png")) {
list.add(null);
} else if (defaultTiles && s3.endsWith("<default>.png")) {
list.add(ConnectedTextures.SPRITE_DEFAULT);
} else {
ResourceLocation resourcelocation1 = new ResourceLocation(s1, s3);
boolean flag = Config.hasResource(resourcelocation1);
if (!flag) {
Config.warn("File not found: " + s3);
}
String s4 = "textures/";
String s5 = s2;
if (s2.startsWith(s4)) {
s5 = s2.substring(s4.length());
}
ResourceLocation resourcelocation2 = new ResourceLocation(s1, s5);
EaglerTextureAtlasSprite textureatlassprite = textureMap.registerSprite(resourcelocation2, baseName);
list.add(textureatlassprite);
}
}
EaglerTextureAtlasSprite[] atextureatlassprite = (EaglerTextureAtlasSprite[]) list
.toArray(new EaglerTextureAtlasSprite[list.size()]);
return atextureatlassprite;
}
}
public boolean matchesBlockId(int blockId) {
return Matches.blockId(blockId, this.matchBlocks);
}
public boolean matchesBlock(int blockId, int metadata) {
return !Matches.block(blockId, metadata, this.matchBlocks) ? false : Matches.metadata(metadata, this.metadatas);
}
public boolean matchesIcon(EaglerTextureAtlasSprite icon) {
return Matches.sprite(icon, this.matchTileIcons);
}
public String toString() {
return "CTM name: " + this.name + ", basePath: " + this.basePath + ", matchBlocks: "
+ Config.arrayToString((Object[]) this.matchBlocks) + ", matchTiles: "
+ Config.arrayToString((Object[]) this.matchTiles);
}
public boolean matchesBiome(BiomeGenBase biome) {
return Matches.biome(biome, this.biomes);
}
public int getMetadataMax() {
int i = -1;
i = this.getMax(this.metadatas, i);
if (this.matchBlocks != null) {
for (int j = 0; j < this.matchBlocks.length; ++j) {
MatchBlock matchblock = this.matchBlocks[j];
i = this.getMax(matchblock.getMetadatas(), i);
}
}
return i;
}
private int getMax(int[] mds, int max) {
if (mds == null) {
return max;
} else {
for (int i = 0; i < mds.length; ++i) {
int j = mds[i];
if (j > max) {
max = j;
}
}
return max;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,450 @@
package net.optifine;
import java.util.IdentityHashMap;
import java.util.Map;
import net.lax1dude.eaglercraft.v1_8.minecraft.EaglerTextureAtlasSprite;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.optifine.render.RenderEnv;
public class ConnectedTexturesCompact {
private static final int COMPACT_NONE = 0;
private static final int COMPACT_ALL = 1;
private static final int COMPACT_V = 2;
private static final int COMPACT_H = 3;
private static final int COMPACT_HV = 4;
public static BakedQuad[] getConnectedTextureCtmCompact(int ctmIndex, ConnectedProperties cp, int side,
BakedQuad quad, RenderEnv renderEnv) {
if (cp.ctmTileIndexes != null && ctmIndex >= 0 && ctmIndex < cp.ctmTileIndexes.length) {
int i = cp.ctmTileIndexes[ctmIndex];
if (i >= 0 && i <= cp.tileIcons.length) {
return getQuadsCompact(i, cp.tileIcons, quad, renderEnv);
}
}
switch (ctmIndex) {
case 1:
return getQuadsCompactH(0, 3, cp.tileIcons, side, quad, renderEnv);
case 2:
return getQuadsCompact(3, cp.tileIcons, quad, renderEnv);
case 3:
return getQuadsCompactH(3, 0, cp.tileIcons, side, quad, renderEnv);
case 4:
return getQuadsCompact4(0, 3, 2, 4, cp.tileIcons, side, quad, renderEnv);
case 5:
return getQuadsCompact4(3, 0, 4, 2, cp.tileIcons, side, quad, renderEnv);
case 6:
return getQuadsCompact4(2, 4, 2, 4, cp.tileIcons, side, quad, renderEnv);
case 7:
return getQuadsCompact4(3, 3, 4, 4, cp.tileIcons, side, quad, renderEnv);
case 8:
return getQuadsCompact4(4, 1, 4, 4, cp.tileIcons, side, quad, renderEnv);
case 9:
return getQuadsCompact4(4, 4, 4, 1, cp.tileIcons, side, quad, renderEnv);
case 10:
return getQuadsCompact4(1, 4, 1, 4, cp.tileIcons, side, quad, renderEnv);
case 11:
return getQuadsCompact4(1, 1, 4, 4, cp.tileIcons, side, quad, renderEnv);
case 12:
return getQuadsCompactV(0, 2, cp.tileIcons, side, quad, renderEnv);
case 13:
return getQuadsCompact4(0, 3, 2, 1, cp.tileIcons, side, quad, renderEnv);
case 14:
return getQuadsCompactV(3, 1, cp.tileIcons, side, quad, renderEnv);
case 15:
return getQuadsCompact4(3, 0, 1, 2, cp.tileIcons, side, quad, renderEnv);
case 16:
return getQuadsCompact4(2, 4, 0, 3, cp.tileIcons, side, quad, renderEnv);
case 17:
return getQuadsCompact4(4, 2, 3, 0, cp.tileIcons, side, quad, renderEnv);
case 18:
return getQuadsCompact4(4, 4, 3, 3, cp.tileIcons, side, quad, renderEnv);
case 19:
return getQuadsCompact4(4, 2, 4, 2, cp.tileIcons, side, quad, renderEnv);
case 20:
return getQuadsCompact4(1, 4, 4, 4, cp.tileIcons, side, quad, renderEnv);
case 21:
return getQuadsCompact4(4, 4, 1, 4, cp.tileIcons, side, quad, renderEnv);
case 22:
return getQuadsCompact4(4, 4, 1, 1, cp.tileIcons, side, quad, renderEnv);
case 23:
return getQuadsCompact4(4, 1, 4, 1, cp.tileIcons, side, quad, renderEnv);
case 24:
return getQuadsCompact(2, cp.tileIcons, quad, renderEnv);
case 25:
return getQuadsCompactH(2, 1, cp.tileIcons, side, quad, renderEnv);
case 26:
return getQuadsCompact(1, cp.tileIcons, quad, renderEnv);
case 27:
return getQuadsCompactH(1, 2, cp.tileIcons, side, quad, renderEnv);
case 28:
return getQuadsCompact4(2, 4, 2, 1, cp.tileIcons, side, quad, renderEnv);
case 29:
return getQuadsCompact4(3, 3, 1, 4, cp.tileIcons, side, quad, renderEnv);
case 30:
return getQuadsCompact4(2, 1, 2, 4, cp.tileIcons, side, quad, renderEnv);
case 31:
return getQuadsCompact4(3, 3, 4, 1, cp.tileIcons, side, quad, renderEnv);
case 32:
return getQuadsCompact4(1, 1, 1, 4, cp.tileIcons, side, quad, renderEnv);
case 33:
return getQuadsCompact4(1, 1, 4, 1, cp.tileIcons, side, quad, renderEnv);
case 34:
return getQuadsCompact4(4, 1, 1, 4, cp.tileIcons, side, quad, renderEnv);
case 35:
return getQuadsCompact4(1, 4, 4, 1, cp.tileIcons, side, quad, renderEnv);
case 36:
return getQuadsCompactV(2, 0, cp.tileIcons, side, quad, renderEnv);
case 37:
return getQuadsCompact4(2, 1, 0, 3, cp.tileIcons, side, quad, renderEnv);
case 38:
return getQuadsCompactV(1, 3, cp.tileIcons, side, quad, renderEnv);
case 39:
return getQuadsCompact4(1, 2, 3, 0, cp.tileIcons, side, quad, renderEnv);
case 40:
return getQuadsCompact4(4, 1, 3, 3, cp.tileIcons, side, quad, renderEnv);
case 41:
return getQuadsCompact4(1, 2, 4, 2, cp.tileIcons, side, quad, renderEnv);
case 42:
return getQuadsCompact4(1, 4, 3, 3, cp.tileIcons, side, quad, renderEnv);
case 43:
return getQuadsCompact4(4, 2, 1, 2, cp.tileIcons, side, quad, renderEnv);
case 44:
return getQuadsCompact4(1, 4, 1, 1, cp.tileIcons, side, quad, renderEnv);
case 45:
return getQuadsCompact4(4, 1, 1, 1, cp.tileIcons, side, quad, renderEnv);
case 46:
return getQuadsCompact(4, cp.tileIcons, quad, renderEnv);
default:
return getQuadsCompact(0, cp.tileIcons, quad, renderEnv);
}
}
private static BakedQuad[] getQuadsCompactH(int indexLeft, int indexRight, EaglerTextureAtlasSprite[] sprites,
int side, BakedQuad quad, RenderEnv renderEnv) {
return getQuadsCompact(ConnectedTexturesCompact.Dir.LEFT, indexLeft, ConnectedTexturesCompact.Dir.RIGHT,
indexRight, sprites, side, quad, renderEnv);
}
private static BakedQuad[] getQuadsCompactV(int indexUp, int indexDown, EaglerTextureAtlasSprite[] sprites,
int side, BakedQuad quad, RenderEnv renderEnv) {
return getQuadsCompact(ConnectedTexturesCompact.Dir.UP, indexUp, ConnectedTexturesCompact.Dir.DOWN, indexDown,
sprites, side, quad, renderEnv);
}
private static BakedQuad[] getQuadsCompact4(int upLeft, int upRight, int downLeft, int downRight,
EaglerTextureAtlasSprite[] sprites, int side, BakedQuad quad, RenderEnv renderEnv) {
return upLeft == upRight ? (downLeft == downRight
? getQuadsCompact(ConnectedTexturesCompact.Dir.UP, upLeft, ConnectedTexturesCompact.Dir.DOWN, downLeft,
sprites, side, quad, renderEnv)
: getQuadsCompact(ConnectedTexturesCompact.Dir.UP, upLeft, ConnectedTexturesCompact.Dir.DOWN_LEFT,
downLeft, ConnectedTexturesCompact.Dir.DOWN_RIGHT, downRight, sprites, side, quad, renderEnv))
: (downLeft == downRight
? getQuadsCompact(ConnectedTexturesCompact.Dir.UP_LEFT, upLeft,
ConnectedTexturesCompact.Dir.UP_RIGHT, upRight, ConnectedTexturesCompact.Dir.DOWN,
downLeft, sprites, side, quad, renderEnv)
: (upLeft == downLeft
? (upRight == downRight ? getQuadsCompact(ConnectedTexturesCompact.Dir.LEFT, upLeft,
ConnectedTexturesCompact.Dir.RIGHT, upRight, sprites, side, quad, renderEnv)
: getQuadsCompact(ConnectedTexturesCompact.Dir.LEFT, upLeft,
ConnectedTexturesCompact.Dir.UP_RIGHT, upRight,
ConnectedTexturesCompact.Dir.DOWN_RIGHT, downRight, sprites, side, quad,
renderEnv))
: (upRight == downRight ? getQuadsCompact(ConnectedTexturesCompact.Dir.UP_LEFT, upLeft,
ConnectedTexturesCompact.Dir.DOWN_LEFT, downLeft,
ConnectedTexturesCompact.Dir.RIGHT, upRight, sprites, side, quad, renderEnv)
: getQuadsCompact(ConnectedTexturesCompact.Dir.UP_LEFT, upLeft,
ConnectedTexturesCompact.Dir.UP_RIGHT, upRight,
ConnectedTexturesCompact.Dir.DOWN_LEFT, downLeft,
ConnectedTexturesCompact.Dir.DOWN_RIGHT, downRight, sprites, side, quad,
renderEnv))));
}
private static BakedQuad[] getQuadsCompact(int index, EaglerTextureAtlasSprite[] sprites, BakedQuad quad,
RenderEnv renderEnv) {
EaglerTextureAtlasSprite textureatlassprite = sprites[index];
return ConnectedTextures.getQuads(textureatlassprite, quad, renderEnv);
}
private static BakedQuad[] getQuadsCompact(ConnectedTexturesCompact.Dir dir1, int index1,
ConnectedTexturesCompact.Dir dir2, int index2, EaglerTextureAtlasSprite[] sprites, int side, BakedQuad quad,
RenderEnv renderEnv) {
BakedQuad bakedquad = getQuadCompact(sprites[index1], dir1, side, quad, renderEnv);
BakedQuad bakedquad1 = getQuadCompact(sprites[index2], dir2, side, quad, renderEnv);
return renderEnv.getArrayQuadsCtm(bakedquad, bakedquad1);
}
private static BakedQuad[] getQuadsCompact(ConnectedTexturesCompact.Dir dir1, int index1,
ConnectedTexturesCompact.Dir dir2, int index2, ConnectedTexturesCompact.Dir dir3, int index3,
EaglerTextureAtlasSprite[] sprites, int side, BakedQuad quad, RenderEnv renderEnv) {
BakedQuad bakedquad = getQuadCompact(sprites[index1], dir1, side, quad, renderEnv);
BakedQuad bakedquad1 = getQuadCompact(sprites[index2], dir2, side, quad, renderEnv);
BakedQuad bakedquad2 = getQuadCompact(sprites[index3], dir3, side, quad, renderEnv);
return renderEnv.getArrayQuadsCtm(bakedquad, bakedquad1, bakedquad2);
}
private static BakedQuad[] getQuadsCompact(ConnectedTexturesCompact.Dir dir1, int index1,
ConnectedTexturesCompact.Dir dir2, int index2, ConnectedTexturesCompact.Dir dir3, int index3,
ConnectedTexturesCompact.Dir dir4, int index4, EaglerTextureAtlasSprite[] sprites, int side, BakedQuad quad,
RenderEnv renderEnv) {
BakedQuad bakedquad = getQuadCompact(sprites[index1], dir1, side, quad, renderEnv);
BakedQuad bakedquad1 = getQuadCompact(sprites[index2], dir2, side, quad, renderEnv);
BakedQuad bakedquad2 = getQuadCompact(sprites[index3], dir3, side, quad, renderEnv);
BakedQuad bakedquad3 = getQuadCompact(sprites[index4], dir4, side, quad, renderEnv);
return renderEnv.getArrayQuadsCtm(bakedquad, bakedquad1, bakedquad2, bakedquad3);
}
private static BakedQuad getQuadCompact(EaglerTextureAtlasSprite sprite, ConnectedTexturesCompact.Dir dir, int side,
BakedQuad quad, RenderEnv renderEnv) {
switch (dir) {
case UP:
return getQuadCompact(sprite, dir, 0, 0, 16, 8, side, quad, renderEnv);
case UP_RIGHT:
return getQuadCompact(sprite, dir, 8, 0, 16, 8, side, quad, renderEnv);
case RIGHT:
return getQuadCompact(sprite, dir, 8, 0, 16, 16, side, quad, renderEnv);
case DOWN_RIGHT:
return getQuadCompact(sprite, dir, 8, 8, 16, 16, side, quad, renderEnv);
case DOWN:
return getQuadCompact(sprite, dir, 0, 8, 16, 16, side, quad, renderEnv);
case DOWN_LEFT:
return getQuadCompact(sprite, dir, 0, 8, 8, 16, side, quad, renderEnv);
case LEFT:
return getQuadCompact(sprite, dir, 0, 0, 8, 16, side, quad, renderEnv);
case UP_LEFT:
return getQuadCompact(sprite, dir, 0, 0, 8, 8, side, quad, renderEnv);
default:
return quad;
}
}
private static BakedQuad getQuadCompact(EaglerTextureAtlasSprite sprite, ConnectedTexturesCompact.Dir dir, int x1,
int y1, int x2, int y2, int side, BakedQuad quadIn, RenderEnv renderEnv) {
Map[][] amap = ConnectedTextures.getSpriteQuadCompactMaps();
if (amap == null) {
return quadIn;
} else {
int i = sprite.getIndexInMap();
if (i >= 0 && i < amap.length) {
Map[] amap1 = amap[i];
if (amap1 == null) {
amap1 = new Map[ConnectedTexturesCompact.Dir.VALUES.length];
amap[i] = amap1;
}
Map<BakedQuad, BakedQuad> map = amap1[dir.ordinal()];
if (map == null) {
map = new IdentityHashMap(1);
amap1[dir.ordinal()] = map;
}
BakedQuad bakedquad = (BakedQuad) map.get(quadIn);
if (bakedquad == null) {
bakedquad = makeSpriteQuadCompact(quadIn, sprite, side, x1, y1, x2, y2);
map.put(quadIn, bakedquad);
}
return bakedquad;
} else {
return quadIn;
}
}
}
private static BakedQuad makeSpriteQuadCompact(BakedQuad quad, EaglerTextureAtlasSprite sprite, int side, int x1,
int y1, int x2, int y2) {
int[] aint = (int[]) quad.getVertexData().clone();
int[] aint2 = (int[]) quad.getVertexDataWithNormals().clone();
EaglerTextureAtlasSprite textureatlassprite = quad.getSprite();
for (int i = 0; i < 4; ++i) {
fixVertexCompact(aint, aint2, i, textureatlassprite, sprite, side, x1, y1, x2, y2);
}
BakedQuad bakedquad = new BakedQuad(aint, aint2, quad.getTintIndex(), quad.getFace(), sprite);
return bakedquad;
}
private static void fixVertexCompact(int[] data, int[] data2, int vertex, EaglerTextureAtlasSprite spriteFrom,
EaglerTextureAtlasSprite spriteTo, int side, int x1, int y1, int x2, int y2) {
int i = data.length / 4;
int j = i * vertex;
int i2 = data2.length / 4;
int j2 = i2 * vertex;
float f = Float.intBitsToFloat(data[j + 4]);
float f1 = Float.intBitsToFloat(data[j + 4 + 1]);
double d0 = spriteFrom.getSpriteU16(f);
double d1 = spriteFrom.getSpriteV16(f1);
float f2 = Float.intBitsToFloat(data[j + 0]);
float f3 = Float.intBitsToFloat(data[j + 1]);
float f4 = Float.intBitsToFloat(data[j + 2]);
float f5;
float f6;
switch (side) {
case 0:
f5 = f2;
f6 = 1.0F - f4;
break;
case 1:
f5 = f2;
f6 = f4;
break;
case 2:
f5 = 1.0F - f2;
f6 = 1.0F - f3;
break;
case 3:
f5 = f2;
f6 = 1.0F - f3;
break;
case 4:
f5 = f4;
f6 = 1.0F - f3;
break;
case 5:
f5 = 1.0F - f4;
f6 = 1.0F - f3;
break;
default:
return;
}
float f7 = 15.968F;
float f8 = 15.968F;
if (d0 < (double) x1) {
f5 = (float) ((double) f5 + ((double) x1 - d0) / (double) f7);
d0 = (double) x1;
}
if (d0 > (double) x2) {
f5 = (float) ((double) f5 - (d0 - (double) x2) / (double) f7);
d0 = (double) x2;
}
if (d1 < (double) y1) {
f6 = (float) ((double) f6 + ((double) y1 - d1) / (double) f8);
d1 = (double) y1;
}
if (d1 > (double) y2) {
f6 = (float) ((double) f6 - (d1 - (double) y2) / (double) f8);
d1 = (double) y2;
}
switch (side) {
case 0:
f2 = f5;
f4 = 1.0F - f6;
break;
case 1:
f2 = f5;
f4 = f6;
break;
case 2:
f2 = 1.0F - f5;
f3 = 1.0F - f6;
break;
case 3:
f2 = f5;
f3 = 1.0F - f6;
break;
case 4:
f4 = f5;
f3 = 1.0F - f6;
break;
case 5:
f4 = 1.0F - f5;
f3 = 1.0F - f6;
break;
default:
return;
}
data[j + 4] = data2[j2 + 4] = Float.floatToRawIntBits(spriteTo.getInterpolatedU(d0));
data[j + 4 + 1] = data2[j2 + 4 + 1] = Float.floatToRawIntBits(spriteTo.getInterpolatedV(d1));
data[j + 0] = data2[j2 + 0] = Float.floatToRawIntBits(f2);
data[j + 1] = data2[j2 + 1] = Float.floatToRawIntBits(f3);
data[j + 2] = data2[j2 + 2] = Float.floatToRawIntBits(f4);
}
private static enum Dir {
UP, UP_RIGHT, RIGHT, DOWN_RIGHT, DOWN, DOWN_LEFT, LEFT, UP_LEFT;
public static final ConnectedTexturesCompact.Dir[] VALUES = values();
}
}

View File

@ -0,0 +1,972 @@
package net.optifine;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import net.lax1dude.eaglercraft.v1_8.internal.ITextureGL;
import net.lax1dude.eaglercraft.v1_8.minecraft.EaglerTextureAtlasSprite;
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.BlockPart;
import net.minecraft.client.renderer.block.model.BlockPartFace;
import net.minecraft.client.renderer.block.model.FaceBakery;
import net.minecraft.client.renderer.block.model.ItemModelGenerator;
import net.minecraft.client.renderer.block.model.ModelBlock;
import net.minecraft.client.renderer.texture.ITextureObject;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.resources.model.IBakedModel;
import net.minecraft.client.resources.model.ModelBakery;
import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.client.resources.model.ModelRotation;
import net.minecraft.client.resources.model.SimpleBakedModel;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemArmor;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.optifine.config.IParserInt;
import net.optifine.config.NbtTagValue;
import net.optifine.config.ParserEnchantmentId;
import net.optifine.config.RangeInt;
import net.optifine.config.RangeListInt;
import net.optifine.render.Blender;
import net.optifine.util.StrUtils;
import net.optifine.util.TextureUtils;
public class CustomItemProperties {
public String name = null;
public String basePath = null;
public int type = 1;
public int[] items = null;
public String texture = null;
public Map<String, String> mapTextures = null;
public String model = null;
public Map<String, String> mapModels = null;
public RangeListInt damage = null;
public boolean damagePercent = false;
public int damageMask = 0;
public RangeListInt stackSize = null;
public RangeListInt enchantmentIds = null;
public RangeListInt enchantmentLevels = null;
public NbtTagValue[] nbtTagValues = null;
public int hand = 0;
public int blend = 1;
public float speed = 0.0F;
public float rotation = 0.0F;
public int layer = 0;
public float duration = 1.0F;
public int weight = 0;
public ResourceLocation textureLocation = null;
public Map mapTextureLocations = null;
public EaglerTextureAtlasSprite sprite = null;
public Map mapSprites = null;
public IBakedModel bakedModelTexture = null;
public Map<String, IBakedModel> mapBakedModelsTexture = null;
public IBakedModel bakedModelFull = null;
public Map<String, IBakedModel> mapBakedModelsFull = null;
private int textureWidth = 0;
private int textureHeight = 0;
public static final int TYPE_UNKNOWN = 0;
public static final int TYPE_ITEM = 1;
public static final int TYPE_ENCHANTMENT = 2;
public static final int TYPE_ARMOR = 3;
public static final int HAND_ANY = 0;
public static final int HAND_MAIN = 1;
public static final int HAND_OFF = 2;
public static final String INVENTORY = "inventory";
public CustomItemProperties(Properties props, String path) {
this.name = parseName(path);
this.basePath = parseBasePath(path);
this.type = this.parseType(props.getProperty("type"));
this.items = this.parseItems(props.getProperty("items"), props.getProperty("matchItems"));
this.mapModels = parseModels(props, this.basePath);
this.model = parseModel(props.getProperty("model"), path, this.basePath, this.type, this.mapModels);
this.mapTextures = parseTextures(props, this.basePath);
boolean flag = this.mapModels == null && this.model == null;
this.texture = parseTexture(props.getProperty("texture"), props.getProperty("tile"),
props.getProperty("source"), path, this.basePath, this.type, this.mapTextures, flag);
String s = props.getProperty("damage");
if (s != null) {
this.damagePercent = s.contains("%");
s = s.replace("%", "");
this.damage = this.parseRangeListInt(s);
this.damageMask = this.parseInt(props.getProperty("damageMask"), 0);
}
this.stackSize = this.parseRangeListInt(props.getProperty("stackSize"));
this.enchantmentIds = this.parseRangeListInt(props.getProperty("enchantmentIDs"), new ParserEnchantmentId());
this.enchantmentLevels = this.parseRangeListInt(props.getProperty("enchantmentLevels"));
this.nbtTagValues = this.parseNbtTagValues(props);
this.hand = this.parseHand(props.getProperty("hand"));
this.blend = Blender.parseBlend(props.getProperty("blend"));
this.speed = this.parseFloat(props.getProperty("speed"), 0.0F);
this.rotation = this.parseFloat(props.getProperty("rotation"), 0.0F);
this.layer = this.parseInt(props.getProperty("layer"), 0);
this.weight = this.parseInt(props.getProperty("weight"), 0);
this.duration = this.parseFloat(props.getProperty("duration"), 1.0F);
}
private static String parseName(String path) {
String s = path;
int i = path.lastIndexOf(47);
if (i >= 0) {
s = path.substring(i + 1);
}
int j = s.lastIndexOf(46);
if (j >= 0) {
s = s.substring(0, j);
}
return s;
}
private static String parseBasePath(String path) {
int i = path.lastIndexOf(47);
return i < 0 ? "" : path.substring(0, i);
}
private int parseType(String str) {
if (str == null) {
return 1;
} else if (str.equals("item")) {
return 1;
} else if (str.equals("enchantment")) {
return 2;
} else if (str.equals("armor")) {
return 3;
} else {
Config.warn("Unknown method: " + str);
return 0;
}
}
private int[] parseItems(String str, String str2) {
if (str == null) {
str = str2;
}
if (str == null) {
return null;
} else {
str = str.trim();
Set set = new TreeSet();
String[] astring = Config.tokenize(str, " ");
label45:
for (int i = 0; i < astring.length; ++i) {
String s = astring[i];
int j = Config.parseInt(s, -1);
if (j >= 0) {
set.add(Integer.valueOf(j));
} else {
if (s.contains("-")) {
String[] astring1 = Config.tokenize(s, "-");
if (astring1.length == 2) {
int k = Config.parseInt(astring1[0], -1);
int l = Config.parseInt(astring1[1], -1);
if (k >= 0 && l >= 0) {
int i1 = Math.min(k, l);
int j1 = Math.max(k, l);
int k1 = i1;
while (true) {
if (k1 > j1) {
continue label45;
}
set.add(Integer.valueOf(k1));
++k1;
}
}
}
}
Item item = Item.getByNameOrId(s);
if (item == null) {
Config.warn("Item not found: " + s);
} else {
int i2 = Item.getIdFromItem(item);
if (i2 <= 0) {
Config.warn("Item not found: " + s);
} else {
set.add(Integer.valueOf(i2));
}
}
}
}
Integer[] ainteger = (Integer[]) ((Integer[]) set.toArray(new Integer[set.size()]));
int[] aint = new int[ainteger.length];
for (int l1 = 0; l1 < aint.length; ++l1) {
aint[l1] = ainteger[l1].intValue();
}
return aint;
}
}
private static String parseTexture(String texStr, String texStr2, String texStr3, String path, String basePath,
int type, Map<String, String> mapTexs, boolean textureFromPath) {
if (texStr == null) {
texStr = texStr2;
}
if (texStr == null) {
texStr = texStr3;
}
if (texStr != null) {
String s2 = ".png";
if (texStr.endsWith(s2)) {
texStr = texStr.substring(0, texStr.length() - s2.length());
}
texStr = fixTextureName(texStr, basePath);
return texStr;
} else if (type == 3) {
return null;
} else {
if (mapTexs != null) {
String s = (String) mapTexs.get("texture.bow_standby");
if (s != null) {
return s;
}
}
if (!textureFromPath) {
return null;
} else {
String s1 = path;
int i = path.lastIndexOf(47);
if (i >= 0) {
s1 = path.substring(i + 1);
}
int j = s1.lastIndexOf(46);
if (j >= 0) {
s1 = s1.substring(0, j);
}
s1 = fixTextureName(s1, basePath);
return s1;
}
}
}
private static Map parseTextures(Properties props, String basePath) {
String s = "texture.";
Map map = getMatchingProperties(props, s);
if (map.size() <= 0) {
return null;
} else {
Set set = map.keySet();
Map map1 = new LinkedHashMap();
for (Object e : set) {
String s1 = (String) e;
String s2 = (String) map.get(s1);
s2 = fixTextureName(s2, basePath);
map1.put(s1, s2);
}
return map1;
}
}
private static String fixTextureName(String iconName, String basePath) {
iconName = TextureUtils.fixResourcePath(iconName, basePath);
if (!iconName.startsWith(basePath) && !iconName.startsWith("textures/") && !iconName.startsWith("mcpatcher/")) {
iconName = basePath + "/" + iconName;
}
if (iconName.endsWith(".png")) {
iconName = iconName.substring(0, iconName.length() - 4);
}
if (iconName.startsWith("/")) {
iconName = iconName.substring(1);
}
return iconName;
}
private static String parseModel(String modelStr, String path, String basePath, int type,
Map<String, String> mapModelNames) {
if (modelStr != null) {
String s1 = ".json";
if (modelStr.endsWith(s1)) {
modelStr = modelStr.substring(0, modelStr.length() - s1.length());
}
modelStr = fixModelName(modelStr, basePath);
return modelStr;
} else if (type == 3) {
return null;
} else {
if (mapModelNames != null) {
String s = (String) mapModelNames.get("model.bow_standby");
if (s != null) {
return s;
}
}
return modelStr;
}
}
private static Map parseModels(Properties props, String basePath) {
String s = "model.";
Map map = getMatchingProperties(props, s);
if (map.size() <= 0) {
return null;
} else {
Set set = map.keySet();
Map map1 = new LinkedHashMap();
for (Object e : set) {
String s1 = (String) e;
String s2 = (String) map.get(s1);
s2 = fixModelName(s2, basePath);
map1.put(s1, s2);
}
return map1;
}
}
private static String fixModelName(String modelName, String basePath) {
modelName = TextureUtils.fixResourcePath(modelName, basePath);
boolean flag = modelName.startsWith("block/") || modelName.startsWith("item/");
if (!modelName.startsWith(basePath) && !flag && !modelName.startsWith("mcpatcher/")) {
modelName = basePath + "/" + modelName;
}
String s = ".json";
if (modelName.endsWith(s)) {
modelName = modelName.substring(0, modelName.length() - s.length());
}
if (modelName.startsWith("/")) {
modelName = modelName.substring(1);
}
return modelName;
}
private int parseInt(String str, int defVal) {
if (str == null) {
return defVal;
} else {
str = str.trim();
int i = Config.parseInt(str, Integer.MIN_VALUE);
if (i == Integer.MIN_VALUE) {
Config.warn("Invalid integer: " + str);
return defVal;
} else {
return i;
}
}
}
private float parseFloat(String str, float defVal) {
if (str == null) {
return defVal;
} else {
str = str.trim();
float f = Config.parseFloat(str, Float.MIN_VALUE);
if (f == Float.MIN_VALUE) {
Config.warn("Invalid float: " + str);
return defVal;
} else {
return f;
}
}
}
private RangeListInt parseRangeListInt(String str) {
return this.parseRangeListInt(str, (IParserInt) null);
}
private RangeListInt parseRangeListInt(String str, IParserInt parser) {
if (str == null) {
return null;
} else {
String[] astring = Config.tokenize(str, " ");
RangeListInt rangelistint = new RangeListInt();
for (int i = 0; i < astring.length; ++i) {
String s = astring[i];
if (parser != null) {
int j = parser.parse(s, Integer.MIN_VALUE);
if (j != Integer.MIN_VALUE) {
rangelistint.addRange(new RangeInt(j, j));
continue;
}
}
RangeInt rangeint = this.parseRangeInt(s);
if (rangeint == null) {
Config.warn("Invalid range list: " + str);
return null;
}
rangelistint.addRange(rangeint);
}
return rangelistint;
}
}
private RangeInt parseRangeInt(String str) {
if (str == null) {
return null;
} else {
str = str.trim();
int i = str.length() - str.replace("-", "").length();
if (i > 1) {
Config.warn("Invalid range: " + str);
return null;
} else {
String[] astring = Config.tokenize(str, "- ");
int[] aint = new int[astring.length];
for (int j = 0; j < astring.length; ++j) {
String s = astring[j];
int k = Config.parseInt(s, -1);
if (k < 0) {
Config.warn("Invalid range: " + str);
return null;
}
aint[j] = k;
}
if (aint.length == 1) {
int i1 = aint[0];
if (str.startsWith("-")) {
return new RangeInt(0, i1);
} else if (str.endsWith("-")) {
return new RangeInt(i1, 65535);
} else {
return new RangeInt(i1, i1);
}
} else if (aint.length == 2) {
int l = Math.min(aint[0], aint[1]);
int j1 = Math.max(aint[0], aint[1]);
return new RangeInt(l, j1);
} else {
Config.warn("Invalid range: " + str);
return null;
}
}
}
}
private NbtTagValue[] parseNbtTagValues(Properties props) {
String s = "nbt.";
Map map = getMatchingProperties(props, s);
if (map.size() <= 0) {
return null;
} else {
List list = new ArrayList();
for (Object e : map.keySet()) {
String s1 = (String) e;
String s2 = (String) map.get(s1);
String s3 = s1.substring(s.length());
NbtTagValue nbttagvalue = new NbtTagValue(s3, s2);
list.add(nbttagvalue);
}
NbtTagValue[] anbttagvalue = (NbtTagValue[]) ((NbtTagValue[]) list.toArray(new NbtTagValue[list.size()]));
return anbttagvalue;
}
}
private static Map getMatchingProperties(Properties props, String keyPrefix) {
Map map = new LinkedHashMap();
for (Object e : props.keySet()) {
String s = (String) e;
String s1 = props.getProperty(s);
if (s.startsWith(keyPrefix)) {
map.put(s, s1);
}
}
return map;
}
private int parseHand(String str) {
if (str == null) {
return 0;
} else {
str = str.toLowerCase();
if (str.equals("any")) {
return 0;
} else if (str.equals("main")) {
return 1;
} else if (str.equals("off")) {
return 2;
} else {
Config.warn("Invalid hand: " + str);
return 0;
}
}
}
public boolean isValid(String path) {
if (this.name != null && this.name.length() > 0) {
if (this.basePath == null) {
Config.warn("No base path found: " + path);
return false;
} else if (this.type == 0) {
Config.warn("No type defined: " + path);
return false;
} else {
if (this.type == 1 || this.type == 3) {
if (this.items == null) {
this.items = this.detectItems();
}
if (this.items == null) {
Config.warn("No items defined: " + path);
return false;
}
}
if (this.texture == null && this.mapTextures == null && this.model == null && this.mapModels == null) {
Config.warn("No texture or model specified: " + path);
return false;
} else if (this.type == 2 && this.enchantmentIds == null) {
Config.warn("No enchantmentIDs specified: " + path);
return false;
} else {
return true;
}
}
} else {
Config.warn("No name found: " + path);
return false;
}
}
private int[] detectItems() {
Item item = Item.getByNameOrId(this.name);
if (item == null) {
return null;
} else {
int i = Item.getIdFromItem(item);
return i <= 0 ? null : new int[] { i };
}
}
public void updateIcons(TextureMap textureMap) {
if (this.texture != null) {
this.textureLocation = this.getTextureLocation(this.texture);
if (this.type == 1) {
ResourceLocation resourcelocation = this.getSpriteLocation(this.textureLocation);
this.sprite = textureMap.registerSprite(resourcelocation);
}
}
if (this.mapTextures != null) {
this.mapTextureLocations = new HashMap();
this.mapSprites = new HashMap();
for (String s : this.mapTextures.keySet()) {
String s1 = (String) this.mapTextures.get(s);
ResourceLocation resourcelocation1 = this.getTextureLocation(s1);
this.mapTextureLocations.put(s, resourcelocation1);
if (this.type == 1) {
ResourceLocation resourcelocation2 = this.getSpriteLocation(resourcelocation1);
EaglerTextureAtlasSprite textureatlassprite = textureMap.registerSprite(resourcelocation2);
this.mapSprites.put(s, textureatlassprite);
}
}
}
}
private ResourceLocation getTextureLocation(String texName) {
if (texName == null) {
return null;
} else {
ResourceLocation resourcelocation = new ResourceLocation(texName);
String s = resourcelocation.getResourceDomain();
String s1 = resourcelocation.getResourcePath();
if (!s1.contains("/")) {
s1 = "textures/items/" + s1;
}
String s2 = s1 + ".png";
ResourceLocation resourcelocation1 = new ResourceLocation(s, s2);
boolean flag = Config.hasResource(resourcelocation1);
if (!flag) {
Config.warn("File not found: " + s2);
}
return resourcelocation1;
}
}
private ResourceLocation getSpriteLocation(ResourceLocation resLoc) {
String s = resLoc.getResourcePath();
s = StrUtils.removePrefix(s, "textures/");
s = StrUtils.removeSuffix(s, ".png");
ResourceLocation resourcelocation = new ResourceLocation(resLoc.getResourceDomain(), s);
return resourcelocation;
}
public void updateModelTexture(TextureMap textureMap, ItemModelGenerator itemModelGenerator) {
if (this.texture != null || this.mapTextures != null) {
String[] astring = this.getModelTextures();
boolean flag = this.isUseTint();
this.bakedModelTexture = makeBakedModel(textureMap, itemModelGenerator, astring, flag);
if (this.type == 1 && this.mapTextures != null) {
for (String s : this.mapTextures.keySet()) {
String s1 = (String) this.mapTextures.get(s);
String s2 = StrUtils.removePrefix(s, "texture.");
if (s2.startsWith("bow") || s2.startsWith("fishing_rod") || s2.startsWith("shield")) {
String[] astring1 = new String[] { s1 };
IBakedModel ibakedmodel = makeBakedModel(textureMap, itemModelGenerator, astring1, flag);
if (this.mapBakedModelsTexture == null) {
this.mapBakedModelsTexture = new HashMap();
}
this.mapBakedModelsTexture.put(s2, ibakedmodel);
}
}
}
}
}
private boolean isUseTint() {
return true;
}
private static IBakedModel makeBakedModel(TextureMap textureMap, ItemModelGenerator itemModelGenerator,
String[] textures, boolean useTint) {
String[] astring = new String[textures.length];
for (int i = 0; i < astring.length; ++i) {
String s = textures[i];
astring[i] = StrUtils.removePrefix(s, "textures/");
}
ModelBlock modelblock = makeModelBlock(astring);
ModelBlock modelblock1 = itemModelGenerator.makeItemModel(textureMap, modelblock);
IBakedModel ibakedmodel = bakeModel(textureMap, modelblock1, useTint);
return ibakedmodel;
}
private String[] getModelTextures() {
if (this.type == 1 && this.items.length == 1) {
Item item = Item.getItemById(this.items[0]);
if (item == Items.potionitem && this.damage != null && this.damage.getCountRanges() > 0) {
RangeInt rangeint = this.damage.getRange(0);
int i = rangeint.getMin();
boolean flag = (i & 16384) != 0;
String s5 = this.getMapTexture(this.mapTextures, "texture.potion_overlay", "items/potion_overlay");
String s6 = null;
if (flag) {
s6 = this.getMapTexture(this.mapTextures, "texture.potion_bottle_splash",
"items/potion_bottle_splash");
} else {
s6 = this.getMapTexture(this.mapTextures, "texture.potion_bottle_drinkable",
"items/potion_bottle_drinkable");
}
return new String[] { s5, s6 };
}
if (item instanceof ItemArmor) {
ItemArmor itemarmor = (ItemArmor) item;
if (itemarmor.getArmorMaterial() == ItemArmor.ArmorMaterial.LEATHER) {
String s = "leather";
String s1 = "helmet";
if (itemarmor.armorType == 0) {
s1 = "helmet";
}
if (itemarmor.armorType == 1) {
s1 = "chestplate";
}
if (itemarmor.armorType == 2) {
s1 = "leggings";
}
if (itemarmor.armorType == 3) {
s1 = "boots";
}
String s2 = s + "_" + s1;
String s3 = this.getMapTexture(this.mapTextures, "texture." + s2, "items/" + s2);
String s4 = this.getMapTexture(this.mapTextures, "texture." + s2 + "_overlay",
"items/" + s2 + "_overlay");
return new String[] { s3, s4 };
}
}
}
return new String[] { this.texture };
}
private String getMapTexture(Map<String, String> map, String key, String def) {
if (map == null) {
return def;
} else {
String s = (String) map.get(key);
return s == null ? def : s;
}
}
private static ModelBlock makeModelBlock(String[] modelTextures) {
StringBuffer stringbuffer = new StringBuffer();
stringbuffer.append("{\"parent\": \"builtin/generated\",\"textures\": {");
for (int i = 0; i < modelTextures.length; ++i) {
String s = modelTextures[i];
if (i > 0) {
stringbuffer.append(", ");
}
stringbuffer.append("\"layer" + i + "\": \"" + s + "\"");
}
stringbuffer.append("}}");
String s1 = stringbuffer.toString();
ModelBlock modelblock = ModelBlock.deserialize(s1);
return modelblock;
}
private static IBakedModel bakeModel(TextureMap textureMap, ModelBlock modelBlockIn, boolean useTint) {
ModelRotation modelrotation = ModelRotation.X0_Y0;
boolean flag = false;
String s = modelBlockIn.resolveTextureName("particle");
EaglerTextureAtlasSprite textureatlassprite = textureMap.getAtlasSprite((new ResourceLocation(s)).toString());
SimpleBakedModel.Builder simplebakedmodel$builder = (new SimpleBakedModel.Builder(modelBlockIn))
.setTexture(textureatlassprite);
for (BlockPart blockpart : modelBlockIn.getElements()) {
for (EnumFacing enumfacing : blockpart.mapFaces.keySet()) {
BlockPartFace blockpartface = (BlockPartFace) blockpart.mapFaces.get(enumfacing);
if (!useTint) {
blockpartface = new BlockPartFace(blockpartface.cullFace, -1, blockpartface.texture,
blockpartface.blockFaceUV);
}
String s1 = modelBlockIn.resolveTextureName(blockpartface.texture);
EaglerTextureAtlasSprite textureatlassprite1 = textureMap
.getAtlasSprite((new ResourceLocation(s1)).toString());
BakedQuad bakedquad = makeBakedQuad(blockpart, blockpartface, textureatlassprite1, enumfacing,
modelrotation, flag);
if (blockpartface.cullFace == null) {
simplebakedmodel$builder.addGeneralQuad(bakedquad);
} else {
simplebakedmodel$builder.addFaceQuad(modelrotation.rotateFace(blockpartface.cullFace), bakedquad);
}
}
}
return simplebakedmodel$builder.makeBakedModel();
}
private static BakedQuad makeBakedQuad(BlockPart blockPart, BlockPartFace blockPartFace,
EaglerTextureAtlasSprite textureAtlasSprite, EnumFacing enumFacing, ModelRotation modelRotation,
boolean uvLocked) {
FaceBakery facebakery = new FaceBakery();
return facebakery.makeBakedQuad(blockPart.positionFrom, blockPart.positionTo, blockPartFace, textureAtlasSprite,
enumFacing, modelRotation, blockPart.partRotation, uvLocked, blockPart.shade);
}
public String toString() {
return "" + this.basePath + "/" + this.name + ", type: " + this.type + ", items: ["
+ Config.arrayToString(this.items) + "], textture: " + this.texture;
}
public float getTextureWidth(TextureManager textureManager) {
if (this.textureWidth <= 0) {
if (this.textureLocation != null) {
ITextureObject itextureobject = textureManager.getTexture(this.textureLocation);
ITextureGL nativeTex = EaglercraftGPU.getNativeTexture(itextureobject.getGlTextureId());
this.textureWidth = nativeTex != null ? nativeTex.getWidth() : 0;
}
if (this.textureWidth <= 0) {
this.textureWidth = 16;
}
}
return (float) this.textureWidth;
}
public float getTextureHeight(TextureManager textureManager) {
if (this.textureHeight <= 0) {
if (this.textureLocation != null) {
ITextureObject itextureobject = textureManager.getTexture(this.textureLocation);
ITextureGL nativeTex = EaglercraftGPU.getNativeTexture(itextureobject.getGlTextureId());
this.textureHeight = nativeTex != null ? nativeTex.getWidth() : 0;
}
if (this.textureHeight <= 0) {
this.textureHeight = 16;
}
}
return (float) this.textureHeight;
}
public IBakedModel getBakedModel(ResourceLocation modelLocation, boolean fullModel) {
IBakedModel ibakedmodel;
Map<String, IBakedModel> map;
if (fullModel) {
ibakedmodel = this.bakedModelFull;
map = this.mapBakedModelsFull;
} else {
ibakedmodel = this.bakedModelTexture;
map = this.mapBakedModelsTexture;
}
if (modelLocation != null && map != null) {
String s = modelLocation.getResourcePath();
IBakedModel ibakedmodel1 = (IBakedModel) map.get(s);
if (ibakedmodel1 != null) {
return ibakedmodel1;
}
}
return ibakedmodel;
}
public void loadModels(ModelBakery modelBakery) {
if (this.model != null) {
loadItemModel(modelBakery, this.model);
}
if (this.type == 1 && this.mapModels != null) {
for (String s : this.mapModels.keySet()) {
String s1 = (String) this.mapModels.get(s);
String s2 = StrUtils.removePrefix(s, "model.");
if (s2.startsWith("bow") || s2.startsWith("fishing_rod") || s2.startsWith("shield")) {
loadItemModel(modelBakery, s1);
}
}
}
}
public void updateModelsFull() {
ModelManager modelmanager = Minecraft.getMinecraft().getModelManager();
IBakedModel ibakedmodel = modelmanager.getMissingModel();
if (this.model != null) {
ResourceLocation resourcelocation = getModelLocation(this.model);
ModelResourceLocation modelresourcelocation = new ModelResourceLocation(resourcelocation, "inventory");
this.bakedModelFull = modelmanager.getModel(modelresourcelocation);
if (this.bakedModelFull == ibakedmodel) {
Config.warn("Custom Items: Model not found " + modelresourcelocation.getResourcePath());
this.bakedModelFull = null;
}
}
if (this.type == 1 && this.mapModels != null) {
for (String s : this.mapModels.keySet()) {
String s1 = (String) this.mapModels.get(s);
String s2 = StrUtils.removePrefix(s, "model.");
if (s2.startsWith("bow") || s2.startsWith("fishing_rod") || s2.startsWith("shield")) {
ResourceLocation resourcelocation1 = getModelLocation(s1);
ModelResourceLocation modelresourcelocation1 = new ModelResourceLocation(resourcelocation1,
"inventory");
IBakedModel ibakedmodel1 = modelmanager.getModel(modelresourcelocation1);
if (ibakedmodel1 == ibakedmodel) {
Config.warn("Custom Items: Model not found " + modelresourcelocation1.getResourcePath());
} else {
if (this.mapBakedModelsFull == null) {
this.mapBakedModelsFull = new HashMap();
}
this.mapBakedModelsFull.put(s2, ibakedmodel1);
}
}
}
}
}
private static void loadItemModel(ModelBakery modelBakery, String model) {
ResourceLocation resourcelocation = getModelLocation(model);
ModelResourceLocation modelresourcelocation = new ModelResourceLocation(resourcelocation, "inventory");
modelBakery.loadItemModel(resourcelocation.toString(), modelresourcelocation, resourcelocation);
}
private static ResourceLocation getModelLocation(String modelName) {
// return Reflector.ModelLoader.exists() && !modelName.startsWith("mcpatcher/")
// && !modelName.startsWith("optifine/") ? new ResourceLocation("models/" + modelName)
// : new ResourceLocation(modelName);
return new ResourceLocation(modelName);
}
}

View File

@ -0,0 +1,840 @@
package net.optifine;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.renderer.block.model.ItemModelGenerator;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.resources.IResourcePack;
import net.minecraft.client.resources.model.IBakedModel;
import net.minecraft.client.resources.model.ModelBakery;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.potion.Potion;
import net.minecraft.util.ResourceLocation;
import net.optifine.config.NbtTagValue;
import net.optifine.render.Blender;
import net.optifine.util.PropertiesOrdered;
import net.optifine.util.ResUtils;
import net.optifine.util.StrUtils;
public class CustomItems {
private static CustomItemProperties[][] itemProperties = (CustomItemProperties[][]) null;
private static CustomItemProperties[][] enchantmentProperties = (CustomItemProperties[][]) null;
private static Map mapPotionIds = null;
private static ItemModelGenerator itemModelGenerator = new ItemModelGenerator();
private static boolean useGlint = true;
private static boolean renderOffHand = false;
public static final int MASK_POTION_SPLASH = 16384;
public static final int MASK_POTION_NAME = 63;
public static final int MASK_POTION_EXTENDED = 64;
public static final String KEY_TEXTURE_OVERLAY = "texture.potion_overlay";
public static final String KEY_TEXTURE_SPLASH = "texture.potion_bottle_splash";
public static final String KEY_TEXTURE_DRINKABLE = "texture.potion_bottle_drinkable";
public static final String DEFAULT_TEXTURE_OVERLAY = "items/potion_overlay";
public static final String DEFAULT_TEXTURE_SPLASH = "items/potion_bottle_splash";
public static final String DEFAULT_TEXTURE_DRINKABLE = "items/potion_bottle_drinkable";
private static final int[][] EMPTY_INT2_ARRAY = new int[0][];
private static final String TYPE_POTION_NORMAL = "normal";
private static final String TYPE_POTION_SPLASH = "splash";
private static final String TYPE_POTION_LINGER = "linger";
public static void update() {
itemProperties = (CustomItemProperties[][]) null;
enchantmentProperties = (CustomItemProperties[][]) null;
useGlint = true;
if (Config.isCustomItems()) {
readCitProperties("mcpatcher/cit.properties");
IResourcePack[] airesourcepack = Config.getResourcePacks();
for (int i = airesourcepack.length - 1; i >= 0; --i) {
IResourcePack iresourcepack = airesourcepack[i];
update(iresourcepack);
}
update(Minecraft.getMinecraft().getDefaultResourcePack());
if (itemProperties.length <= 0) {
itemProperties = (CustomItemProperties[][]) null;
}
if (enchantmentProperties.length <= 0) {
enchantmentProperties = (CustomItemProperties[][]) null;
}
}
}
private static void readCitProperties(String fileName) {
ResourceLocation resourcelocation = new ResourceLocation(fileName);
try (InputStream inputstream = Minecraft.getMinecraft().getResourceManager().getResource(resourcelocation)
.getInputStream()) {
Config.dbg("CustomItems: Loading " + fileName);
Properties properties = new PropertiesOrdered();
properties.load(inputstream);
inputstream.close();
useGlint = Config.parseBoolean(properties.getProperty("useGlint"), true);
} catch (FileNotFoundException var4) {
return;
} catch (IOException ioexception) {
ioexception.printStackTrace();
}
}
private static void update(IResourcePack rp) {
List<String> astring = ResUtils.collectPropertyFiles(rp, "mcpatcher/cit/", "optifine/cit/");
Map map = makeAutoImageProperties(rp);
if (map.size() > 0) {
astring.addAll(map.keySet());
}
Collections.sort(astring);
List list = makePropertyList(itemProperties);
List list1 = makePropertyList(enchantmentProperties);
for (int i = 0; i < astring.size(); ++i) {
String s = astring.get(i);
Config.dbg("CustomItems: " + s);
try {
CustomItemProperties customitemproperties = null;
if (map.containsKey(s)) {
customitemproperties = (CustomItemProperties) map.get(s);
}
if (customitemproperties == null) {
ResourceLocation resourcelocation = new ResourceLocation(s);
InputStream inputstream = rp.getInputStream(resourcelocation);
if (inputstream == null) {
Config.warn("CustomItems file not found: " + s);
continue;
}
Properties properties = new PropertiesOrdered();
properties.load(inputstream);
inputstream.close();
customitemproperties = new CustomItemProperties(properties, s);
}
if (customitemproperties.isValid(s)) {
addToItemList(customitemproperties, list);
addToEnchantmentList(customitemproperties, list1);
}
} catch (FileNotFoundException var11) {
Config.warn("CustomItems file not found: " + s);
} catch (Exception exception) {
exception.printStackTrace();
}
}
itemProperties = propertyListToArray(list);
enchantmentProperties = propertyListToArray(list1);
Comparator comparator = getPropertiesComparator();
for (int j = 0; j < itemProperties.length; ++j) {
CustomItemProperties[] acustomitemproperties = itemProperties[j];
if (acustomitemproperties != null) {
Arrays.sort(acustomitemproperties, comparator);
}
}
for (int k = 0; k < enchantmentProperties.length; ++k) {
CustomItemProperties[] acustomitemproperties1 = enchantmentProperties[k];
if (acustomitemproperties1 != null) {
Arrays.sort(acustomitemproperties1, comparator);
}
}
}
private static Comparator getPropertiesComparator() {
Comparator comparator = new Comparator() {
public int compare(Object o1, Object o2) {
CustomItemProperties customitemproperties = (CustomItemProperties) o1;
CustomItemProperties customitemproperties1 = (CustomItemProperties) o2;
return customitemproperties.layer != customitemproperties1.layer
? customitemproperties.layer - customitemproperties1.layer
: (customitemproperties.weight != customitemproperties1.weight
? customitemproperties1.weight - customitemproperties.weight
: (!customitemproperties.basePath.equals(customitemproperties1.basePath)
? customitemproperties.basePath.compareTo(customitemproperties1.basePath)
: customitemproperties.name.compareTo(customitemproperties1.name)));
}
};
return comparator;
}
public static void updateIcons(TextureMap textureMap) {
for (CustomItemProperties customitemproperties : getAllProperties()) {
customitemproperties.updateIcons(textureMap);
}
}
public static void loadModels(ModelBakery modelBakery) {
for (CustomItemProperties customitemproperties : getAllProperties()) {
customitemproperties.loadModels(modelBakery);
}
}
public static void updateModels() {
for (CustomItemProperties customitemproperties : getAllProperties()) {
if (customitemproperties.type == 1) {
TextureMap texturemap = Minecraft.getMinecraft().getTextureMapBlocks();
customitemproperties.updateModelTexture(texturemap, itemModelGenerator);
customitemproperties.updateModelsFull();
}
}
}
private static List<CustomItemProperties> getAllProperties() {
List<CustomItemProperties> list = new ArrayList();
addAll(itemProperties, list);
addAll(enchantmentProperties, list);
return list;
}
private static void addAll(CustomItemProperties[][] cipsArr, List<CustomItemProperties> list) {
if (cipsArr != null) {
for (int i = 0; i < cipsArr.length; ++i) {
CustomItemProperties[] acustomitemproperties = cipsArr[i];
if (acustomitemproperties != null) {
for (int j = 0; j < acustomitemproperties.length; ++j) {
CustomItemProperties customitemproperties = acustomitemproperties[j];
if (customitemproperties != null) {
list.add(customitemproperties);
}
}
}
}
}
}
private static Map makeAutoImageProperties(IResourcePack rp) {
Map map = new HashMap();
map.putAll(makePotionImageProperties(rp, "normal", Item.getIdFromItem(Items.potionitem)));
map.putAll(makePotionImageProperties(rp, "splash", Item.getIdFromItem(Items.potionitem)));
map.putAll(makePotionImageProperties(rp, "linger", Item.getIdFromItem(Items.potionitem)));
return map;
}
private static Map makePotionImageProperties(IResourcePack rp, String type, int itemId) {
Map map = new HashMap();
String s = type + "/";
String[] astring = new String[] { "mcpatcher/cit/potion/" + s, "mcpatcher/cit/Potion/" + s, "optifine/cit/potion/" + s };
String[] astring1 = new String[] { ".png" };
Collection<String> astring2 = ResUtils.collectPotionFiles(rp, astring);
for (String s1 : astring2) {
String name = StrUtils.removePrefixSuffix(s1, astring, astring1);
Properties properties = makePotionProperties(name, type, itemId, s1);
if (properties != null) {
String s3 = StrUtils.removeSuffix(s1, astring1) + ".properties";
CustomItemProperties customitemproperties = new CustomItemProperties(properties, s3);
map.put(s3, customitemproperties);
}
}
return map;
}
private static Properties makePotionProperties(String name, String type, int itemId, String path) {
if (StrUtils.endsWith(name, new String[] { "_n", "_s" })) {
return null;
} else if (name.equals("empty") && type.equals("normal")) {
itemId = Item.getIdFromItem(Items.glass_bottle);
Properties properties = new PropertiesOrdered();
properties.put("type", "item");
properties.put("items", "" + itemId);
return properties;
} else {
int[] aint = (int[]) ((int[]) getMapPotionIds().get(name));
if (aint == null) {
Config.warn("Potion not found for image: " + path);
return null;
} else {
StringBuffer stringbuffer = new StringBuffer();
for (int i = 0; i < aint.length; ++i) {
int j = aint[i];
if (type.equals("splash")) {
j |= 16384;
}
if (i > 0) {
stringbuffer.append(" ");
}
stringbuffer.append(j);
}
int k = 16447;
if (name.equals("water") || name.equals("mundane")) {
k |= 64;
}
Properties properties1 = new PropertiesOrdered();
properties1.put("type", "item");
properties1.put("items", "" + itemId);
properties1.put("damage", "" + stringbuffer.toString());
properties1.put("damageMask", "" + k);
if (type.equals("splash")) {
properties1.put("texture.potion_bottle_splash", name);
} else {
properties1.put("texture.potion_bottle_drinkable", name);
}
return properties1;
}
}
}
private static Map getMapPotionIds() {
if (mapPotionIds == null) {
mapPotionIds = new LinkedHashMap();
mapPotionIds.put("water", getPotionId(0, 0));
mapPotionIds.put("awkward", getPotionId(0, 1));
mapPotionIds.put("thick", getPotionId(0, 2));
mapPotionIds.put("potent", getPotionId(0, 3));
mapPotionIds.put("regeneration", getPotionIds(1));
mapPotionIds.put("movespeed", getPotionIds(2));
mapPotionIds.put("fireresistance", getPotionIds(3));
mapPotionIds.put("poison", getPotionIds(4));
mapPotionIds.put("heal", getPotionIds(5));
mapPotionIds.put("nightvision", getPotionIds(6));
mapPotionIds.put("clear", getPotionId(7, 0));
mapPotionIds.put("bungling", getPotionId(7, 1));
mapPotionIds.put("charming", getPotionId(7, 2));
mapPotionIds.put("rank", getPotionId(7, 3));
mapPotionIds.put("weakness", getPotionIds(8));
mapPotionIds.put("damageboost", getPotionIds(9));
mapPotionIds.put("moveslowdown", getPotionIds(10));
mapPotionIds.put("leaping", getPotionIds(11));
mapPotionIds.put("harm", getPotionIds(12));
mapPotionIds.put("waterbreathing", getPotionIds(13));
mapPotionIds.put("invisibility", getPotionIds(14));
mapPotionIds.put("thin", getPotionId(15, 0));
mapPotionIds.put("debonair", getPotionId(15, 1));
mapPotionIds.put("sparkling", getPotionId(15, 2));
mapPotionIds.put("stinky", getPotionId(15, 3));
mapPotionIds.put("mundane", getPotionId(0, 4));
mapPotionIds.put("speed", mapPotionIds.get("movespeed"));
mapPotionIds.put("fire_resistance", mapPotionIds.get("fireresistance"));
mapPotionIds.put("instant_health", mapPotionIds.get("heal"));
mapPotionIds.put("night_vision", mapPotionIds.get("nightvision"));
mapPotionIds.put("strength", mapPotionIds.get("damageboost"));
mapPotionIds.put("slowness", mapPotionIds.get("moveslowdown"));
mapPotionIds.put("instant_damage", mapPotionIds.get("harm"));
mapPotionIds.put("water_breathing", mapPotionIds.get("waterbreathing"));
}
return mapPotionIds;
}
private static int[] getPotionIds(int baseId) {
return new int[] { baseId, baseId + 16, baseId + 32, baseId + 48 };
}
private static int[] getPotionId(int baseId, int subId) {
return new int[] { baseId + subId * 16 };
}
private static int getPotionNameDamage(String name) {
String s = "potion." + name;
Potion[] apotion = Potion.potionTypes;
for (int i = 0; i < apotion.length; ++i) {
Potion potion = apotion[i];
if (potion != null) {
String s1 = potion.getName();
if (s.equals(s1)) {
return potion.getId();
}
}
}
return -1;
}
private static List makePropertyList(CustomItemProperties[][] propsArr) {
List list = new ArrayList();
if (propsArr != null) {
for (int i = 0; i < propsArr.length; ++i) {
CustomItemProperties[] acustomitemproperties = propsArr[i];
List list1 = null;
if (acustomitemproperties != null) {
list1 = new ArrayList(Arrays.asList(acustomitemproperties));
}
list.add(list1);
}
}
return list;
}
private static CustomItemProperties[][] propertyListToArray(List list) {
CustomItemProperties[][] acustomitemproperties = new CustomItemProperties[list.size()][];
for (int i = 0; i < list.size(); ++i) {
List list1 = (List) list.get(i);
if (list1 != null) {
CustomItemProperties[] acustomitemproperties1 = (CustomItemProperties[]) ((CustomItemProperties[]) list1
.toArray(new CustomItemProperties[list1.size()]));
Arrays.sort(acustomitemproperties1, new CustomItemsComparator());
acustomitemproperties[i] = acustomitemproperties1;
}
}
return acustomitemproperties;
}
private static void addToItemList(CustomItemProperties cp, List itemList) {
if (cp.items != null) {
for (int i = 0; i < cp.items.length; ++i) {
int j = cp.items[i];
if (j <= 0) {
Config.warn("Invalid item ID: " + j);
} else {
addToList(cp, itemList, j);
}
}
}
}
private static void addToEnchantmentList(CustomItemProperties cp, List enchantmentList) {
if (cp.type == 2) {
if (cp.enchantmentIds != null) {
for (int i = 0; i < 256; ++i) {
if (cp.enchantmentIds.isInRange(i)) {
addToList(cp, enchantmentList, i);
}
}
}
}
}
private static void addToList(CustomItemProperties cp, List list, int id) {
while (id >= list.size()) {
list.add(null);
}
List list1 = (List) list.get(id);
if (list1 == null) {
list1 = new ArrayList();
list.set(id, list1);
}
list1.add(cp);
}
public static IBakedModel getCustomItemModel(ItemStack itemStack, IBakedModel model, ResourceLocation modelLocation,
boolean fullModel) {
if (!fullModel && model.isGui3d()) {
return model;
} else if (itemProperties == null) {
return model;
} else {
CustomItemProperties customitemproperties = getCustomItemProperties(itemStack, 1);
if (customitemproperties == null) {
return model;
} else {
IBakedModel ibakedmodel = customitemproperties.getBakedModel(modelLocation, fullModel);
return ibakedmodel != null ? ibakedmodel : model;
}
}
}
public static boolean bindCustomArmorTexture(ItemStack itemStack, int layer, String overlay) {
if (itemProperties == null) {
return false;
} else {
ResourceLocation resourcelocation = getCustomArmorLocation(itemStack, layer, overlay);
if (resourcelocation == null) {
return false;
} else {
Minecraft.getMinecraft().getTextureManager().bindTexture(resourcelocation);
return true;
}
}
}
private static ResourceLocation getCustomArmorLocation(ItemStack itemStack, int layer, String overlay) {
CustomItemProperties customitemproperties = getCustomItemProperties(itemStack, 3);
if (customitemproperties == null) {
return null;
} else if (customitemproperties.mapTextureLocations == null) {
return customitemproperties.textureLocation;
} else {
Item item = itemStack.getItem();
if (!(item instanceof ItemArmor)) {
return null;
} else {
ItemArmor itemarmor = (ItemArmor) item;
String s = itemarmor.getArmorMaterial().getName();
StringBuffer stringbuffer = new StringBuffer();
stringbuffer.append("texture.");
stringbuffer.append(s);
stringbuffer.append("_layer_");
stringbuffer.append(layer);
if (overlay != null) {
stringbuffer.append("_");
stringbuffer.append(overlay);
}
String s1 = stringbuffer.toString();
ResourceLocation resourcelocation = (ResourceLocation) customitemproperties.mapTextureLocations.get(s1);
return resourcelocation == null ? customitemproperties.textureLocation : resourcelocation;
}
}
}
private static CustomItemProperties getCustomItemProperties(ItemStack itemStack, int type) {
if (itemProperties == null) {
return null;
} else if (itemStack == null) {
return null;
} else {
Item item = itemStack.getItem();
int i = Item.getIdFromItem(item);
if (i >= 0 && i < itemProperties.length) {
CustomItemProperties[] acustomitemproperties = itemProperties[i];
if (acustomitemproperties != null) {
for (int j = 0; j < acustomitemproperties.length; ++j) {
CustomItemProperties customitemproperties = acustomitemproperties[j];
if (customitemproperties.type == type
&& matchesProperties(customitemproperties, itemStack, (int[][]) null)) {
return customitemproperties;
}
}
}
}
return null;
}
}
private static boolean matchesProperties(CustomItemProperties cip, ItemStack itemStack,
int[][] enchantmentIdLevels) {
Item item = itemStack.getItem();
if (cip.damage != null) {
int i = itemStack.getItemDamage();
if (cip.damageMask != 0) {
i &= cip.damageMask;
}
if (cip.damagePercent) {
int j = item.getMaxDamage();
i = (int) ((double) (i * 100) / (double) j);
}
if (!cip.damage.isInRange(i)) {
return false;
}
}
if (cip.stackSize != null && !cip.stackSize.isInRange(itemStack.stackSize)) {
return false;
} else {
int[][] aint = enchantmentIdLevels;
if (cip.enchantmentIds != null) {
if (enchantmentIdLevels == null) {
aint = getEnchantmentIdLevels(itemStack);
}
boolean flag = false;
for (int k = 0; k < aint.length; ++k) {
int l = aint[k][0];
if (cip.enchantmentIds.isInRange(l)) {
flag = true;
break;
}
}
if (!flag) {
return false;
}
}
if (cip.enchantmentLevels != null) {
if (aint == null) {
aint = getEnchantmentIdLevels(itemStack);
}
boolean flag1 = false;
for (int i1 = 0; i1 < aint.length; ++i1) {
int k1 = aint[i1][1];
if (cip.enchantmentLevels.isInRange(k1)) {
flag1 = true;
break;
}
}
if (!flag1) {
return false;
}
}
if (cip.nbtTagValues != null) {
NBTTagCompound nbttagcompound = itemStack.getTagCompound();
for (int j1 = 0; j1 < cip.nbtTagValues.length; ++j1) {
NbtTagValue nbttagvalue = cip.nbtTagValues[j1];
if (!nbttagvalue.matches(nbttagcompound)) {
return false;
}
}
}
if (cip.hand != 0) {
if (cip.hand == 1 && renderOffHand) {
return false;
}
if (cip.hand == 2 && !renderOffHand) {
return false;
}
}
return true;
}
}
private static int[][] getEnchantmentIdLevels(ItemStack itemStack) {
Item item = itemStack.getItem();
NBTTagList nbttaglist = item == Items.enchanted_book ? Items.enchanted_book.getEnchantments(itemStack)
: itemStack.getEnchantmentTagList();
if (nbttaglist != null && nbttaglist.tagCount() > 0) {
int[][] aint = new int[nbttaglist.tagCount()][2];
for (int i = 0; i < nbttaglist.tagCount(); ++i) {
NBTTagCompound nbttagcompound = nbttaglist.getCompoundTagAt(i);
int j = nbttagcompound.getShort("id");
int k = nbttagcompound.getShort("lvl");
aint[i][0] = j;
aint[i][1] = k;
}
return aint;
} else {
return EMPTY_INT2_ARRAY;
}
}
public static boolean renderCustomEffect(RenderItem renderItem, ItemStack itemStack, IBakedModel model) {
if (enchantmentProperties == null) {
return false;
} else if (itemStack == null) {
return false;
} else {
int[][] aint = getEnchantmentIdLevels(itemStack);
if (aint.length <= 0) {
return false;
} else {
Set set = null;
boolean flag = false;
TextureManager texturemanager = Minecraft.getMinecraft().getTextureManager();
for (int i = 0; i < aint.length; ++i) {
int j = aint[i][0];
if (j >= 0 && j < enchantmentProperties.length) {
CustomItemProperties[] acustomitemproperties = enchantmentProperties[j];
if (acustomitemproperties != null) {
for (int k = 0; k < acustomitemproperties.length; ++k) {
CustomItemProperties customitemproperties = acustomitemproperties[k];
if (set == null) {
set = new HashSet();
}
if (set.add(Integer.valueOf(j))
&& matchesProperties(customitemproperties, itemStack, aint)
&& customitemproperties.textureLocation != null) {
texturemanager.bindTexture(customitemproperties.textureLocation);
float f = customitemproperties.getTextureWidth(texturemanager);
if (!flag) {
flag = true;
GlStateManager.depthMask(false);
GlStateManager.depthFunc(514);
GlStateManager.disableLighting();
GlStateManager.matrixMode(5890);
}
Blender.setupBlend(customitemproperties.blend, 1.0F);
GlStateManager.pushMatrix();
GlStateManager.scale(f / 2.0F, f / 2.0F, f / 2.0F);
float f1 = customitemproperties.speed * (float) (Minecraft.getSystemTime() % 3000L)
/ 3000.0F / 8.0F;
GlStateManager.translate(f1, 0.0F, 0.0F);
GlStateManager.rotate(customitemproperties.rotation, 0.0F, 0.0F, 1.0F);
renderItem.renderModel(model, -1);
GlStateManager.popMatrix();
}
}
}
}
}
if (flag) {
GlStateManager.enableAlpha();
GlStateManager.enableBlend();
GlStateManager.blendFunc(770, 771);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
GlStateManager.matrixMode(5888);
GlStateManager.enableLighting();
GlStateManager.depthFunc(515);
GlStateManager.depthMask(true);
texturemanager.bindTexture(TextureMap.locationBlocksTexture);
}
return flag;
}
}
}
public static boolean renderCustomArmorEffect(EntityLivingBase entity, ItemStack itemStack, ModelBase model,
float limbSwing, float prevLimbSwing, float partialTicks, float timeLimbSwing, float yaw, float pitch,
float scale) {
if (enchantmentProperties == null) {
return false;
} else if (itemStack == null) {
return false;
} else {
int[][] aint = getEnchantmentIdLevels(itemStack);
if (aint.length <= 0) {
return false;
} else {
Set set = null;
boolean flag = false;
TextureManager texturemanager = Minecraft.getMinecraft().getTextureManager();
for (int i = 0; i < aint.length; ++i) {
int j = aint[i][0];
if (j >= 0 && j < enchantmentProperties.length) {
CustomItemProperties[] acustomitemproperties = enchantmentProperties[j];
if (acustomitemproperties != null) {
for (int k = 0; k < acustomitemproperties.length; ++k) {
CustomItemProperties customitemproperties = acustomitemproperties[k];
if (set == null) {
set = new HashSet();
}
if (set.add(Integer.valueOf(j))
&& matchesProperties(customitemproperties, itemStack, aint)
&& customitemproperties.textureLocation != null) {
texturemanager.bindTexture(customitemproperties.textureLocation);
float f = customitemproperties.getTextureWidth(texturemanager);
if (!flag) {
flag = true;
GlStateManager.enableBlend();
GlStateManager.depthFunc(514);
GlStateManager.depthMask(false);
}
Blender.setupBlend(customitemproperties.blend, 1.0F);
GlStateManager.disableLighting();
GlStateManager.matrixMode(5890);
GlStateManager.loadIdentity();
GlStateManager.rotate(customitemproperties.rotation, 0.0F, 0.0F, 1.0F);
float f1 = f / 8.0F;
GlStateManager.scale(f1, f1 / 2.0F, f1);
float f2 = customitemproperties.speed * (float) (Minecraft.getSystemTime() % 3000L)
/ 3000.0F / 8.0F;
GlStateManager.translate(0.0F, f2, 0.0F);
GlStateManager.matrixMode(5888);
model.render(entity, limbSwing, prevLimbSwing, timeLimbSwing, yaw, pitch, scale);
}
}
}
}
}
if (flag) {
GlStateManager.enableAlpha();
GlStateManager.enableBlend();
GlStateManager.blendFunc(770, 771);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
GlStateManager.matrixMode(5890);
GlStateManager.loadIdentity();
GlStateManager.matrixMode(5888);
GlStateManager.enableLighting();
GlStateManager.depthMask(true);
GlStateManager.depthFunc(515);
GlStateManager.disableBlend();
}
return flag;
}
}
}
public static boolean isUseGlint() {
return useGlint;
}
}

View File

@ -0,0 +1,15 @@
package net.optifine;
import java.util.Comparator;
public class CustomItemsComparator implements Comparator {
public int compare(Object o1, Object o2) {
CustomItemProperties customitemproperties = (CustomItemProperties) o1;
CustomItemProperties customitemproperties1 = (CustomItemProperties) o2;
return customitemproperties.weight != customitemproperties1.weight
? customitemproperties1.weight - customitemproperties.weight
: (!Config.equals(customitemproperties.basePath, customitemproperties1.basePath)
? customitemproperties.basePath.compareTo(customitemproperties1.basePath)
: customitemproperties.name.compareTo(customitemproperties1.name));
}
}

View File

@ -0,0 +1,149 @@
package net.optifine;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.ITextureObject;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.optifine.render.Blender;
import net.optifine.util.PropertiesOrdered;
public class CustomSky {
private static CustomSkyLayer[][] worldSkyLayers = (CustomSkyLayer[][]) null;
public static void reset() {
worldSkyLayers = (CustomSkyLayer[][]) null;
}
public static void update() {
reset();
if (Config.isCustomSky()) {
worldSkyLayers = readCustomSkies();
}
}
private static CustomSkyLayer[][] readCustomSkies() {
CustomSkyLayer[][] acustomskylayer = new CustomSkyLayer[10][0];
String s = "mcpatcher/sky/world";
int i = -1;
for (int j = 0; j < acustomskylayer.length; ++j) {
String s1 = s + j + "/sky";
List list = new ArrayList();
for (int k = 1; k < 1000; ++k) {
String s2 = s1 + k + ".properties";
ResourceLocation resourcelocation = new ResourceLocation(s2);
try (InputStream inputstream = Minecraft.getMinecraft().getResourceManager()
.getResource(resourcelocation).getInputStream()) {
if (inputstream == null) {
break;
}
Properties properties = new PropertiesOrdered();
properties.load(inputstream);
inputstream.close();
Config.dbg("CustomSky properties: " + s2);
String s3 = s1 + k + ".png";
CustomSkyLayer customskylayer = new CustomSkyLayer(properties, s3);
if (customskylayer.isValid(s2)) {
ResourceLocation resourcelocation1 = new ResourceLocation(customskylayer.source);
TextureManager mgr = Minecraft.getMinecraft().getTextureManager();
mgr.bindTexture(resourcelocation1);
ITextureObject itextureobject = mgr.getTexture(resourcelocation1);
if (itextureobject == null) {
Config.warn("CustomSky: Texture not found: " + resourcelocation1);
} else {
customskylayer.textureId = itextureobject.getGlTextureId();
list.add(customskylayer);
inputstream.close();
}
}
} catch (FileNotFoundException var15) {
break;
} catch (IOException ioexception) {
ioexception.printStackTrace();
}
}
if (list.size() > 0) {
CustomSkyLayer[] acustomskylayer2 = (CustomSkyLayer[]) ((CustomSkyLayer[]) list
.toArray(new CustomSkyLayer[list.size()]));
acustomskylayer[j] = acustomskylayer2;
i = j;
}
}
if (i < 0) {
return (CustomSkyLayer[][]) null;
} else {
int l = i + 1;
CustomSkyLayer[][] acustomskylayer1 = new CustomSkyLayer[l][0];
for (int i1 = 0; i1 < acustomskylayer1.length; ++i1) {
acustomskylayer1[i1] = acustomskylayer[i1];
}
return acustomskylayer1;
}
}
public static void renderSky(World world, TextureManager re, float partialTicks) {
if (worldSkyLayers != null) {
int i = world.provider.getDimensionId();
if (i >= 0 && i < worldSkyLayers.length) {
CustomSkyLayer[] acustomskylayer = worldSkyLayers[i];
if (acustomskylayer != null) {
long j = world.getWorldTime();
int k = (int) (j % 24000L);
float f = world.getCelestialAngle(partialTicks);
float f1 = world.getRainStrength(partialTicks);
float f2 = world.getThunderStrength(partialTicks);
if (f1 > 0.0F) {
f2 /= f1;
}
for (int l = 0; l < acustomskylayer.length; ++l) {
CustomSkyLayer customskylayer = acustomskylayer[l];
if (customskylayer.isActive(world, k)) {
customskylayer.render(world, k, f, f1, f2);
}
}
float f3 = 1.0F - f1;
Blender.clearBlend(f3);
}
}
}
}
public static boolean hasSkyLayers(World world) {
if (worldSkyLayers == null) {
return false;
} else {
int i = world.provider.getDimensionId();
if (i >= 0 && i < worldSkyLayers.length) {
CustomSkyLayer[] acustomskylayer = worldSkyLayers[i];
return acustomskylayer == null ? false : acustomskylayer.length > 0;
} else {
return false;
}
}
}
}

View File

@ -0,0 +1,434 @@
package net.optifine;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.lax1dude.eaglercraft.v1_8.opengl.WorldRenderer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.Entity;
import net.minecraft.util.BlockPos;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.biome.BiomeGenBase;
import net.optifine.config.ConnectedParser;
import net.optifine.config.Matches;
import net.optifine.config.RangeListInt;
import net.optifine.render.Blender;
import net.optifine.util.NumUtils;
import net.optifine.util.SmoothFloat;
import net.optifine.util.TextureUtils;
public class CustomSkyLayer {
public String source = null;
private int startFadeIn = -1;
private int endFadeIn = -1;
private int startFadeOut = -1;
private int endFadeOut = -1;
private int blend = 1;
private boolean rotate = false;
private float speed = 1.0F;
private float[] axis;
private RangeListInt days;
private int daysLoop;
private boolean weatherClear;
private boolean weatherRain;
private boolean weatherThunder;
public BiomeGenBase[] biomes;
public RangeListInt heights;
private float transition;
private SmoothFloat smoothPositionBrightness;
public int textureId;
private World lastWorld;
public static final float[] DEFAULT_AXIS = new float[] { 1.0F, 0.0F, 0.0F };
private static final String WEATHER_CLEAR = "clear";
private static final String WEATHER_RAIN = "rain";
private static final String WEATHER_THUNDER = "thunder";
public CustomSkyLayer(Properties props, String defSource) {
this.axis = DEFAULT_AXIS;
this.days = null;
this.daysLoop = 8;
this.weatherClear = true;
this.weatherRain = false;
this.weatherThunder = false;
this.biomes = null;
this.heights = null;
this.transition = 1.0F;
this.smoothPositionBrightness = null;
this.textureId = -1;
this.lastWorld = null;
ConnectedParser connectedparser = new ConnectedParser("CustomSky");
this.source = props.getProperty("source", defSource);
this.startFadeIn = this.parseTime(props.getProperty("startFadeIn"));
this.endFadeIn = this.parseTime(props.getProperty("endFadeIn"));
this.startFadeOut = this.parseTime(props.getProperty("startFadeOut"));
this.endFadeOut = this.parseTime(props.getProperty("endFadeOut"));
this.blend = Blender.parseBlend(props.getProperty("blend"));
this.rotate = this.parseBoolean(props.getProperty("rotate"), true);
this.speed = this.parseFloat(props.getProperty("speed"), 1.0F);
this.axis = this.parseAxis(props.getProperty("axis"), DEFAULT_AXIS);
this.days = connectedparser.parseRangeListInt(props.getProperty("days"));
this.daysLoop = connectedparser.parseInt(props.getProperty("daysLoop"), 8);
List<String> list = this.parseWeatherList(props.getProperty("weather", "clear"));
this.weatherClear = list.contains("clear");
this.weatherRain = list.contains("rain");
this.weatherThunder = list.contains("thunder");
this.biomes = connectedparser.parseBiomes(props.getProperty("biomes"));
this.heights = connectedparser.parseRangeListInt(props.getProperty("heights"));
this.transition = this.parseFloat(props.getProperty("transition"), 1.0F);
}
private List<String> parseWeatherList(String str) {
List<String> list = Arrays.<String>asList(new String[] { "clear", "rain", "thunder" });
List<String> list1 = new ArrayList();
String[] astring = Config.tokenize(str, " ");
for (int i = 0; i < astring.length; ++i) {
String s = astring[i];
if (!list.contains(s)) {
Config.warn("Unknown weather: " + s);
} else {
list1.add(s);
}
}
return list1;
}
private int parseTime(String str) {
if (str == null) {
return -1;
} else {
String[] astring = Config.tokenize(str, ":");
if (astring.length != 2) {
Config.warn("Invalid time: " + str);
return -1;
} else {
String s = astring[0];
String s1 = astring[1];
int i = Config.parseInt(s, -1);
int j = Config.parseInt(s1, -1);
if (i >= 0 && i <= 23 && j >= 0 && j <= 59) {
i = i - 6;
if (i < 0) {
i += 24;
}
int k = i * 1000 + (int) ((double) j / 60.0D * 1000.0D);
return k;
} else {
Config.warn("Invalid time: " + str);
return -1;
}
}
}
}
private boolean parseBoolean(String str, boolean defVal) {
if (str == null) {
return defVal;
} else if (str.toLowerCase().equals("true")) {
return true;
} else if (str.toLowerCase().equals("false")) {
return false;
} else {
Config.warn("Unknown boolean: " + str);
return defVal;
}
}
private float parseFloat(String str, float defVal) {
if (str == null) {
return defVal;
} else {
float f = Config.parseFloat(str, Float.MIN_VALUE);
if (f == Float.MIN_VALUE) {
Config.warn("Invalid value: " + str);
return defVal;
} else {
return f;
}
}
}
private float[] parseAxis(String str, float[] defVal) {
if (str == null) {
return defVal;
} else {
String[] astring = Config.tokenize(str, " ");
if (astring.length != 3) {
Config.warn("Invalid axis: " + str);
return defVal;
} else {
float[] afloat = new float[3];
for (int i = 0; i < astring.length; ++i) {
afloat[i] = Config.parseFloat(astring[i], Float.MIN_VALUE);
if (afloat[i] == Float.MIN_VALUE) {
Config.warn("Invalid axis: " + str);
return defVal;
}
if (afloat[i] < -1.0F || afloat[i] > 1.0F) {
Config.warn("Invalid axis values: " + str);
return defVal;
}
}
float f2 = afloat[0];
float f = afloat[1];
float f1 = afloat[2];
float l = f2 * f2 + f * f + f1 * f1;
if (l < 1.0E-5F) {
Config.warn("Invalid axis values: " + str);
return defVal;
} else {
l = MathHelper.sqrt_float(l);
return new float[] { f1 / l, f / l, -f2 / l };
}
}
}
}
public boolean isValid(String path) {
if (this.source == null) {
Config.warn("No source texture: " + path);
return false;
} else {
this.source = TextureUtils.fixResourcePath(this.source, TextureUtils.getBasePath(path));
if (this.startFadeIn >= 0 && this.endFadeIn >= 0 && this.endFadeOut >= 0) {
int i = this.normalizeTime(this.endFadeIn - this.startFadeIn);
if (this.startFadeOut < 0) {
this.startFadeOut = this.normalizeTime(this.endFadeOut - i);
if (this.timeBetween(this.startFadeOut, this.startFadeIn, this.endFadeIn)) {
this.startFadeOut = this.endFadeIn;
}
}
int j = this.normalizeTime(this.startFadeOut - this.endFadeIn);
int k = this.normalizeTime(this.endFadeOut - this.startFadeOut);
int l = this.normalizeTime(this.startFadeIn - this.endFadeOut);
int i1 = i + j + k + l;
if (i1 != 24000) {
Config.warn("Invalid fadeIn/fadeOut times, sum is not 24h: " + i1);
return false;
} else if (this.speed < 0.0F) {
Config.warn("Invalid speed: " + this.speed);
return false;
} else if (this.daysLoop <= 0) {
Config.warn("Invalid daysLoop: " + this.daysLoop);
return false;
} else {
return true;
}
} else {
Config.warn("Invalid times, required are: startFadeIn, endFadeIn and endFadeOut.");
return false;
}
}
}
private int normalizeTime(int timeMc) {
while (timeMc >= 24000) {
timeMc -= 24000;
}
while (timeMc < 0) {
timeMc += 24000;
}
return timeMc;
}
public void render(World world, int timeOfDay, float celestialAngle, float rainStrength, float thunderStrength) {
float f = this.getPositionBrightness(world);
float f1 = this.getWeatherBrightness(rainStrength, thunderStrength);
float f2 = this.getFadeBrightness(timeOfDay);
float f3 = f * f1 * f2;
f3 = Config.limit(f3, 0.0F, 1.0F);
if (f3 >= 1.0E-4F) {
GlStateManager.bindTexture(this.textureId);
Blender.setupBlend(this.blend, f3);
GlStateManager.pushMatrix();
if (this.rotate) {
float f4 = 0.0F;
if (this.speed != (float) Math.round(this.speed)) {
long i = (world.getWorldTime() + 18000L) / 24000L;
double d0 = (double) (this.speed % 1.0F);
double d1 = (double) i * d0;
f4 = (float) (d1 % 1.0D);
}
GlStateManager.rotate(360.0F * (f4 + celestialAngle * this.speed), this.axis[0], this.axis[1],
this.axis[2]);
}
Tessellator tessellator = Tessellator.getInstance();
GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F);
GlStateManager.rotate(-90.0F, 0.0F, 0.0F, 1.0F);
this.renderSide(tessellator, 4);
GlStateManager.pushMatrix();
GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F);
this.renderSide(tessellator, 1);
GlStateManager.popMatrix();
GlStateManager.pushMatrix();
GlStateManager.rotate(-90.0F, 1.0F, 0.0F, 0.0F);
this.renderSide(tessellator, 0);
GlStateManager.popMatrix();
GlStateManager.rotate(90.0F, 0.0F, 0.0F, 1.0F);
this.renderSide(tessellator, 5);
GlStateManager.rotate(90.0F, 0.0F, 0.0F, 1.0F);
this.renderSide(tessellator, 2);
GlStateManager.rotate(90.0F, 0.0F, 0.0F, 1.0F);
this.renderSide(tessellator, 3);
GlStateManager.popMatrix();
}
}
private float getPositionBrightness(World world) {
if (this.biomes == null && this.heights == null) {
return 1.0F;
} else {
float f = this.getPositionBrightnessRaw(world);
if (this.smoothPositionBrightness == null) {
this.smoothPositionBrightness = new SmoothFloat(f, this.transition);
}
f = this.smoothPositionBrightness.getSmoothValue(f);
return f;
}
}
private float getPositionBrightnessRaw(World world) {
Entity entity = Minecraft.getMinecraft().getRenderViewEntity();
if (entity == null) {
return 0.0F;
} else {
BlockPos blockpos = entity.getPosition();
if (this.biomes != null) {
BiomeGenBase biomegenbase = world.getBiomeGenForCoords(blockpos);
if (biomegenbase == null) {
return 0.0F;
}
if (!Matches.biome(biomegenbase, this.biomes)) {
return 0.0F;
}
}
return this.heights != null && !this.heights.isInRange(blockpos.getY()) ? 0.0F : 1.0F;
}
}
private float getWeatherBrightness(float rainStrength, float thunderStrength) {
float f = 1.0F - rainStrength;
float f1 = rainStrength - thunderStrength;
float f2 = 0.0F;
if (this.weatherClear) {
f2 += f;
}
if (this.weatherRain) {
f2 += f1;
}
if (this.weatherThunder) {
f2 += thunderStrength;
}
f2 = NumUtils.limit(f2, 0.0F, 1.0F);
return f2;
}
private float getFadeBrightness(int timeOfDay) {
if (this.timeBetween(timeOfDay, this.startFadeIn, this.endFadeIn)) {
int k = this.normalizeTime(this.endFadeIn - this.startFadeIn);
int l = this.normalizeTime(timeOfDay - this.startFadeIn);
return (float) l / (float) k;
} else if (this.timeBetween(timeOfDay, this.endFadeIn, this.startFadeOut)) {
return 1.0F;
} else if (this.timeBetween(timeOfDay, this.startFadeOut, this.endFadeOut)) {
int i = this.normalizeTime(this.endFadeOut - this.startFadeOut);
int j = this.normalizeTime(timeOfDay - this.startFadeOut);
return 1.0F - (float) j / (float) i;
} else {
return 0.0F;
}
}
private void renderSide(Tessellator tess, int side) {
WorldRenderer worldrenderer = tess.getWorldRenderer();
double d0 = (double) (side % 3) / 3.0D;
double d1 = (double) (side / 3) / 2.0D;
worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX);
worldrenderer.pos(-100.0D, -100.0D, -100.0D).tex(d0, d1).endVertex();
worldrenderer.pos(-100.0D, -100.0D, 100.0D).tex(d0, d1 + 0.5D).endVertex();
worldrenderer.pos(100.0D, -100.0D, 100.0D).tex(d0 + 0.3333333333333333D, d1 + 0.5D).endVertex();
worldrenderer.pos(100.0D, -100.0D, -100.0D).tex(d0 + 0.3333333333333333D, d1).endVertex();
tess.draw();
}
public boolean isActive(World world, int timeOfDay) {
if (world != this.lastWorld) {
this.lastWorld = world;
this.smoothPositionBrightness = null;
}
if (this.timeBetween(timeOfDay, this.endFadeOut, this.startFadeIn)) {
return false;
} else {
if (this.days != null) {
long i = world.getWorldTime();
long j;
for (j = i - (long) this.startFadeIn; j < 0L; j += (long) (24000 * this.daysLoop)) {
;
}
int k = (int) (j / 24000L);
int l = k % this.daysLoop;
if (!this.days.isInRange(l)) {
return false;
}
}
return true;
}
}
private boolean timeBetween(int timeOfDay, int timeStart, int timeEnd) {
return timeStart <= timeEnd ? timeOfDay >= timeStart && timeOfDay <= timeEnd
: timeOfDay >= timeStart || timeOfDay <= timeEnd;
}
public String toString() {
return "" + this.source + ", " + this.startFadeIn + "-" + this.endFadeIn + " " + this.startFadeOut + "-"
+ this.endFadeOut;
}
}

View File

@ -0,0 +1,198 @@
package net.optifine;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.BlockNewLeaf;
import net.minecraft.block.BlockOldLeaf;
import net.minecraft.block.BlockPlanks;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.resources.DefaultResourcePack;
import net.minecraft.client.resources.model.IBakedModel;
import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.optifine.model.ModelUtils;
public class SmartLeaves {
private static IBakedModel modelLeavesCullAcacia = null;
private static IBakedModel modelLeavesCullBirch = null;
private static IBakedModel modelLeavesCullDarkOak = null;
private static IBakedModel modelLeavesCullJungle = null;
private static IBakedModel modelLeavesCullOak = null;
private static IBakedModel modelLeavesCullSpruce = null;
private static List generalQuadsCullAcacia = null;
private static List generalQuadsCullBirch = null;
private static List generalQuadsCullDarkOak = null;
private static List generalQuadsCullJungle = null;
private static List generalQuadsCullOak = null;
private static List generalQuadsCullSpruce = null;
private static IBakedModel modelLeavesDoubleAcacia = null;
private static IBakedModel modelLeavesDoubleBirch = null;
private static IBakedModel modelLeavesDoubleDarkOak = null;
private static IBakedModel modelLeavesDoubleJungle = null;
private static IBakedModel modelLeavesDoubleOak = null;
private static IBakedModel modelLeavesDoubleSpruce = null;
public static IBakedModel getLeavesModel(IBakedModel model, IBlockState stateIn) {
if (!Config.isTreesSmart()) {
return model;
} else {
List list = model.getGeneralQuads();
return list == generalQuadsCullAcacia ? modelLeavesDoubleAcacia
: (list == generalQuadsCullBirch ? modelLeavesDoubleBirch
: (list == generalQuadsCullDarkOak ? modelLeavesDoubleDarkOak
: (list == generalQuadsCullJungle ? modelLeavesDoubleJungle
: (list == generalQuadsCullOak ? modelLeavesDoubleOak
: (list == generalQuadsCullSpruce ? modelLeavesDoubleSpruce
: model)))));
}
}
public static boolean isSameLeaves(IBlockState state1, IBlockState state2) {
if (state1 == state2) {
return true;
} else {
Block block = state1.getBlock();
Block block1 = state2.getBlock();
return block != block1 ? false
: (block instanceof BlockOldLeaf
? ((BlockPlanks.EnumType) state1.getValue(BlockOldLeaf.VARIANT))
.equals(state2.getValue(BlockOldLeaf.VARIANT))
: (block instanceof BlockNewLeaf
? ((BlockPlanks.EnumType) state1.getValue(BlockNewLeaf.VARIANT)).equals(
state2.getValue(BlockNewLeaf.VARIANT))
: false));
}
}
public static void updateLeavesModels() {
List list = new ArrayList();
modelLeavesCullAcacia = getModelCull("acacia", list);
modelLeavesCullBirch = getModelCull("birch", list);
modelLeavesCullDarkOak = getModelCull("dark_oak", list);
modelLeavesCullJungle = getModelCull("jungle", list);
modelLeavesCullOak = getModelCull("oak", list);
modelLeavesCullSpruce = getModelCull("spruce", list);
generalQuadsCullAcacia = getGeneralQuadsSafe(modelLeavesCullAcacia);
generalQuadsCullBirch = getGeneralQuadsSafe(modelLeavesCullBirch);
generalQuadsCullDarkOak = getGeneralQuadsSafe(modelLeavesCullDarkOak);
generalQuadsCullJungle = getGeneralQuadsSafe(modelLeavesCullJungle);
generalQuadsCullOak = getGeneralQuadsSafe(modelLeavesCullOak);
generalQuadsCullSpruce = getGeneralQuadsSafe(modelLeavesCullSpruce);
modelLeavesDoubleAcacia = getModelDoubleFace(modelLeavesCullAcacia);
modelLeavesDoubleBirch = getModelDoubleFace(modelLeavesCullBirch);
modelLeavesDoubleDarkOak = getModelDoubleFace(modelLeavesCullDarkOak);
modelLeavesDoubleJungle = getModelDoubleFace(modelLeavesCullJungle);
modelLeavesDoubleOak = getModelDoubleFace(modelLeavesCullOak);
modelLeavesDoubleSpruce = getModelDoubleFace(modelLeavesCullSpruce);
if (list.size() > 0) {
Config.dbg("Enable face culling: " + Config.arrayToString(list.toArray()));
}
}
private static List getGeneralQuadsSafe(IBakedModel model) {
return model == null ? null : model.getGeneralQuads();
}
static IBakedModel getModelCull(String type, List updatedTypes) {
ModelManager modelmanager = Minecraft.getMinecraft().getModelManager();
if (modelmanager == null) {
return null;
} else {
ResourceLocation resourcelocation = new ResourceLocation("blockstates/" + type + "_leaves.json");
DefaultResourcePack res = Minecraft.getMinecraft().getDefaultResourcePack();
if (Config.getDefiningResourcePack(resourcelocation) != res) {
return null;
} else {
ResourceLocation resourcelocation1 = new ResourceLocation("models/block/" + type + "_leaves.json");
if (Config.getDefiningResourcePack(resourcelocation1) != res) {
return null;
} else {
ModelResourceLocation modelresourcelocation = new ModelResourceLocation(type + "_leaves", "normal");
IBakedModel ibakedmodel = modelmanager.getModel(modelresourcelocation);
if (ibakedmodel != null && ibakedmodel != modelmanager.getMissingModel()) {
List list = ibakedmodel.getGeneralQuads();
if (list.size() == 0) {
return ibakedmodel;
} else if (list.size() != 6) {
return null;
} else {
for (Object bakedquad0 : list) {
BakedQuad bakedquad = (BakedQuad) bakedquad0;
List list1 = ibakedmodel.getFaceQuads(bakedquad.getFace());
if (list1.size() > 0) {
return null;
}
list1.add(bakedquad);
}
list.clear();
updatedTypes.add(type + "_leaves");
return ibakedmodel;
}
} else {
return null;
}
}
}
}
}
private static IBakedModel getModelDoubleFace(IBakedModel model) {
if (model == null) {
return null;
} else if (model.getGeneralQuads().size() > 0) {
Config.warn("SmartLeaves: Model is not cube, general quads: " + model.getGeneralQuads().size() + ", model: "
+ model);
return model;
} else {
EnumFacing[] aenumfacing = EnumFacing._VALUES;
for (int i = 0; i < aenumfacing.length; ++i) {
EnumFacing enumfacing = aenumfacing[i];
List<BakedQuad> list = model.getFaceQuads(enumfacing);
if (list.size() != 1) {
Config.warn("SmartLeaves: Model is not cube, side: " + enumfacing + ", quads: " + list.size()
+ ", model: " + model);
return model;
}
}
IBakedModel ibakedmodel = ModelUtils.duplicateModel(model);
List[] alist = new List[aenumfacing.length];
for (int k = 0; k < aenumfacing.length; ++k) {
EnumFacing enumfacing1 = aenumfacing[k];
List<BakedQuad> list1 = ibakedmodel.getFaceQuads(enumfacing1);
BakedQuad bakedquad = (BakedQuad) list1.get(0);
BakedQuad bakedquad1 = new BakedQuad((int[]) bakedquad.getVertexData().clone(),
(int[]) bakedquad.getVertexDataWithNormals().clone(), bakedquad.getTintIndex(),
bakedquad.getFace(), bakedquad.getSprite());
int[] aint = bakedquad1.getVertexData();
int[] aint1 = (int[]) aint.clone();
int j = aint.length / 4;
System.arraycopy(aint, 0 * j, aint1, 3 * j, j);
System.arraycopy(aint, 1 * j, aint1, 2 * j, j);
System.arraycopy(aint, 2 * j, aint1, 1 * j, j);
System.arraycopy(aint, 3 * j, aint1, 0 * j, j);
System.arraycopy(aint1, 0, aint, 0, aint1.length);
list1.add(bakedquad1);
}
return ibakedmodel;
}
}
}

View File

@ -0,0 +1,914 @@
package net.optifine.config;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDoublePlant;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.Item;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumWorldBlockLayer;
import net.minecraft.util.IStringSerializable;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.biome.BiomeGenBase;
import net.optifine.Config;
import net.optifine.ConnectedProperties;
public class ConnectedParser {
private String context = null;
public static final EnumDyeColor[] DYE_COLORS_INVALID = new EnumDyeColor[0];
private static final INameGetter<Enum> NAME_GETTER_ENUM = new INameGetter<Enum>() {
public String getName(Enum en) {
return en.name();
}
};
private static final INameGetter<EnumDyeColor> NAME_GETTER_DYE_COLOR = new INameGetter<EnumDyeColor>() {
public String getName(EnumDyeColor col) {
return col.getName();
}
};
public ConnectedParser(String context) {
this.context = context;
}
public String parseName(String path) {
String s = path;
int i = path.lastIndexOf(47);
if (i >= 0) {
s = path.substring(i + 1);
}
int j = s.lastIndexOf(46);
if (j >= 0) {
s = s.substring(0, j);
}
return s;
}
public String parseBasePath(String path) {
int i = path.lastIndexOf(47);
return i < 0 ? "" : path.substring(0, i);
}
public MatchBlock[] parseMatchBlocks(String propMatchBlocks) {
if (propMatchBlocks == null) {
return null;
} else {
List list = new ArrayList();
String[] astring = Config.tokenize(propMatchBlocks, " ");
for (int i = 0; i < astring.length; ++i) {
String s = astring[i];
MatchBlock[] amatchblock = this.parseMatchBlock(s);
if (amatchblock != null) {
list.addAll(Arrays.asList(amatchblock));
}
}
MatchBlock[] amatchblock1 = (MatchBlock[]) ((MatchBlock[]) list.toArray(new MatchBlock[list.size()]));
return amatchblock1;
}
}
public IBlockState parseBlockState(String str, IBlockState def) {
MatchBlock[] amatchblock = this.parseMatchBlock(str);
if (amatchblock == null) {
return def;
} else if (amatchblock.length != 1) {
return def;
} else {
MatchBlock matchblock = amatchblock[0];
int i = matchblock.getBlockId();
Block block = Block.getBlockById(i);
return block.getDefaultState();
}
}
public MatchBlock[] parseMatchBlock(String blockStr) {
if (blockStr == null) {
return null;
} else {
blockStr = blockStr.trim();
if (blockStr.length() <= 0) {
return null;
} else {
String[] astring = Config.tokenize(blockStr, ":");
String s = "minecraft";
int i = 0;
if (astring.length > 1 && this.isFullBlockName(astring)) {
s = astring[0];
i = 1;
} else {
s = "minecraft";
i = 0;
}
String s1 = astring[i];
String[] astring1 = (String[]) Arrays.copyOfRange(astring, i + 1, astring.length);
Block[] ablock = this.parseBlockPart(s, s1);
if (ablock == null) {
return null;
} else {
MatchBlock[] amatchblock = new MatchBlock[ablock.length];
for (int j = 0; j < ablock.length; ++j) {
Block block = ablock[j];
int k = Block.getIdFromBlock(block);
int[] aint = null;
if (astring1.length > 0) {
aint = this.parseBlockMetadatas(block, astring1);
if (aint == null) {
return null;
}
}
MatchBlock matchblock = new MatchBlock(k, aint);
amatchblock[j] = matchblock;
}
return amatchblock;
}
}
}
}
public boolean isFullBlockName(String[] parts) {
if (parts.length < 2) {
return false;
} else {
String s = parts[1];
return s.length() < 1 ? false : (this.startsWithDigit(s) ? false : !s.contains("="));
}
}
public boolean startsWithDigit(String str) {
if (str == null) {
return false;
} else if (str.length() < 1) {
return false;
} else {
char c0 = str.charAt(0);
return Character.isDigit(c0);
}
}
public Block[] parseBlockPart(String domain, String blockPart) {
if (this.startsWithDigit(blockPart)) {
int[] aint = this.parseIntList(blockPart);
if (aint == null) {
return null;
} else {
Block[] ablock1 = new Block[aint.length];
for (int j = 0; j < aint.length; ++j) {
int i = aint[j];
Block block1 = Block.getBlockById(i);
if (block1 == null) {
this.warn("Block not found for id: " + i);
return null;
}
ablock1[j] = block1;
}
return ablock1;
}
} else {
String s = domain + ":" + blockPart;
Block block = Block.getBlockFromName(s);
if (block == null) {
this.warn("Block not found for name: " + s);
return null;
} else {
Block[] ablock = new Block[] { block };
return ablock;
}
}
}
public int[] parseBlockMetadatas(Block block, String[] params) {
if (params.length <= 0) {
return null;
} else {
String s = params[0];
if (this.startsWithDigit(s)) {
int[] aint = this.parseIntList(s);
return aint;
} else {
IBlockState iblockstate = block.getDefaultState();
Collection collection = iblockstate.getPropertyNames();
Map<IProperty, List<Comparable>> map = new HashMap();
for (int i = 0; i < params.length; ++i) {
String s1 = params[i];
if (s1.length() > 0) {
String[] astring = Config.tokenize(s1, "=");
if (astring.length != 2) {
this.warn("Invalid block property: " + s1);
return null;
}
String s2 = astring[0];
String s3 = astring[1];
IProperty iproperty = ConnectedProperties.getProperty(s2, collection);
if (iproperty == null) {
this.warn("Property not found: " + s2 + ", block: " + block);
return null;
}
List<Comparable> list = (List) map.get(s2);
if (list == null) {
list = new ArrayList();
map.put(iproperty, list);
}
String[] astring1 = Config.tokenize(s3, ",");
for (int j = 0; j < astring1.length; ++j) {
String s4 = astring1[j];
Comparable comparable = parsePropertyValue(iproperty, s4);
if (comparable == null) {
this.warn(
"Property value not found: " + s4 + ", property: " + s2 + ", block: " + block);
return null;
}
list.add(comparable);
}
}
}
if (map.isEmpty()) {
return null;
} else {
List<Integer> list1 = new ArrayList();
for (int k = 0; k < 16; ++k) {
int l = k;
try {
IBlockState iblockstate1 = this.getStateFromMeta(block, l);
if (this.matchState(iblockstate1, map)) {
list1.add(Integer.valueOf(l));
}
} catch (IllegalArgumentException var18) {
;
}
}
if (list1.size() == 16) {
return null;
} else {
int[] aint1 = new int[list1.size()];
for (int i1 = 0; i1 < aint1.length; ++i1) {
aint1[i1] = ((Integer) list1.get(i1)).intValue();
}
return aint1;
}
}
}
}
}
private IBlockState getStateFromMeta(Block block, int md) {
try {
IBlockState iblockstate = block.getStateFromMeta(md);
if (block == Blocks.double_plant && md > 7) {
IBlockState iblockstate1 = block.getStateFromMeta(md & 7);
iblockstate = iblockstate.withProperty(BlockDoublePlant.VARIANT,
iblockstate1.getValue(BlockDoublePlant.VARIANT));
}
return iblockstate;
} catch (IllegalArgumentException var5) {
return block.getDefaultState();
}
}
public static Comparable parsePropertyValue(IProperty prop, String valStr) {
Class oclass = prop.getValueClass();
Comparable comparable = parseValue(valStr, oclass);
if (comparable == null) {
Collection collection = prop.getAllowedValues();
comparable = getPropertyValue(valStr, collection);
}
return comparable;
}
public static Comparable getPropertyValue(String value, Collection propertyValues) {
for (Object comparable0 : propertyValues) {
Comparable comparable = (Comparable) comparable0;
if (getValueName(comparable).equals(value)) {
return comparable;
}
}
return null;
}
private static Object getValueName(Comparable obj) {
if (obj instanceof IStringSerializable) {
IStringSerializable istringserializable = (IStringSerializable) obj;
return istringserializable.getName();
} else {
return obj.toString();
}
}
public static Comparable parseValue(String str, Class cls) {
if (cls == String.class) {
return str;
} else if (cls == Boolean.class) {
return Boolean.valueOf(str);
} else if (cls == Float.class) {
return Float.valueOf(str);
} else if (cls == Double.class) {
return Double.valueOf(str);
} else if (cls == Integer.class) {
return Integer.valueOf(str);
} else {
return cls == Long.class ? Long.valueOf(str) : null;
}
}
public boolean matchState(IBlockState bs, Map<IProperty, List<Comparable>> mapPropValues) {
for (IProperty iproperty : mapPropValues.keySet()) {
List<Comparable> list = (List) mapPropValues.get(iproperty);
Comparable comparable = bs.getValue(iproperty);
if (comparable == null) {
return false;
}
if (!list.contains(comparable)) {
return false;
}
}
return true;
}
public BiomeGenBase[] parseBiomes(String str) {
if (str == null) {
return null;
} else {
str = str.trim();
boolean flag = false;
if (str.startsWith("!")) {
flag = true;
str = str.substring(1);
}
String[] astring = Config.tokenize(str, " ");
List list = new ArrayList();
for (int i = 0; i < astring.length; ++i) {
String s = astring[i];
BiomeGenBase biomegenbase = this.findBiome(s);
if (biomegenbase == null) {
this.warn("Biome not found: " + s);
} else {
list.add(biomegenbase);
}
}
if (flag) {
List<BiomeGenBase> list1 = new ArrayList(Arrays.asList(BiomeGenBase.getBiomeGenArray()));
list1.removeAll(list);
list = list1;
}
BiomeGenBase[] abiomegenbase = (BiomeGenBase[]) ((BiomeGenBase[]) list
.toArray(new BiomeGenBase[list.size()]));
return abiomegenbase;
}
}
public BiomeGenBase findBiome(String biomeName) {
biomeName = biomeName.toLowerCase();
if (biomeName.equals("nether")) {
return BiomeGenBase.hell;
} else {
BiomeGenBase[] abiomegenbase = BiomeGenBase.getBiomeGenArray();
for (int i = 0; i < abiomegenbase.length; ++i) {
BiomeGenBase biomegenbase = abiomegenbase[i];
if (biomegenbase != null) {
String s = biomegenbase.biomeName.replace(" ", "").toLowerCase();
if (s.equals(biomeName)) {
return biomegenbase;
}
}
}
return null;
}
}
public int parseInt(String str, int defVal) {
if (str == null) {
return defVal;
} else {
str = str.trim();
int i = Config.parseInt(str, -1);
if (i < 0) {
this.warn("Invalid number: " + str);
return defVal;
} else {
return i;
}
}
}
public int[] parseIntList(String str) {
if (str == null) {
return null;
} else {
List<Integer> list = new ArrayList();
String[] astring = Config.tokenize(str, " ,");
for (int i = 0; i < astring.length; ++i) {
String s = astring[i];
if (s.contains("-")) {
String[] astring1 = Config.tokenize(s, "-");
if (astring1.length != 2) {
this.warn("Invalid interval: " + s + ", when parsing: " + str);
} else {
int k = Config.parseInt(astring1[0], -1);
int l = Config.parseInt(astring1[1], -1);
if (k >= 0 && l >= 0 && k <= l) {
for (int i1 = k; i1 <= l; ++i1) {
list.add(Integer.valueOf(i1));
}
} else {
this.warn("Invalid interval: " + s + ", when parsing: " + str);
}
}
} else {
int j = Config.parseInt(s, -1);
if (j < 0) {
this.warn("Invalid number: " + s + ", when parsing: " + str);
} else {
list.add(Integer.valueOf(j));
}
}
}
int[] aint = new int[list.size()];
for (int j1 = 0; j1 < aint.length; ++j1) {
aint[j1] = ((Integer) list.get(j1)).intValue();
}
return aint;
}
}
public boolean[] parseFaces(String str, boolean[] defVal) {
if (str == null) {
return defVal;
} else {
EnumSet enumset = EnumSet.allOf(EnumFacing.class);
String[] astring = Config.tokenize(str, " ,");
for (int i = 0; i < astring.length; ++i) {
String s = astring[i];
if (s.equals("sides")) {
enumset.add(EnumFacing.NORTH);
enumset.add(EnumFacing.SOUTH);
enumset.add(EnumFacing.WEST);
enumset.add(EnumFacing.EAST);
} else if (s.equals("all")) {
enumset.addAll(Arrays.asList(EnumFacing._VALUES));
} else {
EnumFacing enumfacing = this.parseFace(s);
if (enumfacing != null) {
enumset.add(enumfacing);
}
}
}
boolean[] aboolean = new boolean[EnumFacing._VALUES.length];
for (int j = 0; j < aboolean.length; ++j) {
aboolean[j] = enumset.contains(EnumFacing._VALUES[j]);
}
return aboolean;
}
}
public EnumFacing parseFace(String str) {
str = str.toLowerCase();
if (!str.equals("bottom") && !str.equals("down")) {
if (!str.equals("top") && !str.equals("up")) {
if (str.equals("north")) {
return EnumFacing.NORTH;
} else if (str.equals("south")) {
return EnumFacing.SOUTH;
} else if (str.equals("east")) {
return EnumFacing.EAST;
} else if (str.equals("west")) {
return EnumFacing.WEST;
} else {
Config.warn("Unknown face: " + str);
return null;
}
} else {
return EnumFacing.UP;
}
} else {
return EnumFacing.DOWN;
}
}
public void dbg(String str) {
Config.dbg("" + this.context + ": " + str);
}
public void warn(String str) {
Config.warn("" + this.context + ": " + str);
}
public RangeListInt parseRangeListInt(String str) {
if (str == null) {
return null;
} else {
RangeListInt rangelistint = new RangeListInt();
String[] astring = Config.tokenize(str, " ,");
for (int i = 0; i < astring.length; ++i) {
String s = astring[i];
RangeInt rangeint = this.parseRangeInt(s);
if (rangeint == null) {
return null;
}
rangelistint.addRange(rangeint);
}
return rangelistint;
}
}
private RangeInt parseRangeInt(String str) {
if (str == null) {
return null;
} else if (str.indexOf(45) >= 0) {
String[] astring = Config.tokenize(str, "-");
if (astring.length != 2) {
this.warn("Invalid range: " + str);
return null;
} else {
int j = Config.parseInt(astring[0], -1);
int k = Config.parseInt(astring[1], -1);
if (j >= 0 && k >= 0) {
return new RangeInt(j, k);
} else {
this.warn("Invalid range: " + str);
return null;
}
}
} else {
int i = Config.parseInt(str, -1);
if (i < 0) {
this.warn("Invalid integer: " + str);
return null;
} else {
return new RangeInt(i, i);
}
}
}
public boolean parseBoolean(String str, boolean defVal) {
if (str == null) {
return defVal;
} else {
String s = str.toLowerCase().trim();
if (s.equals("true")) {
return true;
} else if (s.equals("false")) {
return false;
} else {
this.warn("Invalid boolean: " + str);
return defVal;
}
}
}
public Boolean parseBooleanObject(String str) {
if (str == null) {
return null;
} else {
String s = str.toLowerCase().trim();
if (s.equals("true")) {
return Boolean.TRUE;
} else if (s.equals("false")) {
return Boolean.FALSE;
} else {
this.warn("Invalid boolean: " + str);
return null;
}
}
}
public static int parseColor(String str, int defVal) {
if (str == null) {
return defVal;
} else {
str = str.trim();
try {
int i = Integer.parseInt(str, 16) & 16777215;
return i;
} catch (NumberFormatException var3) {
return defVal;
}
}
}
public static int parseColor4(String str, int defVal) {
if (str == null) {
return defVal;
} else {
str = str.trim();
try {
int i = (int) (Long.parseLong(str, 16) & -1L);
return i;
} catch (NumberFormatException var3) {
return defVal;
}
}
}
public EnumWorldBlockLayer parseBlockRenderLayer(String str, EnumWorldBlockLayer def) {
if (str == null) {
return def;
} else {
str = str.toLowerCase().trim();
EnumWorldBlockLayer[] aenumworldblocklayer = EnumWorldBlockLayer.values();
for (int i = 0; i < aenumworldblocklayer.length; ++i) {
EnumWorldBlockLayer enumworldblocklayer = aenumworldblocklayer[i];
if (str.equals(enumworldblocklayer.name().toLowerCase())) {
return enumworldblocklayer;
}
}
return def;
}
}
public <T> T parseObject(String str, T[] objs, INameGetter nameGetter, String property) {
if (str == null) {
return (T) null;
} else {
String s = str.toLowerCase().trim();
for (int i = 0; i < objs.length; ++i) {
T t = objs[i];
String s1 = nameGetter.getName(t);
if (s1 != null && s1.toLowerCase().equals(s)) {
return t;
}
}
this.warn("Invalid " + property + ": " + str);
return (T) null;
}
}
public <T> T[] parseObjects(String str, T[] objs, INameGetter nameGetter, String property, T[] errValue) {
if (str == null) {
return null;
} else {
str = str.toLowerCase().trim();
String[] astring = Config.tokenize(str, " ");
T[] at = (T[]) Array.newInstance(objs.getClass().getComponentType(), astring.length);
for (int i = 0; i < astring.length; ++i) {
String s = astring[i];
T t = this.parseObject(s, objs, nameGetter, property);
if (t == null) {
return (T[]) errValue;
}
at[i] = t;
}
return at;
}
}
public Enum parseEnum(String str, Enum[] enums, String property) {
return (Enum) this.parseObject(str, enums, NAME_GETTER_ENUM, property);
}
public Enum[] parseEnums(String str, Enum[] enums, String property, Enum[] errValue) {
return (Enum[]) this.parseObjects(str, enums, NAME_GETTER_ENUM, property, errValue);
}
public EnumDyeColor[] parseDyeColors(String str, String property, EnumDyeColor[] errValue) {
return (EnumDyeColor[]) this.parseObjects(str, EnumDyeColor.values(), NAME_GETTER_DYE_COLOR, property,
errValue);
}
public Weather[] parseWeather(String str, String property, Weather[] errValue) {
return (Weather[]) this.parseObjects(str, Weather.values(), NAME_GETTER_ENUM, property, errValue);
}
public NbtTagValue parseNbtTagValue(String path, String value) {
return path != null && value != null ? new NbtTagValue(path, value) : null;
}
private static int parseProfessionId(String str) {
int i = Config.parseInt(str, -1);
return i >= 0 ? i
: (str.equals("farmer") ? 0
: (str.equals("librarian") ? 1
: (str.equals("priest") ? 2
: (str.equals("blacksmith") ? 3
: (str.equals("butcher") ? 4 : (str.equals("nitwit") ? 5 : -1))))));
}
private static int[] parseCareerIds(int prof, String str) {
Set<Integer> set = new HashSet();
String[] astring = Config.tokenize(str, ",");
for (int i = 0; i < astring.length; ++i) {
String s = astring[i];
int j = parseCareerId(prof, s);
if (j < 0) {
return null;
}
set.add(Integer.valueOf(j));
}
Integer[] ainteger = (Integer[]) ((Integer[]) set.toArray(new Integer[set.size()]));
int[] aint = new int[ainteger.length];
for (int k = 0; k < aint.length; ++k) {
aint[k] = ainteger[k].intValue();
}
return aint;
}
private static int parseCareerId(int prof, String str) {
int i = Config.parseInt(str, -1);
if (i >= 0) {
return i;
} else {
if (prof == 0) {
if (str.equals("farmer")) {
return 1;
}
if (str.equals("fisherman")) {
return 2;
}
if (str.equals("shepherd")) {
return 3;
}
if (str.equals("fletcher")) {
return 4;
}
}
if (prof == 1) {
if (str.equals("librarian")) {
return 1;
}
if (str.equals("cartographer")) {
return 2;
}
}
if (prof == 2 && str.equals("cleric")) {
return 1;
} else {
if (prof == 3) {
if (str.equals("armor")) {
return 1;
}
if (str.equals("weapon")) {
return 2;
}
if (str.equals("tool")) {
return 3;
}
}
if (prof == 4) {
if (str.equals("butcher")) {
return 1;
}
if (str.equals("leather")) {
return 2;
}
}
return prof == 5 && str.equals("nitwit") ? 1 : -1;
}
}
}
public int[] parseItems(String str) {
str = str.trim();
Set<Integer> set = new TreeSet();
String[] astring = Config.tokenize(str, " ");
for (int i = 0; i < astring.length; ++i) {
String s = astring[i];
ResourceLocation resourcelocation = new ResourceLocation(s);
Item item = (Item) Item.itemRegistry.getObject(resourcelocation);
if (item == null) {
this.warn("Item not found: " + s);
} else {
int j = Item.getIdFromItem(item);
if (j < 0) {
this.warn("Item has no ID: " + item + ", name: " + s);
} else {
set.add(Integer.valueOf(j));
}
}
}
Integer[] ainteger = (Integer[]) ((Integer[]) set.toArray(new Integer[set.size()]));
int[] aint = Config.toPrimitive(ainteger);
return aint;
}
}

View File

@ -0,0 +1,46 @@
package net.optifine.config;
public class GlVersion {
private int major;
private int minor;
private int release;
private String suffix;
public GlVersion(int major, int minor) {
this(major, minor, 0);
}
public GlVersion(int major, int minor, int release) {
this(major, minor, release, (String) null);
}
public GlVersion(int major, int minor, int release, String suffix) {
this.major = major;
this.minor = minor;
this.release = release;
this.suffix = suffix;
}
public int getMajor() {
return this.major;
}
public int getMinor() {
return this.minor;
}
public int getRelease() {
return this.release;
}
public int toInt() {
return this.minor > 9 ? this.major * 100 + this.minor
: (this.release > 9 ? this.major * 100 + this.minor * 10 + 9
: this.major * 100 + this.minor * 10 + this.release);
}
public String toString() {
return this.suffix == null ? "" + this.major + "." + this.minor + "." + this.release
: "" + this.major + "." + this.minor + "." + this.release + this.suffix;
}
}

View File

@ -0,0 +1,5 @@
package net.optifine.config;
public interface INameGetter<T> {
String getName(T var1);
}

View File

@ -0,0 +1,7 @@
package net.optifine.config;
import net.minecraft.util.ResourceLocation;
public interface IObjectLocator {
Object getObject(ResourceLocation var1);
}

View File

@ -0,0 +1,5 @@
package net.optifine.config;
public interface IParserInt {
int parse(String var1, int var2);
}

View File

@ -0,0 +1,11 @@
package net.optifine.config;
import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
public class ItemLocator implements IObjectLocator {
public Object getObject(ResourceLocation loc) {
Item item = Item.getByNameOrId(loc.toString());
return item;
}
}

View File

@ -0,0 +1,61 @@
package net.optifine.config;
import net.minecraft.block.state.BlockStateBase;
import net.optifine.Config;
public class MatchBlock {
private int blockId = -1;
private int[] metadatas = null;
public MatchBlock(int blockId) {
this.blockId = blockId;
}
public MatchBlock(int blockId, int metadata) {
this.blockId = blockId;
if (metadata >= 0 && metadata <= 15) {
this.metadatas = new int[] { metadata };
}
}
public MatchBlock(int blockId, int[] metadatas) {
this.blockId = blockId;
this.metadatas = metadatas;
}
public int getBlockId() {
return this.blockId;
}
public int[] getMetadatas() {
return this.metadatas;
}
public boolean matches(BlockStateBase blockState) {
return blockState.getBlockId() != this.blockId ? false
: Matches.metadata(blockState.getMetadata(), this.metadatas);
}
public boolean matches(int id, int metadata) {
return id != this.blockId ? false : Matches.metadata(metadata, this.metadatas);
}
public void addMetadata(int metadata) {
if (this.metadatas != null) {
if (metadata >= 0 && metadata <= 15) {
for (int i = 0; i < this.metadatas.length; ++i) {
if (this.metadatas[i] == metadata) {
return;
}
}
this.metadatas = Config.addIntToArray(this.metadatas, metadata);
}
}
}
public String toString() {
return "" + this.blockId + ":" + Config.arrayToString(this.metadatas);
}
}

View File

@ -0,0 +1,97 @@
package net.optifine.config;
import net.lax1dude.eaglercraft.v1_8.minecraft.EaglerTextureAtlasSprite;
import net.minecraft.block.state.BlockStateBase;
import net.minecraft.world.biome.BiomeGenBase;
public class Matches {
public static boolean block(BlockStateBase blockStateBase, MatchBlock[] matchBlocks) {
if (matchBlocks == null) {
return true;
} else {
for (int i = 0; i < matchBlocks.length; ++i) {
MatchBlock matchblock = matchBlocks[i];
if (matchblock.matches(blockStateBase)) {
return true;
}
}
return false;
}
}
public static boolean block(int blockId, int metadata, MatchBlock[] matchBlocks) {
if (matchBlocks == null) {
return true;
} else {
for (int i = 0; i < matchBlocks.length; ++i) {
MatchBlock matchblock = matchBlocks[i];
if (matchblock.matches(blockId, metadata)) {
return true;
}
}
return false;
}
}
public static boolean blockId(int blockId, MatchBlock[] matchBlocks) {
if (matchBlocks == null) {
return true;
} else {
for (int i = 0; i < matchBlocks.length; ++i) {
MatchBlock matchblock = matchBlocks[i];
if (matchblock.getBlockId() == blockId) {
return true;
}
}
return false;
}
}
public static boolean metadata(int metadata, int[] metadatas) {
if (metadatas == null) {
return true;
} else {
for (int i = 0; i < metadatas.length; ++i) {
if (metadatas[i] == metadata) {
return true;
}
}
return false;
}
}
public static boolean sprite(EaglerTextureAtlasSprite sprite, EaglerTextureAtlasSprite[] sprites) {
if (sprites == null) {
return true;
} else {
for (int i = 0; i < sprites.length; ++i) {
if (sprites[i] == sprite) {
return true;
}
}
return false;
}
}
public static boolean biome(BiomeGenBase biome, BiomeGenBase[] biomes) {
if (biomes == null) {
return true;
} else {
for (int i = 0; i < biomes.length; ++i) {
if (biomes[i] == biome) {
return true;
}
}
return false;
}
}
}

View File

@ -0,0 +1,254 @@
package net.optifine.config;
import java.util.Arrays;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringEscapeUtils;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagByte;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagDouble;
import net.minecraft.nbt.NBTTagFloat;
import net.minecraft.nbt.NBTTagInt;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagLong;
import net.minecraft.nbt.NBTTagShort;
import net.minecraft.nbt.NBTTagString;
import net.optifine.Config;
import net.optifine.util.StrUtils;
public class NbtTagValue {
private String[] parents = null;
private String name = null;
private boolean negative = false;
private int type = 0;
private String value = null;
private int valueFormat = 0;
private static final int TYPE_TEXT = 0;
private static final int TYPE_PATTERN = 1;
private static final int TYPE_IPATTERN = 2;
private static final int TYPE_REGEX = 3;
private static final int TYPE_IREGEX = 4;
private static final String PREFIX_PATTERN = "pattern:";
private static final String PREFIX_IPATTERN = "ipattern:";
private static final String PREFIX_REGEX = "regex:";
private static final String PREFIX_IREGEX = "iregex:";
private static final int FORMAT_DEFAULT = 0;
private static final int FORMAT_HEX_COLOR = 1;
private static final String PREFIX_HEX_COLOR = "#";
private static final Pattern PATTERN_HEX_COLOR = Pattern.compile("^#[0-9a-f]{6}+$");
public NbtTagValue(String tag, String value) {
String[] astring = Config.tokenize(tag, ".");
this.parents = (String[]) Arrays.copyOfRange(astring, 0, astring.length - 1);
this.name = astring[astring.length - 1];
if (value.startsWith("!")) {
this.negative = true;
value = value.substring(1);
}
if (value.startsWith("pattern:")) {
this.type = 1;
value = value.substring("pattern:".length());
} else if (value.startsWith("ipattern:")) {
this.type = 2;
value = value.substring("ipattern:".length()).toLowerCase();
} else if (value.startsWith("regex:")) {
this.type = 3;
value = value.substring("regex:".length());
} else if (value.startsWith("iregex:")) {
this.type = 4;
value = value.substring("iregex:".length()).toLowerCase();
} else {
this.type = 0;
}
value = StringEscapeUtils.unescapeJava(value);
if (this.type == 0 && PATTERN_HEX_COLOR.matcher(value).matches()) {
this.valueFormat = 1;
}
this.value = value;
}
public boolean matches(NBTTagCompound nbt) {
return this.negative ? !this.matchesCompound(nbt) : this.matchesCompound(nbt);
}
public boolean matchesCompound(NBTTagCompound nbt) {
if (nbt == null) {
return false;
} else {
NBTBase nbtbase = nbt;
for (int i = 0; i < this.parents.length; ++i) {
String s = this.parents[i];
nbtbase = getChildTag(nbtbase, s);
if (nbtbase == null) {
return false;
}
}
if (this.name.equals("*")) {
return this.matchesAnyChild(nbtbase);
} else {
nbtbase = getChildTag(nbtbase, this.name);
if (nbtbase == null) {
return false;
} else if (this.matchesBase(nbtbase)) {
return true;
} else {
return false;
}
}
}
}
private boolean matchesAnyChild(NBTBase tagBase) {
if (tagBase instanceof NBTTagCompound) {
NBTTagCompound nbttagcompound = (NBTTagCompound) tagBase;
for (String s : nbttagcompound.getKeySet()) {
NBTBase nbtbase = nbttagcompound.getTag(s);
if (this.matchesBase(nbtbase)) {
return true;
}
}
}
if (tagBase instanceof NBTTagList) {
NBTTagList nbttaglist = (NBTTagList) tagBase;
int i = nbttaglist.tagCount();
for (int j = 0; j < i; ++j) {
NBTBase nbtbase1 = nbttaglist.get(j);
if (this.matchesBase(nbtbase1)) {
return true;
}
}
}
return false;
}
private static NBTBase getChildTag(NBTBase tagBase, String tag) {
if (tagBase instanceof NBTTagCompound) {
NBTTagCompound nbttagcompound = (NBTTagCompound) tagBase;
return nbttagcompound.getTag(tag);
} else if (tagBase instanceof NBTTagList) {
NBTTagList nbttaglist = (NBTTagList) tagBase;
if (tag.equals("count")) {
return new NBTTagInt(nbttaglist.tagCount());
} else {
int i = Config.parseInt(tag, -1);
return i >= 0 && i < nbttaglist.tagCount() ? nbttaglist.get(i) : null;
}
} else {
return null;
}
}
public boolean matchesBase(NBTBase nbtBase) {
if (nbtBase == null) {
return false;
} else {
String s = getNbtString(nbtBase, this.valueFormat);
return this.matchesValue(s);
}
}
public boolean matchesValue(String nbtValue) {
if (nbtValue == null) {
return false;
} else {
switch (this.type) {
case 0:
return nbtValue.equals(this.value);
case 1:
return this.matchesPattern(nbtValue, this.value);
case 2:
return this.matchesPattern(nbtValue.toLowerCase(), this.value);
case 3:
return this.matchesRegex(nbtValue, this.value);
case 4:
return this.matchesRegex(nbtValue.toLowerCase(), this.value);
default:
throw new IllegalArgumentException("Unknown NbtTagValue type: " + this.type);
}
}
}
private boolean matchesPattern(String str, String pattern) {
return StrUtils.equalsMask(str, pattern, '*', '?');
}
private boolean matchesRegex(String str, String regex) {
return str.matches(regex);
}
private static String getNbtString(NBTBase nbtBase, int format) {
if (nbtBase == null) {
return null;
} else if (nbtBase instanceof NBTTagString) {
NBTTagString nbttagstring = (NBTTagString) nbtBase;
return nbttagstring.getString();
} else if (nbtBase instanceof NBTTagInt) {
NBTTagInt nbttagint = (NBTTagInt) nbtBase;
return format == 1 ? "#" + StrUtils.fillLeft(Integer.toHexString(nbttagint.getInt()), 6, '0')
: Integer.toString(nbttagint.getInt());
} else if (nbtBase instanceof NBTTagByte) {
NBTTagByte nbttagbyte = (NBTTagByte) nbtBase;
return Byte.toString(nbttagbyte.getByte());
} else if (nbtBase instanceof NBTTagShort) {
NBTTagShort nbttagshort = (NBTTagShort) nbtBase;
return Short.toString(nbttagshort.getShort());
} else if (nbtBase instanceof NBTTagLong) {
NBTTagLong nbttaglong = (NBTTagLong) nbtBase;
return Long.toString(nbttaglong.getLong());
} else if (nbtBase instanceof NBTTagFloat) {
NBTTagFloat nbttagfloat = (NBTTagFloat) nbtBase;
return Float.toString(nbttagfloat.getFloat());
} else if (nbtBase instanceof NBTTagDouble) {
NBTTagDouble nbttagdouble = (NBTTagDouble) nbtBase;
return Double.toString(nbttagdouble.getDouble());
} else {
return nbtBase.toString();
}
}
public String toString() {
StringBuffer stringbuffer = new StringBuffer();
for (int i = 0; i < this.parents.length; ++i) {
String s = this.parents[i];
if (i > 0) {
stringbuffer.append(".");
}
stringbuffer.append(s);
}
if (stringbuffer.length() > 0) {
stringbuffer.append(".");
}
stringbuffer.append(this.name);
stringbuffer.append(" = ");
stringbuffer.append(this.value);
return stringbuffer.toString();
}
}

View File

@ -0,0 +1,10 @@
package net.optifine.config;
import net.minecraft.enchantment.Enchantment;
public class ParserEnchantmentId implements IParserInt {
public int parse(String str, int defVal) {
Enchantment enchantment = Enchantment.getEnchantmentByLocation(str);
return enchantment == null ? defVal : enchantment.effectId;
}
}

View File

@ -0,0 +1,27 @@
package net.optifine.config;
public class RangeInt {
private int min;
private int max;
public RangeInt(int min, int max) {
this.min = Math.min(min, max);
this.max = Math.max(min, max);
}
public boolean isInRange(int val) {
return val < this.min ? false : val <= this.max;
}
public int getMin() {
return this.min;
}
public int getMax() {
return this.max;
}
public String toString() {
return "min: " + this.min + ", max: " + this.max;
}
}

View File

@ -0,0 +1,57 @@
package net.optifine.config;
public class RangeListInt {
private RangeInt[] ranges = new RangeInt[0];
public RangeListInt() {
}
public RangeListInt(RangeInt ri) {
this.addRange(ri);
}
public void addRange(RangeInt ri) {
RangeInt[] newRanges = new RangeInt[ranges.length + 1];
System.arraycopy(ranges, 0, newRanges, 0, ranges.length);
newRanges[ranges.length] = ri;
this.ranges = newRanges;
}
public boolean isInRange(int val) {
for (int i = 0; i < this.ranges.length; ++i) {
RangeInt rangeint = this.ranges[i];
if (rangeint.isInRange(val)) {
return true;
}
}
return false;
}
public int getCountRanges() {
return this.ranges.length;
}
public RangeInt getRange(int i) {
return this.ranges[i];
}
public String toString() {
StringBuffer stringbuffer = new StringBuffer();
stringbuffer.append("[");
for (int i = 0; i < this.ranges.length; ++i) {
RangeInt rangeint = this.ranges[i];
if (i > 0) {
stringbuffer.append(", ");
}
stringbuffer.append(rangeint.toString());
}
stringbuffer.append("]");
return stringbuffer.toString();
}
}

View File

@ -0,0 +1,18 @@
package net.optifine.config;
import net.minecraft.world.World;
public enum Weather {
CLEAR, RAIN, THUNDER;
public static Weather getWeather(World world, float partialTicks) {
float f = world.getThunderStrength(partialTicks);
if (f > 0.5F) {
return THUNDER;
} else {
float f1 = world.getRainStrength(partialTicks);
return f1 > 0.5F ? RAIN : CLEAR;
}
}
}

View File

@ -0,0 +1,100 @@
package net.optifine.model;
import com.google.common.collect.ImmutableList;
import java.util.List;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.resources.model.IBakedModel;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumWorldBlockLayer;
import net.minecraft.world.IBlockAccess;
import net.optifine.BetterGrass;
import net.optifine.Config;
import net.optifine.ConnectedTextures;
import net.optifine.SmartLeaves;
import net.optifine.render.RenderEnv;
public class BlockModelCustomizer {
private static final List<BakedQuad> NO_QUADS = ImmutableList.<BakedQuad>of();
public static IBakedModel getRenderModel(IBakedModel modelIn, IBlockState stateIn, RenderEnv renderEnv) {
if (renderEnv.isSmartLeaves()) {
modelIn = SmartLeaves.getLeavesModel(modelIn, stateIn);
}
return modelIn;
}
public static List<BakedQuad> getRenderQuads(List<BakedQuad> quads, IBlockAccess worldIn, IBlockState stateIn,
BlockPos posIn, EnumFacing enumfacing, EnumWorldBlockLayer layer, long rand, RenderEnv renderEnv) {
if (enumfacing != null) {
if (renderEnv.isSmartLeaves()
&& SmartLeaves.isSameLeaves(worldIn.getBlockState(posIn.offset(enumfacing)), stateIn)) {
return NO_QUADS;
}
if (!renderEnv.isBreakingAnimation(quads) && Config.isBetterGrass()) {
quads = BetterGrass.getFaceQuads(worldIn, stateIn, posIn, enumfacing, quads);
}
}
List<BakedQuad> list = renderEnv.getListQuadsCustomizer();
list.clear();
for (int i = 0; i < quads.size(); ++i) {
BakedQuad bakedquad = (BakedQuad) quads.get(i);
BakedQuad[] abakedquad = getRenderQuads(bakedquad, worldIn, stateIn, posIn, enumfacing, rand, renderEnv);
if (i == 0 && quads.size() == 1 && abakedquad.length == 1 && abakedquad[0] == bakedquad
/* && bakedquad.getQuadEmissive() == null */) {
return quads;
}
for (int j = 0; j < abakedquad.length; ++j) {
BakedQuad bakedquad1 = abakedquad[j];
list.add(bakedquad1);
// if (bakedquad1.getQuadEmissive() != null) {
// renderEnv.getListQuadsOverlay(getEmissiveLayer(layer)).addQuad(bakedquad1.getQuadEmissive(),
// stateIn);
// renderEnv.setOverlaysRendered(true);
// }
}
}
return list;
}
private static EnumWorldBlockLayer getEmissiveLayer(EnumWorldBlockLayer layer) {
return layer != null && layer != EnumWorldBlockLayer.SOLID ? layer : EnumWorldBlockLayer.CUTOUT_MIPPED;
}
private static BakedQuad[] getRenderQuads(BakedQuad quad, IBlockAccess worldIn, IBlockState stateIn, BlockPos posIn,
EnumFacing enumfacing, long rand, RenderEnv renderEnv) {
if (renderEnv.isBreakingAnimation(quad)) {
return renderEnv.getArrayQuadsCtm(quad);
} else {
// BakedQuad bakedquad = quad;
if (Config.isConnectedTextures()) {
BakedQuad[] abakedquad = ConnectedTextures.getConnectedTexture(worldIn, stateIn, posIn, quad,
renderEnv);
if (abakedquad.length != 1 || abakedquad[0] != quad) {
return abakedquad;
}
}
// if (Config.isNaturalTextures()) {
// quad = NaturalTextures.getNaturalTexture(posIn, quad);
//
// if (quad != bakedquad) {
// return renderEnv.getArrayQuadsCtm(quad);
// }
// }
return renderEnv.getArrayQuadsCtm(quad);
}
}
}

View File

@ -0,0 +1,173 @@
package net.optifine.model;
import java.util.ArrayList;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.minecraft.EaglerTextureAtlasSprite;
import net.lax1dude.eaglercraft.v1_8.vector.Vector3f;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.BlockFaceUV;
import net.minecraft.client.renderer.block.model.BlockPartFace;
import net.minecraft.client.renderer.block.model.BlockPartRotation;
import net.minecraft.client.renderer.block.model.BreakingFour;
import net.minecraft.client.renderer.block.model.FaceBakery;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.resources.model.IBakedModel;
import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.client.resources.model.ModelRotation;
import net.minecraft.client.resources.model.SimpleBakedModel;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
public class BlockModelUtils {
private static final float VERTEX_COORD_ACCURACY = 1.0E-6F;
public static IBakedModel makeModelCube(String spriteName, int tintIndex) {
EaglerTextureAtlasSprite textureatlassprite = Minecraft.getMinecraft().getTextureMapBlocks()
.getAtlasSprite(spriteName);
return makeModelCube(textureatlassprite, tintIndex);
}
public static IBakedModel makeModelCube(EaglerTextureAtlasSprite sprite, int tintIndex) {
List list = new ArrayList();
EnumFacing[] aenumfacing = EnumFacing._VALUES;
List<List<BakedQuad>> list1 = new ArrayList();
for (int i = 0; i < aenumfacing.length; ++i) {
EnumFacing enumfacing = aenumfacing[i];
List list2 = new ArrayList();
list2.add(makeBakedQuad(enumfacing, sprite, tintIndex));
list1.add(list2);
}
IBakedModel ibakedmodel = new SimpleBakedModel(list, list1, true, true, sprite, ItemCameraTransforms.DEFAULT);
return ibakedmodel;
}
public static IBakedModel joinModelsCube(IBakedModel modelBase, IBakedModel modelAdd) {
List<BakedQuad> list = new ArrayList();
list.addAll(modelBase.getGeneralQuads());
list.addAll(modelAdd.getGeneralQuads());
EnumFacing[] aenumfacing = EnumFacing._VALUES;
List list1 = new ArrayList();
for (int i = 0; i < aenumfacing.length; ++i) {
EnumFacing enumfacing = aenumfacing[i];
List list2 = new ArrayList();
list2.addAll(modelBase.getFaceQuads(enumfacing));
list2.addAll(modelAdd.getFaceQuads(enumfacing));
list1.add(list2);
}
boolean flag = modelBase.isAmbientOcclusion();
boolean flag1 = modelBase.isBuiltInRenderer();
EaglerTextureAtlasSprite textureatlassprite = modelBase.getParticleTexture();
ItemCameraTransforms itemcameratransforms = modelBase.getItemCameraTransforms();
IBakedModel ibakedmodel = new SimpleBakedModel(list, list1, flag, flag1, textureatlassprite,
itemcameratransforms);
return ibakedmodel;
}
public static BakedQuad makeBakedQuad(EnumFacing facing, EaglerTextureAtlasSprite sprite, int tintIndex) {
Vector3f vector3f = new Vector3f(0.0F, 0.0F, 0.0F);
Vector3f vector3f1 = new Vector3f(16.0F, 16.0F, 16.0F);
BlockFaceUV blockfaceuv = new BlockFaceUV(new float[] { 0.0F, 0.0F, 16.0F, 16.0F }, 0);
BlockPartFace blockpartface = new BlockPartFace(facing, tintIndex, "#" + facing.getName(), blockfaceuv);
ModelRotation modelrotation = ModelRotation.X0_Y0;
BlockPartRotation blockpartrotation = null;
boolean flag = false;
boolean flag1 = true;
FaceBakery facebakery = new FaceBakery();
BakedQuad bakedquad = facebakery.makeBakedQuad(vector3f, vector3f1, blockpartface, sprite, facing,
modelrotation, blockpartrotation, flag, flag1);
return bakedquad;
}
public static IBakedModel makeModel(String modelName, String spriteOldName, String spriteNewName) {
TextureMap texturemap = Minecraft.getMinecraft().getTextureMapBlocks();
EaglerTextureAtlasSprite textureatlassprite = texturemap.getAtlasSprite(spriteOldName); // getSpriteSafe
EaglerTextureAtlasSprite textureatlassprite1 = texturemap.getAtlasSprite(spriteNewName);
return makeModel(modelName, textureatlassprite, textureatlassprite1);
}
public static IBakedModel makeModel(String modelName, EaglerTextureAtlasSprite spriteOld,
EaglerTextureAtlasSprite spriteNew) {
if (spriteOld != null && spriteNew != null) {
ModelManager modelmanager = Minecraft.getMinecraft().getModelManager();
if (modelmanager == null) {
return null;
} else {
ModelResourceLocation modelresourcelocation = new ModelResourceLocation(modelName, "normal");
IBakedModel ibakedmodel = modelmanager.getModel(modelresourcelocation);
if (ibakedmodel != null && ibakedmodel != modelmanager.getMissingModel()) {
IBakedModel ibakedmodel1 = ModelUtils.duplicateModel(ibakedmodel);
EnumFacing[] aenumfacing = EnumFacing._VALUES;
for (int i = 0; i < aenumfacing.length; ++i) {
EnumFacing enumfacing = aenumfacing[i];
List<BakedQuad> list = ibakedmodel1.getFaceQuads(enumfacing);
replaceTexture(list, spriteOld, spriteNew);
}
List<BakedQuad> list1 = ibakedmodel1.getGeneralQuads();
replaceTexture(list1, spriteOld, spriteNew);
return ibakedmodel1;
} else {
return null;
}
}
} else {
return null;
}
}
private static void replaceTexture(List<BakedQuad> quads, EaglerTextureAtlasSprite spriteOld,
EaglerTextureAtlasSprite spriteNew) {
List<BakedQuad> list = new ArrayList();
for (BakedQuad bakedquad : quads) {
if (bakedquad.getSprite() == spriteOld) {
bakedquad = new BreakingFour(bakedquad, spriteNew);
}
list.add(bakedquad);
}
quads.clear();
quads.addAll(list);
}
public static void snapVertexPosition(Vector3f pos) {
pos.setX(snapVertexCoord(pos.getX()));
pos.setY(snapVertexCoord(pos.getY()));
pos.setZ(snapVertexCoord(pos.getZ()));
}
private static float snapVertexCoord(float x) {
return x > -1.0E-6F && x < 1.0E-6F ? 0.0F : (x > 0.999999F && x < 1.000001F ? 1.0F : x);
}
public static AxisAlignedBB getOffsetBoundingBox(AxisAlignedBB aabb, Block.EnumOffsetType offsetType,
BlockPos pos) {
int i = pos.getX();
int j = pos.getZ();
long k = (long) (i * 3129871) ^ (long) j * 116129781L;
k = k * k * 42317861L + k * 11L;
double d0 = ((double) ((float) (k >> 16 & 15L) / 15.0F) - 0.5D) * 0.5D;
double d1 = ((double) ((float) (k >> 24 & 15L) / 15.0F) - 0.5D) * 0.5D;
double d2 = 0.0D;
if (offsetType == Block.EnumOffsetType.XYZ) {
d2 = ((double) ((float) (k >> 20 & 15L) / 15.0F) - 1.0D) * 0.2D;
}
return aabb.offset(d0, d2, d1);
}
}

View File

@ -0,0 +1,44 @@
package net.optifine.model;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.init.Blocks;
public class ListQuadsOverlay {
private List<BakedQuad> listQuads = new ArrayList();
private List<IBlockState> listBlockStates = new ArrayList();
private List<BakedQuad> listQuadsSingle = Arrays.<BakedQuad>asList(new BakedQuad[1]);
public void addQuad(BakedQuad quad, IBlockState blockState) {
if (quad != null) {
this.listQuads.add(quad);
this.listBlockStates.add(blockState);
}
}
public int size() {
return this.listQuads.size();
}
public BakedQuad getQuad(int index) {
return (BakedQuad) this.listQuads.get(index);
}
public IBlockState getBlockState(int index) {
return index >= 0 && index < this.listBlockStates.size() ? (IBlockState) this.listBlockStates.get(index)
: Blocks.air.getDefaultState();
}
public List<BakedQuad> getListQuadsSingle(BakedQuad quad) {
this.listQuadsSingle.set(0, quad);
return this.listQuadsSingle;
}
public void clear() {
this.listQuads.clear();
this.listBlockStates.clear();
}
}

View File

@ -0,0 +1,94 @@
package net.optifine.model;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.resources.model.IBakedModel;
import net.minecraft.client.resources.model.SimpleBakedModel;
import net.minecraft.util.EnumFacing;
public class ModelUtils {
public static void dbgModel(IBakedModel model) {
if (model != null) {
// Config.dbg("Model: " + model + ", ao: " + model.isAmbientOcclusion() + ",
// gui3d: " + model.isGui3d() + ", builtIn: " + model.isBuiltInRenderer() + ",
// particle: " + model.getParticleTexture());
EnumFacing[] aenumfacing = EnumFacing._VALUES;
for (int i = 0; i < aenumfacing.length; ++i) {
EnumFacing enumfacing = aenumfacing[i];
List list = model.getFaceQuads(enumfacing);
dbgQuads(enumfacing.getName(), list, " ");
}
List list1 = model.getGeneralQuads();
dbgQuads("General", list1, " ");
}
}
private static void dbgQuads(String name, List quads, String prefix) {
for (Object bakedquad0 : quads) {
BakedQuad bakedQuad = (BakedQuad) bakedquad0;
dbgQuad(name, bakedQuad, prefix);
}
}
public static void dbgQuad(String name, BakedQuad quad, String prefix) {
// Config.dbg(prefix + "Quad: " + quad.getClass().getName() + ", type: " + name
// + ", face: " + quad.getFace() + ", tint: " + quad.getTintIndex() + ", sprite:
// " + quad.getSprite());
dbgVertexData(quad.getVertexData(), " " + prefix);
}
public static void dbgVertexData(int[] vd, String prefix) {
int i = vd.length / 4;
// Config.dbg(prefix + "Length: " + vd.length + ", step: " + i);
for (int j = 0; j < 4; ++j) {
int k = j * i;
float f = Float.intBitsToFloat(vd[k + 0]);
float f1 = Float.intBitsToFloat(vd[k + 1]);
float f2 = Float.intBitsToFloat(vd[k + 2]);
int l = vd[k + 3];
float f3 = Float.intBitsToFloat(vd[k + 4]);
float f4 = Float.intBitsToFloat(vd[k + 5]);
// Config.dbg(prefix + j + " xyz: " + f + "," + f1 + "," + f2 + " col: " + l + "
// u,v: " + f3 + "," + f4);
}
}
public static IBakedModel duplicateModel(IBakedModel model) {
List list = duplicateQuadList(model.getGeneralQuads());
EnumFacing[] aenumfacing = EnumFacing._VALUES;
List list1 = new ArrayList();
for (int i = 0; i < aenumfacing.length; ++i) {
EnumFacing enumfacing = aenumfacing[i];
List list2 = model.getFaceQuads(enumfacing);
List list3 = duplicateQuadList(list2);
list1.add(list3);
}
SimpleBakedModel simplebakedmodel = new SimpleBakedModel(list, list1, model.isAmbientOcclusion(),
model.isGui3d(), model.getParticleTexture(), model.getItemCameraTransforms());
return simplebakedmodel;
}
public static List duplicateQuadList(List lists) {
List list = new ArrayList();
for (Object e : lists) {
BakedQuad bakedquad = (BakedQuad) e;
BakedQuad bakedquad1 = duplicateQuad(bakedquad);
list.add(bakedquad1);
}
return list;
}
public static BakedQuad duplicateQuad(BakedQuad quad) {
BakedQuad bakedquad = new BakedQuad((int[]) quad.getVertexData().clone(),
(int[]) quad.getVertexDataWithNormals().clone(), quad.getTintIndex(), quad.getFace(), quad.getSprite());
return bakedquad;
}
}

View File

@ -0,0 +1,158 @@
package net.optifine.model;
import net.minecraft.util.EnumFacing;
public class QuadBounds {
private float minX = Float.MAX_VALUE;
private float minY = Float.MAX_VALUE;
private float minZ = Float.MAX_VALUE;
private float maxX = -3.4028235E38F;
private float maxY = -3.4028235E38F;
private float maxZ = -3.4028235E38F;
public QuadBounds(int[] vertexData) {
int i = vertexData.length / 4;
for (int j = 0; j < 4; ++j) {
int k = j * i;
float f = Float.intBitsToFloat(vertexData[k + 0]);
float f1 = Float.intBitsToFloat(vertexData[k + 1]);
float f2 = Float.intBitsToFloat(vertexData[k + 2]);
if (this.minX > f) {
this.minX = f;
}
if (this.minY > f1) {
this.minY = f1;
}
if (this.minZ > f2) {
this.minZ = f2;
}
if (this.maxX < f) {
this.maxX = f;
}
if (this.maxY < f1) {
this.maxY = f1;
}
if (this.maxZ < f2) {
this.maxZ = f2;
}
}
}
public float getMinX() {
return this.minX;
}
public float getMinY() {
return this.minY;
}
public float getMinZ() {
return this.minZ;
}
public float getMaxX() {
return this.maxX;
}
public float getMaxY() {
return this.maxY;
}
public float getMaxZ() {
return this.maxZ;
}
public boolean isFaceQuad(EnumFacing face) {
float f;
float f1;
float f2;
switch (face) {
case DOWN:
f = this.getMinY();
f1 = this.getMaxY();
f2 = 0.0F;
break;
case UP:
f = this.getMinY();
f1 = this.getMaxY();
f2 = 1.0F;
break;
case NORTH:
f = this.getMinZ();
f1 = this.getMaxZ();
f2 = 0.0F;
break;
case SOUTH:
f = this.getMinZ();
f1 = this.getMaxZ();
f2 = 1.0F;
break;
case WEST:
f = this.getMinX();
f1 = this.getMaxX();
f2 = 0.0F;
break;
case EAST:
f = this.getMinX();
f1 = this.getMaxX();
f2 = 1.0F;
break;
default:
return false;
}
return f == f2 && f1 == f2;
}
public boolean isFullQuad(EnumFacing face) {
float f;
float f1;
float f2;
float f3;
switch (face) {
case DOWN:
case UP:
f = this.getMinX();
f1 = this.getMaxX();
f2 = this.getMinZ();
f3 = this.getMaxZ();
break;
case NORTH:
case SOUTH:
f = this.getMinX();
f1 = this.getMaxX();
f2 = this.getMinY();
f3 = this.getMaxY();
break;
case WEST:
case EAST:
f = this.getMinY();
f1 = this.getMaxY();
f2 = this.getMinZ();
f3 = this.getMaxZ();
break;
default:
return false;
}
return f == 0.0F && f1 == 1.0F && f2 == 0.0F && f3 == 1.0F;
}
}

View File

@ -0,0 +1,122 @@
package net.optifine.render;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.optifine.Config;
public class Blender {
public static final int BLEND_ALPHA = 0;
public static final int BLEND_ADD = 1;
public static final int BLEND_SUBSTRACT = 2;
public static final int BLEND_MULTIPLY = 3;
public static final int BLEND_DODGE = 4;
public static final int BLEND_BURN = 5;
public static final int BLEND_SCREEN = 6;
public static final int BLEND_OVERLAY = 7;
public static final int BLEND_REPLACE = 8;
public static final int BLEND_DEFAULT = 1;
public static int parseBlend(String str) {
if (str == null) {
return 1;
} else {
str = str.toLowerCase().trim();
if (str.equals("alpha")) {
return 0;
} else if (str.equals("add")) {
return 1;
} else if (str.equals("subtract")) {
return 2;
} else if (str.equals("multiply")) {
return 3;
} else if (str.equals("dodge")) {
return 4;
} else if (str.equals("burn")) {
return 5;
} else if (str.equals("screen")) {
return 6;
} else if (str.equals("overlay")) {
return 7;
} else if (str.equals("replace")) {
return 8;
} else {
Config.warn("Unknown blend: " + str);
return 1;
}
}
}
public static void setupBlend(int blend, float brightness) {
switch (blend) {
case 0:
GlStateManager.disableAlpha();
GlStateManager.enableBlend();
GlStateManager.blendFunc(770, 771);
GlStateManager.color(1.0F, 1.0F, 1.0F, brightness);
break;
case 1:
GlStateManager.disableAlpha();
GlStateManager.enableBlend();
GlStateManager.blendFunc(770, 1);
GlStateManager.color(1.0F, 1.0F, 1.0F, brightness);
break;
case 2:
GlStateManager.disableAlpha();
GlStateManager.enableBlend();
GlStateManager.blendFunc(775, 0);
GlStateManager.color(brightness, brightness, brightness, 1.0F);
break;
case 3:
GlStateManager.disableAlpha();
GlStateManager.enableBlend();
GlStateManager.blendFunc(774, 771);
GlStateManager.color(brightness, brightness, brightness, brightness);
break;
case 4:
GlStateManager.disableAlpha();
GlStateManager.enableBlend();
GlStateManager.blendFunc(1, 1);
GlStateManager.color(brightness, brightness, brightness, 1.0F);
break;
case 5:
GlStateManager.disableAlpha();
GlStateManager.enableBlend();
GlStateManager.blendFunc(0, 769);
GlStateManager.color(brightness, brightness, brightness, 1.0F);
break;
case 6:
GlStateManager.disableAlpha();
GlStateManager.enableBlend();
GlStateManager.blendFunc(1, 769);
GlStateManager.color(brightness, brightness, brightness, 1.0F);
break;
case 7:
GlStateManager.disableAlpha();
GlStateManager.enableBlend();
GlStateManager.blendFunc(774, 768);
GlStateManager.color(brightness, brightness, brightness, 1.0F);
break;
case 8:
GlStateManager.enableAlpha();
GlStateManager.disableBlend();
GlStateManager.color(1.0F, 1.0F, 1.0F, brightness);
}
GlStateManager.enableTexture2D();
}
public static void clearBlend(float rainBrightness) {
GlStateManager.disableAlpha();
GlStateManager.enableBlend();
GlStateManager.blendFunc(770, 1);
GlStateManager.color(1.0F, 1.0F, 1.0F, rainBrightness);
}
}

View File

@ -0,0 +1,265 @@
package net.optifine.render;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.BlockLeaves;
import net.minecraft.block.state.BlockStateBase;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.BlockModelRenderer;
import net.minecraft.client.renderer.RegionRenderCacheBuilder;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.BreakingFour;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumWorldBlockLayer;
import net.optifine.Config;
import net.optifine.model.ListQuadsOverlay;
public class RenderEnv {
private IBlockState blockState;
private BlockPos blockPos;
private int blockId = -1;
private int metadata = -1;
private int breakingAnimation = -1;
private int smartLeaves = -1;
private float[] quadBounds = new float[EnumFacing._VALUES.length * 2];
private BitSet boundsFlags = new BitSet(3);
private BlockModelRenderer.AmbientOcclusionFace aoFace = new BlockModelRenderer.AmbientOcclusionFace();
private BlockPos colorizerBlockPosM = null;
private boolean[] borderFlags = null;
private boolean[] borderFlags2 = null;
private boolean[] borderFlags3 = null;
private EnumFacing[] borderDirections = null;
private List<BakedQuad> listQuadsCustomizer = new ArrayList();
private List<BakedQuad> listQuadsCtmMultipass = new ArrayList();
private BakedQuad[] arrayQuadsCtm1 = new BakedQuad[1];
private BakedQuad[] arrayQuadsCtm2 = new BakedQuad[2];
private BakedQuad[] arrayQuadsCtm3 = new BakedQuad[3];
private BakedQuad[] arrayQuadsCtm4 = new BakedQuad[4];
private RegionRenderCacheBuilder regionRenderCacheBuilder = null;
private ListQuadsOverlay[] listsQuadsOverlay = new ListQuadsOverlay[EnumWorldBlockLayer.values().length];
private boolean overlaysRendered = false;
private static final int UNKNOWN = -1;
private static final int FALSE = 0;
private static final int TRUE = 1;
public RenderEnv(IBlockState blockState, BlockPos blockPos) {
this.blockState = blockState;
this.blockPos = blockPos;
}
public void reset(IBlockState blockStateIn, BlockPos blockPosIn) {
if (this.blockState != blockStateIn || this.blockPos != blockPosIn) {
this.blockState = blockStateIn;
this.blockPos = blockPosIn;
this.blockId = -1;
this.metadata = -1;
this.breakingAnimation = -1;
this.smartLeaves = -1;
this.boundsFlags.clear();
}
}
public int getBlockId() {
if (this.blockId < 0) {
if (this.blockState instanceof BlockStateBase) {
BlockStateBase blockstatebase = (BlockStateBase) this.blockState;
this.blockId = blockstatebase.getBlockId();
} else {
this.blockId = Block.getIdFromBlock(this.blockState.getBlock());
}
}
return this.blockId;
}
public int getMetadata() {
if (this.metadata < 0) {
if (this.blockState instanceof BlockStateBase) {
BlockStateBase blockstatebase = (BlockStateBase) this.blockState;
this.metadata = blockstatebase.getMetadata();
} else {
this.metadata = this.blockState.getBlock().getMetaFromState(this.blockState);
}
}
return this.metadata;
}
public float[] getQuadBounds() {
return this.quadBounds;
}
public BitSet getBoundsFlags() {
return this.boundsFlags;
}
public BlockModelRenderer.AmbientOcclusionFace getAoFace() {
return this.aoFace;
}
public boolean isBreakingAnimation(List listQuads) {
if (this.breakingAnimation == -1 && listQuads.size() > 0) {
if (listQuads.get(0) instanceof BreakingFour) {
this.breakingAnimation = 1;
} else {
this.breakingAnimation = 0;
}
}
return this.breakingAnimation == 1;
}
public boolean isBreakingAnimation(BakedQuad quad) {
if (this.breakingAnimation < 0) {
if (quad instanceof BreakingFour) {
this.breakingAnimation = 1;
} else {
this.breakingAnimation = 0;
}
}
return this.breakingAnimation == 1;
}
public boolean isBreakingAnimation() {
return this.breakingAnimation == 1;
}
public IBlockState getBlockState() {
return this.blockState;
}
public BlockPos getColorizerBlockPosM() {
if (this.colorizerBlockPosM == null) {
this.colorizerBlockPosM = new BlockPos(0, 0, 0);
}
return this.colorizerBlockPosM;
}
public boolean[] getBorderFlags() {
if (this.borderFlags == null) {
this.borderFlags = new boolean[4];
}
return this.borderFlags;
}
public boolean[] getBorderFlags2() {
if (this.borderFlags2 == null) {
this.borderFlags2 = new boolean[4];
}
return this.borderFlags2;
}
public boolean[] getBorderFlags3() {
if (this.borderFlags3 == null) {
this.borderFlags3 = new boolean[4];
}
return this.borderFlags3;
}
public EnumFacing[] getBorderDirections() {
if (this.borderDirections == null) {
this.borderDirections = new EnumFacing[4];
}
return this.borderDirections;
}
public EnumFacing[] getBorderDirections(EnumFacing dir0, EnumFacing dir1, EnumFacing dir2, EnumFacing dir3) {
EnumFacing[] aenumfacing = this.getBorderDirections();
aenumfacing[0] = dir0;
aenumfacing[1] = dir1;
aenumfacing[2] = dir2;
aenumfacing[3] = dir3;
return aenumfacing;
}
public boolean isSmartLeaves() {
if (this.smartLeaves == -1) {
if (Config.isTreesSmart() && this.blockState.getBlock() instanceof BlockLeaves) {
this.smartLeaves = 1;
} else {
this.smartLeaves = 0;
}
}
return this.smartLeaves == 1;
}
public List<BakedQuad> getListQuadsCustomizer() {
return this.listQuadsCustomizer;
}
public BakedQuad[] getArrayQuadsCtm(BakedQuad quad) {
this.arrayQuadsCtm1[0] = quad;
return this.arrayQuadsCtm1;
}
public BakedQuad[] getArrayQuadsCtm(BakedQuad quad0, BakedQuad quad1) {
this.arrayQuadsCtm2[0] = quad0;
this.arrayQuadsCtm2[1] = quad1;
return this.arrayQuadsCtm2;
}
public BakedQuad[] getArrayQuadsCtm(BakedQuad quad0, BakedQuad quad1, BakedQuad quad2) {
this.arrayQuadsCtm3[0] = quad0;
this.arrayQuadsCtm3[1] = quad1;
this.arrayQuadsCtm3[2] = quad2;
return this.arrayQuadsCtm3;
}
public BakedQuad[] getArrayQuadsCtm(BakedQuad quad0, BakedQuad quad1, BakedQuad quad2, BakedQuad quad3) {
this.arrayQuadsCtm4[0] = quad0;
this.arrayQuadsCtm4[1] = quad1;
this.arrayQuadsCtm4[2] = quad2;
this.arrayQuadsCtm4[3] = quad3;
return this.arrayQuadsCtm4;
}
public List<BakedQuad> getListQuadsCtmMultipass(BakedQuad[] quads) {
this.listQuadsCtmMultipass.clear();
if (quads != null) {
for (int i = 0; i < quads.length; ++i) {
BakedQuad bakedquad = quads[i];
this.listQuadsCtmMultipass.add(bakedquad);
}
}
return this.listQuadsCtmMultipass;
}
public RegionRenderCacheBuilder getRegionRenderCacheBuilder() {
return this.regionRenderCacheBuilder;
}
public void setRegionRenderCacheBuilder(RegionRenderCacheBuilder regionRenderCacheBuilder) {
this.regionRenderCacheBuilder = regionRenderCacheBuilder;
}
public ListQuadsOverlay getListQuadsOverlay(EnumWorldBlockLayer layer) {
ListQuadsOverlay listquadsoverlay = this.listsQuadsOverlay[layer.ordinal()];
if (listquadsoverlay == null) {
listquadsoverlay = new ListQuadsOverlay();
this.listsQuadsOverlay[layer.ordinal()] = listquadsoverlay;
}
return listquadsoverlay;
}
public boolean isOverlaysRendered() {
return this.overlaysRendered;
}
public void setOverlaysRendered(boolean overlaysRendered) {
this.overlaysRendered = overlaysRendered;
}
}

View File

@ -0,0 +1,24 @@
package net.optifine.util;
public class CounterInt {
private int startValue;
private int value;
public CounterInt(int startValue) {
this.startValue = startValue;
this.value = startValue;
}
public int nextValue() {
int i = this.value++;
return i;
}
public void reset() {
this.value = this.startValue;
}
public int getValue() {
return this.value;
}
}

View File

@ -0,0 +1,74 @@
package net.optifine.util;
import net.minecraft.util.MathHelper;
public class MathUtils {
public static final float PI = (float) Math.PI;
public static final float PI2 = ((float) Math.PI * 2F);
public static final float PId2 = ((float) Math.PI / 2F);
// private static final float[] ASIN_TABLE = new float[65536];
//
// public static float asin(float value) {
// return ASIN_TABLE[(int) ((double) (value + 1.0F) * 32767.5D) & 65535];
// }
//
// public static float acos(float value) {
// return ((float) Math.PI / 2F) - ASIN_TABLE[(int) ((double) (value + 1.0F) * 32767.5D) & 65535];
// }
public static int getAverage(int[] vals) {
if (vals.length <= 0) {
return 0;
} else {
int i = getSum(vals);
int j = i / vals.length;
return j;
}
}
public static int getSum(int[] vals) {
if (vals.length <= 0) {
return 0;
} else {
int i = 0;
for (int j = 0; j < vals.length; ++j) {
int k = vals[j];
i += k;
}
return i;
}
}
public static int roundDownToPowerOfTwo(int val) {
int i = MathHelper.roundUpToPowerOfTwo(val);
return val == i ? i : i / 2;
}
public static boolean equalsDelta(float f1, float f2, float delta) {
return Math.abs(f1 - f2) <= delta;
}
public static float toDeg(float angle) {
return angle * 180.0F / PI;
}
public static float toRad(float angle) {
return angle / 180.0F * PI;
}
public static float roundToFloat(double d) {
return (float) ((double) Math.round(d * 1.0E8D) / 1.0E8D);
}
// static {
// for (int i = 0; i < 65536; ++i) {
// ASIN_TABLE[i] = (float) Math.asin((double) i / 32767.5D - 1.0D);
// }
//
// for (int j = -1; j < 2; ++j) {
// ASIN_TABLE[(int) (((double) j + 1.0D) * 32767.5D) & 65535] = (float) Math.asin((double) j);
// }
// }
}

View File

@ -0,0 +1,17 @@
package net.optifine.util;
public class NumUtils {
public static float limit(float val, float min, float max) {
return val < min ? min : (val > max ? max : val);
}
public static int mod(int x, int y) {
int i = x % y;
if (i < 0) {
i += y;
}
return i;
}
}

Some files were not shown because too many files have changed in this diff Show More