From 85893d825f22e3accb0583b5035afa079915a817 Mon Sep 17 00:00:00 2001 From: Ned Loynd <41816363+NeRdTheNed@users.noreply.github.com> Date: Mon, 27 Sep 2021 00:08:25 +1000 Subject: [PATCH] De-duplicate constants, improve Javadoc, fix scaling - De-duplicate shared constants relating to texture sizes - Improve some Javadoc formatting & use @link and @see more - Fix scaling issues for some textures --- build.gradle | 2 + .../generators/AbstractLavaGenerator.java | 29 +++++++------- .../generators/AbstractLiquidGenerator.java | 21 +++------- .../generators/AbstractTextureGenerator.java | 13 ++++++- .../generators/Classic19aWaterGenerator.java | 16 ++++---- .../generators/FireGenerator.java | 21 +++++----- .../GearRotationFramesGenerator.java | 23 ++++------- .../generators/MC4k1Generator.java | 11 ++---- .../generators/MC4k2Generator.java | 25 ++++++------ .../generators/MissingTextureGenerator.java | 38 +++++++++++-------- .../generators/NetherPortalGenerator.java | 23 +++++------ 11 files changed, 109 insertions(+), 113 deletions(-) diff --git a/build.gradle b/build.gradle index 0a54d8f..815f7ed 100644 --- a/build.gradle +++ b/build.gradle @@ -45,6 +45,8 @@ javadoc { options.memberLevel = JavadocMemberLevel.PRIVATE // Add custom "todo" tag options.tags = ["todo:a:To Do:"] + // Ensures that the encoding of javadoc source files is set to UTF-8 + options.encoding = "UTF-8" } tasks.withType(JavaCompile) { diff --git a/src/main/java/mcTextureGen/generators/AbstractLavaGenerator.java b/src/main/java/mcTextureGen/generators/AbstractLavaGenerator.java index a8f634c..04e2dc0 100644 --- a/src/main/java/mcTextureGen/generators/AbstractLavaGenerator.java +++ b/src/main/java/mcTextureGen/generators/AbstractLavaGenerator.java @@ -2,12 +2,15 @@ /** * Although this class is called AbstractLavaGenerator, it's pretty much just a lava texture generator, - * minus an implementation of setABGR(). Classes that extend this class must therefore implement setABGR(). + * minus an implementation of {@link AbstractLiquidGenerator#setABGR(byte[], float, int)}. + * Classes that extend this class must therefore implement {@link AbstractLiquidGenerator#setABGR(byte[], float, int)}. * This is mainly due to the fact that this is one of the only differences between Classic 0.0.19a lava textures * and Classic 0.0.22a lava textures (the other difference being how pixels are clamped). * This is a non-deterministic generator. * * @todo clean up, refactor + * @see AbstractLiquidGenerator#clampCurrentPixelIntensity(float) + * @see AbstractLiquidGenerator#setABGR(byte[], float, int) */ public abstract class AbstractLavaGenerator extends AbstractLiquidGenerator { @@ -27,15 +30,15 @@ protected AbstractLavaGenerator(String generatorName) { * @todo better Javadoc */ public final void generateLiquidTexture(final float[] liquidImagePrevious, final float[] liquidImageCurrent, final float[] liquidIntensity, final float[] liquidIntensityIntensity) { - for (int currentLavaX = 0; currentLavaX < LIQUID_IMAGE_SIZE; ++currentLavaX) { - for (int currentLavaY = 0; currentLavaY < LIQUID_IMAGE_SIZE; ++currentLavaY) { + for (int currentLavaX = 0; currentLavaX < STANDARD_IMAGE_SIZE; ++currentLavaX) { + for (int currentLavaY = 0; currentLavaY < STANDARD_IMAGE_SIZE; ++currentLavaY) { float localPreviousIntensity = 0.0F; // Side note: 1.2F is the value originally used, despite it being "incorrect" to use a float here // (would usually be a double, as 1.2F gets promoted to double at compile time, due to Math.sin returning a double). // This was likely due to programmer oversight when writing this code. // TL;DR: I meant to type 1.2F, Notch probably didn't. - final int ySin = (int) (Math.sin((currentLavaY * Math.PI * 2.0D) / LIQUID_IMAGE_SIZE) * 1.2F); - final int xCos = (int) (Math.sin((currentLavaX * Math.PI * 2.0D) / LIQUID_IMAGE_SIZE) * 1.2F); + final int ySin = (int) (Math.sin((currentLavaY * Math.PI * 2.0D) / STANDARD_IMAGE_SIZE) * 1.2F); + final int xCos = (int) (Math.sin((currentLavaX * Math.PI * 2.0D) / STANDARD_IMAGE_SIZE) * 1.2F); // Iterates through (x - 1, y - 1) to (x + 1, y + 1). // For each x and y value, it accumulates the previous pixel value at (x + ySin, y + xCos) into localPixelIntensity. @@ -43,22 +46,22 @@ public final void generateLiquidTexture(final float[] liquidImagePrevious, final for (int localLavaY = currentLavaY - 1; localLavaY <= (currentLavaY + 1); ++localLavaY) { // Restrict the adjusted coordinates to be in range of the maximum valid coordinate (liquidImageSize). // If a coordinate is out of range, it wraps to be in range. - final int localLavaXWrapped = (localLavaX + ySin) & LIQUID_IMAGE_MASK; - final int localLavaYWrapped = (localLavaY + xCos) & LIQUID_IMAGE_MASK; - localPreviousIntensity += liquidImagePrevious[localLavaXWrapped + (localLavaYWrapped * LIQUID_IMAGE_SIZE)]; + final int localLavaXWrapped = (localLavaX + ySin) & STANDARD_IMAGE_SIZE_BITMASK; + final int localLavaYWrapped = (localLavaY + xCos) & STANDARD_IMAGE_SIZE_BITMASK; + localPreviousIntensity += liquidImagePrevious[localLavaXWrapped + (localLavaYWrapped * STANDARD_IMAGE_SIZE)]; } } - final int currentLavaOffset = currentLavaX + (currentLavaY * LIQUID_IMAGE_SIZE); + final int currentLavaOffset = currentLavaX + (currentLavaY * STANDARD_IMAGE_SIZE); // A manually unrolled loop iterating from (y, x) to (y + 1, x + 1). Wraps coordinates in the same way as above. // For each x and y value, it accumulates the additional pixel intensity into localLiquidIntensity. // I don't want to change floating point semantics, so I'm not re-rolling this for now. // This was originally inlined as part of the next line of code. I un-inlined it for readability. // I'm pretty sure this shouldn't change anything, but I should probably figure out how floats work in Java to verify that. - final float localLiquidIntensity = liquidIntensity[(currentLavaX & LIQUID_IMAGE_MASK) + ((currentLavaY & LIQUID_IMAGE_MASK) * LIQUID_IMAGE_SIZE)] - + liquidIntensity[(currentLavaX & LIQUID_IMAGE_MASK) + (((currentLavaY + 1) & LIQUID_IMAGE_MASK) * LIQUID_IMAGE_SIZE)] - + liquidIntensity[((currentLavaX + 1) & LIQUID_IMAGE_MASK) + ((currentLavaY & LIQUID_IMAGE_MASK) * LIQUID_IMAGE_SIZE)] - + liquidIntensity[((currentLavaX + 1) & LIQUID_IMAGE_MASK) + (((currentLavaY + 1) & LIQUID_IMAGE_MASK) * LIQUID_IMAGE_SIZE)]; + final float localLiquidIntensity = liquidIntensity[(currentLavaX & STANDARD_IMAGE_SIZE_BITMASK) + ((currentLavaY & STANDARD_IMAGE_SIZE_BITMASK) * STANDARD_IMAGE_SIZE)] + + liquidIntensity[(currentLavaX & STANDARD_IMAGE_SIZE_BITMASK) + (((currentLavaY + 1) & STANDARD_IMAGE_SIZE_BITMASK) * STANDARD_IMAGE_SIZE)] + + liquidIntensity[((currentLavaX + 1) & STANDARD_IMAGE_SIZE_BITMASK) + ((currentLavaY & STANDARD_IMAGE_SIZE_BITMASK) * STANDARD_IMAGE_SIZE)] + + liquidIntensity[((currentLavaX + 1) & STANDARD_IMAGE_SIZE_BITMASK) + (((currentLavaY + 1) & STANDARD_IMAGE_SIZE_BITMASK) * STANDARD_IMAGE_SIZE)]; // localLiquidIntensity is divided by 4.0F, because it samples from 4 points. // localPreviousIntensity is divided by 10.0F, because the whims of other programmers are inscrutable. // You'd expect it to be 9.0F based on the previous bit of logic. Maybe someone made an off-by-one error? Or rounded up from 9.9? TODO investigate diff --git a/src/main/java/mcTextureGen/generators/AbstractLiquidGenerator.java b/src/main/java/mcTextureGen/generators/AbstractLiquidGenerator.java index e8b7f53..0f3f22d 100644 --- a/src/main/java/mcTextureGen/generators/AbstractLiquidGenerator.java +++ b/src/main/java/mcTextureGen/generators/AbstractLiquidGenerator.java @@ -14,15 +14,6 @@ */ public abstract class AbstractLiquidGenerator extends AbstractTextureGenerator { - /** The size of a liquid image in bits. */ - private static final int LIQUID_IMAGE_BITS = 4; - - /** A bit mask of the amount of bits in a liquid image. */ - static final int LIQUID_IMAGE_MASK = ~(-1 << LIQUID_IMAGE_BITS); - - /** The size of a liquid image in pixels. */ - static final int LIQUID_IMAGE_SIZE = LIQUID_IMAGE_MASK + 1; - /** The name of this liquid texture generator. */ private final String generatorName; @@ -97,10 +88,10 @@ public final TextureGroup[] getTextureGroups() { */ private final TextureGroup liquidTextures() { rand = getRandom(); - float[] liquidImagePrevious = new float[LIQUID_IMAGE_SIZE * LIQUID_IMAGE_SIZE]; - float[] liquidImageCurrent = new float[LIQUID_IMAGE_SIZE * LIQUID_IMAGE_SIZE]; - final float[] liquidIntensity = new float[LIQUID_IMAGE_SIZE * LIQUID_IMAGE_SIZE]; - final float[] liquidIntensityIntensity = new float[LIQUID_IMAGE_SIZE * LIQUID_IMAGE_SIZE]; + float[] liquidImagePrevious = new float[STANDARD_IMAGE_SIZE * STANDARD_IMAGE_SIZE]; + float[] liquidImageCurrent = new float[STANDARD_IMAGE_SIZE * STANDARD_IMAGE_SIZE]; + final float[] liquidIntensity = new float[STANDARD_IMAGE_SIZE * STANDARD_IMAGE_SIZE]; + final float[] liquidIntensityIntensity = new float[STANDARD_IMAGE_SIZE * STANDARD_IMAGE_SIZE]; final BufferedImage[] liquidImages = new BufferedImage[nonDeterministicFrames]; for (int currentFrame = 0; currentFrame < nonDeterministicFrames; currentFrame++) { @@ -108,10 +99,10 @@ private final TextureGroup liquidTextures() { final float[] liquidImageCurrentTemp = liquidImageCurrent; liquidImageCurrent = liquidImagePrevious; liquidImagePrevious = liquidImageCurrentTemp; - final BufferedImage currentLiquidImage = new BufferedImage(LIQUID_IMAGE_SIZE, LIQUID_IMAGE_SIZE, BufferedImage.TYPE_4BYTE_ABGR); + final BufferedImage currentLiquidImage = new BufferedImage(STANDARD_IMAGE_SIZE, STANDARD_IMAGE_SIZE, BufferedImage.TYPE_4BYTE_ABGR); final byte[] imageByteData = ((DataBufferByte) currentLiquidImage.getRaster().getDataBuffer()).getData(); - for (int currentPixel = 0; currentPixel < (LIQUID_IMAGE_SIZE * LIQUID_IMAGE_SIZE); ++currentPixel) { + for (int currentPixel = 0; currentPixel < (STANDARD_IMAGE_SIZE * STANDARD_IMAGE_SIZE); ++currentPixel) { final float currentPixelIntensity = clampCurrentPixelIntensity(liquidImagePrevious[currentPixel]); final int imageOffset = currentPixel * 4; setABGR(imageByteData, currentPixelIntensity, imageOffset); diff --git a/src/main/java/mcTextureGen/generators/AbstractTextureGenerator.java b/src/main/java/mcTextureGen/generators/AbstractTextureGenerator.java index 10f0354..9915bfb 100644 --- a/src/main/java/mcTextureGen/generators/AbstractTextureGenerator.java +++ b/src/main/java/mcTextureGen/generators/AbstractTextureGenerator.java @@ -21,6 +21,17 @@ public abstract class AbstractTextureGenerator { /** True if platform dependent texture generators should generate platform dependent textures. */ protected static boolean shouldGeneratePlatformDependentTextures = false; + // Image size constants + + /** A convenience variable to generate larger textures. Must be a power of two, or one. */ + static final int STANDARD_IMAGE_SIZE_MULTIPLIER = 1; + + /** The size of a standard image in pixels. */ + static final int STANDARD_IMAGE_SIZE = 16 * STANDARD_IMAGE_SIZE_MULTIPLIER; + + /** A bit mask of the size of a standard image. */ + static final int STANDARD_IMAGE_SIZE_BITMASK = STANDARD_IMAGE_SIZE - 1; + /* * Constants to determine the size of the sin and cos lookup tables. * Adapted from https://jvm-gaming.org/t/fast-math-sin-cos-lookup-tables/36660. @@ -92,7 +103,7 @@ public static void setNonDeterministicFrames(int nonDeterministicFrames) { } /** - * Sets the seed used by getRandom(). + * Sets the seed used by {@link #getRandom()}. * * @param randomSeed the new random seed */ diff --git a/src/main/java/mcTextureGen/generators/Classic19aWaterGenerator.java b/src/main/java/mcTextureGen/generators/Classic19aWaterGenerator.java index 8731dbf..004fb3e 100644 --- a/src/main/java/mcTextureGen/generators/Classic19aWaterGenerator.java +++ b/src/main/java/mcTextureGen/generators/Classic19aWaterGenerator.java @@ -20,28 +20,28 @@ public Classic19aWaterGenerator() { */ public void generateLiquidTexture(final float[] liquidImagePrevious, final float[] liquidImageCurrent, final float[] liquidIntensity, final float[] liquidIntensityIntensity) { // Generate the image pixel values - for (int currentWaterX = 0; currentWaterX < LIQUID_IMAGE_SIZE; ++currentWaterX) { - for (int currentWaterY = 0; currentWaterY < LIQUID_IMAGE_SIZE; ++currentWaterY) { + for (int currentWaterX = 0; currentWaterX < STANDARD_IMAGE_SIZE; ++currentWaterX) { + for (int currentWaterY = 0; currentWaterY < STANDARD_IMAGE_SIZE; ++currentWaterY) { float localPixelIntensity = 0.0F; // Iterates through (x - 1, y) to (x + 1, y), and accumulates the previous pixel value at each location into localPixelIntensity. // Only iterating over the x values causes the water to generate horizontal "stripes", as the y value does not change. for (int localWaterX = currentWaterX - 1; localWaterX <= (currentWaterX + 1); ++localWaterX) { - // Restrict the adjusted x coordinate to be in range of the maximum valid coordinate (liquidImageSize). + // Restrict the adjusted x coordinate to be in range of the maximum valid coordinate (STANDARD_IMAGE_SIZE). // If the x coordinate is out of range, it wraps to be in range. - localPixelIntensity += liquidImagePrevious[(localWaterX & LIQUID_IMAGE_MASK) + (currentWaterY * LIQUID_IMAGE_SIZE)]; + localPixelIntensity += liquidImagePrevious[(localWaterX & STANDARD_IMAGE_SIZE_BITMASK) + (currentWaterY * STANDARD_IMAGE_SIZE)]; } - final int currentWaterOffset = currentWaterX + (currentWaterY * LIQUID_IMAGE_SIZE); + final int currentWaterOffset = currentWaterX + (currentWaterY * STANDARD_IMAGE_SIZE); // localPixelIntensity is divided by 3.3F, because it samples from 3 x points. liquidImageCurrent[currentWaterOffset] = (localPixelIntensity / 3.3F) + (liquidIntensity[currentWaterOffset] * 0.8F); } } // Update liquidIntensity and liquidIntensityIntensity - for (int currentWaterX = 0; currentWaterX < LIQUID_IMAGE_SIZE; ++currentWaterX) { - for (int currentWaterY = 0; currentWaterY < LIQUID_IMAGE_SIZE; ++currentWaterY) { - final int currentWaterOffset = currentWaterX + (currentWaterY * LIQUID_IMAGE_SIZE); + for (int currentWaterX = 0; currentWaterX < STANDARD_IMAGE_SIZE; ++currentWaterX) { + for (int currentWaterY = 0; currentWaterY < STANDARD_IMAGE_SIZE; ++currentWaterY) { + final int currentWaterOffset = currentWaterX + (currentWaterY * STANDARD_IMAGE_SIZE); liquidIntensity[currentWaterOffset] += liquidIntensityIntensity[currentWaterOffset] * 0.05F; if (liquidIntensity[currentWaterOffset] < 0.0F) { diff --git a/src/main/java/mcTextureGen/generators/FireGenerator.java b/src/main/java/mcTextureGen/generators/FireGenerator.java index cae1fcb..bb81920 100644 --- a/src/main/java/mcTextureGen/generators/FireGenerator.java +++ b/src/main/java/mcTextureGen/generators/FireGenerator.java @@ -12,14 +12,11 @@ */ public final class FireGenerator extends AbstractTextureGenerator { - /** A convenience variable to generate larger fire textures with. */ - private static final int FIRE_MULTI = 1; - /** How wide the fire texture is. */ - private static final int FIRE_TEXTURE_WIDTH = 16 * FIRE_MULTI; + private static final int FIRE_TEXTURE_WIDTH = 16 * STANDARD_IMAGE_SIZE_MULTIPLIER; /** How high the fire texture is. */ - private static final int FIRE_TEXTURE_HEIGHT = 20 * FIRE_MULTI; + private static final int FIRE_TEXTURE_HEIGHT = 20 * STANDARD_IMAGE_SIZE_MULTIPLIER; /** How many pixels left to sample from when generating the texture. */ private static final int SAMPLE_X_LEFT = 1; @@ -43,7 +40,7 @@ public final class FireGenerator extends AbstractTextureGenerator { */ /** The staring value for the "sample counter". */ - private static final int SAMPLE_COUNTER_START = 18 * FIRE_MULTI; + private static final int SAMPLE_COUNTER_START = 18 * STANDARD_IMAGE_SIZE_MULTIPLIER; /** How many times the "sample counter" would increment. */ private static final int SAMPLE_COUNTER_ITERATIONS = (SAMPLE_X_LEFT + SAMPLE_SELF + SAMPLE_X_RIGHT) * (SAMPLE_Y_DOWN + SAMPLE_SELF + SAMPLE_Y_UP); @@ -53,16 +50,18 @@ public final class FireGenerator extends AbstractTextureGenerator { /** * WTFLOAT is a very strange constant. I felt the name was appropriate, given how hard it was to pin down. - * Earlier versions of Minecraft define this as 1.06F. Later versions defined it as 1.0600001F. + * Earlier versions of Minecraft define this as ≈ 1.06F. Later versions defined it as ≈ 1.0600001F. * This is the current method I've settled on to determine the scaled value of WTFLOAT. - * If fireMulti is 1, it results in 1.06F. + * If {@link AbstractTextureGenerator#STANDARD_IMAGE_SIZE_MULTIPLIER} is + * {@value mcTextureGen.generators.AbstractTextureGenerator#STANDARD_IMAGE_SIZE_MULTIPLIER}, + * it results in {@value} (the same as earlier versions of Minecraft). */ - private static final float WTFLOAT = 1.0F + (SAMPLE_SELF * 0.01F) + (((SAMPLE_COUNTER_ITERATIONS - SAMPLE_SELF) * 0.01F) / FIRE_MULTI); + private static final float WTFLOAT = 1.0F + (SAMPLE_SELF * 0.01F) + (((SAMPLE_COUNTER_ITERATIONS - SAMPLE_SELF) * 0.01F) / STANDARD_IMAGE_SIZE_MULTIPLIER); /** * Used during fire texture generation to compensate for sampling multiple pixels. * @todo It's rumored that some versions of pocket edition have this as 25.2? - * If that's true, removing " + (SAMPLE_SELF * 0.01F)" from WTFLOAT might simulate this. + * If that's true, removing " + (SAMPLE_SELF * 0.01F)" from {@link #WTFLOAT} might simulate this. */ private static final float DIV_PIXEL_INTENSITY = SAMPLE_COUNTER_END * WTFLOAT; @@ -100,7 +99,7 @@ private static TextureGroup fireTextures() { } // Randomize bottom row of pixels - fireImageCurrent[fireX + ((FIRE_TEXTURE_HEIGHT - 1) * FIRE_TEXTURE_WIDTH)] = (float)((rand.nextDouble() * rand.nextDouble() * rand.nextDouble() * (3 + FIRE_MULTI)) + (rand.nextDouble() * 0.1F) + 0.2F); + fireImageCurrent[fireX + ((FIRE_TEXTURE_HEIGHT - 1) * FIRE_TEXTURE_WIDTH)] = (float)((rand.nextDouble() * rand.nextDouble() * rand.nextDouble() * (3 + STANDARD_IMAGE_SIZE_MULTIPLIER)) + (rand.nextDouble() * 0.1F) + 0.2F); } final float[] fireImageCurrentTemp = fireImageCurrent; diff --git a/src/main/java/mcTextureGen/generators/GearRotationFramesGenerator.java b/src/main/java/mcTextureGen/generators/GearRotationFramesGenerator.java index 35ab75b..92c6eb7 100644 --- a/src/main/java/mcTextureGen/generators/GearRotationFramesGenerator.java +++ b/src/main/java/mcTextureGen/generators/GearRotationFramesGenerator.java @@ -20,21 +20,12 @@ public final class GearRotationFramesGenerator extends AbstractTextureGenerator */ private static final int GEAR_ROTATION_STEPS = 64; - /** - * This variable can be changed to create higher resolution output rotated textures. - * This is just for convenience. - */ - private static final int ROTATED_TEXTURE_SIZE_MULTIPLIER = 1; - /** gearmiddle.png has a resolution of 16 by 16. */ private static final int MIDDLE_GEAR_TEXTURE_SIZE = 16; /** gear.png has a resolution of 32 by 32. */ private static final int ORIGINAL_GEAR_TEXTURE_SIZE = 32; - /** This variable controls the resolution of the output rotated gear textures. */ - private static final int ROTATED_TEXTURE_SIZE = MIDDLE_GEAR_TEXTURE_SIZE * ROTATED_TEXTURE_SIZE_MULTIPLIER; - /** An integer array that contains the ARGB values of the "middle gear" image. */ private static final int[] GEAR_MIDDLE_ARGB_VALUES = new int[MIDDLE_GEAR_TEXTURE_SIZE * MIDDLE_GEAR_TEXTURE_SIZE]; @@ -81,18 +72,18 @@ private static TextureGroup gearRotationTextures() { */ // TODO better documentation, variable names are way to verbose, check if gear rotation animation was consistent across all versions of Minecraft private static BufferedImage generateGearTextureForRotation(int rotationStep) { - final BufferedImage rotatedImage = new BufferedImage(ROTATED_TEXTURE_SIZE, ROTATED_TEXTURE_SIZE, BufferedImage.TYPE_4BYTE_ABGR); + final BufferedImage rotatedImage = new BufferedImage(STANDARD_IMAGE_SIZE, STANDARD_IMAGE_SIZE, BufferedImage.TYPE_4BYTE_ABGR); final byte[] imageByteData = ((DataBufferByte) rotatedImage.getRaster().getDataBuffer()).getData(); // Convert the current rotation step into an angle in radians, // and use the lookup table to get the current sine and cosine of the angle. final float sinRotationAngle = lookupSin((rotationStep / (float) GEAR_ROTATION_STEPS) * (float) Math.PI * 2.0F); final float cosRotationAngle = lookupCos((rotationStep / (float) GEAR_ROTATION_STEPS) * (float) Math.PI * 2.0F); - for (int rotatedImageX = 0; rotatedImageX < ROTATED_TEXTURE_SIZE; ++rotatedImageX) { - for (int rotatedImageY = 0; rotatedImageY < ROTATED_TEXTURE_SIZE; ++rotatedImageY) { + for (int rotatedImageX = 0; rotatedImageX < STANDARD_IMAGE_SIZE; ++rotatedImageX) { + for (int rotatedImageY = 0; rotatedImageY < STANDARD_IMAGE_SIZE; ++rotatedImageY) { // TODO I'm not sure why this is done this way - final float gearImageX = ((rotatedImageX / (ROTATED_TEXTURE_SIZE - 1.0F)) - 0.5F) * (ORIGINAL_GEAR_TEXTURE_SIZE - 1.0F); - final float gearImageY = ((rotatedImageY / (ROTATED_TEXTURE_SIZE - 1.0F)) - 0.5F) * (ORIGINAL_GEAR_TEXTURE_SIZE - 1.0F); + final float gearImageX = ((rotatedImageX / (STANDARD_IMAGE_SIZE - 1.0F)) - 0.5F) * (ORIGINAL_GEAR_TEXTURE_SIZE - 1.0F); + final float gearImageY = ((rotatedImageY / (STANDARD_IMAGE_SIZE - 1.0F)) - 0.5F) * (ORIGINAL_GEAR_TEXTURE_SIZE - 1.0F); // Rotate the coordinates TODO document more final float rotatedOffsetGearImageX = (cosRotationAngle * gearImageX) - (sinRotationAngle * gearImageY); final float rotatedOffsetGearImageY = (cosRotationAngle * gearImageY) + (sinRotationAngle * gearImageX); @@ -102,7 +93,7 @@ private static BufferedImage generateGearTextureForRotation(int rotationStep) { final int ARGB; if ((rotatedGearImageX >= 0) && (rotatedGearImageY >= 0) && (rotatedGearImageX < ORIGINAL_GEAR_TEXTURE_SIZE) && (rotatedGearImageY < ORIGINAL_GEAR_TEXTURE_SIZE)) { - final int gearDiv = ROTATED_TEXTURE_SIZE / MIDDLE_GEAR_TEXTURE_SIZE; + final int gearDiv = STANDARD_IMAGE_SIZE / MIDDLE_GEAR_TEXTURE_SIZE; final int gearMiddleARGB = GEAR_MIDDLE_ARGB_VALUES[(rotatedImageX / gearDiv) + ((rotatedImageY / gearDiv) * MIDDLE_GEAR_TEXTURE_SIZE)]; // Is the alpha component of the RGBA value for the middle piece of the gear greater than 128? // (i.e. in the context of the gear images, is there a non-transparent pixel at that position? @@ -113,7 +104,7 @@ private static BufferedImage generateGearTextureForRotation(int rotationStep) { ARGB = 0; } - final int imageOffset = (rotatedImageX + (rotatedImageY * ROTATED_TEXTURE_SIZE)) * 4; + final int imageOffset = (rotatedImageX + (rotatedImageY * STANDARD_IMAGE_SIZE)) * 4; // Set ABGR values imageByteData[imageOffset + 0] = (byte) ((ARGB >>> 24) > 128 ? 255 : 0); imageByteData[imageOffset + 1] = (byte) ((ARGB >> 16) & 0xFF); diff --git a/src/main/java/mcTextureGen/generators/MC4k1Generator.java b/src/main/java/mcTextureGen/generators/MC4k1Generator.java index 40d929f..1c85093 100644 --- a/src/main/java/mcTextureGen/generators/MC4k1Generator.java +++ b/src/main/java/mcTextureGen/generators/MC4k1Generator.java @@ -13,9 +13,6 @@ public final class MC4k1Generator extends AbstractTextureGenerator { /** How many light levels to generate textures for. */ private static final int MAX_LIGHT_LEVEL = 2; - /** The texture size. */ - private static final int TILE_SIZE = 16; - /** * Generates Minecraft 4k-1's "XOR fractal" textures, for each light level. * @@ -26,12 +23,12 @@ private static TextureGroup xorTextures() { final BufferedImage[] xorImages = new BufferedImage[MAX_LIGHT_LEVEL + 1]; for (int tileLightLevel = 0; tileLightLevel <= MAX_LIGHT_LEVEL; tileLightLevel++) { - final BufferedImage tile = new BufferedImage(TILE_SIZE, TILE_SIZE, BufferedImage.TYPE_BYTE_GRAY); + final BufferedImage tile = new BufferedImage(STANDARD_IMAGE_SIZE, STANDARD_IMAGE_SIZE, BufferedImage.TYPE_BYTE_GRAY); final byte[] tileByteData = ((DataBufferByte) tile.getRaster().getDataBuffer()).getData(); - for (int tileX = 0; tileX < TILE_SIZE; tileX++) { - for (int tileY = 0; tileY < TILE_SIZE; tileY++) { - tileByteData[(tileX * TILE_SIZE) + tileY] = (byte) ((((((tileX ^ tileY) * 8) + 128) & 0xFF) * (int) ((1.0F - (tileLightLevel * 0.2F)) * 0xFF)) / 0xFF); + for (int tileX = 0; tileX < STANDARD_IMAGE_SIZE; tileX++) { + for (int tileY = 0; tileY < STANDARD_IMAGE_SIZE; tileY++) { + tileByteData[(tileX * STANDARD_IMAGE_SIZE) + tileY] = (byte) ((((((tileX ^ tileY) * 8) + 128) & 0xFF) * (int) ((1.0F - (tileLightLevel * 0.2F)) * 0xFF)) / 0xFF); } } diff --git a/src/main/java/mcTextureGen/generators/MC4k2Generator.java b/src/main/java/mcTextureGen/generators/MC4k2Generator.java index de623db..6b231cb 100644 --- a/src/main/java/mcTextureGen/generators/MC4k2Generator.java +++ b/src/main/java/mcTextureGen/generators/MC4k2Generator.java @@ -62,9 +62,6 @@ public final class MC4k2Generator extends AbstractTextureGenerator { /** The maximum amount of block / texture IDs. */ private static final int MAX_TEXTURE_IDS = 16; - /** The texture size. */ - private static final int TEXTURE_SIZE = 16; - /** The amount of generated textures per ID. */ private static final int TEXTURES_PER_ID = 3; @@ -73,7 +70,7 @@ public final class MC4k2Generator extends AbstractTextureGenerator { /** * Generates all textures generated by Minecraft 4k-2. - * Each block / texture ID is generated as texture group containing 3 textures, + * Each block / texture ID is generated as texture group containing {@value #TEXTURES_PER_ID} textures, * one for each block light level. * * @todo refactor into separate texture group generators @@ -126,11 +123,11 @@ private static TextureGroup[] rawTextureDump() { } for (int subTexture = 0; subTexture < TEXTURES_PER_ID; subTexture++) { - final BufferedImage tile = new BufferedImage(TEXTURE_SIZE, TEXTURE_SIZE, BufferedImage.TYPE_INT_ARGB); + final BufferedImage tile = new BufferedImage(STANDARD_IMAGE_SIZE, STANDARD_IMAGE_SIZE, BufferedImage.TYPE_INT_ARGB); final int[] textureData = ((DataBufferInt) tile.getRaster().getDataBuffer()).getData(); - for (int yPixel = 0; yPixel < TEXTURE_SIZE; yPixel++) { - for (int xPixel = 0; xPixel < TEXTURE_SIZE; xPixel++) { + for (int yPixel = 0; yPixel < STANDARD_IMAGE_SIZE; yPixel++) { + for (int xPixel = 0; xPixel < STANDARD_IMAGE_SIZE; xPixel++) { // The stone texture generates "stripes" by only varying the texture 1/4 of the time this loop runs. // Otherwise, the same "variation" is used in this position as the last X position. if ((textureID != TEXTURE_STONE) || (rand.nextInt(3) == 0)) { @@ -155,7 +152,7 @@ private static TextureGroup[] rawTextureDump() { // Log texture generation depends on what side of the log texture is being generated. // TODO refactor - if ((xPixel <= 0) || (xPixel >= 15) || (yPixel <= 0) || (yPixel >= 15) || (subTexture == 1)) { + if ((xPixel <= 0) || (xPixel >= (STANDARD_IMAGE_SIZE - 1)) || (yPixel <= 0) || (yPixel >= (STANDARD_IMAGE_SIZE - 1)) || (subTexture == 1)) { color = COLOR_DARK_BROWN; if (rand.nextInt(2) == 0) { @@ -163,8 +160,8 @@ private static TextureGroup[] rawTextureDump() { } } else { color = COLOR_LIGHT_BROWN; - int tempOne = xPixel - 7; - int tempTwo = (yPixel & 15) - 7; + int tempOne = xPixel - ((STANDARD_IMAGE_SIZE / 2) - 1); + int tempTwo = (yPixel & STANDARD_IMAGE_SIZE_BITMASK) - ((STANDARD_IMAGE_SIZE / 2) - 1); if (tempOne < 0) { tempOne = 1 - tempOne; @@ -189,15 +186,15 @@ private static TextureGroup[] rawTextureDump() { case TEXTURE_GRASS: // On the side of the grass block, grass elements only generate until a certain threshold. - final int grassCheck = (((xPixel * xPixel * 3) + (xPixel * 81)) >> 2) & 3; + final int grassCheck = (((xPixel * xPixel * 3) + (xPixel * 81)) / 4) & ((STANDARD_IMAGE_SIZE / 4) - 1); - if ((yPixel + (subTexture * TEXTURE_SIZE)) < (grassCheck + 18)) { + if ((yPixel + (subTexture * STANDARD_IMAGE_SIZE)) < (grassCheck + STANDARD_IMAGE_SIZE + (STANDARD_IMAGE_SIZE / 8))) { color = COLOR_GREEN; break; } // If this threshold has just been exceeded, "blend" the grass texture into the dirt texture by darkening the dirt below the grass. - if ((yPixel + (subTexture * TEXTURE_SIZE)) < (grassCheck + 19)) { + if ((yPixel + (subTexture * STANDARD_IMAGE_SIZE)) < (grassCheck + STANDARD_IMAGE_SIZE + (STANDARD_IMAGE_SIZE / 8) + 1)) { randomVariation = (randomVariation * 2) / 3; } @@ -223,7 +220,7 @@ private static TextureGroup[] rawTextureDump() { } // Modify RGB data & merge into textureData - textureData[xPixel + (yPixel * TEXTURE_SIZE)] = + textureData[xPixel + (yPixel * STANDARD_IMAGE_SIZE)] = (color & 0xFF000000) | (((((color >> 16) & 0xFF) * randomVariationWithBlockSideLight) / 0xFF) << 16) | (((((color >> 8) & 0xFF) * randomVariationWithBlockSideLight) / 0xFF) << 8) | diff --git a/src/main/java/mcTextureGen/generators/MissingTextureGenerator.java b/src/main/java/mcTextureGen/generators/MissingTextureGenerator.java index 68a4e0d..461a83a 100644 --- a/src/main/java/mcTextureGen/generators/MissingTextureGenerator.java +++ b/src/main/java/mcTextureGen/generators/MissingTextureGenerator.java @@ -1,6 +1,7 @@ package mcTextureGen.generators; import java.awt.Color; +import java.awt.Font; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Toolkit; @@ -20,11 +21,11 @@ */ public final class MissingTextureGenerator extends AbstractTextureGenerator { - /** The size of the generated "checkerboard" textures. */ - private static final int CHECKERBOARD_TEXTURE_SIZE = 16; - /** The size of the generated text based textures. */ - private static final int TEXT_TEXTURE_SZIE = 64; + private static final int TEXT_TEXTURE_SZIE = STANDARD_IMAGE_SIZE * 4; + + /** The starting y-position for text-based textures. */ + private static final int TEXT_STARTING_YPOS = 10 * STANDARD_IMAGE_SIZE_MULTIPLIER; /** * Generates a "checkerboard" texture with the provided colors. @@ -35,12 +36,12 @@ public final class MissingTextureGenerator extends AbstractTextureGenerator { * @return the generated "checkerboard" texture */ private static TextureGroup missingTextureCheckerboard(String name, int colorOne, int colorTwo) { - final BufferedImage missingTexture = new BufferedImage(CHECKERBOARD_TEXTURE_SIZE, CHECKERBOARD_TEXTURE_SIZE, BufferedImage.TYPE_INT_RGB); + final BufferedImage missingTexture = new BufferedImage(STANDARD_IMAGE_SIZE, STANDARD_IMAGE_SIZE, BufferedImage.TYPE_INT_RGB); final int[] textureData = ((DataBufferInt) missingTexture.getRaster().getDataBuffer()).getData(); - for (int xPixel = 0; xPixel < CHECKERBOARD_TEXTURE_SIZE; ++xPixel) { - for (int yPixel = 0; yPixel < CHECKERBOARD_TEXTURE_SIZE; ++yPixel) { - textureData[xPixel + (yPixel * CHECKERBOARD_TEXTURE_SIZE)] = (xPixel < (CHECKERBOARD_TEXTURE_SIZE / 2)) ^ (yPixel < (CHECKERBOARD_TEXTURE_SIZE / 2)) ? colorOne : colorTwo; + for (int xPixel = 0; xPixel < STANDARD_IMAGE_SIZE; ++xPixel) { + for (int yPixel = 0; yPixel < STANDARD_IMAGE_SIZE; ++yPixel) { + textureData[xPixel + (yPixel * STANDARD_IMAGE_SIZE)] = (xPixel < (STANDARD_IMAGE_SIZE / 2)) ^ (yPixel < (STANDARD_IMAGE_SIZE / 2)) ? colorOne : colorTwo; } } @@ -78,14 +79,21 @@ private static TextureGroup missingTextureText(String name, boolean repeats, Str if ((lines != null) && (lines.length > 0)) { // Set color to black for text rendering graphics.setColor(Color.BLACK); - int fontSize = graphics.getFont().getSize(); - - // Prevent infinite loops - if (fontSize < 1) { - fontSize = 1; + final int checkFontSize; + + // Scale font size with image size multiplier + if (STANDARD_IMAGE_SIZE_MULTIPLIER != 1) { + final Font initualFont = graphics.getFont(); + final Font newFont = initualFont.deriveFont(initualFont.getSize2D() * STANDARD_IMAGE_SIZE_MULTIPLIER); + graphics.setFont(newFont); + checkFontSize = newFont.getSize(); + } else { + checkFontSize = graphics.getFont().getSize(); } - int yPos = 10; + // Prevent infinite loops + final int fontSize = checkFontSize < 1 ? 1 : checkFontSize; + int yPos = TEXT_STARTING_YPOS; int stringsDrawn = 0; while (yPos < TEXT_TEXTURE_SZIE) { @@ -99,7 +107,7 @@ private static TextureGroup missingTextureText(String name, boolean repeats, Str break; } - yPos += 5; + yPos += TEXT_STARTING_YPOS / 2; } } } diff --git a/src/main/java/mcTextureGen/generators/NetherPortalGenerator.java b/src/main/java/mcTextureGen/generators/NetherPortalGenerator.java index 6efaf8c..69f82e4 100644 --- a/src/main/java/mcTextureGen/generators/NetherPortalGenerator.java +++ b/src/main/java/mcTextureGen/generators/NetherPortalGenerator.java @@ -20,13 +20,11 @@ public final class NetherPortalGenerator extends AbstractTextureGenerator { /** The amount of generated nether portal images. */ private static final int PORTAL_IMAGE_AMOUNT = 32; - /** The size of generated nether portal images. */ - private static final int PORTAL_IMAGE_SIZE = 16; - /** * How many spirals the generated image has. * - * @todo this doesn't really work for more than a value of 2, see "TODO fix this" in {@link #netherPortalFrames()} + * @todo this doesn't really work for more than a value of 2 + * @see #netherPortalFrames() */ private static final int SPIRAL_AMOUNT = 2; @@ -41,17 +39,17 @@ private static TextureGroup netherPortalFrames() { final Random rand = new Random(100L); for (int currentPortalImage = 0; currentPortalImage < PORTAL_IMAGE_AMOUNT; currentPortalImage++) { - final BufferedImage portalImage = new BufferedImage(PORTAL_IMAGE_SIZE, PORTAL_IMAGE_SIZE, BufferedImage.TYPE_4BYTE_ABGR); + final BufferedImage portalImage = new BufferedImage(STANDARD_IMAGE_SIZE, STANDARD_IMAGE_SIZE, BufferedImage.TYPE_4BYTE_ABGR); final byte[] imageByteData = ((DataBufferByte) portalImage.getRaster().getDataBuffer()).getData(); - for (int portalImageX = 0; portalImageX < PORTAL_IMAGE_SIZE; portalImageX++) { - for (int portalImageY = 0; portalImageY < PORTAL_IMAGE_SIZE; portalImageY++) { + for (int portalImageX = 0; portalImageX < STANDARD_IMAGE_SIZE; portalImageX++) { + for (int portalImageY = 0; portalImageY < STANDARD_IMAGE_SIZE; portalImageY++) { float currentPixelIntensity = 0.0F; for (int currentSpiral = 0; currentSpiral < SPIRAL_AMOUNT; currentSpiral++) { - final float currentSpiralOffset = currentSpiral * (PORTAL_IMAGE_SIZE / SPIRAL_AMOUNT); - float currentSpiralX = ((portalImageX - currentSpiralOffset) / PORTAL_IMAGE_SIZE) * 2.0F; - float currentSpiralY = ((portalImageY - currentSpiralOffset) / PORTAL_IMAGE_SIZE) * 2.0F; + final float currentSpiralOffset = currentSpiral * (STANDARD_IMAGE_SIZE / SPIRAL_AMOUNT); + float currentSpiralX = ((portalImageX - currentSpiralOffset) / STANDARD_IMAGE_SIZE) * 2.0F; + float currentSpiralY = ((portalImageY - currentSpiralOffset) / STANDARD_IMAGE_SIZE) * 2.0F; if (ADD_CONSTANT_OFFSET) { if (currentSpiralX < -1.0F) { @@ -72,9 +70,8 @@ private static TextureGroup netherPortalFrames() { } final float spiralPowerThingy = (currentSpiralX * currentSpiralX) + (currentSpiralY * currentSpiralY); - // TODO fix this to actually make more than two spirals work, you can see my nonsensical attempt to do this before I got too confused to continue + // TODO fix this to actually make more than two spirals work float currentSpiralIntensity = (float)Math.atan2(currentSpiralY, currentSpiralX) + ((((((float)currentPortalImage / (float)PORTAL_IMAGE_AMOUNT) * (float) Math.PI * 2.0F) - (spiralPowerThingy * 10.0F)) + (currentSpiral * 2)) * ((currentSpiral * 2) - 1)); - // float currentSpiralIntensity = (float)Math.atan2(currentSpiralY, currentSpiralX) + ((((((float)currentPortalImage / (float)portalImageAmount) * (float) Math.PI * 2.0F) - (spiralPowerThingy * 10.0F)) + (currentSpiral * spiralAmount)) * ((((currentSpiral % 2) * 2) - 1) * ((currentSpiral + 2) / 2))); currentSpiralIntensity = (lookupSin(currentSpiralIntensity) + 1.0F) / 2.0F; currentSpiralIntensity /= spiralPowerThingy + 1.0F; currentPixelIntensity += currentSpiralIntensity * (1.0F / SPIRAL_AMOUNT); @@ -85,7 +82,7 @@ private static TextureGroup netherPortalFrames() { } // Construct the ABGR components of the image. - final int imageOffset = (portalImageX + (portalImageY * PORTAL_IMAGE_SIZE)) * 4; + final int imageOffset = (portalImageX + (portalImageY * STANDARD_IMAGE_SIZE)) * 4; /* * Aplha / blue is very common, and has a fairly normal distribution. * The alpha value is the same as the blue value.